"Gregory Stark" <[EMAIL PROTECTED]> writes:

> "Tom Lane" <[EMAIL PROTECTED]> writes:
>
>> For the moment, lie about WITH's status in the table so it will still get
>> quoted --- this is because of the expectation that WITH will become reserved
>> when the SQL recursive-queries patch gets done.
>
> Out of curiosity I'm checking what consequences some other future grammer
> changes might have for us.

And checking OLAP window functions it at first glance at least it seems we
would have to make ROWS, WINDOW, RANGE, and PARTITION reserved keywords.

Again, I just sucked in the spec's grammar and fixed it up to fit in our
grammar. I did make PARTITION BY and ORDER BY take arbitrary expressions as is
our general approach.

It's possible there may be clever ways around these conflicts, in particular
it seems like it might be possible to make PARTITION not a keyword given the
nearby BY. However it appears in parentheses which looks like it makes things
a bit tricky.

Here's the relevant grammar snippet, and I attached the diff for gram.y to
parse both window clause and rollup/cube/grouping sets.

window_clause: 
        WINDOW window_definition_list
        | /* EMPTY */
        ;

window_definition_list:
        window_definition
        | window_definition ',' window_definition
        ;

window_definition: 
        ColId AS window_specification
        ;

window_specification:
        '(' window_specification_details ')'
        ;

window_specification_details:
        opt_window_name
        window_partition_clause
        window_order_clause
        window_frame_clause
        ;

opt_window_name: 
        ColId 
        | /*EMPTY*/ ;
        ;

window_partition_clause:
        PARTITION BY expr_list
        | /* EMPTY */
        ;

window_order_clause:
        ORDER BY sortby_list
        | /* EMPTY */
        ;

window_frame_clause:
        window_frame_units window_frame_extent opt_window_frame_exclusion
        | /* EMPTY */
        ;

window_frame_units:
        ROWS
        | RANGE
        ;

window_frame_extent:
        window_frame_start
        | window_frame_between
        ;

window_frame_start:
        UNBOUNDED PRECEDING
        | window_frame_preceding
        | CURRENT_P ROW
        ;

window_frame_preceding: 
        Iconst PRECEDING
        ;

window_frame_between: BETWEEN window_frame_bound AND window_frame_bound
        ;

window_frame_bound:
        window_frame_start
        | UNBOUNDED FOLLOWING
        | window_frame_following
        ;

window_frame_following: 
        Iconst FOLLOWING
        ;

opt_window_frame_exclusion:
        /*EMPTY*/
        | EXCLUDE CURRENT_P ROW
        | EXCLUDE GROUP_P
        | EXCLUDE TIES
        | EXCLUDE NO OTHERS
        ;

Index: gram.y
===================================================================
RCS file: /home/stark/src/REPOSITORY/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.596
diff -u -r2.596 gram.y
--- gram.y	23 Jun 2007 22:12:51 -0000	2.596
+++ gram.y	26 Jun 2007 13:38:25 -0000
@@ -248,7 +248,7 @@
 				TableFuncElementList opt_type_modifiers
 				prep_type_clause
 				execute_param_clause using_clause returning_clause
-				enum_val_list
+				enum_val_list 
 
 %type <range>	OptTempTableName
 %type <into>	into_clause create_as_target
@@ -298,7 +298,7 @@
 %type <defelt>	def_elem old_aggr_elem
 %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
+				columnref in_expr having_clause func_table array_expr 
 %type <list>	row type_list array_expr_list
 %type <node>	case_expr case_arg when_clause case_default
 %type <list>	when_clause_list
@@ -451,6 +451,10 @@
 
 	ZONE
 
+	CUBE ROLLUP GROUPING SETS
+
+    PRECEDING WINDOW FOLLOWING RANGE OTHERS UNBOUNDED TIES PARTITION EXCLUDE
+
 /* The grammar thinks these are keywords, but they are not in the keywords.c
  * list and so can never be entered directly.  The filter in parser.c
  * creates these tokens when required.
@@ -5989,7 +5993,7 @@
 simple_select:
 			SELECT opt_distinct target_list
 			into_clause from_clause where_clause
-			group_clause having_clause
+			group_clause having_clause window_clause
 				{
 					SelectStmt *n = makeNode(SelectStmt);
 					n->distinctClause = $2;
@@ -6169,16 +6173,149 @@
 			a_expr									{ $$ = $1; }
 		;
 
+opt_group_set_clause:
+			DISTINCT
+			| ALL
+			| /*EMPTY*/
+		;
+
 group_clause:
