v11-0001-Print-out-error-position-for-CreateDomainStmt.patch
text/x-patch
Filename: v11-0001-Print-out-error-position-for-CreateDomainStmt.patch
Type: text/x-patch
Part: 1
Patch
Format: format-patch
Series: patch v11-0001
Subject: Print out error position for CreateDomainStmt
| File | + | − |
|---|---|---|
| src/backend/commands/typecmds.c | 34 | 24 |
| src/backend/tcop/utility.c | 1 | 1 |
| src/include/commands/typecmds.h | 1 | 1 |
| src/test/regress/expected/collate.icu.utf8.out | 2 | 0 |
| src/test/regress/expected/collate.linux.utf8.out | 2 | 0 |
| src/test/regress/expected/collate.out | 2 | 0 |
| src/test/regress/expected/collate.windows.win1252.out | 2 | 0 |
| src/test/regress/expected/domain.out | 26 | 0 |
From 4b5f688e72f8dd1b6498347cd625c59c926a078e Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Thu, 12 Dec 2024 12:20:51 +0800
Subject: [PATCH v11 1/2] Print out error position for CreateDomainStmt
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
with this patch,
almost of all the user visible errors in DefineDomain will print out error position.
one of example:
CREATE DOMAIN testdomain_i AS int COLLATE "sv_SE";
ERROR: collations are not supported by type integer
LINE 1: CREATE DOMAIN testdomain_i AS int COLLATE "sv_SE";
^
Author: Kirill Reshke <reshkekirill@gmail.com>
Author: Jian He <jian.universality@gmail.com>
Reviewed-By: Michaël Paquier <michael@paquier.xyz>
Reviewed-By: Álvaro Herrera <alvherre@alvh.no-ip.org>
discussion: https://postgr.es/m/CALdSSPhqfvKbDwqJaY=yEePi_aq61GmMpW88i6ZH7CMG_2Z4Cg@mail.gmail.com
---
src/backend/commands/typecmds.c | 58 +++++++++++--------
src/backend/tcop/utility.c | 2 +-
src/include/commands/typecmds.h | 2 +-
.../regress/expected/collate.icu.utf8.out | 2 +
.../regress/expected/collate.linux.utf8.out | 2 +
src/test/regress/expected/collate.out | 2 +
.../expected/collate.windows.win1252.out | 2 +
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 da591c0922..6127313956 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 f28bf37105..33dea5a781 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 e1b02927c4..cb30d1a258 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 6cbadafcfb..d4f327636f 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 01664f7c1b..fbaab7cdf8 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 593a622637..bf72908fbd 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 31f794988b..4644f56b31 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 d03ab128e4..7a2a717aea 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.
--
2.34.1