aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_target.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-03-23 00:19:30 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-03-23 00:19:30 +0000
commit19956e0d5388b11a1cc3eaf2dbf628aa531ce331 (patch)
treef2c7071f4daee4588d4c004d809bd327baa4adde /src/backend/parser/parse_target.c
parenta3f0b3d68f9a5357a3f72b40a45bcc714a9e0649 (diff)
downloadpostgresql-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.c70
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);
}