Error message inconsistency

Started by Simon Riggsalmost 7 years ago30 messages
#1Simon Riggs
simon@2ndquadrant.com
1 attachment(s)

As noted by a PostgreSQL user to me, error messages for NOT NULL
constraints are inconsistent - they do not mention the relation name in the
message, as all other variants of this message do. e.g.

postgres=# create table nn (id integer not null);
CREATE TABLE
postgres=# insert into nn values (NULL);
ERROR: null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null).

postgres=# create table nn2 (id integer check (id is not null));
CREATE TABLE
postgres=# insert into nn2 values (NULL);
ERROR: new row for relation "nn2" violates check constraint "nn2_id_check"
DETAIL: Failing row contains (null).

I propose the attached patch as a fix, changing the wording (of the first
case) to
ERROR: null value in column "id" for relation "nn" violates not-null
constraint

It causes breakage in multiple tests, which is easy to fix once/if we agree
to change.

Thanks

--
Simon Riggs http://www.2ndQuadrant.com/
<http://www.2ndquadrant.com/&gt;
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Attachments:

rationalize_constraint_error_messages.v1.patchapplication/octet-stream; name=rationalize_constraint_error_messages.v1.patchDownload
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 63a34760ee..ab71b85dce 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -1965,8 +1965,9 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
 
 				ereport(ERROR,
 						(errcode(ERRCODE_NOT_NULL_VIOLATION),
-						 errmsg("null value in column \"%s\" violates not-null constraint",
-								NameStr(att->attname)),
+						 errmsg("null value in column \"%s\" of relation \"%s\" violates not-null constraint",
+								NameStr(att->attname),
+								RelationGetRelationName(orig_rel)),
 						 val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
 						 errtablecol(orig_rel, attrChk)));
 			}
#2Fabrízio de Royes Mello
fabriziomello@gmail.com
In reply to: Simon Riggs (#1)
Re: Error message inconsistency

On Fri, Mar 22, 2019 at 2:25 PM Simon Riggs <simon@2ndquadrant.com> wrote:

As noted by a PostgreSQL user to me, error messages for NOT NULL

constraints are inconsistent - they do not mention the relation name in the
message, as all other variants of this message do. e.g.

postgres=# create table nn (id integer not null);
CREATE TABLE
postgres=# insert into nn values (NULL);
ERROR: null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null).

postgres=# create table nn2 (id integer check (id is not null));
CREATE TABLE
postgres=# insert into nn2 values (NULL);
ERROR: new row for relation "nn2" violates check constraint "nn2_id_check"
DETAIL: Failing row contains (null).

I propose the attached patch as a fix, changing the wording (of the first

case) to

ERROR: null value in column "id" for relation "nn" violates not-null

constraint

It causes breakage in multiple tests, which is easy to fix once/if we

agree to change.

I totally agree with that change because I already get some negative
feedback from users about this message too.

Regards,

--
Fabrízio de Royes Mello Timbira - http://www.timbira.com.br/
PostgreSQL: Consultoria, Desenvolvimento, Suporte 24x7 e Treinamento

#3Amit Kapila
amit.kapila16@gmail.com
In reply to: Fabrízio de Royes Mello (#2)
Re: Error message inconsistency

On Sat, Mar 23, 2019 at 4:33 AM Fabrízio de Royes Mello
<fabriziomello@gmail.com> wrote:

On Fri, Mar 22, 2019 at 2:25 PM Simon Riggs <simon@2ndquadrant.com> wrote:

As noted by a PostgreSQL user to me, error messages for NOT NULL constraints are inconsistent - they do not mention the relation name in the message, as all other variants of this message do. e.g.

postgres=# create table nn (id integer not null);
CREATE TABLE
postgres=# insert into nn values (NULL);
ERROR: null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null).

postgres=# create table nn2 (id integer check (id is not null));
CREATE TABLE
postgres=# insert into nn2 values (NULL);
ERROR: new row for relation "nn2" violates check constraint "nn2_id_check"
DETAIL: Failing row contains (null).

I propose the attached patch as a fix, changing the wording (of the first case) to
ERROR: null value in column "id" for relation "nn" violates not-null constraint

I think we are inconsistent for a similar message at a few other
places as well. See, below two messages:

column \"%s\" contains null values
column \"%s\" of table \"%s\" contains null values

If we decide to change this case, then why not change another place
which has a similar symptom?

It causes breakage in multiple tests, which is easy to fix once/if we agree to change.

I totally agree with that change because I already get some negative feedback from users about this message too.

What kind of negative feedback did you get from users? If I see in
the log file, the message is displayed as :

2019-03-24 18:12:49.331 IST [6348] ERROR: null value in column "id"
violates not-null constraint
2019-03-24 18:12:49.331 IST [6348] DETAIL: Failing row contains (null).
2019-03-24 18:12:49.331 IST [6348] STATEMENT: insert into nn values (NULL);

So, it is not difficult to identify the relation.

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#4Greg Steiner
greg.steiner89@gmail.com
In reply to: Amit Kapila (#3)
Re: Error message inconsistency

To me the error message that includes more detail is superior. Even though
you can get the detail from the logs, it seems like it would much more
convenient for it to be reported out via the error to allow
users/applications to identify the problem relation without fetching logs.
I understand if that's not worth breaking numerous tests, though.
Personally, I think consistency here is important enough to warrant it.

On Sun, Mar 24, 2019, 9:02 AM Amit Kapila <amit.kapila16@gmail.com> wrote:

Show quoted text

On Sat, Mar 23, 2019 at 4:33 AM Fabrízio de Royes Mello
<fabriziomello@gmail.com> wrote:

On Fri, Mar 22, 2019 at 2:25 PM Simon Riggs <simon@2ndquadrant.com>

wrote:

As noted by a PostgreSQL user to me, error messages for NOT NULL

constraints are inconsistent - they do not mention the relation name in the
message, as all other variants of this message do. e.g.

postgres=# create table nn (id integer not null);
CREATE TABLE
postgres=# insert into nn values (NULL);
ERROR: null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null).

postgres=# create table nn2 (id integer check (id is not null));
CREATE TABLE
postgres=# insert into nn2 values (NULL);
ERROR: new row for relation "nn2" violates check constraint

"nn2_id_check"

DETAIL: Failing row contains (null).

I propose the attached patch as a fix, changing the wording (of the

first case) to

ERROR: null value in column "id" for relation "nn" violates not-null

constraint

I think we are inconsistent for a similar message at a few other
places as well. See, below two messages:

column \"%s\" contains null values
column \"%s\" of table \"%s\" contains null values

If we decide to change this case, then why not change another place
which has a similar symptom?

It causes breakage in multiple tests, which is easy to fix once/if we

agree to change.

I totally agree with that change because I already get some negative

feedback from users about this message too.

What kind of negative feedback did you get from users? If I see in
the log file, the message is displayed as :

2019-03-24 18:12:49.331 IST [6348] ERROR: null value in column "id"
violates not-null constraint
2019-03-24 18:12:49.331 IST [6348] DETAIL: Failing row contains (null).
2019-03-24 18:12:49.331 IST [6348] STATEMENT: insert into nn values
(NULL);

So, it is not difficult to identify the relation.

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#5Simon Riggs
simon@2ndquadrant.com
In reply to: Amit Kapila (#3)
Re: Error message inconsistency

On Sun, 24 Mar 2019 at 13:02, Amit Kapila <amit.kapila16@gmail.com> wrote:

On Sat, Mar 23, 2019 at 4:33 AM Fabrízio de Royes Mello
<fabriziomello@gmail.com> wrote:

On Fri, Mar 22, 2019 at 2:25 PM Simon Riggs <simon@2ndquadrant.com>

wrote:

As noted by a PostgreSQL user to me, error messages for NOT NULL

constraints are inconsistent - they do not mention the relation name in the
message, as all other variants of this message do. e.g.

postgres=# create table nn (id integer not null);
CREATE TABLE
postgres=# insert into nn values (NULL);
ERROR: null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null).

postgres=# create table nn2 (id integer check (id is not null));
CREATE TABLE
postgres=# insert into nn2 values (NULL);
ERROR: new row for relation "nn2" violates check constraint

"nn2_id_check"

DETAIL: Failing row contains (null).

I propose the attached patch as a fix, changing the wording (of the

first case) to

ERROR: null value in column "id" for relation "nn" violates not-null

constraint

I think we are inconsistent for a similar message at a few other
places as well. See, below two messages:

column \"%s\" contains null values
column \"%s\" of table \"%s\" contains null values

If we decide to change this case, then why not change another place
which has a similar symptom?

Yes, lets do that.

I'm passing on feedback, so if it applies in other cases, I'm happy to
change other common cases also for the benefit of users.

Do you have a list of cases you'd like to see changed?

It causes breakage in multiple tests, which is easy to fix once/if we

agree to change.

I totally agree with that change because I already get some negative

feedback from users about this message too.

What kind of negative feedback did you get from users? If I see in
the log file, the message is displayed as :

2019-03-24 18:12:49.331 IST [6348] ERROR: null value in column "id"
violates not-null constraint
2019-03-24 18:12:49.331 IST [6348] DETAIL: Failing row contains (null).
2019-03-24 18:12:49.331 IST [6348] STATEMENT: insert into nn values
(NULL);

So, it is not difficult to identify the relation.

The user is not shown the failing statement, and if they are, it might have
been generated for them.

Your example assumes the user has access to the log, that
log_min_error_statement is set appropriately and that the user can locate
their log entries to identify the table name. The log contains timed
entries but the user may not be aware of the time of the error accurately
enough to locate the correct statement amongst many others.

If the statement is modified by triggers or rules, then you have no chance.

e.g. add this to the above example:

create or replace rule rr as on insert to nn2 do instead insert into nn
values (new.*);

and its clear that the LOG of the statement, even if it is visible, is
misleading since the SQL refers to table nn, but the error is generated by
the insert into table nn2.