-			GROUP_P BY expr_list					{ $$ = $3; }
+			GROUP_P BY opt_group_set_clause grouping_element_list { $$ = NIL; }
 			| /*EMPTY*/								{ $$ = NIL; }
 		;
 
+grouping_element_list:
+	grouping_element
+	| grouping_element_list ',' grouping_element
+	;
+
+grouping_element:
+	a_expr
+	| rollup_list
+	| cube_list
+	| grouping_sets_specification
+	| empty_grouping_set
+	;
+
+rollup_list:
+	ROLLUP '(' expr_list ')'
+	;
+
+cube_list:
+	CUBE '(' expr_list ')'
+	;
+
+grouping_sets_specification:
+	GROUPING SETS '(' grouping_set_list ')'
+	;
+
+grouping_set_list:
+	grouping_set
+	| grouping_set_list ',' grouping_set
+	;
+
+grouping_set:
+	a_expr
+	| rollup_list
+	| cube_list
+	| grouping_sets_specification
+	| empty_grouping_set
+	;
+
+empty_grouping_set: '(' ')'
+	;
+
 having_clause:
 			HAVING a_expr							{ $$ = $2; }
 			| /*EMPTY*/								{ $$ = NULL; }
 		;
 
+window_clause: 
+	WINDOW window_definition_list
+	| /* EMPTY */
+	;
+
+window_definition_list:
+	window_definition
+	| window_definition ',' window_definition
+	;
+
+window_definition: 
+	ColId AS window_specification
+	;
+
+window_specification:
+	'(' window_specification_details ')'
+	;
+
+window_specification_details:
+	opt_window_name
+	window_partition_clause
+	window_order_clause
+	window_frame_clause
+	;
+
+opt_window_name: 
+	ColId 
+	| /*EMPTY*/ ;
+	;
+
+window_partition_clause:
+	PARTITION BY expr_list
+	| /* EMPTY */
+	;
+
+window_order_clause:
+	ORDER BY sortby_list
+	| /* EMPTY */
+	;
+
+window_frame_clause:
+	window_frame_units window_frame_extent opt_window_frame_exclusion
+	| /* EMPTY */
+	;
+
+window_frame_units:
+	ROWS
+	| RANGE
+	;
+
+window_frame_extent:
+	window_frame_start
+	| window_frame_between
+	;
+
+window_frame_start:
+	UNBOUNDED PRECEDING
+	| window_frame_preceding
+	| CURRENT_P ROW
+	;
+
+window_frame_preceding: 
+	Iconst PRECEDING
+	;
+
+window_frame_between: BETWEEN window_frame_bound AND window_frame_bound
+	;
+
+window_frame_bound:
+	window_frame_start
+	| UNBOUNDED FOLLOWING
+	| window_frame_following
+	;
+
+window_frame_following: 
+	Iconst FOLLOWING
+	;
+
+opt_window_frame_exclusion:
+	/*EMPTY*/
+	| EXCLUDE CURRENT_P ROW
+	| EXCLUDE GROUP_P
+	| EXCLUDE TIES
+	| EXCLUDE NO OTHERS
+	;
+
 for_locking_clause:
 			for_locking_items						{ $$ = $1; }
 			| FOR READ ONLY							{ $$ = NIL; }
@@ -8971,7 +9108,6 @@
 			| REVOKE
 			| ROLE
 			| ROLLBACK
-			| ROWS
 			| RULE
 			| SAVEPOINT
 			| SCHEMA
@@ -9030,6 +9166,14 @@
 			| YEAR_P
 			| YES_P
 			| ZONE
+	| GROUPING
+	| SETS
+    | PRECEDING
+	| FOLLOWING
+	| OTHERS
+	| UNBOUNDED
+	| TIES
+	| EXCLUDE
 		;
 
 /* Column identifier --- keywords that can be column, table, etc names.
@@ -9089,6 +9233,8 @@
 			| XMLPI
 			| XMLROOT
 			| XMLSERIALIZE
+	| CUBE
+	| ROLLUP
 		;
 
 /* Type/function identifier --- keywords that can be type or function names.
@@ -9205,6 +9351,10 @@
 			| USING
 			| WHEN
 			| WHERE
+	| ROWS
+	| WINDOW
+	| RANGE
+	| PARTITION
 		;
 
 
-- 
  Gregory Stark
  EnterpriseDB          http://www.enterprisedb.com
---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?

               http://www.postgresql.org/docs/faq

Reply via email to