aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser')
-rw-r--r--src/backend/parser/analyze.c10
-rw-r--r--src/backend/parser/gram.y25
-rw-r--r--src/backend/parser/keywords.c3
-rw-r--r--src/backend/parser/parse_expr.c20
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 */