--
Simon Riggs http://www.2ndQuadrant.com/
<http://www.2ndquadrant.com/&gt;
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#6Amit Kapila
amit.kapila16@gmail.com
In reply to: Simon Riggs (#5)
Re: Error message inconsistency

On Sun, Mar 24, 2019 at 11:53 PM Simon Riggs <simon@2ndquadrant.com> wrote:

On Sun, 24 Mar 2019 at 13:02, Amit Kapila <amit.kapila16@gmail.com> wrote:

I think we are inconsistent for a similar message at a few other
places as well. See, below two messages:

column \"%s\" contains null values
column \"%s\" of table \"%s\" contains null values

If we decide to change this case, then why not change another place
which has a similar symptom?

Yes, lets do that.

I'm passing on feedback, so if it applies in other cases, I'm happy to change other common cases also for the benefit of users.

Do you have a list of cases you'd like to see changed?

I think we can once scrutinize all the error messages with error codes
ERRCODE_NOT_NULL_VIOLATION and ERRCODE_CHECK_VIOLATION to see if
anything else need change.

It causes breakage in multiple tests, which is easy to fix once/if we agree to change.

I totally agree with that change because I already get some negative feedback from users about this message too.

What kind of negative feedback did you get from users? If I see in
the log file, the message is displayed as :

2019-03-24 18:12:49.331 IST [6348] ERROR: null value in column "id"
violates not-null constraint
2019-03-24 18:12:49.331 IST [6348] DETAIL: Failing row contains (null).
2019-03-24 18:12:49.331 IST [6348] STATEMENT: insert into nn values (NULL);

So, it is not difficult to identify the relation.

The user is not shown the failing statement, and if they are, it might have been generated for them.

I can imagine that in some cases where queries/statements are
generated for some application, they might be presented just with
errors that occurred while execution and now it will be difficult to
identify the relation for which that problem has occurred.

Your example assumes the user has access to the log, that log_min_error_statement is set appropriately and that the user can locate their log entries to identify the table name. The log contains timed entries but the user may not be aware of the time of the error accurately enough to locate the correct statement amongst many others.

If the statement is modified by triggers or rules, then you have no chance.

e.g. add this to the above example:

create or replace rule rr as on insert to nn2 do instead insert into nn values (new.*);

and its clear that the LOG of the statement, even if it is visible, is misleading since the SQL refers to table nn, but the error is generated by the insert into table nn2.

This example also indicates that it will be helpful for users to see
the relation name in the error message.

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#7Amit Kapila
amit.kapila16@gmail.com
In reply to: Greg Steiner (#4)
Re: Error message inconsistency

On Sun, Mar 24, 2019 at 7:11 PM Greg Steiner <greg.steiner89@gmail.com> wrote:

To me the error message that includes more detail is superior. Even though you can get the detail from the logs, it seems like it would much more convenient for it to be reported out via the error to allow users/applications to identify the problem relation without fetching logs. I understand if that's not worth breaking numerous tests, though.

Yeah, I think that is the main point. There will be a quite some
churn in the regression test output, but OTOH, if it is for good of
users, then it might be worth.

Personally, I think consistency here is important enough to warrant it.

Fair point. Can such an error message change break any application?
I see some cases where users have check based on Error Code, but not
sure if there are people who have check based on error messages.

Anyone else having an opinion on this matter? Basically, I would like
to hear if anybody thinks that this change can cause any sort of
problem.

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#8Robert Haas
robertmhaas@gmail.com
In reply to: Amit Kapila (#7)
Re: Error message inconsistency

On Sun, Mar 24, 2019 at 11:23 PM Amit Kapila <amit.kapila16@gmail.com> wrote:

Fair point. Can such an error message change break any application?
I see some cases where users have check based on Error Code, but not
sure if there are people who have check based on error messages.

I'm sure there are -- in fact, I've written code that does that. But
I also don't think that's a reason not to improve the error messages.
If we start worrying about stuff like this, we'll be unable to ever
improve anything.

Anyone else having an opinion on this matter? Basically, I would like
to hear if anybody thinks that this change can cause any sort of
problem.

I don't think it's going to cause a problem for users, provided the
patch is correct. I wondered whether it was always going to pick up
the relation name, e.g. if partitioning is involved, but I didn't
check into it at all, so it may be fine.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

#9Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Amit Kapila (#6)
Re: Error message inconsistency

Do we have an actual patch here?

--
�lvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#10Amit Kapila
amit.kapila16@gmail.com
In reply to: Alvaro Herrera (#9)
Re: Error message inconsistency

On Mon, Jul 1, 2019 at 10:05 PM Alvaro Herrera <alvherre@2ndquadrant.com> wrote:

Do we have an actual patch here?

We have a patch, but it needs some more work like finding similar
places and change all of them at the same time and then change the
tests to adapt the same.

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#11Mahendra Singh Thalor
mahi6run@gmail.com
In reply to: Amit Kapila (#10)
1 attachment(s)
Re: Error message inconsistency

On Sat, 6 Jul 2019 at 09:53, Amit Kapila <amit.kapila16@gmail.com> wrote:

On Mon, Jul 1, 2019 at 10:05 PM Alvaro Herrera <alvherre@2ndquadrant.com>

wrote:

Do we have an actual patch here?

We have a patch, but it needs some more work like finding similar
places and change all of them at the same time and then change the
tests to adapt the same.

Hi all,
Based on above discussion, I tried to find out all the places where we need
to change error for "not null constraint". As Amit Kapila pointed out 1
place, I changed the error and adding modified patch.

*What does this patch? *
Before this patch, to display error of "not-null constraint", we were not
displaying relation name in some cases so attached patch is adding relation
name with the "not-null constraint" error in 2 places. I didn't changed out
files of test suite as we haven't finalized error messages.

I verified Robert's point of for partition tables also. With the error, we
are adding relation name of "child table" and i think, it is correct.

Please review attached patch and let me know feedback.

Thanks and Regards
Mahendra Singh Thalor
EnterpriseDB: http://www.enterprisedb.com

Attachments:

rationalize_constraint_error_messages_v2.patchapplication/octet-stream; name=rationalize_constraint_error_messages_v2.patchDownload
commit 0d6619694bb4c20b9f006d5f71af61d5ddb4c2d7
Author: Mahendra Singh Thalor <mahi6run@gmail.com>
Date:   Mon Jan 6 18:14:40 2020 +0530

    Added table name in "not-null constrain" error

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 1c4394a..c683673 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -5007,8 +5007,9 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 
 					ereport(ERROR,
 							(errcode(ERRCODE_NOT_NULL_VIOLATION),
-							 errmsg("column \"%s\" contains null values",
-									NameStr(attr->attname)),
+							 errmsg("column \"%s\" of relation \"%s\" contains null values",
+									NameStr(attr->attname),
+									RelationGetRelationName(oldrel)),
 							 errtablecol(oldrel, attn + 1)));
 				}
 			}
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 4181a7e..f787ead 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -1957,8 +1957,9 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
 
 				ereport(ERROR,
 						(errcode(ERRCODE_NOT_NULL_VIOLATION),
-						 errmsg("null value in column \"%s\" violates not-null constraint",
-								NameStr(att->attname)),
+						 errmsg("null value in column \"%s\" of relation \"%s\" violates not-null constraint",
+								NameStr(att->attname),
+								RelationGetRelationName(orig_rel)),
 						 val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
 						 errtablecol(orig_rel, attrChk)));
 			}
#12MBeena Emerson
mbeena.emerson@gmail.com
In reply to: Mahendra Singh Thalor (#11)
Re: Error message inconsistency

Hi Mahendra,

Thanks for the patch.
I am not sure but maybe the relation name should also be added to the
following test case?

create table t4 (id int);
insert into t4 values (1);
ALTER TABLE t4 ADD CONSTRAINT c1 CHECK (id > 10) NOT VALID; -- succeeds
ALTER TABLE t4 VALIDATE CONSTRAINT c1;
*ERROR: check constraint "c1" is violated by some row*

On Mon, 6 Jan 2020 at 18:31, Mahendra Singh Thalor <mahi6run@gmail.com>
wrote:

On Sat, 6 Jul 2019 at 09:53, Amit Kapila <amit.kapila16@gmail.com> wrote:

On Mon, Jul 1, 2019 at 10:05 PM Alvaro Herrera <alvherre@2ndquadrant.com>

wrote:

Do we have an actual patch here?

We have a patch, but it needs some more work like finding similar
places and change all of them at the same time and then change the
tests to adapt the same.

Hi all,
Based on above discussion, I tried to find out all the places where we
need to change error for "not null constraint". As Amit Kapila pointed out
1 place, I changed the error and adding modified patch.

*What does this patch? *
Before this patch, to display error of "not-null constraint", we were not
displaying relation name in some cases so attached patch is adding relation
name with the "not-null constraint" error in 2 places. I didn't changed out
files of test suite as we haven't finalized error messages.

I verified Robert's point of for partition tables also. With the error, we
are adding relation name of "child table" and i think, it is correct.

Please review attached patch and let me know feedback.

Thanks and Regards
Mahendra Singh Thalor
EnterpriseDB: http://www.enterprisedb.com

--
--
M Beena Emerson

#13Amit Kapila
amit.kapila16@gmail.com
In reply to: MBeena Emerson (#12)
Re: Error message inconsistency

On Thu, Jan 9, 2020 at 5:42 PM MBeena Emerson <mbeena.emerson@gmail.com> wrote:

Hi Beena,

It is better to reply inline.

Hi Mahendra,

Thanks for the patch.
I am not sure but maybe the relation name should also be added to the following test case?

create table t4 (id int);
insert into t4 values (1);
ALTER TABLE t4 ADD CONSTRAINT c1 CHECK (id > 10) NOT VALID; -- succeeds
ALTER TABLE t4 VALIDATE CONSTRAINT c1;
ERROR: check constraint "c1" is violated by some row

I see that in this case, we are using errtableconstraint which should
set table/schema name, but then that doesn't seem to be used. Can we
explore it a bit from that angle?

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#14Amit Kapila
amit.kapila16@gmail.com
In reply to: Mahendra Singh Thalor (#11)
Re: Error message inconsistency

On Mon, Jan 6, 2020 at 6:31 PM Mahendra Singh Thalor <mahi6run@gmail.com> wrote:

On Sat, 6 Jul 2019 at 09:53, Amit Kapila <amit.kapila16@gmail.com> wrote:

On Mon, Jul 1, 2019 at 10:05 PM Alvaro Herrera <alvherre@2ndquadrant.com> wrote:

Do we have an actual patch here?

We have a patch, but it needs some more work like finding similar
places and change all of them at the same time and then change the
tests to adapt the same.

Hi all,
Based on above discussion, I tried to find out all the places where we need to change error for "not null constraint". As Amit Kapila pointed out 1 place, I changed the error and adding modified patch.

It seems you have not used the two error codes
(ERRCODE_NOT_NULL_VIOLATION and ERRCODE_CHECK_VIOLATION) pointed by me
above.

What does this patch?
Before this patch, to display error of "not-null constraint", we were not displaying relation name in some cases so attached patch is adding relation name with the "not-null constraint" error in 2 places. I didn't changed out files of test suite as we haven't finalized error messages.

I verified Robert's point of for partition tables also. With the error, we are adding relation name of "child table" and i think, it is correct.

Can you show the same with the help of an example?

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#15MBeena Emerson
mbeena.emerson@gmail.com
In reply to: Amit Kapila (#13)
Re: Error message inconsistency

Hi Amit,

On Tue, 21 Jan 2020 at 10:49, Amit Kapila <amit.kapila16@gmail.com> wrote:

On Thu, Jan 9, 2020 at 5:42 PM MBeena Emerson <mbeena.emerson@gmail.com>
wrote:

Hi Beena,

It is better to reply inline.

Hi Mahendra,

Thanks for the patch.
I am not sure but maybe the relation name should also be added to the

following test case?

create table t4 (id int);
insert into t4 values (1);
ALTER TABLE t4 ADD CONSTRAINT c1 CHECK (id > 10) NOT VALID; -- succeeds
ALTER TABLE t4 VALIDATE CONSTRAINT c1;
ERROR: check constraint "c1" is violated by some row

I see that in this case, we are using errtableconstraint which should
set table/schema name, but then that doesn't seem to be used. Can we
explore it a bit from that angle?

The usage of the function errtableconstraint seems only to set the
schema_name table_name constraint_name internally and not for display
purposes. As seen in the following two cases where the relation name is
displayed using RelationGetRelationName and errtableconstraint is called as
part of errcode parameter not errmsg.

ereport(ERROR,
(errcode(ERRCODE_CHECK_VIOLATION),
errmsg("new row for relation \"%s\" violates check
constraint \"%s\"",
RelationGetRelationName(orig_rel), failed),
val_desc ? errdetail("Failing row contains %s.",
val_desc) : 0,
errtableconstraint(orig_rel, failed)));

ereport(ERROR,
(errcode(ERRCODE_UNIQUE_VIOLATION),
errmsg("duplicate key value violates
unique constraint \"%s\"",
RelationGetRelationName(rel)),
key_desc ? errdetail("Key %s already
exists.",
key_desc) : 0,
errtableconstraint(heapRel,

RelationGetRelationName(rel))));

--
M Beena Emerson

EnterpriseDB: http://www.enterprisedb.com

#16Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: MBeena Emerson (#15)
Re: Error message inconsistency

On 2020-Jan-21, MBeena Emerson wrote:

The usage of the function errtableconstraint seems only to set the
schema_name table_name constraint_name internally and not for display
purposes. As seen in the following two cases where the relation name is
displayed using RelationGetRelationName and errtableconstraint is called as
part of errcode parameter not errmsg.

You can see those fields by raising the log verbosity; it's a
client-side thing. For example, in psql you can use
\set VERBOSITY verbose

In psql you can also use \errverbose after an error to print those
fields.

--
�lvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#17Mahendra Singh Thalor
mahi6run@gmail.com
In reply to: Alvaro Herrera (#16)
Re: Error message inconsistency

On Tue, 21 Jan 2020 at 20:09, Alvaro Herrera <alvherre@2ndquadrant.com> wrote:

On 2020-Jan-21, MBeena Emerson wrote:

The usage of the function errtableconstraint seems only to set the
schema_name table_name constraint_name internally and not for display
purposes. As seen in the following two cases where the relation name is
displayed using RelationGetRelationName and errtableconstraint is called as
part of errcode parameter not errmsg.

You can see those fields by raising the log verbosity; it's a
client-side thing. For example, in psql you can use
\set VERBOSITY verbose

In psql you can also use \errverbose after an error to print those
fields.

Thanks for the explanation.

--
Thanks and Regards
Mahendra Singh Thalor
EnterpriseDB: http://www.enterprisedb.com

#18Mahendra Singh Thalor
mahi6run@gmail.com
In reply to: Amit Kapila (#14)
1 attachment(s)
Re: Error message inconsistency

On Tue, 21 Jan 2020 at 10:51, Amit Kapila <amit.kapila16@gmail.com> wrote:

On Mon, Jan 6, 2020 at 6:31 PM Mahendra Singh Thalor <mahi6run@gmail.com>

wrote:

On Sat, 6 Jul 2019 at 09:53, Amit Kapila <amit.kapila16@gmail.com>

wrote:

On Mon, Jul 1, 2019 at 10:05 PM Alvaro Herrera <

alvherre@2ndquadrant.com> wrote:

Do we have an actual patch here?

We have a patch, but it needs some more work like finding similar
places and change all of them at the same time and then change the
tests to adapt the same.

Hi all,
Based on above discussion, I tried to find out all the places where we

need to change error for "not null constraint". As Amit Kapila pointed out
1 place, I changed the error and adding modified patch.

It seems you have not used the two error codes
(ERRCODE_NOT_NULL_VIOLATION and ERRCODE_CHECK_VIOLATION) pointed by me
above.

Thanks Amit and Beena for reviewing patch.

Yes, you are correct. I searched using error messages not error code. That
was my mistake. Now, I grepped using above error codes and found that
these error codes are used in 19 places. Below is the code parts of 19
places.

1. src/backend/utils/adt/domains.c

- 146 if (isnull)
- 147 ereport(ERROR,
- 148 (errcode(ERRCODE_NOT_NULL_VIOLATION),
- 149 errmsg("domain %s does not allow null
values",
- 150
format_type_be(my_extra->domain_type)),
- 151 errdatatype(my_extra->domain_type)));
- 152 break;

I think, above error is for domain, so there is no need to add anything in
error message.
-----------------------------------------------------------------------------------------------------
2. src/backend/utils/adt/domains.c

- 181 if (!ExecCheck(con->check_exprstate,
econtext))
- 182 ereport(ERROR,
- 183 (errcode(ERRCODE_CHECK_VIOLATION),
- 184 errmsg("value for domain %s
violates check constraint \"%s\"",
- 185
format_type_be(my_extra->domain_type),
- 186 con->name),
- 187
errdomainconstraint(my_extra->domain_type,
- 188 con->name)));

I think, above error is for domain, so there is no need to add anything in
error message.
-----------------------------------------------------------------------------------------------------
3. src/backend/partitioning/partbounds.c

- 1330 if (part_rel->rd_rel->relkind ==
RELKIND_FOREIGN_TABLE)
- 1331 ereport(WARNING,
- 1332 (errcode(ERRCODE_CHECK_VIOLATION),
- 1333 errmsg("skipped scanning foreign table
\"%s\" which is a partition of default partition \"%s\"",
- 1334 RelationGetRelationName(part_rel),
- 1335
RelationGetRelationName(default_rel))));

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------
4. src/backend/partitioning/partbounds.c

- 1363 if (!ExecCheck(partqualstate, econtext))
- 1364 ereport(ERROR,
- 1365 (errcode(ERRCODE_CHECK_VIOLATION),
- 1366 errmsg("updated partition constraint for
default partition \"%s\" would be violated by some row",
- 1367
RelationGetRelationName(default_rel))));

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------
5. src/backend/executor/execPartition.c

- 342 ereport(ERROR,
- 343 (errcode(ERRCODE_CHECK_VIOLATION),
- 344 errmsg("no partition of relation \"%s\"
found for row",
- 345 RelationGetRelationName(rel)),
- 346 val_desc ?
- 347 errdetail("Partition key of the failing row
contains %s.",
- 348 val_desc) : 0));

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------
6. src/backend/executor/execMain.c

- 1877 ereport(ERROR,
- 1878 (errcode(ERRCODE_CHECK_VIOLATION),
- 1879 errmsg("new row for relation \"%s\" violates
partition constraint",
- 1880
RelationGetRelationName(resultRelInfo->ri_RelationDesc)),
- 1881 val_desc ? errdetail("Failing row contains %s.",
val_desc) : 0));

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------
7. src/backend/executor/execMain.c

- 1958 ereport(ERROR,
- 1959 (errcode(ERRCODE_NOT_NULL_VIOLATION),
- 1960 errmsg("null value in column \"%s\"
violates not-null constraint",
- 1961 NameStr(att->attname)),
- 1962 val_desc ? errdetail("Failing row
contains %s.", val_desc) : 0,
- 1963 errtablecol(orig_rel, attrChk)));

Added relation name for this error. This can be verified by below example:
*Ex:*
CREATE TABLE test (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a,
0)) STORED NOT NULL);
INSERT INTO test (a) VALUES (1);
INSERT INTO test (a) VALUES (0);

*Without patch:*
ERROR: null value in column "b" violates not-null constraint
DETAIL: Failing row contains (0, null).
*With patch:*
ERROR: null value in column "b" of relation "test" violates not-null
constraint
DETAIL: Failing row contains (0, null).
-----------------------------------------------------------------------------------------------------
8. src/backend/executor/execMain.c

- 2006 ereport(ERROR,
- 2007 (errcode(ERRCODE_CHECK_VIOLATION),
- 2008 errmsg("new row for relation \"%s\" violates
check constraint \"%s\"",
- 2009 RelationGetRelationName(orig_rel),
failed),
- 2010 val_desc ? errdetail("Failing row contains
%s.", val_desc) : 0,
- 2011 errtableconstraint(orig_rel, failed)));

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------
9. src/backend/executor/execExprInterp.c

- 3600 ereport(ERROR,
- 3601 (errcode(ERRCODE_NOT_NULL_VIOLATION),
- 3602 errmsg("domain %s does not allow null values",
- 3603
format_type_be(op->d.domaincheck.resulttype)),
- 3604 errdatatype(op->d.domaincheck.resulttype)));

I think, above error is for domain, so there is no need to add anything in
error message.
-----------------------------------------------------------------------------------------------------
10. src/backend/executor/execExprInterp.c

- 3615 ereport(ERROR,
- 3616 (errcode(ERRCODE_CHECK_VIOLATION),
- 3617 errmsg("value for domain %s violates check
constraint \"%s\"",
- 3618
format_type_be(op->d.domaincheck.resulttype),
- 3619 op->d.domaincheck.constraintname),
- 3620 errdomainconstraint(op->d.domaincheck.resulttype,
- 3621
op->d.domaincheck.constraintname)));

I think, above error is for domain, so there is no need to add anything in
error message.
-----------------------------------------------------------------------------------------------------
11. src/backend/commands/tablecmds.c

- 5273 ereport(ERROR,
- 5274 (errcode(ERRCODE_NOT_NULL_VIOLATION),
- 5275 errmsg("column \"%s\" contains null
values",
- 5276 NameStr(attr->attname)),
- 5277 errtablecol(oldrel, attn + 1)));

Added relation name for this error. This can be verified by below example:
*Ex:*
CREATE TABLE test (a int);
INSERT INTO test VALUES (0), (1);
ALTER TABLE test ADD COLUMN b int NOT NULL, ALTER COLUMN b ADD GENERATED
ALWAYS AS IDENTITY;

*Without patch:*
ERROR: column "b" contains null values
*With patch*:
ERROR: column "b" of relation "test" contains null values
-----------------------------------------------------------------------------------------------------
12. src/backend/commands/tablecmds.c

- 5288 if (!ExecCheck(con->qualstate,
econtext))
- 5289 ereport(ERROR,
- 5290
(errcode(ERRCODE_CHECK_VIOLATION),
- 5291 errmsg("check constraint
\"%s\" is violated by some row",
- 5292 con->name),
- 5293 errtableconstraint(oldrel,
con->name)));

Added relation name for this error. This can be verified by below example:
*Ex:*
CREATE TABLE test (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2)
STORED);
INSERT INTO test (a) VALUES (10), (30);
ALTER TABLE test ADD CHECK (b < 50);

*Without patch:*
ERROR: check constraint "test_b_check" is violated by some row
*With patch:*
ERROR: check constraint "test_b_check" of relation "test" is violated by
some row
-----------------------------------------------------------------------------------------------------
13. src/backend/commands/tablecmds.c

- 5306 if (tab->validate_default)
- 5307 ereport(ERROR,
- 5308 (errcode(ERRCODE_CHECK_VIOLATION),
- 5309 errmsg("updated partition
constraint for default partition would be violated by some row")));

Added relation name for this error. This can be verified by below example:
*Ex:*
CREATE TABLE list_parted ( a int, b char ) PARTITION BY LIST (a);
CREATE TABLE list_parted_def PARTITION OF list_parted DEFAULT;
INSERT INTO list_parted_def VALUES (11, 'z');
CREATE TABLE part_1 (LIKE list_parted);
ALTER TABLE list_parted ATTACH PARTITION part_1 FOR VALUES IN (11);

*Without patch:*
ERROR: updated partition constraint for default partition would be
violated by some row
*With patch:*
ERROR: updated partition constraint for default partition
"list_parted_def" would be violated by some row
-----------------------------------------------------------------------------------------------------
14. src/backend/commands/tablecmds.c

- 5310 else
- 5311 ereport(ERROR,
- 5312 (errcode(ERRCODE_CHECK_VIOLATION),
- 5313 errmsg("partition constraint is
violated by some row")));

Added relation name for this error. This can be verified by below example:
*Ex:*
CREATE TABLE list_parted (a int,b char)PARTITION BY LIST (a);
CREATE TABLE part_1 (LIKE list_parted);
INSERT INTO part_1 VALUES (3, 'a');
ALTER TABLE list_parted ATTACH PARTITION part_1 FOR VALUES IN (2);

*Without patch:*
ERROR: partition constraint is violated by some row
*With patch:*
ERROR: partition constraint "part_1" is violated by some row
---------------------------------------------------------------------------
15. src/backend/commands/tablecmds.c

- 10141 ereport(ERROR,
- 10142 (errcode(ERRCODE_CHECK_VIOLATION),
- 10143 errmsg("check constraint \"%s\" is violated
by some row",
- 10144 NameStr(constrForm->conname)),
- 10145 errtableconstraint(rel,
NameStr(constrForm->conname))));

Added relation name for this error. This can be verified by below example:
*Ex:*
CREATE TABLE test (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2)
STORED);
INSERT INTO test (a) VALUES (10), (30);
ALTER TABLE test ADD CONSTRAINT chk CHECK (b < 50) NOT VALID;
ALTER TABLE test VALIDATE CONSTRAINT chk;

*Without patch:*
ERROR: check constraint "chk" is violated by some row
*With patch:*
ERROR: check constraint "chk" of relation "test" is violated by some row
-----------------------------------------------------------------------------------------------------
16. src/backend/commands/typecmds.c

- 2396 ereport(ERROR,
- 2397
(errcode(ERRCODE_NOT_NULL_VIOLATION),
- 2398 errmsg("column \"%s\" of table
\"%s\" contains null values",
- 2399 NameStr(attr->attname),
- 2400
RelationGetRelationName(testrel)),
- 2401 errtablecol(testrel, attnum)));

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------
17. src/backend/commands/typecmds.c

- 2824 ereport(ERROR,
- 2825 (errcode(ERRCODE_CHECK_VIOLATION),
- 2826 errmsg("column \"%s\" of table
\"%s\" contains values that violate the new constraint",
- 2827 NameStr(attr->attname),
- 2828
RelationGetRelationName(testrel)),
- 2829 errtablecol(testrel, attnum)));

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------
18. src/backend/commands/typecmds.c

- 2396 ereport(ERROR,
- 2397
(errcode(ERRCODE_NOT_NULL_VIOLATION),
- 2398 errmsg("column \"%s\" of table
\"%s\" contains null values",
- 2399 NameStr(attr->attname),
- 2400
RelationGetRelationName(testrel)),
- 2401 errtablecol(testrel, attnum)));

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------
19. src/backend/commands/typecmds.c

- 2824 ereport(ERROR,
- 2825 (errcode(ERRCODE_CHECK_VIOLATION),
- 2826 errmsg("column \"%s\" of table
\"%s\" contains values that violate the new constraint",
- 2827 NameStr(attr->attname),
- 2828
RelationGetRelationName(testrel)),
- 2829 errtablecol(testrel, attnum)))

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------

What does this patch?
Before this patch, to display error of "not-null constraint", we were

not displaying relation name in some cases so attached patch is adding
relation name with the "not-null constraint" error in 2 places. I didn't
changed out files of test suite as we haven't finalized error messages.

I verified Robert's point of for partition tables also. With the error,

we are adding relation name of "child table" and i think, it is correct.

Can you show the same with the help of an example?

Okay. Below is the example:
create table parent (a int, b int not null) partition by range (a);
create table ch1 partition of parent for values from ( 10 ) to (20);
postgres=# insert into parent values (9);
ERROR: no partition of relation "parent" found for row
DETAIL: Partition key of the failing row contains (a) = (9).
postgres=# insert into parent values (11);
*ERROR: null value in column "b" of relation "ch1" violates not-null
constraint*
DETAIL: Failing row contains (11, null).

Attaching a patch for review. In this patch, total 6 places I added
relation name in error message and verifyed same with above mentioned
examples.

Please review attahced patch and let me know your feedback. I haven't
modifed .out files because we haven't finalied patch.

--
Thanks and Regards
Mahendra Singh Thalor
EnterpriseDB: http://www.enterprisedb.com

Attachments:

rationalize_constraint_error_messages_v3.patchapplication/octet-stream; name=rationalize_constraint_error_messages_v3.patchDownload
commit 27ede32cd35afc2872152c9edcd91f05feda1fe0
Author: Mahendra Singh Thalor <mahi6run@gmail.com>
Date:   Wed Jan 22 09:47:44 2020 +0530

    fixed error message inconsistancy

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 30b72b6..b0bed6a 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -5272,8 +5272,9 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 
 					ereport(ERROR,
 							(errcode(ERRCODE_NOT_NULL_VIOLATION),
-							 errmsg("column \"%s\" contains null values",
-									NameStr(attr->attname)),
+							 errmsg("column \"%s\" of relation \"%s\" contains null values",
+									NameStr(attr->attname),
+									RelationGetRelationName(oldrel)),
 							 errtablecol(oldrel, attn + 1)));
 				}
 			}
@@ -5288,8 +5289,9 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 						if (!ExecCheck(con->qualstate, econtext))
 							ereport(ERROR,
 									(errcode(ERRCODE_CHECK_VIOLATION),
-									 errmsg("check constraint \"%s\" is violated by some row",
-											con->name),
+									 errmsg("check constraint \"%s\" of relation \"%s\" is violated by some row",
+											con->name,
+											RelationGetRelationName(oldrel)),
 									 errtableconstraint(oldrel, con->name)));
 						break;
 					case CONSTR_FOREIGN:
@@ -5306,11 +5308,13 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 				if (tab->validate_default)
 					ereport(ERROR,
 							(errcode(ERRCODE_CHECK_VIOLATION),
-							 errmsg("updated partition constraint for default partition would be violated by some row")));
+							 errmsg("updated partition constraint for default partition \"%s\" would be violated by some row",
+									RelationGetRelationName(oldrel))));
 				else
 					ereport(ERROR,
 							(errcode(ERRCODE_CHECK_VIOLATION),
-							 errmsg("partition constraint is violated by some row")));
+							 errmsg("partition constraint \"%s\" is violated by some row",
+									RelationGetRelationName(oldrel))));
 			}
 
 			/* Write the tuple out to the new relation */
@@ -10140,8 +10144,9 @@ validateCheckConstraint(Relation rel, HeapTuple constrtup)
 		if (!ExecCheck(exprstate, econtext))
 			ereport(ERROR,
 					(errcode(ERRCODE_CHECK_VIOLATION),
-					 errmsg("check constraint \"%s\" is violated by some row",
-							NameStr(constrForm->conname)),
+					 errmsg("check constraint \"%s\" of relation \"%s\" is violated by some row",
+							NameStr(constrForm->conname),
+							RelationGetRelationName(rel)),
 					 errtableconstraint(rel, NameStr(constrForm->conname))));
 
 		ResetExprContext(econtext);
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index b03e02a..3a9ce99 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -1957,8 +1957,9 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
 
 				ereport(ERROR,
 						(errcode(ERRCODE_NOT_NULL_VIOLATION),
-						 errmsg("null value in column \"%s\" violates not-null constraint",
-								NameStr(att->attname)),
+						 errmsg("null value in column \"%s\" of relation \"%s\" violates not-null constraint",
+								NameStr(att->attname),
+								RelationGetRelationName(orig_rel)),
 						 val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
 						 errtablecol(orig_rel, attrChk)));
 			}
#19MBeena Emerson
mbeena.emerson@gmail.com
In reply to: Mahendra Singh Thalor (#18)
Re: Error message inconsistency

Hi Mahendra,

Thanks for working on this.

On Wed, 22 Jan 2020 at 13:26, Mahendra Singh Thalor <mahi6run@gmail.com> wrote:

On Tue, 21 Jan 2020 at 10:51, Amit Kapila <amit.kapila16@gmail.com> wrote:

On Mon, Jan 6, 2020 at 6:31 PM Mahendra Singh Thalor <mahi6run@gmail.com> wrote:

On Sat, 6 Jul 2019 at 09:53, Amit Kapila <amit.kapila16@gmail.com> wrote:

On Mon, Jul 1, 2019 at 10:05 PM Alvaro Herrera <alvherre@2ndquadrant.com> wrote:

Do we have an actual patch here?

We have a patch, but it needs some more work like finding similar
places and change all of them at the same time and then change the
tests to adapt the same.

Hi all,
Based on above discussion, I tried to find out all the places where we need to change error for "not null constraint". As Amit Kapila pointed out 1 place, I changed the error and adding modified patch.

It seems you have not used the two error codes
(ERRCODE_NOT_NULL_VIOLATION and ERRCODE_CHECK_VIOLATION) pointed by me
above.

Thanks Amit and Beena for reviewing patch.

Yes, you are correct. I searched using error messages not error code. That was my mistake. Now, I grepped using above error codes and found that these error codes are used in 19 places. Below is the code parts of 19 places.

1. src/backend/utils/adt/domains.c

146 if (isnull)
147 ereport(ERROR,
148 (errcode(ERRCODE_NOT_NULL_VIOLATION),
149 errmsg("domain %s does not allow null values",
150 format_type_be(my_extra->domain_type)),
151 errdatatype(my_extra->domain_type)));
152 break;

I think, above error is for domain, so there is no need to add anything in error message.
-----------------------------------------------------------------------------------------------------
2. src/backend/utils/adt/domains.c

181 if (!ExecCheck(con->check_exprstate, econtext))
182 ereport(ERROR,
183 (errcode(ERRCODE_CHECK_VIOLATION),
184 errmsg("value for domain %s violates check constraint \"%s\"",
185 format_type_be(my_extra->domain_type),
186 con->name),
187 errdomainconstraint(my_extra->domain_type,
188 con->name)));

I think, above error is for domain, so there is no need to add anything in error message.
-----------------------------------------------------------------------------------------------------
3. src/backend/partitioning/partbounds.c

1330 if (part_rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
1331 ereport(WARNING,
1332 (errcode(ERRCODE_CHECK_VIOLATION),
1333 errmsg("skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"",
1334 RelationGetRelationName(part_rel),
1335 RelationGetRelationName(default_rel))));

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------
4. src/backend/partitioning/partbounds.c

1363 if (!ExecCheck(partqualstate, econtext))
1364 ereport(ERROR,
1365 (errcode(ERRCODE_CHECK_VIOLATION),
1366 errmsg("updated partition constraint for default partition \"%s\" would be violated by some row",
1367 RelationGetRelationName(default_rel))));

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------
5. src/backend/executor/execPartition.c

342 ereport(ERROR,
343 (errcode(ERRCODE_CHECK_VIOLATION),
344 errmsg("no partition of relation \"%s\" found for row",
345 RelationGetRelationName(rel)),
346 val_desc ?
347 errdetail("Partition key of the failing row contains %s.",
348 val_desc) : 0));

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------
6. src/backend/executor/execMain.c

1877 ereport(ERROR,
1878 (errcode(ERRCODE_CHECK_VIOLATION),
1879 errmsg("new row for relation \"%s\" violates partition constraint",
1880 RelationGetRelationName(resultRelInfo->ri_RelationDesc)),
1881 val_desc ? errdetail("Failing row contains %s.", val_desc) : 0));

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------
7. src/backend/executor/execMain.c

1958 ereport(ERROR,
1959 (errcode(ERRCODE_NOT_NULL_VIOLATION),
1960 errmsg("null value in column \"%s\" violates not-null constraint",
1961 NameStr(att->attname)),
1962 val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
1963 errtablecol(orig_rel, attrChk)));

Added relation name for this error. This can be verified by below example:
Ex:
CREATE TABLE test (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED NOT NULL);
INSERT INTO test (a) VALUES (1);
INSERT INTO test (a) VALUES (0);

Without patch:
ERROR: null value in column "b" violates not-null constraint
DETAIL: Failing row contains (0, null).
With patch:
ERROR: null value in column "b" of relation "test" violates not-null constraint
DETAIL: Failing row contains (0, null).
-----------------------------------------------------------------------------------------------------
8. src/backend/executor/execMain.c

2006 ereport(ERROR,
2007 (errcode(ERRCODE_CHECK_VIOLATION),
2008 errmsg("new row for relation \"%s\" violates check constraint \"%s\"",
2009 RelationGetRelationName(orig_rel), failed),
2010 val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
2011 errtableconstraint(orig_rel, failed)));

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------
9. src/backend/executor/execExprInterp.c

3600 ereport(ERROR,
3601 (errcode(ERRCODE_NOT_NULL_VIOLATION),
3602 errmsg("domain %s does not allow null values",
3603 format_type_be(op->d.domaincheck.resulttype)),
3604 errdatatype(op->d.domaincheck.resulttype)));

I think, above error is for domain, so there is no need to add anything in error message.
-----------------------------------------------------------------------------------------------------
10. src/backend/executor/execExprInterp.c

3615 ereport(ERROR,
3616 (errcode(ERRCODE_CHECK_VIOLATION),
3617 errmsg("value for domain %s violates check constraint \"%s\"",
3618 format_type_be(op->d.domaincheck.resulttype),
3619 op->d.domaincheck.constraintname),
3620 errdomainconstraint(op->d.domaincheck.resulttype,
3621 op->d.domaincheck.constraintname)));

I think, above error is for domain, so there is no need to add anything in error message.
-----------------------------------------------------------------------------------------------------
11. src/backend/commands/tablecmds.c

5273 ereport(ERROR,
5274 (errcode(ERRCODE_NOT_NULL_VIOLATION),
5275 errmsg("column \"%s\" contains null values",
5276 NameStr(attr->attname)),
5277 errtablecol(oldrel, attn + 1)));

Added relation name for this error. This can be verified by below example:
Ex:
CREATE TABLE test (a int);
INSERT INTO test VALUES (0), (1);
ALTER TABLE test ADD COLUMN b int NOT NULL, ALTER COLUMN b ADD GENERATED ALWAYS AS IDENTITY;

Without patch:
ERROR: column "b" contains null values
With patch:
ERROR: column "b" of relation "test" contains null values
-----------------------------------------------------------------------------------------------------
12. src/backend/commands/tablecmds.c

5288 if (!ExecCheck(con->qualstate, econtext))
5289 ereport(ERROR,
5290 (errcode(ERRCODE_CHECK_VIOLATION),
5291 errmsg("check constraint \"%s\" is violated by some row",
5292 con->name),
5293 errtableconstraint(oldrel, con->name)));

Added relation name for this error. This can be verified by below example:
Ex:
CREATE TABLE test (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED);
INSERT INTO test (a) VALUES (10), (30);
ALTER TABLE test ADD CHECK (b < 50);

Without patch:
ERROR: check constraint "test_b_check" is violated by some row
With patch:
ERROR: check constraint "test_b_check" of relation "test" is violated by some row
-----------------------------------------------------------------------------------------------------
13. src/backend/commands/tablecmds.c

5306 if (tab->validate_default)
5307 ereport(ERROR,
5308 (errcode(ERRCODE_CHECK_VIOLATION),
5309 errmsg("updated partition constraint for default partition would be violated by some row")));

Added relation name for this error. This can be verified by below example:
Ex:
CREATE TABLE list_parted ( a int, b char ) PARTITION BY LIST (a);
CREATE TABLE list_parted_def PARTITION OF list_parted DEFAULT;
INSERT INTO list_parted_def VALUES (11, 'z');
CREATE TABLE part_1 (LIKE list_parted);
ALTER TABLE list_parted ATTACH PARTITION part_1 FOR VALUES IN (11);

Without patch:
ERROR: updated partition constraint for default partition would be violated by some row
With patch:
ERROR: updated partition constraint for default partition "list_parted_def" would be violated by some row
-----------------------------------------------------------------------------------------------------
14. src/backend/commands/tablecmds.c

5310 else
5311 ereport(ERROR,
5312 (errcode(ERRCODE_CHECK_VIOLATION),
5313 errmsg("partition constraint is violated by some row")));

Added relation name for this error. This can be verified by below example:
Ex:
CREATE TABLE list_parted (a int,b char)PARTITION BY LIST (a);
CREATE TABLE part_1 (LIKE list_parted);
INSERT INTO part_1 VALUES (3, 'a');
ALTER TABLE list_parted ATTACH PARTITION part_1 FOR VALUES IN (2);

Without patch:
ERROR: partition constraint is violated by some row
With patch:
ERROR: partition constraint "part_1" is violated by some row

Here it seems as if "part_1" is the constraint name. It would be
better to change it to:

partition constraint is violated by some row in relation "part_1" OR
partition constraint of relation "part_1" is violated b some row

---------------------------------------------------------------------------
15. src/backend/commands/tablecmds.c

10141 ereport(ERROR,
10142 (errcode(ERRCODE_CHECK_VIOLATION),
10143 errmsg("check constraint \"%s\" is violated by some row",
10144 NameStr(constrForm->conname)),
10145 errtableconstraint(rel, NameStr(constrForm->conname))));

Added relation name for this error. This can be verified by below example:
Ex:
CREATE TABLE test (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED);
INSERT INTO test (a) VALUES (10), (30);
ALTER TABLE test ADD CONSTRAINT chk CHECK (b < 50) NOT VALID;
ALTER TABLE test VALIDATE CONSTRAINT chk;

Without patch:
ERROR: check constraint "chk" is violated by some row
With patch:
ERROR: check constraint "chk" of relation "test" is violated by some row
-----------------------------------------------------------------------------------------------------
16. src/backend/commands/typecmds.c

2396 ereport(ERROR,
2397 (errcode(ERRCODE_NOT_NULL_VIOLATION),
2398 errmsg("column \"%s\" of table \"%s\" contains null values",
2399 NameStr(attr->attname),
2400 RelationGetRelationName(testrel)),
2401 errtablecol(testrel, attnum)));

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------
17. src/backend/commands/typecmds.c

2824 ereport(ERROR,
2825 (errcode(ERRCODE_CHECK_VIOLATION),
2826 errmsg("column \"%s\" of table \"%s\" contains values that violate the new constraint",
2827 NameStr(attr->attname),
2828 RelationGetRelationName(testrel)),
2829 errtablecol(testrel, attnum)));

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------
18. src/backend/commands/typecmds.c

2396 ereport(ERROR,
2397 (errcode(ERRCODE_NOT_NULL_VIOLATION),
2398 errmsg("column \"%s\" of table \"%s\" contains null values",
2399 NameStr(attr->attname),
2400 RelationGetRelationName(testrel)),
2401 errtablecol(testrel, attnum)));

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------
19. src/backend/commands/typecmds.c

2824 ereport(ERROR,
2825 (errcode(ERRCODE_CHECK_VIOLATION),
2826 errmsg("column \"%s\" of table \"%s\" contains values that violate the new constraint",
2827 NameStr(attr->attname),
2828 RelationGetRelationName(testrel)),
2829 errtablecol(testrel, attnum)))

Relation name is already appended in error messgae.
-----------------------------------------------------------------------------------------------------

What does this patch?
Before this patch, to display error of "not-null constraint", we were not displaying relation name in some cases so attached patch is adding relation name with the "not-null constraint" error in 2 places. I didn't changed out files of test suite as we haven't finalized error messages.

I verified Robert's point of for partition tables also. With the error, we are adding relation name of "child table" and i think, it is correct.

Can you show the same with the help of an example?

Okay. Below is the example:
create table parent (a int, b int not null) partition by range (a);
create table ch1 partition of parent for values from ( 10 ) to (20);
postgres=# insert into parent values (9);
ERROR: no partition of relation "parent" found for row
DETAIL: Partition key of the failing row contains (a) = (9).
postgres=# insert into parent values (11);
ERROR: null value in column "b" of relation "ch1" violates not-null constraint
DETAIL: Failing row contains (11, null).

Attaching a patch for review. In this patch, total 6 places I added relation name in error message and verifyed same with above mentioned examples.

Please review attahced patch and let me know your feedback. I haven't modifed .out files because we haven't finalied patch.

--

M Beena Emerson

EnterpriseDB: http://www.enterprisedb.com

#20Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: MBeena Emerson (#19)
Re: Error message inconsistency

I wonder if we shouldn't be using errtablecol() here instead of (in
addition to?) patching the errmsg() to include the table name.

Discussion: If we really like having the table names in errtable(), then
we should have psql display it by default, and other tools will follow
suit; in that case we should remove the table name from error messages,
or at least not add it to even more messages.

If we instead think that errtable() is there just for programmatically
knowing the affected table, then we should add the table name to all
errmsg() where relevant, as in the patch under discussion.

What do others think?

--
�lvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#21Tom Lane
tgl@sss.pgh.pa.us
In reply to: Alvaro Herrera (#20)
Re: Error message inconsistency

Alvaro Herrera <alvherre@2ndquadrant.com> writes:

I wonder if we shouldn't be using errtablecol() here instead of (in
addition to?) patching the errmsg() to include the table name.

Discussion: If we really like having the table names in errtable(), then
we should have psql display it by default, and other tools will follow
suit; in that case we should remove the table name from error messages,
or at least not add it to even more messages.

If we instead think that errtable() is there just for programmatically
knowing the affected table, then we should add the table name to all
errmsg() where relevant, as in the patch under discussion.

What do others think?

I believe that the intended use of errtable() and friends is so that
applications don't have to parse those names out of a human-friendly
message. We should add calls to them in cases where (a) an application
can tell from the SQLSTATE that some particular table is involved
and (b) it's likely that the app would wish to know which table that is.
I don't feel a need to sprinkle every single ereport() in the backend
with errtable(), just ones where there's a plausible use-case for the
extra cycles that will be spent.

On the other side of the coin, whether we use errtable() is not directly
a factor in deciding what the human-friendly messages should say.
I do find it hard to envision a case where we'd want to use errtable()
and *not* put the table name in the error message, just because if
applications need to know something then humans probably do too. But
saying that we can make the messages omit info because it's available
from these program-friendly fields seems 100% wrong to me, even if one
turns a blind eye to the fact that existing client code likely won't
show those fields to users.

regards, tom lane

#22Amit Kapila
amit.kapila16@gmail.com
In reply to: MBeena Emerson (#19)
Re: Error message inconsistency

On Wed, Jan 22, 2020 at 3:23 PM MBeena Emerson <mbeena.emerson@gmail.com> wrote:

-----------------------------------------------------------------------------------------------------
14. src/backend/commands/tablecmds.c

5310 else
5311 ereport(ERROR,
5312 (errcode(ERRCODE_CHECK_VIOLATION),
5313 errmsg("partition constraint is violated by some row")));

Added relation name for this error. This can be verified by below example:
Ex:
CREATE TABLE list_parted (a int,b char)PARTITION BY LIST (a);
CREATE TABLE part_1 (LIKE list_parted);
INSERT INTO part_1 VALUES (3, 'a');
ALTER TABLE list_parted ATTACH PARTITION part_1 FOR VALUES IN (2);

Without patch:
ERROR: partition constraint is violated by some row
With patch:
ERROR: partition constraint "part_1" is violated by some row

Here it seems as if "part_1" is the constraint name.

I agree.

It would be
better to change it to:

partition constraint is violated by some row in relation "part_1" OR
partition constraint of relation "part_1" is violated b some row

+1 for the second option suggested by Beena.

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#23Amit Kapila
amit.kapila16@gmail.com
In reply to: Tom Lane (#21)
Re: Error message inconsistency

On Wed, Jan 22, 2020 at 8:48 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Alvaro Herrera <alvherre@2ndquadrant.com> writes:

I wonder if we shouldn't be using errtablecol() here instead of (in
addition to?) patching the errmsg() to include the table name.

Discussion: If we really like having the table names in errtable(), then
we should have psql display it by default, and other tools will follow
suit; in that case we should remove the table name from error messages,
or at least not add it to even more messages.

If we instead think that errtable() is there just for programmatically
knowing the affected table, then we should add the table name to all
errmsg() where relevant, as in the patch under discussion.

What do others think?

I believe that the intended use of errtable() and friends is so that
applications don't have to parse those names out of a human-friendly
message. We should add calls to them in cases where (a) an application
can tell from the SQLSTATE that some particular table is involved
and (b) it's likely that the app would wish to know which table that is.
I don't feel a need to sprinkle every single ereport() in the backend
with errtable(), just ones where there's a plausible use-case for the
extra cycles that will be spent.

On the other side of the coin, whether we use errtable() is not directly
a factor in deciding what the human-friendly messages should say.
I do find it hard to envision a case where we'd want to use errtable()
and *not* put the table name in the error message, just because if
applications need to know something then humans probably do too.

makes sense.

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#24Mahendra Singh Thalor
mahi6run@gmail.com
In reply to: Amit Kapila (#23)
3 attachment(s)
Re: Error message inconsistency

On Thu, 23 Jan 2020 at 10:20, Amit Kapila <amit.kapila16@gmail.com> wrote:

On Wed, Jan 22, 2020 at 8:48 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Alvaro Herrera <alvherre@2ndquadrant.com> writes:

I wonder if we shouldn't be using errtablecol() here instead of (in
addition to?) patching the errmsg() to include the table name.

Discussion: If we really like having the table names in errtable(), then
we should have psql display it by default, and other tools will follow
suit; in that case we should remove the table name from error messages,
or at least not add it to even more messages.

If we instead think that errtable() is there just for programmatically
knowing the affected table, then we should add the table name to all
errmsg() where relevant, as in the patch under discussion.

What do others think?

I believe that the intended use of errtable() and friends is so that
applications don't have to parse those names out of a human-friendly
message. We should add calls to them in cases where (a) an application
can tell from the SQLSTATE that some particular table is involved
and (b) it's likely that the app would wish to know which table that is.
I don't feel a need to sprinkle every single ereport() in the backend
with errtable(), just ones where there's a plausible use-case for the
extra cycles that will be spent.

On the other side of the coin, whether we use errtable() is not directly
a factor in deciding what the human-friendly messages should say.
I do find it hard to envision a case where we'd want to use errtable()
and *not* put the table name in the error message, just because if
applications need to know something then humans probably do too.

makes sense.

Thanks all for reviewing and giving comments.

Added relation name for this error. This can be verified by below example:
Ex:
CREATE TABLE list_parted (a int,b char)PARTITION BY LIST (a);
CREATE TABLE part_1 (LIKE list_parted);
INSERT INTO part_1 VALUES (3, 'a');
ALTER TABLE list_parted ATTACH PARTITION part_1 FOR VALUES IN (2);

Without patch:
ERROR: partition constraint is violated by some row
With patch:
ERROR: partition constraint "part_1" is violated by some row

Here it seems as if "part_1" is the constraint name.

I agree.

It would be
better to change it to:

partition constraint is violated by some row in relation "part_1" OR
partition constraint of relation "part_1" is violated b some row

+1 for the second option suggested by Beena.

I fixed above comment and updated expected .out files. Attaching
updated patches.

To make review simple, I made 3 patches as:

v4_0001_rationalize_constraint_error_messages.patch:
This patch has .c file changes. Added relation name in 6 error
messages for check constraint.

v4_0002_updated-regress-expected-.out-files.patch:
This patch has changes of expected .out files for regress test suite.

v4_0003_updated-constraints.source-file.patch:
This patch has changes of .source file for constraints.sql regress test.

Please review attached patches and let me know your comments.

--
Thanks and Regards
Mahendra Singh Thalor
EnterpriseDB: http://www.enterprisedb.com

Attachments:

v4_0001_rationalize_constraint_error_messages.patchapplication/octet-stream; name=v4_0001_rationalize_constraint_error_messages.patchDownload
From 08c89ce460360b13b5cbe62836d67a10627cc14e Mon Sep 17 00:00:00 2001
From: Mahendra Singh Thalor <mahi6run@gmail.com>
Date: Thu, 23 Jan 2020 17:01:53 +0530
Subject: [PATCH 1/3] Added relation name in error messages for constraint
 check

---
 src/backend/commands/tablecmds.c | 21 +++++++++++++--------
 src/backend/executor/execMain.c  |  5 +++--
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 7c23968..70589dd 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -5288,8 +5288,9 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 
 					ereport(ERROR,
 							(errcode(ERRCODE_NOT_NULL_VIOLATION),
-							 errmsg("column \"%s\" contains null values",
-									NameStr(attr->attname)),
+							 errmsg("column \"%s\" of relation \"%s\" contains null values",
+									NameStr(attr->attname),
+									RelationGetRelationName(oldrel)),
 							 errtablecol(oldrel, attn + 1)));
 				}
 			}
@@ -5304,8 +5305,9 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 						if (!ExecCheck(con->qualstate, econtext))
 							ereport(ERROR,
 									(errcode(ERRCODE_CHECK_VIOLATION),
-									 errmsg("check constraint \"%s\" is violated by some row",
-											con->name),
+									 errmsg("check constraint \"%s\" of relation \"%s\" is violated by some row",
+											con->name,
+											RelationGetRelationName(oldrel)),
 									 errtableconstraint(oldrel, con->name)));
 						break;
 					case CONSTR_FOREIGN:
@@ -5322,11 +5324,13 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 				if (tab->validate_default)
 					ereport(ERROR,
 							(errcode(ERRCODE_CHECK_VIOLATION),
-							 errmsg("updated partition constraint for default partition would be violated by some row")));
+							 errmsg("updated partition constraint for default partition \"%s\" would be violated by some row",
+									RelationGetRelationName(oldrel))));
 				else
 					ereport(ERROR,
 							(errcode(ERRCODE_CHECK_VIOLATION),
-							 errmsg("partition constraint is violated by some row")));
+							 errmsg("partition constraint of relation \"%s\" is violated by some row",
+									RelationGetRelationName(oldrel))));
 			}
 
 			/* Write the tuple out to the new relation */
