Compare commits
12 Commits
f45d157b81
...
731456990e
Author | SHA1 | Date | |
---|---|---|---|
731456990e | |||
5745358dbf | |||
bbc0e26dd5 | |||
869bd2f4ef | |||
92f8331bda | |||
9de86673dc | |||
d4e2f7eb07 | |||
ae9b0b5b79 | |||
8d2d099974 | |||
dc1ea6642f | |||
2e00eb4e86 | |||
aa4028fcf0 |
@ -1,4 +1,4 @@
|
||||
# OCAML SQL PARSER
|
||||
|
||||
using [this grammar](https://ronsavage.github.io/SQL/sql-2003-2.bnf.html)
|
||||
resource on iceberg table format [here](https://www.dremio.com/resources/guides/apache-iceberg-an-architectural-look-under-the-covers/?utm_campaign=Search - Nonbrand - Iceberg - Global&utm_medium=cpc&utm_source=google&utm_term=apache iceberg architecture&campaignid=21254670688&adgroupid=161477881323&matchtype=p&gad_source=1&gclid=EAIaIQobChMIqu6NnIybigMV2ExBAh1xii74EAAYASAAEgLUhPD_BwE)
|
||||
resource on iceberg table format [here](https://www.dremio.com/resources/guides/apache-iceberg-an-architectural-look-under-the-covers/?utm_campaign=Search - Nonbrand - Iceberg - Global&utm_medium=cpc&utm_source=google&utm_term=apache iceberg architecture&campaignid=21254670688&adgroupid=161477881323&matchtype=p&gad_source=1&gclid=EAIaIQobChMIqu6NnIybigMV2ExBAh1xii74EAAYASAAEgLUhPD_BwE)
|
||||
|
@ -7,9 +7,9 @@
|
||||
(source
|
||||
(github username/reponame))
|
||||
|
||||
(authors "Author Name")
|
||||
(authors "Simon Petit")
|
||||
|
||||
(maintainers "Maintainer Name")
|
||||
(maintainers "Simon Petit")
|
||||
|
||||
(license LICENSE)
|
||||
|
||||
|
@ -16,12 +16,16 @@ rule read_token = parse
|
||||
| "COUNT" { COUNT }
|
||||
| "DISTINCT" { DISTINCT }
|
||||
| "FROM" { FROM }
|
||||
| "INNER" { INNER }
|
||||
| "LEFT" { LEFT }
|
||||
| "RIGHT" { RIGHT }
|
||||
| "CROSS" { CROSS }
|
||||
| "UNION" { UNION }
|
||||
| "NATURAL" { NATURAL }
|
||||
| "JOIN" { JOIN }
|
||||
| "ON" { ON }
|
||||
| "OR" { OR }
|
||||
| "AND" { AND }
|
||||
| "WHERE" { WHERE }
|
||||
| "HAVING" { HAVING }
|
||||
| "BETWEEN" { BETWEEN }
|
||||
@ -36,6 +40,12 @@ rule read_token = parse
|
||||
| ")" { RIGHT_PAREN }
|
||||
| "," { COMMA }
|
||||
| "|" { PIPE }
|
||||
| "'" { QUOTE }
|
||||
| "+" { PLUS_SIGN }
|
||||
| "-" { MINUS_SIGN }
|
||||
| whitespace { read_token lexbuf }
|
||||
| digit+ { INTEGER }
|
||||
| digit+"."digit+ { FLOAT }
|
||||
| '.'digit+ { FLOAT }
|
||||
| alpha alphanumeric* as ident { IDENT ident }
|
||||
| eof { EOF }
|
||||
|
10
lib/ast.ml
10
lib/ast.ml
@ -1,6 +1,6 @@
|
||||
type query = Query of select_stmt
|
||||
and select_stmt =
|
||||
| Select of column list * table list
|
||||
| Select of column list * table list * filter option
|
||||
and column =
|
||||
| Asterisk
|
||||
| Column of string
|
||||
@ -27,6 +27,7 @@ and predicate =
|
||||
| In of string list
|
||||
| NotIn of string list
|
||||
| Like of string
|
||||
| NotLike of string
|
||||
and operator =
|
||||
| Equals
|
||||
| NotEquals
|
||||
@ -35,19 +36,17 @@ and operator =
|
||||
| LessEquals
|
||||
| GreaterEquals
|
||||
and filter =
|
||||
| Filter of string
|
||||
| Filter of condition
|
||||
and search_condition =
|
||||
| Search of string
|
||||
|
||||
|
||||
|
||||
let rec pp_query fmt ast =
|
||||
match ast with
|
||||
| Query(s) -> Format.fprintf fmt "%s" (pp_select s)
|
||||
|
||||
and pp_select s =
|
||||
match s with
|
||||
| Select(cols, _) -> pp_columns cols
|
||||
| Select(cols, _, _) -> pp_columns cols
|
||||
|
||||
and pp_columns cols =
|
||||
match cols with
|
||||
@ -81,4 +80,3 @@ and pp_join_type j =
|
||||
| Union -> "union"
|
||||
| Natural -> "natural"
|
||||
|
||||
|
||||
|
@ -8,4 +8,3 @@ let load path delimiter header filter =
|
||||
let line = read_line ic in
|
||||
let columns = String.split_on_char delimiter line in
|
||||
|
||||
|
||||
|
@ -19,7 +19,7 @@ let rec generate_from_clause tables =
|
||||
|
||||
let generate_logical_plan ast =
|
||||
match ast with
|
||||
| Ast.Query(Select(_, tables)) ->
|
||||
| Ast.Query(Select(_, tables, _)) ->
|
||||
let base_plan = generate_from_clause tables in
|
||||
base_plan
|
||||
|
||||
|
@ -2,8 +2,8 @@
|
||||
opam-version: "2.0"
|
||||
synopsis: "A short synopsis"
|
||||
description: "A longer description"
|
||||
maintainer: ["Maintainer Name"]
|
||||
authors: ["Author Name"]
|
||||
maintainer: ["Simon Petit"]
|
||||
authors: ["Simon Petit"]
|
||||
license: "LICENSE"
|
||||
tags: ["topics" "to describe" "your" "project"]
|
||||
homepage: "https://github.com/username/reponame"
|
||||
|
@ -4,7 +4,7 @@ open Ast
|
||||
%}
|
||||
|
||||
%token CREATE TABLE
|
||||
%token SELECT ALL DISTINCT FROM WHERE HAVING BETWEEN IN LIKE
|
||||
%token SELECT ALL DISTINCT FROM WHERE HAVING BETWEEN IN LIKE IS
|
||||
%token LEFT RIGHT FULL INNER OUTER
|
||||
%token CROSS NATURAL UNION JOIN
|
||||
%token GREATER_THAN_OPERATOR LESS_THAN_OPERATOR EQUALS_OPERATOR
|
||||
@ -16,6 +16,9 @@ open Ast
|
||||
%token ASTERISK
|
||||
%token AS ON GROUP BY FILTER
|
||||
%token OR AND NOT
|
||||
%token TRUE FALSE UNKNOWN
|
||||
%token PLUS_SIGN MINUS_SIGN INTEGER FLOAT
|
||||
%token UNDERSCORE QUOTE
|
||||
%token EOF
|
||||
%start main
|
||||
%type <query> main
|
||||
@ -25,53 +28,243 @@ open Ast
|
||||
main:
|
||||
| query_specification EOF { Query($1) }
|
||||
|
||||
query_specification :
|
||||
| SELECT select_list table_expression { Select($2, $3) }
|
||||
| SELECT set_quantifier select_list table_expression { Select($3, $4) }
|
||||
(* 5.2 TOKEN / SEPARATOR *)
|
||||
|
||||
set_quantifier :
|
||||
| ALL {}
|
||||
| DISTINCT {}
|
||||
concatenation_operator:
|
||||
| PIPE PIPE {}
|
||||
|
||||
select_list :
|
||||
| ASTERISK { [Asterisk] }
|
||||
| select_sublist {$1}
|
||||
not_equals_operator :
|
||||
| LESS_THAN_OPERATOR GREATER_THAN_OPERATOR {}
|
||||
|
||||
select_sublist :
|
||||
| IDENT { [Column($1)] }
|
||||
| select_sublist COMMA IDENT { Column($3)::$1 }
|
||||
less_than_or_equals_operator:
|
||||
| LESS_THAN_OPERATOR EQUALS_OPERATOR {}
|
||||
|
||||
derived_column:
|
||||
| value_expression {}
|
||||
| value_expression as_clause {}
|
||||
greater_than_or_equals_operator:
|
||||
| GREATER_THAN_OPERATOR EQUALS_OPERATOR {}
|
||||
|
||||
as_clause :
|
||||
| AS column_name {}
|
||||
| column_name {}
|
||||
(*********************)
|
||||
|
||||
(* 5.3 LITERAL *)
|
||||
literal :
|
||||
| signed_numeric_literal {}
|
||||
| general_literal {}
|
||||
|
||||
unsigned_literal:
|
||||
(* | unsigned_numeric_literal {}*)
|
||||
| general_literal {}
|
||||
|
||||
general_literal:
|
||||
| character_string_literal {}
|
||||
|
||||
character_string_literal:
|
||||
| QUOTE IDENT QUOTE {}
|
||||
|
||||
introducer:
|
||||
| UNDERSCORE { }
|
||||
|
||||
signed_numeric_literal:
|
||||
| sign unsigned_numeric_literal {}
|
||||
| unsigned_numeric_literal {}
|
||||
|
||||
unsigned_numeric_literal :
|
||||
| exact_numeric_literal {}
|
||||
|
||||
exact_numeric_literal:
|
||||
| FLOAT {}
|
||||
|
||||
sign:
|
||||
| PLUS_SIGN {}
|
||||
| MINUS_SIGN {}
|
||||
|
||||
(***********)
|
||||
|
||||
(* 5.4 NAMES AND IDENTIFIER *)
|
||||
|
||||
column_name :
|
||||
| IDENT {}
|
||||
|
||||
table_name :
|
||||
| IDENT { Table($1) }
|
||||
|
||||
(****************************)
|
||||
|
||||
character_value_expression:
|
||||
(* | concatenation {} *)
|
||||
| character_factor { $1 }
|
||||
|
||||
|
||||
(* 6. SCALAR EXPRESSION *)
|
||||
|
||||
(* 6.3 VALUE EXPRESSION PRIMARY *)
|
||||
|
||||
value_expression_primary:
|
||||
| parenthesized_value_expression { $1 }
|
||||
| nonparenthesized_value_expression_primary { $1 }
|
||||
|
||||
parenthesized_value_expression:
|
||||
| LEFT_PAREN value_expression RIGHT_PAREN { $2 }
|
||||
|
||||
nonparenthesized_value_expression_primary:
|
||||
| column_reference { $1 }
|
||||
|
||||
(***************************)
|
||||
|
||||
(* 6.4 VALUE SPECIFCATION / TARGET SPECIFICATION *)
|
||||
|
||||
unsigned_value_specification:
|
||||
| unsigned_literal {}
|
||||
| general_value_specification {}
|
||||
|
||||
general_value_specification:
|
||||
| {}
|
||||
|
||||
(*********************************************)
|
||||
|
||||
(* 6.6 IDENTIFIER CHAIN *)
|
||||
|
||||
basic_identifier_chain:
|
||||
| identifier_chain { $1 }
|
||||
|
||||
identifier_chain:
|
||||
| IDENT { $1 }
|
||||
(*| identifier_chain DOT IDENT {}*)
|
||||
|
||||
|
||||
(************************)
|
||||
|
||||
(* 6.7 COLUMN REFERENCE *)
|
||||
|
||||
column_reference:
|
||||
| basic_identifier_chain { $1 }
|
||||
|
||||
(************************)
|
||||
|
||||
(* 6.9 SET FUCTION SPECIFICATION *)
|
||||
|
||||
set_function_specification:
|
||||
| aggregate_function { $1 }
|
||||
|
||||
(*********************************)
|
||||
|
||||
(* 6.25 VALUE EXPRESSION *)
|
||||
|
||||
value_expression:
|
||||
| common_value_expression {}
|
||||
|
||||
common_value_expression:
|
||||
| reference_value_expression {}
|
||||
(*| numeric_value_expression {}*)
|
||||
(*| string_value_expression {} *)
|
||||
| reference_value_expression { $1 }
|
||||
|
||||
reference_value_expression:
|
||||
| value_expression_primary {}
|
||||
| value_expression_primary { $1 }
|
||||
|
||||
value_expression_primary:
|
||||
| parenthesized_value_expression {}
|
||||
(*************************)
|
||||
|
||||
(* 6.28 STRING VALUE EXPRESSION *)
|
||||
|
||||
string_value_expression :
|
||||
| character_value_expression {}
|
||||
(* | blob_value_expression {} *)
|
||||
|
||||
character_primary:
|
||||
| value_expression_primary { $1 }
|
||||
(* | string_value_function {} *)
|
||||
|
||||
concatenation:
|
||||
| character_value_expression concatenation_operator character_factor {}
|
||||
|
||||
character_factor :
|
||||
| character_primary { $1 }
|
||||
|
||||
(********************************)
|
||||
|
||||
(* 6.29 STRING VALUE FUNCTION *)
|
||||
|
||||
string_value_function:
|
||||
| character_value_function {}
|
||||
|
||||
character_value_function :
|
||||
| {}
|
||||
|
||||
(*************************)
|
||||
|
||||
(* 6.34 BOOLEAN VALUE EXPRESSION *)
|
||||
|
||||
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 IS truth_value { $1 }
|
||||
| boolean_primary IS NOT truth_value { $1 }
|
||||
|
||||
truth_value:
|
||||
| TRUE {}
|
||||
| FALSE {}
|
||||
| UNKNOWN {}
|
||||
|
||||
boolean_primary :
|
||||
| predicate { $1 }
|
||||
(*| boolean_predicand {}*)
|
||||
|
||||
boolean_predicand:
|
||||
| parenthesized_boolean_value_expression {}
|
||||
| nonparenthesized_value_expression_primary {}
|
||||
|
||||
parenthesized_value_expression:
|
||||
| LEFT_PAREN value_expression RIGHT_PAREN {}
|
||||
parenthesized_boolean_value_expression:
|
||||
| LEFT_PAREN boolean_value_expression RIGHT_PAREN {}
|
||||
|
||||
(****************************)
|
||||
|
||||
(************************)
|
||||
|
||||
(* 7. QUERY EXPRESSION *)
|
||||
|
||||
(* 7.1 ROW VALUE CONSTRUCTOR *)
|
||||
|
||||
row_value_constructor_predicand:
|
||||
| common_value_expression { $1 }
|
||||
|
||||
(*************************)
|
||||
|
||||
(* 7.2 ROW VALUE EXPRESION *)
|
||||
|
||||
row_value_expression :
|
||||
| row_value_special_case { $1 }
|
||||
|
||||
row_value_predicand:
|
||||
| row_value_special_case { $1 }
|
||||
(* | row_value_constructor_predicand { $1 } *)
|
||||
|
||||
row_value_special_case :
|
||||
| nonparenthesized_value_expression_primary { $1 }
|
||||
|
||||
(***********************)
|
||||
|
||||
(* 7.3 TABLE VALUE CONSTRUCTOR *)
|
||||
|
||||
(*******************************)
|
||||
|
||||
(* 7.4 TABLE EXPRESSION *)
|
||||
|
||||
table_expression:
|
||||
| from_clause { $1 }
|
||||
| from_clause where_clause { $1 }
|
||||
|
||||
(************************)
|
||||
|
||||
(* 7.5 FROM CLAUSE *)
|
||||
|
||||
from_clause :
|
||||
| FROM table_reference_list { $2 }
|
||||
|
||||
@ -79,6 +272,10 @@ table_reference_list :
|
||||
| table_reference { [$1] }
|
||||
| table_reference_list COMMA table_reference { $3::$1 }
|
||||
|
||||
(*******************)
|
||||
|
||||
(* 7.6 TABLE REFERENCE *)
|
||||
|
||||
table_reference :
|
||||
| table_primary_or_joined_table { $1 }
|
||||
(* | table_primary_or_joined_table sample_clause { $1 } *)
|
||||
@ -93,6 +290,10 @@ table_primary :
|
||||
table_or_query_name:
|
||||
| table_name { $1 }
|
||||
|
||||
(***********************)
|
||||
|
||||
(* 7.7 JOINED TABLE *)
|
||||
|
||||
joined_table :
|
||||
| cross_join { $1 }
|
||||
| qualified_join { $1 }
|
||||
@ -106,12 +307,6 @@ 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) }
|
||||
@ -119,8 +314,12 @@ natural_join:
|
||||
union_join:
|
||||
| table_reference UNION JOIN table_primary { Join($1, Union, $4, None) }
|
||||
|
||||
table_name :
|
||||
| IDENT { Table($1) }
|
||||
join_specification:
|
||||
| join_condition { $1 }
|
||||
(* | named_columns_join {} *)
|
||||
|
||||
join_condition:
|
||||
| ON search_condition { Some($2) }
|
||||
|
||||
join_type:
|
||||
| INNER { Inner }
|
||||
@ -132,171 +331,24 @@ outer_join_type:
|
||||
| RIGHT { Right }
|
||||
| FULL { Full }
|
||||
|
||||
(*
|
||||
named_columns_join:
|
||||
| USING LEFT_PAREN join_column_list RIGHT_PAREN {}
|
||||
|
||||
join_column_list :
|
||||
| column_name_list {}
|
||||
*)
|
||||
|
||||
(********************)
|
||||
|
||||
(* 7.8 WHERE CLAUSE *)
|
||||
|
||||
where_clause :
|
||||
| WHERE search_condition { }
|
||||
| WHERE search_condition { $2 }
|
||||
|
||||
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 }
|
||||
| in_predicate { $1 }
|
||||
(* | like_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 { Condition($1, $2) }
|
||||
|
||||
between_predicate_part2 :
|
||||
| BETWEEN between_symetry row_value_predicand AND row_value_predicand { Between($3, $5) }
|
||||
| NOT BETWEEN between_symetry row_value_predicand AND row_value_predicand {NotBetween($4, $6) }
|
||||
|
||||
between_symetry :
|
||||
| {}
|
||||
| ASYMMETRIC {}
|
||||
| SYMMETRIC {}
|
||||
|
||||
in_predicate :
|
||||
| row_value_predicand in_predicate_part2 { Condition($1, $2) }
|
||||
|
||||
in_predicate_part2:
|
||||
| IN in_predicate_value { In($2) }
|
||||
| NOT IN in_predicate_value { NotIn($3) }
|
||||
|
||||
in_predicate_value:
|
||||
| LEFT_PAREN in_value_list RIGHT_PAREN { $2 }
|
||||
|
||||
in_value_list:
|
||||
| row_value_expression { [$1] }
|
||||
| in_value_list COMMA row_value_expression { $3::$1 }
|
||||
|
||||
like_predicate :
|
||||
| character_like_predicate { $1 }
|
||||
|
||||
character_like_predicate :
|
||||
| row_value_predicand character_like_predicate_part2 { }
|
||||
|
||||
character_like_predicate_part2:
|
||||
| LIKE character_pattern {}
|
||||
| NOT LIKE character_pattern {}
|
||||
|
||||
character_pattern :
|
||||
| character_value_expression {}
|
||||
|
||||
character_value_expression:
|
||||
| concatenation {}
|
||||
| character_factor {}
|
||||
|
||||
concatenation:
|
||||
| character_value_expression concatenation_operator character_factor {}
|
||||
|
||||
character_factor :
|
||||
| character_primary {}
|
||||
|
||||
character_primary:
|
||||
| value_expression_primary {}
|
||||
(* | string_value_function {} *)
|
||||
|
||||
concatenation_operator:
|
||||
| PIPE PIPE {}
|
||||
|
||||
row_value_expression :
|
||||
| row_value_special_case { $1 }
|
||||
|
||||
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 {}
|
||||
(* 7.9 GROUP BY CLAUSE *)
|
||||
|
||||
group_by_clause:
|
||||
| GROUP BY grouping_element_list {}
|
||||
@ -316,6 +368,199 @@ grouping_column_reference:
|
||||
| column_reference {}
|
||||
(*| column_reference collate_clause {}*)
|
||||
|
||||
(***********************)
|
||||
|
||||
(* 7.10 HAVING CLAUSE *)
|
||||
|
||||
having_clause :
|
||||
| HAVING search_condition { $2 }
|
||||
|
||||
(**********************)
|
||||
|
||||
(* 7.11 WINDOW CLAUSE *)
|
||||
|
||||
(**********************)
|
||||
|
||||
(* 7.12 QUERY SPECIFICATION *)
|
||||
|
||||
query_specification :
|
||||
| SELECT select_list table_expression { Select($2, $3, None) }
|
||||
| SELECT set_quantifier select_list table_expression { Select($3, $4, None) }
|
||||
|
||||
select_list :
|
||||
| ASTERISK { [Asterisk] }
|
||||
| select_sublist {$1}
|
||||
|
||||
select_sublist :
|
||||
| IDENT { [Column($1)] }
|
||||
| select_sublist COMMA IDENT { Column($3)::$1 }
|
||||
|
||||
select_sublist_element :
|
||||
| derived_column {}
|
||||
| qualified_asterisk {}
|
||||
|
||||
qualified_asterisk:
|
||||
| asterisked_identifier_chain {}
|
||||
|
||||
asterisked_identifier_chain:
|
||||
| asterisked_identifier {}
|
||||
| asterisked_identifier_chain DOT asterisked_identifier {}
|
||||
|
||||
asterisked_identifier :
|
||||
| IDENT {}
|
||||
|
||||
derived_column:
|
||||
| value_expression {}
|
||||
| value_expression as_clause {}
|
||||
|
||||
as_clause :
|
||||
| AS column_name {}
|
||||
| column_name {}
|
||||
|
||||
(****************************)
|
||||
|
||||
(* 7.13 QUERY EXPRESSION *)
|
||||
|
||||
(*************************)
|
||||
|
||||
(* 7.14 SEARCH OR CYCLE CLAUSE *)
|
||||
|
||||
(*******************************)
|
||||
|
||||
(* 7.15 SUBQUERY *)
|
||||
(*****************)
|
||||
|
||||
(***********************)
|
||||
|
||||
(* 8. PREDICATES *)
|
||||
|
||||
(* 8.1 PREDICATE *)
|
||||
|
||||
predicate :
|
||||
| comparison_predicate { $1 }
|
||||
| between_predicate { $1 }
|
||||
| in_predicate { $1 }
|
||||
(* | like_predicate { $1 }*)
|
||||
|
||||
(*****************)
|
||||
|
||||
(* 8.2 COMPARISON PREDICATE *)
|
||||
|
||||
comparison_predicate :
|
||||
| row_value_predicand comparison_predicate_part2 { Condition($1, $2) }
|
||||
|
||||
comparison_predicate_part2:
|
||||
| comp_op row_value_predicand { Comparison($1, $2) }
|
||||
|
||||
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 }
|
||||
|
||||
(****************************)
|
||||
|
||||
(* 8.3 BETWEEN PREDICATE *)
|
||||
|
||||
between_predicate :
|
||||
| row_value_predicand between_predicate_part2 { Condition($1, $2) }
|
||||
|
||||
between_predicate_part2 :
|
||||
| BETWEEN between_symetry row_value_predicand AND row_value_predicand { Between($3, $5) }
|
||||
| NOT BETWEEN between_symetry row_value_predicand AND row_value_predicand {NotBetween($4, $6) }
|
||||
|
||||
between_symetry :
|
||||
| {}
|
||||
| ASYMMETRIC {}
|
||||
| SYMMETRIC {}
|
||||
|
||||
(*************************)
|
||||
|
||||
(* 8.4 IN PREDICATE *)
|
||||
|
||||
in_predicate :
|
||||
| row_value_predicand in_predicate_part2 { Condition($1, $2) }
|
||||
|
||||
in_predicate_part2:
|
||||
| IN in_predicate_value { In($2) }
|
||||
| NOT IN in_predicate_value { NotIn($3) }
|
||||
|
||||
in_predicate_value:
|
||||
| LEFT_PAREN in_value_list RIGHT_PAREN { $2 }
|
||||
|
||||
in_value_list:
|
||||
| row_value_expression { [$1] }
|
||||
| in_value_list COMMA row_value_expression { $3::$1 }
|
||||
|
||||
(********************)
|
||||
|
||||
(* 8.5 LIKE PREDICATE *)
|
||||
|
||||
like_predicate :
|
||||
| character_like_predicate { $1 }
|
||||
|
||||
character_like_predicate :
|
||||
| row_value_predicand character_like_predicate_part2 { Condition($1, $2) }
|
||||
|
||||
character_like_predicate_part2:
|
||||
| LIKE character_pattern { Like($2) }
|
||||
| NOT LIKE character_pattern { NotLike($3) }
|
||||
|
||||
character_pattern :
|
||||
| character_value_expression { $1 }
|
||||
|
||||
(**********************)
|
||||
|
||||
(* 8.6 SIMILAR PREDICATE *)
|
||||
|
||||
(*************************)
|
||||
|
||||
(* 8.19 SEARCH CONDITION *)
|
||||
|
||||
search_condition:
|
||||
| boolean_value_expression { $1 }
|
||||
|
||||
(*************************)
|
||||
|
||||
(*****************)
|
||||
|
||||
(* 10 ADDITIONAL COMMON ELEMENTS *)
|
||||
|
||||
(* 10.9 AGGREGATE FUNCTION *)
|
||||
|
||||
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 {}
|
||||
|
||||
set_quantifier :
|
||||
| ALL {}
|
||||
| DISTINCT {}
|
||||
|
||||
filter_clause :
|
||||
| FILTER LEFT_PAREN WHERE search_condition RIGHT_PAREN {}
|
||||
|
||||
computationnal_operation:
|
||||
| AVG {}
|
||||
| MAX {}
|
||||
| MIN {}
|
||||
| SUM {}
|
||||
| COUNT {}
|
||||
|
||||
(***************************)
|
||||
|
||||
(*********************************)
|
||||
|
||||
(* 11.1 SCHEMA DEFINITION *)
|
||||
|
||||
schema_definition:
|
||||
|
@ -1,54 +0,0 @@
|
||||
open Ast
|
||||
|
||||
let parse query =
|
||||
let lexbuf = Lexing.from_string query in
|
||||
Parser.main Lexer.read_token lexbuf
|
||||
|
||||
let () =
|
||||
assert(parse "SELECT ab FROM b1" = Query(Select([Column("ab")], [Table "b1"])));
|
||||
assert(parse "SELECT ab FROM test" = Query(Select([Column("ab")], [Table "test"])));
|
||||
assert(parse "SELECT * FROM b1" = Query(Select([Asterisk], [Table "b1"])));
|
||||
assert(parse "SELECT * FROM t1 CROSS JOIN t2" = Query(Select([Asterisk], [Join(Table("t1"), Cross, Table("t2"), None)])));
|
||||
assert(parse "SELECT * FROM t1 JOIN t2 ON a = b" = Query(
|
||||
Select([Asterisk], [
|
||||
Join(
|
||||
Table("t1"),
|
||||
Left,
|
||||
Table("t2"),
|
||||
Some(
|
||||
Condition(
|
||||
"a",
|
||||
Comparison(Equals, "b")
|
||||
)
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
));
|
||||
assert(parse "SELECT * FROM t1 JOIN t2 ON a = b JOIN t3 ON c = d" = Query(
|
||||
Select([Asterisk], [
|
||||
Join(
|
||||
Join(
|
||||
Table("t1"),
|
||||
Left,
|
||||
Table("t2"),
|
||||
Some(
|
||||
Condition(
|
||||
"a",
|
||||
Comparison(Equals, "b")
|
||||
)
|
||||
)
|
||||
),
|
||||
Left,
|
||||
Table("t3"),
|
||||
Some(
|
||||
Condition(
|
||||
"c",
|
||||
Comparison(Equals, "d")
|
||||
)
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
);
|
@ -1,16 +1,7 @@
|
||||
(test
|
||||
(name SQL_parser)
|
||||
(libraries parser lexer ast))
|
||||
|
||||
(test
|
||||
(name logical_plan_test)
|
||||
(libraries ast logical_plan))
|
||||
|
||||
(test
|
||||
(name test_ast)
|
||||
(libraries parser lexer ast alcotest))
|
||||
|
||||
|
||||
(test
|
||||
(name test_parquet)
|
||||
(libraries parquet)
|
||||
|
@ -1,13 +0,0 @@
|
||||
open Ast
|
||||
|
||||
let () =
|
||||
let ast1 = Query(Select([Column("ab")], [Table "b1"])) in
|
||||
assert( Logical_plan.generate_logical_plan ast1 = Logical_plan.Scan("b1"));
|
||||
let ast2 = Query(Select([Asterisk], [Join(Table("t1"), Cross, Table("t2"), None)])) in
|
||||
assert(Logical_plan.generate_logical_plan ast2 =
|
||||
Logical_plan.Join(
|
||||
Logical_plan.Scan("t1"),
|
||||
Cross,
|
||||
Logical_plan.Scan("t2")
|
||||
)
|
||||
);
|
203
test/test_ast.ml
203
test/test_ast.ml
@ -10,13 +10,208 @@ let equal_ast ast1 ast2 =
|
||||
let query_testable =
|
||||
Alcotest.testable Ast.pp_query equal_ast
|
||||
|
||||
let test_simple_select() =
|
||||
let test_simple_select () =
|
||||
let q1 = parse "SELECT a FROM t" in
|
||||
let ast1 = Query(Select([Column("a")], [Table("t")])) in
|
||||
Alcotest.(check query_testable) "Ok" q1 ast1
|
||||
let ast1 = Query(Select([Column("a")], [Table("t")], None)) in
|
||||
Alcotest.(check query_testable) "Ok" q1 ast1;
|
||||
|
||||
let q2 = parse "SELECT * FROM t" in
|
||||
let ast2 = Query(Select([Asterisk], [Table("t")], None)) in
|
||||
Alcotest.(check query_testable) "Ok2" q2 ast2
|
||||
|
||||
let test_default_join () =
|
||||
let q1 = parse "SELECT a FROM t1 JOIN t2 ON a = b" in
|
||||
let ast1 = Query(
|
||||
Select(
|
||||
[Column("a")],
|
||||
[Join(
|
||||
Table("t1"),
|
||||
Left,
|
||||
Table("t2"),
|
||||
Some(
|
||||
Condition(
|
||||
"a",
|
||||
Comparison(Equals, "b")
|
||||
)
|
||||
)
|
||||
)],
|
||||
None
|
||||
)
|
||||
) in
|
||||
Alcotest.(check query_testable) "Ok" q1 ast1
|
||||
|
||||
let test_left_join () =
|
||||
let q1 = parse "SELECT a FROM t1 LEFT JOIN t2 ON a = b" in
|
||||
let ast1 = Query(
|
||||
Select([Column("a")],
|
||||
[Join(
|
||||
Table("t1"),
|
||||
Left,
|
||||
Table("t2"),
|
||||
Some(
|
||||
Condition(
|
||||
"a",
|
||||
Comparison(Equals, "b")
|
||||
)
|
||||
)
|
||||
)],
|
||||
None
|
||||
)
|
||||
) in
|
||||
Alcotest.(check query_testable) "Ok" q1 ast1
|
||||
|
||||
let test_right_join () =
|
||||
let q1 = parse "SELECT a FROM t1 RIGHT JOIN t2 ON a = b" in
|
||||
let ast1 = Query(
|
||||
Select([Column("a")],
|
||||
[Join(
|
||||
Table("t1"),
|
||||
Right,
|
||||
Table("t2"),
|
||||
Some(
|
||||
Condition(
|
||||
"a",
|
||||
Comparison(Equals, "b")
|
||||
)
|
||||
)
|
||||
)],
|
||||
None
|
||||
)
|
||||
) in
|
||||
Alcotest.(check query_testable) "Ok" q1 ast1
|
||||
|
||||
let test_inner_join () =
|
||||
let q1 = parse "SELECT a FROM t1 INNER JOIN t2 ON a = b" in
|
||||
let ast1 = Query(
|
||||
Select([Column("a")],
|
||||
[Join(
|
||||
Table("t1"),
|
||||
Inner,
|
||||
Table("t2"),
|
||||
Some(
|
||||
Condition(
|
||||
"a",
|
||||
Comparison(Equals, "b")
|
||||
)
|
||||
)
|
||||
)],
|
||||
None
|
||||
)
|
||||
) in
|
||||
Alcotest.(check query_testable) "Ok" q1 ast1
|
||||
|
||||
let test_union_join () =
|
||||
let q1 = parse "SELECT a FROM t1 UNION JOIN t2" in
|
||||
let ast1 = Query(
|
||||
Select([Column("a")],
|
||||
[Join(
|
||||
Table("t1"),
|
||||
Union,
|
||||
Table("t2"),
|
||||
None
|
||||
)],
|
||||
None
|
||||
)
|
||||
) in
|
||||
Alcotest.(check query_testable) "Ok" q1 ast1
|
||||
|
||||
let test_cross_join () =
|
||||
let q1 = parse "SELECT a FROM t1 CROSS JOIN t2" in
|
||||
let ast1 = Query(
|
||||
Select([Column("a")],
|
||||
[Join(
|
||||
Table("t1"),
|
||||
Cross,
|
||||
Table("t2"),
|
||||
None
|
||||
)],
|
||||
None
|
||||
)
|
||||
) in
|
||||
Alcotest.(check query_testable) "Ok" q1 ast1
|
||||
|
||||
let test_natural_join () =
|
||||
let q1 = parse "SELECT a FROM t1 NATURAL JOIN t2" in
|
||||
let ast1 = Query(
|
||||
Select([Column("a")],
|
||||
[Join(
|
||||
Table("t1"),
|
||||
Natural,
|
||||
Table("t2"),
|
||||
None
|
||||
)],
|
||||
None
|
||||
)
|
||||
) in
|
||||
Alcotest.(check query_testable) "Ok" q1 ast1
|
||||
|
||||
let test_join_join () =
|
||||
let q1 = parse "SELECT a FROM t1 JOIN t2 ON a = b JOIN t3 ON a = c" in
|
||||
let ast1 = Query(
|
||||
Select([Column("a")], [
|
||||
Join(
|
||||
Join(
|
||||
Table("t1"),
|
||||
Left,
|
||||
Table("t2"),
|
||||
Some(
|
||||
Condition(
|
||||
"a",
|
||||
Comparison(Equals, "b")
|
||||
)
|
||||
)
|
||||
),
|
||||
Left,
|
||||
Table("t3"),
|
||||
Some(
|
||||
Condition(
|
||||
"a",
|
||||
Comparison(Equals, "c")
|
||||
)
|
||||
)
|
||||
)
|
||||
],
|
||||
None
|
||||
)
|
||||
) in
|
||||
Alcotest.(check query_testable) "Ok" q1 ast1
|
||||
|
||||
let test_where_equals () =
|
||||
let q1 = parse "SELECT a FROM t1 WHERE a = a OR a = b" in
|
||||
let ast1 = Query(
|
||||
Select(
|
||||
[Column("a")],
|
||||
[Table("t1")],
|
||||
None
|
||||
)
|
||||
) in
|
||||
Alcotest.(check query_testable) "Ok" q1 ast1
|
||||
|
||||
let simple_select_set = [ ("Equals", `Quick, test_simple_select) ]
|
||||
|
||||
let simple_join_set = [
|
||||
("Default Join", `Quick, test_default_join);
|
||||
("Left Join", `Quick, test_left_join);
|
||||
("Right Join", `Quick, test_right_join);
|
||||
("Inner Join", `Quick, test_inner_join);
|
||||
("Union Join", `Quick, test_union_join);
|
||||
("Cross Join", `Quick, test_cross_join);
|
||||
("Natural Join", `Quick, test_natural_join)
|
||||
]
|
||||
|
||||
let multiple_joins_set = [
|
||||
("Join Join", `Quick, test_join_join)
|
||||
]
|
||||
|
||||
let where_clauses_set = [
|
||||
("Where Equals", `Quick, test_where_equals)
|
||||
]
|
||||
|
||||
let () =
|
||||
Alcotest.run "Ast tests"
|
||||
[ ("Simple Selects", simple_select_set) ]
|
||||
[
|
||||
("Simple Selects", simple_select_set);
|
||||
("Simple Joins", simple_join_set);
|
||||
("Multiple Joins", multiple_joins_set);
|
||||
("Where Clauses", where_clauses_set)
|
||||
]
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* fb303.thrift
|
||||
*/
|
||||
|
||||
namespace java com.facebook.fb303
|
||||
namespace cpp facebook.fb303
|
||||
namespace perl Facebook.FB303
|
||||
namespace netstd Facebook.FB303.Test
|
||||
|
||||
/**
|
||||
* Common status reporting mechanism across all services
|
||||
*/
|
||||
enum fb_status {
|
||||
DEAD = 0,
|
||||
STARTING = 1,
|
||||
ALIVE = 2,
|
||||
STOPPING = 3,
|
||||
STOPPED = 4,
|
||||
WARNING = 5,
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard base service
|
||||
*/
|
||||
service FacebookService {
|
||||
|
||||
/**
|
||||
* Returns a descriptive name of the service
|
||||
*/
|
||||
string getName(),
|
||||
|
||||
/**
|
||||
* Returns the version of the service
|
||||
*/
|
||||
string getVersion(),
|
||||
|
||||
/**
|
||||
* Gets the status of this service
|
||||
*/
|
||||
fb_status getStatus(),
|
||||
|
||||
/**
|
||||
* User friendly description of status, such as why the service is in
|
||||
* the dead or warning state, or what is being started or stopped.
|
||||
*/
|
||||
string getStatusDetails(),
|
||||
|
||||
/**
|
||||
* Gets the counters for this service
|
||||
*/
|
||||
map<string, i64> getCounters(),
|
||||
|
||||
/**
|
||||
* Gets the value of a single counter
|
||||
*/
|
||||
i64 getCounter(1: string key),
|
||||
|
||||
/**
|
||||
* Sets an option
|
||||
*/
|
||||
void setOption(1: string key, 2: string value),
|
||||
|
||||
/**
|
||||
* Gets an option
|
||||
*/
|
||||
string getOption(1: string key),
|
||||
|
||||
/**
|
||||
* Gets all options
|
||||
*/
|
||||
map<string, string> getOptions(),
|
||||
|
||||
/**
|
||||
* Returns a CPU profile over the given time interval (client and server
|
||||
* must agree on the profile format).
|
||||
*/
|
||||
string getCpuProfile(1: i32 profileDurationInSec),
|
||||
|
||||
/**
|
||||
* Returns the unix time that the server has been running since
|
||||
*/
|
||||
i64 aliveSince(),
|
||||
|
||||
/**
|
||||
* Tell the server to reload its configuration, reopen log files, etc
|
||||
*/
|
||||
oneway void reinitialize(),
|
||||
|
||||
/**
|
||||
* Suggest a shutdown to the server
|
||||
*/
|
||||
oneway void shutdown(),
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user