mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-17 19:30:00 +08:00
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 0172b4c944
.
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
This commit is contained in:
parent
3ad8b840ce
commit
39240bcad5
@ -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 */
|
||||
|
@ -1712,7 +1712,7 @@ ProcessUtilitySlow(ParseState *pstate,
|
||||
break;
|
||||
|
||||
case T_CreateDomainStmt:
|
||||
address = DefineDomain((CreateDomainStmt *) parsetree);
|
||||
address = DefineDomain(pstate, (CreateDomainStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_CreateConversionStmt:
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user