diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index e9eef00ad7c..7782596b23d 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -23082,8 +23082,7 @@ checkPartitionGenExprMatchesParent(Relation parent_rel, Relation partRel) AttrMap *attmap = NULL; /* Nothing to compare if the partitioned table has no generated columns. */ - if (constr == NULL || - !(constr->has_generated_stored || constr->has_generated_virtual)) + if (constr == NULL || constr->num_defval == 0) return; for (AttrNumber parent_attno = 1; parent_attno <= parentDesc->natts; @@ -23095,7 +23094,7 @@ checkPartitionGenExprMatchesParent(Relation parent_rel, Relation partRel) Node *childExpr; bool found_whole_row; - if (pattr->attisdropped || pattr->attgenerated == '\0') + if (pattr->attisdropped || !pattr->atthasdef) continue; /* @@ -23106,6 +23105,22 @@ checkPartitionGenExprMatchesParent(Relation parent_rel, Relation partRel) child_attno = get_attnum(RelationGetRelid(partRel), NameStr(pattr->attname)); Assert(child_attno != InvalidAttrNumber); + if (pattr->attgenerated == '\0') + { + parentExpr = build_column_default(parent_rel, parent_attno); + childExpr = build_column_default(partRel, child_attno); + + if (!equal(parentExpr, childExpr)) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot merge or split partitions when a partition's default expression differs from the partitioned table"), + errdetail("Generated column \"%s\" of partition \"%s\" has a default expression different from table \"%s\".", + NameStr(pattr->attname), + RelationGetRelationName(partRel), + RelationGetRelationName(parent_rel))); + continue; + } + parentExpr = build_generation_expression(parent_rel, parent_attno); childExpr = build_generation_expression(partRel, child_attno); @@ -24030,6 +24045,12 @@ ATExecMergePartitions(List **wqueue, AlteredTableInfo *tab, Relation rel, */ checkPartitionSystemColumnRefs(rel); + if (rel->trigdesc) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot merge or split partition because partitioned table \"%s\" has triggers on it", + RelationGetRelationName(rel))); + /* * Check ownership of merged partitions - partitions with different owners * cannot be merged. Also, collect the OIDs of these partitions during the @@ -24058,6 +24079,76 @@ ATExecMergePartitions(List **wqueue, AlteredTableInfo *tab, Relation rel, else ownerId = mergingPartition->rd_rel->relowner; + if (mergingPartition->trigdesc) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot merge or split partition because partition table \"%s\" has triggers on it", + RelationGetRelationName(mergingPartition))); + + /* Look up the access method for the new relation. */ + if (OidIsValid(rel->rd_rel->relam) && (rel->rd_rel->relam != mergingPartition->rd_rel->relam)) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot merge or split partition because partition table \"%s\" table am differ from partitioned table", + RelationGetRelationName(mergingPartition))); + { + Relation indrel; + SysScanDesc indscan; + ScanKeyData skey; + HeapTuple htup; + List *result; + + result = NIL; + + /* + * Prepare to scan pg_index for entries having indrelid = this + * rel. + */ + ScanKeyInit(&skey, + Anum_pg_index_indrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(mergingPartition))); + + indrel = table_open(IndexRelationId, AccessShareLock); + indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true, + NULL, 1, &skey); + + while (HeapTupleIsValid(htup = systable_getnext(indscan))) + { + Form_pg_index index = (Form_pg_index) GETSTRUCT(htup); + + /* add index's OID to result list */ + result = lappend_oid(result, index->indexrelid); + } + + systable_endscan(indscan); + table_close(indrel, AccessShareLock); + + /* Sort the result list into OID order, per API spec. */ + list_sort(result, list_oid_cmp); + + foreach_oid(mergingPartitionIdxs, result) + { + HeapTuple tup; + Form_pg_class classForm; + bool ispartition; + + tup = SearchSysCache1(RELOID, ObjectIdGetDatum(mergingPartitionIdxs)); + if (!HeapTupleIsValid(tup)) + elog(ERROR, "cache lookup failed for relation %u", mergingPartitionIdxs); + classForm = (Form_pg_class) GETSTRUCT(tup); + ispartition = classForm->relispartition; + ReleaseSysCache(tup); + if (ispartition) + continue; + + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot merge or split partition because partition table \"%s\" has local index on it", + RelationGetRelationName(mergingPartition))); + } + } + /* * The new partition inherits the partitioned table's generation * expressions, but rows are moved as-is; reject a partition whose @@ -24066,6 +24157,37 @@ ATExecMergePartitions(List **wqueue, AlteredTableInfo *tab, Relation rel, */ checkPartitionGenExprMatchesParent(rel, mergingPartition); + { + Relation pg_constraint; + HeapTuple conTup; + SysScanDesc scan; + ScanKeyData key; + + pg_constraint = table_open(ConstraintRelationId, AccessShareLock); + ScanKeyInit(&key, + Anum_pg_constraint_conrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(mergingPartition))); + scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, + true, NULL, 1, &key); + + while (HeapTupleIsValid(conTup = systable_getnext(scan))) + { + Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(conTup); + + if (!con->conislocal) + continue; + + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot merge or split partition \"%s\" that has local constraints", + RelationGetRelationName(mergingPartition))); + } + + systable_endscan(scan); + table_close(pg_constraint, AccessShareLock); + } + /* Store the next merging partition into the list. */ mergingPartitions = lappend_oid(mergingPartitions, RelationGetRelid(mergingPartition)); diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h index 214ef1e7e2d..282008062a1 100644 --- a/src/include/catalog/dependency.h +++ b/src/include/catalog/dependency.h @@ -109,6 +109,8 @@ extern void performDeletion(const ObjectAddress *object, extern void performDeletionCheck(const ObjectAddress *object, DropBehavior behavior, int flags); +extern bool partition_dependent_objects_exists(const ObjectAddress *object, + int flags); extern void performMultipleDeletions(const ObjectAddresses *objects, DropBehavior behavior, int flags); diff --git a/src/test/regress/expected/partition_merge.out b/src/test/regress/expected/partition_merge.out index bc4963b06c3..d887a1ba63c 100644 --- a/src/test/regress/expected/partition_merge.out +++ b/src/test/regress/expected/partition_merge.out @@ -330,14 +330,15 @@ NOTICE: trigger(salespeople) called: action = INSERT, when = AFTER, level = STA -- 1 trigger should fire here (row): INSERT INTO salespeople10_20 VALUES (19, 'Ivanov'); NOTICE: trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW -ALTER TABLE salespeople MERGE PARTITIONS (salespeople10_20, salespeople20_30, salespeople30_40) INTO salespeople10_40; --- 2 triggers should fire here (row + statement): -INSERT INTO salespeople VALUES (20, 'Smirnoff'); -NOTICE: trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW -NOTICE: trigger(salespeople) called: action = INSERT, when = AFTER, level = STATEMENT --- 1 trigger should fire here (row): -INSERT INTO salespeople10_40 VALUES (30, 'Ford'); -NOTICE: trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW +ALTER TABLE salespeople MERGE PARTITIONS (salespeople10_20, salespeople20_30, salespeople30_40) INTO salespeople10_40; -- error +ERROR: cannot merge or split partition because partitioned table "salespeople" has triggers on it +DROP TRIGGER salespeople_after_insert_statement_trigger ON salespeople; +DROP TRIGGER salespeople_after_insert_row_trigger ON salespeople; +ALTER TABLE salespeople MERGE PARTITIONS (salespeople10_20, salespeople20_30, salespeople30_40) INTO salespeople10_40; -- ok +-- 2 triggers should fire here (row + statement): (not supported) +-- INSERT INTO salespeople VALUES (20, 'Smirnoff'); +-- 1 trigger should fire here (row): (not supported) +-- INSERT INTO salespeople10_40 VALUES (30, 'Ford'); SELECT * FROM salespeople01_10; salesperson_id | salesperson_name ----------------+------------------ @@ -349,9 +350,7 @@ SELECT * FROM salespeople10_40; ----------------+------------------ 10 | May 19 | Ivanov - 20 | Smirnoff - 30 | Ford -(4 rows) +(2 rows) DROP TABLE salespeople; DROP FUNCTION after_insert_row_trigger(); @@ -647,7 +646,11 @@ CREATE TABLE t (i int, PRIMARY KEY(i)) PARTITION BY RANGE (i); CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); CREATE INDEX tidx ON t(i); -ALTER TABLE t MERGE PARTITIONS (tp_1_2, tp_0_1) INTO tp_1_2; +CREATE INDEX tp_1_2_idx ON tp_1_2(i); +ALTER TABLE t MERGE PARTITIONS (tp_1_2, tp_0_1) INTO tp_1_2; -- error, not supported +ERROR: cannot merge or split partition because partition table "tp_1_2" has local index on it +DROP INDEX tp_1_2_idx; +ALTER TABLE t MERGE PARTITIONS (tp_1_2, tp_0_1) INTO tp_1_2; -- ok -- Indexname values should be 'tp_1_2_pkey' and 'tp_1_2_i_idx'. \d+ tp_1_2 Table "partitions_merge_schema.tp_1_2" @@ -923,6 +926,7 @@ ALTER TABLE t ADD CONSTRAINT t_b_check CHECK (b > 0); ALTER TABLE t ADD CONSTRAINT t_b_check1 CHECK (b > 0) NOT ENFORCED; ALTER TABLE t ADD CONSTRAINT t_b_check2 CHECK (b > 0) NOT VALID; ALTER TABLE t ADD CONSTRAINT t_b_nn NOT NULL b NOT VALID; +ALTER TABLE tp_1_2 ADD CONSTRAINT t_b_check3 CHECK (b > 0) NOT VALID; INSERT INTO tp_0_1(i, t, b) VALUES(0, DEFAULT, 1); INSERT INTO tp_1_2(i, t, b) VALUES(1, DEFAULT, 2); CREATE OR REPLACE FUNCTION trigger_function() RETURNS trigger LANGUAGE 'plpgsql' AS @@ -932,12 +936,12 @@ BEGIN RETURN new; END; $BODY$; -CREATE TRIGGER t_before_insert_row_trigger BEFORE INSERT ON t FOR EACH ROW - EXECUTE PROCEDURE trigger_function('t'); -CREATE TRIGGER tp_0_1_before_insert_row_trigger BEFORE INSERT ON tp_0_1 FOR EACH ROW - EXECUTE PROCEDURE trigger_function('tp_0_1'); -CREATE TRIGGER tp_1_2_before_insert_row_trigger BEFORE INSERT ON tp_1_2 FOR EACH ROW - EXECUTE PROCEDURE trigger_function('tp_1_2'); +-- CREATE TRIGGER t_before_insert_row_trigger BEFORE INSERT ON t FOR EACH ROW +-- EXECUTE PROCEDURE trigger_function('t'); +-- CREATE TRIGGER tp_0_1_before_insert_row_trigger BEFORE INSERT ON tp_0_1 FOR EACH ROW +-- EXECUTE PROCEDURE trigger_function('tp_0_1'); +-- CREATE TRIGGER tp_1_2_before_insert_row_trigger BEFORE INSERT ON tp_1_2 FOR EACH ROW +-- EXECUTE PROCEDURE trigger_function('tp_1_2'); \d+ tp_0_1 Table "partitions_merge_schema.tp_0_1" Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description @@ -957,11 +961,16 @@ Statistics objects: Not-null constraints: "tp_0_1_i_not_null" NOT NULL "i" (inherited) "t_b_nn" NOT NULL "b" (inherited) NOT VALID -Triggers: - t_before_insert_row_trigger BEFORE INSERT ON tp_0_1 FOR EACH ROW EXECUTE FUNCTION trigger_function('t'), ON TABLE t - tp_0_1_before_insert_row_trigger BEFORE INSERT ON tp_0_1 FOR EACH ROW EXECUTE FUNCTION trigger_function('tp_0_1') -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_1; +ALTER TABLE tp_0_1 ALTER COLUMN t SET DEFAULT 'default_t'; +ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_1; -- error +ERROR: cannot merge or split partitions when a partition's default expression differs from the partitioned table +DETAIL: Generated column "t" of partition "tp_1_2" has a default expression different from table "t". +ALTER TABLE tp_1_2 ALTER COLUMN t SET DEFAULT 'default_t'; +ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_1; -- error +ERROR: cannot merge or split partition "tp_1_2" that has local constraints +ALTER TABLE tp_1_2 DROP CONSTRAINT t_b_check3; +ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_1; -- ok \d+ tp_0_1 Table "partitions_merge_schema.tp_0_1" Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description @@ -979,11 +988,8 @@ Check constraints: Not-null constraints: "t_i_not_null" NOT NULL "i" (inherited) "t_b_nn" NOT NULL "b" (inherited) NOT VALID -Triggers: - t_before_insert_row_trigger BEFORE INSERT ON tp_0_1 FOR EACH ROW EXECUTE FUNCTION trigger_function('t'), ON TABLE t INSERT INTO t(i, t, b) VALUES(1, DEFAULT, 3); -NOTICE: trigger(t) called: action = INSERT, when = BEFORE, level = ROW SELECT tableoid::regclass, * FROM t ORDER BY b; tableoid | i | t | b | d ----------+---+----------------+---+------------ @@ -996,32 +1002,20 @@ DROP TABLE t; DROP FUNCTION trigger_function(); \set HIDE_TOAST_COMPRESSION true -- Test MERGE PARTITIONS with not valid foreign key constraint -CREATE TABLE t (i INT PRIMARY KEY) PARTITION BY RANGE (i); -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -INSERT INTO t VALUES (0), (1); -CREATE TABLE t_fk (i INT); -INSERT INTO t_fk VALUES (1), (2); -ALTER TABLE t_fk ADD CONSTRAINT t_fk_i_fkey FOREIGN KEY (i) REFERENCES t NOT VALID; -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; --- Should be NOT VALID FOREIGN KEY -\d tp_0_2 - Table "partitions_merge_schema.tp_0_2" - Column | Type | Collation | Nullable | Default ---------+---------+-----------+----------+--------- - i | integer | | not null | -Partition of: t FOR VALUES FROM (0) TO (2) -Indexes: - "tp_0_2_pkey" PRIMARY KEY, btree (i) -Referenced by: - TABLE "t_fk" CONSTRAINT "t_fk_i_fkey" FOREIGN KEY (i) REFERENCES t(i) NOT VALID - --- ERROR -ALTER TABLE t_fk VALIDATE CONSTRAINT t_fk_i_fkey; -ERROR: insert or update on table "t_fk" violates foreign key constraint "t_fk_i_fkey" -DETAIL: Key (i)=(2) is not present in table "t". -DROP TABLE t_fk; -DROP TABLE t; +-- CREATE TABLE t (i INT PRIMARY KEY) PARTITION BY RANGE (i); +-- CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); +-- CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); +-- INSERT INTO t VALUES (0), (1); +-- CREATE TABLE t_fk (i INT); +-- INSERT INTO t_fk VALUES (1), (2); +-- ALTER TABLE t_fk ADD CONSTRAINT t_fk_i_fkey FOREIGN KEY (i) REFERENCES t NOT VALID; +-- ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; +-- -- Should be NOT VALID FOREIGN KEY (not supported) +-- \d tp_0_2 +-- -- ERROR +-- ALTER TABLE t_fk VALIDATE CONSTRAINT t_fk_i_fkey; +-- DROP TABLE t_fk; +-- DROP TABLE t; -- Test MERGE PARTITIONS with not enforced foreign key constraint CREATE TABLE t (i INT PRIMARY KEY) PARTITION BY RANGE (i); CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); diff --git a/src/test/regress/sql/partition_merge.sql b/src/test/regress/sql/partition_merge.sql index 558f5a12a86..6dcff084f69 100644 --- a/src/test/regress/sql/partition_merge.sql +++ b/src/test/regress/sql/partition_merge.sql @@ -235,12 +235,15 @@ INSERT INTO salespeople VALUES (10, 'May'); -- 1 trigger should fire here (row): INSERT INTO salespeople10_20 VALUES (19, 'Ivanov'); -ALTER TABLE salespeople MERGE PARTITIONS (salespeople10_20, salespeople20_30, salespeople30_40) INTO salespeople10_40; +ALTER TABLE salespeople MERGE PARTITIONS (salespeople10_20, salespeople20_30, salespeople30_40) INTO salespeople10_40; -- error +DROP TRIGGER salespeople_after_insert_statement_trigger ON salespeople; +DROP TRIGGER salespeople_after_insert_row_trigger ON salespeople; +ALTER TABLE salespeople MERGE PARTITIONS (salespeople10_20, salespeople20_30, salespeople30_40) INTO salespeople10_40; -- ok --- 2 triggers should fire here (row + statement): -INSERT INTO salespeople VALUES (20, 'Smirnoff'); --- 1 trigger should fire here (row): -INSERT INTO salespeople10_40 VALUES (30, 'Ford'); +-- 2 triggers should fire here (row + statement): (not supported) +-- INSERT INTO salespeople VALUES (20, 'Smirnoff'); +-- 1 trigger should fire here (row): (not supported) +-- INSERT INTO salespeople10_40 VALUES (30, 'Ford'); SELECT * FROM salespeople01_10; SELECT * FROM salespeople10_40; @@ -456,7 +459,11 @@ CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); CREATE INDEX tidx ON t(i); -ALTER TABLE t MERGE PARTITIONS (tp_1_2, tp_0_1) INTO tp_1_2; +CREATE INDEX tp_1_2_idx ON tp_1_2(i); + +ALTER TABLE t MERGE PARTITIONS (tp_1_2, tp_0_1) INTO tp_1_2; -- error, not supported +DROP INDEX tp_1_2_idx; +ALTER TABLE t MERGE PARTITIONS (tp_1_2, tp_0_1) INTO tp_1_2; -- ok -- Indexname values should be 'tp_1_2_pkey' and 'tp_1_2_i_idx'. \d+ tp_1_2 @@ -684,6 +691,7 @@ ALTER TABLE t ADD CONSTRAINT t_b_check CHECK (b > 0); ALTER TABLE t ADD CONSTRAINT t_b_check1 CHECK (b > 0) NOT ENFORCED; ALTER TABLE t ADD CONSTRAINT t_b_check2 CHECK (b > 0) NOT VALID; ALTER TABLE t ADD CONSTRAINT t_b_nn NOT NULL b NOT VALID; +ALTER TABLE tp_1_2 ADD CONSTRAINT t_b_check3 CHECK (b > 0) NOT VALID; INSERT INTO tp_0_1(i, t, b) VALUES(0, DEFAULT, 1); INSERT INTO tp_1_2(i, t, b) VALUES(1, DEFAULT, 2); @@ -695,15 +703,20 @@ BEGIN END; $BODY$; -CREATE TRIGGER t_before_insert_row_trigger BEFORE INSERT ON t FOR EACH ROW - EXECUTE PROCEDURE trigger_function('t'); -CREATE TRIGGER tp_0_1_before_insert_row_trigger BEFORE INSERT ON tp_0_1 FOR EACH ROW - EXECUTE PROCEDURE trigger_function('tp_0_1'); -CREATE TRIGGER tp_1_2_before_insert_row_trigger BEFORE INSERT ON tp_1_2 FOR EACH ROW - EXECUTE PROCEDURE trigger_function('tp_1_2'); +-- CREATE TRIGGER t_before_insert_row_trigger BEFORE INSERT ON t FOR EACH ROW +-- EXECUTE PROCEDURE trigger_function('t'); +-- CREATE TRIGGER tp_0_1_before_insert_row_trigger BEFORE INSERT ON tp_0_1 FOR EACH ROW +-- EXECUTE PROCEDURE trigger_function('tp_0_1'); +-- CREATE TRIGGER tp_1_2_before_insert_row_trigger BEFORE INSERT ON tp_1_2 FOR EACH ROW +-- EXECUTE PROCEDURE trigger_function('tp_1_2'); \d+ tp_0_1 -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_1; +ALTER TABLE tp_0_1 ALTER COLUMN t SET DEFAULT 'default_t'; +ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_1; -- error +ALTER TABLE tp_1_2 ALTER COLUMN t SET DEFAULT 'default_t'; +ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_1; -- error +ALTER TABLE tp_1_2 DROP CONSTRAINT t_b_check3; +ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_1; -- ok \d+ tp_0_1 INSERT INTO t(i, t, b) VALUES(1, DEFAULT, 3); @@ -714,22 +727,22 @@ DROP FUNCTION trigger_function(); -- Test MERGE PARTITIONS with not valid foreign key constraint -CREATE TABLE t (i INT PRIMARY KEY) PARTITION BY RANGE (i); -CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); -CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); -INSERT INTO t VALUES (0), (1); -CREATE TABLE t_fk (i INT); -INSERT INTO t_fk VALUES (1), (2); -ALTER TABLE t_fk ADD CONSTRAINT t_fk_i_fkey FOREIGN KEY (i) REFERENCES t NOT VALID; -ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; - --- Should be NOT VALID FOREIGN KEY -\d tp_0_2 --- ERROR -ALTER TABLE t_fk VALIDATE CONSTRAINT t_fk_i_fkey; - -DROP TABLE t_fk; -DROP TABLE t; +-- CREATE TABLE t (i INT PRIMARY KEY) PARTITION BY RANGE (i); +-- CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1); +-- CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2); +-- INSERT INTO t VALUES (0), (1); +-- CREATE TABLE t_fk (i INT); +-- INSERT INTO t_fk VALUES (1), (2); +-- ALTER TABLE t_fk ADD CONSTRAINT t_fk_i_fkey FOREIGN KEY (i) REFERENCES t NOT VALID; +-- ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2; + +-- -- Should be NOT VALID FOREIGN KEY (not supported) +-- \d tp_0_2 +-- -- ERROR +-- ALTER TABLE t_fk VALIDATE CONSTRAINT t_fk_i_fkey; + +-- DROP TABLE t_fk; +-- DROP TABLE t; -- Test MERGE PARTITIONS with not enforced foreign key constraint CREATE TABLE t (i INT PRIMARY KEY) PARTITION BY RANGE (i);