@@ -10160,8 +10164,9 @@ validateCheckConstraint(Relation rel, HeapTuple constrtup)
 		if (!ExecCheck(exprstate, econtext))
 			ereport(ERROR,
 					(errcode(ERRCODE_CHECK_VIOLATION),
-					 errmsg("check constraint \"%s\" is violated by some row",
-							NameStr(constrForm->conname)),
+					 errmsg("check constraint \"%s\" of relation \"%s\" is violated by some row",
+							NameStr(constrForm->conname),
+							RelationGetRelationName(rel)),
 					 errtableconstraint(rel, NameStr(constrForm->conname))));
 
 		ResetExprContext(econtext);
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index b03e02a..3a9ce99 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -1957,8 +1957,9 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
 
 				ereport(ERROR,
 						(errcode(ERRCODE_NOT_NULL_VIOLATION),
-						 errmsg("null value in column \"%s\" violates not-null constraint",
-								NameStr(att->attname)),
+						 errmsg("null value in column \"%s\" of relation \"%s\" violates not-null constraint",
+								NameStr(att->attname),
+								RelationGetRelationName(orig_rel)),
 						 val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
 						 errtablecol(orig_rel, attrChk)));
 			}
-- 
1.8.3.1

v4_0002_updated-regress-expected-.out-files.patchapplication/octet-stream; name=v4_0002_updated-regress-expected-.out-files.patchDownload
From 0f556d3200b58ddf4165b30a1317ce50cc77ee13 Mon Sep 17 00:00:00 2001
From: Mahendra Singh Thalor <mahi6run@gmail.com>
Date: Thu, 23 Jan 2020 17:02:49 +0530
Subject: [PATCH 2/3] updated regress/expected .out files

