diff options
Diffstat (limited to 'src/backend/parser')
-rw-r--r-- | src/backend/parser/analyze.c | 21 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 10 | ||||
-rw-r--r-- | src/backend/parser/parse_relation.c | 12 | ||||
-rw-r--r-- | src/backend/parser/parse_target.c | 70 |
4 files changed, 81 insertions, 32 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 1c4dc363034..39c562b8188 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.331 2006/03/14 22:48:20 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.332 2006/03/23 00:19:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -700,7 +700,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt, Assert(!tle->resjunk); updateTargetListEntry(pstate, tle, col->name, lfirst_int(attnos), - col->indirection); + col->indirection, col->location); icols = lnext(icols); attnos = lnext(attnos); @@ -2360,6 +2360,7 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt) { TargetEntry *tle = (TargetEntry *) lfirst(tl); ResTarget *origTarget; + int attrno; if (tle->resjunk) { @@ -2378,10 +2379,20 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt) origTarget = (ResTarget *) lfirst(origTargetList); Assert(IsA(origTarget, ResTarget)); + attrno = attnameAttNum(pstate->p_target_relation, + origTarget->name, true); + if (attrno == InvalidAttrNumber) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" of relation \"%s\" does not exist", + origTarget->name, + RelationGetRelationName(pstate->p_target_relation)), + parser_errposition(pstate, origTarget->location))); + updateTargetListEntry(pstate, tle, origTarget->name, - attnameAttNum(pstate->p_target_relation, - origTarget->name, true), - origTarget->indirection); + attrno, + origTarget->indirection, + origTarget->location); origTargetList = lnext(origTargetList); } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 1eb95199633..43277e45877 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.536 2006/03/14 23:03:20 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.537 2006/03/23 00:19:29 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -5187,6 +5187,7 @@ insert_column_item: $$->name = $1; $$->indirection = $2; $$->val = NULL; + $$->location = @1; } ; @@ -7918,6 +7919,7 @@ target_el: a_expr AS ColLabel $$->name = $3; $$->indirection = NIL; $$->val = (Node *)$1; + $$->location = @1; } | a_expr { @@ -7925,6 +7927,7 @@ target_el: a_expr AS ColLabel $$->name = NULL; $$->indirection = NIL; $$->val = (Node *)$1; + $$->location = @1; } | '*' { @@ -7936,6 +7939,7 @@ target_el: a_expr AS ColLabel $$->name = NULL; $$->indirection = NIL; $$->val = (Node *)n; + $$->location = @1; } ; @@ -7951,6 +7955,7 @@ update_target_el: $$->name = $1; $$->indirection = $2; $$->val = (Node *) $4; + $$->location = @1; } | ColId opt_indirection '=' DEFAULT { @@ -7958,6 +7963,7 @@ update_target_el: $$->name = $1; $$->indirection = $2; $$->val = (Node *) makeNode(SetToDefault); + $$->location = @1; } ; @@ -7974,6 +7980,7 @@ insert_target_el: $$->name = NULL; $$->indirection = NIL; $$->val = (Node *)$1; + $$->location = @1; } | DEFAULT { @@ -7981,6 +7988,7 @@ insert_target_el: $$->name = NULL; $$->indirection = NIL; $$->val = (Node *) makeNode(SetToDefault); + $$->location = @1; } ; diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index e8e11ad167a..d3e138e8ecb 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.121 2006/03/16 00:31:55 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.122 2006/03/23 00:19:30 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1703,7 +1703,9 @@ get_tle_by_resno(List *tlist, AttrNumber resno) } /* - * given relation and att name, return id of variable + * given relation and att name, return attnum of variable + * + * Returns InvalidAttrNumber if the attr doesn't exist (or is dropped). * * This should only be used if the relation is already * heap_open()'ed. Use the cache version get_attnum() @@ -1732,11 +1734,7 @@ attnameAttNum(Relation rd, const char *attname, bool sysColOK) } /* on failure */ - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_COLUMN), - errmsg("column \"%s\" of relation \"%s\" does not exist", - attname, RelationGetRelationName(rd)))); - return InvalidAttrNumber; /* keep compiler quiet */ + return InvalidAttrNumber; } /* specialAttNum() 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); } |