mirror of
https://github.com/postgres/postgres.git
synced 2025-07-05 07:21:24 +03:00
Code review for UPDATE tab SET col = DEFAULT patch ... whack it around
so it has some chance of working in rules ...
This commit is contained in:
@ -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,
|
||||
|
Reference in New Issue
Block a user