for various mistakes involving INSERT and UPDATE target columns.
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
char *col = strVal(lfirst(le));
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);
if (vacattrstats[tcnt] != NULL)
tcnt++;
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
char *name = strVal(lfirst(l));
int attnum;
- /* Lookup column name, ereport on failure */
+ /* Lookup column name */
/* Note we disallow system columns here */
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 */
if (list_member_int(attnums, attnum))
ereport(ERROR,
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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 $
*
*-------------------------------------------------------------------------
*/
COPY_STRING_FIELD(name);
COPY_NODE_FIELD(indirection);
COPY_NODE_FIELD(val);
+ COPY_SCALAR_FIELD(location);
return newnode;
}
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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 $
*
*-------------------------------------------------------------------------
*/
COMPARE_STRING_FIELD(name);
COMPARE_NODE_FIELD(indirection);
COMPARE_NODE_FIELD(val);
+ COMPARE_SCALAR_FIELD(location);
return true;
}
*
*
* 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
* Every node type that can appear in stored rules' parsetrees *must*
WRITE_STRING_FIELD(name);
WRITE_NODE_FIELD(indirection);
WRITE_NODE_FIELD(val);
+ WRITE_INT_FIELD(location);
}
static void
* 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 $
*
*-------------------------------------------------------------------------
*/
Assert(!tle->resjunk);
updateTargetListEntry(pstate, tle, col->name, lfirst_int(attnos),
- col->indirection);
+ col->indirection, col->location);
icols = lnext(icols);
attnos = lnext(attnos);
{
TargetEntry *tle = (TargetEntry *) lfirst(tl);
ResTarget *origTarget;
+ int attrno;
if (tle->resjunk)
{
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);
}
*
*
* 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
$$->name = $1;
$$->indirection = $2;
$$->val = NULL;
+ $$->location = @1;
}
;
$$->name = $3;
$$->indirection = NIL;
$$->val = (Node *)$1;
+ $$->location = @1;
}
| a_expr
{
$$->name = NULL;
$$->indirection = NIL;
$$->val = (Node *)$1;
+ $$->location = @1;
}
| '*'
{
$$->name = NULL;
$$->indirection = NIL;
$$->val = (Node *)n;
+ $$->location = @1;
}
;
$$->name = $1;
$$->indirection = $2;
$$->val = (Node *) $4;
+ $$->location = @1;
}
| ColId opt_indirection '=' DEFAULT
{
$$->name = $1;
$$->indirection = $2;
$$->val = (Node *) makeNode(SetToDefault);
+ $$->location = @1;
}
;
$$->name = NULL;
$$->indirection = NIL;
$$->val = (Node *)$1;
+ $$->location = @1;
}
| DEFAULT
{
$$->name = NULL;
$$->indirection = NIL;
$$->val = (Node *) makeNode(SetToDefault);
+ $$->location = @1;
}
;
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
}
/*
- * 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()
}
/* 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()
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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);
* 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 */
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;
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)));
}
}
attrtype,
attrtypmod,
list_head(indirection),
- (Node *) tle->expr);
+ (Node *) tle->expr,
+ location);
}
else
{
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)));
}
/*
*
* 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,
Oid targetTypeId,
int32 targetTypMod,
ListCell *indirection,
- Node *rhs)
+ Node *rhs,
+ int location)
{
Node *result;
List *subscripts = NIL;
typeNeeded,
targetTypMod,
i,
- rhs);
+ rhs,
+ location);
/* process subscripts */
return (Node *) transformArraySubscripts(pstate,
basenode,
(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)
(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);
fieldTypeId,
fieldTypMod,
lnext(i),
- rhs);
+ rhs,
+ location);
/* and build a FieldStore node */
fstore = makeNode(FieldStore);
typeNeeded,
targetTypMod,
NULL,
- rhs);
+ rhs,
+ location);
/* process subscripts */
return (Node *) transformArraySubscripts(pstate,
basenode,
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),
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;
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);
}
/* 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
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
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);
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
/* Find the column to search */
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,
0, (ScanKey) NULL);
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* 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 $
*
*-------------------------------------------------------------------------
*/
char *name; /* column name or NULL */
List *indirection; /* subscripts and field names, or NIL */
Node *val; /* the value expression to compute or assign */
+ int location; /* token location, or -1 if unknown */
} ResTarget;
/*
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* 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 $
*
*-------------------------------------------------------------------------
*/
char *colname, bool resjunk);
extern void updateTargetListEntry(ParseState *pstate, TargetEntry *tle,
char *colname, int attrno,
- List *indirection);
+ List *indirection,
+ int location);
extern List *checkInsertTargets(ParseState *pstate, List *cols,
List **attrnos);
extern TupleDesc expandRecordVariable(ParseState *pstate, Var *var,
-- UPDATEs
update atacc1 set a = 3;
ERROR: column "a" of relation "atacc1" does not exist
+LINE 1: update atacc1 set a = 3;
+ ^
update atacc1 set b = 2 where a = 3;
ERROR: column "a" does not exist
LINE 1: update atacc1 set b = 2 where a = 3;
^
update atacc1 set "........pg.dropped.1........" = 3;
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;
ERROR: column "........pg.dropped.1........" does not exist
LINE 1: update atacc1 set b = 2 where "........pg.dropped.1........"...
insert into atacc1 values (11, 12, 13);
insert into atacc1 (a) values (10);
ERROR: column "a" of relation "atacc1" does not exist
+LINE 1: insert into atacc1 (a) values (10);
+ ^
insert into atacc1 (a) values (default);
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);
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);
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 ("........pg.dropped.1........") values (10);
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);
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);
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);
ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist
+LINE 1: insert into atacc1 ("........pg.dropped.1........",b,c,d) va...
+ ^
-- DELETEs
delete from atacc1 where a = 3;
ERROR: column "a" does not exist