| /** |
| * 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. |
| **/ |
| |
| %name-prefix "quickstep_yy" |
| %define api.pure |
| %locations |
| %lex-param {yyscan_t yyscanner} |
| %parse-param {yyscan_t yyscanner} |
| %parse-param {quickstep::ParseStatement **parsedStatement} |
| |
| /** |
| * NOTE(chasseur): There are two known shift/reduce conflicts in this parser. |
| * They are noted where they occur in the source below. When such a conflict |
| * occurs, Bison resolves it by preferring to shift rather than reduce, which |
| * is the correct, expected behavior for both cases in this parser. |
| **/ |
| %expect 2 |
| |
| %{ |
| |
| /* Override the default definition, as we only need <first_line> and <first_column>. */ |
| typedef struct YYLTYPE { |
| int first_line; |
| int first_column; |
| } YYLTYPE; |
| |
| #define YYLTYPE_IS_DECLARED 1 |
| |
| /* |
| * Modified from the default YYLLOC_DEFAULT |
| * (http://www.gnu.org/software/bison/manual/html_node/Location-Default-Action.html). |
| * The assignments for last_line and last_column are removed as they are not used. |
| */ |
| #define YYLLOC_DEFAULT(current, rhs, n) \ |
| do { \ |
| if (n) { \ |
| (current).first_line = YYRHSLOC(rhs, 1).first_line; \ |
| (current).first_column = YYRHSLOC(rhs, 1).first_column; \ |
| } else { \ |
| /* empty RHS */ \ |
| (current).first_line = YYRHSLOC(rhs, 0).first_line; \ |
| (current).first_column = YYRHSLOC(rhs, 0).first_column; \ |
| } \ |
| } while (0) |
| |
| %} |
| |
| %{ |
| #include <cstdlib> |
| #include <string> |
| #include <utility> |
| |
| #include "catalog/PartitionSchemeHeader.hpp" |
| #include "parser/ParseAssignment.hpp" |
| #include "parser/ParseAttributeDefinition.hpp" |
| #include "parser/ParseBasicExpressions.hpp" |
| #include "parser/ParseBlockProperties.hpp" |
| #include "parser/ParseCaseExpressions.hpp" |
| #include "parser/ParseExpression.hpp" |
| #include "parser/ParseGeneratorTableReference.hpp" |
| #include "parser/ParseGroupBy.hpp" |
| #include "parser/ParseHaving.hpp" |
| #include "parser/ParseJoinedTableReference.hpp" |
| #include "parser/ParseKeyValue.hpp" |
| #include "parser/ParseLimit.hpp" |
| #include "parser/ParseLiteralValue.hpp" |
| #include "parser/ParseOrderBy.hpp" |
| #include "parser/ParsePartitionClause.hpp" |
| #include "parser/ParsePredicate.hpp" |
| #include "parser/ParsePredicateExists.hpp" |
| #include "parser/ParsePredicateInTableQuery.hpp" |
| #include "parser/ParsePriority.hpp" |
| #include "parser/ParserUtil.hpp" |
| #include "parser/ParseSample.hpp" |
| #include "parser/ParseSelect.hpp" |
| #include "parser/ParseSelectionClause.hpp" |
| #include "parser/ParseSimpleTableReference.hpp" |
| #include "parser/ParseStatement.hpp" |
| #include "parser/ParseString.hpp" |
| #include "parser/ParseSubqueryExpression.hpp" |
| #include "parser/ParseSubqueryTableReference.hpp" |
| #include "parser/ParseTableReference.hpp" |
| #include "parser/ParseWindow.hpp" |
| #include "storage/StorageBlockInfo.hpp" |
| #include "types/Type.hpp" |
| #include "types/TypeFactory.hpp" |
| #include "types/TypeID.hpp" |
| #include "types/operations/binary_operations/BinaryOperation.hpp" |
| #include "types/operations/binary_operations/BinaryOperationFactory.hpp" |
| #include "types/operations/binary_operations/BinaryOperationID.hpp" |
| #include "types/operations/comparisons/Comparison.hpp" |
| #include "types/operations/comparisons/ComparisonFactory.hpp" |
| #include "types/operations/comparisons/ComparisonID.hpp" |
| #include "types/operations/unary_operations/UnaryOperation.hpp" |
| #include "types/operations/unary_operations/UnaryOperationFactory.hpp" |
| #include "types/operations/unary_operations/UnaryOperationID.hpp" |
| #include "utility/PtrList.hpp" |
| #include "utility/PtrVector.hpp" |
| |
| // Needed for Bison 2.6 and higher, which do not automatically provide this typedef. |
| typedef void* yyscan_t; |
| %} |
| |
| %union{ |
| quickstep::ParseString *string_value_; |
| |
| quickstep::PtrList<quickstep::ParseString> *string_list_; |
| |
| bool boolean_value_; |
| |
| quickstep::NumericParseLiteralValue *numeric_literal_value_; |
| quickstep::ParseLiteralValue *literal_value_; |
| quickstep::PtrList<quickstep::ParseScalarLiteral> *literal_value_list_; |
| |
| quickstep::ParseExpression *expression_; |
| |
| quickstep::ParseScalarLiteral *scalar_literal_; |
| quickstep::ParseAttribute *attribute_; |
| quickstep::PtrList<quickstep::ParseAttribute> *attribute_list_; |
| |
| quickstep::ParsePredicate *predicate_; |
| |
| quickstep::ParseSubqueryExpression *subquery_expression_; |
| |
| quickstep::PtrVector<quickstep::ParseSimpleWhenClause> *simple_when_clause_list_; |
| quickstep::ParseSimpleWhenClause *simple_when_clause_; |
| |
| quickstep::PtrVector<quickstep::ParseSearchedWhenClause> *searched_when_clause_list_; |
| quickstep::ParseSearchedWhenClause *searched_when_clause_; |
| |
| quickstep::ParseSelectionClause *selection_; |
| quickstep::ParseSelectionItem *selection_item_; |
| quickstep::ParseSelectionList *selection_list_; |
| |
| quickstep::ParseTableReference *table_reference_; |
| quickstep::PtrList<quickstep::ParseTableReference> *table_reference_list_; |
| quickstep::ParseTableReferenceSignature *table_reference_signature_; |
| |
| quickstep::ParseJoinedTableReference::JoinType join_type_; |
| |
| quickstep::ParseDataType *data_type_; |
| quickstep::ParseAttributeDefinition *attribute_definition_; |
| quickstep::ParseColumnConstraint *column_constraint_; |
| quickstep::PtrList<quickstep::ParseColumnConstraint> *column_constraint_list_; |
| quickstep::PtrList<quickstep::ParseAttributeDefinition> *attribute_definition_list_; |
| |
| quickstep::ParseKeyValue *key_value_; |
| quickstep::PtrList<quickstep::ParseKeyValue> *key_value_list_; |
| quickstep::ParseKeyStringValue *key_string_value_; |
| quickstep::ParseKeyStringList *key_string_list_; |
| quickstep::ParseKeyIntegerValue *key_integer_value_; |
| |
| quickstep::ParseCopyFromParams *copy_from_params_; |
| |
| quickstep::ParseAssignment *assignment_; |
| quickstep::PtrList<quickstep::ParseAssignment> *assignment_list_; |
| |
| quickstep::ParseCommand *command_; |
| quickstep::PtrVector<quickstep::ParseString> *command_argument_list_; |
| |
| quickstep::ParseStatement *statement_; |
| quickstep::ParseStatementSelect *select_statement_; |
| quickstep::ParseStatementUpdate *update_statement_; |
| quickstep::ParseStatementInsert *insert_statement_; |
| quickstep::ParseStatementDelete *delete_statement_; |
| quickstep::ParseStatementCopyFrom *copy_from_statement_; |
| quickstep::ParseStatementCreateTable *create_table_statement_; |
| quickstep::ParsePartitionClause *partition_clause_; |
| quickstep::ParseBlockProperties *block_properties_; |
| quickstep::ParseStatementDropTable *drop_table_statement_; |
| quickstep::ParseStatementQuit *quit_statement_; |
| |
| const quickstep::Comparison *comparison_; |
| const quickstep::UnaryOperation *unary_operation_; |
| const quickstep::BinaryOperation *binary_operation_; |
| |
| quickstep::ParseFunctionCall *function_call_; |
| quickstep::PtrList<quickstep::ParseExpression> *expression_list_; |
| |
| quickstep::ParseSelect *select_query_; |
| quickstep::ParseGroupBy *opt_group_by_clause_; |
| quickstep::ParseHaving *opt_having_clause_; |
| quickstep::ParseOrderBy *opt_order_by_clause_; |
| bool *order_direction_; |
| quickstep::ParseLimit *opt_limit_clause_; |
| |
| quickstep::ParseSample *opt_sample_clause_; |
| |
| quickstep::PtrList<quickstep::ParseWindow> *opt_window_clause_; |
| quickstep::ParseWindow *window_definition_; |
| quickstep::PtrList<quickstep::ParseExpression> *window_partition_by_list_; |
| quickstep::PtrList<quickstep::ParseOrderByItem> *window_order_by_list_; |
| quickstep::ParseFrameInfo *window_frame_info_; |
| |
| quickstep::PtrList<quickstep::ParseOrderByItem> *order_commalist_; |
| quickstep::ParseOrderByItem *order_item_; |
| |
| quickstep::PtrVector<quickstep::ParseSubqueryTableReference> *with_list_; |
| quickstep::ParseSubqueryTableReference *with_list_element_; |
| |
| quickstep::ParsePriority *opt_priority_clause_; |
| } |
| |
| %{ |
| /* This header needs YYSTYPE, which is defined by the %union directive above */ |
| #include "SqlLexer_gen.hpp" |
| void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string &feature); |
| %} |
| |
| %token <string_value_> TOKEN_COMMAND; |
| %token <string_value_> TOKEN_NAME; |
| %token <string_value_> TOKEN_STRING_SINGLE_QUOTED; |
| %token <string_value_> TOKEN_STRING_DOUBLE_QUOTED; |
| %token <numeric_literal_value_> TOKEN_UNSIGNED_NUMVAL; |
| |
| /* Operator precedence - least to greatest */ |
| %left TOKEN_OR |
| %left TOKEN_AND |
| %right TOKEN_NOT |
| %right TOKEN_EQ |
| %nonassoc TOKEN_LT TOKEN_LEQ TOKEN_GT TOKEN_GEQ TOKEN_NEQ |
| %nonassoc TOKEN_LIKE TOKEN_REGEXP |
| %nonassoc TOKEN_BETWEEN |
| %nonassoc TOKEN_IS |
| %left '+' '-' |
| %left '*' '/' |
| %right UNARY_PLUS UNARY_MINUS |
| %left '.' |
| |
| %token TOKEN_ADD; |
| %token TOKEN_ALL; |
| %token TOKEN_ALTER; |
| %token TOKEN_AND; |
| %token TOKEN_AS; |
| %token TOKEN_ASC; |
| %token TOKEN_BIGINT; |
| %token TOKEN_BIT; |
| %token TOKEN_BITWEAVING; |
| %token TOKEN_BLOCKPROPERTIES; |
| %token TOKEN_BLOCKSAMPLE; |
| %token TOKEN_BLOOM_FILTER; |
| %token TOKEN_CSB_TREE; |
| %token TOKEN_BY; |
| %token TOKEN_CASE; |
| %token TOKEN_CHARACTER; |
| %token TOKEN_CHECK; |
| %token TOKEN_COLUMN; |
| %token TOKEN_CONSTRAINT; |
| %token TOKEN_COPY; |
| %token TOKEN_CREATE; |
| %token TOKEN_CURRENT; |
| %token TOKEN_DATE; |
| %token TOKEN_DATETIME; |
| %token TOKEN_DAY; |
| %token TOKEN_DECIMAL; |
| %token TOKEN_DEFAULT; |
| %token TOKEN_DELETE; |
| %token TOKEN_DELIMITER; |
| %token TOKEN_DESC; |
| %token TOKEN_DISTINCT; |
| %token TOKEN_DOUBLE; |
| %token TOKEN_DROP; |
| %token TOKEN_ELSE; |
| %token TOKEN_END; |
| %token TOKEN_ESCAPE_STRINGS; |
| %token TOKEN_EXISTS; |
| %token TOKEN_EXTRACT; |
| %token TOKEN_FALSE; |
| %token TOKEN_FIRST; |
| %token TOKEN_FLOAT; |
| %token TOKEN_FOLLOWING; |
| %token TOKEN_FOR; |
| %token TOKEN_FOREIGN; |
| %token TOKEN_FROM; |
| %token TOKEN_FULL; |
| %token TOKEN_GROUP; |
| %token TOKEN_HASH; |
| %token TOKEN_HAVING; |
| %token TOKEN_HOUR; |
| %token TOKEN_IN; |
| %token TOKEN_INDEX; |
| %token TOKEN_INNER; |
| %token TOKEN_INSERT; |
| %token TOKEN_INTEGER; |
| %token TOKEN_INTERVAL; |
| %token TOKEN_INTO; |
| %token TOKEN_JOIN; |
| %token TOKEN_KEY; |
| %token TOKEN_LAST; |
| %token TOKEN_LEFT; |
| %token TOKEN_LIMIT; |
| %token TOKEN_LONG; |
| %token TOKEN_MINUTE; |
| %token TOKEN_MONTH; |
| %token TOKEN_NOT; |
| %token TOKEN_NULL; |
| %token TOKEN_NULLS; |
| %token TOKEN_OFF; |
| %token TOKEN_ON; |
| %token TOKEN_OR; |
| %token TOKEN_ORDER; |
| %token TOKEN_OUTER; |
| %token TOKEN_OVER; |
| %token TOKEN_PARTITION; |
| %token TOKEN_PARTITIONS; |
| %token TOKEN_PERCENT; |
| %token TOKEN_PRECEDING; |
| %token TOKEN_PRIMARY; |
| %token TOKEN_PRIORITY; |
| %token TOKEN_QUIT; |
| %token TOKEN_RANGE; |
| %token TOKEN_REAL; |
| %token TOKEN_REFERENCES; |
| %token TOKEN_REGEXP; |
| %token TOKEN_RIGHT; |
| %token TOKEN_ROW; |
| %token TOKEN_ROW_DELIMITER; |
| %token TOKEN_ROWS; |
| %token TOKEN_SECOND; |
| %token TOKEN_SELECT; |
| %token TOKEN_SET; |
| %token TOKEN_SMA; |
| %token TOKEN_SMALLINT; |
| %token TOKEN_SUBSTRING; |
| %token TOKEN_TABLE; |
| %token TOKEN_THEN; |
| %token TOKEN_TIME; |
| %token TOKEN_TIMESTAMP; |
| %token TOKEN_TRUE; |
| %token TOKEN_TUPLESAMPLE; |
| %token TOKEN_UNBOUNDED; |
| %token TOKEN_UNIQUE; |
| %token TOKEN_UPDATE; |
| %token TOKEN_USING; |
| %token TOKEN_VALUES; |
| %token TOKEN_VARCHAR; |
| %token TOKEN_WHEN; |
| %token TOKEN_WHERE; |
| %token TOKEN_WINDOW; |
| %token TOKEN_WITH; |
| %token TOKEN_YEAR; |
| %token TOKEN_YEARMONTH; |
| %token TOKEN_EOF; |
| %token TOKEN_LEX_ERROR; |
| |
| %type <string_value_> |
| any_name |
| datetime_unit |
| index_type |
| partition_type |
| |
| %type <boolean_value_> |
| boolean_value |
| frame_mode |
| |
| %type <literal_value_> |
| literal_value |
| |
| %type <numeric_literal_value_> |
| frame_preceding |
| frame_following |
| |
| %type <literal_value_list_> |
| literal_value_commalist |
| |
| %type <expression_> |
| expression_base |
| unary_expression |
| multiply_expression |
| add_expression |
| case_expression |
| opt_else_clause |
| extract_function |
| substr_function |
| |
| %type <attribute_> |
| attribute_ref |
| |
| %type <attribute_list_> |
| attribute_ref_list |
| opt_column_list |
| |
| %type <predicate_> |
| predicate_expression_base |
| not_expression |
| and_expression |
| or_expression |
| where_clause |
| opt_where_clause |
| |
| %type <subquery_expression_> |
| subquery_expression |
| |
| %type <simple_when_clause_list_> |
| simple_when_clause_list |
| |
| %type <simple_when_clause_> |
| simple_when_clause |
| |
| %type <searched_when_clause_list_> |
| searched_when_clause_list |
| |
| %type <searched_when_clause_> |
| searched_when_clause |
| |
| %type <selection_> |
| selection |
| |
| %type <selection_item_> |
| selection_item |
| |
| %type <selection_list_> |
| selection_item_commalist |
| |
| %type <table_reference_> |
| table_reference |
| joined_table_reference |
| |
| %type <table_reference_list_> |
| joined_table_reference_commalist |
| from_clause |
| |
| %type <table_reference_signature_> |
| table_reference_signature |
| table_reference_signature_primary |
| |
| %type <join_type_> |
| join_type |
| |
| %type <data_type_> |
| data_type |
| |
| %type <attribute_definition_> |
| column_def |
| |
| %type <column_constraint_> |
| column_constraint_def |
| |
| %type <column_constraint_list_> |
| column_constraint_def_list |
| opt_column_constraint_def_list |
| |
| %type <attribute_definition_list_> |
| column_def_commalist |
| |
| %type <key_value_> |
| key_value |
| |
| %type <key_value_list_> |
| key_value_list |
| opt_index_properties |
| |
| %type <key_string_value_> |
| key_string_value |
| |
| %type <key_string_list_> |
| key_string_list |
| |
| %type <key_integer_value_> |
| key_integer_value |
| |
| %type <assignment_> |
| assignment_item |
| |
| %type <assignment_list_> |
| assignment_list |
| |
| %type <statement_> |
| sql_statement |
| alter_table_statement |
| |
| %type <select_statement_> |
| select_statement |
| |
| %type <select_query_> |
| select_query |
| |
| %type <update_statement_> |
| update_statement |
| |
| %type <delete_statement_> |
| delete_statement |
| |
| %type <insert_statement_> |
| insert_statement |
| |
| %type <copy_from_statement_> |
| copy_from_statement |
| |
| %type <copy_from_params_> |
| copy_from_params |
| opt_copy_from_params |
| |
| %type <create_table_statement_> |
| create_table_statement |
| |
| %type <block_properties_> |
| opt_block_properties |
| |
| %type <partition_clause_> |
| opt_partition_clause |
| |
| %type <statement_> |
| create_index_statement |
| |
| %type <drop_table_statement_> |
| drop_table_statement |
| |
| %type <quit_statement_> |
| quit_statement |
| |
| %type <string_list_> |
| name_commalist |
| |
| %type <comparison_> |
| comparison_operation |
| |
| %type <unary_operation_> |
| unary_operation |
| |
| %type <binary_operation_> |
| /* binary_operation */ |
| add_operation |
| multiply_operation |
| |
| %type <function_call_> |
| function_call |
| |
| %type <expression_list_> |
| expression_list |
| |
| %type <opt_group_by_clause_> |
| opt_group_by_clause |
| |
| %type <opt_having_clause_> |
| opt_having_clause |
| |
| %type <opt_order_by_clause_> |
| opt_order_by_clause |
| |
| %type <order_commalist_> |
| order_commalist |
| |
| %type <order_item_> |
| order_item |
| |
| %type <order_direction_> |
| opt_order_direction |
| opt_nulls_first |
| |
| %type <opt_limit_clause_> |
| opt_limit_clause |
| |
| %type <opt_sample_clause_> |
| opt_sample_clause |
| |
| %type <opt_window_clause_> |
| opt_window_clause |
| window_declaration_list |
| |
| %type <window_definition_> |
| window_declaration |
| window_definition |
| |
| %type <window_partition_by_list_> |
| opt_window_partition |
| |
| %type <window_order_by_list_> |
| opt_window_order |
| |
| %type <window_frame_info_> |
| opt_window_frame |
| |
| %type <opt_priority_clause_> |
| opt_priority_clause |
| |
| %type <with_list_> |
| with_clause |
| with_list |
| |
| %type <with_list_element_> |
| with_list_element |
| |
| %type <command_> |
| command |
| |
| %type <command_argument_list_> |
| command_argument_list |
| |
| /* |
| %type <int_val> |
| opt_all_distinct // unimplemented |
| table_constraint_def // unimplemented |
| table_constraint_def_commalist // unimplemented |
| opt_table_constraint_def_commalist // unimplemented |
| */ |
| |
| %destructor { } <boolean_value_> |
| %destructor { } <comparison_> |
| %destructor { } <unary_operation_> |
| %destructor { } <binary_operation_> |
| %destructor { } <join_type_> |
| |
| %destructor { |
| if ($$ != nullptr) { |
| delete $$; |
| } |
| } <*> |
| |
| %% |
| |
| start: |
| sql_statement ';' { |
| *parsedStatement = $1; |
| YYACCEPT; |
| } |
| | sql_statement TOKEN_EOF { |
| *parsedStatement = $1; |
| YYACCEPT; |
| } |
| | command '\n' { |
| *parsedStatement = $1; |
| YYACCEPT; |
| } |
| | command TOKEN_EOF { |
| *parsedStatement = $1; |
| YYACCEPT; |
| } |
| | error { |
| YYABORT; |
| } |
| | TOKEN_EOF { |
| // Regular yyparse() return codes are non-negative, so use a negative one here. |
| return -1; |
| }; |
| |
| /* All supported statement types */ |
| sql_statement: |
| alter_table_statement { |
| $$ = $1; |
| } |
| | copy_from_statement { |
| $$ = $1; |
| } |
| | create_table_statement { |
| $$ = $1; |
| } |
| | create_index_statement { |
| $$ = $1; |
| } |
| | delete_statement { |
| $$ = $1; |
| } |
| | drop_table_statement { |
| $$ = $1; |
| } |
| | insert_statement { |
| $$ = $1; |
| } |
| | quit_statement { |
| $$ = $1; |
| } |
| | select_statement { |
| $$ = $1; |
| } |
| | update_statement { |
| $$ = $1; |
| }; |
| |
| /* Quit statement */ |
| quit_statement: |
| TOKEN_QUIT { |
| $$ = new quickstep::ParseStatementQuit(@1.first_line, @1.first_column); |
| }; |
| |
| /* Table modification statements */ |
| alter_table_statement: |
| TOKEN_ALTER TOKEN_TABLE any_name TOKEN_ADD TOKEN_COLUMN column_def { |
| delete $3; |
| delete $6; |
| $$ = nullptr; |
| NotSupported(&@1, yyscanner, "ALTER statements"); |
| YYERROR; |
| } |
| | TOKEN_ALTER TOKEN_TABLE any_name TOKEN_ADD TOKEN_CONSTRAINT table_constraint_def { |
| delete $3; |
| $$ = nullptr; |
| NotSupported(&@1, yyscanner, "ALTER statements"); |
| YYERROR; |
| } |
| | TOKEN_ALTER TOKEN_TABLE any_name TOKEN_DROP TOKEN_COLUMN any_name { |
| delete $3; |
| delete $6; |
| $$ = nullptr; |
| NotSupported(&@1, yyscanner, "ALTER statements"); |
| YYERROR; |
| } |
| | TOKEN_ALTER TOKEN_TABLE any_name TOKEN_DROP TOKEN_CONSTRAINT any_name { |
| delete $3; |
| delete $6; |
| $$ = nullptr; |
| NotSupported(&@1, yyscanner, "ALTER statements"); |
| YYERROR; |
| }; |
| |
| create_table_statement: |
| TOKEN_CREATE TOKEN_TABLE any_name '(' column_def_commalist ')' opt_table_constraint_def_commalist opt_block_properties opt_partition_clause { |
| $$ = new quickstep::ParseStatementCreateTable(@1.first_line, @1.first_column, $3, $5, $8, $9); |
| }; |
| |
| create_index_statement: |
| TOKEN_CREATE TOKEN_INDEX any_name TOKEN_ON any_name opt_column_list TOKEN_USING index_type opt_index_properties { |
| if ($9) { |
| $$ = new quickstep::ParseStatementCreateIndex(@1.first_line, @1.first_column, $3, $5, $6, $8, @9.first_line, @9.first_column, $9); |
| } else { |
| $$ = new quickstep::ParseStatementCreateIndex(@1.first_line, @1.first_column, $3, $5, $6, $8); |
| } |
| }; |
| |
| drop_table_statement: |
| TOKEN_DROP TOKEN_TABLE any_name { |
| $$ = new quickstep::ParseStatementDropTable(@1.first_line, @1.first_column, $3); |
| }; |
| |
| column_def: |
| any_name data_type opt_column_constraint_def_list { |
| $$ = new quickstep::ParseAttributeDefinition(@1.first_line, @1.first_column, $1, $2, $3); |
| }; |
| |
| column_def_commalist: |
| column_def { |
| $$ = new quickstep::PtrList<quickstep::ParseAttributeDefinition>(); |
| $$->push_back($1); |
| } |
| | column_def_commalist ',' column_def { |
| $$ = $1; |
| $$->push_back($3); |
| }; |
| |
| data_type: |
| TOKEN_BIT { |
| $$ = nullptr; |
| NotSupported(&@1, yyscanner, "BIT data type"); |
| YYERROR; |
| } |
| | TOKEN_DATE { |
| $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDate)); |
| } |
| | TOKEN_DATETIME { |
| $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDatetime)); |
| } |
| | TOKEN_TIME { |
| $$ = nullptr; |
| NotSupported(&@1, yyscanner, "TIME data type"); |
| YYERROR; |
| } |
| | TOKEN_TIMESTAMP { |
| $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDatetime)); |
| } |
| | TOKEN_DECIMAL { |
| $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDouble)); |
| } |
| | TOKEN_REAL { |
| $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDouble)); |
| } |
| | TOKEN_DOUBLE { |
| $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDouble)); |
| } |
| | TOKEN_FLOAT { |
| $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kFloat)); |
| } |
| | TOKEN_SMALLINT { |
| $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kInt)); |
| } |
| | TOKEN_INTEGER { |
| $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kInt)); |
| } |
| | TOKEN_BIGINT { |
| $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kLong)); |
| } |
| | TOKEN_LONG { |
| $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kLong)); |
| } |
| | TOKEN_INTERVAL { |
| /** |
| * NOTE(chasseur): This pattern exhibits a shift/reduce conflict with the |
| * TOKEN_INTERVAL case in 'literal_value'. Bison prefers to shift rather |
| * than reduce, so the case in 'literal_value' has precedence over this. |
| **/ |
| $$ = nullptr; |
| quickstep_yyerror(&@1, yyscanner, nullptr, |
| "INTERVAL is ambiguous as a column type. Specify either DATETIME INTERVAL " |
| "or YEARMONTH INTERVAL"); |
| YYERROR; |
| } |
| | TOKEN_DATETIME TOKEN_INTERVAL { |
| $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDatetimeInterval)); |
| } |
| | TOKEN_YEARMONTH TOKEN_INTERVAL { |
| $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kYearMonthInterval)); |
| } |
| | TOKEN_CHARACTER '(' TOKEN_UNSIGNED_NUMVAL ')' { |
| if ($3->float_like()) { |
| delete $3; |
| $$ = NULL; |
| quickstep_yyerror(&@3, yyscanner, nullptr, "Non-integer length supplied for CHAR type"); |
| YYERROR; |
| } else { |
| if ($3->long_value() <= 0) { |
| delete $3; |
| $$ = NULL; |
| quickstep_yyerror(&@3, yyscanner, nullptr, "Length for CHAR type must be at least 1"); |
| YYERROR; |
| } else { |
| $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kChar, $3->long_value(), false)); |
| delete $3; |
| } |
| } |
| } |
| | TOKEN_VARCHAR '(' TOKEN_UNSIGNED_NUMVAL ')' { |
| if ($3->float_like()) { |
| delete $3; |
| $$ = NULL; |
| quickstep_yyerror(&@3, yyscanner, nullptr, "Non-integer length supplied for VARCHAR type"); |
| YYERROR; |
| } else { |
| if ($3->long_value() < 0) { |
| delete $3; |
| $$ = NULL; |
| quickstep_yyerror(&@3, yyscanner, nullptr, "Negative length supplied for VARCHAR type"); |
| YYERROR; |
| } else { |
| $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kVarChar, $3->long_value(), false)); |
| delete $3; |
| } |
| } |
| }; |
| |
| column_constraint_def: |
| TOKEN_NULL { |
| $$ = new quickstep::ParseColumnConstraintNull(@1.first_line, @1.first_column); |
| } |
| | TOKEN_NOT TOKEN_NULL { |
| $$ = new quickstep::ParseColumnConstraintNotNull(@1.first_line, @1.first_column); |
| } |
| | TOKEN_UNIQUE { |
| $$ = nullptr; |
| NotSupported(&@1, yyscanner, "Column Constraints (UNIQUE)"); |
| YYERROR; |
| } |
| | TOKEN_PRIMARY TOKEN_KEY { |
| $$ = nullptr; |
| NotSupported(&@1, yyscanner, "Column Constraints (PRIMARY KEY)"); |
| YYERROR; |
| } |
| | TOKEN_DEFAULT literal_value { |
| $$ = nullptr; |
| delete $2; |
| NotSupported(&@1, yyscanner, "Column Constraints (DEFAULT)"); |
| YYERROR; |
| } |
| | TOKEN_CHECK '(' or_expression ')' { |
| $$ = nullptr; |
| delete $3; |
| NotSupported(&@1, yyscanner, "Column Constraints (CHECK)"); |
| YYERROR; |
| } |
| | TOKEN_REFERENCES any_name '(' any_name ')' { |
| $$ = nullptr; |
| delete $2; |
| delete $4; |
| NotSupported(&@1, yyscanner, "Foreign Keys"); |
| YYERROR; |
| }; |
| |
| column_constraint_def_list: |
| column_constraint_def_list column_constraint_def { |
| $$ = $1; |
| $$->push_back($2); |
| } |
| | column_constraint_def { |
| $$ = new quickstep::PtrList<quickstep::ParseColumnConstraint>(); |
| $$->push_back($1); |
| }; |
| |
| opt_column_constraint_def_list: |
| { |
| $$ = nullptr; |
| } |
| | column_constraint_def_list { |
| $$ = $1; |
| }; |
| |
| table_constraint_def: |
| TOKEN_UNIQUE '(' name_commalist ')' { |
| delete $3; |
| NotSupported(&@1, yyscanner, "Table Constraints (UNIQUE)"); |
| YYERROR; |
| } |
| | TOKEN_PRIMARY TOKEN_KEY '(' name_commalist ')' { |
| delete $4; |
| NotSupported(&@1, yyscanner, "Table Constraints (PRIMARY KEY)"); |
| YYERROR; |
| } |
| | TOKEN_FOREIGN TOKEN_KEY '(' name_commalist ')' TOKEN_REFERENCES any_name '(' name_commalist ')' { |
| delete $4; |
| delete $7; |
| delete $9; |
| NotSupported(&@1, yyscanner, "Table Constraints (FOREIGN KEY)"); |
| YYERROR; |
| } |
| | TOKEN_CHECK '(' or_expression ')' { |
| delete $3; |
| NotSupported(&@1, yyscanner, "Table Constraints (CHECK)"); |
| YYERROR; |
| }; |
| |
| table_constraint_def_commalist: |
| table_constraint_def_commalist ',' table_constraint_def { |
| NotSupported(&@1, yyscanner, "Table Constraints"); |
| YYERROR; |
| } |
| | table_constraint_def { |
| NotSupported(&@1, yyscanner, "Table Constraints"); |
| YYERROR; |
| }; |
| |
| opt_table_constraint_def_commalist: |
| { |
| /* $$ = nullptr; */ |
| } |
| | table_constraint_def_commalist { |
| /* $$ = $1; */ |
| }; |
| |
| opt_column_list: |
| { |
| $$ = nullptr; |
| } |
| | '(' attribute_ref_list ')' { |
| $$ = $2; |
| }; |
| |
| opt_block_properties: |
| { |
| $$ = nullptr; |
| } |
| | TOKEN_WITH TOKEN_BLOCKPROPERTIES '(' key_value_list ')' { |
| $$ = new quickstep::ParseBlockProperties(@2.first_line, @2.first_column, $4); |
| } |
| |
| opt_partition_clause: |
| { |
| $$ = nullptr; |
| } |
| | TOKEN_PARTITION TOKEN_BY partition_type '(' name_commalist ')' TOKEN_PARTITIONS TOKEN_UNSIGNED_NUMVAL { |
| if ($8->float_like()) { |
| delete $8; |
| $$ = NULL; |
| quickstep_yyerror(&@8, yyscanner, NULL, "NUMBER OF PARTITIONS must be an integer"); |
| YYERROR; |
| } else { |
| if ($8->long_value() <= 0 || $8->long_value() > 64) { |
| delete $8; |
| $$ = NULL; |
| quickstep_yyerror(&@8, yyscanner, NULL, "NUMBER OF PARITIONS must be between 1 and 64"); |
| YYERROR; |
| } else { |
| $$ = new quickstep::ParsePartitionClause(@1.first_line, @1.first_column, $3, $5, $8); |
| } |
| } |
| } |
| |
| partition_type: |
| TOKEN_HASH { |
| $$ = new quickstep::ParseString(@1.first_line, @1.first_column, |
| std::to_string(quickstep::PartitionSchemeHeader::PartitionType::kHash)); |
| } |
| | TOKEN_RANGE{ |
| $$ = new quickstep::ParseString(@1.first_line, @1.first_column, |
| std::to_string(quickstep::PartitionSchemeHeader::PartitionType::kRange)); |
| }; |
| |
| key_value_list: |
| key_value { |
| $$ = new quickstep::PtrList<quickstep::ParseKeyValue>(); |
| $$->push_back($1); |
| } |
| | key_value_list ',' key_value { |
| $$ = $1; |
| $$->push_back($3); |
| }; |
| |
| key_value: |
| key_string_value { |
| $$ = $1; |
| } |
| | key_string_list { |
| $$ = $1; |
| } |
| | key_integer_value { |
| $$ = $1; |
| }; |
| |
| key_string_value: |
| any_name any_name { |
| $$ = new quickstep::ParseKeyStringValue(@1.first_line, @1.first_column, $1, $2); |
| } |
| | any_name TOKEN_ALL { |
| // This is a special case to handle the COMPRESS ALL option of the BLOCK PROPERTIES. |
| $$ = new quickstep::ParseKeyStringValue(@1.first_line, @1.first_column, $1, |
| new quickstep::ParseString(@2.first_line, @2.first_column, "ALL")); |
| } |
| |
| key_string_list: |
| any_name '(' name_commalist ')' { |
| $$ = new quickstep::ParseKeyStringList(@1.first_line, @1.first_column, $1, $3); |
| }; |
| |
| key_integer_value: |
| any_name TOKEN_UNSIGNED_NUMVAL { |
| if ($2->float_like()) { |
| delete $2; |
| $$ = nullptr; |
| quickstep_yyerror(&@2, yyscanner, nullptr, "Value must be an integer"); |
| YYERROR; |
| } |
| $$ = new quickstep::ParseKeyIntegerValue(@1.first_line, @1.first_column, $1, $2); |
| }; |
| |
| index_type: |
| TOKEN_BITWEAVING { |
| // Defaults to BitWeavingV, but IndexProperties can change this to H. |
| $$ = new quickstep::ParseString(@1.first_line, @1.first_column, |
| std::to_string(quickstep::IndexSubBlockType::kBitWeavingV)); |
| } |
| | TOKEN_BLOOM_FILTER { |
| $$ = new quickstep::ParseString(@1.first_line, @1.first_column, |
| std::to_string(quickstep::IndexSubBlockType::kBloomFilter)); |
| } |
| | TOKEN_CSB_TREE { |
| $$ = new quickstep::ParseString(@1.first_line, @1.first_column, |
| std::to_string(quickstep::IndexSubBlockType::kCSBTree)); |
| } |
| | TOKEN_SMA { |
| $$ = new quickstep::ParseString(@1.first_line, @1.first_column, |
| std::to_string(quickstep::IndexSubBlockType::kSMA)); |
| }; |
| |
| opt_index_properties: |
| { |
| $$ = nullptr; |
| } |
| | '(' key_value_list ')' { |
| $$ = $2; |
| }; |
| |
| /* Update Database Contents */ |
| insert_statement: |
| TOKEN_INSERT TOKEN_INTO any_name '(' name_commalist ')' TOKEN_VALUES '(' literal_value_commalist ')' { |
| delete $3; |
| delete $5; |
| delete $9; |
| $$ = nullptr; |
| NotSupported(&@4, yyscanner, "list of column names in INSERT statement"); |
| YYERROR; |
| } |
| | TOKEN_INSERT TOKEN_INTO any_name TOKEN_VALUES '(' literal_value_commalist ')' { |
| $$ = new quickstep::ParseStatementInsertTuple(@1.first_line, @1.first_column, $3, $6); |
| } |
| | TOKEN_INSERT TOKEN_INTO any_name select_query { |
| $$ = new quickstep::ParseStatementInsertSelection(@1.first_line, @2.first_column, $3, $4, nullptr); |
| } |
| | with_clause TOKEN_INSERT TOKEN_INTO any_name select_query { |
| $$ = new quickstep::ParseStatementInsertSelection(@1.first_line, @2.first_column, $4, $5, $1); |
| } |
| ; |
| |
| copy_from_statement: |
| TOKEN_COPY any_name TOKEN_FROM TOKEN_STRING_SINGLE_QUOTED opt_copy_from_params { |
| $$ = new quickstep::ParseStatementCopyFrom(@1.first_line, @1.first_column, $2, $4, $5); |
| }; |
| |
| opt_copy_from_params: |
| { |
| $$ = nullptr; |
| } |
| | TOKEN_WITH '(' copy_from_params ')' { |
| $$ = $3; |
| }; |
| |
| copy_from_params: |
| TOKEN_DELIMITER TOKEN_STRING_SINGLE_QUOTED { |
| $$ = new quickstep::ParseCopyFromParams(@1.first_line, @1.first_column); |
| $$->set_delimiter($2); |
| } |
| | TOKEN_ESCAPE_STRINGS boolean_value { |
| $$ = new quickstep::ParseCopyFromParams(@1.first_line, @1.first_column); |
| $$->escape_strings = $2; |
| } |
| | copy_from_params ',' TOKEN_DELIMITER TOKEN_STRING_SINGLE_QUOTED { |
| $$ = $1; |
| $$->set_delimiter($4); |
| } |
| | copy_from_params ',' TOKEN_ESCAPE_STRINGS boolean_value { |
| $$ = $1; |
| $$->escape_strings = $4; |
| }; |
| |
| update_statement: |
| TOKEN_UPDATE any_name TOKEN_SET assignment_list opt_where_clause { |
| $$ = new quickstep::ParseStatementUpdate(@1.first_line, @1.first_column, $2, $4, $5); |
| }; |
| |
| delete_statement: |
| TOKEN_DELETE TOKEN_FROM any_name opt_where_clause { |
| $$ = new quickstep::ParseStatementDelete(@1.first_line, @1.first_column, $3, $4); |
| }; |
| |
| assignment_list: |
| assignment_list ',' assignment_item { |
| $$ = $1; |
| $$->push_back($3); |
| } |
| | assignment_item { |
| $$ = new quickstep::PtrList<quickstep::ParseAssignment>(); |
| $$->push_back($1); |
| }; |
| |
| assignment_item: |
| any_name TOKEN_EQ add_expression { |
| $$ = new quickstep::ParseAssignment(@1.first_line, @1.first_column, $1, $3); |
| }; |
| |
| /* Select Queries */ |
| select_statement: |
| select_query opt_priority_clause { |
| $$ = new quickstep::ParseStatementSelect(@1.first_line, @1.first_column, $1, nullptr, $2); |
| } |
| | with_clause select_query opt_priority_clause { |
| $$ = new quickstep::ParseStatementSelect(@1.first_line, @1.first_column, $2, $1, $3); |
| }; |
| |
| opt_priority_clause: |
| { |
| $$ = nullptr; |
| } |
| | TOKEN_WITH TOKEN_PRIORITY TOKEN_UNSIGNED_NUMVAL { |
| if ($3->float_like()) { |
| delete $3; |
| $$ = nullptr; |
| quickstep_yyerror(&@3, yyscanner, nullptr, "PRIORITY value must be an integer"); |
| YYERROR; |
| } else { |
| if ($3->long_value() <= 0) { |
| delete $3; |
| $$ = nullptr; |
| quickstep_yyerror(&@3, yyscanner, nullptr, "PRIORITY value must be positive"); |
| YYERROR; |
| } else { |
| $$ = new quickstep::ParsePriority(@1.first_line, @1.first_column, $3); |
| } |
| } |
| }; |
| |
| with_clause: |
| TOKEN_WITH with_list { |
| $$ = $2; |
| } |
| |
| with_list: |
| with_list_element { |
| $$ = new quickstep::PtrVector<quickstep::ParseSubqueryTableReference>(); |
| $$->push_back($1); |
| } |
| | with_list ',' with_list_element { |
| $$ = $1; |
| $$->push_back($3); |
| }; |
| |
| with_list_element: |
| table_reference_signature_primary TOKEN_AS subquery_expression { |
| $$ = new quickstep::ParseSubqueryTableReference(@1.first_line, @1.first_column, $3); |
| $$->set_table_reference_signature($1); |
| }; |
| |
| select_query: |
| TOKEN_SELECT opt_all_distinct selection from_clause opt_where_clause opt_group_by_clause opt_having_clause |
| opt_order_by_clause opt_limit_clause opt_window_clause { |
| $$ = new quickstep::ParseSelect(@1.first_line, @1.first_column, $3, $4, $5, $6, $7, $8, $9, $10); |
| }; |
| |
| opt_all_distinct: |
| { |
| /* $$ = nullptr; */ |
| } |
| | TOKEN_ALL { |
| NotSupported(&@1, yyscanner, "ALL in selection"); |
| YYERROR; |
| } |
| | TOKEN_DISTINCT { |
| NotSupported(&@1, yyscanner, "DISTINCT in selection"); |
| YYERROR; |
| }; |
| |
| selection: |
| '*' { |
| $$ = new quickstep::ParseSelectionStar(@1.first_line, @1.first_column); |
| } |
| | selection_item_commalist { |
| $$ = $1; |
| }; |
| |
| selection_item_commalist: |
| selection_item { |
| $$ = new quickstep::ParseSelectionList(@1.first_line, @1.first_column); |
| $$->add($1); |
| } |
| | selection_item_commalist ',' selection_item { |
| $$ = $1; |
| $$->add($3); |
| }; |
| |
| selection_item: |
| add_expression TOKEN_AS any_name { |
| $$ = new quickstep::ParseSelectionItem(@1.first_line, @1.first_column, $1, $3); |
| } |
| | add_expression any_name { |
| $$ = new quickstep::ParseSelectionItem(@1.first_line, @1.first_column, $1, $2); |
| } |
| | add_expression { |
| $$ = new quickstep::ParseSelectionItem(@1.first_line, @1.first_column, $1); |
| }; |
| |
| from_clause: |
| TOKEN_FROM joined_table_reference_commalist { |
| $$ = $2; |
| }; |
| |
| subquery_expression: |
| '(' select_query ')' { |
| $$ = new quickstep::ParseSubqueryExpression(@1.first_line, @1.first_column, $2); |
| }; |
| |
| opt_sample_clause: |
| { |
| $$ = NULL; |
| } |
| | TOKEN_BLOCKSAMPLE TOKEN_UNSIGNED_NUMVAL TOKEN_PERCENT { |
| $$ = new quickstep::ParseSample(@1.first_line, @1.first_column, true, $2); |
| } |
| | TOKEN_TUPLESAMPLE TOKEN_UNSIGNED_NUMVAL TOKEN_PERCENT { |
| $$ = new quickstep::ParseSample(@1.first_line, @1.first_column, false, $2); |
| }; |
| |
| join_type: |
| { |
| $$ = quickstep::ParseJoinedTableReference::JoinType::kInnerJoin; |
| } |
| | TOKEN_INNER { |
| $$ = quickstep::ParseJoinedTableReference::JoinType::kInnerJoin; |
| } |
| | TOKEN_LEFT { |
| $$ = quickstep::ParseJoinedTableReference::JoinType::kLeftOuterJoin; |
| } |
| | TOKEN_LEFT TOKEN_OUTER { |
| $$ = quickstep::ParseJoinedTableReference::JoinType::kLeftOuterJoin; |
| } |
| | TOKEN_RIGHT { |
| $$ = quickstep::ParseJoinedTableReference::JoinType::kRightOuterJoin; |
| } |
| | TOKEN_RIGHT TOKEN_OUTER { |
| $$ = quickstep::ParseJoinedTableReference::JoinType::kRightOuterJoin; |
| } |
| | TOKEN_FULL { |
| $$ = quickstep::ParseJoinedTableReference::JoinType::kFullOuterJoin; |
| } |
| | TOKEN_FULL TOKEN_OUTER { |
| $$ = quickstep::ParseJoinedTableReference::JoinType::kFullOuterJoin; |
| }; |
| |
| joined_table_reference: |
| joined_table_reference join_type TOKEN_JOIN table_reference TOKEN_ON or_expression { |
| $$ = new quickstep::ParseJoinedTableReference(@3.first_line, @3.first_column, $2, $1, $4, $6); |
| } |
| | table_reference { |
| $$ = $1; |
| }; |
| |
| table_reference: |
| subquery_expression table_reference_signature { |
| $$ = new quickstep::ParseSubqueryTableReference(@1.first_line, @1.first_column, $1); |
| $$->set_table_reference_signature($2); |
| } |
| | any_name opt_sample_clause table_reference_signature { |
| $$ = new quickstep::ParseSimpleTableReference(@1.first_line, @1.first_column, $1, $2); |
| $$->set_table_reference_signature($3); |
| } |
| | any_name opt_sample_clause { |
| $$ = new quickstep::ParseSimpleTableReference(@1.first_line, @1.first_column, $1, $2); |
| } |
| | function_call table_reference_signature { |
| $$ = new quickstep::ParseGeneratorTableReference(@1.first_line, @1.first_column, $1); |
| $$->set_table_reference_signature($2); |
| } |
| | function_call { |
| $$ = new quickstep::ParseGeneratorTableReference(@1.first_line, @1.first_column, $1); |
| } |
| | '(' joined_table_reference ')' { |
| $$ = $2; |
| }; |
| |
| table_reference_signature: |
| table_reference_signature_primary { |
| $$ = $1; |
| } |
| | TOKEN_AS table_reference_signature_primary { |
| $$ = $2; |
| }; |
| |
| table_reference_signature_primary: |
| any_name { |
| $$ = new ::quickstep::ParseTableReferenceSignature(@1.first_line, @1.first_column, $1); |
| } |
| | any_name '(' name_commalist ')' { |
| $$ = new ::quickstep::ParseTableReferenceSignature(@1.first_line, @1.first_column, $1, $3); |
| }; |
| |
| joined_table_reference_commalist: |
| joined_table_reference { |
| $$ = new quickstep::PtrList<quickstep::ParseTableReference>(); |
| $$->push_back($1); |
| } |
| | joined_table_reference_commalist ',' joined_table_reference { |
| $$ = $1; |
| $$->push_back($3); |
| }; |
| |
| opt_group_by_clause: |
| { |
| $$ = nullptr; |
| } |
| | TOKEN_GROUP TOKEN_BY expression_list { |
| $$ = new quickstep::ParseGroupBy(@1.first_line, @1.first_column, $3); |
| }; |
| |
| opt_having_clause: |
| { |
| $$ = nullptr; |
| } |
| | TOKEN_HAVING or_expression { |
| $$ = new quickstep::ParseHaving(@1.first_line, @1.first_column, $2); |
| }; |
| |
| opt_order_by_clause: |
| { |
| $$ = nullptr; |
| } |
| | TOKEN_ORDER TOKEN_BY order_commalist { |
| $$ = new quickstep::ParseOrderBy(@1.first_line, @1.first_column, $3); |
| }; |
| |
| opt_limit_clause: |
| { |
| $$ = nullptr; |
| } |
| | TOKEN_LIMIT TOKEN_UNSIGNED_NUMVAL { |
| if ($2->float_like()) { |
| delete $2; |
| $$ = nullptr; |
| quickstep_yyerror(&@2, yyscanner, nullptr, "LIMIT value must be an integer"); |
| YYERROR; |
| } else { |
| if ($2->long_value() <= 0) { |
| delete $2; |
| $$ = nullptr; |
| quickstep_yyerror(&@2, yyscanner, nullptr, "LIMIT value must be positive"); |
| YYERROR; |
| } else { |
| $$ = new quickstep::ParseLimit(@1.first_line, @1.first_column, $2); |
| } |
| } |
| } |
| |
| opt_window_clause: |
| { |
| $$ = nullptr; |
| } |
| | window_declaration_list { |
| $$ = $1; |
| } |
| |
| window_declaration_list: |
| window_declaration { |
| $$ = new quickstep::PtrList<quickstep::ParseWindow>(); |
| $$->push_back($1); |
| } |
| | window_declaration_list window_declaration { |
| $$ = $1; |
| $$->push_back($2); |
| } |
| |
| window_declaration: |
| TOKEN_WINDOW any_name TOKEN_AS '(' window_definition ')' { |
| $$ = $5; |
| $$->setName($2); |
| } |
| |
| window_definition: |
| opt_window_partition opt_window_order opt_window_frame { |
| $$ = new quickstep::ParseWindow(@1.first_line, @1.first_column, $1, $2, $3); |
| }; |
| |
| opt_window_partition: |
| { |
| $$ = nullptr; |
| } |
| | TOKEN_PARTITION TOKEN_BY expression_list { |
| $$ = $3; |
| }; |
| |
| opt_window_order: |
| { |
| $$ = nullptr; |
| } |
| | TOKEN_ORDER TOKEN_BY order_commalist { |
| $$ = $3; |
| }; |
| |
| opt_window_frame: |
| { |
| $$ = nullptr; |
| } |
| | frame_mode TOKEN_BETWEEN frame_preceding TOKEN_AND frame_following { |
| $$ = new quickstep::ParseFrameInfo(@1.first_line, @1.first_column, $1, $3->long_value(), $5->long_value()); |
| }; |
| |
| frame_mode: |
| TOKEN_ROWS { |
| $$ = true; |
| } |
| | TOKEN_RANGE { |
| $$ = false; |
| }; |
| |
| frame_preceding: |
| TOKEN_UNSIGNED_NUMVAL TOKEN_PRECEDING |
| | TOKEN_UNBOUNDED TOKEN_PRECEDING { |
| $$ = new quickstep::NumericParseLiteralValue(@1.first_line, @1.first_column, "-1"); |
| } |
| | TOKEN_CURRENT TOKEN_ROW { |
| $$ = new quickstep::NumericParseLiteralValue(@1.first_line, @1.first_column, "0"); |
| }; |
| |
| frame_following: |
| TOKEN_UNSIGNED_NUMVAL TOKEN_FOLLOWING |
| | TOKEN_UNBOUNDED TOKEN_FOLLOWING { |
| $$ = new quickstep::NumericParseLiteralValue(@1.first_line, @1.first_column, "-1"); |
| } |
| | TOKEN_CURRENT TOKEN_ROW { |
| $$ = new quickstep::NumericParseLiteralValue(@1.first_line, @1.first_column, "0"); |
| }; |
| |
| order_commalist: |
| order_item { |
| $$ = new quickstep::PtrList<quickstep::ParseOrderByItem>(); |
| $$->push_back($1); |
| } |
| | order_commalist ',' order_item { |
| $$ = $1; |
| $$->push_back($3); |
| }; |
| |
| order_item: |
| add_expression opt_order_direction opt_nulls_first { |
| $$ = new quickstep::ParseOrderByItem(@1.first_line, @1.first_column, $1, $2, $3); |
| delete $2; |
| delete $3; |
| }; |
| |
| opt_order_direction: |
| { |
| $$ = nullptr; |
| } |
| | TOKEN_ASC { |
| $$ = new bool(true); |
| } |
| | TOKEN_DESC { |
| $$ = new bool(false); |
| }; |
| |
| opt_nulls_first: |
| { |
| $$ = nullptr; |
| } |
| | TOKEN_NULLS TOKEN_FIRST { |
| $$ = new bool(true); |
| } |
| | TOKEN_NULLS TOKEN_LAST { |
| $$ = new bool(false); |
| }; |
| |
| /* Predicates */ |
| opt_where_clause: |
| { |
| $$ = nullptr; |
| } |
| | where_clause { |
| $$ = $1; |
| }; |
| |
| where_clause: |
| TOKEN_WHERE or_expression { |
| $$ = $2; |
| }; |
| |
| or_expression: |
| or_expression TOKEN_OR and_expression { |
| if ($1->getParsePredicateType() == quickstep::ParsePredicate::kDisjunction) { |
| $$ = $1; |
| } else { |
| $$ = new quickstep::ParsePredicateDisjunction(@1.first_line, @1.first_column); |
| static_cast<quickstep::ParsePredicateDisjunction *>($$)->addPredicate($1); |
| } |
| static_cast<quickstep::ParsePredicateDisjunction *>($$)->addPredicate($3); |
| } |
| | and_expression { |
| $$ = $1; |
| }; |
| |
| and_expression: |
| and_expression TOKEN_AND not_expression { |
| if ($1->getParsePredicateType() == quickstep::ParsePredicate::kConjunction) { |
| $$ = $1; |
| } else { |
| $$ = new quickstep::ParsePredicateConjunction(@1.first_line, @1.first_column); |
| static_cast<quickstep::ParsePredicateConjunction *>($$)->addPredicate($1); |
| } |
| static_cast<quickstep::ParsePredicateConjunction *>($$)->addPredicate($3); |
| } |
| | not_expression { |
| $$ = $1; |
| }; |
| |
| not_expression: |
| TOKEN_NOT predicate_expression_base { |
| $$ = new quickstep::ParsePredicateNegation(@1.first_line, @1.first_column, $2); |
| } |
| | predicate_expression_base { |
| $$ = $1; |
| }; |
| |
| predicate_expression_base: |
| add_expression TOKEN_BETWEEN add_expression TOKEN_AND add_expression { |
| $$ = new quickstep::ParsePredicateBetween(@2.first_line, @2.first_column, $1, $3, $5); |
| } |
| | add_expression TOKEN_NOT TOKEN_BETWEEN add_expression TOKEN_AND add_expression { |
| $$ = new quickstep::ParsePredicateNegation( |
| @2.first_line, @2.first_column, |
| new quickstep::ParsePredicateBetween(@3.first_line, @3.first_column, $1, $4, $6)); |
| } |
| | attribute_ref TOKEN_IS TOKEN_NOT TOKEN_NULL { |
| delete $1; |
| $$ = nullptr; |
| NotSupported(&@2, yyscanner, "NULL comparison predicates"); |
| YYERROR; |
| } |
| | attribute_ref TOKEN_IS TOKEN_NULL { |
| delete $1; |
| $$ = nullptr; |
| NotSupported(&@2, yyscanner, "NULL comparison predicates"); |
| YYERROR; |
| } |
| | add_expression comparison_operation add_expression { |
| $$ = new quickstep::ParsePredicateComparison(@2.first_line, @2.first_column, *$2, $1, $3); |
| } |
| | '(' or_expression ')' { |
| $$ = $2; |
| } |
| | TOKEN_EXISTS subquery_expression { |
| $$ = new quickstep::ParsePredicateExists(@1.first_line, @1.first_column, $2); |
| } |
| | add_expression TOKEN_IN subquery_expression { |
| $$ = new quickstep::ParsePredicateInTableQuery(@2.first_line, @2.first_column, $1, $3); |
| } |
| | add_expression TOKEN_IN '(' expression_list ')' { |
| $$ = new quickstep::ParsePredicateInValueList(@2.first_line, @2.first_column, $1, $4); |
| } |
| | add_expression TOKEN_NOT TOKEN_IN subquery_expression { |
| $$ = new quickstep::ParsePredicateNegation( |
| @2.first_line, |
| @2.first_column, |
| new quickstep::ParsePredicateInTableQuery(@3.first_line, @3.first_column, $1, $4)); |
| } |
| | add_expression TOKEN_NOT TOKEN_IN '(' expression_list ')' { |
| $$ = new quickstep::ParsePredicateNegation( |
| @2.first_line, |
| @2.first_column, |
| new quickstep::ParsePredicateInValueList(@3.first_line, @3.first_column, $1, $5)); |
| }; |
| |
| /* Scalars */ |
| add_expression: |
| add_expression add_operation multiply_expression { |
| $$ = new quickstep::ParseBinaryExpression(@2.first_line, @2.first_column, *$2, $1, $3); |
| } |
| | multiply_expression { |
| $$ = $1; |
| }; |
| |
| multiply_expression: |
| multiply_expression multiply_operation unary_expression { |
| $$ = new quickstep::ParseBinaryExpression(@2.first_line, @2.first_column, *$2, $1, $3); |
| } |
| | unary_expression { |
| $$ = $1; |
| }; |
| |
| unary_expression: |
| unary_operation expression_base { |
| $$ = new quickstep::ParseUnaryExpression(@1.first_line, @1.first_column, *$1, $2); |
| } |
| | expression_base { |
| $$ = $1; |
| }; |
| |
| expression_base: |
| attribute_ref { |
| $$ = $1; |
| } |
| | literal_value { |
| $$ = new quickstep::ParseScalarLiteral($1); |
| } |
| | function_call { |
| $$ = $1; |
| } |
| | function_call TOKEN_OVER any_name { |
| $1->setWindowName($3); |
| $$ = $1; |
| } |
| | function_call TOKEN_OVER '(' window_definition ')' { |
| $1->setWindow($4); |
| $$ = $1; |
| } |
| | extract_function { |
| $$ = $1; |
| } |
| | substr_function { |
| $$ = $1; |
| } |
| | case_expression { |
| $$ = $1; |
| } |
| | '(' add_expression ')' { |
| $$ = $2; |
| } |
| | subquery_expression { |
| $$ = $1; |
| }; |
| |
| function_call: |
| any_name '(' ')' { |
| $$ = new quickstep::ParseFunctionCall( |
| @1.first_line, @1.first_column, false, $1, new quickstep::PtrList<quickstep::ParseExpression>()); |
| } |
| | any_name '(' '*' ')' { |
| $$ = new quickstep::ParseFunctionCall( |
| @1.first_line, @1.first_column, $1, new quickstep::ParseStar(@3.first_line, @3.first_column)); |
| } |
| | any_name '(' expression_list ')' { |
| $$ = new quickstep::ParseFunctionCall(@1.first_line, @1.first_column, false, $1, $3); |
| }; |
| | any_name '(' TOKEN_DISTINCT expression_list ')' { |
| $$ = new quickstep::ParseFunctionCall(@1.first_line, @1.first_column, true, $1, $4); |
| }; |
| |
| extract_function: |
| TOKEN_EXTRACT '(' datetime_unit TOKEN_FROM add_expression ')' { |
| $$ = new quickstep::ParseExtractFunction(@1.first_line, @1.first_column, $3, $5); |
| }; |
| |
| substr_function: |
| TOKEN_SUBSTRING '(' add_expression TOKEN_FROM TOKEN_UNSIGNED_NUMVAL ')' { |
| $$ = new quickstep::ParseSubstringFunction( |
| @1.first_line, @1.first_column, $3, $5->long_value()); |
| } |
| | TOKEN_SUBSTRING '(' add_expression TOKEN_FROM TOKEN_UNSIGNED_NUMVAL TOKEN_FOR TOKEN_UNSIGNED_NUMVAL ')' { |
| $$ = new quickstep::ParseSubstringFunction( |
| @1.first_line, @1.first_column, $3, $5->long_value(), $7->long_value()); |
| }; |
| |
| case_expression: |
| TOKEN_CASE add_expression simple_when_clause_list opt_else_clause TOKEN_END { |
| $$ = new quickstep::ParseSimpleCaseExpression(@1.first_line, @1.first_column, $2, $3, $4); |
| } |
| | TOKEN_CASE searched_when_clause_list opt_else_clause TOKEN_END { |
| $$ = new quickstep::ParseSearchedCaseExpression(@1.first_line, @1.first_column, $2, $3); |
| }; |
| |
| simple_when_clause_list: |
| simple_when_clause { |
| $$ = new quickstep::PtrVector<quickstep::ParseSimpleWhenClause>; |
| $$->push_back($1); |
| } |
| | simple_when_clause_list simple_when_clause { |
| $$ = $1; |
| $$->push_back($2); |
| }; |
| |
| simple_when_clause: |
| TOKEN_WHEN add_expression TOKEN_THEN add_expression { |
| $$ = new quickstep::ParseSimpleWhenClause(@1.first_line, @1.first_column, $2, $4); |
| }; |
| |
| searched_when_clause_list: |
| searched_when_clause { |
| $$ = new quickstep::PtrVector<quickstep::ParseSearchedWhenClause>; |
| $$->push_back($1); |
| } |
| | searched_when_clause_list searched_when_clause { |
| $$ = $1; |
| $$->push_back($2); |
| }; |
| |
| searched_when_clause: |
| TOKEN_WHEN or_expression TOKEN_THEN add_expression { |
| $$ = new quickstep::ParseSearchedWhenClause(@1.first_line, @1.first_column, $2, $4); |
| }; |
| |
| opt_else_clause: |
| { |
| $$ = NULL; |
| } |
| | TOKEN_ELSE add_expression { |
| $$ = $2; |
| }; |
| |
| expression_list: |
| add_expression { |
| $$ = new quickstep::PtrList<quickstep::ParseExpression>(); |
| $$->push_back($1); |
| } |
| | expression_list ',' add_expression { |
| $$ = $1; |
| $$->push_back($3); |
| }; |
| |
| literal_value: |
| TOKEN_NULL { |
| $$ = new quickstep::NullParseLiteralValue(@1.first_line, @1.first_column); |
| } |
| | TOKEN_UNSIGNED_NUMVAL { |
| $$ = $1; |
| } |
| | '+' TOKEN_UNSIGNED_NUMVAL %prec UNARY_PLUS { |
| $$ = $2; |
| } |
| | '-' TOKEN_UNSIGNED_NUMVAL %prec UNARY_MINUS { |
| /** |
| * NOTE(chasseur): This case exhibits a shift/reduce conflict with the |
| * minus character as a 'unary_operation' followed by a numeric literal. |
| * Because Bison prefers to shift rather than reduce, this case has |
| * precedence (i.e. the parser will prefer to interpret the ambiguous |
| * pattern as a negative number literal rather than a unary minus operation |
| * applied to a non-negative number literal). |
| **/ |
| $2->prependMinus(); |
| $$ = $2; |
| } |
| | TOKEN_STRING_SINGLE_QUOTED { |
| $$ = new quickstep::StringParseLiteralValue($1, |
| nullptr); // No explicit type. |
| } |
| | TOKEN_INTERVAL TOKEN_STRING_SINGLE_QUOTED { |
| /** |
| * NOTE(chasseur): This case exhibits a shift/reduce conflict with the |
| * plain TOKEN_INTERVAL case in 'data_type' reduced and used in the case |
| * below. Because Bison prefers to shift rather than reduce, this case has |
| * precedence (i.e. the special |
| * StringParseLiteralValue::ParseAmbiguousInterval() method will be used to |
| * parse the string as either one of the interval types, rather than an |
| * error being emitted because of an ambiguous type). |
| **/ |
| quickstep::StringParseLiteralValue *parse_value; |
| if (quickstep::StringParseLiteralValue::ParseAmbiguousInterval($2, &parse_value)) { |
| $$ = parse_value; |
| } else { |
| $$ = nullptr; |
| quickstep_yyerror(&@2, yyscanner, nullptr, "Failed to parse literal as specified type"); |
| YYERROR; |
| } |
| } |
| | TOKEN_INTERVAL TOKEN_STRING_SINGLE_QUOTED datetime_unit { |
| quickstep::StringParseLiteralValue *parse_value; |
| const std::string &datetime_type_value = $3->value(); |
| if (quickstep::StringParseLiteralValue::ParseAmbiguousInterval( |
| &($2->append((" " + datetime_type_value).c_str(), datetime_type_value.length() + 1)), |
| &parse_value)) { |
| $$ = parse_value; |
| } else { |
| $$ = nullptr; |
| quickstep_yyerror(&@3, yyscanner, nullptr, "Failed to parse literal as specified type"); |
| YYERROR; |
| } |
| } |
| | data_type TOKEN_STRING_SINGLE_QUOTED { |
| quickstep::StringParseLiteralValue *parse_value |
| = new quickstep::StringParseLiteralValue($2, &($1->getType())); |
| delete $1; |
| if (!parse_value->tryExplicitTypeParse()) { |
| delete parse_value; |
| $$ = nullptr; |
| quickstep_yyerror(&@2, yyscanner, nullptr, "Failed to parse literal as specified type"); |
| YYERROR; |
| } else { |
| $$ = parse_value; |
| } |
| } |
| |
| datetime_unit: |
| TOKEN_YEAR { |
| $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("YEAR")); |
| } |
| | TOKEN_MONTH { |
| $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("MONTH")); |
| } |
| | TOKEN_DAY { |
| $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("DAY")); |
| } |
| | TOKEN_HOUR { |
| $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("HOUR")); |
| } |
| | TOKEN_MINUTE { |
| $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("MINUTE")); |
| } |
| | TOKEN_SECOND { |
| $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("SECOND")); |
| }; |
| |
| literal_value_commalist: |
| literal_value { |
| $$ = new quickstep::PtrList<quickstep::ParseScalarLiteral>(); |
| $$->push_back(new quickstep::ParseScalarLiteral($1)); |
| } |
| | literal_value_commalist ',' literal_value { |
| $$ = $1; |
| $$->push_back(new quickstep::ParseScalarLiteral($3)); |
| }; |
| |
| attribute_ref: |
| any_name { |
| $$ = new quickstep::ParseAttribute(@1.first_line, @1.first_column, $1); |
| } |
| | any_name '.' any_name { |
| $$ = new quickstep::ParseAttribute(@1.first_line, @1.first_column, $3, $1); |
| }; |
| |
| attribute_ref_list: |
| attribute_ref { |
| $$ = new quickstep::PtrList<quickstep::ParseAttribute>(); |
| $$->push_back($1); |
| } |
| | attribute_ref_list ',' attribute_ref { |
| $$ = $1; |
| $$->push_back($3); |
| } |
| |
| /* Operations from libtypes */ |
| comparison_operation: |
| TOKEN_EQ { |
| $$ = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kEqual); |
| } |
| | TOKEN_NEQ { |
| $$ = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kNotEqual); |
| } |
| | TOKEN_LT { |
| $$ = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kLess); |
| } |
| | TOKEN_LEQ { |
| $$ = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kLessOrEqual); |
| } |
| | TOKEN_GT { |
| $$ = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kGreater); |
| } |
| | TOKEN_GEQ { |
| $$ = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kGreaterOrEqual); |
| } |
| | TOKEN_LIKE { |
| $$ = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kLike); |
| } |
| | TOKEN_NOT TOKEN_LIKE { |
| $$ = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kNotLike); |
| } |
| | TOKEN_REGEXP { |
| $$ = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kRegexMatch); |
| } |
| | TOKEN_NOT TOKEN_REGEXP { |
| $$ = &quickstep::ComparisonFactory::GetComparison(quickstep::ComparisonID::kNotRegexMatch); |
| }; |
| |
| unary_operation: |
| '-' %prec UNARY_MINUS { |
| /** |
| * NOTE(chasseur): This case exhibits a shift/reduce conflict with the |
| * '-' TOKEN_UNSIGNED_NUMVAL case in 'literal_value'. Because Bison prefers |
| * to shift rather than reduce, the case in 'literal_value' has precedence |
| * over this one. |
| **/ |
| $$ = &quickstep::UnaryOperationFactory::GetUnaryOperation(quickstep::UnaryOperationID::kNegate); |
| }; |
| |
| add_operation: |
| '+' { |
| $$ = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kAdd); |
| } |
| | '-' { |
| $$ = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kSubtract); |
| }; |
| |
| multiply_operation: |
| '%' { |
| $$ = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kModulo); |
| } |
| | '*' { |
| $$ = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kMultiply); |
| } |
| | '/' { |
| $$ = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kDivide); |
| }; |
| |
| /* General Utility Stuff */ |
| name_commalist: |
| any_name { |
| $$ = new quickstep::PtrList<quickstep::ParseString>(); |
| $$->push_back($1); |
| } |
| | name_commalist ',' any_name { |
| $$ = $1; |
| $$->push_back($3); |
| }; |
| |
| any_name: |
| TOKEN_NAME { |
| $$ = $1; |
| } |
| | TOKEN_STRING_DOUBLE_QUOTED { |
| if ($1->value().empty()) { |
| quickstep_yyerror(&@1, yyscanner, nullptr, "Zero-length identifier"); |
| } |
| $$ = $1; |
| }; |
| |
| boolean_value: |
| TOKEN_TRUE { |
| $$ = true; |
| } |
| | TOKEN_ON { |
| $$ = true; |
| } |
| | TOKEN_FALSE { |
| $$ = false; |
| } |
| | TOKEN_OFF { |
| $$ = false; |
| }; |
| |
| /* Command Statments */ |
| command: |
| TOKEN_COMMAND command_argument_list { |
| $$ = new quickstep::ParseCommand(@1.first_line, @1.first_column, $1, $2); |
| }; |
| |
| command_argument_list: |
| command_argument_list TOKEN_COMMAND { |
| quickstep::PtrVector<quickstep::ParseString> *argument_list = $1; |
| argument_list->push_back($2); |
| $$ = argument_list; |
| } |
| | { /* Epsilon, an empy match. */ |
| $$ = new quickstep::PtrVector<quickstep::ParseString>(); |
| } |
| |
| %% |
| |
| void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string &feature) { |
| std::string msg; |
| msg.append(feature); |
| msg.append(" is not supported yet"); |
| |
| quickstep_yyerror(location, yyscanner, nullptr, msg.c_str()); |
| } |
| |
| int quickstep_yyget_line_number(const YYLTYPE *yyloc) { |
| return yyloc->first_line; |
| } |
| |
| int quickstep_yyget_column_number(const YYLTYPE *yyloc) { |
| return yyloc->first_column; |
| } |