---
 src/test/regress/expected/alter_table.out       | 76 ++++++++++++-------------
 src/test/regress/expected/copy2.out             |  2 +-
 src/test/regress/expected/create_table.out      |  2 +-
 src/test/regress/expected/create_table_like.out |  2 +-
 src/test/regress/expected/domain.out            |  8 +--
 src/test/regress/expected/generated.out         |  8 +--
 src/test/regress/expected/identity.out          |  4 +-
 src/test/regress/expected/index_including.out   |  4 +-
 src/test/regress/expected/inherit.out           |  6 +-
 src/test/regress/expected/insert.out            |  2 +-
 src/test/regress/expected/privileges.out        |  6 +-
 src/test/regress/expected/reloptions.out        |  4 +-
 src/test/regress/expected/sequence.out          |  2 +-
 src/test/regress/expected/vacuum.out            |  2 +-
 14 files changed, 64 insertions(+), 64 deletions(-)

diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out
index 4dd3507..e73ce4b 100644
--- a/src/test/regress/expected/alter_table.out
+++ b/src/test/regress/expected/alter_table.out
@@ -457,10 +457,10 @@ ALTER TABLE attmp3 validate constraint attmpconstr;
 ALTER TABLE attmp3 validate constraint attmpconstr;
 -- Try a non-verified CHECK constraint
 ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10); -- fail
-ERROR:  check constraint "b_greater_than_ten" is violated by some row
+ERROR:  check constraint "b_greater_than_ten" of relation "attmp3" is violated by some row
 ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10) NOT VALID; -- succeeds
 ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- fails
-ERROR:  check constraint "b_greater_than_ten" is violated by some row
+ERROR:  check constraint "b_greater_than_ten" of relation "attmp3" is violated by some row
 DELETE FROM attmp3 WHERE NOT b > 10;
 ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- succeeds
 ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- succeeds
@@ -476,7 +476,7 @@ CREATE TABLE attmp7 () INHERITS (attmp3);
 INSERT INTO attmp6 VALUES (6, 30), (7, 16);
 ALTER TABLE attmp3 ADD CONSTRAINT b_le_20 CHECK (b <= 20) NOT VALID;
 ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20;	-- fails
-ERROR:  check constraint "b_le_20" is violated by some row
+ERROR:  check constraint "b_le_20" of relation "attmp6" is violated by some row
 DELETE FROM attmp6 WHERE b > 20;
 ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20;	-- succeeds
 -- An already validated constraint must not be revalidated
@@ -497,7 +497,7 @@ insert into child_noinh_convalid values (1);
 alter table parent_noinh_convalid add constraint check_a_is_2 check (a = 2) no inherit not valid;
 -- fail, because of the row in parent
 alter table parent_noinh_convalid validate constraint check_a_is_2;
-ERROR:  check constraint "check_a_is_2" is violated by some row
+ERROR:  check constraint "check_a_is_2" of relation "parent_noinh_convalid" is violated by some row
 delete from only parent_noinh_convalid;
 -- ok (parent itself contains no violating rows)
 alter table parent_noinh_convalid validate constraint check_a_is_2;
@@ -754,7 +754,7 @@ create table atacc1 ( test int );
 insert into atacc1 (test) values (2);
 -- add a check constraint (fails)
 alter table atacc1 add constraint atacc_test1 check (test>3);
-ERROR:  check constraint "atacc_test1" is violated by some row
+ERROR:  check constraint "atacc_test1" of relation "atacc1" is violated by some row
 insert into atacc1 (test) values (4);
 drop table atacc1;
 -- let's do one where the check fails because the column doesn't exist
@@ -867,7 +867,7 @@ DETAIL:  Failing row contains (-3).
 insert into atacc1 (test) values (3);
 -- fail, violating row:
 alter table atacc2 add constraint foo check (test>0) no inherit;
-ERROR:  check constraint "foo" is violated by some row
+ERROR:  check constraint "foo" of relation "atacc2" is violated by some row
 drop table atacc2;
 drop table atacc1;
 -- test unique constraint adding
@@ -943,7 +943,7 @@ DETAIL:  Key (test)=(2) already exists.
 insert into atacc1 (test) values (4);
 -- inserting NULL should fail
 insert into atacc1 (test) values(NULL);
-ERROR:  null value in column "test" violates not-null constraint
+ERROR:  null value in column "test" of relation "atacc1" violates not-null constraint
 DETAIL:  Failing row contains (4, null).
 -- try adding a second primary key (should fail)
 alter table atacc1 add constraint atacc_oid1 primary key(id);
@@ -970,7 +970,7 @@ create table atacc1 ( test int );
 insert into atacc1 (test) values (NULL);
 -- add a primary key (fails)
 alter table atacc1 add constraint atacc_test1 primary key (test);
-ERROR:  column "test" contains null values
+ERROR:  column "test" of relation "atacc1" contains null values
 insert into atacc1 (test) values (3);
 drop table atacc1;
 -- let's do one where the primary key constraint fails
@@ -986,7 +986,7 @@ create table atacc1 ( test int );
 insert into atacc1 (test) values (0);
 -- add a primary key column without a default (fails).
 alter table atacc1 add column test2 int primary key;
-ERROR:  column "test2" contains null values
+ERROR:  column "test2" of relation "atacc1" contains null values
 -- now add a primary key column with a default (succeeds).
 alter table atacc1 add column test2 int default 0 primary key;
 drop table atacc1;
@@ -1011,13 +1011,13 @@ insert into atacc1 (test,test2) values (4,4);
 ERROR:  duplicate key value violates unique constraint "atacc_test1"
 DETAIL:  Key (test, test2)=(4, 4) already exists.
 insert into atacc1 (test,test2) values (NULL,3);
-ERROR:  null value in column "test" violates not-null constraint
+ERROR:  null value in column "test" of relation "atacc1" violates not-null constraint
 DETAIL:  Failing row contains (null, 3).
 insert into atacc1 (test,test2) values (3, NULL);
-ERROR:  null value in column "test2" violates not-null constraint
+ERROR:  null value in column "test2" of relation "atacc1" violates not-null constraint
 DETAIL:  Failing row contains (3, null).
 insert into atacc1 (test,test2) values (NULL,NULL);
-ERROR:  null value in column "test" violates not-null constraint
+ERROR:  null value in column "test" of relation "atacc1" violates not-null constraint
 DETAIL:  Failing row contains (null, null).
 -- should all succeed
 insert into atacc1 (test,test2) values (4,5);
@@ -1032,7 +1032,7 @@ insert into atacc1 (test2, test) values (2, 3);
 ERROR:  duplicate key value violates unique constraint "atacc1_pkey"
 DETAIL:  Key (test)=(3) already exists.
 insert into atacc1 (test2, test) values (1, NULL);
-ERROR:  null value in column "test" violates not-null constraint
+ERROR:  null value in column "test" of relation "atacc1" violates not-null constraint
 DETAIL:  Failing row contains (null, 1).
 drop table atacc1;
 -- alter table / alter column [set/drop] not null tests
@@ -1056,7 +1056,7 @@ alter table atacc1 drop constraint "atacc1_pkey";
 alter table atacc1 alter column test drop not null;
 insert into atacc1 values (null);
 alter table atacc1 alter test set not null;
