aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_expr.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-06-11 01:16:30 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-06-11 01:16:30 +0000
commit6808f1b1de0ebcd4af558ba84c3226b2027f55ea (patch)
treeebd12580d3aaca6ec79b5d99563a1eff02451e88 /src/backend/parser/parse_expr.c
parent85d72f05167b87bc44464b2eabea8538f1fd1e45 (diff)
downloadpostgresql-6808f1b1de0ebcd4af558ba84c3226b2027f55ea.tar.gz
postgresql-6808f1b1de0ebcd4af558ba84c3226b2027f55ea.zip
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/parser/parse_expr.c')
-rw-r--r--src/backend/parser/parse_expr.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 45107e43ace..6601bfe40ee 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 */