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/executor/nodeTidscan.c | |
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/executor/nodeTidscan.c')
-rw-r--r-- | src/backend/executor/nodeTidscan.c | 25 |
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"); } |