searching bison guru - grouping sets implementation
Hello
I trying to implement GROUPING SETS feature. But there is basic
difference between PostgreSQL and ANSI. Pg allows expressions, ANSI
only column reference. I have syntax:
group_clause:
GROUP_P BY grouping_element_list
| /*EMPTY*/
;
grouping_element_list:
grouping_element
{
$$ = list_make1($1);
}
| grouping_element_list ',' grouping_element
{
$$ = lappend($1, $3);
}
;
grouping_element:
ordinary_grouping_set
{
}
| ROLLUP '(' ordinary_grouping_set_list ')'
{
}
| CUBE '(' ordinary_grouping_set_list ')'
{
}
| GROUPING SETS '(' grouping_element_list ')'
{
}
| '(' ')'
{
}
;
ordinary_grouping_set:
grouping_column_ref
{
}
| '(' grouping_ref_list ')'
{
}
;
grouping_ref_list:
grouping_column_ref
{
}
| grouping_ref_list ',' grouping_column_ref
{
}
;
ordinary_grouping_set_list:
ordinary_grouping_set
{
}
| ordinary_grouping_set_list ',' ordinary_grouping_set
{
}
;
grouping_column_ref:
columnref
{}
| Iconst
{}
;
;
this works well, but it is ANSI compliant not pg compliant
after change:
grouping_column_ref:
a_expr
{}
;
I getting
[pavel@localhost parser]$ bison gram.y
gram.y: conflicts: 1 shift/reduce, 1 reduce/reduce
so I cannot find any way to remove shift/reduce.
any ideas?
Attachments:
groupingsets.difftext/x-patch; name=groupingsets.diffDownload
*** ./gram.y.orig 2008-08-05 10:06:05.000000000 +0200
--- ./gram.y 2008-08-05 14:15:16.000000000 +0200
***************
*** 362,367 ****
--- 362,372 ----
%type <node> xml_root_version opt_xml_root_standalone
%type <ival> document_or_content
%type <boolean> xml_whitespace_option
+ %type <list> grouping_element_list
+ %type <node> grouping_element
+ %type <list> grouping_ref_list
+ %type <list> ordinary_grouping_set ordinary_grouping_set_list
+ %type <node> grouping_column_ref
/*
***************
*** 384,390 ****
CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
! CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
--- 389,395 ----
CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
! CREATEROLE CREATEUSER CROSS CSV CUBE CURRENT_P CURRENT_DATE CURRENT_ROLE
CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
***************
*** 397,403 ****
FALSE_P FAMILY FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD
FREEZE FROM FULL FUNCTION
! GLOBAL GRANT GRANTED GREATEST GROUP_P
HANDLER HAVING HEADER_P HOLD HOUR_P
--- 402,408 ----
FALSE_P FAMILY FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD
FREEZE FROM FULL FUNCTION
! GLOBAL GRANT GRANTED GREATEST GROUP_P GROUPING
HANDLER HAVING HEADER_P HOLD HOUR_P
***************
*** 431,440 ****
READ REAL REASSIGN RECHECK REFERENCES REINDEX RELATIVE_P RELEASE RENAME
REPEATABLE REPLACE REPLICA RESET RESTART RESTRICT RETURNING RETURNS REVOKE
! RIGHT ROLE ROLLBACK ROW ROWS RULE
SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE
! SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT
STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SUPERUSER_P
SYMMETRIC SYSID SYSTEM_P
--- 436,445 ----
READ REAL REASSIGN RECHECK REFERENCES REINDEX RELATIVE_P RELEASE RENAME
REPEATABLE REPLACE REPLICA RESET RESTART RESTRICT RETURNING RETURNS REVOKE
! RIGHT ROLE ROLLBACK ROLLUP ROW ROWS RULE
SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE
! SERIALIZABLE SESSION SESSION_USER SET SETOF SETS SHARE
SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT
STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SUPERUSER_P
SYMMETRIC SYSID SYSTEM_P
***************
*** 6470,6479 ****
;
group_clause:
! GROUP_P BY expr_list { $$ = $3; }
| /*EMPTY*/ { $$ = NIL; }
;
having_clause:
HAVING a_expr { $$ = $2; }
| /*EMPTY*/ { $$ = NULL; }
--- 6475,6547 ----
;
group_clause:
! GROUP_P BY grouping_element_list { $$ = NIL; }
| /*EMPTY*/ { $$ = NIL; }
;
+ grouping_element_list:
+ grouping_element
+ {
+ $$ = list_make1($1);
+ }
+ | grouping_element_list ',' grouping_element
+ {
+ $$ = lappend($1, $3);
+ }
+ ;
+
+ grouping_element:
+ ordinary_grouping_set
+ {
+ }
+ | ROLLUP '(' ordinary_grouping_set_list ')'
+ {
+ }
+ | CUBE '(' ordinary_grouping_set_list ')'
+ {
+ }
+ | GROUPING SETS '(' grouping_element_list ')'
+ {
+ }
+ | '(' ')'
+ {
+ }
+ ;
+
+
+ ordinary_grouping_set:
+ grouping_column_ref
+ {
+ }
+ | '(' grouping_ref_list ')'
+ {
+ }
+ ;
+
+ grouping_ref_list:
+ grouping_column_ref
+ {
+ }
+ | grouping_ref_list ',' grouping_column_ref
+ {
+ }
+ ;
+
+ ordinary_grouping_set_list:
+ ordinary_grouping_set
+ {
+ }
+ | ordinary_grouping_set_list ',' ordinary_grouping_set
+ {
+ }
+ ;
+
+ grouping_column_ref:
+ a_expr
+ {}
+ ;
+
+
having_clause:
HAVING a_expr { $$ = $2; }
| /*EMPTY*/ { $$ = NULL; }
***************
*** 9228,9233 ****
--- 9296,9302 ----
| SERIALIZABLE
| SESSION
| SET
+ | SETS
| SHARE
| SHOW
| SIMPLE
***************
*** 9394,9399 ****
--- 9463,9469 ----
| COLUMN
| CONSTRAINT
| CREATE
+ | CUBE
| CURRENT_DATE
| CURRENT_ROLE
| CURRENT_TIME
***************
*** 9413,9418 ****
--- 9483,9489 ----
| FROM
| GRANT
| GROUP_P
+ | GROUPING
| HAVING
| IN_P
| INITIALLY
***************
*** 9436,9441 ****
--- 9507,9513 ----
| PRIMARY
| REFERENCES
| RETURNING
+ | ROLLUP
| SELECT
| SESSION_USER
| SOME
*** ./keywords.c.orig 2008-08-05 10:06:10.000000000 +0200
--- ./keywords.c 2008-08-05 10:15:40.000000000 +0200
***************
*** 114,119 ****
--- 114,120 ----
{"createuser", CREATEUSER, UNRESERVED_KEYWORD},
{"cross", CROSS, TYPE_FUNC_NAME_KEYWORD},
{"csv", CSV, UNRESERVED_KEYWORD},
+ {"cube", CUBE, RESERVED_KEYWORD},
{"current", CURRENT_P, UNRESERVED_KEYWORD},
{"current_date", CURRENT_DATE, RESERVED_KEYWORD},
{"current_role", CURRENT_ROLE, RESERVED_KEYWORD},
***************
*** 180,185 ****
--- 181,187 ----
{"granted", GRANTED, UNRESERVED_KEYWORD},
{"greatest", GREATEST, COL_NAME_KEYWORD},
{"group", GROUP_P, RESERVED_KEYWORD},
+ {"grouping", GROUPING, RESERVED_KEYWORD},
{"handler", HANDLER, UNRESERVED_KEYWORD},
{"having", HAVING, RESERVED_KEYWORD},
{"header", HEADER_P, UNRESERVED_KEYWORD},
***************
*** 321,326 ****
--- 323,329 ----
{"right", RIGHT, TYPE_FUNC_NAME_KEYWORD},
{"role", ROLE, UNRESERVED_KEYWORD},
{"rollback", ROLLBACK, UNRESERVED_KEYWORD},
+ {"rollup", ROLLUP, RESERVED_KEYWORD},
{"row", ROW, COL_NAME_KEYWORD},
{"rows", ROWS, UNRESERVED_KEYWORD},
{"rule", RULE, UNRESERVED_KEYWORD},
***************
*** 337,342 ****
--- 340,346 ----
{"session_user", SESSION_USER, RESERVED_KEYWORD},
{"set", SET, UNRESERVED_KEYWORD},
{"setof", SETOF, COL_NAME_KEYWORD},
+ {"sets", SETS, UNRESERVED_KEYWORD},
{"share", SHARE, UNRESERVED_KEYWORD},
{"show", SHOW, UNRESERVED_KEYWORD},
{"similar", SIMILAR, TYPE_FUNC_NAME_KEYWORD},
Pavel Stehule wrote:
I trying to implement GROUPING SETS feature. But there is basic
difference between PostgreSQL and ANSI. Pg allows expressions, ANSI
only column reference.
The conflict seems to arise from the parenthesis, between these two rules:
ordinary_grouping_set:
grouping_column_ref
{
}
*** | '(' grouping_ref_list ')'
{
}
;
and
grouping_column_ref:
a_expr
{}
;
where a_expr can be something like "(foobar)" as well, enclosed in
parenthesis. The grammar is ambiguous for something like
"SELECT ... GROUP BY (foobar)", bison doesn't know if that should be
interpreted as an "'(' grouping_ref_list ')'", whatever that is, or an
a_expr.
I don't know how that should be resolved, or if it's a genuine ambiguity
in the ANSI and PostgreSQL syntax or something that can be fixed with
some Bison magic.
--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com
"Heikki Linnakangas" <heikki@enterprisedb.com> writes:
I don't know how that should be resolved, or if it's a genuine ambiguity in the
ANSI and PostgreSQL syntax or something that can be fixed with some Bison
magic.
Fwiw I looked into this once already and noted the same conflict:
http://article.gmane.org/gmane.comp.db.postgresql.devel.general/83563/match=rollup
Tom pointed out that there's more than one way to skin a cat:
http://thread.gmane.org/gmane.comp.db.postgresql.devel.cvs/22326/focus=83563
(Oh look at that, he actually used precisely that phrase)
--
Gregory Stark
EnterpriseDB http://www.enterprisedb.com
Get trained by Bruce Momjian - ask me about EnterpriseDB's PostgreSQL training!
[Oops sorry -- I used the wrong links for the previous message. Here are the
correct links]
"Heikki Linnakangas" <heikki@enterprisedb.com> writes:
I don't know how that should be resolved, or if it's a genuine ambiguity in the
ANSI and PostgreSQL syntax or something that can be fixed with some Bison
magic.
Fwiw I looked into this once already and noted the same conflict:
http://article.gmane.org/gmane.comp.db.postgresql.devel.general/83564
Tom pointed out that there's more than one way to skin a cat:
http://article.gmane.org/gmane.comp.db.postgresql.devel.general/83578
(Oh look at that, he actually used precisely that phrase)
--
Gregory Stark
EnterpriseDB http://www.enterprisedb.com
Get trained by Bruce Momjian - ask me about EnterpriseDB's PostgreSQL training!