-ERROR:  column "test" contains null values
+ERROR:  column "test" of relation "atacc1" contains null values
 delete from atacc1;
 alter table atacc1 alter test set not null;
 -- try altering a non-existent column, should fail
@@ -1078,12 +1078,12 @@ insert into atacc1 values (null, 1);
 -- constraint not cover all values, should fail
 alter table atacc1 add constraint atacc1_constr_or check(test_a is not null or test_b < 10);
 alter table atacc1 alter test_a set not null;
-ERROR:  column "test_a" contains null values
+ERROR:  column "test_a" of relation "atacc1" contains null values
 alter table atacc1 drop constraint atacc1_constr_or;
 -- not valid constraint, should fail
 alter table atacc1 add constraint atacc1_constr_invalid check(test_a is not null) not valid;
 alter table atacc1 alter test_a set not null;
-ERROR:  column "test_a" contains null values
+ERROR:  column "test_a" of relation "atacc1" contains null values
 alter table atacc1 drop constraint atacc1_constr_invalid;
 -- with valid constraint
 update atacc1 set test_a = 1;
@@ -1095,10 +1095,10 @@ alter table atacc1 alter test_a drop not null;
 -- test multiple set not null at same time
 -- test_a checked by atacc1_constr_a_valid, test_b should fail by table scan
 alter table atacc1 alter test_a set not null, alter test_b set not null;
-ERROR:  column "test_b" contains null values
+ERROR:  column "test_b" of relation "atacc1" contains null values
 -- commands order has no importance
 alter table atacc1 alter test_b set not null, alter test_a set not null;
-ERROR:  column "test_b" contains null values
+ERROR:  column "test_b" of relation "atacc1" contains null values
 -- valid one by table scan, one by check constraints
 update atacc1 set test_b = 1;
 alter table atacc1 alter test_b set not null, alter test_a set not null;
@@ -1112,31 +1112,31 @@ create table parent (a int);
 create table child (b varchar(255)) inherits (parent);
 alter table parent alter a set not null;
 insert into parent values (NULL);
-ERROR:  null value in column "a" violates not-null constraint
+ERROR:  null value in column "a" of relation "parent" violates not-null constraint
 DETAIL:  Failing row contains (null).
 insert into child (a, b) values (NULL, 'foo');
-ERROR:  null value in column "a" violates not-null constraint
+ERROR:  null value in column "a" of relation "child" violates not-null constraint
 DETAIL:  Failing row contains (null, foo).
 alter table parent alter a drop not null;
 insert into parent values (NULL);
 insert into child (a, b) values (NULL, 'foo');
 alter table only parent alter a set not null;
-ERROR:  column "a" contains null values
+ERROR:  column "a" of relation "parent" contains null values
 alter table child alter a set not null;
-ERROR:  column "a" contains null values
+ERROR:  column "a" of relation "child" contains null values
 delete from parent;
 alter table only parent alter a set not null;
 insert into parent values (NULL);
-ERROR:  null value in column "a" violates not-null constraint
+ERROR:  null value in column "a" of relation "parent" violates not-null constraint
 DETAIL:  Failing row contains (null).
 alter table child alter a set not null;
 insert into child (a, b) values (NULL, 'foo');
-ERROR:  null value in column "a" violates not-null constraint
+ERROR:  null value in column "a" of relation "child" violates not-null constraint
 DETAIL:  Failing row contains (null, foo).
 delete from child;
 alter table child alter a set not null;
 insert into child (a, b) values (NULL, 'foo');
-ERROR:  null value in column "a" violates not-null constraint
+ERROR:  null value in column "a" of relation "child" violates not-null constraint
 DETAIL:  Failing row contains (null, foo).
 drop table child;
 drop table parent;
@@ -1474,7 +1474,7 @@ insert into atacc1(value) values (100);
 ERROR:  new row for relation "atacc1" violates check constraint "atacc1_value_check"
 DETAIL:  Failing row contains (2, 100).
 insert into atacc1(id, value) values (null, 0);
-ERROR:  null value in column "id" violates not-null constraint
+ERROR:  null value in column "id" of relation "atacc1" violates not-null constraint
 DETAIL:  Failing row contains (null, 0).
 drop table atacc1;
 -- test inheritance
@@ -3804,7 +3804,7 @@ CREATE TABLE list_parted2 (
 CREATE TABLE part_2 (LIKE list_parted2);
 INSERT INTO part_2 VALUES (3, 'a');
 ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2);
-ERROR:  partition constraint is violated by some row
+ERROR:  partition constraint of relation "part_2" is violated by some row
 -- should be ok after deleting the bad row
 DELETE FROM part_2;
 ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2);
@@ -3813,7 +3813,7 @@ CREATE TABLE list_parted2_def PARTITION OF list_parted2 DEFAULT;
 INSERT INTO list_parted2_def VALUES (11, 'z');
 CREATE TABLE part_3 (LIKE list_parted2);
 ALTER TABLE list_parted2 ATTACH PARTITION part_3 FOR VALUES IN (11);
-ERROR:  updated partition constraint for default partition would be violated by some row
+ERROR:  updated partition constraint for default partition "list_parted2_def" would be violated by some row
 -- should be ok after deleting the bad row
 DELETE FROM list_parted2_def WHERE a = 11;
 ALTER TABLE list_parted2 ATTACH PARTITION part_3 FOR VALUES IN (11);
@@ -3847,7 +3847,7 @@ CREATE TABLE part1 (
 INSERT INTO part1 VALUES (1, 10);
 -- Remember the TO bound is exclusive
 ALTER TABLE range_parted ATTACH PARTITION part1 FOR VALUES FROM (1, 1) TO (1, 10);
-ERROR:  partition constraint is violated by some row
+ERROR:  partition constraint of relation "part1" is violated by some row
 -- should be ok after deleting the bad row
 DELETE FROM part1;
 ALTER TABLE range_parted ATTACH PARTITION part1 FOR VALUES FROM (1, 1) TO (1, 10);
@@ -3868,7 +3868,7 @@ ERROR:  partition "partr_def2" conflicts with existing default partition "partr_
 INSERT INTO partr_def1 VALUES (2, 10);
 CREATE TABLE part3 (LIKE range_parted);
 ALTER TABLE range_parted ATTACH partition part3 FOR VALUES FROM (2, 10) TO (2, 20);
-ERROR:  updated partition constraint for default partition would be violated by some row
+ERROR:  updated partition constraint for default partition "partr_def1" would be violated by some row
 -- Attaching partitions should be successful when there are no overlapping rows
 ALTER TABLE range_parted ATTACH partition part3 FOR VALUES FROM (3, 10) TO (3, 20);
 -- check that leaf partitions are scanned when attaching a partitioned
@@ -3880,7 +3880,7 @@ CREATE TABLE part_5 (
 CREATE TABLE part_5_a PARTITION OF part_5 FOR VALUES IN ('a');
 INSERT INTO part_5_a (a, b) VALUES (6, 'a');
 ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5);
-ERROR:  partition constraint is violated by some row
+ERROR:  partition constraint of relation "part_5_a" is violated by some row
 -- delete the faulting row and also add a constraint to skip the scan
 DELETE FROM part_5_a WHERE a NOT IN (3);
 ALTER TABLE part_5 ADD CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 5);
@@ -3931,7 +3931,7 @@ SELECT tableoid::regclass, a, b FROM part_7 order by a;
 (2 rows)
 
 ALTER TABLE list_parted2 ATTACH PARTITION part_7 FOR VALUES IN (7);
-ERROR:  partition constraint is violated by some row
+ERROR:  partition constraint of relation "part_7_a_null" is violated by some row
 -- check that leaf partitions of default partition are scanned when
 -- attaching a partitioned table.
 ALTER TABLE part_5 DROP CONSTRAINT check_a;
@@ -3940,7 +3940,7 @@ CREATE TABLE part5_def_p1 PARTITION OF part5_def FOR VALUES IN (5);
 INSERT INTO part5_def_p1 VALUES (5, 'y');
 CREATE TABLE part5_p1 (LIKE part_5);
 ALTER TABLE part_5 ATTACH PARTITION part5_p1 FOR VALUES IN ('y');
-ERROR:  updated partition constraint for default partition would be violated by some row
+ERROR:  updated partition constraint for default partition "part5_def_p1" would be violated by some row
 -- should be ok after deleting the bad row
 DELETE FROM part5_def_p1 WHERE b = 'y';
 ALTER TABLE part_5 ATTACH PARTITION part5_p1 FOR VALUES IN ('y');
@@ -3992,7 +3992,7 @@ DROP TABLE fail_part;
 CREATE TABLE hpart_2 (LIKE hash_parted);
 INSERT INTO hpart_2 VALUES (3, 0);
 ALTER TABLE hash_parted ATTACH PARTITION hpart_2 FOR VALUES WITH (MODULUS 4, REMAINDER 1);
-ERROR:  partition constraint is violated by some row
+ERROR:  partition constraint of relation "hpart_2" is violated by some row
 -- should be ok after deleting the bad row
 DELETE FROM hpart_2;
 ALTER TABLE hash_parted ATTACH PARTITION hpart_2 FOR VALUES WITH (MODULUS 4, REMAINDER 1);
@@ -4005,7 +4005,7 @@ CREATE TABLE hpart_5 (
 CREATE TABLE hpart_5_a PARTITION OF hpart_5 FOR VALUES IN ('1', '2', '3');
 INSERT INTO hpart_5_a (a, b) VALUES (7, 1);
 ALTER TABLE hash_parted ATTACH PARTITION hpart_5 FOR VALUES WITH (MODULUS 4, REMAINDER 2);
-ERROR:  partition constraint is violated by some row
+ERROR:  partition constraint of relation "hpart_5_a" is violated by some row
 -- should be ok after deleting the bad row
 DELETE FROM hpart_5_a;
 ALTER TABLE hash_parted ATTACH PARTITION hpart_5 FOR VALUES WITH (MODULUS 4, REMAINDER 2);
@@ -4172,7 +4172,7 @@ alter table p1 attach partition p11 for values from (2) to (5);
 insert into p1 (a, b) values (2, 3);
 -- check that partition validation scan correctly detects violating rows
 alter table p attach partition p1 for values from (1, 2) to (1, 10);
-ERROR:  partition constraint is violated by some row
+ERROR:  partition constraint of relation "p11" is violated by some row
 -- cleanup
 drop table p;
 drop table p1;
@@ -4200,7 +4200,7 @@ insert into defpart_attach_test_d values (1), (2);
 -- error because its constraint as the default partition would be violated
 -- by the row containing 1
 alter table defpart_attach_test attach partition defpart_attach_test_d default;
-ERROR:  partition constraint is violated by some row
+ERROR:  partition constraint of relation "defpart_attach_test_d" is violated by some row
 delete from defpart_attach_test_d where a = 1;
 alter table defpart_attach_test_d add check (a > 1);
 -- should be attached successfully and without needing to be scanned
@@ -4210,7 +4210,7 @@ alter table defpart_attach_test attach partition defpart_attach_test_d default;
 -- successfully
 create table defpart_attach_test_2 (like defpart_attach_test_d);
 alter table defpart_attach_test attach partition defpart_attach_test_2 for values in (2);
-ERROR:  updated partition constraint for default partition would be violated by some row
+ERROR:  updated partition constraint for default partition "defpart_attach_test_d" would be violated by some row
 drop table defpart_attach_test;
 -- check combinations of temporary and permanent relations when attaching
 -- partitions.
diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out
index c53ed3e..e40287d 100644
--- a/src/test/regress/expected/copy2.out
+++ b/src/test/regress/expected/copy2.out
@@ -440,7 +440,7 @@ SELECT c, d FROM forcetest WHERE a = 2;
 -- should fail with not-null constraint violation
 BEGIN;
 COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NULL(b), FORCE_NOT_NULL(c));
-ERROR:  null value in column "b" violates not-null constraint
+ERROR:  null value in column "b" of relation "forcetest" violates not-null constraint
 DETAIL:  Failing row contains (3, null, , null, null).
 CONTEXT:  COPY forcetest, line 1: "3,,"""
 ROLLBACK;
diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out
index b64f919..c5e95ed 100644
--- a/src/test/regress/expected/create_table.out
+++ b/src/test/regress/expected/create_table.out
@@ -955,7 +955,7 @@ CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10);
 create table parted_notnull_inh_test (a int default 1, b int not null default 0) partition by list (a);
 create table parted_notnull_inh_test1 partition of parted_notnull_inh_test (a not null, b default 1) for values in (1);
 insert into parted_notnull_inh_test (b) values (null);
-ERROR:  null value in column "b" violates not-null constraint
+ERROR:  null value in column "b" of relation "parted_notnull_inh_test1" violates not-null constraint
 DETAIL:  Failing row contains (1, null).
 -- note that while b's default is overriden, a's default is preserved
 \d parted_notnull_inh_test1
diff --git a/src/test/regress/expected/create_table_like.out b/src/test/regress/expected/create_table_like.out
index 2a063a8..94d4858 100644
--- a/src/test/regress/expected/create_table_like.out
+++ b/src/test/regress/expected/create_table_like.out
@@ -90,7 +90,7 @@ CREATE TABLE test_like_id_2 (LIKE test_like_id_1);
  b      | text   |           |          | 
 
 INSERT INTO test_like_id_2 (b) VALUES ('b2');
-ERROR:  null value in column "a" violates not-null constraint
+ERROR:  null value in column "a" of relation "test_like_id_2" violates not-null constraint
 DETAIL:  Failing row contains (null, b2).
 SELECT * FROM test_like_id_2;  -- identity was not copied
  a | b 
diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out
index 4ff1b4a..2a033a6 100644
--- a/src/test/regress/expected/domain.out
+++ b/src/test/regress/expected/domain.out
@@ -542,12 +542,12 @@ ERROR:  domain dnotnull does not allow null values
 INSERT INTO nulltest values ('a', NULL, 'c', 'd', 'c');
 ERROR:  domain dnotnull does not allow null values
 INSERT INTO nulltest values ('a', 'b', NULL, 'd', 'c');
-ERROR:  null value in column "col3" violates not-null constraint
+ERROR:  null value in column "col3" of relation "nulltest" violates not-null constraint
 DETAIL:  Failing row contains (a, b, null, d, c).
 INSERT INTO nulltest values ('a', 'b', 'c', NULL, 'd'); -- Good
 -- Test copy
 COPY nulltest FROM stdin; --fail
-ERROR:  null value in column "col3" violates not-null constraint
+ERROR:  null value in column "col3" of relation "nulltest" violates not-null constraint
 DETAIL:  Failing row contains (a, b, null, d, d).
 CONTEXT:  COPY nulltest, line 1: "a	b	\N	d	d"
 COPY nulltest FROM stdin; --fail
@@ -601,14 +601,14 @@ create table defaulttest
             , col8 ddef5
             );
 insert into defaulttest(col4) values(0); -- fails, col5 defaults to null
-ERROR:  null value in column "col5" violates not-null constraint
+ERROR:  null value in column "col5" of relation "defaulttest" violates not-null constraint
 DETAIL:  Failing row contains (3, 12, 5, 0, null, 88, 8000, 12.12).
 alter table defaulttest alter column col5 drop default;
 insert into defaulttest default values; -- succeeds, inserts domain default
 -- We used to treat SET DEFAULT NULL as equivalent to DROP DEFAULT; wrong
 alter table defaulttest alter column col5 set default null;
 insert into defaulttest(col4) values(0); -- fails
-ERROR:  null value in column "col5" violates not-null constraint
+ERROR:  null value in column "col5" of relation "defaulttest" violates not-null constraint
 DETAIL:  Failing row contains (3, 12, 5, 0, null, 88, 8000, 12.12).
 alter table defaulttest alter column col5 drop default;
 insert into defaulttest default values;
diff --git a/src/test/regress/expected/generated.out b/src/test/regress/expected/generated.out
index a6d3670..620579a 100644
--- a/src/test/regress/expected/generated.out
+++ b/src/test/regress/expected/generated.out
@@ -406,24 +406,24 @@ CREATE TABLE gtest20a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STOR
 INSERT INTO gtest20a (a) VALUES (10);
 INSERT INTO gtest20a (a) VALUES (30);
 ALTER TABLE gtest20a ADD CHECK (b < 50);  -- fails on existing row
-ERROR:  check constraint "gtest20a_b_check" is violated by some row
+ERROR:  check constraint "gtest20a_b_check" of relation "gtest20a" is violated by some row
 CREATE TABLE gtest20b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED);
 INSERT INTO gtest20b (a) VALUES (10);
 INSERT INTO gtest20b (a) VALUES (30);
 ALTER TABLE gtest20b ADD CONSTRAINT chk CHECK (b < 50) NOT VALID;
 ALTER TABLE gtest20b VALIDATE CONSTRAINT chk;  -- fails on existing row
-ERROR:  check constraint "chk" is violated by some row
+ERROR:  check constraint "chk" of relation "gtest20b" is violated by some row
 -- not-null constraints
 CREATE TABLE gtest21a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED NOT NULL);
 INSERT INTO gtest21a (a) VALUES (1);  -- ok
 INSERT INTO gtest21a (a) VALUES (0);  -- violates constraint
-ERROR:  null value in column "b" violates not-null constraint
+ERROR:  null value in column "b" of relation "gtest21a" violates not-null constraint
 DETAIL:  Failing row contains (0, null).
 CREATE TABLE gtest21b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED);
 ALTER TABLE gtest21b ALTER COLUMN b SET NOT NULL;
 INSERT INTO gtest21b (a) VALUES (1);  -- ok
 INSERT INTO gtest21b (a) VALUES (0);  -- violates constraint
-ERROR:  null value in column "b" violates not-null constraint
+ERROR:  null value in column "b" of relation "gtest21b" violates not-null constraint
 DETAIL:  Failing row contains (0, null).
 ALTER TABLE gtest21b ALTER COLUMN b DROP NOT NULL;
 INSERT INTO gtest21b (a) VALUES (0);  -- ok now
