From 6808f1b1de0ebcd4af558ba84c3226b2027f55ea Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 11 Jun 2007 01:16:30 +0000 Subject: 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. --- src/backend/parser/parse_expr.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'src/backend/parser/parse_expr.c') diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 45107e43ac..6601bfe40e 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.218 2007/06/05 21:31:05 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.219 2007/06/11 01:16:25 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -243,6 +243,21 @@ transformExpr(ParseState *pstate, Node *expr) result = transformBooleanTest(pstate, (BooleanTest *) expr); break; + case T_CurrentOfExpr: + { + CurrentOfExpr *c = (CurrentOfExpr *) expr; + int sublevels_up; + + /* CURRENT OF can only appear at top level of UPDATE/DELETE */ + Assert(pstate->p_target_rangetblentry != NULL); + c->cvarno = RTERangeTablePosn(pstate, + pstate->p_target_rangetblentry, + &sublevels_up); + Assert(sublevels_up == 0); + result = expr; + break; + } + /********************************************* * Quietly accept node types that may be presented when we are * called on an already-transformed tree. @@ -1863,6 +1878,9 @@ exprType(Node *expr) case T_SetToDefault: type = ((SetToDefault *) expr)->typeId; break; + case T_CurrentOfExpr: + type = BOOLOID; + break; default: elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr)); type = InvalidOid; /* keep compiler quiet */ -- cgit v1.2.1