blob: 5db217116264b077024d554d6d0987b8e88c1cf5 [file] [log] [blame]
/**
* 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/ParseSetOperation.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::ParseSetOperation *set_operation_;
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::ParseStatementSetOperation *set_operation_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 '.'
%left TOKEN_ALL TOKEN_UNION TOKEN_INTERSECT
%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_INTERSECT;
%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_UNION;
%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
opt_all_distinct
%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 <set_operation_statement_>
set_operation_statement
%type <set_operation_>
set_operation_union
set_operation_intersect
%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>
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;
}
| set_operation_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, quickstep::kHashPartitionType);
}
| TOKEN_RANGE{
$$ = new quickstep::ParseString(@1.first_line, @1.first_column, quickstep::kRangePartitionType);
};
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);
};
/**
* Set Operation Queries.
* Select Queries are now included in set operations.
**/
set_operation_statement:
set_operation_union opt_priority_clause {
$$ = new quickstep::ParseStatementSetOperation(@1.first_line, @1.first_column, $1, nullptr, $2);
}
| with_clause set_operation_union opt_priority_clause {
$$ = new quickstep::ParseStatementSetOperation(@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);
};
set_operation_union:
set_operation_union TOKEN_UNION opt_all_distinct set_operation_intersect {
if ($3) {
$$ = new quickstep::ParseSetOperation(@1.first_line, @1.first_column, quickstep::ParseSetOperation::kUnion);
} else {
$$ = new quickstep::ParseSetOperation(@1.first_line, @1.first_column, quickstep::ParseSetOperation::kUnionAll);
}
$$->addOperand($1);
$$->addOperand($4);
}
| set_operation_intersect {
$$ = $1;
}
set_operation_intersect:
set_operation_intersect TOKEN_INTERSECT select_query {
$$ = new quickstep::ParseSetOperation(@1.first_line, @1.first_column, quickstep::ParseSetOperation::kIntersect);
quickstep::ParseSetOperation *op = new quickstep::ParseSetOperation(
@3.first_line, @3.first_column, quickstep::ParseSetOperation::kSelect);
op->addOperand($3);
$$->addOperand($1);
$$->addOperand(op);
}
| select_query {
$$ = new quickstep::ParseSetOperation(@1.first_line, @1.first_column, quickstep::ParseSetOperation::kSelect);
$$->addOperand($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:
{
$$ = true; // Distinct
}
| TOKEN_ALL {
$$ = false; // All
}
| TOKEN_DISTINCT {
$$ = true; // Distinct
};
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:
'(' set_operation_union ')' {
$$ = 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;
}