diff --git a/src/test/regress/expected/identity.out b/src/test/regress/expected/identity.out
index 1a614b8..7322b28 100644
--- a/src/test/regress/expected/identity.out
+++ b/src/test/regress/expected/identity.out
@@ -186,7 +186,7 @@ ERROR:  column "a" of relation "itest4" is not an identity column
 ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY IF EXISTS;  -- noop
 NOTICE:  column "a" of relation "itest4" is not an identity column, skipping
 INSERT INTO itest4 DEFAULT VALUES;  -- fails because NOT NULL is not dropped
-ERROR:  null value in column "a" violates not-null constraint
+ERROR:  null value in column "a" of relation "itest4" violates not-null constraint
 DETAIL:  Failing row contains (null, ).
 ALTER TABLE itest4 ALTER COLUMN a DROP NOT NULL;
 INSERT INTO itest4 DEFAULT VALUES;
@@ -414,7 +414,7 @@ INSERT INTO itest8 VALUES(0), (1);
 ALTER TABLE itest8
   ADD COLUMN f22 int NOT NULL,
   ALTER COLUMN f22 ADD GENERATED ALWAYS AS IDENTITY;
-ERROR:  column "f22" contains null values
+ERROR:  column "f22" of relation "itest8" contains null values
 TABLE itest8;
  f1 | f2 | f3 | f4 | f5 
 ----+----+----+----+----
diff --git a/src/test/regress/expected/index_including.out b/src/test/regress/expected/index_including.out
index 2405709..8e5d53e 100644
--- a/src/test/regress/expected/index_including.out
+++ b/src/test/regress/expected/index_including.out
@@ -124,7 +124,7 @@ INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x
 ERROR:  duplicate key value violates unique constraint "covering"
 DETAIL:  Key (c1, c2)=(1, 2) already exists.
 INSERT INTO tbl SELECT 1, NULL, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
-ERROR:  null value in column "c2" violates not-null constraint
+ERROR:  null value in column "c2" of relation "tbl" violates not-null constraint
 DETAIL:  Failing row contains (1, null, 3, (4,4),(4,4)).
 INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,300) AS x;
 explain (costs off)
@@ -202,7 +202,7 @@ INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x
 ERROR:  duplicate key value violates unique constraint "tbl_pkey"
 DETAIL:  Key (c1, c2)=(1, 2) already exists.
 INSERT INTO tbl SELECT 1, NULL, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
-ERROR:  null value in column "c2" violates not-null constraint
+ERROR:  null value in column "c2" of relation "tbl" violates not-null constraint
 DETAIL:  Failing row contains (1, null, 3, (4,4),(4,4)).
 INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,10) AS x;
 DROP TABLE tbl;
diff --git a/src/test/regress/expected/inherit.out b/src/test/regress/expected/inherit.out
index d8f56d2..dfd0ee4 100644
--- a/src/test/regress/expected/inherit.out
+++ b/src/test/regress/expected/inherit.out
@@ -537,7 +537,7 @@ SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid;
 -- Confirm PRIMARY KEY adds NOT NULL constraint to child table
 CREATE TEMP TABLE z (b TEXT, PRIMARY KEY(aa, b)) inherits (a);
 INSERT INTO z VALUES (NULL, 'text'); -- should fail
-ERROR:  null value in column "aa" violates not-null constraint
+ERROR:  null value in column "aa" of relation "z" violates not-null constraint
 DETAIL:  Failing row contains (null, text).
 -- Check inherited UPDATE with all children excluded
 create table some_tab (a int, b int);
@@ -940,9 +940,9 @@ create table p2(f2 int);
 create table c1(f3 int) inherits(p1,p2);
 insert into c1 values(1,-1,2);
 alter table p2 add constraint cc check (f2>0);  -- fail
-ERROR:  check constraint "cc" is violated by some row
+ERROR:  check constraint "cc" of relation "c1" is violated by some row
 alter table p2 add check (f2>0);  -- check it without a name, too
-ERROR:  check constraint "p2_f2_check" is violated by some row
+ERROR:  check constraint "p2_f2_check" of relation "c1" is violated by some row
 delete from c1;
 insert into c1 values(1,1,2);
 alter table p2 add check (f2>0);
diff --git a/src/test/regress/expected/insert.out b/src/test/regress/expected/insert.out
index 75e25cd..45d77ba 100644
--- a/src/test/regress/expected/insert.out
+++ b/src/test/regress/expected/insert.out
@@ -3,7 +3,7 @@
 --
 create table inserttest (col1 int4, col2 int4 NOT NULL, col3 text default 'testing');
 insert into inserttest (col1, col2, col3) values (DEFAULT, DEFAULT, DEFAULT);
-ERROR:  null value in column "col2" violates not-null constraint
+ERROR:  null value in column "col2" of relation "inserttest" violates not-null constraint
 DETAIL:  Failing row contains (null, null, testing).
 insert into inserttest (col2, col3) values (3, DEFAULT);
 insert into inserttest (col1, col2, col3) values (DEFAULT, 5, DEFAULT);
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
index 0ddbd8e..6674f26 100644
--- a/src/test/regress/expected/privileges.out
+++ b/src/test/regress/expected/privileges.out
@@ -592,13 +592,13 @@ ERROR:  duplicate key value violates unique constraint "t1_pkey"
 UPDATE t1 SET c2 = 1; -- fail, but row not shown
 ERROR:  duplicate key value violates unique constraint "t1_pkey"
 INSERT INTO t1 (c1, c2) VALUES (null, null); -- fail, but see columns being inserted
-ERROR:  null value in column "c1" violates not-null constraint
+ERROR:  null value in column "c1" of relation "t1" violates not-null constraint
 DETAIL:  Failing row contains (c1, c2) = (null, null).
 INSERT INTO t1 (c3) VALUES (null); -- fail, but see columns being inserted or have SELECT
-ERROR:  null value in column "c1" violates not-null constraint
+ERROR:  null value in column "c1" of relation "t1" violates not-null constraint
 DETAIL:  Failing row contains (c1, c3) = (null, null).
 INSERT INTO t1 (c1) VALUES (5); -- fail, but see columns being inserted or have SELECT
-ERROR:  null value in column "c2" violates not-null constraint
+ERROR:  null value in column "c2" of relation "t1" violates not-null constraint
 DETAIL:  Failing row contains (c1) = (5).
 UPDATE t1 SET c3 = 10; -- fail, but see columns with SELECT rights, or being modified
 ERROR:  new row for relation "t1" violates check constraint "t1_c3_check"
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 7cb7467..44c1304 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -100,7 +100,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 (1 row)
 
 INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL);
-ERROR:  null value in column "i" violates not-null constraint
+ERROR:  null value in column "i" of relation "reloptions_test" violates not-null constraint
 DETAIL:  Failing row contains (null, null).
 VACUUM reloptions_test;
 SELECT pg_relation_size('reloptions_test') > 0;
@@ -125,7 +125,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 (1 row)
 
 INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL);
-ERROR:  null value in column "i" violates not-null constraint
+ERROR:  null value in column "i" of relation "reloptions_test" violates not-null constraint
 DETAIL:  Failing row contains (null, null).
 VACUUM reloptions_test;
 SELECT pg_relation_size('reloptions_test') = 0;
diff --git a/src/test/regress/expected/sequence.out b/src/test/regress/expected/sequence.out
index 75eb501..8b928b2 100644
--- a/src/test/regress/expected/sequence.out
+++ b/src/test/regress/expected/sequence.out
@@ -69,7 +69,7 @@ INSERT INTO serialTest1 VALUES ('foo');
 INSERT INTO serialTest1 VALUES ('bar');
 INSERT INTO serialTest1 VALUES ('force', 100);
 INSERT INTO serialTest1 VALUES ('wrong', NULL);
-ERROR:  null value in column "f2" violates not-null constraint
+ERROR:  null value in column "f2" of relation "serialtest1" violates not-null constraint
 DETAIL:  Failing row contains (wrong, null).
 SELECT * FROM serialTest1;
   f1   | f2  
diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out
index f4250a4..0cfe28e 100644
--- a/src/test/regress/expected/vacuum.out
+++ b/src/test/regress/expected/vacuum.out
@@ -164,7 +164,7 @@ VACUUM (INDEX_CLEANUP FALSE, FREEZE TRUE) vaccluster;
 CREATE TABLE vac_truncate_test(i INT NOT NULL, j text)
 	WITH (vacuum_truncate=true, autovacuum_enabled=false);
 INSERT INTO vac_truncate_test VALUES (1, NULL), (NULL, NULL);
-ERROR:  null value in column "i" violates not-null constraint
+ERROR:  null value in column "i" of relation "vac_truncate_test" violates not-null constraint
 DETAIL:  Failing row contains (null, null).
 VACUUM (TRUNCATE FALSE) vac_truncate_test;
 SELECT pg_relation_size('vac_truncate_test') > 0;
-- 
1.8.3.1

v4_0003_updated-constraints.source-file.patchapplication/octet-stream; name=v4_0003_updated-constraints.source-file.patchDownload
From 93566ebdab8cb7e76d9f22fd91bedc04977b8750 Mon Sep 17 00:00:00 2001
From: Mahendra Singh Thalor <mahi6run@gmail.com>
Date: Thu, 23 Jan 2020 17:04:48 +0530
Subject: [PATCH 3/3] updated constraints.source file

---
 src/test/regress/output/constraints.source | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/test/regress/output/constraints.source b/src/test/regress/output/constraints.source
index e27caed..b727c61 100644
--- a/src/test/regress/output/constraints.source
+++ b/src/test/regress/output/constraints.source
@@ -377,7 +377,7 @@ DETAIL:  Key (i)=(1) already exists.
 INSERT INTO PRIMARY_TBL VALUES (4, 'three');
 INSERT INTO PRIMARY_TBL VALUES (5, 'one');
 INSERT INTO PRIMARY_TBL (t) VALUES ('six');
-ERROR:  null value in column "i" violates not-null constraint
+ERROR:  null value in column "i" of relation "primary_tbl" violates not-null constraint
 DETAIL:  Failing row contains (null, six).
 SELECT '' AS four, * FROM PRIMARY_TBL;
  four | i |   t   
@@ -397,7 +397,7 @@ INSERT INTO PRIMARY_TBL VALUES (1, 'three');
 INSERT INTO PRIMARY_TBL VALUES (4, 'three');
 INSERT INTO PRIMARY_TBL VALUES (5, 'one');
 INSERT INTO PRIMARY_TBL (t) VALUES ('six');
-ERROR:  null value in column "i" violates not-null constraint
+ERROR:  null value in column "i" of relation "primary_tbl" violates not-null constraint
 DETAIL:  Failing row contains (null, six).
 SELECT '' AS three, * FROM PRIMARY_TBL;
  three | i |   t   
-- 
1.8.3.1

#25Amit Kapila
amit.kapila16@gmail.com
In reply to: Mahendra Singh Thalor (#24)
1 attachment(s)
Re: Error message inconsistency

On Thu, Jan 23, 2020 at 5:51 PM Mahendra Singh Thalor
<mahi6run@gmail.com> wrote:

I fixed above comment and updated expected .out files. Attaching
updated patches.

LGTM. I have combined them into the single patch. What do we think
about backpatching this? As there are quite a few changes in the
regression tests, so it might be a good idea to keep the back branches
code in sync, but, OTOH, this is more of a change related to providing
more information, so we don't have any pressing need to backpatch
this. What do others think?

One thing to note is that there are places in code where we use
'table' instead of 'relation' for the same thing in the error messages
as seen in the below places (the first one uses 'relation', the second
one uses 'table') and the patch is using 'relation' which I think is
fine.

1. src/backend/executor/execPartition.c
342 ereport(ERROR,
343 (errcode(ERRCODE_CHECK_VIOLATION),
344 errmsg("no partition of relation \"%s\"
found for row",
345 RelationGetRelationName(rel)),
346 val_desc ?
347 errdetail("Partition key of the failing row
contains %s.",
348 val_desc) : 0));

2. src/backend/commands/typecmds.c
2396 ereport(ERROR,
2397 (errcode(ERRCODE_NOT_NULL_VIOLATION),
2398 errmsg("column \"%s\" of table
\"%s\" contains null values",
2399 NameStr(attr->attname),
2400 RelationGetRelationName(testrel)),
2401 errtablecol(testrel, attnum)));

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

Attachments:

v5-0001-Added-relation-name-in-error-messages-for-constraint.patchapplication/octet-stream; name=v5-0001-Added-relation-name-in-error-messages-for-constraint.patchDownload
From 1853e30caa5d21d2e1711374d8e8f4281cc5cbe1 Mon Sep 17 00:00:00 2001
From: Amit Kapila <akapila@postgresql.org>
Date: Fri, 24 Jan 2020 10:39:08 +0530
Subject: [PATCH] Added relation name in error messages for constraint checks.

This gives more information to the user about the error and it makes such
messages consistent with the other similar messages in the code.

Reported-by: Simon Riggs
Author: Mahendra Singh and Simon Riggs
Reviewed-by: Beena Emerson and Amit Kapila
Discussion: https://postgr.es/m/CANP8+j+7YUvQvGxTrCiw77R23enMJ7DFmyA3buR+fa2pKs4XhA@mail.gmail.com
---
 src/backend/commands/tablecmds.c                | 21 ++++---
 src/backend/executor/execMain.c                 |  5 +-
 src/test/regress/expected/alter_table.out       | 76 ++++++++++++-------------
 src/test/regress/expected/copy2.out             |  2 +-
 src/test/regress/expected/create_table.out      |  2 +-
 src/test/regress/expected/create_table_like.out |  2 +-
 src/test/regress/expected/domain.out            |  8 +--
 src/test/regress/expected/generated.out         |  8 +--
 src/test/regress/expected/identity.out          |  4 +-
 src/test/regress/expected/index_including.out   |  4 +-
 src/test/regress/expected/inherit.out           |  6 +-
 src/test/regress/expected/insert.out            |  2 +-
 src/test/regress/expected/privileges.out        |  6 +-
 src/test/regress/expected/reloptions.out        |  4 +-
 src/test/regress/expected/sequence.out          |  2 +-
 src/test/regress/expected/vacuum.out            |  2 +-
 src/test/regress/output/constraints.source      |  4 +-
 17 files changed, 82 insertions(+), 76 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 7c23968..70589dd 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -5288,8 +5288,9 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 
 					ereport(ERROR,
 							(errcode(ERRCODE_NOT_NULL_VIOLATION),
-							 errmsg("column \"%s\" contains null values",
-									NameStr(attr->attname)),
+							 errmsg("column \"%s\" of relation \"%s\" contains null values",
+									NameStr(attr->attname),
+									RelationGetRelationName(oldrel)),
 							 errtablecol(oldrel, attn + 1)));
 				}
 			}
@@ -5304,8 +5305,9 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 						if (!ExecCheck(con->qualstate, econtext))
 							ereport(ERROR,
 									(errcode(ERRCODE_CHECK_VIOLATION),
-									 errmsg("check constraint \"%s\" is violated by some row",
-											con->name),
+									 errmsg("check constraint \"%s\" of relation \"%s\" is violated by some row",
+											con->name,
+											RelationGetRelationName(oldrel)),
 									 errtableconstraint(oldrel, con->name)));
 						break;
 					case CONSTR_FOREIGN:
@@ -5322,11 +5324,13 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 				if (tab->validate_default)
 					ereport(ERROR,
 							(errcode(ERRCODE_CHECK_VIOLATION),
-							 errmsg("updated partition constraint for default partition would be violated by some row")));
+							 errmsg("updated partition constraint for default partition \"%s\" would be violated by some row",
+									RelationGetRelationName(oldrel))));
 				else
 					ereport(ERROR,
 							(errcode(ERRCODE_CHECK_VIOLATION),
-							 errmsg("partition constraint is violated by some row")));
+							 errmsg("partition constraint of relation \"%s\" is violated by some row",
+									RelationGetRelationName(oldrel))));
 			}
 
 			/* Write the tuple out to the new relation */
@@ -10160,8 +10164,9 @@ validateCheckConstraint(Relation rel, HeapTuple constrtup)
 		if (!ExecCheck(exprstate, econtext))
 			ereport(ERROR,
 					(errcode(ERRCODE_CHECK_VIOLATION),
-					 errmsg("check constraint \"%s\" is violated by some row",
-							NameStr(constrForm->conname)),
+					 errmsg("check constraint \"%s\" of relation \"%s\" is violated by some row",
+							NameStr(constrForm->conname),
+							RelationGetRelationName(rel)),
 					 errtableconstraint(rel, NameStr(constrForm->conname))));
 
 		ResetExprContext(econtext);
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index b03e02a..3a9ce99 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -1957,8 +1957,9 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
 
 				ereport(ERROR,
 						(errcode(ERRCODE_NOT_NULL_VIOLATION),
-						 errmsg("null value in column \"%s\" violates not-null constraint",
-								NameStr(att->attname)),
+						 errmsg("null value in column \"%s\" of relation \"%s\" violates not-null constraint",
+								NameStr(att->attname),
+								RelationGetRelationName(orig_rel)),
 						 val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
 						 errtablecol(orig_rel, attrChk)));
 			}
diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out
index 4dd3507..e73ce4b 100644
--- a/src/test/regress/expected/alter_table.out
+++ b/src/test/regress/expected/alter_table.out
@@ -457,10 +457,10 @@ ALTER TABLE attmp3 validate constraint attmpconstr;
 ALTER TABLE attmp3 validate constraint attmpconstr;
 -- Try a non-verified CHECK constraint
 ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10); -- fail
-ERROR:  check constraint "b_greater_than_ten" is violated by some row
+ERROR:  check constraint "b_greater_than_ten" of relation "attmp3" is violated by some row
 ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10) NOT VALID; -- succeeds
 ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- fails
-ERROR:  check constraint "b_greater_than_ten" is violated by some row
+ERROR:  check constraint "b_greater_than_ten" of relation "attmp3" is violated by some row
 DELETE FROM attmp3 WHERE NOT b > 10;
 ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- succeeds
 ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- succeeds
@@ -476,7 +476,7 @@ CREATE TABLE attmp7 () INHERITS (attmp3);
 INSERT INTO attmp6 VALUES (6, 30), (7, 16);
 ALTER TABLE attmp3 ADD CONSTRAINT b_le_20 CHECK (b <= 20) NOT VALID;
 ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20;	-- fails
