diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2006-03-23 00:19:30 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2006-03-23 00:19:30 +0000 |
commit | 19956e0d5388b11a1cc3eaf2dbf628aa531ce331 (patch) | |
tree | f2c7071f4daee4588d4c004d809bd327baa4adde /src/backend/parser/parse_target.c | |
parent | a3f0b3d68f9a5357a3f72b40a45bcc714a9e0649 (diff) | |
download | postgresql-19956e0d5388b11a1cc3eaf2dbf628aa531ce331.tar.gz postgresql-19956e0d5388b11a1cc3eaf2dbf628aa531ce331.zip |
Add error location info to ResTarget parse nodes. Allows error cursor to be supplied
for various mistakes involving INSERT and UPDATE target columns.
Diffstat (limited to 'src/backend/parser/parse_target.c')
-rw-r--r-- | src/backend/parser/parse_target.c | 70 |
1 files changed, 51 insertions, 19 deletions
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index 300e02d90b9..4e3c47eb208 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -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); } |