On 3/18/20 6:56 AM, Amit Kapila wrote: > On Thu, Mar 12, 2020 at 7:46 PM Amit Kapila <amit.kapil...@gmail.com> wrote: >> >> On Wed, Mar 11, 2020 at 8:51 PM Chris Bandy <bandy.ch...@gmail.com> wrote: >>> >>> On 3/11/20 6:29 AM, Amit Kapila wrote: >>>> >>>> I have tried with git am as well, but it failed. I am not sure what >>>> is the reason. Can you please once check at your end? >>> >>> Yes, sorry. This set (and v3 and v4) should work with -p0. Any following >>> patches from me will use the normal -p1. >>> >> >> Okay. >> > > I again tried the latest patch v5 both with -p1 and -p0, but it gives > an error while applying the patch. Can you send a patch that we can > apply with patch -p1 or git-am? > > [1] - > https://www.postgresql.org/message-id/0731def8-978e-0285-04ee-582762729b38%40gmail.com >
Sorry for these troubles. Attached are patches created using `git format-patch -n -v6` on master at 487e9861d0. Thanks, Chris
>From 6e5e47dc9a816c8d3e3453759da5ea0dcbeea31a Mon Sep 17 00:00:00 2001 From: Chris Bandy <bandy.ch...@gmail.com> Date: Fri, 6 Mar 2020 20:48:55 -0600 Subject: [PATCH v6 1/2] Add tests for integrity violation error fields The documentation states that all errors of SQLSTATE class 23 should include the name of an object associated with the error. --- src/test/regress/expected/integrity_errors.out | 408 +++++++++++++++++++++++++ src/test/regress/parallel_schedule | 2 +- src/test/regress/sql/integrity_errors.sql | 193 ++++++++++++ 3 files changed, 602 insertions(+), 1 deletion(-) create mode 100644 src/test/regress/expected/integrity_errors.out create mode 100644 src/test/regress/sql/integrity_errors.sql diff --git a/src/test/regress/expected/integrity_errors.out b/src/test/regress/expected/integrity_errors.out new file mode 100644 index 0000000000..e75e6b722f --- /dev/null +++ b/src/test/regress/expected/integrity_errors.out @@ -0,0 +1,408 @@ +-- +-- Tests for integrity violation error fields +-- +-- Errors in SQLSTATE class 23 (integrity constraint violation) should +-- include the name of a database object as a separate field. +-- +-- The fields of interest are shown at the same verbosity level as +-- volatile details such as source code line numbers. To produce stable +-- regression output, the following function returns a portion of the +-- full error reported. +CREATE FUNCTION integrity_error_record( + dml text, + OUT err_sqlstate text, + OUT err_message text, + OUT err_detail text, + OUT err_datatype text, + OUT err_schema text, + OUT err_table text, + OUT err_column text, + OUT err_constraint text) +AS $$ +BEGIN + EXECUTE $1; +EXCEPTION + WHEN integrity_constraint_violation THEN GET STACKED DIAGNOSTICS + err_sqlstate := RETURNED_SQLSTATE, + err_message := MESSAGE_TEXT, + err_detail := PG_EXCEPTION_DETAIL, + err_datatype := PG_DATATYPE_NAME, + err_schema := SCHEMA_NAME, + err_table := TABLE_NAME, + err_column := COLUMN_NAME, + err_constraint := CONSTRAINT_NAME; +END; +$$ LANGUAGE plpgsql; +\pset expanded on +\pset tuples_only on +-- table not null +CREATE TABLE ivnt1 (n int NOT NULL); +SELECT * FROM integrity_error_record($$ + INSERT INTO ivnt1 VALUES (NULL); +$$); +err_sqlstate | 23502 +err_message | null value in column "n" of relation "ivnt1" violates not-null constraint +err_detail | Failing row contains (null). +err_datatype | +err_schema | public +err_table | ivnt1 +err_column | n +err_constraint | + +-- alter table not null +CREATE TABLE ivnt2 (n int); +INSERT INTO ivnt2 VALUES (NULL); +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivnt2 ALTER n SET NOT NULL; +$$); +err_sqlstate | 23502 +err_message | column "n" of relation "ivnt2" contains null values +err_detail | +err_datatype | +err_schema | public +err_table | ivnt2 +err_column | n +err_constraint | + +DROP TABLE ivnt1, ivnt2; +-- table unique +CREATE TABLE ivpkt1 (x int, y int, PRIMARY KEY (x, y)); +INSERT INTO ivpkt1 VALUES (1, 2); +SELECT * FROM integrity_error_record($$ + INSERT INTO ivpkt1 VALUES (1, 2); +$$); +err_sqlstate | 23505 +err_message | duplicate key value violates unique constraint "ivpkt1_pkey" +err_detail | Key (x, y)=(1, 2) already exists. +err_datatype | +err_schema | public +err_table | ivpkt1 +err_column | +err_constraint | ivpkt1_pkey + +-- alter table unique +CREATE TABLE ivpkt2 (x int, y int); +INSERT INTO ivpkt2 VALUES (1, 2), (1, 2); +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivpkt2 ADD PRIMARY KEY (x, y); +$$); +err_sqlstate | 23505 +err_message | could not create unique index "ivpkt2_pkey" +err_detail | Key (x, y)=(1, 2) is duplicated. +err_datatype | +err_schema | public +err_table | ivpkt2 +err_column | +err_constraint | ivpkt2_pkey + +-- table foreign key reference +CREATE TABLE ivfkt1 (x int, y int, FOREIGN KEY (x, y) REFERENCES ivpkt1); +SELECT * FROM integrity_error_record($$ + INSERT INTO ivfkt1 VALUES (10, 10); +$$); +err_sqlstate | 23503 +err_message | insert or update on table "ivfkt1" violates foreign key constraint "ivfkt1_x_y_fkey" +err_detail | Key (x, y)=(10, 10) is not present in table "ivpkt1". +err_datatype | +err_schema | public +err_table | ivfkt1 +err_column | +err_constraint | ivfkt1_x_y_fkey + +INSERT INTO ivfkt1 VALUES (1, 2); +SELECT * FROM integrity_error_record($$ + DELETE FROM ivpkt1; +$$); +err_sqlstate | 23503 +err_message | update or delete on table "ivpkt1" violates foreign key constraint "ivfkt1_x_y_fkey" on table "ivfkt1" +err_detail | Key (x, y)=(1, 2) is still referenced from table "ivfkt1". +err_datatype | +err_schema | public +err_table | ivfkt1 +err_column | +err_constraint | ivfkt1_x_y_fkey + +-- foreign key reference match full +CREATE TABLE ivfkt2 (x int, y int, FOREIGN KEY (x, y) REFERENCES ivpkt1 MATCH FULL); +SELECT * FROM integrity_error_record($$ + INSERT INTO ivfkt2 VALUES (1, NULL); +$$); +err_sqlstate | 23503 +err_message | insert or update on table "ivfkt2" violates foreign key constraint "ivfkt2_x_y_fkey" +err_detail | MATCH FULL does not allow mixing of null and nonnull key values. +err_datatype | +err_schema | public +err_table | ivfkt2 +err_column | +err_constraint | ivfkt2_x_y_fkey + +CREATE TABLE ivfkt3 (x int, y int); +INSERT INTO ivfkt3 VALUES (1, NULL); +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivfkt3 ADD FOREIGN KEY (x, y) REFERENCES ivpkt1 MATCH FULL; +$$); +err_sqlstate | 23503 +err_message | insert or update on table "ivfkt3" violates foreign key constraint "ivfkt3_x_y_fkey" +err_detail | MATCH FULL does not allow mixing of null and nonnull key values. +err_datatype | +err_schema | public +err_table | ivfkt3 +err_column | +err_constraint | ivfkt3_x_y_fkey + +DROP TABLE ivfkt1, ivfkt2, ivfkt3, ivpkt1, ivpkt2; +-- table exclusion +CREATE TABLE ivet1 (n int, EXCLUDE (n WITH =)); +INSERT INTO ivet1 VALUES (1); +SELECT * FROM integrity_error_record($$ + INSERT INTO ivet1 VALUES (1); +$$); +err_sqlstate | 23P01 +err_message | conflicting key value violates exclusion constraint "ivet1_n_excl" +err_detail | Key (n)=(1) conflicts with existing key (n)=(1). +err_datatype | +err_schema | public +err_table | ivet1 +err_column | +err_constraint | ivet1_n_excl + +-- alter table exclusion +CREATE TABLE ivet2 (n int); +INSERT INTO ivet2 VALUES (1), (1); +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivet2 ADD EXCLUDE (n WITH =); +$$); +err_sqlstate | 23P01 +err_message | could not create exclusion constraint "ivet2_n_excl" +err_detail | Key (n)=(1) conflicts with key (n)=(1). +err_datatype | +err_schema | public +err_table | ivet2 +err_column | +err_constraint | ivet2_n_excl + +DROP TABLE ivet1, ivet2; +-- domain +CREATE DOMAIN ivd1 int NOT NULL CHECK (VALUE < 5); +CREATE TABLE ivdt1 (n ivd1); +SELECT * FROM integrity_error_record($$ + SELECT NULL::ivd1; +$$); +err_sqlstate | 23502 +err_message | domain ivd1 does not allow null values +err_detail | +err_datatype | ivd1 +err_schema | public +err_table | +err_column | +err_constraint | + +SELECT * FROM integrity_error_record($$ + SELECT 10::ivd1; +$$); +err_sqlstate | 23514 +err_message | value for domain ivd1 violates check constraint "ivd1_check" +err_detail | +err_datatype | ivd1 +err_schema | public +err_table | +err_column | +err_constraint | ivd1_check + +SELECT * FROM integrity_error_record($$ + SELECT json_populate_record(NULL::ivdt1, '{"n":null}'); +$$); +err_sqlstate | 23502 +err_message | domain ivd1 does not allow null values +err_detail | +err_datatype | ivd1 +err_schema | public +err_table | +err_column | +err_constraint | + +SELECT * FROM integrity_error_record($$ + SELECT json_populate_record(NULL::ivdt1, '{"n":10}'); +$$); +err_sqlstate | 23514 +err_message | value for domain ivd1 violates check constraint "ivd1_check" +err_detail | +err_datatype | ivd1 +err_schema | public +err_table | +err_column | +err_constraint | ivd1_check + +-- alter domain +CREATE DOMAIN ivd2 int; +CREATE TABLE ivdt2 (n ivd2); +INSERT INTO ivdt2 VALUES (NULL), (10); +SELECT * FROM integrity_error_record($$ + ALTER DOMAIN ivd2 SET NOT NULL; +$$); +err_sqlstate | 23502 +err_message | column "n" of table "ivdt2" contains null values +err_detail | +err_datatype | +err_schema | public +err_table | ivdt2 +err_column | n +err_constraint | + +SELECT * FROM integrity_error_record($$ + ALTER DOMAIN ivd2 ADD CHECK (VALUE < 5); +$$); +err_sqlstate | 23514 +err_message | column "n" of table "ivdt2" contains values that violate the new constraint +err_detail | +err_datatype | +err_schema | public +err_table | ivdt2 +err_column | n +err_constraint | + +DROP TABLE ivdt1, ivdt2; +DROP DOMAIN ivd1, ivd2; +-- table check +CREATE TABLE ivct1 (n int, CHECK (n < 5)); +SELECT * FROM integrity_error_record($$ + INSERT INTO ivct1 VALUES (10); +$$); +err_sqlstate | 23514 +err_message | new row for relation "ivct1" violates check constraint "ivct1_n_check" +err_detail | Failing row contains (10). +err_datatype | +err_schema | public +err_table | ivct1 +err_column | +err_constraint | ivct1_n_check + +-- alter table check +CREATE TABLE ivct2 (n int); +INSERT INTO ivct2 VALUES (10); +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivct2 ADD CHECK (n < 5); +$$); +err_sqlstate | 23514 +err_message | check constraint "ivct2_n_check" of relation "ivct2" is violated by some row +err_detail | +err_datatype | +err_schema | public +err_table | ivct2 +err_column | +err_constraint | ivct2_n_check + +-- alter table validate check +ALTER TABLE ivct2 ADD CONSTRAINT ivct2_check CHECK (n < 5) NOT VALID; +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivct2 VALIDATE CONSTRAINT ivct2_check; +$$); +err_sqlstate | 23514 +err_message | check constraint "ivct2_check" of relation "ivct2" is violated by some row +err_detail | +err_datatype | +err_schema | public +err_table | ivct2 +err_column | +err_constraint | ivct2_check + +DROP TABLE ivct1, ivct2; +-- no partitions +CREATE TABLE ivpt1 (x int, y int, PRIMARY KEY (x, y)) PARTITION BY RANGE (y); +SELECT * FROM integrity_error_record($$ + INSERT INTO ivpt1 VALUES (10, 10); +$$); +err_sqlstate | 23514 +err_message | no partition of relation "ivpt1" found for row +err_detail | Partition key of the failing row contains (y) = (10). +err_datatype | +err_schema | +err_table | +err_column | +err_constraint | + +-- partition constraint +CREATE TABLE ivpt1_p1 PARTITION OF ivpt1 FOR VALUES FROM (1) TO (5); +SELECT * FROM integrity_error_record($$ + INSERT INTO ivpt1 VALUES (10, 10); +$$); +err_sqlstate | 23514 +err_message | no partition of relation "ivpt1" found for row +err_detail | Partition key of the failing row contains (y) = (10). +err_datatype | +err_schema | +err_table | +err_column | +err_constraint | + +SELECT * FROM integrity_error_record($$ + INSERT INTO ivpt1_p1 VALUES (10, 10); +$$); +err_sqlstate | 23514 +err_message | new row for relation "ivpt1_p1" violates partition constraint +err_detail | Failing row contains (10, 10). +err_datatype | +err_schema | +err_table | +err_column | +err_constraint | + +-- alter partition constraint +CREATE TABLE ivpt1_p2 (LIKE ivpt1); +INSERT INTO ivpt1_p2 VALUES (10, 10); +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivpt1 ATTACH PARTITION ivpt1_p2 FOR VALUES FROM (6) TO (10); +$$); +err_sqlstate | 23514 +err_message | partition constraint of relation "ivpt1_p2" is violated by some row +err_detail | +err_datatype | +err_schema | +err_table | +err_column | +err_constraint | + +-- conflict with default partition +CREATE TABLE ivpt1_default PARTITION OF ivpt1 DEFAULT; +INSERT INTO ivpt1 VALUES (10, 10); +SELECT * FROM integrity_error_record($$ + CREATE TABLE ivpt1_p3 PARTITION OF ivpt1 FOR VALUES FROM (10) TO (20); +$$); +err_sqlstate | 23514 +err_message | updated partition constraint for default partition "ivpt1_default" would be violated by some row +err_detail | +err_datatype | +err_schema | +err_table | +err_column | +err_constraint | + +CREATE TABLE ivpt1_p3 (LIKE ivpt1); +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivpt1 ATTACH PARTITION ivpt1_p3 FOR VALUES FROM (10) TO (20); +$$); +err_sqlstate | 23514 +err_message | updated partition constraint for default partition "ivpt1_default" would be violated by some row +err_detail | +err_datatype | +err_schema | +err_table | +err_column | +err_constraint | + +-- partition foreign key reference +CREATE TABLE ivpt2 (x int, y int, FOREIGN KEY (x, y) REFERENCES ivpt1); +INSERT INTO ivpt2 VALUES (10, 10); +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivpt1 DETACH PARTITION ivpt1_default; +$$); +err_sqlstate | 23503 +err_message | removing partition "ivpt1_default" violates foreign key constraint "ivpt2_x_y_fkey2" +err_detail | Key (x, y)=(10, 10) is still referenced from table "ivpt2". +err_datatype | +err_schema | +err_table | +err_column | +err_constraint | + +DROP TABLE ivpt1, ivpt1_p2, ivpt1_p2, ivpt1_p3, ivpt2; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index d2b17dd3ea..4fc2b0b467 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -55,7 +55,7 @@ test: create_index create_index_spgist create_view index_including index_includi # ---------- # Another group of parallel tests # ---------- -test: create_aggregate create_function_3 create_cast constraints triggers select inherit typed_table vacuum drop_if_exists updatable_views roleattributes create_am hash_func errors +test: create_aggregate create_function_3 create_cast constraints triggers select inherit typed_table vacuum drop_if_exists updatable_views roleattributes create_am hash_func errors integrity_errors # ---------- # sanity_check does a vacuum, affecting the sort order of SELECT * diff --git a/src/test/regress/sql/integrity_errors.sql b/src/test/regress/sql/integrity_errors.sql new file mode 100644 index 0000000000..1616d216ff --- /dev/null +++ b/src/test/regress/sql/integrity_errors.sql @@ -0,0 +1,193 @@ +-- +-- Tests for integrity violation error fields +-- +-- Errors in SQLSTATE class 23 (integrity constraint violation) should +-- include the name of a database object as a separate field. +-- +-- The fields of interest are shown at the same verbosity level as +-- volatile details such as source code line numbers. To produce stable +-- regression output, the following function returns a portion of the +-- full error reported. +CREATE FUNCTION integrity_error_record( + dml text, + OUT err_sqlstate text, + OUT err_message text, + OUT err_detail text, + OUT err_datatype text, + OUT err_schema text, + OUT err_table text, + OUT err_column text, + OUT err_constraint text) +AS $$ +BEGIN + EXECUTE $1; +EXCEPTION + WHEN integrity_constraint_violation THEN GET STACKED DIAGNOSTICS + err_sqlstate := RETURNED_SQLSTATE, + err_message := MESSAGE_TEXT, + err_detail := PG_EXCEPTION_DETAIL, + err_datatype := PG_DATATYPE_NAME, + err_schema := SCHEMA_NAME, + err_table := TABLE_NAME, + err_column := COLUMN_NAME, + err_constraint := CONSTRAINT_NAME; +END; +$$ LANGUAGE plpgsql; + +\pset expanded on +\pset tuples_only on + +-- table not null +CREATE TABLE ivnt1 (n int NOT NULL); +SELECT * FROM integrity_error_record($$ + INSERT INTO ivnt1 VALUES (NULL); +$$); + +-- alter table not null +CREATE TABLE ivnt2 (n int); +INSERT INTO ivnt2 VALUES (NULL); +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivnt2 ALTER n SET NOT NULL; +$$); +DROP TABLE ivnt1, ivnt2; + +-- table unique +CREATE TABLE ivpkt1 (x int, y int, PRIMARY KEY (x, y)); +INSERT INTO ivpkt1 VALUES (1, 2); +SELECT * FROM integrity_error_record($$ + INSERT INTO ivpkt1 VALUES (1, 2); +$$); + +-- alter table unique +CREATE TABLE ivpkt2 (x int, y int); +INSERT INTO ivpkt2 VALUES (1, 2), (1, 2); +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivpkt2 ADD PRIMARY KEY (x, y); +$$); + +-- table foreign key reference +CREATE TABLE ivfkt1 (x int, y int, FOREIGN KEY (x, y) REFERENCES ivpkt1); +SELECT * FROM integrity_error_record($$ + INSERT INTO ivfkt1 VALUES (10, 10); +$$); +INSERT INTO ivfkt1 VALUES (1, 2); +SELECT * FROM integrity_error_record($$ + DELETE FROM ivpkt1; +$$); + +-- foreign key reference match full +CREATE TABLE ivfkt2 (x int, y int, FOREIGN KEY (x, y) REFERENCES ivpkt1 MATCH FULL); +SELECT * FROM integrity_error_record($$ + INSERT INTO ivfkt2 VALUES (1, NULL); +$$); +CREATE TABLE ivfkt3 (x int, y int); +INSERT INTO ivfkt3 VALUES (1, NULL); +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivfkt3 ADD FOREIGN KEY (x, y) REFERENCES ivpkt1 MATCH FULL; +$$); +DROP TABLE ivfkt1, ivfkt2, ivfkt3, ivpkt1, ivpkt2; + +-- table exclusion +CREATE TABLE ivet1 (n int, EXCLUDE (n WITH =)); +INSERT INTO ivet1 VALUES (1); +SELECT * FROM integrity_error_record($$ + INSERT INTO ivet1 VALUES (1); +$$); + +-- alter table exclusion +CREATE TABLE ivet2 (n int); +INSERT INTO ivet2 VALUES (1), (1); +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivet2 ADD EXCLUDE (n WITH =); +$$); +DROP TABLE ivet1, ivet2; + +-- domain +CREATE DOMAIN ivd1 int NOT NULL CHECK (VALUE < 5); +CREATE TABLE ivdt1 (n ivd1); +SELECT * FROM integrity_error_record($$ + SELECT NULL::ivd1; +$$); +SELECT * FROM integrity_error_record($$ + SELECT 10::ivd1; +$$); +SELECT * FROM integrity_error_record($$ + SELECT json_populate_record(NULL::ivdt1, '{"n":null}'); +$$); +SELECT * FROM integrity_error_record($$ + SELECT json_populate_record(NULL::ivdt1, '{"n":10}'); +$$); + +-- alter domain +CREATE DOMAIN ivd2 int; +CREATE TABLE ivdt2 (n ivd2); +INSERT INTO ivdt2 VALUES (NULL), (10); +SELECT * FROM integrity_error_record($$ + ALTER DOMAIN ivd2 SET NOT NULL; +$$); +SELECT * FROM integrity_error_record($$ + ALTER DOMAIN ivd2 ADD CHECK (VALUE < 5); +$$); +DROP TABLE ivdt1, ivdt2; +DROP DOMAIN ivd1, ivd2; + +-- table check +CREATE TABLE ivct1 (n int, CHECK (n < 5)); +SELECT * FROM integrity_error_record($$ + INSERT INTO ivct1 VALUES (10); +$$); + +-- alter table check +CREATE TABLE ivct2 (n int); +INSERT INTO ivct2 VALUES (10); +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivct2 ADD CHECK (n < 5); +$$); + +-- alter table validate check +ALTER TABLE ivct2 ADD CONSTRAINT ivct2_check CHECK (n < 5) NOT VALID; +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivct2 VALIDATE CONSTRAINT ivct2_check; +$$); +DROP TABLE ivct1, ivct2; + +-- no partitions +CREATE TABLE ivpt1 (x int, y int, PRIMARY KEY (x, y)) PARTITION BY RANGE (y); +SELECT * FROM integrity_error_record($$ + INSERT INTO ivpt1 VALUES (10, 10); +$$); + +-- partition constraint +CREATE TABLE ivpt1_p1 PARTITION OF ivpt1 FOR VALUES FROM (1) TO (5); +SELECT * FROM integrity_error_record($$ + INSERT INTO ivpt1 VALUES (10, 10); +$$); +SELECT * FROM integrity_error_record($$ + INSERT INTO ivpt1_p1 VALUES (10, 10); +$$); + +-- alter partition constraint +CREATE TABLE ivpt1_p2 (LIKE ivpt1); +INSERT INTO ivpt1_p2 VALUES (10, 10); +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivpt1 ATTACH PARTITION ivpt1_p2 FOR VALUES FROM (6) TO (10); +$$); + +-- conflict with default partition +CREATE TABLE ivpt1_default PARTITION OF ivpt1 DEFAULT; +INSERT INTO ivpt1 VALUES (10, 10); +SELECT * FROM integrity_error_record($$ + CREATE TABLE ivpt1_p3 PARTITION OF ivpt1 FOR VALUES FROM (10) TO (20); +$$); +CREATE TABLE ivpt1_p3 (LIKE ivpt1); +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivpt1 ATTACH PARTITION ivpt1_p3 FOR VALUES FROM (10) TO (20); +$$); + +-- partition foreign key reference +CREATE TABLE ivpt2 (x int, y int, FOREIGN KEY (x, y) REFERENCES ivpt1); +INSERT INTO ivpt2 VALUES (10, 10); +SELECT * FROM integrity_error_record($$ + ALTER TABLE ivpt1 DETACH PARTITION ivpt1_default; +$$); +DROP TABLE ivpt1, ivpt1_p2, ivpt1_p2, ivpt1_p3, ivpt2; -- 2.11.0
>From 6e65ef7d5cb1f8b722b0fabad8b2e4b0e965563c Mon Sep 17 00:00:00 2001 From: Chris Bandy <bandy.ch...@gmail.com> Date: Fri, 6 Mar 2020 21:02:52 -0600 Subject: [PATCH v6 2/2] Add object names to partition integrity violations All errors of SQLSTATE class 23 should include the name of an object associated with the error. --- src/backend/commands/tablecmds.c | 6 ++++-- src/backend/executor/execMain.c | 3 ++- src/backend/executor/execPartition.c | 3 ++- src/backend/partitioning/partbounds.c | 3 ++- src/backend/utils/adt/ri_triggers.c | 3 ++- src/test/regress/expected/integrity_errors.out | 30 +++++++++++++------------- 6 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 729025470d..8e35c5bd1a 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -5343,12 +5343,14 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) ereport(ERROR, (errcode(ERRCODE_CHECK_VIOLATION), errmsg("updated partition constraint for default partition \"%s\" would be violated by some row", - RelationGetRelationName(oldrel)))); + RelationGetRelationName(oldrel)), + errtable(oldrel))); else ereport(ERROR, (errcode(ERRCODE_CHECK_VIOLATION), errmsg("partition constraint of relation \"%s\" is violated by some row", - RelationGetRelationName(oldrel)))); + RelationGetRelationName(oldrel)), + errtable(oldrel))); } /* Write the tuple out to the new relation */ diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 28130fbc2b..4fdffad6f3 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -1878,7 +1878,8 @@ ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo, (errcode(ERRCODE_CHECK_VIOLATION), errmsg("new row for relation \"%s\" violates partition constraint", RelationGetRelationName(resultRelInfo->ri_RelationDesc)), - val_desc ? errdetail("Failing row contains %s.", val_desc) : 0)); + val_desc ? errdetail("Failing row contains %s.", val_desc) : 0, + errtable(resultRelInfo->ri_RelationDesc))); } /* diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index ef74ad85ff..fb6ce49056 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -346,7 +346,8 @@ ExecFindPartition(ModifyTableState *mtstate, RelationGetRelationName(rel)), val_desc ? errdetail("Partition key of the failing row contains %s.", - val_desc) : 0)); + val_desc) : 0, + errtable(rel))); } if (partdesc->is_leaf[partidx]) diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c index 35953f23fa..4c47f54a57 100644 --- a/src/backend/partitioning/partbounds.c +++ b/src/backend/partitioning/partbounds.c @@ -1366,7 +1366,8 @@ check_default_partition_contents(Relation parent, Relation default_rel, ereport(ERROR, (errcode(ERRCODE_CHECK_VIOLATION), errmsg("updated partition constraint for default partition \"%s\" would be violated by some row", - RelationGetRelationName(default_rel)))); + RelationGetRelationName(default_rel)), + errtable(default_rel))); ResetExprContext(econtext); CHECK_FOR_INTERRUPTS(); diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 4ab7cda110..bb49e80d16 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -2452,7 +2452,8 @@ ri_ReportViolation(const RI_ConstraintInfo *riinfo, NameStr(riinfo->conname)), errdetail("Key (%s)=(%s) is still referenced from table \"%s\".", key_names.data, key_values.data, - RelationGetRelationName(fk_rel)))); + RelationGetRelationName(fk_rel)), + errtableconstraint(fk_rel, NameStr(riinfo->conname)))); else if (onfk) ereport(ERROR, (errcode(ERRCODE_FOREIGN_KEY_VIOLATION), diff --git a/src/test/regress/expected/integrity_errors.out b/src/test/regress/expected/integrity_errors.out index e75e6b722f..14796a99c9 100644 --- a/src/test/regress/expected/integrity_errors.out +++ b/src/test/regress/expected/integrity_errors.out @@ -316,8 +316,8 @@ err_sqlstate | 23514 err_message | no partition of relation "ivpt1" found for row err_detail | Partition key of the failing row contains (y) = (10). err_datatype | -err_schema | -err_table | +err_schema | public +err_table | ivpt1 err_column | err_constraint | @@ -330,8 +330,8 @@ err_sqlstate | 23514 err_message | no partition of relation "ivpt1" found for row err_detail | Partition key of the failing row contains (y) = (10). err_datatype | -err_schema | -err_table | +err_schema | public +err_table | ivpt1 err_column | err_constraint | @@ -342,8 +342,8 @@ err_sqlstate | 23514 err_message | new row for relation "ivpt1_p1" violates partition constraint err_detail | Failing row contains (10, 10). err_datatype | -err_schema | -err_table | +err_schema | public +err_table | ivpt1_p1 err_column | err_constraint | @@ -357,8 +357,8 @@ err_sqlstate | 23514 err_message | partition constraint of relation "ivpt1_p2" is violated by some row err_detail | err_datatype | -err_schema | -err_table | +err_schema | public +err_table | ivpt1_p2 err_column | err_constraint | @@ -372,8 +372,8 @@ err_sqlstate | 23514 err_message | updated partition constraint for default partition "ivpt1_default" would be violated by some row err_detail | err_datatype | -err_schema | -err_table | +err_schema | public +err_table | ivpt1_default err_column | err_constraint | @@ -385,8 +385,8 @@ err_sqlstate | 23514 err_message | updated partition constraint for default partition "ivpt1_default" would be violated by some row err_detail | err_datatype | -err_schema | -err_table | +err_schema | public +err_table | ivpt1_default err_column | err_constraint | @@ -400,9 +400,9 @@ err_sqlstate | 23503 err_message | removing partition "ivpt1_default" violates foreign key constraint "ivpt2_x_y_fkey2" err_detail | Key (x, y)=(10, 10) is still referenced from table "ivpt2". err_datatype | -err_schema | -err_table | +err_schema | public +err_table | ivpt2 err_column | -err_constraint | +err_constraint | ivpt2_x_y_fkey2 DROP TABLE ivpt1, ivpt1_p2, ivpt1_p2, ivpt1_p3, ivpt2; -- 2.11.0