-ERROR:  check constraint "b_le_20" is violated by some row
+ERROR:  check constraint "b_le_20" of relation "attmp6" is violated by some row
 DELETE FROM attmp6 WHERE b > 20;
 ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20;	-- succeeds
 -- An already validated constraint must not be revalidated
@@ -497,7 +497,7 @@ insert into child_noinh_convalid values (1);
 alter table parent_noinh_convalid add constraint check_a_is_2 check (a = 2) no inherit not valid;
 -- fail, because of the row in parent
 alter table parent_noinh_convalid validate constraint check_a_is_2;
-ERROR:  check constraint "check_a_is_2" is violated by some row
+ERROR:  check constraint "check_a_is_2" of relation "parent_noinh_convalid" is violated by some row
 delete from only parent_noinh_convalid;
 -- ok (parent itself contains no violating rows)
 alter table parent_noinh_convalid validate constraint check_a_is_2;
@@ -754,7 +754,7 @@ create table atacc1 ( test int );
 insert into atacc1 (test) values (2);
 -- add a check constraint (fails)
 alter table atacc1 add constraint atacc_test1 check (test>3);
-ERROR:  check constraint "atacc_test1" is violated by some row
+ERROR:  check constraint "atacc_test1" of relation "atacc1" is violated by some row
 insert into atacc1 (test) values (4);
 drop table atacc1;
 -- let's do one where the check fails because the column doesn't exist
@@ -867,7 +867,7 @@ DETAIL:  Failing row contains (-3).
 insert into atacc1 (test) values (3);
 -- fail, violating row:
 alter table atacc2 add constraint foo check (test>0) no inherit;
-ERROR:  check constraint "foo" is violated by some row
+ERROR:  check constraint "foo" of relation "atacc2" is violated by some row
 drop table atacc2;
 drop table atacc1;
 -- test unique constraint adding
@@ -943,7 +943,7 @@ DETAIL:  Key (test)=(2) already exists.
 insert into atacc1 (test) values (4);
 -- inserting NULL should fail
 insert into atacc1 (test) values(NULL);
-ERROR:  null value in column "test" violates not-null constraint
+ERROR:  null value in column "test" of relation "atacc1" violates not-null constraint
 DETAIL:  Failing row contains (4, null).
 -- try adding a second primary key (should fail)
 alter table atacc1 add constraint atacc_oid1 primary key(id);
@@ -970,7 +970,7 @@ create table atacc1 ( test int );
 insert into atacc1 (test) values (NULL);
 -- add a primary key (fails)
 alter table atacc1 add constraint atacc_test1 primary key (test);
-ERROR:  column "test" contains null values
+ERROR:  column "test" of relation "atacc1" contains null values
 insert into atacc1 (test) values (3);
 drop table atacc1;
 -- let's do one where the primary key constraint fails
@@ -986,7 +986,7 @@ create table atacc1 ( test int );
 insert into atacc1 (test) values (0);
 -- add a primary key column without a default (fails).
 alter table atacc1 add column test2 int primary key;
-ERROR:  column "test2" contains null values
+ERROR:  column "test2" of relation "atacc1" contains null values
 -- now add a primary key column with a default (succeeds).
 alter table atacc1 add column test2 int default 0 primary key;
 drop table atacc1;
@@ -1011,13 +1011,13 @@ insert into atacc1 (test,test2) values (4,4);
 ERROR:  duplicate key value violates unique constraint "atacc_test1"
 DETAIL:  Key (test, test2)=(4, 4) already exists.
 insert into atacc1 (test,test2) values (NULL,3);
-ERROR:  null value in column "test" violates not-null constraint
+ERROR:  null value in column "test" of relation "atacc1" violates not-null constraint
 DETAIL:  Failing row contains (null, 3).
 insert into atacc1 (test,test2) values (3, NULL);
-ERROR:  null value in column "test2" violates not-null constraint
+ERROR:  null value in column "test2" of relation "atacc1" violates not-null constraint
 DETAIL:  Failing row contains (3, null).
 insert into atacc1 (test,test2) values (NULL,NULL);
-ERROR:  null value in column "test" violates not-null constraint
+ERROR:  null value in column "test" of relation "atacc1" violates not-null constraint
 DETAIL:  Failing row contains (null, null).
 -- should all succeed
 insert into atacc1 (test,test2) values (4,5);
@@ -1032,7 +1032,7 @@ insert into atacc1 (test2, test) values (2, 3);
 ERROR:  duplicate key value violates unique constraint "atacc1_pkey"
 DETAIL:  Key (test)=(3) already exists.
 insert into atacc1 (test2, test) values (1, NULL);
-ERROR:  null value in column "test" violates not-null constraint
+ERROR:  null value in column "test" of relation "atacc1" violates not-null constraint
 DETAIL:  Failing row contains (null, 1).
 drop table atacc1;
 -- alter table / alter column [set/drop] not null tests
@@ -1056,7 +1056,7 @@ alter table atacc1 drop constraint "atacc1_pkey";
 alter table atacc1 alter column test drop not null;
 insert into atacc1 values (null);
 alter table atacc1 alter test set not null;
-ERROR:  column "test" contains null values
+ERROR:  column "test" of relation "atacc1" contains null values
 delete from atacc1;
 alter table atacc1 alter test set not null;
 -- try altering a non-existent column, should fail
@@ -1078,12 +1078,12 @@ insert into atacc1 values (null, 1);
 -- constraint not cover all values, should fail
 alter table atacc1 add constraint atacc1_constr_or check(test_a is not null or test_b < 10);
 alter table atacc1 alter test_a set not null;
-ERROR:  column "test_a" contains null values
+ERROR:  column "test_a" of relation "atacc1" contains null values
 alter table atacc1 drop constraint atacc1_constr_or;
 -- not valid constraint, should fail
 alter table atacc1 add constraint atacc1_constr_invalid check(test_a is not null) not valid;
 alter table atacc1 alter test_a set not null;
-ERROR:  column "test_a" contains null values
+ERROR:  column "test_a" of relation "atacc1" contains null values
 alter table atacc1 drop constraint atacc1_constr_invalid;
 -- with valid constraint
 update atacc1 set test_a = 1;
@@ -1095,10 +1095,10 @@ alter table atacc1 alter test_a drop not null;
 -- test multiple set not null at same time
 -- test_a checked by atacc1_constr_a_valid, test_b should fail by table scan
 alter table atacc1 alter test_a set not null, alter test_b set not null;
-ERROR:  column "test_b" contains null values
+ERROR:  column "test_b" of relation "atacc1" contains null values
 -- commands order has no importance
 alter table atacc1 alter test_b set not null, alter test_a set not null;
-ERROR:  column "test_b" contains null values
+ERROR:  column "test_b" of relation "atacc1" contains null values
 -- valid one by table scan, one by check constraints
 update atacc1 set test_b = 1;
 alter table atacc1 alter test_b set not null, alter test_a set not null;
@@ -1112,31 +1112,31 @@ create table parent (a int);
 create table child (b varchar(255)) inherits (parent);
 alter table parent alter a set not null;
 insert into parent values (NULL);
-ERROR:  null value in column "a" violates not-null constraint
+ERROR:  null value in column "a" of relation "parent" violates not-null constraint
 DETAIL:  Failing row contains (null).
 insert into child (a, b) values (NULL, 'foo');
-ERROR:  null value in column "a" violates not-null constraint
+ERROR:  null value in column "a" of relation "child" violates not-null constraint
 DETAIL:  Failing row contains (null, foo).
 alter table parent alter a drop not null;
 insert into parent values (NULL);
 insert into child (a, b) values (NULL, 'foo');
 alter table only parent alter a set not null;
-ERROR:  column "a" contains null values
+ERROR:  column "a" of relation "parent" contains null values
 alter table child alter a set not null;
-ERROR:  column "a" contains null values
+ERROR:  column "a" of relation "child" contains null values
 delete from parent;
 alter table only parent alter a set not null;
 insert into parent values (NULL);
-ERROR:  null value in column "a" violates not-null constraint
+ERROR:  null value in column "a" of relation "parent" violates not-null constraint
 DETAIL:  Failing row contains (null).
 alter table child alter a set not null;
 insert into child (a, b) values (NULL, 'foo');
-ERROR:  null value in column "a" violates not-null constraint
+ERROR:  null value in column "a" of relation "child" violates not-null constraint
 DETAIL:  Failing row contains (null, foo).
 delete from child;
 alter table child alter a set not null;
 insert into child (a, b) values (NULL, 'foo');
-ERROR:  null value in column "a" violates not-null constraint
+ERROR:  null value in column "a" of relation "child" violates not-null constraint
 DETAIL:  Failing row contains (null, foo).
 drop table child;
 drop table parent;
@@ -1474,7 +1474,7 @@ insert into atacc1(value) values (100);
 ERROR:  new row for relation "atacc1" violates check constraint "atacc1_value_check"
 DETAIL:  Failing row contains (2, 100).
 insert into atacc1(id, value) values (null, 0);
-ERROR:  null value in column "id" violates not-null constraint
+ERROR:  null value in column "id" of relation "atacc1" violates not-null constraint
 DETAIL:  Failing row contains (null, 0).
 drop table atacc1;
 -- test inheritance
@@ -3804,7 +3804,7 @@ CREATE TABLE list_parted2 (
 CREATE TABLE part_2 (LIKE list_parted2);
 INSERT INTO part_2 VALUES (3, 'a');
 ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2);
-ERROR:  partition constraint is violated by some row
+ERROR:  partition constraint of relation "part_2" is violated by some row
 -- should be ok after deleting the bad row
 DELETE FROM part_2;
 ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2);
@@ -3813,7 +3813,7 @@ CREATE TABLE list_parted2_def PARTITION OF list_parted2 DEFAULT;
 INSERT INTO list_parted2_def VALUES (11, 'z');
 CREATE TABLE part_3 (LIKE list_parted2);
 ALTER TABLE list_parted2 ATTACH PARTITION part_3 FOR VALUES IN (11);
-ERROR:  updated partition constraint for default partition would be violated by some row
+ERROR:  updated partition constraint for default partition "list_parted2_def" would be violated by some row
 -- should be ok after deleting the bad row
 DELETE FROM list_parted2_def WHERE a = 11;
 ALTER TABLE list_parted2 ATTACH PARTITION part_3 FOR VALUES IN (11);
@@ -3847,7 +3847,7 @@ CREATE TABLE part1 (
 INSERT INTO part1 VALUES (1, 10);
 -- Remember the TO bound is exclusive
 ALTER TABLE range_parted ATTACH PARTITION part1 FOR VALUES FROM (1, 1) TO (1, 10);
-ERROR:  partition constraint is violated by some row
+ERROR:  partition constraint of relation "part1" is violated by some row
 -- should be ok after deleting the bad row
 DELETE FROM part1;
 ALTER TABLE range_parted ATTACH PARTITION part1 FOR VALUES FROM (1, 1) TO (1, 10);
@@ -3868,7 +3868,7 @@ ERROR:  partition "partr_def2" conflicts with existing default partition "partr_
 INSERT INTO partr_def1 VALUES (2, 10);
 CREATE TABLE part3 (LIKE range_parted);
 ALTER TABLE range_parted ATTACH partition part3 FOR VALUES FROM (2, 10) TO (2, 20);
-ERROR:  updated partition constraint for default partition would be violated by some row
+ERROR:  updated partition constraint for default partition "partr_def1" would be violated by some row
 -- Attaching partitions should be successful when there are no overlapping rows
 ALTER TABLE range_parted ATTACH partition part3 FOR VALUES FROM (3, 10) TO (3, 20);
 -- check that leaf partitions are scanned when attaching a partitioned
@@ -3880,7 +3880,7 @@ CREATE TABLE part_5 (
 CREATE TABLE part_5_a PARTITION OF part_5 FOR VALUES IN ('a');
 INSERT INTO part_5_a (a, b) VALUES (6, 'a');
 ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5);
-ERROR:  partition constraint is violated by some row
+ERROR:  partition constraint of relation "part_5_a" is violated by some row
 -- delete the faulting row and also add a constraint to skip the scan
 DELETE FROM part_5_a WHERE a NOT IN (3);
 ALTER TABLE part_5 ADD CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 5);
@@ -3931,7 +3931,7 @@ SELECT tableoid::regclass, a, b FROM part_7 order by a;
 (2 rows)
 
 ALTER TABLE list_parted2 ATTACH PARTITION part_7 FOR VALUES IN (7);
-ERROR:  partition constraint is violated by some row
+ERROR:  partition constraint of relation "part_7_a_null" is violated by some row
 -- check that leaf partitions of default partition are scanned when
 -- attaching a partitioned table.
 ALTER TABLE part_5 DROP CONSTRAINT check_a;
@@ -3940,7 +3940,7 @@ CREATE TABLE part5_def_p1 PARTITION OF part5_def FOR VALUES IN (5);
 INSERT INTO part5_def_p1 VALUES (5, 'y');
 CREATE TABLE part5_p1 (LIKE part_5);
 ALTER TABLE part_5 ATTACH PARTITION part5_p1 FOR VALUES IN ('y');
-ERROR:  updated partition constraint for default partition would be violated by some row
+ERROR:  updated partition constraint for default partition "part5_def_p1" would be violated by some row
 -- should be ok after deleting the bad row
 DELETE FROM part5_def_p1 WHERE b = 'y';
 ALTER TABLE part_5 ATTACH PARTITION part5_p1 FOR VALUES IN ('y');
@@ -3992,7 +3992,7 @@ DROP TABLE fail_part;
 CREATE TABLE hpart_2 (LIKE hash_parted);
 INSERT INTO hpart_2 VALUES (3, 0);
 ALTER TABLE hash_parted ATTACH PARTITION hpart_2 FOR VALUES WITH (MODULUS 4, REMAINDER 1);
-ERROR:  partition constraint is violated by some row
+ERROR:  partition constraint of relation "hpart_2" is violated by some row
 -- should be ok after deleting the bad row
 DELETE FROM hpart_2;
 ALTER TABLE hash_parted ATTACH PARTITION hpart_2 FOR VALUES WITH (MODULUS 4, REMAINDER 1);
@@ -4005,7 +4005,7 @@ CREATE TABLE hpart_5 (
 CREATE TABLE hpart_5_a PARTITION OF hpart_5 FOR VALUES IN ('1', '2', '3');
 INSERT INTO hpart_5_a (a, b) VALUES (7, 1);
 ALTER TABLE hash_parted ATTACH PARTITION hpart_5 FOR VALUES WITH (MODULUS 4, REMAINDER 2);
-ERROR:  partition constraint is violated by some row
+ERROR:  partition constraint of relation "hpart_5_a" is violated by some row
 -- should be ok after deleting the bad row
 DELETE FROM hpart_5_a;
 ALTER TABLE hash_parted ATTACH PARTITION hpart_5 FOR VALUES WITH (MODULUS 4, REMAINDER 2);
@@ -4172,7 +4172,7 @@ alter table p1 attach partition p11 for values from (2) to (5);
 insert into p1 (a, b) values (2, 3);
 -- check that partition validation scan correctly detects violating rows
 alter table p attach partition p1 for values from (1, 2) to (1, 10);
-ERROR:  partition constraint is violated by some row
+ERROR:  partition constraint of relation "p11" is violated by some row
 -- cleanup
 drop table p;
 drop table p1;
@@ -4200,7 +4200,7 @@ insert into defpart_attach_test_d values (1), (2);
 -- error because its constraint as the default partition would be violated
 -- by the row containing 1
 alter table defpart_attach_test attach partition defpart_attach_test_d default;
-ERROR:  partition constraint is violated by some row
+ERROR:  partition constraint of relation "defpart_attach_test_d" is violated by some row
 delete from defpart_attach_test_d where a = 1;
 alter table defpart_attach_test_d add check (a > 1);
 -- should be attached successfully and without needing to be scanned
@@ -4210,7 +4210,7 @@ alter table defpart_attach_test attach partition defpart_attach_test_d default;
 -- successfully
 create table defpart_attach_test_2 (like defpart_attach_test_d);
 alter table defpart_attach_test attach partition defpart_attach_test_2 for values in (2);
-ERROR:  updated partition constraint for default partition would be violated by some row
+ERROR:  updated partition constraint for default partition "defpart_attach_test_d" would be violated by some row
 drop table defpart_attach_test;
 -- check combinations of temporary and permanent relations when attaching
 -- partitions.
diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out
index c53ed3e..e40287d 100644
--- a/src/test/regress/expected/copy2.out
+++ b/src/test/regress/expected/copy2.out
@@ -440,7 +440,7 @@ SELECT c, d FROM forcetest WHERE a = 2;
 -- should fail with not-null constraint violation
 BEGIN;
 COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NULL(b), FORCE_NOT_NULL(c));
-ERROR:  null value in column "b" violates not-null constraint
+ERROR:  null value in column "b" of relation "forcetest" violates not-null constraint
 DETAIL:  Failing row contains (3, null, , null, null).
 CONTEXT:  COPY forcetest, line 1: "3,,"""
 ROLLBACK;
diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out
index b64f919..c5e95ed 100644
--- a/src/test/regress/expected/create_table.out
+++ b/src/test/regress/expected/create_table.out
@@ -955,7 +955,7 @@ CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10);
 create table parted_notnull_inh_test (a int default 1, b int not null default 0) partition by list (a);
 create table parted_notnull_inh_test1 partition of parted_notnull_inh_test (a not null, b default 1) for values in (1);
 insert into parted_notnull_inh_test (b) values (null);
-ERROR:  null value in column "b" violates not-null constraint
+ERROR:  null value in column "b" of relation "parted_notnull_inh_test1" violates not-null constraint
 DETAIL:  Failing row contains (1, null).
 -- note that while b's default is overriden, a's default is preserved
 \d parted_notnull_inh_test1
diff --git a/src/test/regress/expected/create_table_like.out b/src/test/regress/expected/create_table_like.out
index 2a063a8..94d4858 100644
--- a/src/test/regress/expected/create_table_like.out
+++ b/src/test/regress/expected/create_table_like.out
@@ -90,7 +90,7 @@ CREATE TABLE test_like_id_2 (LIKE test_like_id_1);
  b      | text   |           |          | 
 
 INSERT INTO test_like_id_2 (b) VALUES ('b2');
