summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Momjian2003-06-25 04:19:24 +0000
committerBruce Momjian2003-06-25 04:19:24 +0000
commit53c4f1233fa950c0c6c0e0bbaa7a177278e14b04 (patch)
tree43a4943c7111a7ffa40c3a41de76d8dc563c535a
parenta09ccc70dd78b33271b06a6c250f7578aa4e16a1 (diff)
UPDATE ... SET <col> = DEFAULT
Rod Taylor
-rw-r--r--doc/src/sgml/ref/update.sgml13
-rw-r--r--src/backend/nodes/copyfuncs.c12
-rw-r--r--src/backend/nodes/equalfuncs.c8
-rw-r--r--src/backend/parser/analyze.c24
-rw-r--r--src/backend/parser/gram.y13
-rw-r--r--src/backend/parser/parse_target.c37
-rw-r--r--src/backend/rewrite/rewriteHandler.c22
-rw-r--r--src/include/nodes/nodes.h4
-rw-r--r--src/include/nodes/parsenodes.h6
9 files changed, 90 insertions, 49 deletions
diff --git a/doc/src/sgml/ref/update.sgml b/doc/src/sgml/ref/update.sgml
index af7d8cce301..02cc07b0bd4 100644
--- a/doc/src/sgml/ref/update.sgml
+++ b/doc/src/sgml/ref/update.sgml
@@ -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
-->
@@ -16,7 +16,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<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> ]
[ WHERE <replaceable class="PARAMETER">condition</replaceable> ]
</synopsis>
@@ -78,6 +78,15 @@ UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> SET <replacea
</varlistentry>
<varlistentry>
+ <term><literal>DEFAULT</literal></term>
+ <listitem>
+ <para>
+ This column will be filled with its default value.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><replaceable class="PARAMETER">fromlist</replaceable></term>
<listitem>
<para>
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index ecc9703b7c5..0cd199656c0 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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;
}
-static InsertDefault *
-_copyInsertDefault(InsertDefault *from)
+static SetToDefault *
+_copySetToDefault(SetToDefault *from)
{
- InsertDefault *newnode = makeNode(InsertDefault);
+ SetToDefault *newnode = makeNode(SetToDefault);
return newnode;
}
@@ -2942,8 +2942,8 @@ copyObject(void *from)
case T_FuncWithArgs:
retval = _copyFuncWithArgs(from);
break;
- case T_InsertDefault:
- retval = _copyInsertDefault(from);
+ case T_SetToDefault:
+ retval = _copySetToDefault(from);
break;
default:
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 0e46d46ea1b..93f63c586c6 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -18,7 +18,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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
-_equalInsertDefault(InsertDefault *a, InsertDefault *b)
+_equalSetToDefault(SetToDefault *a, SetToDefault *b)
{
return true;
}
@@ -2055,8 +2055,8 @@ equal(void *a, void *b)
case T_FuncWithArgs:
retval = _equalFuncWithArgs(a, b);
break;
- case T_InsertDefault:
- retval = _equalInsertDefault(a, b);
+ case T_SetToDefault:
+ retval = _equalSetToDefault(a, b);
break;
default:
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 6476b09f99b..99efae80721 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -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)
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 9806d658889..ed409c91715 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -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;
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index 0b36e6b5e58..91726df7aa2 100644
--- a/src/backend/parser/parse_target.c
+++ b/src/backend/parser/parse_target.c
@@ -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,
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 5d481a3f0a5..4c1e1247b2c 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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,
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 */
}
}
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index a6c2c022141..af87482e42a 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* 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_FuncWithArgs,
T_PrivTarget,
- T_InsertDefault,
+ T_SetToDefault,
T_CreateOpClassItem,
T_CompositeTypeStmt,
T_InhRelation,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 772e4341721..2e6e1559fa0 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* 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
*/
-typedef struct InsertDefault
+typedef struct SetToDefault
{
NodeTag type;
-} InsertDefault;
+} SetToDefault;
/*
* SortGroupBy - for ORDER BY clause