mirror of
https://github.com/postgres/postgres.git
synced 2025-06-14 18:42:34 +03:00
Add error location info to ResTarget parse nodes. Allows error cursor to be supplied
for various mistakes involving INSERT and UPDATE target columns.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.141 2006/03/14 22:48:21 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.142 2006/03/23 00:19:30 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -40,7 +40,8 @@ static Node *transformAssignmentIndirection(ParseState *pstate,
|
||||
Oid targetTypeId,
|
||||
int32 targetTypMod,
|
||||
ListCell *indirection,
|
||||
Node *rhs);
|
||||
Node *rhs,
|
||||
int location);
|
||||
static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref);
|
||||
static List *ExpandAllTables(ParseState *pstate);
|
||||
static List *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind);
|
||||
@ -247,13 +248,15 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
|
||||
* colname target column name (ie, name of attribute to be assigned to)
|
||||
* attrno target attribute number
|
||||
* indirection subscripts/field names for target column, if any
|
||||
* location error cursor position (should point at column name), or -1
|
||||
*/
|
||||
void
|
||||
updateTargetListEntry(ParseState *pstate,
|
||||
TargetEntry *tle,
|
||||
char *colname,
|
||||
int attrno,
|
||||
List *indirection)
|
||||
List *indirection,
|
||||
int location)
|
||||
{
|
||||
Oid type_id; /* type of value provided */
|
||||
Oid attrtype; /* type of target column */
|
||||
@ -265,7 +268,8 @@ updateTargetListEntry(ParseState *pstate,
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot assign to system column \"%s\"",
|
||||
colname)));
|
||||
colname),
|
||||
parser_errposition(pstate, location)));
|
||||
attrtype = attnumTypeId(rd, attrno);
|
||||
attrtypmod = rd->rd_att->attrs[attrno - 1]->atttypmod;
|
||||
|
||||
@ -288,11 +292,13 @@ updateTargetListEntry(ParseState *pstate,
|
||||
if (IsA(linitial(indirection), A_Indices))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot set an array element to DEFAULT")));
|
||||
errmsg("cannot set an array element to DEFAULT"),
|
||||
parser_errposition(pstate, location)));
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot set a subfield to DEFAULT")));
|
||||
errmsg("cannot set a subfield to DEFAULT"),
|
||||
parser_errposition(pstate, location)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -336,7 +342,8 @@ updateTargetListEntry(ParseState *pstate,
|
||||
attrtype,
|
||||
attrtypmod,
|
||||
list_head(indirection),
|
||||
(Node *) tle->expr);
|
||||
(Node *) tle->expr,
|
||||
location);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -358,7 +365,8 @@ updateTargetListEntry(ParseState *pstate,
|
||||
colname,
|
||||
format_type_be(attrtype),
|
||||
format_type_be(type_id)),
|
||||
errhint("You will need to rewrite or cast the expression.")));
|
||||
errhint("You will need to rewrite or cast the expression."),
|
||||
parser_errposition(pstate, location)));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -395,6 +403,11 @@ updateTargetListEntry(ParseState *pstate,
|
||||
*
|
||||
* rhs is the already-transformed value to be assigned; note it has not been
|
||||
* coerced to any particular type.
|
||||
*
|
||||
* location is the cursor error position for any errors. (Note: this points
|
||||
* to the head of the target clause, eg "foo" in "foo.bar[baz]". Later we
|
||||
* might want to decorate indirection cells with their own location info,
|
||||
* in which case the location argument could probably be dropped.)
|
||||
*/
|
||||
static Node *
|
||||
transformAssignmentIndirection(ParseState *pstate,
|
||||
@ -404,7 +417,8 @@ transformAssignmentIndirection(ParseState *pstate,
|
||||
Oid targetTypeId,
|
||||
int32 targetTypMod,
|
||||
ListCell *indirection,
|
||||
Node *rhs)
|
||||
Node *rhs,
|
||||
int location)
|
||||
{
|
||||
Node *result;
|
||||
List *subscripts = NIL;
|
||||
@ -460,7 +474,8 @@ transformAssignmentIndirection(ParseState *pstate,
|
||||
typeNeeded,
|
||||
targetTypMod,
|
||||
i,
|
||||
rhs);
|
||||
rhs,
|
||||
location);
|
||||
/* process subscripts */
|
||||
return (Node *) transformArraySubscripts(pstate,
|
||||
basenode,
|
||||
@ -479,7 +494,8 @@ transformAssignmentIndirection(ParseState *pstate,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type",
|
||||
strVal(n), targetName,
|
||||
format_type_be(targetTypeId))));
|
||||
format_type_be(targetTypeId)),
|
||||
parser_errposition(pstate, location)));
|
||||
|
||||
attnum = get_attnum(typrelid, strVal(n));
|
||||
if (attnum == InvalidAttrNumber)
|
||||
@ -487,12 +503,14 @@ transformAssignmentIndirection(ParseState *pstate,
|
||||
(errcode(ERRCODE_UNDEFINED_COLUMN),
|
||||
errmsg("cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s",
|
||||
strVal(n), targetName,
|
||||
format_type_be(targetTypeId))));
|
||||
format_type_be(targetTypeId)),
|
||||
parser_errposition(pstate, location)));
|
||||
if (attnum < 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_COLUMN),
|
||||
errmsg("cannot assign to system column \"%s\"",
|
||||
strVal(n))));
|
||||
strVal(n)),
|
||||
parser_errposition(pstate, location)));
|
||||
|
||||
get_atttypetypmod(typrelid, attnum,
|
||||
&fieldTypeId, &fieldTypMod);
|
||||
@ -505,7 +523,8 @@ transformAssignmentIndirection(ParseState *pstate,
|
||||
fieldTypeId,
|
||||
fieldTypMod,
|
||||
lnext(i),
|
||||
rhs);
|
||||
rhs,
|
||||
location);
|
||||
|
||||
/* and build a FieldStore node */
|
||||
fstore = makeNode(FieldStore);
|
||||
@ -532,7 +551,8 @@ transformAssignmentIndirection(ParseState *pstate,
|
||||
typeNeeded,
|
||||
targetTypMod,
|
||||
NULL,
|
||||
rhs);
|
||||
rhs,
|
||||
location);
|
||||
/* process subscripts */
|
||||
return (Node *) transformArraySubscripts(pstate,
|
||||
basenode,
|
||||
@ -560,7 +580,8 @@ transformAssignmentIndirection(ParseState *pstate,
|
||||
targetName,
|
||||
format_type_be(targetTypeId),
|
||||
format_type_be(exprType(rhs))),
|
||||
errhint("You will need to rewrite or cast the expression.")));
|
||||
errhint("You will need to rewrite or cast the expression."),
|
||||
parser_errposition(pstate, location)));
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
@ -569,7 +590,8 @@ transformAssignmentIndirection(ParseState *pstate,
|
||||
targetName,
|
||||
format_type_be(targetTypeId),
|
||||
format_type_be(exprType(rhs))),
|
||||
errhint("You will need to rewrite or cast the expression.")));
|
||||
errhint("You will need to rewrite or cast the expression."),
|
||||
parser_errposition(pstate, location)));
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -607,6 +629,7 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
|
||||
col->name = pstrdup(NameStr(attr[i]->attname));
|
||||
col->indirection = NIL;
|
||||
col->val = NULL;
|
||||
col->location = -1;
|
||||
cols = lappend(cols, col);
|
||||
*attrnos = lappend_int(*attrnos, i + 1);
|
||||
}
|
||||
@ -628,6 +651,13 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
|
||||
|
||||
/* Lookup column name, ereport on failure */
|
||||
attrno = attnameAttNum(pstate->p_target_relation, name, false);
|
||||
if (attrno == InvalidAttrNumber)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_COLUMN),
|
||||
errmsg("column \"%s\" of relation \"%s\" does not exist",
|
||||
name,
|
||||
RelationGetRelationName(pstate->p_target_relation)),
|
||||
parser_errposition(pstate, col->location)));
|
||||
|
||||
/*
|
||||
* Check for duplicates, but only of whole columns --- we allow
|
||||
@ -641,7 +671,8 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DUPLICATE_COLUMN),
|
||||
errmsg("column \"%s\" specified more than once",
|
||||
name)));
|
||||
name),
|
||||
parser_errposition(pstate, col->location)));
|
||||
wholecols = bms_add_member(wholecols, attrno);
|
||||
}
|
||||
else
|
||||
@ -651,7 +682,8 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DUPLICATE_COLUMN),
|
||||
errmsg("column \"%s\" specified more than once",
|
||||
name)));
|
||||
name),
|
||||
parser_errposition(pstate, col->location)));
|
||||
partialcols = bms_add_member(partialcols, attrno);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user