Skip to content

Commit a1cba4e

Browse files
committed
Hookup GROUP BY for SELECT
1 parent 77dcd39 commit a1cba4e

File tree

3 files changed

+88
-5
lines changed

3 files changed

+88
-5
lines changed

regress/expected/new_cypher.out

+5
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ SELECT a.* FROM tst as a;
163163
---
164164
(0 rows)
165165

166+
SELECT a.i as j FROM tst a GROUP BY a.i;
167+
j
168+
---
169+
(0 rows)
170+
166171
DROP GRAPH new_cypher CASCADE;
167172
NOTICE: drop cascades to 2 other objects
168173
DETAIL: drop cascades to table new_cypher._ag_label_vertex

regress/sql/new_cypher.sql

+4
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,9 @@ SELECT i FROM tst WHERE i > i;
8282
--SELECT a.j FROM tst a(j);
8383
SELECT a.* FROM tst as a;
8484

85+
86+
SELECT a.i as j FROM tst a GROUP BY a.i;
87+
88+
8589
DROP GRAPH new_cypher CASCADE;
8690
DROP GRAPH new_cypher_2 CASCADE;

src/backend/parser/cypher_gram.y

+79-5
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@
5151

5252
#define parser_yyerror(msg) scanner_yyerror(msg, yyscanner)
5353
#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+
5462
%}
5563

5664
%locations
@@ -82,6 +90,7 @@
8290
struct Value *value;
8391
struct ResTarget *target;
8492
struct Alias *alias;
93+
struct GroupClause *groupclause;
8594
}
8695

8796
%token <integer> INTEGER
@@ -136,12 +145,18 @@
136145
%type <node> where_clause
137146
a_expr b_expr c_expr indirection_el
138147
columnref
148+
149+
%type <integer> set_quantifier
139150
%type <target> target_el
140151
%type <node> table_ref
141152
%type <range> relation_expr
142153
%type <range> relation_expr_opt_alias
143154
%type <alias> alias_clause opt_alias_clause
144155
%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
145160

146161
/* RETURN and WITH clause */
147162
%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:
514529
simple_select:
515530
SELECT opt_all_clause opt_target_list
516531
//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
519534
{
520535
SelectStmt *n = makeNode(SelectStmt);
521536
/*n->targetList = $3;
@@ -529,9 +544,9 @@ simple_select:
529544
n->targetList = $3;
530545
n->intoClause = NULL;
531546
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;
535550
n->havingClause = NULL;
536551
n->windowClause = NULL;
537552
$$ = (Node *)n;
@@ -1176,6 +1191,48 @@ having_opt:
11761191
}
11771192
;
11781193

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+
;
11791236

11801237
group_by_opt:
11811238
/* empty */
@@ -1187,7 +1244,24 @@ group_by_opt:
11871244
$$ = $3;
11881245
}
11891246
;
1247+
group_by_list:
1248+
group_by_item { $$ = list_make1($1); }
1249+
| group_by_list ',' group_by_item { $$ = lappend($1,$3); }
1250+
;
11901251

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+
;
11911265
group_item_list:
11921266
group_item { $$ = list_make1($1); }
11931267
| group_item_list ',' group_item { $$ = lappend($1, $3); }

0 commit comments

Comments
 (0)