mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Add error location info to ResTarget parse nodes. Allows error cursor to be supplied
for various mistakes involving INSERT and UPDATE target columns.
This commit is contained in:
@ -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)
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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)
|
|||||||
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 @@
|
|||||||
* 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)
|
|||||||
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 @@
|
|||||||
* 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)
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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)
|
|||||||
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 @@
|
|||||||
* 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,
|
|||||||
|
|
||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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:
|
|||||||
$$->name = $1;
|
$$->name = $1;
|
||||||
$$->indirection = $2;
|
$$->indirection = $2;
|
||||||
$$->val = NULL;
|
$$->val = NULL;
|
||||||
|
$$->location = @1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -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
|
|||||||
$$->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
|
|||||||
$$->name = NULL;
|
$$->name = NULL;
|
||||||
$$->indirection = NIL;
|
$$->indirection = NIL;
|
||||||
$$->val = (Node *)n;
|
$$->val = (Node *)n;
|
||||||
|
$$->location = @1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -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:
|
|||||||
$$->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:
|
|||||||
$$->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:
|
|||||||
$$->name = NULL;
|
$$->name = NULL;
|
||||||
$$->indirection = NIL;
|
$$->indirection = NIL;
|
||||||
$$->val = (Node *) makeNode(SetToDefault);
|
$$->val = (Node *) makeNode(SetToDefault);
|
||||||
|
$$->location = @1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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,
|
|||||||
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,
|
|||||||
* 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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
*
|
*
|
||||||
* 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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
(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,
|
|||||||
(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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
/* 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)
|
|||||||
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)
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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)
|
|||||||
|
|
||||||
/* 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 @@
|
|||||||
* 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
|
|||||||
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 @@
|
|||||||
* 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,
|
|||||||
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........" = ...
|
|||||||
-- 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
|
|||||||
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
|
||||||
|
Reference in New Issue
Block a user