From c44323176ece538372bfdcd999e241e00ce753ee Mon Sep 17 00:00:00 2001 From: Bruce Momjian <bruce@momjian.us> Date: Sat, 28 Oct 2000 19:41:00 +0000 Subject: [PATCH] Back out change to gram.y for parens. --- src/backend/parser/gram.y | 169 +++++++++++--------------------------- 1 file changed, 50 insertions(+), 119 deletions(-) diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index d63de99f1b0..cfdc429f023 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.199 2000/10/28 15:44:04 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.200 2000/10/28 19:41:00 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -127,15 +127,14 @@ static void doNegateFloat(Value *v); DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt, DropTrigStmt, DropUserStmt, DropdbStmt, ExplainStmt, ExtendStmt, FetchStmt, GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt, LockStmt, - NotifyStmt, OptimizableStmt, ProcedureStmt - QualifiedSelectStmt, ReindexStmt, + NotifyStmt, OptimizableStmt, ProcedureStmt, ReindexStmt, RemoveAggrStmt, RemoveFuncStmt, RemoveOperStmt, RenameStmt, RevokeStmt, RuleActionStmt, RuleActionStmtOrEmpty, RuleStmt, SelectStmt, SetSessionStmt, TransactionStmt, TruncateStmt, UnlistenStmt, UpdateStmt, VacuumStmt, VariableResetStmt, VariableSetStmt, VariableShowStmt, ViewStmt -%type <node> subquery, simple_select, select_head, set_select +%type <node> select_clause, select_subclause %type <list> SessionList %type <node> SessionClause @@ -178,20 +177,19 @@ static void doNegateFloat(Value *v); result, OptTempTableName, relation_name_list, OptTableElementList, OptUnder, OptInherit, definition, opt_distinct, opt_with, func_args, func_args_list, func_as, - oper_argtypes, RuleActionList, RuleActionMulti, - RuleActionOrSelectMulti, RuleActions, RuleActionBracket, + oper_argtypes, RuleActionList, RuleActionMulti, opt_column_list, columnList, opt_va_list, va_list, sort_clause, sortby_list, index_params, index_list, name_list, from_clause, from_list, opt_array_bounds, expr_list, attrs, target_list, update_target_list, def_list, opt_indirection, group_clause, TriggerFuncArgs, - opt_select_limit, select_limit + opt_select_limit %type <typnam> func_arg, func_return, aggr_argtype %type <boolean> opt_arg, TriggerForOpt, TriggerForType, OptTemp -%type <list> opt_for_update_clause, for_update_clause, update_list +%type <list> for_update_clause, update_list %type <boolean> opt_all %type <boolean> opt_table %type <boolean> opt_chain, opt_trans @@ -2662,7 +2660,7 @@ opt_column: COLUMN { $$ = COLUMN; } RuleStmt: CREATE RULE name AS { QueryIsRule=TRUE; } ON event TO event_object where_clause - DO opt_instead RuleActions + DO opt_instead RuleActionList { RuleStmt *n = makeNode(RuleStmt); n->rulename = $3; @@ -2675,78 +2673,28 @@ RuleStmt: CREATE RULE name AS } ; -RuleActions: NOTHING { $$ = NIL; } - | RuleActionStmt { $$ = makeList1($1); } - | SelectStmt { $$ = makeList1($1); } - | RuleActionList - | RuleActionBracket - ; - -/* LEGACY: Version 7.0 did not like SELECT statements in these lists, - * but because of an oddity in the syntax for select_clause, allowed - * certain forms like "DO INSTEAD (select 1)", and this is used in - * the regression tests. - * Here, we're allowing just one SELECT in parentheses, to preserve - * any such expectations, and make the regression tests work. - * ++ KO'G - */ -RuleActionList: '(' RuleActionMulti ')' { $$ = $2; } - | '(' SelectStmt ')' { $$ = makeList1($2); } - ; - -/* An undocumented feature, bracketed lists are allowed to contain - * SELECT statements on the same basis as the others. Before this, - * they were the same as parenthesized lists, and did not allow - * SelectStmts. Anybody know why they were here originally? Or if - * they're in the regression tests at all? - * ++ KO'G - */ -RuleActionBracket: '[' RuleActionOrSelectMulti ']' { $$ = $2; } +RuleActionList: NOTHING { $$ = NIL; } + | SelectStmt { $$ = makeList1($1); } + | RuleActionStmt { $$ = makeList1($1); } + | '[' RuleActionMulti ']' { $$ = $2; } + | '(' RuleActionMulti ')' { $$ = $2; } ; /* the thrashing around here is to discard "empty" statements... */ RuleActionMulti: RuleActionMulti ';' RuleActionStmtOrEmpty { if ($3 != (Node *) NULL) - if ($1 != NIL) - $$ = lappend($1, $3); - else - $$ = makeList1($3); - else - $$ = $1; - } - | RuleActionStmtOrEmpty - { if ($1 != (Node *) NULL) - $$ = makeList1($1); - else - $$ = NIL; - } - ; - -RuleActionOrSelectMulti: RuleActionOrSelectMulti ';' RuleActionStmtOrEmpty - { if ($3 != (Node *) NULL) - if ($1 != NIL) - $$ = lappend($1, $3); - else - $$ = makeList1($3); + $$ = lappend($1, $3); else $$ = $1; } - | RuleActionOrSelectMulti ';' SelectStmt - { if ($1 != NIL) - $$ = lappend($1, $3); - else - $$ = makeList1($3); - } | RuleActionStmtOrEmpty { if ($1 != (Node *) NULL) $$ = makeList1($1); else $$ = NIL; } - | SelectStmt { $$ = makeList1($1); } ; - RuleActionStmt: InsertStmt | UpdateStmt | DeleteStmt @@ -3300,12 +3248,7 @@ opt_cursor: BINARY { $$ = TRUE; } * However, this is not checked by the grammar; parse analysis must check it. */ -SelectStmt: QualifiedSelectStmt - | select_head - ; - -QualifiedSelectStmt: - select_head sort_clause opt_for_update_clause opt_select_limit +SelectStmt: select_clause sort_clause for_update_clause opt_select_limit { SelectStmt *n = findLeftmostSelect($1); @@ -3315,35 +3258,34 @@ QualifiedSelectStmt: n->limitCount = nth(1, $4); $$ = $1; } - | select_head for_update_clause opt_select_limit - { - SelectStmt *n = findLeftmostSelect($1); + ; - n->sortClause = NULL; - n->forUpdate = $2; - n->limitOffset = nth(0, $3); - n->limitCount = nth(1, $3); - $$ = $1; +/* This rule parses Select statements that can appear within set operations, + * including UNION, INTERSECT and EXCEPT. '(' and ')' can be used to specify + * the ordering of the set operations. Without '(' and ')' we want the + * operations to be ordered per the precedence specs at the head of this file. + * + * Since parentheses around SELECTs also appear in the expression grammar, + * there is a parse ambiguity if parentheses are allowed at the top level of a + * select_clause: are the parens part of the expression or part of the select? + * We separate select_clause into two levels to resolve this: select_clause + * can have top-level parentheses, select_subclause cannot. + * + * Note that sort clauses cannot be included at this level --- a sort clause + * can only appear at the end of the complete Select, and it will be handled + * by the topmost SelectStmt rule. Likewise FOR UPDATE and LIMIT. + */ +select_clause: '(' select_subclause ')' + { + $$ = $2; } - | select_head select_limit + | select_subclause { - SelectStmt *n = findLeftmostSelect($1); - - n->sortClause = NULL; - n->forUpdate = NULL; - n->limitOffset = nth(0, $2); - n->limitCount = nth(1, $2); - $$ = $1; + $$ = $1; } ; -subquery: '(' subquery ')' { $$ = $2; } - | '(' QualifiedSelectStmt ')' { $$ = $2; } - | '(' set_select ')' { $$ = $2; } - | simple_select { $$ = $1; } - ; - -simple_select: SELECT opt_distinct target_list +select_subclause: SELECT opt_distinct target_list result from_clause where_clause group_clause having_clause { @@ -3358,13 +3300,7 @@ simple_select: SELECT opt_distinct target_list n->havingClause = $8; $$ = (Node *)n; } - ; - -select_head: simple_select { $$ = $1; } - | set_select { $$ = $1; } - ; - -set_select: select_head UNION opt_all subquery + | select_clause UNION opt_all select_clause { SetOperationStmt *n = makeNode(SetOperationStmt); n->op = SETOP_UNION; @@ -3373,7 +3309,7 @@ set_select: select_head UNION opt_all subquery n->rarg = $4; $$ = (Node *) n; } - | select_head INTERSECT opt_all subquery + | select_clause INTERSECT opt_all select_clause { SetOperationStmt *n = makeNode(SetOperationStmt); n->op = SETOP_INTERSECT; @@ -3382,7 +3318,7 @@ set_select: select_head UNION opt_all subquery n->rarg = $4; $$ = (Node *) n; } - | select_head EXCEPT opt_all subquery + | select_clause EXCEPT opt_all select_clause { SetOperationStmt *n = makeNode(SetOperationStmt); n->op = SETOP_EXCEPT; @@ -3447,6 +3383,7 @@ opt_distinct: DISTINCT { $$ = makeList1(NIL); } ; sort_clause: ORDER BY sortby_list { $$ = $3; } + | /*EMPTY*/ { $$ = NIL; } ; sortby_list: sortby { $$ = makeList1($1); } @@ -3468,7 +3405,7 @@ OptUseOp: USING all_Op { $$ = $2; } ; -select_limit: LIMIT select_limit_value ',' select_offset_value +opt_select_limit: LIMIT select_limit_value ',' select_offset_value { $$ = makeList2($4, $2); } | LIMIT select_limit_value OFFSET select_offset_value { $$ = makeList2($4, $2); } @@ -3478,9 +3415,6 @@ select_limit: LIMIT select_limit_value ',' select_offset_value { $$ = makeList2($2, $4); } | OFFSET select_offset_value { $$ = makeList2($2, NULL); } - ; - -opt_select_limit: select_limit { $$ = $1; } | /* EMPTY */ { $$ = makeList2(NULL, NULL); } ; @@ -3580,9 +3514,6 @@ having_clause: HAVING a_expr for_update_clause: FOR UPDATE update_list { $$ = $3; } | FOR READ ONLY { $$ = NULL; } - ; - -opt_for_update_clause: for_update_clause { $$ = $1; } | /* EMPTY */ { $$ = NULL; } ; @@ -3626,7 +3557,7 @@ table_ref: relation_expr $1->name = $2; $$ = (Node *) $1; } - | '(' SelectStmt ')' alias_clause + | '(' select_subclause ')' alias_clause { RangeSubselect *n = makeNode(RangeSubselect); n->subquery = $2; @@ -4162,7 +4093,7 @@ opt_interval: datetime { $$ = makeList1($1); } * Define row_descriptor to allow yacc to break the reduce/reduce conflict * with singleton expressions. */ -row_expr: '(' row_descriptor ')' IN '(' SelectStmt ')' +row_expr: '(' row_descriptor ')' IN '(' select_subclause ')' { SubLink *n = makeNode(SubLink); n->lefthand = $2; @@ -4172,7 +4103,7 @@ row_expr: '(' row_descriptor ')' IN '(' SelectStmt ')' n->subselect = $6; $$ = (Node *)n; } - | '(' row_descriptor ')' NOT IN '(' SelectStmt ')' + | '(' row_descriptor ')' NOT IN '(' select_subclause ')' { SubLink *n = makeNode(SubLink); n->lefthand = $2; @@ -4182,7 +4113,7 @@ row_expr: '(' row_descriptor ')' IN '(' SelectStmt ')' n->subselect = $7; $$ = (Node *)n; } - | '(' row_descriptor ')' all_Op sub_type '(' SelectStmt ')' + | '(' row_descriptor ')' all_Op sub_type '(' select_subclause ')' { SubLink *n = makeNode(SubLink); n->lefthand = $2; @@ -4195,7 +4126,7 @@ row_expr: '(' row_descriptor ')' IN '(' SelectStmt ')' n->subselect = $7; $$ = (Node *)n; } - | '(' row_descriptor ')' all_Op '(' SelectStmt ')' + | '(' row_descriptor ')' all_Op '(' select_subclause ')' { SubLink *n = makeNode(SubLink); n->lefthand = $2; @@ -4526,7 +4457,7 @@ a_expr: c_expr $$ = n; } } - | a_expr all_Op sub_type '(' SelectStmt ')' + | a_expr all_Op sub_type '(' select_subclause ')' { SubLink *n = makeNode(SubLink); n->lefthand = makeList1($1); @@ -4922,7 +4853,7 @@ c_expr: attr n->agg_distinct = FALSE; $$ = (Node *)n; } - | '(' SelectStmt ')' + | '(' select_subclause ')' { SubLink *n = makeNode(SubLink); n->lefthand = NIL; @@ -4932,7 +4863,7 @@ c_expr: attr n->subselect = $2; $$ = (Node *)n; } - | EXISTS '(' SelectStmt ')' + | EXISTS '(' select_subclause ')' { SubLink *n = makeNode(SubLink); n->lefthand = NIL; @@ -5031,7 +4962,7 @@ trim_list: a_expr FROM expr_list { $$ = $1; } ; -in_expr: SelectStmt +in_expr: select_subclause { SubLink *n = makeNode(SubLink); n->subselect = $1; -- GitLab