mirror of
https://github.com/postgres/postgres.git
synced 2025-11-09 06:21:09 +03:00
UPDATE ... SET <col> = DEFAULT
Rod Taylor
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.276 2003/06/25 03:40:17 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.277 2003/06/25 04:19:24 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -660,23 +660,9 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
|
||||
col = (ResTarget *) lfirst(icolumns);
|
||||
Assert(IsA(col, ResTarget));
|
||||
|
||||
/*
|
||||
* When the value is to be set to the column default we can simply
|
||||
* drop the TLE now and handle it later on using methods for missing
|
||||
* columns.
|
||||
*/
|
||||
if (IsA(tle, InsertDefault))
|
||||
{
|
||||
qry->targetList = lremove(tle, qry->targetList);
|
||||
/* Note: the stmt->cols list is not adjusted to match */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Normal case */
|
||||
Assert(!tle->resdom->resjunk);
|
||||
updateTargetListEntry(pstate, tle, col->name, lfirsti(attnos),
|
||||
col->indirection);
|
||||
}
|
||||
Assert(!tle->resdom->resjunk);
|
||||
updateTargetListEntry(pstate, tle, col->name, lfirsti(attnos),
|
||||
col->indirection);
|
||||
|
||||
icolumns = lnext(icolumns);
|
||||
attnos = lnext(attnos);
|
||||
@@ -2431,10 +2417,12 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
|
||||
if (origTargetList == NIL)
|
||||
elog(ERROR, "UPDATE target count mismatch --- internal error");
|
||||
origTarget = (ResTarget *) lfirst(origTargetList);
|
||||
|
||||
updateTargetListEntry(pstate, tle, origTarget->name,
|
||||
attnameAttNum(pstate->p_target_relation,
|
||||
origTarget->name, true),
|
||||
origTarget->indirection);
|
||||
|
||||
origTargetList = lnext(origTargetList);
|
||||
}
|
||||
if (origTargetList != NIL)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.419 2003/06/25 03:40:18 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.420 2003/06/25 04:19:24 momjian Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@@ -6945,6 +6945,15 @@ update_target_el:
|
||||
$$->indirection = $2;
|
||||
$$->val = (Node *)$4;
|
||||
}
|
||||
| ColId opt_indirection '=' DEFAULT
|
||||
{
|
||||
SetToDefault *def = makeNode(SetToDefault);
|
||||
$$ = makeNode(ResTarget);
|
||||
$$->name = $1;
|
||||
$$->indirection = NULL;
|
||||
$$->val = (Node *)def;
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
insert_target_list:
|
||||
@@ -6956,7 +6965,7 @@ insert_target_el:
|
||||
target_el { $$ = $1; }
|
||||
| DEFAULT
|
||||
{
|
||||
InsertDefault *def = makeNode(InsertDefault);
|
||||
SetToDefault *def = makeNode(SetToDefault);
|
||||
$$ = makeNode(ResTarget);
|
||||
$$->name = NULL;
|
||||
$$->indirection = NULL;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.102 2003/05/31 19:03:34 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.103 2003/06/25 04:19:24 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -177,19 +177,24 @@ transformTargetList(ParseState *pstate, List *targetlist)
|
||||
false));
|
||||
}
|
||||
}
|
||||
else if (IsA(res->val, InsertDefault))
|
||||
else if (IsA(res->val, SetToDefault))
|
||||
{
|
||||
InsertDefault *newnode = makeNode(InsertDefault);
|
||||
|
||||
/*
|
||||
* If this is a DEFAULT element, we make a junk entry which
|
||||
* will get dropped on return to transformInsertStmt().
|
||||
* If this is a DEFAULT element, we make a standard entry using
|
||||
* the default for the target expression. rewriteTargetList will
|
||||
* substitute the columns default for this expression.
|
||||
*/
|
||||
p_target = lappend(p_target, newnode);
|
||||
p_target = lappend(p_target,
|
||||
makeTargetEntry(makeResdom((AttrNumber) pstate->p_next_resno++,
|
||||
UNKNOWNOID,
|
||||
-1,
|
||||
res->name,
|
||||
false),
|
||||
(Expr *) res->val));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Everything else but ColumnRef and InsertDefault */
|
||||
/* Everything else but ColumnRef and SetToDefault */
|
||||
p_target = lappend(p_target,
|
||||
transformTargetEntry(pstate,
|
||||
res->val,
|
||||
@@ -321,9 +326,10 @@ updateTargetListEntry(ParseState *pstate,
|
||||
int attrno,
|
||||
List *indirection)
|
||||
{
|
||||
Oid type_id = exprType((Node *) tle->expr); /* type of value provided */
|
||||
Oid type_id; /* type of value provided */
|
||||
Oid attrtype; /* type of target column */
|
||||
int32 attrtypmod;
|
||||
bool isDefault = false;
|
||||
Resdom *resnode = tle->resdom;
|
||||
Relation rd = pstate->p_target_relation;
|
||||
|
||||
@@ -333,6 +339,17 @@ updateTargetListEntry(ParseState *pstate,
|
||||
attrtype = attnumTypeId(rd, attrno);
|
||||
attrtypmod = rd->rd_att->attrs[attrno - 1]->atttypmod;
|
||||
|
||||
/* The type of the default column is equivalent to that of the column */
|
||||
if (tle->expr != NULL && IsA(tle->expr, SetToDefault))
|
||||
{
|
||||
type_id = attrtype;
|
||||
isDefault = true;
|
||||
}
|
||||
|
||||
/* Otherwise the expression holds the type */
|
||||
else
|
||||
type_id = exprType((Node *) tle->expr);
|
||||
|
||||
/*
|
||||
* If there are subscripts on the target column, prepare an array
|
||||
* assignment expression. This will generate an array value that the
|
||||
@@ -383,7 +400,7 @@ updateTargetListEntry(ParseState *pstate,
|
||||
* coercion. But accept InvalidOid, which indicates the source is
|
||||
* a NULL constant. (XXX is that still true?)
|
||||
*/
|
||||
if (type_id != InvalidOid)
|
||||
if (!isDefault && type_id != InvalidOid)
|
||||
{
|
||||
tle->expr = (Expr *)
|
||||
coerce_to_target_type(pstate,
|
||||
|
||||
Reference in New Issue
Block a user