mirror of
https://github.com/postgres/postgres.git
synced 2025-11-09 06:21:09 +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:
@@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.424 2003/07/01 00:04:31 petere Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.425 2003/07/03 16:33:37 tgl Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@@ -6999,15 +6999,14 @@ update_target_el:
|
||||
$$ = makeNode(ResTarget);
|
||||
$$->name = $1;
|
||||
$$->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;
|
||||
$$->indirection = $2;
|
||||
$$->val = (Node *) makeNode(SetToDefault);
|
||||
}
|
||||
|
||||
;
|
||||
@@ -7021,11 +7020,10 @@ insert_target_el:
|
||||
target_el { $$ = $1; }
|
||||
| DEFAULT
|
||||
{
|
||||
SetToDefault *def = makeNode(SetToDefault);
|
||||
$$ = makeNode(ResTarget);
|
||||
$$->name = NULL;
|
||||
$$->indirection = NULL;
|
||||
$$->val = (Node *)def;
|
||||
$$->indirection = NIL;
|
||||
$$->val = (Node *) makeNode(SetToDefault);
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.154 2003/06/29 00:33:43 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.155 2003/07/03 16:34:16 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -914,6 +914,7 @@ transformExpr(ParseState *pstate, Node *expr)
|
||||
case T_RelabelType:
|
||||
case T_CoerceToDomain:
|
||||
case T_CoerceToDomainValue:
|
||||
case T_SetToDefault:
|
||||
{
|
||||
result = (Node *) expr;
|
||||
break;
|
||||
@@ -1291,6 +1292,9 @@ exprType(Node *expr)
|
||||
case T_CoerceToDomainValue:
|
||||
type = ((CoerceToDomainValue *) expr)->typeId;
|
||||
break;
|
||||
case T_SetToDefault:
|
||||
type = ((SetToDefault *) expr)->typeId;
|
||||
break;
|
||||
case T_RangeVar:
|
||||
/*
|
||||
* If someone uses a bare relation name in an expression,
|
||||
@@ -1420,6 +1424,8 @@ exprTypmod(Node *expr)
|
||||
return ((CoerceToDomain *) expr)->resulttypmod;
|
||||
case T_CoerceToDomainValue:
|
||||
return ((CoerceToDomainValue *) expr)->typeMod;
|
||||
case T_SetToDefault:
|
||||
return ((SetToDefault *) expr)->typeMod;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.105 2003/06/27 17:04:53 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.106 2003/07/03 16:34:20 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -178,24 +178,9 @@ transformTargetList(ParseState *pstate, List *targetlist)
|
||||
false));
|
||||
}
|
||||
}
|
||||
else if (IsA(res->val, SetToDefault))
|
||||
{
|
||||
/*
|
||||
* 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,
|
||||
makeTargetEntry(makeResdom((AttrNumber) pstate->p_next_resno++,
|
||||
UNKNOWNOID,
|
||||
-1,
|
||||
res->name,
|
||||
false),
|
||||
(Expr *) res->val));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Everything else but ColumnRef and SetToDefault */
|
||||
/* Everything else but ColumnRef */
|
||||
p_target = lappend(p_target,
|
||||
transformTargetEntry(pstate,
|
||||
res->val,
|
||||
@@ -330,7 +315,6 @@ updateTargetListEntry(ParseState *pstate,
|
||||
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;
|
||||
|
||||
@@ -340,16 +324,26 @@ 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))
|
||||
/*
|
||||
* If the expression is a DEFAULT placeholder, insert the attribute's
|
||||
* type/typmod into it so that exprType will report the right things.
|
||||
* (We expect that the eventually substituted default expression will
|
||||
* in fact have this type and typmod.) Also, reject trying to update
|
||||
* an array element with DEFAULT, since there can't be any default for
|
||||
* individual elements of a column.
|
||||
*/
|
||||
if (tle->expr && IsA(tle->expr, SetToDefault))
|
||||
{
|
||||
type_id = attrtype;
|
||||
isDefault = true;
|
||||
SetToDefault *def = (SetToDefault *) tle->expr;
|
||||
|
||||
def->typeId = attrtype;
|
||||
def->typeMod = attrtypmod;
|
||||
if (indirection)
|
||||
elog(ERROR, "cannot set an array element to DEFAULT");
|
||||
}
|
||||
|
||||
/* Otherwise the expression holds the type */
|
||||
else
|
||||
type_id = exprType((Node *) tle->expr);
|
||||
/* Now we can use exprType() safely. */
|
||||
type_id = exprType((Node *) tle->expr);
|
||||
|
||||
/*
|
||||
* If there are subscripts on the target column, prepare an array
|
||||
@@ -401,7 +395,7 @@ updateTargetListEntry(ParseState *pstate,
|
||||
* coercion. But accept InvalidOid, which indicates the source is
|
||||
* a NULL constant. (XXX is that still true?)
|
||||
*/
|
||||
if (!isDefault && type_id != InvalidOid)
|
||||
if (type_id != InvalidOid)
|
||||
{
|
||||
tle->expr = (Expr *)
|
||||
coerce_to_target_type(pstate,
|
||||
|
||||
Reference in New Issue
Block a user