-ERROR:  null value in column "a" violates not-null constraint
+ERROR:  null value in column "a" of relation "test_like_id_2" violates not-null constraint
 DETAIL:  Failing row contains (null, b2).
 SELECT * FROM test_like_id_2;  -- identity was not copied
  a | b 
diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out
index 4ff1b4a..2a033a6 100644
--- a/src/test/regress/expected/domain.out
+++ b/src/test/regress/expected/domain.out
@@ -542,12 +542,12 @@ ERROR:  domain dnotnull does not allow null values
 INSERT INTO nulltest values ('a', NULL, 'c', 'd', 'c');
 ERROR:  domain dnotnull does not allow null values
 INSERT INTO nulltest values ('a', 'b', NULL, 'd', 'c');
-ERROR:  null value in column "col3" violates not-null constraint
+ERROR:  null value in column "col3" of relation "nulltest" violates not-null constraint
 DETAIL:  Failing row contains (a, b, null, d, c).
 INSERT INTO nulltest values ('a', 'b', 'c', NULL, 'd'); -- Good
 -- Test copy
 COPY nulltest FROM stdin; --fail
-ERROR:  null value in column "col3" violates not-null constraint
+ERROR:  null value in column "col3" of relation "nulltest" violates not-null constraint
 DETAIL:  Failing row contains (a, b, null, d, d).
 CONTEXT:  COPY nulltest, line 1: "a	b	\N	d	d"
 COPY nulltest FROM stdin; --fail
@@ -601,14 +601,14 @@ create table defaulttest
             , col8 ddef5
             );
 insert into defaulttest(col4) values(0); -- fails, col5 defaults to null
-ERROR:  null value in column "col5" violates not-null constraint
+ERROR:  null value in column "col5" of relation "defaulttest" violates not-null constraint
 DETAIL:  Failing row contains (3, 12, 5, 0, null, 88, 8000, 12.12).
 alter table defaulttest alter column col5 drop default;
 insert into defaulttest default values; -- succeeds, inserts domain default
 -- We used to treat SET DEFAULT NULL as equivalent to DROP DEFAULT; wrong
 alter table defaulttest alter column col5 set default null;
 insert into defaulttest(col4) values(0); -- fails
-ERROR:  null value in column "col5" violates not-null constraint
+ERROR:  null value in column "col5" of relation "defaulttest" violates not-null constraint
 DETAIL:  Failing row contains (3, 12, 5, 0, null, 88, 8000, 12.12).
 alter table defaulttest alter column col5 drop default;
 insert into defaulttest default values;
diff --git a/src/test/regress/expected/generated.out b/src/test/regress/expected/generated.out
index a6d3670..620579a 100644
--- a/src/test/regress/expected/generated.out
+++ b/src/test/regress/expected/generated.out
@@ -406,24 +406,24 @@ CREATE TABLE gtest20a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STOR
 INSERT INTO gtest20a (a) VALUES (10);
 INSERT INTO gtest20a (a) VALUES (30);
 ALTER TABLE gtest20a ADD CHECK (b < 50);  -- fails on existing row
-ERROR:  check constraint "gtest20a_b_check" is violated by some row
+ERROR:  check constraint "gtest20a_b_check" of relation "gtest20a" is violated by some row
 CREATE TABLE gtest20b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED);
 INSERT INTO gtest20b (a) VALUES (10);
 INSERT INTO gtest20b (a) VALUES (30);
 ALTER TABLE gtest20b ADD CONSTRAINT chk CHECK (b < 50) NOT VALID;
 ALTER TABLE gtest20b VALIDATE CONSTRAINT chk;  -- fails on existing row
-ERROR:  check constraint "chk" is violated by some row
+ERROR:  check constraint "chk" of relation "gtest20b" is violated by some row
 -- not-null constraints
 CREATE TABLE gtest21a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED NOT NULL);
 INSERT INTO gtest21a (a) VALUES (1);  -- ok
 INSERT INTO gtest21a (a) VALUES (0);  -- violates constraint
-ERROR:  null value in column "b" violates not-null constraint
+ERROR:  null value in column "b" of relation "gtest21a" violates not-null constraint
 DETAIL:  Failing row contains (0, null).
 CREATE TABLE gtest21b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED);
 ALTER TABLE gtest21b ALTER COLUMN b SET NOT NULL;
 INSERT INTO gtest21b (a) VALUES (1);  -- ok
 INSERT INTO gtest21b (a) VALUES (0);  -- violates constraint
-ERROR:  null value in column "b" violates not-null constraint
+ERROR:  null value in column "b" of relation "gtest21b" violates not-null constraint
 DETAIL:  Failing row contains (0, null).
 ALTER TABLE gtest21b ALTER COLUMN b DROP NOT NULL;
 INSERT INTO gtest21b (a) VALUES (0);  -- ok now
diff --git a/src/test/regress/expected/identity.out b/src/test/regress/expected/identity.out
index 1a614b8..7322b28 100644
--- a/src/test/regress/expected/identity.out
+++ b/src/test/regress/expected/identity.out
@@ -186,7 +186,7 @@ ERROR:  column "a" of relation "itest4" is not an identity column
 ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY IF EXISTS;  -- noop
 NOTICE:  column "a" of relation "itest4" is not an identity column, skipping
 INSERT INTO itest4 DEFAULT VALUES;  -- fails because NOT NULL is not dropped
-ERROR:  null value in column "a" violates not-null constraint
+ERROR:  null value in column "a" of relation "itest4" violates not-null constraint
 DETAIL:  Failing row contains (null, ).
 ALTER TABLE itest4 ALTER COLUMN a DROP NOT NULL;
 INSERT INTO itest4 DEFAULT VALUES;
@@ -414,7 +414,7 @@ INSERT INTO itest8 VALUES(0), (1);
 ALTER TABLE itest8
   ADD COLUMN f22 int NOT NULL,
   ALTER COLUMN f22 ADD GENERATED ALWAYS AS IDENTITY;
-ERROR:  column "f22" contains null values
+ERROR:  column "f22" of relation "itest8" contains null values
 TABLE itest8;
  f1 | f2 | f3 | f4 | f5 
 ----+----+----+----+----
diff --git a/src/test/regress/expected/index_including.out b/src/test/regress/expected/index_including.out
index 2405709..8e5d53e 100644
--- a/src/test/regress/expected/index_including.out
+++ b/src/test/regress/expected/index_including.out
@@ -124,7 +124,7 @@ INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x
 ERROR:  duplicate key value violates unique constraint "covering"
 DETAIL:  Key (c1, c2)=(1, 2) already exists.
 INSERT INTO tbl SELECT 1, NULL, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
-ERROR:  null value in column "c2" violates not-null constraint
+ERROR:  null value in column "c2" of relation "tbl" violates not-null constraint
 DETAIL:  Failing row contains (1, null, 3, (4,4),(4,4)).
 INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,300) AS x;
 explain (costs off)
@@ -202,7 +202,7 @@ INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x
 ERROR:  duplicate key value violates unique constraint "tbl_pkey"
 DETAIL:  Key (c1, c2)=(1, 2) already exists.
 INSERT INTO tbl SELECT 1, NULL, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;
-ERROR:  null value in column "c2" violates not-null constraint
+ERROR:  null value in column "c2" of relation "tbl" violates not-null constraint
 DETAIL:  Failing row contains (1, null, 3, (4,4),(4,4)).
 INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,10) AS x;
 DROP TABLE tbl;
diff --git a/src/test/regress/expected/inherit.out b/src/test/regress/expected/inherit.out
index d8f56d2..dfd0ee4 100644
--- a/src/test/regress/expected/inherit.out
+++ b/src/test/regress/expected/inherit.out
@@ -537,7 +537,7 @@ SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid;
 -- Confirm PRIMARY KEY adds NOT NULL constraint to child table
 CREATE TEMP TABLE z (b TEXT, PRIMARY KEY(aa, b)) inherits (a);
 INSERT INTO z VALUES (NULL, 'text'); -- should fail
-ERROR:  null value in column "aa" violates not-null constraint
+ERROR:  null value in column "aa" of relation "z" violates not-null constraint
 DETAIL:  Failing row contains (null, text).
 -- Check inherited UPDATE with all children excluded
 create table some_tab (a int, b int);
@@ -940,9 +940,9 @@ create table p2(f2 int);
 create table c1(f3 int) inherits(p1,p2);
 insert into c1 values(1,-1,2);
 alter table p2 add constraint cc check (f2>0);  -- fail
-ERROR:  check constraint "cc" is violated by some row
+ERROR:  check constraint "cc" of relation "c1" is violated by some row
 alter table p2 add check (f2>0);  -- check it without a name, too
-ERROR:  check constraint "p2_f2_check" is violated by some row
+ERROR:  check constraint "p2_f2_check" of relation "c1" is violated by some row
 delete from c1;
 insert into c1 values(1,1,2);
 alter table p2 add check (f2>0);
diff --git a/src/test/regress/expected/insert.out b/src/test/regress/expected/insert.out
index 75e25cd..45d77ba 100644
--- a/src/test/regress/expected/insert.out
+++ b/src/test/regress/expected/insert.out
@@ -3,7 +3,7 @@
 --
 create table inserttest (col1 int4, col2 int4 NOT NULL, col3 text default 'testing');
 insert into inserttest (col1, col2, col3) values (DEFAULT, DEFAULT, DEFAULT);
-ERROR:  null value in column "col2" violates not-null constraint
+ERROR:  null value in column "col2" of relation "inserttest" violates not-null constraint
 DETAIL:  Failing row contains (null, null, testing).
 insert into inserttest (col2, col3) values (3, DEFAULT);
 insert into inserttest (col1, col2, col3) values (DEFAULT, 5, DEFAULT);
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
index 0ddbd8e..6674f26 100644
--- a/src/test/regress/expected/privileges.out
+++ b/src/test/regress/expected/privileges.out
@@ -592,13 +592,13 @@ ERROR:  duplicate key value violates unique constraint "t1_pkey"
 UPDATE t1 SET c2 = 1; -- fail, but row not shown
 ERROR:  duplicate key value violates unique constraint "t1_pkey"
 INSERT INTO t1 (c1, c2) VALUES (null, null); -- fail, but see columns being inserted
-ERROR:  null value in column "c1" violates not-null constraint
+ERROR:  null value in column "c1" of relation "t1" violates not-null constraint
 DETAIL:  Failing row contains (c1, c2) = (null, null).
 INSERT INTO t1 (c3) VALUES (null); -- fail, but see columns being inserted or have SELECT
-ERROR:  null value in column "c1" violates not-null constraint
+ERROR:  null value in column "c1" of relation "t1" violates not-null constraint
 DETAIL:  Failing row contains (c1, c3) = (null, null).
 INSERT INTO t1 (c1) VALUES (5); -- fail, but see columns being inserted or have SELECT
-ERROR:  null value in column "c2" violates not-null constraint
+ERROR:  null value in column "c2" of relation "t1" violates not-null constraint
 DETAIL:  Failing row contains (c1) = (5).
 UPDATE t1 SET c3 = 10; -- fail, but see columns with SELECT rights, or being modified
 ERROR:  new row for relation "t1" violates check constraint "t1_c3_check"
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 7cb7467..44c1304 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -100,7 +100,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 (1 row)
 
 INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL);
-ERROR:  null value in column "i" violates not-null constraint
+ERROR:  null value in column "i" of relation "reloptions_test" violates not-null constraint
 DETAIL:  Failing row contains (null, null).
 VACUUM reloptions_test;
 SELECT pg_relation_size('reloptions_test') > 0;
@@ -125,7 +125,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 (1 row)
 
 INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL);
-ERROR:  null value in column "i" violates not-null constraint
+ERROR:  null value in column "i" of relation "reloptions_test" violates not-null constraint
 DETAIL:  Failing row contains (null, null).
 VACUUM reloptions_test;
 SELECT pg_relation_size('reloptions_test') = 0;
diff --git a/src/test/regress/expected/sequence.out b/src/test/regress/expected/sequence.out
index 75eb501..8b928b2 100644
--- a/src/test/regress/expected/sequence.out
+++ b/src/test/regress/expected/sequence.out
@@ -69,7 +69,7 @@ INSERT INTO serialTest1 VALUES ('foo');
 INSERT INTO serialTest1 VALUES ('bar');
 INSERT INTO serialTest1 VALUES ('force', 100);
 INSERT INTO serialTest1 VALUES ('wrong', NULL);
-ERROR:  null value in column "f2" violates not-null constraint
+ERROR:  null value in column "f2" of relation "serialtest1" violates not-null constraint
 DETAIL:  Failing row contains (wrong, null).
 SELECT * FROM serialTest1;
   f1   | f2  
diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out
index f4250a4..0cfe28e 100644
--- a/src/test/regress/expected/vacuum.out
+++ b/src/test/regress/expected/vacuum.out
@@ -164,7 +164,7 @@ VACUUM (INDEX_CLEANUP FALSE, FREEZE TRUE) vaccluster;
 CREATE TABLE vac_truncate_test(i INT NOT NULL, j text)
 	WITH (vacuum_truncate=true, autovacuum_enabled=false);
 INSERT INTO vac_truncate_test VALUES (1, NULL), (NULL, NULL);
-ERROR:  null value in column "i" violates not-null constraint
+ERROR:  null value in column "i" of relation "vac_truncate_test" violates not-null constraint
 DETAIL:  Failing row contains (null, null).
 VACUUM (TRUNCATE FALSE) vac_truncate_test;
 SELECT pg_relation_size('vac_truncate_test') > 0;
diff --git a/src/test/regress/output/constraints.source b/src/test/regress/output/constraints.source
index e27caed..b727c61 100644
--- a/src/test/regress/output/constraints.source
+++ b/src/test/regress/output/constraints.source
@@ -377,7 +377,7 @@ DETAIL:  Key (i)=(1) already exists.
 INSERT INTO PRIMARY_TBL VALUES (4, 'three');
 INSERT INTO PRIMARY_TBL VALUES (5, 'one');
 INSERT INTO PRIMARY_TBL (t) VALUES ('six');
-ERROR:  null value in column "i" violates not-null constraint
+ERROR:  null value in column "i" of relation "primary_tbl" violates not-null constraint
 DETAIL:  Failing row contains (null, six).
 SELECT '' AS four, * FROM PRIMARY_TBL;
  four | i |   t   
@@ -397,7 +397,7 @@ INSERT INTO PRIMARY_TBL VALUES (1, 'three');
 INSERT INTO PRIMARY_TBL VALUES (4, 'three');
 INSERT INTO PRIMARY_TBL VALUES (5, 'one');
 INSERT INTO PRIMARY_TBL (t) VALUES ('six');
-ERROR:  null value in column "i" violates not-null constraint
+ERROR:  null value in column "i" of relation "primary_tbl" violates not-null constraint
 DETAIL:  Failing row contains (null, six).
 SELECT '' AS three, * FROM PRIMARY_TBL;
  three | i |   t   
-- 
1.8.3.1

#26Tom Lane
tgl@sss.pgh.pa.us
In reply to: Amit Kapila (#25)
Re: Error message inconsistency

Amit Kapila <amit.kapila16@gmail.com> writes:

LGTM. I have combined them into the single patch. What do we think
about backpatching this?

No objection to the patch for HEAD, but it does not seem like
back-patch material: it is not fixing a bug.

regards, tom lane

#27Amit Kapila
amit.kapila16@gmail.com
In reply to: Tom Lane (#26)
Re: Error message inconsistency

On Fri, Jan 24, 2020 at 9:37 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Amit Kapila <amit.kapila16@gmail.com> writes:

LGTM. I have combined them into the single patch. What do we think
about backpatching this?

No objection to the patch for HEAD, but it does not seem like
back-patch material: it is not fixing a bug.

Okay, I will commit this early next week (by Tuesday).

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#28Robert Haas
robertmhaas@gmail.com
In reply to: Amit Kapila (#25)
Re: Error message inconsistency

On Fri, Jan 24, 2020 at 12:22 AM Amit Kapila <amit.kapila16@gmail.com> wrote:

One thing to note is that there are places in code where we use
'table' instead of 'relation' for the same thing in the error messages
as seen in the below places (the first one uses 'relation', the second
one uses 'table') and the patch is using 'relation' which I think is
fine.

We often use "relation" as a sort of a weasel-word when we don't know
the relkind; i.e. when we're complaining about something that might be
a view or index or foreign table or whatever. If we say "table," we
need to know that it is, precisely, a table.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

#29Amit Kapila
amit.kapila16@gmail.com
In reply to: Amit Kapila (#27)
Re: Error message inconsistency

On Sat, Jan 25, 2020 at 10:16 AM Amit Kapila <amit.kapila16@gmail.com> wrote:

On Fri, Jan 24, 2020 at 9:37 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Amit Kapila <amit.kapila16@gmail.com> writes:

LGTM. I have combined them into the single patch. What do we think
about backpatching this?

No objection to the patch for HEAD, but it does not seem like
back-patch material: it is not fixing a bug.

Okay, I will commit this early next week (by Tuesday).

Pushed.

--
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#30Mahendra Singh Thalor
mahi6run@gmail.com
In reply to: Amit Kapila (#29)
Re: Error message inconsistency

On Tue, 28 Jan 2020 at 18:13, Amit Kapila <amit.kapila16@gmail.com> wrote:

On Sat, Jan 25, 2020 at 10:16 AM Amit Kapila <amit.kapila16@gmail.com> wrote:

On Fri, Jan 24, 2020 at 9:37 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Amit Kapila <amit.kapila16@gmail.com> writes:

LGTM. I have combined them into the single patch. What do we think
about backpatching this?

No objection to the patch for HEAD, but it does not seem like
back-patch material: it is not fixing a bug.

Okay, I will commit this early next week (by Tuesday).

Pushed.

Thank you for committing it!

--
Thanks and Regards
Mahendra Singh Thalor
EnterpriseDB: http://www.enterprisedb.com