51
51
52
52
#define parser_yyerror (msg ) scanner_yyerror(msg, yyscanner)
53
53
#define parser_errposition (pos ) scanner_errposition(pos, yyscanner)
54
+
55
+ /* Private struct for the result of group_clause production */
56
+ typedef struct GroupClause
57
+ {
58
+ bool distinct;
59
+ List *list;
60
+ } GroupClause;
61
+
54
62
%}
55
63
56
64
%locations
82
90
struct Value *value;
83
91
struct ResTarget *target;
84
92
struct Alias *alias;
93
+ struct GroupClause *groupclause;
85
94
}
86
95
87
96
%token <integer> INTEGER
136
145
%type <node> where_clause
137
146
a_expr b_expr c_expr indirection_el
138
147
columnref
148
+
149
+ %type <integer> set_quantifier
139
150
%type <target> target_el
140
151
%type <node> table_ref
141
152
%type <range> relation_expr
142
153
%type <range> relation_expr_opt_alias
143
154
%type <alias> alias_clause opt_alias_clause
144
155
%type <node> clause
156
+ %type <groupclause> group_clause
157
+ %type <list> group_by_list
158
+ %type <node> group_by_item
159
+ %type <node> grouping_sets_clause
145
160
146
161
/* RETURN and WITH clause */
147
162
%type <node> empty_grouping_set cube_clause rollup_clause group_item having_opt return return_item sort_item skip_opt limit_opt with
@@ -514,8 +529,8 @@ select_clause:
514
529
simple_select :
515
530
SELECT opt_all_clause opt_target_list
516
531
//into_clause
517
- from_clause where_clause
518
- // group_clause having_clause window_clause
532
+ from_clause where_clause group_clause
533
+ group_clause // having_clause window_clause
519
534
{
520
535
SelectStmt *n = makeNode(SelectStmt);
521
536
/* n->targetList = $3;
@@ -529,9 +544,9 @@ simple_select:
529
544
n->targetList = $3 ;
530
545
n->intoClause = NULL ;
531
546
n->fromClause = $4 ;
532
- n->whereClause = NULL ;
533
- n->groupClause = NULL ;
534
- n->groupDistinct = NULL ;
547
+ n->whereClause = $5 ;
548
+ n->groupClause = ( $6 )->list ;
549
+ n->groupDistinct = ( $6 )->distinct ;
535
550
n->havingClause = NULL ;
536
551
n->windowClause = NULL ;
537
552
$$ = (Node *)n;
@@ -1176,6 +1191,48 @@ having_opt:
1176
1191
}
1177
1192
;
1178
1193
1194
+ /*
1195
+ * This syntax for group_clause tries to follow the spec quite closely.
1196
+ * However, the spec allows only column references, not expressions,
1197
+ * which introduces an ambiguity between implicit row constructors
1198
+ * (a,b) and lists of column references.
1199
+ *
1200
+ * We handle this by using the a_expr production for what the spec calls
1201
+ * <ordinary grouping set>, which in the spec represents either one column
1202
+ * reference or a parenthesized list of column references. Then, we check the
1203
+ * top node of the a_expr to see if it's an implicit RowExpr, and if so, just
1204
+ * grab and use the list, discarding the node. (this is done in parse analysis,
1205
+ * not here)
1206
+ *
1207
+ * (we abuse the row_format field of RowExpr to distinguish implicit and
1208
+ * explicit row constructors; it's debatable if anyone sanely wants to use them
1209
+ * in a group clause, but if they have a reason to, we make it possible.)
1210
+ *
1211
+ * Each item in the group_clause list is either an expression tree or a
1212
+ * GroupingSet node of some type.
1213
+ */
1214
+ group_clause :
1215
+ GROUP BY set_quantifier group_by_list
1216
+ {
1217
+ GroupClause *n = (GroupClause *) palloc(sizeof (GroupClause));
1218
+ n->distinct = $3 == SET_QUANTIFIER_DISTINCT;
1219
+ n->list = $4 ;
1220
+ $$ = n;
1221
+ }
1222
+ | /* EMPTY*/
1223
+ {
1224
+ GroupClause *n = (GroupClause *) palloc(sizeof (GroupClause));
1225
+ n->distinct = false ;
1226
+ n->list = NIL;
1227
+ $$ = n;
1228
+ }
1229
+ ;
1230
+
1231
+ set_quantifier :
1232
+ ALL { $$ = SET_QUANTIFIER_ALL; }
1233
+ | DISTINCT { $$ = SET_QUANTIFIER_DISTINCT; }
1234
+ | /* EMPTY*/ { $$ = SET_QUANTIFIER_DEFAULT; }
1235
+ ;
1179
1236
1180
1237
group_by_opt :
1181
1238
/* empty */
@@ -1187,7 +1244,24 @@ group_by_opt:
1187
1244
$$ = $3 ;
1188
1245
}
1189
1246
;
1247
+ group_by_list :
1248
+ group_by_item { $$ = list_make1($1 ); }
1249
+ | group_by_list ' ,' group_by_item { $$ = lappend($1 ,$3 ); }
1250
+ ;
1190
1251
1252
+ group_by_item :
1253
+ a_expr { $$ = $1 ; }
1254
+ | empty_grouping_set { $$ = $1 ; }
1255
+ | cube_clause { $$ = $1 ; }
1256
+ | rollup_clause { $$ = $1 ; }
1257
+ | grouping_sets_clause { $$ = $1 ; }
1258
+ ;
1259
+ grouping_sets_clause :
1260
+ GROUPING SETS ' (' group_by_list ' )'
1261
+ {
1262
+ $$ = (Node *) makeGroupingSet(GROUPING_SET_SETS, $4 , @1 );
1263
+ }
1264
+ ;
1191
1265
group_item_list :
1192
1266
group_item { $$ = list_make1($1 ); }
1193
1267
| group_item_list ' ,' group_item { $$ = lappend($1 , $3 ); }
0 commit comments