diff --git a/parser/parser.mly b/parser/parser.mly index ea90977..4ff6069 100644 --- a/parser/parser.mly +++ b/parser/parser.mly @@ -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 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,5 +368,198 @@ 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 {} + +(***************************) + +(*********************************) + table_definition : | CREATE TABLE table_name {}