summaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeTidscan.c
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/executor/nodeTidscan.c
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/executor/nodeTidscan.c')
-rw-r--r--src/backend/executor/nodeTidscan.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c
index 9b6724537e7..986ff1f3f19 100644
--- a/src/backend/executor/nodeTidscan.c
+++ b/src/backend/executor/nodeTidscan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeTidscan.c,v 1.53 2007/01/05 22:19:28 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeTidscan.c,v 1.54 2007/06/11 01:16:22 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -61,8 +61,8 @@ TidListCreate(TidScanState *tidstate)
/*
* We initialize the array with enough slots for the case that all quals
- * are simple OpExprs. If there's any ScalarArrayOpExprs, we may have to
- * enlarge the array.
+ * are simple OpExprs or CurrentOfExprs. If there are any
+ * ScalarArrayOpExprs, we may have to enlarge the array.
*/
numAllocTids = list_length(evalList);
tidList = (ItemPointerData *)
@@ -148,6 +148,25 @@ TidListCreate(TidScanState *tidstate)
pfree(ipdatums);
pfree(ipnulls);
}
+ else if (expr && IsA(expr, CurrentOfExpr))
+ {
+ CurrentOfExpr *cexpr = (CurrentOfExpr *) expr;
+ ItemPointerData cursor_tid;
+
+ if (execCurrentOf(cexpr->cursor_name,
+ RelationGetRelid(tidstate->ss.ss_currentRelation),
+ &cursor_tid))
+ {
+ if (numTids >= numAllocTids)
+ {
+ numAllocTids *= 2;
+ tidList = (ItemPointerData *)
+ repalloc(tidList,
+ numAllocTids * sizeof(ItemPointerData));
+ }
+ tidList[numTids++] = cursor_tid;
+ }
+ }
else
elog(ERROR, "could not identify CTID expression");
}