268 lines
6.0 KiB
OCaml
268 lines
6.0 KiB
OCaml
%{
|
|
(* Header: Define the AST type *)
|
|
open Ast
|
|
%}
|
|
|
|
%token SELECT ALL DISTINCT FROM WHERE HAVING BETWEEN
|
|
%token LEFT RIGHT FULL INNER OUTER
|
|
%token CROSS NATURAL UNION JOIN
|
|
%token GREATER_THAN_OPERATOR LESS_THAN_OPERATOR EQUALS_OPERATOR
|
|
%token MAX MIN SUM COUNT AVG
|
|
%token ASYMMETRIC SYMMETRIC
|
|
%token <string> IDENT
|
|
%token COMMA DOT
|
|
%token LEFT_PAREN RIGHT_PAREN
|
|
%token ASTERISK
|
|
%token AS ON GROUP BY FILTER
|
|
%token OR AND NOT
|
|
%token EOF
|
|
%start main
|
|
%type <query> main
|
|
|
|
%%
|
|
|
|
main:
|
|
| select_stmt EOF { Query($1) }
|
|
|
|
select_stmt :
|
|
| SELECT select_list table_expression { Select($2, $3) }
|
|
| SELECT set_quantifier select_list table_expression { Select($3, $4) }
|
|
|
|
set_quantifier :
|
|
| ALL {}
|
|
| DISTINCT {}
|
|
|
|
select_list :
|
|
| ASTERISK { [Asterisk] }
|
|
| select_sublist {$1}
|
|
|
|
select_sublist :
|
|
| IDENT { [Column($1)] }
|
|
| select_sublist COMMA IDENT { Column($3)::$1 }
|
|
|
|
derived_column:
|
|
| value_expression {}
|
|
| value_expression as_clause {}
|
|
|
|
as_clause :
|
|
| AS column_name {}
|
|
| column_name {}
|
|
|
|
column_name :
|
|
| IDENT {}
|
|
|
|
value_expression:
|
|
| common_value_expression {}
|
|
|
|
common_value_expression:
|
|
| reference_value_expression {}
|
|
|
|
reference_value_expression:
|
|
| value_expression_primary {}
|
|
|
|
value_expression_primary:
|
|
| parenthesized_value_expression {}
|
|
| nonparenthesized_value_expression_primary {}
|
|
|
|
parenthesized_value_expression:
|
|
| LEFT_PAREN value_expression RIGHT_PAREN {}
|
|
|
|
table_expression:
|
|
| from_clause { $1 }
|
|
| from_clause where_clause { $1 }
|
|
|
|
from_clause :
|
|
| FROM table_reference_list { $2 }
|
|
|
|
table_reference_list :
|
|
| table_reference { [$1] }
|
|
| table_reference_list COMMA table_reference { $3::$1 }
|
|
|
|
table_reference :
|
|
| table_primary_or_joined_table { $1 }
|
|
(* | table_primary_or_joined_table sample_clause { $1 } *)
|
|
|
|
table_primary_or_joined_table:
|
|
| table_primary { $1 }
|
|
| joined_table { $1 }
|
|
|
|
table_primary :
|
|
| table_or_query_name { $1 }
|
|
|
|
table_or_query_name:
|
|
| table_name { $1 }
|
|
|
|
joined_table :
|
|
| cross_join { $1 }
|
|
| qualified_join { $1 }
|
|
| natural_join { $1 }
|
|
| union_join { $1 }
|
|
|
|
cross_join:
|
|
| table_reference CROSS JOIN table_primary { Join($1, Cross, $4, None) }
|
|
|
|
qualified_join:
|
|
| table_reference JOIN table_reference join_specification { Join($1, Left, $3, $4) }
|
|
| table_reference join_type JOIN table_reference join_specification { Join($1, $2, $4, $5) }
|
|
|
|
join_specification:
|
|
| join_condition { $1 }
|
|
|
|
join_condition:
|
|
| ON search_condition { Some($2) }
|
|
|
|
natural_join:
|
|
| table_reference NATURAL JOIN table_primary { Join($1, Natural, $4, None) }
|
|
| table_reference NATURAL join_type JOIN table_primary { Join($1, Natural, $5, None) }
|
|
|
|
union_join:
|
|
| table_reference UNION JOIN table_primary { Join($1, Union, $4, None) }
|
|
|
|
table_name :
|
|
| IDENT { Table($1) }
|
|
|
|
join_type:
|
|
| INNER { Inner }
|
|
| outer_join_type { $1 }
|
|
| outer_join_type OUTER { $1 }
|
|
|
|
outer_join_type:
|
|
| LEFT { Left }
|
|
| RIGHT { Right }
|
|
| FULL { Full }
|
|
|
|
where_clause :
|
|
| WHERE search_condition { }
|
|
|
|
having_clause :
|
|
| HAVING search_condition {}
|
|
|
|
search_condition:
|
|
(*| IDENT EQUALS_OPERATOR IDENT {}*)
|
|
| boolean_value_expression { $1 }
|
|
|
|
boolean_value_expression:
|
|
| boolean_term { $1 }
|
|
| boolean_value_expression OR boolean_term { Or($1, $3) }
|
|
|
|
boolean_term:
|
|
| boolean_factor { $1 }
|
|
| boolean_term AND boolean_factor { And($1, $3) }
|
|
|
|
boolean_factor:
|
|
| boolean_test { $1 }
|
|
| NOT boolean_test { Not($2) }
|
|
|
|
boolean_test:
|
|
| boolean_primary { $1 }
|
|
|
|
boolean_primary :
|
|
| predicate { $1 }
|
|
(*| boolean_predicand {}*)
|
|
|
|
predicate :
|
|
| comparison_predicate { $1 }
|
|
(* | between_predicate { $1 }*)
|
|
|
|
comparison_predicate :
|
|
| row_value_predicand comparison_predicate_part2 { Condition($1, $2) }
|
|
|
|
comparison_predicate_part2:
|
|
| comp_op row_value_predicand { Comparison($1, $2) }
|
|
|
|
between_predicate :
|
|
| row_value_predicand between_predicate_part2 { }
|
|
|
|
between_predicate_part2 :
|
|
| BETWEEN between_symetry row_value_predicand AND row_value_predicand {}
|
|
| NOT BETWEEN between_symetry row_value_predicand AND row_value_predicand {}
|
|
|
|
between_symetry :
|
|
| {}
|
|
| ASYMMETRIC {}
|
|
| SYMMETRIC {}
|
|
|
|
comp_op :
|
|
| EQUALS_OPERATOR { Equals }
|
|
| not_equals_operator { NotEquals }
|
|
| LESS_THAN_OPERATOR { LessThan }
|
|
| GREATER_THAN_OPERATOR { GreaterThan }
|
|
| less_than_or_equals_operator { LessEquals }
|
|
| greater_than_or_equals_operator { GreaterEquals }
|
|
|
|
not_equals_operator :
|
|
| LESS_THAN_OPERATOR GREATER_THAN_OPERATOR {}
|
|
|
|
less_than_or_equals_operator:
|
|
| LESS_THAN_OPERATOR EQUALS_OPERATOR {}
|
|
|
|
greater_than_or_equals_operator:
|
|
| GREATER_THAN_OPERATOR EQUALS_OPERATOR {}
|
|
|
|
row_value_predicand:
|
|
| row_value_special_case { $1 }
|
|
|
|
row_value_special_case :
|
|
| nonparenthesized_value_expression_primary { $1 }
|
|
|
|
nonparenthesized_value_expression_primary:
|
|
| column_reference { $1 }
|
|
(* | set_function_specification { $1 }*)
|
|
|
|
set_function_specification:
|
|
| aggregate_function { $1 }
|
|
|
|
aggregate_function:
|
|
| COUNT LEFT_PAREN ASTERISK RIGHT_PAREN { Asterisk }
|
|
| COUNT LEFT_PAREN ASTERISK RIGHT_PAREN filter_clause { Asterisk }
|
|
| general_set_function { $1 }
|
|
| general_set_function filter_clause { $1 }
|
|
|
|
general_set_function:
|
|
| set_function_type LEFT_PAREN value_expression RIGHT_PAREN { $3 }
|
|
| set_function_type LEFT_PAREN set_quantifier value_expression RIGHT_PAREN { $4 }
|
|
|
|
set_function_type:
|
|
| computationnal_operation {}
|
|
|
|
computationnal_operation:
|
|
| AVG {}
|
|
| MAX {}
|
|
| MIN {}
|
|
| SUM {}
|
|
| COUNT {}
|
|
|
|
filter_clause :
|
|
| FILTER LEFT_PAREN WHERE search_condition RIGHT_PAREN {}
|
|
|
|
column_reference:
|
|
| basic_identifier_chain { $1 }
|
|
|
|
basic_identifier_chain:
|
|
| identifier_chain { $1 }
|
|
|
|
identifier_chain:
|
|
| IDENT { $1 }
|
|
(*| identifier_chain DOT IDENT {}*)
|
|
|
|
boolean_predicand:
|
|
| nonparenthesized_value_expression_primary {}
|
|
|
|
group_by_clause:
|
|
| GROUP BY grouping_element_list {}
|
|
| GROUP BY set_quantifier grouping_element_list {}
|
|
|
|
grouping_element_list :
|
|
| grouping_element {}
|
|
| grouping_element_list COMMA grouping_element_list {}
|
|
|
|
grouping_element:
|
|
| ordinary_grouping_set {}
|
|
|
|
ordinary_grouping_set :
|
|
| grouping_column_reference {}
|
|
|
|
grouping_column_reference:
|
|
| column_reference {}
|
|
(*| column_reference collate_clause {}*)
|