Skip to content

Commit 5c1b83d

Browse files
committed
check that partitions tuple format is compatible with parent (instead of basic comparison of attributes of parent and partition)
1 parent e84e169 commit 5c1b83d

File tree

5 files changed

+46
-36
lines changed

5 files changed

+46
-36
lines changed

expected/pathman_basic.out

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,12 +1342,12 @@ CREATE TABLE test.range_rel_test1 (
13421342
txt TEXT,
13431343
abc INTEGER);
13441344
SELECT pathman.attach_range_partition('test.range_rel', 'test.range_rel_test1', '2013-01-01'::DATE, '2014-01-01'::DATE);
1345-
ERROR: partition must have the exact same structure as parent
1345+
ERROR: partition must have a compatible tuple format
13461346
CREATE TABLE test.range_rel_test2 (
13471347
id SERIAL PRIMARY KEY,
13481348
dt TIMESTAMP);
13491349
SELECT pathman.attach_range_partition('test.range_rel', 'test.range_rel_test2', '2013-01-01'::DATE, '2014-01-01'::DATE);
1350-
ERROR: partition must have the exact same structure as parent
1350+
ERROR: column "dt" in child table must be marked NOT NULL
13511351
/* Half open ranges */
13521352
SELECT pathman.add_range_partition('test.range_rel', NULL, '2014-12-01'::DATE, 'test.range_rel_minus_infinity');
13531353
add_range_partition
@@ -1499,7 +1499,7 @@ CREATE TABLE test.hash_rel_wrong(
14991499
id INTEGER NOT NULL,
15001500
value INTEGER);
15011501
SELECT pathman.replace_hash_partition('test.hash_rel_1', 'test.hash_rel_wrong');
1502-
ERROR: partition must have the exact same structure as parent
1502+
ERROR: column "value" in child table must be marked NOT NULL
15031503
EXPLAIN (COSTS OFF) SELECT * FROM test.hash_rel;
15041504
QUERY PLAN
15051505
-----------------------------------

hash.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ BEGIN
110110
END IF;
111111

112112
/* Check that new partition has an equal structure as parent does */
113-
IF NOT @extschema@.validate_relations_equality(parent_relid, new_partition) THEN
114-
RAISE EXCEPTION 'partition must have the exact same structure as parent';
113+
IF NOT @extschema@.tuple_format_is_convertable(parent_relid, new_partition) THEN
114+
RAISE EXCEPTION 'partition must have a compatible tuple format';
115115
END IF;
116116

117117
/* Get partitioning key */

init.sql

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -491,36 +491,13 @@ $$
491491
LANGUAGE plpgsql STRICT;
492492

493493
/*
494-
* Check if two relations have equal structures.
494+
* Check that tuple from first relation could be converted to fit the second one
495495
*/
496-
CREATE OR REPLACE FUNCTION @extschema@.validate_relations_equality(
497-
relation1 OID, relation2 OID)
498-
RETURNS BOOLEAN AS
499-
$$
500-
DECLARE
501-
rec RECORD;
502-
503-
BEGIN
504-
FOR rec IN (
505-
WITH
506-
a1 AS (select * from pg_catalog.pg_attribute
507-
where attrelid = relation1 and attnum > 0),
508-
a2 AS (select * from pg_catalog.pg_attribute
509-
where attrelid = relation2 and attnum > 0)
510-
SELECT a1.attname name1, a2.attname name2, a1.atttypid type1, a2.atttypid type2
511-
FROM a1
512-
FULL JOIN a2 ON a1.attnum = a2.attnum
513-
)
514-
LOOP
515-
IF rec.name1 IS NULL OR rec.name2 IS NULL OR rec.name1 != rec.name2 THEN
516-
RETURN false;
517-
END IF;
518-
END LOOP;
519-
520-
RETURN true;
521-
END
522-
$$
523-
LANGUAGE plpgsql;
496+
CREATE OR REPLACE FUNCTION @extschema@.tuple_format_is_convertable(
497+
relation1 OID,
498+
relation2 OID)
499+
RETURNS BOOL AS 'pg_pathman', 'tuple_format_is_convertable'
500+
LANGUAGE C;
524501

525502
/*
526503
* DDL trigger that removes entry from pathman_config table.

range.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -905,8 +905,8 @@ BEGIN
905905
/* check range overlap */
906906
PERFORM @extschema@.check_range_available(parent_relid, start_value, end_value);
907907

908-
IF NOT @extschema@.validate_relations_equality(parent_relid, partition_relid) THEN
909-
RAISE EXCEPTION 'partition must have the exact same structure as parent';
908+
IF NOT @extschema@.tuple_format_is_convertable(parent_relid, partition_relid) THEN
909+
RAISE EXCEPTION 'partition must have a compatible tuple format';
910910
END IF;
911911

912912
/* Set inheritance */

src/pl_funcs.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ PG_FUNCTION_INFO_V1( build_check_constraint_name_attname );
6161
PG_FUNCTION_INFO_V1( validate_relname );
6262
PG_FUNCTION_INFO_V1( is_date_type );
6363
PG_FUNCTION_INFO_V1( is_attribute_nullable );
64+
PG_FUNCTION_INFO_V1( tuple_format_is_convertable );
6465

6566
PG_FUNCTION_INFO_V1( add_to_pathman_config );
6667
PG_FUNCTION_INFO_V1( pathman_config_params_trigger_func );
@@ -509,6 +510,38 @@ is_attribute_nullable(PG_FUNCTION_ARGS)
509510
PG_RETURN_BOOL(result); /* keep compiler happy */
510511
}
511512

513+
Datum
514+
tuple_format_is_convertable(PG_FUNCTION_ARGS)
515+
{
516+
Oid relid1 = PG_GETARG_OID(0),
517+
relid2 = PG_GETARG_OID(1);
518+
Relation rel1,
519+
rel2;
520+
bool res = true;
521+
522+
/* Relations should be already locked */
523+
rel1 = heap_open(relid1, NoLock);
524+
rel2 = heap_open(relid2, NoLock);
525+
526+
PG_TRY();
527+
{
528+
/* Try to build a conversion map */
529+
(void) convert_tuples_by_name_map(rel1->rd_att,
530+
rel2->rd_att,
531+
"doesn't matter");
532+
}
533+
PG_CATCH();
534+
{
535+
res = false;
536+
}
537+
PG_END_TRY();
538+
539+
heap_close(rel1, NoLock);
540+
heap_close(rel2, NoLock);
541+
542+
PG_RETURN_BOOL(res);
543+
}
544+
512545

513546
/*
514547
* ------------------------

0 commit comments

Comments
 (0)