summaryrefslogtreecommitdiff
path: root/src/backend/rewrite/rewriteHandler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/rewrite/rewriteHandler.c')
-rw-r--r--src/backend/rewrite/rewriteHandler.c65
1 files changed, 38 insertions, 27 deletions
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 4c1e1247b2c..a1d9122f828 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.121 2003/06/25 04:19:24 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.122 2003/07/03 16:34:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -250,7 +250,9 @@ adjustJoinTreeList(Query *parsetree, bool removert, int rt_index)
* attributes that have defaults and are not assigned to in the given tlist.
* (We do not insert anything for default-less attributes, however. The
* planner will later insert NULLs for them, but there's no reason to slow
- * down rewriter processing with extra tlist nodes.)
+ * down rewriter processing with extra tlist nodes.) Also, for both INSERT
+ * and UPDATE, replace explicit DEFAULT specifications with column default
+ * expressions.
*
* 2. Merge multiple entries for the same target attribute, or declare error
* if we can't. Presently, multiple entries are only allowed for UPDATE of
@@ -307,40 +309,49 @@ rewriteTargetList(Query *parsetree, Relation target_relation)
{
Assert(strcmp(resdom->resname,
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 */
}
}
- if (new_tle == NULL && commandType == CMD_INSERT)
+ /*
+ * Handle the two cases where we need to insert a default expression:
+ * it's an INSERT and there's no tlist entry for the column, or the
+ * tlist entry is a DEFAULT placeholder node.
+ */
+ if ((new_tle == NULL && commandType == CMD_INSERT) ||
+ (new_tle && new_tle->expr && IsA(new_tle->expr, SetToDefault)))
{
- /*
- * Didn't find a matching tlist entry; if it's an INSERT, look
- * for a default value, and add a tlist entry computing the
- * default if we find one.
- */
Node *new_expr;
new_expr = build_column_default(target_relation, attrno);
+ /*
+ * If there is no default (ie, default is effectively NULL),
+ * we can omit the tlist entry in the INSERT case, since the
+ * planner can insert a NULL for itself, and there's no point
+ * in spending any more rewriter cycles on the entry. But in the
+ * UPDATE case we've got to explicitly set the column to NULL.
+ */
+ if (!new_expr)
+ {
+ if (commandType == CMD_INSERT)
+ new_tle = NULL;
+ else
+ {
+ new_expr = (Node *) makeConst(att_tup->atttypid,
+ att_tup->attlen,
+ (Datum) 0,
+ true, /* isnull */
+ att_tup->attbyval);
+ /* this is to catch a NOT NULL domain constraint */
+ new_expr = coerce_to_domain(new_expr,
+ InvalidOid,
+ att_tup->atttypid,
+ COERCE_IMPLICIT_CAST);
+ }
+ }
+
if (new_expr)
new_tle = makeTargetEntry(makeResdom(attrno,
att_tup->atttypid,