diff options
| author | Tom Lane | 2007-06-11 01:16:30 +0000 |
|---|---|---|
| committer | Tom Lane | 2007-06-11 01:16:30 +0000 |
| commit | 6808f1b1de0ebcd4af558ba84c3226b2027f55ea (patch) | |
| tree | ebd12580d3aaca6ec79b5d99563a1eff02451e88 /src/backend/nodes | |
| parent | 85d72f05167b87bc44464b2eabea8538f1fd1e45 (diff) | |
Support UPDATE/DELETE WHERE CURRENT OF cursor_name, per SQL standard.
Along the way, allow FOR UPDATE in non-WITH-HOLD cursors; there may once
have been a reason to disallow that, but it seems to work now, and it's
really rather necessary if you want to select a row via a cursor and then
update it in a concurrent-safe fashion.
Original patch by Arul Shaji, rather heavily editorialized by Tom Lane.
Diffstat (limited to 'src/backend/nodes')
| -rw-r--r-- | src/backend/nodes/copyfuncs.c | 19 | ||||
| -rw-r--r-- | src/backend/nodes/equalfuncs.c | 14 | ||||
| -rw-r--r-- | src/backend/nodes/outfuncs.c | 14 | ||||
| -rw-r--r-- | src/backend/nodes/readfuncs.c | 18 |
4 files changed, 61 insertions, 4 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 39027b1dbc8..c868ff574d9 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 - * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.377 2007/06/05 21:31:04 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.378 2007/06/11 01:16:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1300,6 +1300,20 @@ _copySetToDefault(SetToDefault *from) } /* + * _copyCurrentOfExpr + */ +static CurrentOfExpr * +_copyCurrentOfExpr(CurrentOfExpr *from) +{ + CurrentOfExpr *newnode = makeNode(CurrentOfExpr); + + COPY_SCALAR_FIELD(cvarno); + COPY_STRING_FIELD(cursor_name); + + return newnode; +} + +/* * _copyTargetEntry */ static TargetEntry * @@ -3177,6 +3191,9 @@ copyObject(void *from) case T_SetToDefault: retval = _copySetToDefault(from); break; + case T_CurrentOfExpr: + retval = _copyCurrentOfExpr(from); + break; case T_TargetEntry: retval = _copyTargetEntry(from); break; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 8a0957c117e..04072c7a654 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 - * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.308 2007/06/05 21:31:04 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.309 2007/06/11 01:16:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -599,6 +599,15 @@ _equalSetToDefault(SetToDefault *a, SetToDefault *b) } static bool +_equalCurrentOfExpr(CurrentOfExpr *a, CurrentOfExpr *b) +{ + COMPARE_SCALAR_FIELD(cvarno); + COMPARE_STRING_FIELD(cursor_name); + + return true; +} + +static bool _equalTargetEntry(TargetEntry *a, TargetEntry *b) { COMPARE_NODE_FIELD(expr); @@ -2124,6 +2133,9 @@ equal(void *a, void *b) case T_SetToDefault: retval = _equalSetToDefault(a, b); break; + case T_CurrentOfExpr: + retval = _equalCurrentOfExpr(a, b); + break; case T_TargetEntry: retval = _equalTargetEntry(a, b); break; diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 5de540642f4..869905f0cc5 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.309 2007/06/05 21:31:04 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.310 2007/06/11 01:16:22 tgl Exp $ * * NOTES * Every node type that can appear in stored rules' parsetrees *must* @@ -1059,6 +1059,15 @@ _outSetToDefault(StringInfo str, SetToDefault *node) } static void +_outCurrentOfExpr(StringInfo str, CurrentOfExpr *node) +{ + WRITE_NODE_TYPE("CURRENTOFEXPR"); + + WRITE_UINT_FIELD(cvarno); + WRITE_STRING_FIELD(cursor_name); +} + +static void _outTargetEntry(StringInfo str, TargetEntry *node) { WRITE_NODE_TYPE("TARGETENTRY"); @@ -2229,6 +2238,9 @@ _outNode(StringInfo str, void *obj) case T_SetToDefault: _outSetToDefault(str, obj); break; + case T_CurrentOfExpr: + _outCurrentOfExpr(str, obj); + break; case T_TargetEntry: _outTargetEntry(str, obj); break; diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 86c9e911a7c..e91a6e5b501 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.207 2007/06/05 21:31:04 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.208 2007/06/11 01:16:22 tgl Exp $ * * NOTES * Path and Plan nodes do not have any readfuncs support, because we @@ -874,6 +874,20 @@ _readSetToDefault(void) } /* + * _readCurrentOfExpr + */ +static CurrentOfExpr * +_readCurrentOfExpr(void) +{ + READ_LOCALS(CurrentOfExpr); + + READ_UINT_FIELD(cvarno); + READ_STRING_FIELD(cursor_name); + + READ_DONE(); +} + +/* * _readTargetEntry */ static TargetEntry * @@ -1093,6 +1107,8 @@ parseNodeString(void) return_value = _readCoerceToDomainValue(); else if (MATCH("SETTODEFAULT", 12)) return_value = _readSetToDefault(); + else if (MATCH("CURRENTOFEXPR", 13)) + return_value = _readCurrentOfExpr(); else if (MATCH("TARGETENTRY", 11)) return_value = _readTargetEntry(); else if (MATCH("RANGETBLREF", 11)) |
