pg.ddx.io pgsql-hackers@postgresql.org mailing list archive
help / color / mirror / Atom feed From: Alexander Lakhin <exclusion@gmail.com>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Michael Paquier <michael@paquier.xyz>
Cc: Andres Freund <andres@anarazel.de>
Cc: pgsql-hackers <pgsql-hackers@postgresql.org>
Cc: Justin Pryzby <pryzby@telsasoft.com>
Subject: Re: Internal error codes triggered by regression tests and user queries, take 2
Date: Sat, 12 Sep 2026 14:00:00 +0300
Message-ID: <7a9b3652-134c-4565-82ad-839035a3a382@gmail.com> (raw )
In-Reply-To: <8343126e-11e5-48df-9f96-ea03a2b7d5ba@gmail.com >
References: <94ac928b-8370-4db5-ada5-579a9ebc089d@gmail.com >
<697477.1787754418@sss.pgh.pa.us >
<mosliefjrclrikqpsasjy5ibzowba6vwk4ygimouikiht2i5pb@5g562jqflxsz >
<73eb724a-c1a3-456c-be12-0375d4556b67@gmail.com >
<apUcBVyazHEW5pcg@paquier.xyz >
<91a1b0ab-2c6c-4471-b7a4-ee8ee8aed64e@gmail.com >
<126103.1788721678@sss.pgh.pa.us >
<8343126e-11e5-48df-9f96-ea03a2b7d5ba@gmail.com >
Hello Tom,
07.09.2026 00:00, Alexander Lakhin wrote:
>
> 06.09.2026 22:07, Tom Lane wrote:
>
>> @@ -794,8 +794,10 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
>> if (constraint->conname &&
>> notnull_constraint->conname &&
>> strcmp(notnull_constraint->conname, constraint->conname) != 0)
>> - elog(ERROR, "conflicting not-null constraint names \"%s\" and \"%s\"",
>> - notnull_constraint->conname, constraint->conname);
>> + ereport(ERROR,
>> + errcode(ERRCODE_SYNTAX_ERROR),
>> + errmsg("conflicting not-null constraint names \"%s\" and \"%s\"",
>> + notnull_constraint->conname, constraint->conname));
>>
>> This does not seem like a "syntax error". Perhaps
>> ERRCODE_INVALID_OBJECT_DEFINITION would serve?
>
> Yeah, I considered this, but the same errmsg in
> AddRelationNotNullConstraints() uses ERRCODE_SYNTAX_ERROR. I found it
> more consistent to emit the same code. Maybe it would make do the opposite
> -- change the errcode in AddRelationNotNullConstraints() (there are two
> instances there, though)... Moreover, ERRCODE_SYNTAX_ERROR is chosen for
> many other similar messages in transformColumnDefinition(), so I'm not
> sure if it makes sense to change all of those or just report "syntax error"
> for consistency while keeping the patch focused.
I've changed that occurrence to ERRCODE_INVALID_OBJECT_DEFINITION, but as
I mentioned above, transformColumnDefinition() has many other SYNTAX_ERRORs
(originating from a56ff9a0b), besides AddRelationNotNullConstraints().
Please find attached a patch to correct these too, for consistency, if you
find this appropriate. There are other similar errors in parse_utilcmd.c,
but I'd stop here unless we want to start a new campaign not to define,
but correct error codes according to some convention.
>> We'd be well advised to make those two messages more consistent,
>> whether they're worth translating or not. Also I guess a sweep
>> for other "unreachable" errors in typmodout functions might be
>> useful
Changed three occurrences to use the same errmsg and errcode.
Please look at the attached v3-Define-...patch, where I think I addressed
all of your comments.
Thank you for your time!
Best regards,
Alexander
Attachments:
[text/x-patch] v3-Define-missing-errcodes.patch (5.4K, ../7a9b3652-134c-4565-82ad-839035a3a382@gmail.com/2-v3-Define-missing-errcodes.patch)
download | inline diff:
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index b08e076e65f..c1b2e84146b 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -4064,7 +4064,9 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
}
default:
- elog(ERROR, "unsupported object class: %u", object->classId);
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("unsupported object class: %u", object->classId)));
}
/* an empty buffer is equivalent to no object found */
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 8dc70bfa0f1..5a2c9f02bf6 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -9621,6 +9621,7 @@ ATPrepAddPrimaryKey(List **wqueue, Relation rel, AlterTableCmd *cmd,
tup = findNotNullConstraint(childrelid, strVal(column));
if (!tup)
ereport(ERROR,
+ errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("column \"%s\" of table \"%s\" is not marked NOT NULL",
strVal(column), get_rel_name(childrelid)));
/* verify it's good enough */
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index f838311090b..f0c7755b8fb 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -805,8 +805,10 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
if (constraint->conname &&
notnull_constraint->conname &&
strcmp(notnull_constraint->conname, constraint->conname) != 0)
- elog(ERROR, "conflicting not-null constraint names \"%s\" and \"%s\"",
- notnull_constraint->conname, constraint->conname);
+ ereport(ERROR,
+ errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("conflicting not-null constraint names \"%s\" and \"%s\"",
+ notnull_constraint->conname, constraint->conname));
if (notnull_constraint->is_no_inherit != constraint->is_no_inherit)
ereport(ERROR,
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index f971ee24192..f78c34daee1 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -1210,7 +1210,9 @@ pg_get_shmem_allocations_numa(PG_FUNCTION_ARGS)
Size *nodes;
if (pg_numa_init() == -1)
- elog(ERROR, "libnuma initialization failed or NUMA is not supported on this platform");
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("libnuma initialization failed or NUMA is not supported on this platform")));
InitMaterializedSRF(fcinfo, 0);
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index a01d8f4bc41..913d715a8c8 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -989,7 +989,16 @@ acldefault_sql(PG_FUNCTION_ARGS)
objtype = OBJECT_TYPE;
break;
default:
- elog(ERROR, "unrecognized object type abbreviation: %c", objtypec);
+ /* Avoid printing non-ASCII bytes, else we have encoding issues */
+ if (objtypec >= ' ' && objtypec < 0x7f)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("unrecognized object type abbreviation: \"%c\"", objtypec)));
+ else /* use \ooo format, like charout() */
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("unrecognized object type abbreviation: \"\\%03o\"",
+ (unsigned char) objtypec)));
}
PG_RETURN_ACL_P(acldefault(objtype, owner));
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index 8ef16c9ad4c..43efa548452 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -1186,7 +1186,9 @@ intervaltypmodout(PG_FUNCTION_ARGS)
fieldstr = "";
break;
default:
- elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("unrecognized interval typmod: %d", typmod)));
fieldstr = "";
break;
}
@@ -1246,7 +1248,9 @@ intervaltypmodleastfield(int32 typmod)
case INTERVAL_FULL_RANGE:
return 0; /* SECOND */
default:
- elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("unrecognized interval typmod: %d", typmod)));
break;
}
return 0; /* can't get here, but keep compiler quiet */
@@ -1489,7 +1493,9 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod,
/* fractional-second rounding will be dealt with below */
}
else
- elog(ERROR, "unrecognized interval typmod: %d", typmod);
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("unrecognized interval typmod: %d", typmod)));
/* Need to adjust sub-second precision? */
if (precision != INTERVAL_FULL_PRECISION)
diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y
index 5e14a2d7302..37785f58cc2 100644
--- a/src/pl/plpgsql/src/pl_gram.y
+++ b/src/pl/plpgsql/src/pl_gram.y
@@ -393,7 +393,9 @@ comp_option : '#' K_OPTION K_DUMP
else if (strcmp($3, "off") == 0)
plpgsql_curr_compile->print_strict_params = false;
else
- elog(ERROR, "unrecognized print_strict_params option %s", $3);
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("unrecognized %s option \"%s\"", "print_strict_params", $3)));
}
| '#' K_VARIABLE_CONFLICT K_ERROR
{
[text/x-patch] v3-Correct-errcodes-in-transformColumnDefinition-AddRelationNotNullConstraints.patch (6.3K, ../7a9b3652-134c-4565-82ad-839035a3a382@gmail.com/3-v3-Correct-errcodes-in-transformColumnDefinition-AddRelationNotNullConstraints.patch)
download | inline diff:
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 1c188b7a0ff..f7fa1b901d1 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -3001,7 +3001,7 @@ AddRelationNotNullConstraints(Relation rel, List *constraints,
{
if (other->is_no_inherit != constr->is_no_inherit)
ereport(ERROR,
- errcode(ERRCODE_SYNTAX_ERROR),
+ errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("conflicting NO INHERIT declaration for not-null constraint on column \"%s\"",
strVal(linitial(constr->keys))));
@@ -3015,7 +3015,7 @@ AddRelationNotNullConstraints(Relation rel, List *constraints,
constr->conname = pstrdup(other->conname);
else if (strcmp(constr->conname, other->conname) != 0)
ereport(ERROR,
- errcode(ERRCODE_SYNTAX_ERROR),
+ errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("conflicting not-null constraint names \"%s\" and \"%s\"",
constr->conname, other->conname));
}
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index f0c7755b8fb..0210b568a1e 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -749,7 +749,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
case CONSTR_NULL:
if ((saw_nullable && column->is_not_null) || need_notnull)
ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"",
column->colname, cxt->relation->relname),
parser_errposition(cxt->pstate,
@@ -767,7 +767,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
/* Disallow conflicting [NOT] NULL markings */
if (saw_nullable && !column->is_not_null)
ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"",
column->colname, cxt->relation->relname),
parser_errposition(cxt->pstate,
@@ -775,7 +775,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
if (disallow_noinherit_notnull && constraint->is_no_inherit)
ereport(ERROR,
- errcode(ERRCODE_SYNTAX_ERROR),
+ errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("conflicting NO INHERIT declarations for not-null constraints on column \"%s\"",
column->colname));
@@ -812,7 +812,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
if (notnull_constraint->is_no_inherit != constraint->is_no_inherit)
ereport(ERROR,
- errcode(ERRCODE_SYNTAX_ERROR),
+ errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("conflicting NO INHERIT declarations for not-null constraints on column \"%s\"",
column->colname));
@@ -825,7 +825,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
case CONSTR_DEFAULT:
if (saw_default)
ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("multiple default values specified for column \"%s\" of table \"%s\"",
column->colname, cxt->relation->relname),
parser_errposition(cxt->pstate,
@@ -855,7 +855,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
if (saw_identity)
ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("multiple identity specifications for column \"%s\" of table \"%s\"",
column->colname, cxt->relation->relname),
parser_errposition(cxt->pstate,
@@ -877,7 +877,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
need_notnull = true;
else if (!column->is_not_null)
ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"",
column->colname, cxt->relation->relname),
parser_errposition(cxt->pstate,
@@ -892,7 +892,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
errmsg("generated columns are not supported on typed tables")));
if (saw_generated)
ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("multiple generation clauses specified for column \"%s\" of table \"%s\"",
column->colname, cxt->relation->relname),
parser_errposition(cxt->pstate,
@@ -910,7 +910,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
case CONSTR_PRIMARY:
if (saw_nullable && !column->is_not_null)
ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"",
column->colname, cxt->relation->relname),
parser_errposition(cxt->pstate,
@@ -975,7 +975,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
if (saw_default && saw_identity)
ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("both default and identity specified for column \"%s\" of table \"%s\"",
column->colname, cxt->relation->relname),
parser_errposition(cxt->pstate,
@@ -983,7 +983,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
if (saw_default && saw_generated)
ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("both default and generation expression specified for column \"%s\" of table \"%s\"",
column->colname, cxt->relation->relname),
parser_errposition(cxt->pstate,
@@ -991,7 +991,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
if (saw_identity && saw_generated)
ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("both identity and generation expression specified for column \"%s\" of table \"%s\"",
column->colname, cxt->relation->relname),
parser_errposition(cxt->pstate,
view thread (11+ messages) latest in thread
Message-ID: <7a9b3652-134c-4565-82ad-839035a3a382@gmail.com>
Permalink: ../7a9b3652-134c-4565-82ad-839035a3a382@gmail.com/
Also on: postgresql.org/message-id/7a9b3652-134c-4565-82ad-839035a3a382@gmail.com
copy link · copy postgr.es · copy git am
reply Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: exclusion@gmail.com, tgl@sss.pgh.pa.us, michael@paquier.xyz, andres@anarazel.de, pryzby@telsasoft.com
Subject: Re: Internal error codes triggered by regression tests and user queries, take 2
In-Reply-To: <7a9b3652-134c-4565-82ad-839035a3a382@gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox