summaryrefslogtreecommitdiff
path: root/src/backend/parser
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser')
-rw-r--r--src/backend/parser/analyze.c90
-rw-r--r--src/backend/parser/gram.y127
-rw-r--r--src/backend/parser/parse_clause.c4
-rw-r--r--src/backend/parser/parse_type.c3
4 files changed, 96 insertions, 128 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 2089008bbf5..3486a1e010b 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.264 2003/02/13 22:50:01 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.265 2003/03/10 03:53:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -96,6 +96,8 @@ static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt);
static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt);
static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt);
static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
+static Query *transformDeclareCursorStmt(ParseState *pstate,
+ DeclareCursorStmt *stmt);
static Query *transformPrepareStmt(ParseState *pstate, PrepareStmt *stmt);
static Query *transformExecuteStmt(ParseState *pstate, ExecuteStmt *stmt);
static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt,
@@ -313,6 +315,11 @@ transformStmt(ParseState *pstate, Node *parseTree,
(SelectStmt *) parseTree);
break;
+ case T_DeclareCursorStmt:
+ result = transformDeclareCursorStmt(pstate,
+ (DeclareCursorStmt *) parseTree);
+ break;
+
default:
/*
@@ -445,7 +452,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
Assert(IsA(selectQuery, Query));
Assert(selectQuery->commandType == CMD_SELECT);
- if (selectQuery->into || selectQuery->isPortal)
+ if (selectQuery->into)
elog(ERROR, "INSERT ... SELECT may not specify INTO");
/*
@@ -1616,27 +1623,6 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
qry->commandType = CMD_SELECT;
- if (stmt->portalname)
- {
- /* DECLARE CURSOR */
- if (stmt->into)
- elog(ERROR, "DECLARE CURSOR must not specify INTO");
- if (stmt->forUpdate)
- elog(ERROR, "DECLARE/UPDATE is not supported"
- "\n\tCursors must be READ ONLY");
- qry->into = makeNode(RangeVar);
- qry->into->relname = stmt->portalname;
- qry->isPortal = TRUE;
- qry->isBinary = stmt->binary; /* internal portal */
- }
- else
- {
- /* SELECT */
- qry->into = stmt->into;
- qry->isPortal = FALSE;
- qry->isBinary = FALSE;
- }
-
/* make FOR UPDATE clause available to addRangeTableEntry */
pstate->p_forUpdate = stmt->forUpdate;
@@ -1646,6 +1632,8 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
/* transform targetlist */
qry->targetList = transformTargetList(pstate, stmt->targetList);
+ /* handle any SELECT INTO/CREATE TABLE AS spec */
+ qry->into = stmt->into;
if (stmt->intoColNames)
applyColumnNames(qry->targetList, stmt->intoColNames);
@@ -1708,8 +1696,6 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
SetOperationStmt *sostmt;
RangeVar *into;
List *intoColNames;
- char *portalname;
- bool binary;
List *sortClause;
Node *limitOffset;
Node *limitCount;
@@ -1738,14 +1724,10 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
leftmostSelect->larg == NULL);
into = leftmostSelect->into;
intoColNames = leftmostSelect->intoColNames;
- portalname = stmt->portalname;
- binary = stmt->binary;
/* clear them to prevent complaints in transformSetOperationTree() */
leftmostSelect->into = NULL;
leftmostSelect->intoColNames = NIL;
- stmt->portalname = NULL;
- stmt->binary = false;
/*
* These are not one-time, exactly, but we want to process them here
@@ -1825,36 +1807,13 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
}
/*
- * Insert one-time items into top-level query
+ * Handle SELECT INTO/CREATE TABLE AS.
*
- * This needs to agree with transformSelectStmt!
- */
- if (portalname)
- {
- /* DECLARE CURSOR */
- if (into)
- elog(ERROR, "DECLARE CURSOR must not specify INTO");
- if (forUpdate)
- elog(ERROR, "DECLARE/UPDATE is not supported"
- "\n\tCursors must be READ ONLY");
- qry->into = makeNode(RangeVar);
- qry->into->relname = portalname;
- qry->isPortal = TRUE;
- qry->isBinary = binary; /* internal portal */
- }
- else
- {
- /* SELECT */
- qry->into = into;
- qry->isPortal = FALSE;
- qry->isBinary = FALSE;
- }
-
- /*
* Any column names from CREATE TABLE AS need to be attached to both
* the top level and the leftmost subquery. We do not do this earlier
* because we do *not* want the targetnames list to be affected.
*/
+ qry->into = into;
if (intoColNames)
{
applyColumnNames(qry->targetList, intoColNames);
@@ -1938,8 +1897,6 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt)
*/
if (stmt->into)
elog(ERROR, "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT");
- if (stmt->portalname) /* should not happen */
- elog(ERROR, "Portal may not appear in UNION/INTERSECT/EXCEPT");
/* We don't support forUpdate with set ops at the moment. */
if (stmt->forUpdate)
elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT");
@@ -2328,6 +2285,27 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt,
}
static Query *
+transformDeclareCursorStmt(ParseState *pstate, DeclareCursorStmt *stmt)
+{
+ Query *result = makeNode(Query);
+ List *extras_before = NIL,
+ *extras_after = NIL;
+
+ result->commandType = CMD_UTILITY;
+ result->utilityStmt = (Node *) stmt;
+
+ stmt->query = (Node *) transformStmt(pstate, stmt->query,
+ &extras_before, &extras_after);
+
+ /* Shouldn't get any extras, since grammar only allows SelectStmt */
+ if (extras_before || extras_after)
+ elog(ERROR, "transformDeclareCursorStmt: internal error");
+
+ return result;
+}
+
+
+static Query *
transformPrepareStmt(ParseState *pstate, PrepareStmt *stmt)
{
Query *result = makeNode(Query);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index c593196dfc8..045d3cc2ca2 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.404 2003/02/16 02:30:38 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.405 2003/03/10 03:53:50 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -135,12 +135,12 @@ static void doNegateFloat(Value *v);
CreateDomainStmt CreateGroupStmt CreateOpClassStmt CreatePLangStmt
CreateSchemaStmt CreateSeqStmt CreateStmt
CreateAssertStmt CreateTrigStmt CreateUserStmt
- CreatedbStmt CursorStmt DefineStmt DeleteStmt
+ CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt
DropGroupStmt DropOpClassStmt DropPLangStmt DropStmt
DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt
DropUserStmt DropdbStmt ExplainStmt FetchStmt
GrantStmt IndexStmt InsertStmt ListenStmt LoadStmt
- LockStmt NotifyStmt OptimizableStmt
+ LockStmt NotifyStmt ExplainableStmt PreparableStmt
CreateFunctionStmt ReindexStmt RemoveAggrStmt
RemoveFuncStmt RemoveOperStmt RenameStmt RevokeStmt
RuleActionStmt RuleActionStmtOrEmpty RuleStmt
@@ -241,7 +241,7 @@ static void doNegateFloat(Value *v);
%type <ival> opt_interval
%type <node> overlay_placing substr_from substr_for
-%type <boolean> opt_instead opt_cursor opt_analyze
+%type <boolean> opt_instead opt_analyze
%type <boolean> index_opt_unique opt_verbose opt_full
%type <boolean> opt_freeze opt_default opt_recheck
%type <defelt> opt_binary opt_oids copy_delimiter
@@ -249,7 +249,7 @@ static void doNegateFloat(Value *v);
%type <boolean> copy_from
%type <ival> direction reindex_type drop_type
- opt_column event comment_type
+ opt_column event comment_type cursor_options
%type <ival> fetch_how_many
@@ -481,68 +481,72 @@ stmt :
| AlterDomainStmt
| AlterGroupStmt
| AlterTableStmt
- | AlterUserStmt
| AlterUserSetStmt
+ | AlterUserStmt
+ | AnalyzeStmt
+ | CheckPointStmt
| ClosePortalStmt
+ | ClusterStmt
+ | CommentStmt
+ | ConstraintsSetStmt
| CopyStmt
- | CreateStmt
| CreateAsStmt
+ | CreateAssertStmt
| CreateCastStmt
+ | CreateConversionStmt
| CreateDomainStmt
| CreateFunctionStmt
- | CreateSchemaStmt
| CreateGroupStmt
- | CreateSeqStmt
| CreateOpClassStmt
| CreatePLangStmt
- | CreateAssertStmt
+ | CreateSchemaStmt
+ | CreateSeqStmt
+ | CreateStmt
| CreateTrigStmt
| CreateUserStmt
- | ClusterStmt
+ | CreatedbStmt
| DeallocateStmt
+ | DeclareCursorStmt
| DefineStmt
- | DropStmt
- | TruncateStmt
- | CommentStmt
+ | DeleteStmt
+ | DropAssertStmt
| DropCastStmt
| DropGroupStmt
| DropOpClassStmt
| DropPLangStmt
- | DropAssertStmt
- | DropTrigStmt
| DropRuleStmt
+ | DropStmt
+ | DropTrigStmt
| DropUserStmt
+ | DropdbStmt
| ExecuteStmt
| ExplainStmt
| FetchStmt
| GrantStmt
| IndexStmt
+ | InsertStmt
| ListenStmt
- | UnlistenStmt
+ | LoadStmt
| LockStmt
| NotifyStmt
| PrepareStmt
| ReindexStmt
| RemoveAggrStmt
- | RemoveOperStmt
| RemoveFuncStmt
+ | RemoveOperStmt
| RenameStmt
| RevokeStmt
- | OptimizableStmt
| RuleStmt
+ | SelectStmt
| TransactionStmt
- | ViewStmt
- | LoadStmt
- | CreatedbStmt
- | DropdbStmt
+ | TruncateStmt
+ | UnlistenStmt
+ | UpdateStmt
| VacuumStmt
- | AnalyzeStmt
+ | VariableResetStmt
| VariableSetStmt
| VariableShowStmt
- | VariableResetStmt
- | ConstraintsSetStmt
- | CheckPointStmt
- | CreateConversionStmt
+ | ViewStmt
| /*EMPTY*/
{ $$ = (Node *)NULL; }
;
@@ -3961,16 +3965,7 @@ opt_name_list:
*
*****************************************************************************/
-ExplainStmt:
- EXPLAIN opt_analyze opt_verbose OptimizableStmt
- {
- ExplainStmt *n = makeNode(ExplainStmt);
- n->analyze = $2;
- n->verbose = $3;
- n->query = (Query*)$4;
- $$ = (Node *)n;
- }
- | EXPLAIN opt_analyze opt_verbose ExecuteStmt
+ExplainStmt: EXPLAIN opt_analyze opt_verbose ExplainableStmt
{
ExplainStmt *n = makeNode(ExplainStmt);
n->analyze = $2;
@@ -3980,6 +3975,15 @@ ExplainStmt:
}
;
+ExplainableStmt:
+ SelectStmt
+ | InsertStmt
+ | UpdateStmt
+ | DeleteStmt
+ | DeclareCursorStmt
+ | ExecuteStmt /* by default all are $$=$1 */
+ ;
+
opt_analyze:
analyze_keyword { $$ = TRUE; }
| /* EMPTY */ { $$ = FALSE; }
@@ -3992,7 +3996,7 @@ opt_analyze:
*
*****************************************************************************/
-PrepareStmt: PREPARE name prep_type_clause AS OptimizableStmt
+PrepareStmt: PREPARE name prep_type_clause AS PreparableStmt
{
PrepareStmt *n = makeNode(PrepareStmt);
n->name = $2;
@@ -4011,6 +4015,13 @@ prep_type_list: Typename { $$ = makeList1($1); }
{ $$ = lappend($1, $3); }
;
+PreparableStmt:
+ SelectStmt
+ | InsertStmt
+ | UpdateStmt
+ | DeleteStmt /* by default all are $$=$1 */
+ ;
+
/*****************************************************************************
*
* QUERY:
@@ -4054,26 +4065,6 @@ DeallocateStmt: DEALLOCATE name
;
/*****************************************************************************
- * *
- * Optimizable Stmts: *
- * *
- * one of the five queries processed by the planner *
- * *
- * [ultimately] produces query-trees as specified *
- * in the query-spec document in ~postgres/ref *
- * *
- *****************************************************************************/
-
-OptimizableStmt:
- SelectStmt
- | CursorStmt
- | UpdateStmt
- | InsertStmt
- | DeleteStmt /* by default all are $$=$1 */
- ;
-
-
-/*****************************************************************************
*
* QUERY:
* INSERT STATEMENTS
@@ -4213,20 +4204,20 @@ UpdateStmt: UPDATE relation_expr
* CURSOR STATEMENTS
*
*****************************************************************************/
-CursorStmt: DECLARE name opt_cursor CURSOR FOR SelectStmt
+DeclareCursorStmt: DECLARE name cursor_options CURSOR FOR SelectStmt
{
- SelectStmt *n = (SelectStmt *)$6;
+ DeclareCursorStmt *n = makeNode(DeclareCursorStmt);
n->portalname = $2;
- n->binary = $3;
- $$ = $6;
+ n->options = $3;
+ n->query = $6;
+ $$ = (Node *)n;
}
;
-opt_cursor: BINARY { $$ = TRUE; }
- | INSENSITIVE { $$ = FALSE; }
- | SCROLL { $$ = FALSE; }
- | INSENSITIVE SCROLL { $$ = FALSE; }
- | /*EMPTY*/ { $$ = FALSE; }
+cursor_options: /*EMPTY*/ { $$ = 0; }
+ | cursor_options BINARY { $$ = $1 | CURSOR_OPT_BINARY; }
+ | cursor_options SCROLL { $$ = $1 | CURSOR_OPT_SCROLL; }
+ | cursor_options INSENSITIVE { $$ = $1 | CURSOR_OPT_INSENSITIVE; }
;
/*****************************************************************************
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 33e7cce4203..d4c13165e5a 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.110 2003/02/16 02:30:38 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.111 2003/03/10 03:53:51 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -414,7 +414,7 @@ transformRangeSubselect(ParseState *pstate, RangeSubselect *r)
if (query->commandType != CMD_SELECT)
elog(ERROR, "Expected SELECT query from subselect in FROM");
- if (query->resultRelation != 0 || query->into != NULL || query->isPortal)
+ if (query->resultRelation != 0 || query->into != NULL)
elog(ERROR, "Subselect in FROM may not have SELECT INTO");
/*
diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c
index e5f1e88ffdb..1f0b7639d5f 100644
--- a/src/backend/parser/parse_type.c
+++ b/src/backend/parser/parse_type.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.53 2003/02/19 23:41:15 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.54 2003/03/10 03:53:51 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -455,7 +455,6 @@ parseTypeString(const char *str, Oid *type_id, int32 *typmod)
stmt->groupClause != NIL ||
stmt->havingClause != NULL ||
stmt->sortClause != NIL ||
- stmt->portalname != NULL ||
stmt->limitOffset != NULL ||
stmt->limitCount != NULL ||
stmt->forUpdate != NIL ||