summaryrefslogtreecommitdiff
path: root/src/backend/nodes
diff options
context:
space:
mode:
authorTom Lane2007-06-11 01:16:30 +0000
committerTom Lane2007-06-11 01:16:30 +0000
commit6808f1b1de0ebcd4af558ba84c3226b2027f55ea (patch)
treeebd12580d3aaca6ec79b5d99563a1eff02451e88 /src/backend/nodes
parent85d72f05167b87bc44464b2eabea8538f1fd1e45 (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.c19
-rw-r--r--src/backend/nodes/equalfuncs.c14
-rw-r--r--src/backend/nodes/outfuncs.c14
-rw-r--r--src/backend/nodes/readfuncs.c18
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))