diff options
author | Michael Paquier <michael@paquier.xyz> | 2024-12-16 14:52:11 +0900 |
---|---|---|
committer | Michael Paquier <michael@paquier.xyz> | 2024-12-16 14:52:11 +0900 |
commit | 39240bcad56dc51a7896d04a1e066efcf988b58f (patch) | |
tree | e85b9529dd7f21273581e7b78cd868c4b648c38c | |
parent | 3ad8b840ce8b1d7279f2d0d5fb7d346c0a6a3e8d (diff) | |
download | postgresql-39240bcad56dc51a7896d04a1e066efcf988b58f.tar.gz postgresql-39240bcad56dc51a7896d04a1e066efcf988b58f.zip |
Print out error position for CREATE DOMAIN
This is simply done by pushing down the ParseState available in
ProcessUtility() to DefineDomain(), giving more information about the
position of an error when running a CREATE DOMAIN query.
Most of the queries impacted by this change have been added previously
in 0172b4c9449e.
Author: Kirill Reshke, Jian He
Reviewed-by: Álvaro Herrera, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/CALdSSPhqfvKbDwqJaY=yEePi_aq61GmMpW88i6ZH7CMG_2Z4Cg@mail.gmail.com
-rw-r--r-- | src/backend/commands/typecmds.c | 58 | ||||
-rw-r--r-- | src/backend/tcop/utility.c | 2 | ||||
-rw-r--r-- | src/include/commands/typecmds.h | 2 | ||||
-rw-r--r-- | src/test/regress/expected/collate.icu.utf8.out | 2 | ||||
-rw-r--r-- | src/test/regress/expected/collate.linux.utf8.out | 2 | ||||
-rw-r--r-- | src/test/regress/expected/collate.out | 2 | ||||
-rw-r--r-- | src/test/regress/expected/collate.windows.win1252.out | 2 | ||||
-rw-r--r-- | src/test/regress/expected/domain.out | 26 |
8 files changed, 70 insertions, 26 deletions
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index da591c0922b..61273139560 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -694,7 +694,7 @@ RemoveTypeById(Oid typeOid) * Registers a new domain. */ ObjectAddress -DefineDomain(CreateDomainStmt *stmt) +DefineDomain(ParseState *pstate, CreateDomainStmt *stmt) { char *domainName; char *domainArrayName; @@ -761,7 +761,7 @@ DefineDomain(CreateDomainStmt *stmt) /* * Look up the base type. */ - typeTup = typenameType(NULL, stmt->typeName, &basetypeMod); + typeTup = typenameType(pstate, stmt->typeName, &basetypeMod); baseType = (Form_pg_type) GETSTRUCT(typeTup); basetypeoid = baseType->oid; @@ -783,7 +783,8 @@ DefineDomain(CreateDomainStmt *stmt) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("\"%s\" is not a valid base type for a domain", - TypeNameToString(stmt->typeName)))); + TypeNameToString(stmt->typeName)), + parser_errposition(pstate, stmt->typeName->location))); aclresult = object_aclcheck(TypeRelationId, basetypeoid, GetUserId(), ACL_USAGE); if (aclresult != ACLCHECK_OK) @@ -809,7 +810,8 @@ DefineDomain(CreateDomainStmt *stmt) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("collations are not supported by type %s", - format_type_be(basetypeoid)))); + format_type_be(basetypeoid)), + parser_errposition(pstate, stmt->typeName->location))); /* passed by value */ byValue = baseType->typbyval; @@ -879,18 +881,15 @@ DefineDomain(CreateDomainStmt *stmt) */ if (saw_default) ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("multiple default expressions"))); + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("multiple default expressions"), + parser_errposition(pstate, constr->location)); saw_default = true; if (constr->raw_expr) { - ParseState *pstate; Node *defaultExpr; - /* Create a dummy ParseState for transformExpr */ - pstate = make_parsestate(NULL); - /* * Cook the constr->raw_expr into an expression. Note: * name is strictly for error message @@ -942,12 +941,14 @@ DefineDomain(CreateDomainStmt *stmt) case CONSTR_NOTNULL: if (nullDefined && !typNotNull) ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting NULL/NOT NULL constraints"))); + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting NULL/NOT NULL constraints"), + parser_errposition(pstate, constr->location)); if (constr->is_no_inherit) ereport(ERROR, errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("not-null constraints for domains cannot be marked NO INHERIT")); + errmsg("not-null constraints for domains cannot be marked NO INHERIT"), + parser_errposition(pstate, constr->location)); typNotNull = true; nullDefined = true; break; @@ -955,8 +956,9 @@ DefineDomain(CreateDomainStmt *stmt) case CONSTR_NULL: if (nullDefined && typNotNull) ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting NULL/NOT NULL constraints"))); + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting NULL/NOT NULL constraints"), + parser_errposition(pstate, constr->location)); typNotNull = false; nullDefined = true; break; @@ -971,8 +973,10 @@ DefineDomain(CreateDomainStmt *stmt) */ if (constr->is_no_inherit) ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("check constraints for domains cannot be marked NO INHERIT"))); + errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("check constraints for domains cannot be marked NO INHERIT"), + parser_errposition(pstate, constr->location)); + break; /* @@ -980,26 +984,30 @@ DefineDomain(CreateDomainStmt *stmt) */ case CONSTR_UNIQUE: ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("unique constraints not possible for domains"))); + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("unique constraints not possible for domains"), + parser_errposition(pstate, constr->location)); break; case CONSTR_PRIMARY: ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("primary key constraints not possible for domains"))); + errmsg("primary key constraints not possible for domains"), + parser_errposition(pstate, constr->location))); break; case CONSTR_EXCLUSION: ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("exclusion constraints not possible for domains"))); + errmsg("exclusion constraints not possible for domains"), + parser_errposition(pstate, constr->location))); break; case CONSTR_FOREIGN: ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("foreign key constraints not possible for domains"))); + errmsg("foreign key constraints not possible for domains"), + parser_errposition(pstate, constr->location))); break; case CONSTR_ATTR_DEFERRABLE: @@ -1008,14 +1016,16 @@ DefineDomain(CreateDomainStmt *stmt) case CONSTR_ATTR_IMMEDIATE: ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("specifying constraint deferrability not supported for domains"))); + errmsg("specifying constraint deferrability not supported for domains"), + parser_errposition(pstate, constr->location))); break; case CONSTR_GENERATED: case CONSTR_IDENTITY: ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("specifying GENERATED not supported for domains"))); + errmsg("specifying GENERATED not supported for domains"), + parser_errposition(pstate, constr->location))); break; /* no default, to let compiler warn about missing case */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index f28bf371059..33dea5a781c 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1712,7 +1712,7 @@ ProcessUtilitySlow(ParseState *pstate, break; case T_CreateDomainStmt: - address = DefineDomain((CreateDomainStmt *) parsetree); + address = DefineDomain(pstate, (CreateDomainStmt *) parsetree); break; case T_CreateConversionStmt: diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h index e1b02927c4b..cb30d1a2583 100644 --- a/src/include/commands/typecmds.h +++ b/src/include/commands/typecmds.h @@ -23,7 +23,7 @@ extern ObjectAddress DefineType(ParseState *pstate, List *names, List *parameters); extern void RemoveTypeById(Oid typeOid); -extern ObjectAddress DefineDomain(CreateDomainStmt *stmt); +extern ObjectAddress DefineDomain(ParseState *pstate, CreateDomainStmt *stmt); extern ObjectAddress DefineEnum(CreateEnumStmt *stmt); extern ObjectAddress DefineRange(ParseState *pstate, CreateRangeStmt *stmt); extern ObjectAddress AlterEnum(AlterEnumStmt *stmt); diff --git a/src/test/regress/expected/collate.icu.utf8.out b/src/test/regress/expected/collate.icu.utf8.out index 6cbadafcfbf..d4f327636fd 100644 --- a/src/test/regress/expected/collate.icu.utf8.out +++ b/src/test/regress/expected/collate.icu.utf8.out @@ -120,6 +120,8 @@ LINE 1: ...* FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "e... CREATE DOMAIN testdomain_sv AS text COLLATE "sv-x-icu"; CREATE DOMAIN testdomain_i AS int COLLATE "sv-x-icu"; -- fails ERROR: collations are not supported by type integer +LINE 1: CREATE DOMAIN testdomain_i AS int COLLATE "sv-x-icu"; + ^ CREATE TABLE collate_test4 ( a int, b testdomain_sv diff --git a/src/test/regress/expected/collate.linux.utf8.out b/src/test/regress/expected/collate.linux.utf8.out index 01664f7c1b5..fbaab7cdf83 100644 --- a/src/test/regress/expected/collate.linux.utf8.out +++ b/src/test/regress/expected/collate.linux.utf8.out @@ -122,6 +122,8 @@ LINE 1: ...* FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "e... CREATE DOMAIN testdomain_sv AS text COLLATE "sv_SE"; CREATE DOMAIN testdomain_i AS int COLLATE "sv_SE"; -- fails ERROR: collations are not supported by type integer +LINE 1: CREATE DOMAIN testdomain_i AS int COLLATE "sv_SE"; + ^ CREATE TABLE collate_test4 ( a int, b testdomain_sv diff --git a/src/test/regress/expected/collate.out b/src/test/regress/expected/collate.out index 593a6226376..bf72908fbd3 100644 --- a/src/test/regress/expected/collate.out +++ b/src/test/regress/expected/collate.out @@ -73,6 +73,8 @@ LINE 1: ...* FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "P... CREATE DOMAIN testdomain_p AS text COLLATE "POSIX"; CREATE DOMAIN testdomain_i AS int COLLATE "POSIX"; -- fail ERROR: collations are not supported by type integer +LINE 1: CREATE DOMAIN testdomain_i AS int COLLATE "POSIX"; + ^ CREATE TABLE collate_test4 ( a int, b testdomain_p diff --git a/src/test/regress/expected/collate.windows.win1252.out b/src/test/regress/expected/collate.windows.win1252.out index 31f794988b3..4644f56b31d 100644 --- a/src/test/regress/expected/collate.windows.win1252.out +++ b/src/test/regress/expected/collate.windows.win1252.out @@ -124,6 +124,8 @@ LINE 1: ...* FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "e... CREATE DOMAIN testdomain_sv AS text COLLATE "sv_SE"; CREATE DOMAIN testdomain_i AS int COLLATE "sv_SE"; -- fails ERROR: collations are not supported by type integer +LINE 1: CREATE DOMAIN testdomain_i AS int COLLATE "sv_SE"; + ^ CREATE TABLE collate_test4 ( a int, b testdomain_sv diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out index d03ab128e48..7a2a717aeae 100644 --- a/src/test/regress/expected/domain.out +++ b/src/test/regress/expected/domain.out @@ -18,30 +18,56 @@ ERROR: type "domaindroptest" does not exist -- some error cases create domain d_fail as no_such_type; ERROR: type "no_such_type" does not exist +LINE 1: create domain d_fail as no_such_type; + ^ create domain d_fail as int constraint cc REFERENCES this_table_not_exists(i); ERROR: foreign key constraints not possible for domains +LINE 1: create domain d_fail as int constraint cc REFERENCES this_ta... + ^ create domain d_fail as int4 not null no inherit; ERROR: not-null constraints for domains cannot be marked NO INHERIT +LINE 1: create domain d_fail as int4 not null no inherit; + ^ create domain d_fail as int4 not null null; ERROR: conflicting NULL/NOT NULL constraints +LINE 1: create domain d_fail as int4 not null null; + ^ create domain d_fail as int4 not null default 3 default 3; ERROR: multiple default expressions +LINE 1: create domain d_fail as int4 not null default 3 default 3; + ^ create domain d_fail int4 DEFAULT 3 + 'h'; ERROR: invalid input syntax for type integer: "h" +LINE 1: create domain d_fail int4 DEFAULT 3 + 'h'; + ^ create domain d_fail int4 collate "C"; ERROR: collations are not supported by type integer +LINE 1: create domain d_fail int4 collate "C"; + ^ create domain d_fail as anyelement; ERROR: "anyelement" is not a valid base type for a domain +LINE 1: create domain d_fail as anyelement; + ^ create domain d_fail as int4 unique; ERROR: unique constraints not possible for domains +LINE 1: create domain d_fail as int4 unique; + ^ create domain d_fail as int4 PRIMARY key; ERROR: primary key constraints not possible for domains +LINE 1: create domain d_fail as int4 PRIMARY key; + ^ create domain d_fail as int4 constraint cc generated by default as identity; ERROR: specifying GENERATED not supported for domains +LINE 1: create domain d_fail as int4 constraint cc generated by defa... + ^ create domain d_fail as int4 constraint cc check (values > 1) no inherit; ERROR: check constraints for domains cannot be marked NO INHERIT +LINE 1: create domain d_fail as int4 constraint cc check (values > 1... + ^ create domain d_fail as int4 constraint cc check (values > 1) deferrable; ERROR: specifying constraint deferrability not supported for domains +LINE 1: ...n d_fail as int4 constraint cc check (values > 1) deferrable... + ^ -- Test domain input. -- Note: the point of checking both INSERT and COPY FROM is that INSERT -- exercises CoerceToDomain while COPY exercises domain_in. |