mirror of
https://github.com/postgres/postgres.git
synced 2025-07-02 09:02:37 +03:00
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.
This commit is contained in:
@ -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");
|
||||
}
|
||||
|
Reference in New Issue
Block a user