aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2024-12-16 14:52:11 +0900
committerMichael Paquier <michael@paquier.xyz>2024-12-16 14:52:11 +0900
commit39240bcad56dc51a7896d04a1e066efcf988b58f (patch)
treee85b9529dd7f21273581e7b78cd868c4b648c38c
parent3ad8b840ce8b1d7279f2d0d5fb7d346c0a6a3e8d (diff)
downloadpostgresql-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.c58
-rw-r--r--src/backend/tcop/utility.c2
-rw-r--r--src/include/commands/typecmds.h2
-rw-r--r--src/test/regress/expected/collate.icu.utf8.out2
-rw-r--r--src/test/regress/expected/collate.linux.utf8.out2
-rw-r--r--src/test/regress/expected/collate.out2
-rw-r--r--src/test/regress/expected/collate.windows.win1252.out2
-rw-r--r--src/test/regress/expected/domain.out26
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.