Commit 19956e0d authored by Tom Lane's avatar Tom Lane

Add error location info to ResTarget parse nodes. Allows error cursor to be supplied

for various mistakes involving INSERT and UPDATE target columns.
parent a3f0b3d6
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.92 2006/03/05 15:58:23 momjian Exp $ * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.93 2006/03/23 00:19:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -216,6 +216,11 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt) ...@@ -216,6 +216,11 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
char *col = strVal(lfirst(le)); char *col = strVal(lfirst(le));
i = attnameAttNum(onerel, col, false); i = attnameAttNum(onerel, col, false);
if (i == InvalidAttrNumber)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
col, RelationGetRelationName(onerel))));
vacattrstats[tcnt] = examine_attribute(onerel, i); vacattrstats[tcnt] = examine_attribute(onerel, i);
if (vacattrstats[tcnt] != NULL) if (vacattrstats[tcnt] != NULL)
tcnt++; tcnt++;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.260 2006/03/05 15:58:23 momjian Exp $ * $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.261 2006/03/23 00:19:29 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -3109,9 +3109,14 @@ CopyGetAttnums(Relation rel, List *attnamelist) ...@@ -3109,9 +3109,14 @@ CopyGetAttnums(Relation rel, List *attnamelist)
char *name = strVal(lfirst(l)); char *name = strVal(lfirst(l));
int attnum; int attnum;
/* Lookup column name, ereport on failure */ /* Lookup column name */
/* Note we disallow system columns here */ /* Note we disallow system columns here */
attnum = attnameAttNum(rel, name, false); attnum = attnameAttNum(rel, name, false);
if (attnum == InvalidAttrNumber)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
name, RelationGetRelationName(rel))));
/* Check for duplicates */ /* Check for duplicates */
if (list_member_int(attnums, attnum)) if (list_member_int(attnums, attnum))
ereport(ERROR, ereport(ERROR,
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.331 2006/03/16 00:31:54 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.332 2006/03/23 00:19:29 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1520,6 +1520,7 @@ _copyResTarget(ResTarget *from) ...@@ -1520,6 +1520,7 @@ _copyResTarget(ResTarget *from)
COPY_STRING_FIELD(name); COPY_STRING_FIELD(name);
COPY_NODE_FIELD(indirection); COPY_NODE_FIELD(indirection);
COPY_NODE_FIELD(val); COPY_NODE_FIELD(val);
COPY_SCALAR_FIELD(location);
return newnode; return newnode;
} }
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.267 2006/03/16 00:31:54 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.268 2006/03/23 00:19:29 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1608,6 +1608,7 @@ _equalResTarget(ResTarget *a, ResTarget *b) ...@@ -1608,6 +1608,7 @@ _equalResTarget(ResTarget *a, ResTarget *b)
COMPARE_STRING_FIELD(name); COMPARE_STRING_FIELD(name);
COMPARE_NODE_FIELD(indirection); COMPARE_NODE_FIELD(indirection);
COMPARE_NODE_FIELD(val); COMPARE_NODE_FIELD(val);
COMPARE_SCALAR_FIELD(location);
return true; return true;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.271 2006/03/16 00:31:54 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.272 2006/03/23 00:19:29 tgl Exp $
* *
* NOTES * NOTES
* Every node type that can appear in stored rules' parsetrees *must* * Every node type that can appear in stored rules' parsetrees *must*
...@@ -1738,6 +1738,7 @@ _outResTarget(StringInfo str, ResTarget *node) ...@@ -1738,6 +1738,7 @@ _outResTarget(StringInfo str, ResTarget *node)
WRITE_STRING_FIELD(name); WRITE_STRING_FIELD(name);
WRITE_NODE_FIELD(indirection); WRITE_NODE_FIELD(indirection);
WRITE_NODE_FIELD(val); WRITE_NODE_FIELD(val);
WRITE_INT_FIELD(location);
} }
static void static void
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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, ...@@ -700,7 +700,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
Assert(!tle->resjunk); Assert(!tle->resjunk);
updateTargetListEntry(pstate, tle, col->name, lfirst_int(attnos), updateTargetListEntry(pstate, tle, col->name, lfirst_int(attnos),
col->indirection); col->indirection, col->location);
icols = lnext(icols); icols = lnext(icols);
attnos = lnext(attnos); attnos = lnext(attnos);
...@@ -2360,6 +2360,7 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt) ...@@ -2360,6 +2360,7 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
{ {
TargetEntry *tle = (TargetEntry *) lfirst(tl); TargetEntry *tle = (TargetEntry *) lfirst(tl);
ResTarget *origTarget; ResTarget *origTarget;
int attrno;
if (tle->resjunk) if (tle->resjunk)
{ {
...@@ -2378,10 +2379,20 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt) ...@@ -2378,10 +2379,20 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
origTarget = (ResTarget *) lfirst(origTargetList); origTarget = (ResTarget *) lfirst(origTargetList);
Assert(IsA(origTarget, ResTarget)); 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, updateTargetListEntry(pstate, tle, origTarget->name,
attnameAttNum(pstate->p_target_relation, attrno,
origTarget->name, true), origTarget->indirection,
origTarget->indirection); origTarget->location);
origTargetList = lnext(origTargetList); origTargetList = lnext(origTargetList);
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -5187,6 +5187,7 @@ insert_column_item: ...@@ -5187,6 +5187,7 @@ insert_column_item:
$$->name = $1; $$->name = $1;
$$->indirection = $2; $$->indirection = $2;
$$->val = NULL; $$->val = NULL;
$$->location = @1;
} }
; ;
...@@ -7918,6 +7919,7 @@ target_el: a_expr AS ColLabel ...@@ -7918,6 +7919,7 @@ target_el: a_expr AS ColLabel
$$->name = $3; $$->name = $3;
$$->indirection = NIL; $$->indirection = NIL;
$$->val = (Node *)$1; $$->val = (Node *)$1;
$$->location = @1;
} }
| a_expr | a_expr
{ {
...@@ -7925,6 +7927,7 @@ target_el: a_expr AS ColLabel ...@@ -7925,6 +7927,7 @@ target_el: a_expr AS ColLabel
$$->name = NULL; $$->name = NULL;
$$->indirection = NIL; $$->indirection = NIL;
$$->val = (Node *)$1; $$->val = (Node *)$1;
$$->location = @1;
} }
| '*' | '*'
{ {
...@@ -7936,6 +7939,7 @@ target_el: a_expr AS ColLabel ...@@ -7936,6 +7939,7 @@ target_el: a_expr AS ColLabel
$$->name = NULL; $$->name = NULL;
$$->indirection = NIL; $$->indirection = NIL;
$$->val = (Node *)n; $$->val = (Node *)n;
$$->location = @1;
} }
; ;
...@@ -7951,6 +7955,7 @@ update_target_el: ...@@ -7951,6 +7955,7 @@ update_target_el:
$$->name = $1; $$->name = $1;
$$->indirection = $2; $$->indirection = $2;
$$->val = (Node *) $4; $$->val = (Node *) $4;
$$->location = @1;
} }
| ColId opt_indirection '=' DEFAULT | ColId opt_indirection '=' DEFAULT
{ {
...@@ -7958,6 +7963,7 @@ update_target_el: ...@@ -7958,6 +7963,7 @@ update_target_el:
$$->name = $1; $$->name = $1;
$$->indirection = $2; $$->indirection = $2;
$$->val = (Node *) makeNode(SetToDefault); $$->val = (Node *) makeNode(SetToDefault);
$$->location = @1;
} }
; ;
...@@ -7974,6 +7980,7 @@ insert_target_el: ...@@ -7974,6 +7980,7 @@ insert_target_el:
$$->name = NULL; $$->name = NULL;
$$->indirection = NIL; $$->indirection = NIL;
$$->val = (Node *)$1; $$->val = (Node *)$1;
$$->location = @1;
} }
| DEFAULT | DEFAULT
{ {
...@@ -7981,6 +7988,7 @@ insert_target_el: ...@@ -7981,6 +7988,7 @@ insert_target_el:
$$->name = NULL; $$->name = NULL;
$$->indirection = NIL; $$->indirection = NIL;
$$->val = (Node *) makeNode(SetToDefault); $$->val = (Node *) makeNode(SetToDefault);
$$->location = @1;
} }
; ;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -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 * This should only be used if the relation is already
* heap_open()'ed. Use the cache version get_attnum() * heap_open()'ed. Use the cache version get_attnum()
...@@ -1732,11 +1734,7 @@ attnameAttNum(Relation rd, const char *attname, bool sysColOK) ...@@ -1732,11 +1734,7 @@ attnameAttNum(Relation rd, const char *attname, bool sysColOK)
} }
/* on failure */ /* on failure */
ereport(ERROR, return InvalidAttrNumber;
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
attname, RelationGetRelationName(rd))));
return InvalidAttrNumber; /* keep compiler quiet */
} }
/* specialAttNum() /* specialAttNum()
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -40,7 +40,8 @@ static Node *transformAssignmentIndirection(ParseState *pstate,
Oid targetTypeId, Oid targetTypeId,
int32 targetTypMod, int32 targetTypMod,
ListCell *indirection, ListCell *indirection,
Node *rhs); Node *rhs,
int location);
static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref); static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref);
static List *ExpandAllTables(ParseState *pstate); static List *ExpandAllTables(ParseState *pstate);
static List *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind); static List *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind);
...@@ -247,13 +248,15 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle, ...@@ -247,13 +248,15 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
* colname target column name (ie, name of attribute to be assigned to) * colname target column name (ie, name of attribute to be assigned to)
* attrno target attribute number * attrno target attribute number
* indirection subscripts/field names for target column, if any * indirection subscripts/field names for target column, if any
* location error cursor position (should point at column name), or -1
*/ */
void void
updateTargetListEntry(ParseState *pstate, updateTargetListEntry(ParseState *pstate,
TargetEntry *tle, TargetEntry *tle,
char *colname, char *colname,
int attrno, int attrno,
List *indirection) List *indirection,
int location)
{ {
Oid type_id; /* type of value provided */ Oid type_id; /* type of value provided */
Oid attrtype; /* type of target column */ Oid attrtype; /* type of target column */
...@@ -265,7 +268,8 @@ updateTargetListEntry(ParseState *pstate, ...@@ -265,7 +268,8 @@ updateTargetListEntry(ParseState *pstate,
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot assign to system column \"%s\"", errmsg("cannot assign to system column \"%s\"",
colname))); colname),
parser_errposition(pstate, location)));
attrtype = attnumTypeId(rd, attrno); attrtype = attnumTypeId(rd, attrno);
attrtypmod = rd->rd_att->attrs[attrno - 1]->atttypmod; attrtypmod = rd->rd_att->attrs[attrno - 1]->atttypmod;
...@@ -288,11 +292,13 @@ updateTargetListEntry(ParseState *pstate, ...@@ -288,11 +292,13 @@ updateTargetListEntry(ParseState *pstate,
if (IsA(linitial(indirection), A_Indices)) if (IsA(linitial(indirection), A_Indices))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (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 else
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (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, ...@@ -336,7 +342,8 @@ updateTargetListEntry(ParseState *pstate,
attrtype, attrtype,
attrtypmod, attrtypmod,
list_head(indirection), list_head(indirection),
(Node *) tle->expr); (Node *) tle->expr,
location);
} }
else else
{ {
...@@ -358,7 +365,8 @@ updateTargetListEntry(ParseState *pstate, ...@@ -358,7 +365,8 @@ updateTargetListEntry(ParseState *pstate,
colname, colname,
format_type_be(attrtype), format_type_be(attrtype),
format_type_be(type_id)), 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, ...@@ -395,6 +403,11 @@ updateTargetListEntry(ParseState *pstate,
* *
* rhs is the already-transformed value to be assigned; note it has not been * rhs is the already-transformed value to be assigned; note it has not been
* coerced to any particular type. * 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 * static Node *
transformAssignmentIndirection(ParseState *pstate, transformAssignmentIndirection(ParseState *pstate,
...@@ -404,7 +417,8 @@ transformAssignmentIndirection(ParseState *pstate, ...@@ -404,7 +417,8 @@ transformAssignmentIndirection(ParseState *pstate,
Oid targetTypeId, Oid targetTypeId,
int32 targetTypMod, int32 targetTypMod,
ListCell *indirection, ListCell *indirection,
Node *rhs) Node *rhs,
int location)
{ {
Node *result; Node *result;
List *subscripts = NIL; List *subscripts = NIL;
...@@ -460,7 +474,8 @@ transformAssignmentIndirection(ParseState *pstate, ...@@ -460,7 +474,8 @@ transformAssignmentIndirection(ParseState *pstate,
typeNeeded, typeNeeded,
targetTypMod, targetTypMod,
i, i,
rhs); rhs,
location);
/* process subscripts */ /* process subscripts */
return (Node *) transformArraySubscripts(pstate, return (Node *) transformArraySubscripts(pstate,
basenode, basenode,
...@@ -479,7 +494,8 @@ transformAssignmentIndirection(ParseState *pstate, ...@@ -479,7 +494,8 @@ transformAssignmentIndirection(ParseState *pstate,
(errcode(ERRCODE_DATATYPE_MISMATCH), (errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type", errmsg("cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type",
strVal(n), targetName, strVal(n), targetName,
format_type_be(targetTypeId)))); format_type_be(targetTypeId)),
parser_errposition(pstate, location)));
attnum = get_attnum(typrelid, strVal(n)); attnum = get_attnum(typrelid, strVal(n));
if (attnum == InvalidAttrNumber) if (attnum == InvalidAttrNumber)
...@@ -487,12 +503,14 @@ transformAssignmentIndirection(ParseState *pstate, ...@@ -487,12 +503,14 @@ transformAssignmentIndirection(ParseState *pstate,
(errcode(ERRCODE_UNDEFINED_COLUMN), (errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s", errmsg("cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s",
strVal(n), targetName, strVal(n), targetName,
format_type_be(targetTypeId)))); format_type_be(targetTypeId)),
parser_errposition(pstate, location)));
if (attnum < 0) if (attnum < 0)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN), (errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("cannot assign to system column \"%s\"", errmsg("cannot assign to system column \"%s\"",
strVal(n)))); strVal(n)),
parser_errposition(pstate, location)));
get_atttypetypmod(typrelid, attnum, get_atttypetypmod(typrelid, attnum,
&fieldTypeId, &fieldTypMod); &fieldTypeId, &fieldTypMod);
...@@ -505,7 +523,8 @@ transformAssignmentIndirection(ParseState *pstate, ...@@ -505,7 +523,8 @@ transformAssignmentIndirection(ParseState *pstate,
fieldTypeId, fieldTypeId,
fieldTypMod, fieldTypMod,
lnext(i), lnext(i),
rhs); rhs,
location);
/* and build a FieldStore node */ /* and build a FieldStore node */
fstore = makeNode(FieldStore); fstore = makeNode(FieldStore);
...@@ -532,7 +551,8 @@ transformAssignmentIndirection(ParseState *pstate, ...@@ -532,7 +551,8 @@ transformAssignmentIndirection(ParseState *pstate,
typeNeeded, typeNeeded,
targetTypMod, targetTypMod,
NULL, NULL,
rhs); rhs,
location);
/* process subscripts */ /* process subscripts */
return (Node *) transformArraySubscripts(pstate, return (Node *) transformArraySubscripts(pstate,
basenode, basenode,
...@@ -560,7 +580,8 @@ transformAssignmentIndirection(ParseState *pstate, ...@@ -560,7 +580,8 @@ transformAssignmentIndirection(ParseState *pstate,
targetName, targetName,
format_type_be(targetTypeId), format_type_be(targetTypeId),
format_type_be(exprType(rhs))), 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 else
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH), (errcode(ERRCODE_DATATYPE_MISMATCH),
...@@ -569,7 +590,8 @@ transformAssignmentIndirection(ParseState *pstate, ...@@ -569,7 +590,8 @@ transformAssignmentIndirection(ParseState *pstate,
targetName, targetName,
format_type_be(targetTypeId), format_type_be(targetTypeId),
format_type_be(exprType(rhs))), 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; return result;
...@@ -607,6 +629,7 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos) ...@@ -607,6 +629,7 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
col->name = pstrdup(NameStr(attr[i]->attname)); col->name = pstrdup(NameStr(attr[i]->attname));
col->indirection = NIL; col->indirection = NIL;
col->val = NULL; col->val = NULL;
col->location = -1;
cols = lappend(cols, col); cols = lappend(cols, col);
*attrnos = lappend_int(*attrnos, i + 1); *attrnos = lappend_int(*attrnos, i + 1);
} }
...@@ -628,6 +651,13 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos) ...@@ -628,6 +651,13 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
/* Lookup column name, ereport on failure */ /* Lookup column name, ereport on failure */
attrno = attnameAttNum(pstate->p_target_relation, name, false); 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 * Check for duplicates, but only of whole columns --- we allow
...@@ -641,7 +671,8 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos) ...@@ -641,7 +671,8 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_COLUMN), (errcode(ERRCODE_DUPLICATE_COLUMN),
errmsg("column \"%s\" specified more than once", errmsg("column \"%s\" specified more than once",
name))); name),
parser_errposition(pstate, col->location)));
wholecols = bms_add_member(wholecols, attrno); wholecols = bms_add_member(wholecols, attrno);
} }
else else
...@@ -651,7 +682,8 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos) ...@@ -651,7 +682,8 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_COLUMN), (errcode(ERRCODE_DUPLICATE_COLUMN),
errmsg("column \"%s\" specified more than once", errmsg("column \"%s\" specified more than once",
name))); name),
parser_errposition(pstate, col->location)));
partialcols = bms_add_member(partialcols, attrno); partialcols = bms_add_member(partialcols, attrno);
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/not_in.c,v 1.44 2006/03/05 15:58:43 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/not_in.c,v 1.45 2006/03/23 00:19:30 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -72,6 +72,12 @@ int4notin(PG_FUNCTION_ARGS) ...@@ -72,6 +72,12 @@ int4notin(PG_FUNCTION_ARGS)
/* Find the column to search */ /* Find the column to search */
attrid = attnameAttNum(relation_to_scan, attribute, true); attrid = attnameAttNum(relation_to_scan, attribute, true);
if (attrid == InvalidAttrNumber)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
attribute,
RelationGetRelationName(relation_to_scan))));
scan_descriptor = heap_beginscan(relation_to_scan, SnapshotNow, scan_descriptor = heap_beginscan(relation_to_scan, SnapshotNow,
0, (ScanKey) NULL); 0, (ScanKey) NULL);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.305 2006/03/16 00:31:55 tgl Exp $ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.306 2006/03/23 00:19:30 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -327,6 +327,7 @@ typedef struct ResTarget ...@@ -327,6 +327,7 @@ typedef struct ResTarget
char *name; /* column name or NULL */ char *name; /* column name or NULL */
List *indirection; /* subscripts and field names, or NIL */ List *indirection; /* subscripts and field names, or NIL */
Node *val; /* the value expression to compute or assign */ Node *val; /* the value expression to compute or assign */
int location; /* token location, or -1 if unknown */
} ResTarget; } ResTarget;
/* /*
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/parser/parse_target.h,v 1.38 2006/03/05 15:58:57 momjian Exp $ * $PostgreSQL: pgsql/src/include/parser/parse_target.h,v 1.39 2006/03/23 00:19:30 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -24,7 +24,8 @@ extern TargetEntry *transformTargetEntry(ParseState *pstate, ...@@ -24,7 +24,8 @@ extern TargetEntry *transformTargetEntry(ParseState *pstate,
char *colname, bool resjunk); char *colname, bool resjunk);
extern void updateTargetListEntry(ParseState *pstate, TargetEntry *tle, extern void updateTargetListEntry(ParseState *pstate, TargetEntry *tle,
char *colname, int attrno, char *colname, int attrno,
List *indirection); List *indirection,
int location);
extern List *checkInsertTargets(ParseState *pstate, List *cols, extern List *checkInsertTargets(ParseState *pstate, List *cols,
List **attrnos); List **attrnos);
extern TupleDesc expandRecordVariable(ParseState *pstate, Var *var, extern TupleDesc expandRecordVariable(ParseState *pstate, Var *var,
......
...@@ -677,12 +677,16 @@ LINE 1: select * from atacc1 where "........pg.dropped.1........" = ... ...@@ -677,12 +677,16 @@ LINE 1: select * from atacc1 where "........pg.dropped.1........" = ...
-- UPDATEs -- UPDATEs
update atacc1 set a = 3; update atacc1 set a = 3;
ERROR: column "a" of relation "atacc1" does not exist ERROR: column "a" of relation "atacc1" does not exist
LINE 1: update atacc1 set a = 3;
^
update atacc1 set b = 2 where a = 3; update atacc1 set b = 2 where a = 3;
ERROR: column "a" does not exist ERROR: column "a" does not exist
LINE 1: update atacc1 set b = 2 where a = 3; LINE 1: update atacc1 set b = 2 where a = 3;
^ ^
update atacc1 set "........pg.dropped.1........" = 3; update atacc1 set "........pg.dropped.1........" = 3;
ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
LINE 1: update atacc1 set "........pg.dropped.1........" = 3;
^
update atacc1 set b = 2 where "........pg.dropped.1........" = 3; update atacc1 set b = 2 where "........pg.dropped.1........" = 3;
ERROR: column "........pg.dropped.1........" does not exist ERROR: column "........pg.dropped.1........" does not exist
LINE 1: update atacc1 set b = 2 where "........pg.dropped.1........"... LINE 1: update atacc1 set b = 2 where "........pg.dropped.1........"...
...@@ -695,21 +699,37 @@ ERROR: INSERT has more expressions than target columns ...@@ -695,21 +699,37 @@ ERROR: INSERT has more expressions than target columns
insert into atacc1 values (11, 12, 13); insert into atacc1 values (11, 12, 13);
insert into atacc1 (a) values (10); insert into atacc1 (a) values (10);
ERROR: column "a" of relation "atacc1" does not exist ERROR: column "a" of relation "atacc1" does not exist
LINE 1: insert into atacc1 (a) values (10);
^
insert into atacc1 (a) values (default); insert into atacc1 (a) values (default);
ERROR: column "a" of relation "atacc1" does not exist ERROR: column "a" of relation "atacc1" does not exist
LINE 1: insert into atacc1 (a) values (default);
^
insert into atacc1 (a,b,c,d) values (10,11,12,13); insert into atacc1 (a,b,c,d) values (10,11,12,13);
ERROR: column "a" of relation "atacc1" does not exist ERROR: column "a" of relation "atacc1" does not exist
LINE 1: insert into atacc1 (a,b,c,d) values (10,11,12,13);
^
insert into atacc1 (a,b,c,d) values (default,11,12,13); insert into atacc1 (a,b,c,d) values (default,11,12,13);
ERROR: column "a" of relation "atacc1" does not exist ERROR: column "a" of relation "atacc1" does not exist
LINE 1: insert into atacc1 (a,b,c,d) values (default,11,12,13);
^
insert into atacc1 (b,c,d) values (11,12,13); insert into atacc1 (b,c,d) values (11,12,13);
insert into atacc1 ("........pg.dropped.1........") values (10); insert into atacc1 ("........pg.dropped.1........") values (10);
ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
LINE 1: insert into atacc1 ("........pg.dropped.1........") values (...
^
insert into atacc1 ("........pg.dropped.1........") values (default); insert into atacc1 ("........pg.dropped.1........") values (default);
ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
LINE 1: insert into atacc1 ("........pg.dropped.1........") values (...
^
insert into atacc1 ("........pg.dropped.1........",b,c,d) values (10,11,12,13); insert into atacc1 ("........pg.dropped.1........",b,c,d) values (10,11,12,13);
ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
LINE 1: insert into atacc1 ("........pg.dropped.1........",b,c,d) va...
^
insert into atacc1 ("........pg.dropped.1........",b,c,d) values (default,11,12,13); insert into atacc1 ("........pg.dropped.1........",b,c,d) values (default,11,12,13);
ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
LINE 1: insert into atacc1 ("........pg.dropped.1........",b,c,d) va...
^
-- DELETEs -- DELETEs
delete from atacc1 where a = 3; delete from atacc1 where a = 3;
ERROR: column "a" does not exist ERROR: column "a" does not exist
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment