mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
UPDATE ... SET <col> = DEFAULT
Rod Taylor
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$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
|
|||||||
|
|
||||||
<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
|
|||||||
</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 @@
|
|||||||
* 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)
|
|||||||
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)
|
|||||||
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 @@
|
|||||||
* 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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
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 @@
|
|||||||
* 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,
|
|||||||
col = (ResTarget *) lfirst(icolumns);
|
col = (ResTarget *) lfirst(icolumns);
|
||||||
Assert(IsA(col, ResTarget));
|
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);
|
Assert(!tle->resdom->resjunk);
|
||||||
updateTargetListEntry(pstate, tle, col->name, lfirsti(attnos),
|
updateTargetListEntry(pstate, tle, col->name, lfirsti(attnos),
|
||||||
col->indirection);
|
col->indirection);
|
||||||
}
|
|
||||||
|
|
||||||
icolumns = lnext(icolumns);
|
icolumns = lnext(icolumns);
|
||||||
attnos = lnext(attnos);
|
attnos = lnext(attnos);
|
||||||
@ -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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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:
|
|||||||
$$->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:
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
* 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 @@
|
|||||||
* 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)
|
|||||||
{
|
{
|
||||||
Assert(strcmp(resdom->resname,
|
Assert(strcmp(resdom->resname,
|
||||||
NameStr(att_tup->attname)) == 0);
|
NameStr(att_tup->attname)) == 0);
|
||||||
|
|
||||||
|
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);
|
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 @@
|
|||||||
* 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
|
|||||||
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 @@
|
|||||||
* 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
|
|||||||
/*
|
/*
|
||||||
* 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
|
||||||
|
Reference in New Issue
Block a user