mirror of
https://github.com/postgres/postgres.git
synced 2025-05-21 00:02:53 -04: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:
parent
7b1885bf98
commit
455891bf96
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/insert.sgml,v 1.22 2003/04/26 23:56:51 petere Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/insert.sgml,v 1.23 2003/07/03 16:32:03 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ INSERT INTO <replaceable class="PARAMETER">table</replaceable> [ ( <replaceable
|
|||||||
<para>
|
<para>
|
||||||
The columns in the target list may be listed in any order.
|
The columns in the target list may be listed in any order.
|
||||||
Each column not present in the target list will be inserted
|
Each column not present in the target list will be inserted
|
||||||
using a default value, either a declared default value
|
using a default value, either its declared default value
|
||||||
or null.
|
or null.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ INSERT INTO <replaceable class="PARAMETER">table</replaceable> [ ( <replaceable
|
|||||||
<term><literal>DEFAULT VALUES</literal></term>
|
<term><literal>DEFAULT VALUES</literal></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
All columns will be filled their default values.
|
All columns will be filled with their default values.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/update.sgml,v 1.22 2003/06/25 04:19:24 momjian Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/update.sgml,v 1.23 2003/07/03 16:32:12 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -28,7 +28,8 @@ UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> SET <replacea
|
|||||||
<para>
|
<para>
|
||||||
<command>UPDATE</command> changes the values of the specified
|
<command>UPDATE</command> changes the values of the specified
|
||||||
columns in all rows that satisfy the condition. Only the columns to
|
columns in all rows that satisfy the condition. Only the columns to
|
||||||
be modified need appear as columns in the statement.
|
be modified need be mentioned in the statement; columns not explicitly
|
||||||
|
<literal>SET</> retain their previous values.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -41,8 +42,9 @@ UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> SET <replacea
|
|||||||
<para>
|
<para>
|
||||||
You must have the <literal>UPDATE</literal> privilege on the table
|
You must have the <literal>UPDATE</literal> privilege on the table
|
||||||
to update it, as well as the <literal>SELECT</literal>
|
to update it, as well as the <literal>SELECT</literal>
|
||||||
privilege to any table whose values are read in the <replaceable
|
privilege to any table whose values are read in the
|
||||||
class="parameter">condition</replaceable>.
|
<replaceable class="parameter">expression</replaceable>s or
|
||||||
|
<replaceable class="parameter">condition</replaceable>.
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
@ -72,7 +74,8 @@ UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> SET <replacea
|
|||||||
<term><replaceable class="PARAMETER">expression</replaceable></term>
|
<term><replaceable class="PARAMETER">expression</replaceable></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
An expression or value to assign to the column.
|
An expression to assign to the column. The expression may use the
|
||||||
|
old values of this and other columns in the table.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -81,7 +84,8 @@ UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> SET <replacea
|
|||||||
<term><literal>DEFAULT</literal></term>
|
<term><literal>DEFAULT</literal></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
This column will be filled with its default value.
|
Set the column to its default value (which will be NULL if no
|
||||||
|
specific default expression has been assigned to it).
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -91,7 +95,7 @@ UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> SET <replacea
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
A list of table expressions, allowing columns from other tables
|
A list of table expressions, allowing columns from other tables
|
||||||
to appear in the <literal>WHERE</> condition.
|
to appear in the <literal>WHERE</> condition and the update expressions.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -100,9 +104,9 @@ UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> SET <replacea
|
|||||||
<term><replaceable class="PARAMETER">condition</replaceable></term>
|
<term><replaceable class="PARAMETER">condition</replaceable></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
A value expression that returns a value of type
|
An expression that returns a value of type <type>boolean</type>.
|
||||||
<type>boolean</type> that determines the rows which are to be
|
Only rows for which this expression returns <literal>true</>
|
||||||
updated.
|
will be updated.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -135,9 +139,20 @@ UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> SET <replacea
|
|||||||
column <structfield>kind</> of the table <literal>films</literal>:
|
column <structfield>kind</> of the table <literal>films</literal>:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
UPDATE filme SET kind = 'Dramatic' WHERE kind = 'Drama';
|
UPDATE films SET kind = 'Dramatic' WHERE kind = 'Drama';
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Adjust temperature entries and reset precipitation to its default
|
||||||
|
value in one row of the table <literal>weather</literal>:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
UPDATE weather SET temp_lo = temp_lo+1, temp_hi = temp_lo+15, prcp = DEFAULT
|
||||||
|
WHERE city = 'San Francisco' AND date = '2003-07-03';
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
|
@ -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.258 2003/06/29 00:33:43 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.259 2003/07/03 16:32:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1041,6 +1041,20 @@ _copyCoerceToDomainValue(CoerceToDomainValue *from)
|
|||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _copySetToDefault
|
||||||
|
*/
|
||||||
|
static SetToDefault *
|
||||||
|
_copySetToDefault(SetToDefault *from)
|
||||||
|
{
|
||||||
|
SetToDefault *newnode = makeNode(SetToDefault);
|
||||||
|
|
||||||
|
COPY_SCALAR_FIELD(typeId);
|
||||||
|
COPY_SCALAR_FIELD(typeMod);
|
||||||
|
|
||||||
|
return newnode;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _copyTargetEntry
|
* _copyTargetEntry
|
||||||
*/
|
*/
|
||||||
@ -1669,14 +1683,6 @@ _copyFuncWithArgs(FuncWithArgs *from)
|
|||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SetToDefault *
|
|
||||||
_copySetToDefault(SetToDefault *from)
|
|
||||||
{
|
|
||||||
SetToDefault *newnode = makeNode(SetToDefault);
|
|
||||||
|
|
||||||
return newnode;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DeclareCursorStmt *
|
static DeclareCursorStmt *
|
||||||
_copyDeclareCursorStmt(DeclareCursorStmt *from)
|
_copyDeclareCursorStmt(DeclareCursorStmt *from)
|
||||||
{
|
{
|
||||||
@ -2607,6 +2613,9 @@ copyObject(void *from)
|
|||||||
case T_CoerceToDomainValue:
|
case T_CoerceToDomainValue:
|
||||||
retval = _copyCoerceToDomainValue(from);
|
retval = _copyCoerceToDomainValue(from);
|
||||||
break;
|
break;
|
||||||
|
case T_SetToDefault:
|
||||||
|
retval = _copySetToDefault(from);
|
||||||
|
break;
|
||||||
case T_TargetEntry:
|
case T_TargetEntry:
|
||||||
retval = _copyTargetEntry(from);
|
retval = _copyTargetEntry(from);
|
||||||
break;
|
break;
|
||||||
@ -2955,9 +2964,6 @@ copyObject(void *from)
|
|||||||
case T_FuncWithArgs:
|
case T_FuncWithArgs:
|
||||||
retval = _copyFuncWithArgs(from);
|
retval = _copyFuncWithArgs(from);
|
||||||
break;
|
break;
|
||||||
case T_SetToDefault:
|
|
||||||
retval = _copySetToDefault(from);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "copyObject: don't know how to copy node type %d",
|
elog(ERROR, "copyObject: don't know how to copy node type %d",
|
||||||
|
@ -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.201 2003/06/29 00:33:43 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.202 2003/07/03 16:32:32 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -485,6 +485,15 @@ _equalCoerceToDomainValue(CoerceToDomainValue *a, CoerceToDomainValue *b)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
_equalSetToDefault(SetToDefault *a, SetToDefault *b)
|
||||||
|
{
|
||||||
|
COMPARE_SCALAR_FIELD(typeId);
|
||||||
|
COMPARE_SCALAR_FIELD(typeMod);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_equalTargetEntry(TargetEntry *a, TargetEntry *b)
|
_equalTargetEntry(TargetEntry *a, TargetEntry *b)
|
||||||
{
|
{
|
||||||
@ -740,12 +749,6 @@ _equalFuncWithArgs(FuncWithArgs *a, FuncWithArgs *b)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
_equalSetToDefault(SetToDefault *a, SetToDefault *b)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_equalDeclareCursorStmt(DeclareCursorStmt *a, DeclareCursorStmt *b)
|
_equalDeclareCursorStmt(DeclareCursorStmt *a, DeclareCursorStmt *b)
|
||||||
{
|
{
|
||||||
@ -1727,6 +1730,9 @@ equal(void *a, void *b)
|
|||||||
case T_CoerceToDomainValue:
|
case T_CoerceToDomainValue:
|
||||||
retval = _equalCoerceToDomainValue(a, b);
|
retval = _equalCoerceToDomainValue(a, b);
|
||||||
break;
|
break;
|
||||||
|
case T_SetToDefault:
|
||||||
|
retval = _equalSetToDefault(a, b);
|
||||||
|
break;
|
||||||
case T_TargetEntry:
|
case T_TargetEntry:
|
||||||
retval = _equalTargetEntry(a, b);
|
retval = _equalTargetEntry(a, b);
|
||||||
break;
|
break;
|
||||||
@ -2073,9 +2079,6 @@ equal(void *a, void *b)
|
|||||||
case T_FuncWithArgs:
|
case T_FuncWithArgs:
|
||||||
retval = _equalFuncWithArgs(a, b);
|
retval = _equalFuncWithArgs(a, b);
|
||||||
break;
|
break;
|
||||||
case T_SetToDefault:
|
|
||||||
retval = _equalSetToDefault(a, b);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
elog(WARNING, "equal: don't know whether nodes of type %d are equal",
|
elog(WARNING, "equal: don't know whether nodes of type %d are equal",
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.211 2003/06/29 00:33:43 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.212 2003/07/03 16:32:38 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Every node type that can appear in stored rules' parsetrees *must*
|
* Every node type that can appear in stored rules' parsetrees *must*
|
||||||
@ -849,6 +849,15 @@ _outCoerceToDomainValue(StringInfo str, CoerceToDomainValue *node)
|
|||||||
WRITE_INT_FIELD(typeMod);
|
WRITE_INT_FIELD(typeMod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_outSetToDefault(StringInfo str, SetToDefault *node)
|
||||||
|
{
|
||||||
|
WRITE_NODE_TYPE("SETTODEFAULT");
|
||||||
|
|
||||||
|
WRITE_OID_FIELD(typeId);
|
||||||
|
WRITE_INT_FIELD(typeMod);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_outTargetEntry(StringInfo str, TargetEntry *node)
|
_outTargetEntry(StringInfo str, TargetEntry *node)
|
||||||
{
|
{
|
||||||
@ -1685,6 +1694,9 @@ _outNode(StringInfo str, void *obj)
|
|||||||
case T_CoerceToDomainValue:
|
case T_CoerceToDomainValue:
|
||||||
_outCoerceToDomainValue(str, obj);
|
_outCoerceToDomainValue(str, obj);
|
||||||
break;
|
break;
|
||||||
|
case T_SetToDefault:
|
||||||
|
_outSetToDefault(str, obj);
|
||||||
|
break;
|
||||||
case T_TargetEntry:
|
case T_TargetEntry:
|
||||||
_outTargetEntry(str, obj);
|
_outTargetEntry(str, obj);
|
||||||
break;
|
break;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.157 2003/06/29 00:33:43 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.158 2003/07/03 16:32:39 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Path and Plan nodes do not have any readfuncs support, because we
|
* Path and Plan nodes do not have any readfuncs support, because we
|
||||||
@ -760,6 +760,20 @@ _readCoerceToDomainValue(void)
|
|||||||
READ_DONE();
|
READ_DONE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _readSetToDefault
|
||||||
|
*/
|
||||||
|
static SetToDefault *
|
||||||
|
_readSetToDefault(void)
|
||||||
|
{
|
||||||
|
READ_LOCALS(SetToDefault);
|
||||||
|
|
||||||
|
READ_OID_FIELD(typeId);
|
||||||
|
READ_INT_FIELD(typeMod);
|
||||||
|
|
||||||
|
READ_DONE();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _readTargetEntry
|
* _readTargetEntry
|
||||||
*/
|
*/
|
||||||
@ -1005,6 +1019,8 @@ parseNodeString(void)
|
|||||||
return_value = _readCoerceToDomain();
|
return_value = _readCoerceToDomain();
|
||||||
else if (MATCH("COERCETODOMAINVALUE", 19))
|
else if (MATCH("COERCETODOMAINVALUE", 19))
|
||||||
return_value = _readCoerceToDomainValue();
|
return_value = _readCoerceToDomainValue();
|
||||||
|
else if (MATCH("SETTODEFAULT", 12))
|
||||||
|
return_value = _readSetToDefault();
|
||||||
else if (MATCH("TARGETENTRY", 11))
|
else if (MATCH("TARGETENTRY", 11))
|
||||||
return_value = _readTargetEntry();
|
return_value = _readTargetEntry();
|
||||||
else if (MATCH("RANGETBLREF", 11))
|
else if (MATCH("RANGETBLREF", 11))
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.144 2003/07/01 19:07:02 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.145 2003/07/03 16:33:07 tgl Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -2157,6 +2157,7 @@ expression_tree_walker(Node *node,
|
|||||||
case T_Const:
|
case T_Const:
|
||||||
case T_Param:
|
case T_Param:
|
||||||
case T_CoerceToDomainValue:
|
case T_CoerceToDomainValue:
|
||||||
|
case T_SetToDefault:
|
||||||
case T_RangeTblRef:
|
case T_RangeTblRef:
|
||||||
/* primitive node types with no subnodes */
|
/* primitive node types with no subnodes */
|
||||||
break;
|
break;
|
||||||
@ -2514,6 +2515,7 @@ expression_tree_mutator(Node *node,
|
|||||||
case T_Const:
|
case T_Const:
|
||||||
case T_Param:
|
case T_Param:
|
||||||
case T_CoerceToDomainValue:
|
case T_CoerceToDomainValue:
|
||||||
|
case T_SetToDefault:
|
||||||
case T_RangeTblRef:
|
case T_RangeTblRef:
|
||||||
/* primitive node types with no subnodes */
|
/* primitive node types with no subnodes */
|
||||||
return (Node *) copyObject(node);
|
return (Node *) copyObject(node);
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -6999,15 +6999,14 @@ update_target_el:
|
|||||||
$$ = makeNode(ResTarget);
|
$$ = makeNode(ResTarget);
|
||||||
$$->name = $1;
|
$$->name = $1;
|
||||||
$$->indirection = $2;
|
$$->indirection = $2;
|
||||||
$$->val = (Node *)$4;
|
$$->val = (Node *) $4;
|
||||||
}
|
}
|
||||||
| ColId opt_indirection '=' DEFAULT
|
| ColId opt_indirection '=' DEFAULT
|
||||||
{
|
{
|
||||||
SetToDefault *def = makeNode(SetToDefault);
|
|
||||||
$$ = makeNode(ResTarget);
|
$$ = makeNode(ResTarget);
|
||||||
$$->name = $1;
|
$$->name = $1;
|
||||||
$$->indirection = NULL;
|
$$->indirection = $2;
|
||||||
$$->val = (Node *)def;
|
$$->val = (Node *) makeNode(SetToDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
;
|
;
|
||||||
@ -7021,11 +7020,10 @@ insert_target_el:
|
|||||||
target_el { $$ = $1; }
|
target_el { $$ = $1; }
|
||||||
| DEFAULT
|
| DEFAULT
|
||||||
{
|
{
|
||||||
SetToDefault *def = makeNode(SetToDefault);
|
|
||||||
$$ = makeNode(ResTarget);
|
$$ = makeNode(ResTarget);
|
||||||
$$->name = NULL;
|
$$->name = NULL;
|
||||||
$$->indirection = NULL;
|
$$->indirection = NIL;
|
||||||
$$->val = (Node *)def;
|
$$->val = (Node *) makeNode(SetToDefault);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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_RelabelType:
|
||||||
case T_CoerceToDomain:
|
case T_CoerceToDomain:
|
||||||
case T_CoerceToDomainValue:
|
case T_CoerceToDomainValue:
|
||||||
|
case T_SetToDefault:
|
||||||
{
|
{
|
||||||
result = (Node *) expr;
|
result = (Node *) expr;
|
||||||
break;
|
break;
|
||||||
@ -1291,6 +1292,9 @@ exprType(Node *expr)
|
|||||||
case T_CoerceToDomainValue:
|
case T_CoerceToDomainValue:
|
||||||
type = ((CoerceToDomainValue *) expr)->typeId;
|
type = ((CoerceToDomainValue *) expr)->typeId;
|
||||||
break;
|
break;
|
||||||
|
case T_SetToDefault:
|
||||||
|
type = ((SetToDefault *) expr)->typeId;
|
||||||
|
break;
|
||||||
case T_RangeVar:
|
case T_RangeVar:
|
||||||
/*
|
/*
|
||||||
* If someone uses a bare relation name in an expression,
|
* If someone uses a bare relation name in an expression,
|
||||||
@ -1420,6 +1424,8 @@ exprTypmod(Node *expr)
|
|||||||
return ((CoerceToDomain *) expr)->resulttypmod;
|
return ((CoerceToDomain *) expr)->resulttypmod;
|
||||||
case T_CoerceToDomainValue:
|
case T_CoerceToDomainValue:
|
||||||
return ((CoerceToDomainValue *) expr)->typeMod;
|
return ((CoerceToDomainValue *) expr)->typeMod;
|
||||||
|
case T_SetToDefault:
|
||||||
|
return ((SetToDefault *) expr)->typeMod;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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));
|
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
|
else
|
||||||
{
|
{
|
||||||
/* Everything else but ColumnRef and SetToDefault */
|
/* Everything else but ColumnRef */
|
||||||
p_target = lappend(p_target,
|
p_target = lappend(p_target,
|
||||||
transformTargetEntry(pstate,
|
transformTargetEntry(pstate,
|
||||||
res->val,
|
res->val,
|
||||||
@ -330,7 +315,6 @@ updateTargetListEntry(ParseState *pstate,
|
|||||||
Oid type_id; /* 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;
|
||||||
|
|
||||||
@ -340,16 +324,26 @@ 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))
|
* 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;
|
SetToDefault *def = (SetToDefault *) tle->expr;
|
||||||
isDefault = true;
|
|
||||||
|
def->typeId = attrtype;
|
||||||
|
def->typeMod = attrtypmod;
|
||||||
|
if (indirection)
|
||||||
|
elog(ERROR, "cannot set an array element to DEFAULT");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise the expression holds the type */
|
/* Now we can use exprType() safely. */
|
||||||
else
|
type_id = exprType((Node *) tle->expr);
|
||||||
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
|
||||||
@ -401,7 +395,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 (!isDefault && type_id != InvalidOid)
|
if (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.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.
|
* attributes that have defaults and are not assigned to in the given tlist.
|
||||||
* (We do not insert anything for default-less attributes, however. The
|
* (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
|
* 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
|
* 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
|
* 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,
|
Assert(strcmp(resdom->resname,
|
||||||
NameStr(att_tup->attname)) == 0);
|
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 */
|
/* 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;
|
Node *new_expr;
|
||||||
|
|
||||||
new_expr = build_column_default(target_relation, attrno);
|
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)
|
if (new_expr)
|
||||||
new_tle = makeTargetEntry(makeResdom(attrno,
|
new_tle = makeTargetEntry(makeResdom(attrno,
|
||||||
att_tup->atttypid,
|
att_tup->atttypid,
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* back to source text
|
* back to source text
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.143 2003/06/29 00:33:44 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.144 2003/07/03 16:34:25 tgl Exp $
|
||||||
*
|
*
|
||||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -2606,6 +2606,10 @@ get_rule_expr(Node *node, deparse_context *context,
|
|||||||
appendStringInfo(buf, "VALUE");
|
appendStringInfo(buf, "VALUE");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_SetToDefault:
|
||||||
|
appendStringInfo(buf, "DEFAULT");
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "get_rule_expr: unknown node type %d", nodeTag(node));
|
elog(ERROR, "get_rule_expr: unknown node type %d", nodeTag(node));
|
||||||
break;
|
break;
|
||||||
|
@ -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.143 2003/06/29 00:33:44 tgl Exp $
|
* $Id: nodes.h,v 1.144 2003/07/03 16:34:25 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -120,6 +120,7 @@ typedef enum NodeTag
|
|||||||
T_BooleanTest,
|
T_BooleanTest,
|
||||||
T_CoerceToDomain,
|
T_CoerceToDomain,
|
||||||
T_CoerceToDomainValue,
|
T_CoerceToDomainValue,
|
||||||
|
T_SetToDefault,
|
||||||
T_TargetEntry,
|
T_TargetEntry,
|
||||||
T_RangeTblRef,
|
T_RangeTblRef,
|
||||||
T_JoinExpr,
|
T_JoinExpr,
|
||||||
@ -279,7 +280,6 @@ typedef enum NodeTag
|
|||||||
T_PrivGrantee,
|
T_PrivGrantee,
|
||||||
T_FuncWithArgs,
|
T_FuncWithArgs,
|
||||||
T_PrivTarget,
|
T_PrivTarget,
|
||||||
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.242 2003/06/29 00:33:44 tgl Exp $
|
* $Id: parsenodes.h,v 1.243 2003/07/03 16:34:25 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -278,14 +278,6 @@ typedef struct ResTarget
|
|||||||
* assign */
|
* assign */
|
||||||
} ResTarget;
|
} ResTarget;
|
||||||
|
|
||||||
/*
|
|
||||||
* Empty node used as a marker for Default Columns
|
|
||||||
*/
|
|
||||||
typedef struct SetToDefault
|
|
||||||
{
|
|
||||||
NodeTag type;
|
|
||||||
} SetToDefault;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SortGroupBy - for ORDER BY clause
|
* SortGroupBy - for ORDER BY clause
|
||||||
*/
|
*/
|
||||||
|
@ -10,7 +10,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: primnodes.h,v 1.86 2003/06/29 00:33:44 tgl Exp $
|
* $Id: primnodes.h,v 1.87 2003/07/03 16:34:26 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -674,6 +674,19 @@ typedef struct CoerceToDomainValue
|
|||||||
int32 typeMod; /* typemod for substituted value */
|
int32 typeMod; /* typemod for substituted value */
|
||||||
} CoerceToDomainValue;
|
} CoerceToDomainValue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Placeholder node for a DEFAULT marker in an INSERT or UPDATE command.
|
||||||
|
*
|
||||||
|
* This is not an executable expression: it must be replaced by the actual
|
||||||
|
* column default expression during rewriting. But it is convenient to
|
||||||
|
* treat it as an expression node during parsing and rewriting.
|
||||||
|
*/
|
||||||
|
typedef struct SetToDefault
|
||||||
|
{
|
||||||
|
Expr xpr;
|
||||||
|
Oid typeId; /* type for substituted value */
|
||||||
|
int32 typeMod; /* typemod for substituted value */
|
||||||
|
} SetToDefault;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TargetEntry -
|
* TargetEntry -
|
||||||
|
Loading…
x
Reference in New Issue
Block a user