1111 *
1212 *
1313 * IDENTIFICATION
14- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.198 2000/10/25 18:56:16 tgl Exp $
14+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.199 2000/10/28 15:44:04 momjian Exp $
1515 *
1616 * HISTORY
1717 * AUTHORDATEMAJOR EVENT
@@ -127,14 +127,15 @@ static void doNegateFloat(Value *v);
127127DropGroupStmt ,DropPLangStmt ,DropSchemaStmt ,DropStmt ,DropTrigStmt ,
128128DropUserStmt ,DropdbStmt ,ExplainStmt ,ExtendStmt ,FetchStmt ,
129129GrantStmt ,IndexStmt ,InsertStmt ,ListenStmt ,LoadStmt ,LockStmt ,
130- NotifyStmt ,OptimizableStmt ,ProcedureStmt ,ReindexStmt ,
130+ NotifyStmt ,OptimizableStmt ,ProcedureStmt
131+ QualifiedSelectStmt ,ReindexStmt ,
131132RemoveAggrStmt ,RemoveFuncStmt ,RemoveOperStmt ,
132133RenameStmt ,RevokeStmt ,RuleActionStmt ,RuleActionStmtOrEmpty ,
133134RuleStmt ,SelectStmt ,SetSessionStmt ,TransactionStmt ,TruncateStmt ,
134135UnlistenStmt ,UpdateStmt ,VacuumStmt ,VariableResetStmt ,
135136VariableSetStmt ,VariableShowStmt ,ViewStmt
136137
137- %type <node> select_clause , select_subclause
138+ %type <node> subquery , simple_select , select_head , set_select
138139
139140%type <list> SessionList
140141%type <node> SessionClause
@@ -177,19 +178,20 @@ static void doNegateFloat(Value *v);
177178result ,OptTempTableName ,relation_name_list ,OptTableElementList ,
178179OptUnder ,OptInherit ,definition ,opt_distinct ,
179180opt_with ,func_args ,func_args_list ,func_as ,
180- oper_argtypes ,RuleActionList ,RuleActionMulti ,
181+ oper_argtypes ,RuleActionList ,RuleActionMulti ,
182+ RuleActionOrSelectMulti ,RuleActions ,RuleActionBracket ,
181183opt_column_list ,columnList ,opt_va_list ,va_list ,
182184sort_clause ,sortby_list ,index_params ,index_list ,name_list ,
183185from_clause ,from_list ,opt_array_bounds ,
184186expr_list ,attrs ,target_list ,update_target_list ,
185187def_list ,opt_indirection ,group_clause ,TriggerFuncArgs ,
186- opt_select_limit
188+ opt_select_limit , select_limit
187189
188190%type <typnam> func_arg ,func_return ,aggr_argtype
189191
190192%type <boolean> opt_arg ,TriggerForOpt ,TriggerForType ,OptTemp
191193
192- %type <list> for_update_clause ,update_list
194+ %type <list> opt_for_update_clause , for_update_clause ,update_list
193195%type <boolean> opt_all
194196%type <boolean> opt_table
195197%type <boolean> opt_chain ,opt_trans
@@ -2660,7 +2662,7 @@ opt_column: COLUMN{ $$ = COLUMN; }
26602662RuleStmt :CREATE RULE name AS
26612663 { QueryIsRule=TRUE ; }
26622664ON event TO event_object where_clause
2663- DO opt_instead RuleActionList
2665+ DO opt_instead RuleActions
26642666{
26652667RuleStmt *n = makeNode(RuleStmt);
26662668n->rulename =$3 ;
@@ -2673,28 +2675,78 @@ RuleStmt: CREATE RULE name AS
26732675}
26742676;
26752677
2676- RuleActionList :NOTHING {$$ = NIL; }
2677- | SelectStmt {$$ = makeList1($1 ); }
2678- | RuleActionStmt {$$ = makeList1($1 ); }
2679- | ' [' RuleActionMulti ' ]' {$$ =$2 ; }
2680- | ' (' RuleActionMulti ' )' {$$ =$2 ; }
2678+ RuleActions :NOTHING {$$ = NIL; }
2679+ | RuleActionStmt {$$ = makeList1($1 ); }
2680+ | SelectStmt {$$ = makeList1($1 ); }
2681+ | RuleActionList
2682+ | RuleActionBracket
2683+ ;
2684+
2685+ /* LEGACY: Version 7.0 did not like SELECT statements in these lists,
2686+ * but because of an oddity in the syntax for select_clause, allowed
2687+ * certain forms like "DO INSTEAD (select 1)", and this is used in
2688+ * the regression tests.
2689+ * Here, we're allowing just one SELECT in parentheses, to preserve
2690+ * any such expectations, and make the regression tests work.
2691+ * ++ KO'G
2692+ */
2693+ RuleActionList :' (' RuleActionMulti ' )' {$$ =$2 ; }
2694+ | ' (' SelectStmt ' )' {$$ = makeList1($2 ); }
2695+ ;
2696+
2697+ /* An undocumented feature, bracketed lists are allowed to contain
2698+ * SELECT statements on the same basis as the others. Before this,
2699+ * they were the same as parenthesized lists, and did not allow
2700+ * SelectStmts. Anybody know why they were here originally? Or if
2701+ * they're in the regression tests at all?
2702+ * ++ KO'G
2703+ */
2704+ RuleActionBracket :' [' RuleActionOrSelectMulti ' ]' {$$ =$2 ; }
26812705;
26822706
26832707/* the thrashing around here is to discard "empty" statements...*/
26842708RuleActionMulti :RuleActionMulti ' ;' RuleActionStmtOrEmpty
26852709{if ($3 != (Node *)NULL )
2686- $$ = lappend($1 ,$3 );
2710+ if ($1 != NIL)
2711+ $$ = lappend($1 ,$3 );
2712+ else
2713+ $$ = makeList1($3 );
2714+ else
2715+ $$ =$1 ;
2716+ }
2717+ | RuleActionStmtOrEmpty
2718+ {if ($1 != (Node *)NULL )
2719+ $$ = makeList1($1 );
2720+ else
2721+ $$ = NIL;
2722+ }
2723+ ;
2724+
2725+ RuleActionOrSelectMulti :RuleActionOrSelectMulti ' ;' RuleActionStmtOrEmpty
2726+ {if ($3 != (Node *)NULL )
2727+ if ($1 != NIL)
2728+ $$ = lappend($1 ,$3 );
2729+ else
2730+ $$ = makeList1($3 );
26872731else
26882732$$ =$1 ;
26892733}
2734+ | RuleActionOrSelectMulti ' ;' SelectStmt
2735+ {if ($1 != NIL)
2736+ $$ = lappend($1 ,$3 );
2737+ else
2738+ $$ = makeList1($3 );
2739+ }
26902740| RuleActionStmtOrEmpty
26912741{if ($1 != (Node *)NULL )
26922742$$ = makeList1($1 );
26932743else
26942744$$ = NIL;
26952745}
2746+ | SelectStmt {$$ = makeList1($1 ); }
26962747;
26972748
2749+
26982750RuleActionStmt :InsertStmt
26992751| UpdateStmt
27002752| DeleteStmt
@@ -3248,7 +3300,12 @@ opt_cursor: BINARY{ $$ = TRUE; }
32483300 * However, this is not checked by the grammar; parse analysis must check it.
32493301*/
32503302
3251- SelectStmt :select_clause sort_clause for_update_clause opt_select_limit
3303+ SelectStmt :QualifiedSelectStmt
3304+ | select_head
3305+ ;
3306+
3307+ QualifiedSelectStmt :
3308+ select_head sort_clause opt_for_update_clause opt_select_limit
32523309{
32533310SelectStmt *n = findLeftmostSelect($1 );
32543311
@@ -3258,34 +3315,35 @@ SelectStmt: select_clause sort_clause for_update_clause opt_select_limit
32583315n->limitCount = nth(1 ,$4 );
32593316$$ =$1 ;
32603317}
3261- ;
3262-
3263- /* This rule parses Select statements that can appear within set operations,
3264- * including UNION, INTERSECT and EXCEPT. '(' and ')' can be used to specify
3265- * the ordering of the set operations. Without '(' and ')' we want the
3266- * operations to be ordered per the precedence specs at the head of this file.
3267- *
3268- * Since parentheses around SELECTs also appear in the expression grammar,
3269- * there is a parse ambiguity if parentheses are allowed at the top level of a
3270- * select_clause: are the parens part of the expression or part of the select?
3271- * We separate select_clause into two levels to resolve this: select_clause
3272- * can have top-level parentheses, select_subclause cannot.
3273- *
3274- * Note that sort clauses cannot be included at this level --- a sort clause
3275- * can only appear at the end of the complete Select, and it will be handled
3276- * by the topmost SelectStmt rule. Likewise FOR UPDATE and LIMIT.
3277- */
3278- select_clause :' (' select_subclause ' )'
3318+ | select_head for_update_clause opt_select_limit
32793319{
3280- $$ =$2 ;
3320+ SelectStmt *n = findLeftmostSelect($1 );
3321+
3322+ n->sortClause =NULL ;
3323+ n->forUpdate =$2 ;
3324+ n->limitOffset = nth(0 ,$3 );
3325+ n->limitCount = nth(1 ,$3 );
3326+ $$ =$1 ;
32813327}
3282- | select_subclause
3328+ | select_head select_limit
32833329{
3284- $$ =$1 ;
3330+ SelectStmt *n = findLeftmostSelect($1 );
3331+
3332+ n->sortClause =NULL ;
3333+ n->forUpdate =NULL ;
3334+ n->limitOffset = nth(0 ,$2 );
3335+ n->limitCount = nth(1 ,$2 );
3336+ $$ =$1 ;
32853337}
32863338;
32873339
3288- select_subclause :SELECT opt_distinct target_list
3340+ subquery :' (' subquery ' )' {$$ =$2 ; }
3341+ | ' (' QualifiedSelectStmt ' )' {$$ =$2 ; }
3342+ | ' (' set_select ' )' {$$ =$2 ; }
3343+ | simple_select {$$ =$1 ; }
3344+ ;
3345+
3346+ simple_select :SELECT opt_distinct target_list
32893347result from_clause where_clause
32903348group_clause having_clause
32913349{
@@ -3300,7 +3358,13 @@ select_subclause: SELECT opt_distinct target_list
33003358n->havingClause =$8 ;
33013359$$ = (Node *)n;
33023360}
3303- | select_clause UNION opt_all select_clause
3361+ ;
3362+
3363+ select_head :simple_select {$$ =$1 ; }
3364+ | set_select {$$ =$1 ; }
3365+ ;
3366+
3367+ set_select :select_head UNION opt_all subquery
33043368{
33053369SetOperationStmt *n = makeNode(SetOperationStmt);
33063370n->op = SETOP_UNION;
@@ -3309,7 +3373,7 @@ select_subclause: SELECT opt_distinct target_list
33093373n->rarg =$4 ;
33103374$$ = (Node *) n;
33113375}
3312- | select_clause INTERSECT opt_all select_clause
3376+ | select_head INTERSECT opt_all subquery
33133377{
33143378SetOperationStmt *n = makeNode(SetOperationStmt);
33153379n->op = SETOP_INTERSECT;
@@ -3318,7 +3382,7 @@ select_subclause: SELECT opt_distinct target_list
33183382n->rarg =$4 ;
33193383$$ = (Node *) n;
33203384}
3321- | select_clause EXCEPT opt_all select_clause
3385+ | select_head EXCEPT opt_all subquery
33223386{
33233387SetOperationStmt *n = makeNode(SetOperationStmt);
33243388n->op = SETOP_EXCEPT;
@@ -3383,7 +3447,6 @@ opt_distinct: DISTINCT{ $$ = makeList1(NIL); }
33833447;
33843448
33853449sort_clause :ORDER BY sortby_list {$$ =$3 ; }
3386- | /* EMPTY*/ {$$ = NIL; }
33873450;
33883451
33893452sortby_list :sortby {$$ = makeList1($1 ); }
@@ -3405,7 +3468,7 @@ OptUseOp: USING all_Op{ $$ = $2; }
34053468;
34063469
34073470
3408- opt_select_limit :LIMIT select_limit_value ' ,' select_offset_value
3471+ select_limit :LIMIT select_limit_value ' ,' select_offset_value
34093472{$$ = makeList2($4 ,$2 ); }
34103473| LIMIT select_limit_value OFFSET select_offset_value
34113474{$$ = makeList2($4 ,$2 ); }
@@ -3415,6 +3478,9 @@ opt_select_limit:LIMIT select_limit_value ',' select_offset_value
34153478{$$ = makeList2($2 ,$4 ); }
34163479| OFFSET select_offset_value
34173480{$$ = makeList2($2 ,NULL ); }
3481+ ;
3482+
3483+ opt_select_limit :select_limit {$$ =$1 ; }
34183484| /* EMPTY*/
34193485{$$ = makeList2(NULL ,NULL ); }
34203486;
@@ -3514,6 +3580,9 @@ having_clause: HAVING a_expr
35143580
35153581for_update_clause :FOR UPDATE update_list {$$ =$3 ; }
35163582| FOR READ ONLY {$$ =NULL ; }
3583+ ;
3584+
3585+ opt_for_update_clause :for_update_clause {$$ =$1 ; }
35173586| /* EMPTY*/ {$$ =NULL ; }
35183587;
35193588
@@ -3557,7 +3626,7 @@ table_ref: relation_expr
35573626$1 ->name =$2 ;
35583627$$ = (Node *)$1 ;
35593628}
3560- | ' (' select_subclause ' )' alias_clause
3629+ | ' (' SelectStmt ' )' alias_clause
35613630{
35623631RangeSubselect *n = makeNode(RangeSubselect);
35633632n->subquery =$2 ;
@@ -4093,7 +4162,7 @@ opt_interval: datetime{ $$ = makeList1($1); }
40934162 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
40944163 * with singleton expressions.
40954164*/
4096- row_expr :' (' row_descriptor ' )' IN ' (' select_subclause ' )'
4165+ row_expr :' (' row_descriptor ' )' IN ' (' SelectStmt ' )'
40974166{
40984167SubLink *n = makeNode(SubLink);
40994168n->lefthand =$2 ;
@@ -4103,7 +4172,7 @@ row_expr: '(' row_descriptor ')' IN '(' select_subclause ')'
41034172n->subselect =$6 ;
41044173$$ = (Node *)n;
41054174}
4106- | ' (' row_descriptor ' )' NOT IN ' (' select_subclause ' )'
4175+ | ' (' row_descriptor ' )' NOT IN ' (' SelectStmt ' )'
41074176{
41084177SubLink *n = makeNode(SubLink);
41094178n->lefthand =$2 ;
@@ -4113,7 +4182,7 @@ row_expr: '(' row_descriptor ')' IN '(' select_subclause ')'
41134182n->subselect =$7 ;
41144183$$ = (Node *)n;
41154184}
4116- | ' (' row_descriptor ' )' all_Op sub_type ' (' select_subclause ' )'
4185+ | ' (' row_descriptor ' )' all_Op sub_type ' (' SelectStmt ' )'
41174186{
41184187SubLink *n = makeNode(SubLink);
41194188n->lefthand =$2 ;
@@ -4126,7 +4195,7 @@ row_expr: '(' row_descriptor ')' IN '(' select_subclause ')'
41264195n->subselect =$7 ;
41274196$$ = (Node *)n;
41284197}
4129- | ' (' row_descriptor ' )' all_Op ' (' select_subclause ' )'
4198+ | ' (' row_descriptor ' )' all_Op ' (' SelectStmt ' )'
41304199{
41314200SubLink *n = makeNode(SubLink);
41324201n->lefthand =$2 ;
@@ -4457,7 +4526,7 @@ a_expr: c_expr
44574526$$ = n;
44584527}
44594528}
4460- | a_expr all_Op sub_type ' (' select_subclause ' )'
4529+ | a_expr all_Op sub_type ' (' SelectStmt ' )'
44614530{
44624531SubLink *n = makeNode(SubLink);
44634532n->lefthand = makeList1($1 );
@@ -4853,7 +4922,7 @@ c_expr: attr
48534922n->agg_distinct =FALSE ;
48544923$$ = (Node *)n;
48554924}
4856- | ' (' select_subclause ' )'
4925+ | ' (' SelectStmt ' )'
48574926{
48584927SubLink *n = makeNode(SubLink);
48594928n->lefthand = NIL;
@@ -4863,7 +4932,7 @@ c_expr: attr
48634932n->subselect =$2 ;
48644933$$ = (Node *)n;
48654934}
4866- | EXISTS ' (' select_subclause ' )'
4935+ | EXISTS ' (' SelectStmt ' )'
48674936{
48684937SubLink *n = makeNode(SubLink);
48694938n->lefthand = NIL;
@@ -4962,7 +5031,7 @@ trim_list: a_expr FROM expr_list
49625031{$$ =$1 ; }
49635032;
49645033
4965- in_expr :select_subclause
5034+ in_expr :SelectStmt
49665035{
49675036SubLink *n = makeNode(SubLink);
49685037n->subselect =$1 ;