Commit 53c4f123 authored by Bruce Momjian's avatar Bruce Momjian

UPDATE ... SET <col> = DEFAULT

Rod Taylor
parent a09ccc70
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/update.sgml,v 1.21 2003/04/26 23:56:51 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/update.sgml,v 1.22 2003/06/25 04:19:24 momjian Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -16,7 +16,7 @@ PostgreSQL documentation ...@@ -16,7 +16,7 @@ PostgreSQL documentation
<refsynopsisdiv> <refsynopsisdiv>
<synopsis> <synopsis>
UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> SET <replaceable class="PARAMETER">column</replaceable> = <replaceable class="PARAMETER">expression</replaceable> [, ...] UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> SET <replaceable class="PARAMETER">column</replaceable> = { <replaceable class="PARAMETER">expression</replaceable> | DEFAULT } [, ...]
[ FROM <replaceable class="PARAMETER">fromlist</replaceable> ] [ FROM <replaceable class="PARAMETER">fromlist</replaceable> ]
[ WHERE <replaceable class="PARAMETER">condition</replaceable> ] [ WHERE <replaceable class="PARAMETER">condition</replaceable> ]
</synopsis> </synopsis>
...@@ -77,6 +77,15 @@ UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> SET <replacea ...@@ -77,6 +77,15 @@ UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> SET <replacea
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><literal>DEFAULT</literal></term>
<listitem>
<para>
This column will be filled with its default value.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><replaceable class="PARAMETER">fromlist</replaceable></term> <term><replaceable class="PARAMETER">fromlist</replaceable></term>
<listitem> <listitem>
......
...@@ -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
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.254 2003/06/25 03:40:17 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.255 2003/06/25 04:19:24 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1661,10 +1661,10 @@ _copyFuncWithArgs(FuncWithArgs *from) ...@@ -1661,10 +1661,10 @@ _copyFuncWithArgs(FuncWithArgs *from)
return newnode; return newnode;
} }
static InsertDefault * static SetToDefault *
_copyInsertDefault(InsertDefault *from) _copySetToDefault(SetToDefault *from)
{ {
InsertDefault *newnode = makeNode(InsertDefault); SetToDefault *newnode = makeNode(SetToDefault);
return newnode; return newnode;
} }
...@@ -2942,8 +2942,8 @@ copyObject(void *from) ...@@ -2942,8 +2942,8 @@ copyObject(void *from)
case T_FuncWithArgs: case T_FuncWithArgs:
retval = _copyFuncWithArgs(from); retval = _copyFuncWithArgs(from);
break; break;
case T_InsertDefault: case T_SetToDefault:
retval = _copyInsertDefault(from); retval = _copySetToDefault(from);
break; break;
default: default:
......
...@@ -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
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.197 2003/06/25 03:40:17 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.198 2003/06/25 04:19:24 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -728,7 +728,7 @@ _equalFuncWithArgs(FuncWithArgs *a, FuncWithArgs *b) ...@@ -728,7 +728,7 @@ _equalFuncWithArgs(FuncWithArgs *a, FuncWithArgs *b)
} }
static bool static bool
_equalInsertDefault(InsertDefault *a, InsertDefault *b) _equalSetToDefault(SetToDefault *a, SetToDefault *b)
{ {
return true; return true;
} }
...@@ -2055,8 +2055,8 @@ equal(void *a, void *b) ...@@ -2055,8 +2055,8 @@ equal(void *a, void *b)
case T_FuncWithArgs: case T_FuncWithArgs:
retval = _equalFuncWithArgs(a, b); retval = _equalFuncWithArgs(a, b);
break; break;
case T_InsertDefault: case T_SetToDefault:
retval = _equalInsertDefault(a, b); retval = _equalSetToDefault(a, b);
break; break;
default: default:
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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, ...@@ -660,23 +660,9 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
col = (ResTarget *) lfirst(icolumns); col = (ResTarget *) lfirst(icolumns);
Assert(IsA(col, ResTarget)); Assert(IsA(col, ResTarget));
/* Assert(!tle->resdom->resjunk);
* When the value is to be set to the column default we can simply updateTargetListEntry(pstate, tle, col->name, lfirsti(attnos),
* drop the TLE now and handle it later on using methods for missing col->indirection);
* 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);
}
icolumns = lnext(icolumns); icolumns = lnext(icolumns);
attnos = lnext(attnos); attnos = lnext(attnos);
...@@ -2431,10 +2417,12 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt) ...@@ -2431,10 +2417,12 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
if (origTargetList == NIL) if (origTargetList == NIL)
elog(ERROR, "UPDATE target count mismatch --- internal error"); elog(ERROR, "UPDATE target count mismatch --- internal error");
origTarget = (ResTarget *) lfirst(origTargetList); origTarget = (ResTarget *) lfirst(origTargetList);
updateTargetListEntry(pstate, tle, origTarget->name, updateTargetListEntry(pstate, tle, origTarget->name,
attnameAttNum(pstate->p_target_relation, attnameAttNum(pstate->p_target_relation,
origTarget->name, true), origTarget->name, true),
origTarget->indirection); origTarget->indirection);
origTargetList = lnext(origTargetList); origTargetList = lnext(origTargetList);
} }
if (origTargetList != NIL) if (origTargetList != NIL)
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -6945,6 +6945,15 @@ update_target_el: ...@@ -6945,6 +6945,15 @@ update_target_el:
$$->indirection = $2; $$->indirection = $2;
$$->val = (Node *)$4; $$->val = (Node *)$4;
} }
| ColId opt_indirection '=' DEFAULT
{
SetToDefault *def = makeNode(SetToDefault);
$$ = makeNode(ResTarget);
$$->name = $1;
$$->indirection = NULL;
$$->val = (Node *)def;
}
; ;
insert_target_list: insert_target_list:
...@@ -6956,7 +6965,7 @@ insert_target_el: ...@@ -6956,7 +6965,7 @@ insert_target_el:
target_el { $$ = $1; } target_el { $$ = $1; }
| DEFAULT | DEFAULT
{ {
InsertDefault *def = makeNode(InsertDefault); SetToDefault *def = makeNode(SetToDefault);
$$ = makeNode(ResTarget); $$ = makeNode(ResTarget);
$$->name = NULL; $$->name = NULL;
$$->indirection = NULL; $$->indirection = NULL;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -177,19 +177,24 @@ transformTargetList(ParseState *pstate, List *targetlist)
false)); 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 * If this is a DEFAULT element, we make a standard entry using
* will get dropped on return to transformInsertStmt(). * 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 else
{ {
/* Everything else but ColumnRef and InsertDefault */ /* Everything else but ColumnRef and SetToDefault */
p_target = lappend(p_target, p_target = lappend(p_target,
transformTargetEntry(pstate, transformTargetEntry(pstate,
res->val, res->val,
...@@ -321,9 +326,10 @@ updateTargetListEntry(ParseState *pstate, ...@@ -321,9 +326,10 @@ updateTargetListEntry(ParseState *pstate,
int attrno, int attrno,
List *indirection) 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 */ Oid attrtype; /* type of target column */
int32 attrtypmod; int32 attrtypmod;
bool isDefault = false;
Resdom *resnode = tle->resdom; Resdom *resnode = tle->resdom;
Relation rd = pstate->p_target_relation; Relation rd = pstate->p_target_relation;
...@@ -333,6 +339,17 @@ updateTargetListEntry(ParseState *pstate, ...@@ -333,6 +339,17 @@ updateTargetListEntry(ParseState *pstate,
attrtype = attnumTypeId(rd, attrno); attrtype = attnumTypeId(rd, attrno);
attrtypmod = rd->rd_att->attrs[attrno - 1]->atttypmod; 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 * If there are subscripts on the target column, prepare an array
* assignment expression. This will generate an array value that the * assignment expression. This will generate an array value that the
...@@ -383,7 +400,7 @@ updateTargetListEntry(ParseState *pstate, ...@@ -383,7 +400,7 @@ updateTargetListEntry(ParseState *pstate,
* coercion. But accept InvalidOid, which indicates the source is * coercion. But accept InvalidOid, which indicates the source is
* a NULL constant. (XXX is that still true?) * a NULL constant. (XXX is that still true?)
*/ */
if (type_id != InvalidOid) if (!isDefault && type_id != InvalidOid)
{ {
tle->expr = (Expr *) tle->expr = (Expr *)
coerce_to_target_type(pstate, coerce_to_target_type(pstate,
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.120 2003/05/02 20:54:35 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.121 2003/06/25 04:19:24 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -307,7 +307,25 @@ rewriteTargetList(Query *parsetree, Relation target_relation) ...@@ -307,7 +307,25 @@ rewriteTargetList(Query *parsetree, Relation target_relation)
{ {
Assert(strcmp(resdom->resname, Assert(strcmp(resdom->resname,
NameStr(att_tup->attname)) == 0); NameStr(att_tup->attname)) == 0);
new_tle = process_matched_tle(old_tle, new_tle);
if (old_tle->expr != NULL && IsA(old_tle->expr, SetToDefault))
{
/* Set to the default value of the column, as requested */
Node *new_expr;
new_expr = build_column_default(target_relation, attrno);
new_tle = makeTargetEntry(makeResdom(attrno,
att_tup->atttypid,
att_tup->atttypmod,
pstrdup(NameStr(att_tup->attname)),
false),
(Expr *) new_expr);
}
else
/* Normal Case */
new_tle = process_matched_tle(old_tle, new_tle);
/* keep scanning to detect multiple assignments to attr */ /* keep scanning to detect multiple assignments to attr */
} }
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: nodes.h,v 1.141 2003/06/25 03:40:19 momjian Exp $ * $Id: nodes.h,v 1.142 2003/06/25 04:19:24 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -277,7 +277,7 @@ typedef enum NodeTag ...@@ -277,7 +277,7 @@ typedef enum NodeTag
T_PrivGrantee, T_PrivGrantee,
T_FuncWithArgs, T_FuncWithArgs,
T_PrivTarget, T_PrivTarget,
T_InsertDefault, T_SetToDefault,
T_CreateOpClassItem, T_CreateOpClassItem,
T_CompositeTypeStmt, T_CompositeTypeStmt,
T_InhRelation, T_InhRelation,
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: parsenodes.h,v 1.239 2003/06/25 03:40:19 momjian Exp $ * $Id: parsenodes.h,v 1.240 2003/06/25 04:19:24 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -279,10 +279,10 @@ typedef struct ResTarget ...@@ -279,10 +279,10 @@ typedef struct ResTarget
/* /*
* Empty node used as a marker for Default Columns * Empty node used as a marker for Default Columns
*/ */
typedef struct InsertDefault typedef struct SetToDefault
{ {
NodeTag type; NodeTag type;
} InsertDefault; } SetToDefault;
/* /*
* SortGroupBy - for ORDER BY clause * SortGroupBy - for ORDER BY clause
......
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