diff options
Diffstat (limited to 'src/backend/parser')
-rw-r--r-- | src/backend/parser/analyze.c | 10 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 25 | ||||
-rw-r--r-- | src/backend/parser/keywords.c | 3 | ||||
-rw-r--r-- | src/backend/parser/parse_expr.c | 20 |
4 files changed, 45 insertions, 13 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 68475387be3..3ac6f000d85 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -20,7 +20,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.363 2007/04/27 22:05:48 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.364 2007/06/11 01:16:24 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -3178,12 +3178,12 @@ transformDeclareCursorStmt(ParseState *pstate, DeclareCursorStmt *stmt) (errcode(ERRCODE_INVALID_CURSOR_DEFINITION), errmsg("DECLARE CURSOR cannot specify INTO"))); - /* Implementation restriction (might go away someday) */ - if (result->rowMarks != NIL) + /* FOR UPDATE and WITH HOLD are not compatible */ + if (result->rowMarks != NIL && (stmt->options & CURSOR_OPT_HOLD)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("DECLARE CURSOR ... FOR UPDATE/SHARE is not supported"), - errdetail("Cursors must be READ ONLY."))); + errmsg("DECLARE CURSOR WITH HOLD ... FOR UPDATE/SHARE is not supported"), + errdetail("Holdable cursors must be READ ONLY."))); /* We won't need the raw querytree any more */ stmt->query = NULL; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 8884da22892..b50be6bd739 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.591 2007/04/27 22:05:48 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.592 2007/06/11 01:16:25 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -296,7 +296,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args) %type <node> TableElement ConstraintElem TableFuncElement %type <node> columnDef %type <defelt> def_elem old_aggr_elem -%type <node> def_arg columnElem where_clause +%type <node> def_arg columnElem where_clause where_or_current_clause a_expr b_expr c_expr func_expr AexprConst indirection_el columnref in_expr having_clause func_table array_expr %type <list> row type_list array_expr_list @@ -377,8 +377,8 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args) CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT COMMITTED CONCURRENTLY CONNECTION CONSTRAINT CONSTRAINTS CONTENT_P CONVERSION_P CONVERT COPY COST CREATE CREATEDB - CREATEROLE CREATEUSER CROSS CSV CURRENT_DATE CURRENT_ROLE CURRENT_TIME - CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE + CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE + CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS @@ -5715,7 +5715,7 @@ returning_clause: *****************************************************************************/ DeleteStmt: DELETE_P FROM relation_expr_opt_alias - using_clause where_clause returning_clause + using_clause where_or_current_clause returning_clause { DeleteStmt *n = makeNode(DeleteStmt); n->relation = $3; @@ -5771,7 +5771,7 @@ opt_nowait: NOWAIT { $$ = TRUE; } UpdateStmt: UPDATE relation_expr_opt_alias SET set_clause_list from_clause - where_clause + where_or_current_clause returning_clause { UpdateStmt *n = makeNode(UpdateStmt); @@ -6562,6 +6562,18 @@ where_clause: | /*EMPTY*/ { $$ = NULL; } ; +/* variant for UPDATE and DELETE */ +where_or_current_clause: + WHERE a_expr { $$ = $2; } + | WHERE CURRENT_P OF name + { + CurrentOfExpr *n = makeNode(CurrentOfExpr); + n->cursor_name = $4; + $$ = (Node *) n; + } + | /*EMPTY*/ { $$ = NULL; } + ; + TableFuncElementList: TableFuncElement @@ -8818,6 +8830,7 @@ unreserved_keyword: | CREATEROLE | CREATEUSER | CSV + | CURRENT_P | CURSOR | CYCLE | DATABASE diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index 5c8ef10a214..b48a0c79583 100644 --- a/src/backend/parser/keywords.c +++ b/src/backend/parser/keywords.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.187 2007/04/26 16:13:12 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.188 2007/06/11 01:16:25 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -101,6 +101,7 @@ static const ScanKeyword ScanKeywords[] = { {"createuser", CREATEUSER}, {"cross", CROSS}, {"csv", CSV}, + {"current", CURRENT_P}, {"current_date", CURRENT_DATE}, {"current_role", CURRENT_ROLE}, {"current_time", CURRENT_TIME}, 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 */ |