ClickHouse/src/Parsers/ExpressionListParsers.cpp

2578 lines
78 KiB
C++
Raw Normal View History

2021-10-31 15:11:46 +00:00
#include <string_view>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/ParserSetQuery.h>
2021-06-03 02:19:07 +00:00
#include <Parsers/ASTAsterisk.h>
#include <Parsers/ASTExpressionList.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTFunctionWithKeyValueArguments.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTLiteral.h>
2021-06-03 02:19:07 +00:00
#include <Parsers/ASTSelectQuery.h>
#include <Parsers/ASTSetQuery.h>
#include <Parsers/ASTSelectWithUnionQuery.h>
2021-06-03 02:19:07 +00:00
#include <Parsers/ASTSubquery.h>
#include <Parsers/ASTTablesInSelectQuery.h>
#include <Parsers/ParserCreateQuery.h>
2021-08-14 12:31:55 +00:00
#include <Parsers/ParserUnionQueryElement.h>
#include <Parsers/parseIntervalKind.h>
#include <Common/StringUtils/StringUtils.h>
2022-04-08 03:30:49 +00:00
#include <Parsers/ParserSelectWithUnionQuery.h>
#include <Common/logger_useful.h>
2022-04-12 15:03:10 +00:00
#include <Parsers/queryToString.h>
2022-02-24 13:54:30 +00:00
2021-10-31 15:11:46 +00:00
using namespace std::literals;
2010-06-24 19:12:10 +00:00
namespace DB
2021-06-01 23:18:15 +00:00
{
2011-08-18 18:48:00 +00:00
2022-06-29 21:51:58 +00:00
namespace ErrorCodes
{
extern const int SYNTAX_ERROR;
}
bool ParserList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
2011-08-18 18:48:00 +00:00
{
ASTs elements;
auto parse_element = [&]
{
ASTPtr element;
if (!elem_parser->parse(pos, element, expected))
return false;
elements.push_back(element);
return true;
};
if (!parseUtil(pos, expected, parse_element, *separator_parser, allow_empty))
return false;
auto list = std::make_shared<ASTExpressionList>(result_separator);
list->children = std::move(elements);
node = list;
2020-11-02 06:05:53 +00:00
return true;
2011-08-18 18:48:00 +00:00
}
2020-10-26 09:33:34 +00:00
bool ParserUnionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
2021-08-14 12:31:55 +00:00
ParserUnionQueryElement elem_parser;
ParserKeyword s_union_parser("UNION");
ParserKeyword s_all_parser("ALL");
ParserKeyword s_distinct_parser("DISTINCT");
ParserKeyword s_except_parser("EXCEPT");
ParserKeyword s_intersect_parser("INTERSECT");
2020-10-26 09:33:34 +00:00
ASTs elements;
auto parse_element = [&]
{
ASTPtr element;
2021-08-14 12:31:55 +00:00
if (!elem_parser.parse(pos, element, expected))
2020-10-26 09:33:34 +00:00
return false;
elements.push_back(element);
return true;
};
2022-08-30 10:09:01 +00:00
/// Parse UNION / INTERSECT / EXCEPT mode
/// The mode can be DEFAULT (unspecified) / DISTINCT / ALL
2020-10-26 09:33:34 +00:00
auto parse_separator = [&]
{
2021-08-14 12:31:55 +00:00
if (s_union_parser.ignore(pos, expected))
2020-10-26 09:33:34 +00:00
{
2021-08-14 12:31:55 +00:00
if (s_all_parser.check(pos, expected))
2022-08-30 10:09:01 +00:00
union_modes.push_back(SelectUnionMode::UNION_ALL);
2021-08-14 12:31:55 +00:00
else if (s_distinct_parser.check(pos, expected))
2022-08-30 10:09:01 +00:00
union_modes.push_back(SelectUnionMode::UNION_DISTINCT);
2020-10-26 09:33:34 +00:00
else
2022-08-30 10:09:01 +00:00
union_modes.push_back(SelectUnionMode::UNION_DEFAULT);
2021-08-13 09:57:15 +00:00
return true;
}
2021-08-14 12:31:55 +00:00
else if (s_except_parser.check(pos, expected))
2021-08-13 09:57:15 +00:00
{
2022-08-30 10:09:01 +00:00
if (s_all_parser.check(pos, expected))
union_modes.push_back(SelectUnionMode::EXCEPT_ALL);
else if (s_distinct_parser.check(pos, expected))
union_modes.push_back(SelectUnionMode::EXCEPT_DISTINCT);
else
union_modes.push_back(SelectUnionMode::EXCEPT_DEFAULT);
2020-10-26 09:33:34 +00:00
return true;
}
2021-08-14 12:31:55 +00:00
else if (s_intersect_parser.check(pos, expected))
{
2022-08-30 10:09:01 +00:00
if (s_all_parser.check(pos, expected))
union_modes.push_back(SelectUnionMode::INTERSECT_ALL);
else if (s_distinct_parser.check(pos, expected))
union_modes.push_back(SelectUnionMode::INTERSECT_DISTINCT);
else
union_modes.push_back(SelectUnionMode::INTERSECT_DEFAULT);
2021-08-14 12:31:55 +00:00
return true;
}
2020-10-26 09:33:34 +00:00
return false;
};
if (!parseUtil(pos, parse_element, parse_separator))
return false;
2020-10-28 01:29:09 +00:00
auto list = std::make_shared<ASTExpressionList>();
2020-10-26 09:33:34 +00:00
list->children = std::move(elements);
node = list;
return true;
}
2011-08-18 18:48:00 +00:00
static bool parseOperator(IParser::Pos & pos, const char * op, Expected & expected)
{
if (isWordCharASCII(*op))
{
return ParserKeyword(op).ignore(pos, expected);
}
else
{
if (strlen(op) == pos->size() && 0 == memcmp(op, pos->begin, pos->size()))
{
++pos;
return true;
}
return false;
}
}
2021-06-03 02:19:07 +00:00
enum class SubqueryFunctionType
{
NONE,
ANY,
ALL
};
2021-08-14 17:04:21 +00:00
static bool modifyAST(ASTPtr ast, SubqueryFunctionType type)
2021-06-03 02:19:07 +00:00
{
2021-08-14 17:04:21 +00:00
/* Rewrite in AST:
* = ANY --> IN
* != ALL --> NOT IN
* = ALL --> IN (SELECT singleValueOrNull(*) FROM subquery)
* != ANY --> NOT IN (SELECT singleValueOrNull(*) FROM subquery)
**/
auto * function = assert_cast<ASTFunction *>(ast.get());
String operator_name = function->name;
auto function_equals = operator_name == "equals";
auto function_not_equals = operator_name == "notEquals";
String aggregate_function_name;
if (function_equals || function_not_equals)
2021-06-03 02:19:07 +00:00
{
if (operator_name == "notEquals")
2021-08-14 17:04:21 +00:00
function->name = "notIn";
else
function->name = "in";
if ((type == SubqueryFunctionType::ANY && function_equals)
|| (type == SubqueryFunctionType::ALL && function_not_equals))
2021-06-03 02:19:07 +00:00
{
2021-08-14 17:04:21 +00:00
return true;
2021-06-03 02:19:07 +00:00
}
2021-08-14 17:04:21 +00:00
aggregate_function_name = "singleValueOrNull";
}
else if (operator_name == "greaterOrEquals" || operator_name == "greater")
{
aggregate_function_name = (type == SubqueryFunctionType::ANY ? "min" : "max");
2021-06-03 02:19:07 +00:00
}
2021-08-14 17:04:21 +00:00
else if (operator_name == "lessOrEquals" || operator_name == "less")
{
aggregate_function_name = (type == SubqueryFunctionType::ANY ? "max" : "min");
}
else
return false;
2021-06-03 02:19:07 +00:00
2021-08-14 17:04:21 +00:00
/// subquery --> (SELECT aggregate_function(*) FROM subquery)
auto aggregate_function = makeASTFunction(aggregate_function_name, std::make_shared<ASTAsterisk>());
auto subquery_node = function->children[0]->children[1];
2021-06-03 02:19:07 +00:00
auto table_expression = std::make_shared<ASTTableExpression>();
2021-08-14 17:04:21 +00:00
table_expression->subquery = std::move(subquery_node);
table_expression->children.push_back(table_expression->subquery);
auto tables_in_select_element = std::make_shared<ASTTablesInSelectQueryElement>();
tables_in_select_element->table_expression = std::move(table_expression);
tables_in_select_element->children.push_back(tables_in_select_element->table_expression);
auto tables_in_select = std::make_shared<ASTTablesInSelectQuery>();
tables_in_select->children.push_back(std::move(tables_in_select_element));
2021-06-03 02:19:07 +00:00
auto select_exp_list = std::make_shared<ASTExpressionList>();
select_exp_list->children.push_back(aggregate_function);
2021-08-14 17:04:21 +00:00
auto select_query = std::make_shared<ASTSelectQuery>();
2021-06-03 02:19:07 +00:00
select_query->children.push_back(select_exp_list);
select_query->children.push_back(tables_in_select);
2021-08-14 17:04:21 +00:00
select_query->setExpression(ASTSelectQuery::Expression::SELECT, select_exp_list);
select_query->setExpression(ASTSelectQuery::Expression::TABLES, tables_in_select);
2021-06-03 02:19:07 +00:00
auto select_with_union_query = std::make_shared<ASTSelectWithUnionQuery>();
2021-08-14 17:04:21 +00:00
select_with_union_query->list_of_selects = std::make_shared<ASTExpressionList>();
select_with_union_query->list_of_selects->children.push_back(std::move(select_query));
2021-06-03 02:19:07 +00:00
select_with_union_query->children.push_back(select_with_union_query->list_of_selects);
auto new_subquery = std::make_shared<ASTSubquery>();
new_subquery->children.push_back(select_with_union_query);
2021-08-14 17:04:21 +00:00
ast->children[0]->children.back() = std::move(new_subquery);
2021-06-03 02:19:07 +00:00
2021-08-14 17:04:21 +00:00
return true;
2021-06-03 02:19:07 +00:00
}
2021-08-15 06:55:43 +00:00
bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
2021-06-03 02:19:07 +00:00
{
bool first = true;
auto current_depth = pos.depth;
while (true)
{
if (first)
{
ASTPtr elem;
2021-08-15 06:55:43 +00:00
if (!first_elem_parser->parse(pos, elem, expected))
2021-06-03 02:19:07 +00:00
return false;
node = elem;
first = false;
}
else
{
/// try to find any of the valid operators
2021-08-15 06:55:43 +00:00
2021-06-03 02:19:07 +00:00
const char ** it;
Expected stub;
for (it = overlapping_operators_to_skip; *it; ++it)
if (ParserKeyword{*it}.checkWithoutMoving(pos, stub))
break;
if (*it)
break;
for (it = operators; *it; it += 2)
if (parseOperator(pos, *it, expected))
break;
if (!*it)
break;
/// the function corresponding to the operator
auto function = std::make_shared<ASTFunction>();
/// function arguments
auto exp_list = std::make_shared<ASTExpressionList>();
ASTPtr elem;
SubqueryFunctionType subquery_function_type = SubqueryFunctionType::NONE;
2022-03-30 18:16:41 +00:00
if (comparison_expression)
2022-03-29 15:34:50 +00:00
{
2022-03-30 18:16:41 +00:00
if (ParserKeyword("ANY").ignore(pos, expected))
subquery_function_type = SubqueryFunctionType::ANY;
else if (ParserKeyword("ALL").ignore(pos, expected))
subquery_function_type = SubqueryFunctionType::ALL;
2022-03-29 15:34:50 +00:00
}
2021-06-03 02:19:07 +00:00
if (subquery_function_type != SubqueryFunctionType::NONE && !ParserSubquery().parse(pos, elem, expected))
2022-03-30 18:16:41 +00:00
subquery_function_type = SubqueryFunctionType::NONE;
if (subquery_function_type == SubqueryFunctionType::NONE
&& !(remaining_elem_parser ? remaining_elem_parser : first_elem_parser)->parse(pos, elem, expected))
2021-06-03 02:19:07 +00:00
return false;
/// the first argument of the function is the previous element, the second is the next one
function->name = it[1];
function->arguments = exp_list;
function->children.push_back(exp_list);
exp_list->children.push_back(node);
exp_list->children.push_back(elem);
2022-03-30 18:16:41 +00:00
if (comparison_expression && subquery_function_type != SubqueryFunctionType::NONE && !modifyAST(function, subquery_function_type))
2021-06-03 02:19:07 +00:00
return false;
2017-04-02 17:37:49 +00:00
/** special exception for the access operator to the element of the array `x[y]`, which
* contains the infix part '[' and the suffix ''] '(specified as' [')
*/
2021-10-31 15:11:46 +00:00
if (it[0] == "["sv)
{
if (pos->type != TokenType::ClosingSquareBracket)
return false;
++pos;
}
2019-08-10 17:08:14 +00:00
/// Left associative operator chain is parsed as a tree: ((((1 + 1) + 1) + 1) + 1)...
/// We must account it's depth - otherwise we may end up with stack overflow later - on destruction of AST.
pos.increaseDepth();
node = function;
}
}
2019-08-10 17:08:14 +00:00
pos.depth = current_depth;
return true;
2010-06-24 19:12:10 +00:00
}
bool ParserVariableArityOperatorList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ASTPtr arguments;
if (!elem_parser->parse(pos, node, expected))
return false;
while (true)
{
if (!parseOperator(pos, infix, expected))
break;
if (!arguments)
{
node = makeASTFunction(function_name, node);
arguments = node->as<ASTFunction &>().arguments;
}
ASTPtr elem;
if (!elem_parser->parse(pos, elem, expected))
return false;
arguments->children.push_back(elem);
}
return true;
}
2010-06-24 19:12:10 +00:00
2022-06-16 01:53:27 +00:00
2022-06-22 21:59:20 +00:00
ASTPtr makeBetweenOperator(bool negative, ASTs arguments)
{
// subject = arguments[0], left = arguments[1], right = arguments[2]
auto f_combined_expression = std::make_shared<ASTFunction>();
auto args_combined_expression = std::make_shared<ASTExpressionList>();
/// [NOT] BETWEEN left AND right
auto f_left_expr = std::make_shared<ASTFunction>();
auto args_left_expr = std::make_shared<ASTExpressionList>();
auto f_right_expr = std::make_shared<ASTFunction>();
auto args_right_expr = std::make_shared<ASTExpressionList>();
args_left_expr->children.emplace_back(arguments[0]);
args_left_expr->children.emplace_back(arguments[1]);
args_right_expr->children.emplace_back(arguments[0]);
args_right_expr->children.emplace_back(arguments[2]);
if (negative)
{
/// NOT BETWEEN
f_left_expr->name = "less";
f_right_expr->name = "greater";
f_combined_expression->name = "or";
}
else
{
/// BETWEEN
f_left_expr->name = "greaterOrEquals";
f_right_expr->name = "lessOrEquals";
f_combined_expression->name = "and";
}
f_left_expr->arguments = args_left_expr;
f_left_expr->children.emplace_back(f_left_expr->arguments);
f_right_expr->arguments = args_right_expr;
f_right_expr->children.emplace_back(f_right_expr->arguments);
args_combined_expression->children.emplace_back(f_left_expr);
args_combined_expression->children.emplace_back(f_right_expr);
f_combined_expression->arguments = args_combined_expression;
f_combined_expression->children.emplace_back(f_combined_expression->arguments);
return f_combined_expression;
}
2022-06-29 21:51:58 +00:00
2022-07-14 12:11:14 +00:00
bool ParserTableFunctionExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
2022-06-29 21:51:58 +00:00
{
2022-07-14 12:11:14 +00:00
if (ParserTableFunctionView().parse(pos, node, expected))
return true;
ParserKeyword s_settings("SETTINGS");
if (s_settings.ignore(pos, expected))
{
ParserSetQuery parser_settings(true);
if (parser_settings.parse(pos, node, expected))
return true;
}
2022-07-14 12:11:14 +00:00
return elem_parser.parse(pos, node, expected);
}
2022-06-16 01:53:27 +00:00
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
bool ParserPrefixUnaryOperatorExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
/// try to find any of the valid operators
const char ** it;
for (it = operators; *it; it += 2)
2022-02-24 13:54:30 +00:00
{
2022-07-14 12:11:14 +00:00
if (parseOperator(pos, *it, expected))
break;
2022-02-24 13:54:30 +00:00
}
2022-07-14 12:11:14 +00:00
/// Let's parse chains of the form `NOT NOT x`. This is hack.
/** This is done, because among the unary operators there is only a minus and NOT.
* But for a minus the chain of unary operators does not need to be supported.
*/
size_t count = 1;
if (it[0] && 0 == strncmp(it[0], "NOT", 3))
2022-02-24 13:54:30 +00:00
{
2022-07-14 12:11:14 +00:00
while (true)
{
const char ** jt;
for (jt = operators; *jt; jt += 2)
if (parseOperator(pos, *jt, expected))
break;
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
if (!*jt)
break;
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
++count;
}
2022-02-24 13:54:30 +00:00
}
2022-07-14 12:11:14 +00:00
ASTPtr elem;
if (!elem_parser->parse(pos, elem, expected))
return false;
if (!*it)
node = elem;
else
2022-02-24 13:54:30 +00:00
{
2022-07-14 12:11:14 +00:00
for (size_t i = 0; i < count; ++i)
2022-06-23 08:18:14 +00:00
{
2022-07-14 12:11:14 +00:00
/// the function corresponding to the operator
auto function = std::make_shared<ASTFunction>();
2022-06-23 08:18:14 +00:00
2022-07-14 12:11:14 +00:00
/// function arguments
auto exp_list = std::make_shared<ASTExpressionList>();
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
function->name = it[1];
function->arguments = exp_list;
function->children.push_back(exp_list);
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
if (node)
exp_list->children.push_back(node);
else
exp_list->children.push_back(elem);
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
node = function;
}
2022-02-24 13:54:30 +00:00
}
2022-07-14 12:11:14 +00:00
return true;
}
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
bool ParserCastExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ASTPtr expr_ast;
if (!elem_parser->parse(pos, expr_ast, expected))
return false;
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
ASTPtr type_ast;
if (ParserToken(TokenType::DoubleColon).ignore(pos, expected)
&& ParserDataType().parse(pos, type_ast, expected))
2022-06-29 21:51:58 +00:00
{
2022-07-14 12:11:14 +00:00
node = createFunctionCast(expr_ast, type_ast);
2022-06-29 21:51:58 +00:00
}
2022-07-14 12:11:14 +00:00
else
2022-02-24 13:54:30 +00:00
{
2022-07-14 12:11:14 +00:00
node = expr_ast;
2022-02-24 13:54:30 +00:00
}
2022-07-14 12:11:14 +00:00
return true;
}
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
ParserExpressionWithOptionalAlias::ParserExpressionWithOptionalAlias(bool allow_alias_without_as_keyword, bool is_table_function)
: impl(std::make_unique<ParserWithOptionalAlias>(
is_table_function ? ParserPtr(std::make_unique<ParserTableFunctionExpression>()) : ParserPtr(std::make_unique<ParserExpression>()),
allow_alias_without_as_keyword))
{
}
2022-05-26 23:38:25 +00:00
2022-06-29 21:51:58 +00:00
2022-07-14 12:11:14 +00:00
bool ParserExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
return ParserList(
std::make_unique<ParserExpressionWithOptionalAlias>(allow_alias_without_as_keyword, is_table_function),
std::make_unique<ParserToken>(TokenType::Comma))
.parse(pos, node, expected);
}
2022-05-26 23:38:25 +00:00
2022-07-14 12:11:14 +00:00
bool ParserNotEmptyExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
return nested_parser.parse(pos, node, expected) && !node->children.empty();
}
2022-07-14 12:11:14 +00:00
bool ParserOrderByExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
return ParserList(std::make_unique<ParserOrderByElement>(), std::make_unique<ParserToken>(TokenType::Comma), false)
.parse(pos, node, expected);
}
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
bool ParserGroupingSetsExpressionListElements::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
auto command_list = std::make_shared<ASTExpressionList>();
node = command_list;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
ParserToken s_comma(TokenType::Comma);
ParserToken s_open(TokenType::OpeningRoundBracket);
ParserToken s_close(TokenType::ClosingRoundBracket);
ParserExpressionWithOptionalAlias p_expression(false);
ParserList p_command(std::make_unique<ParserExpressionWithOptionalAlias>(false),
std::make_unique<ParserToken>(TokenType::Comma), true);
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
do
2022-04-17 20:59:03 +00:00
{
2022-07-14 12:11:14 +00:00
Pos begin = pos;
ASTPtr command;
if (!s_open.ignore(pos, expected))
2022-04-17 20:59:03 +00:00
{
2022-07-14 12:11:14 +00:00
pos = begin;
if (!p_expression.parse(pos, command, expected))
{
return false;
}
auto list = std::make_shared<ASTExpressionList>(',');
list->children.push_back(command);
command = std::move(list);
2022-04-17 20:59:03 +00:00
}
else
{
2022-07-14 12:11:14 +00:00
if (!p_command.parse(pos, command, expected))
return false;
if (!s_close.ignore(pos, expected))
break;
2022-04-17 20:59:03 +00:00
}
2022-07-14 12:11:14 +00:00
command_list->children.push_back(command);
2022-04-17 20:59:03 +00:00
}
2022-07-14 12:11:14 +00:00
while (s_comma.ignore(pos, expected));
2022-04-17 20:59:03 +00:00
2022-07-14 12:11:14 +00:00
return true;
}
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
bool ParserGroupingSetsExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ParserGroupingSetsExpressionListElements grouping_sets_elements;
return grouping_sets_elements.parse(pos, node, expected);
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
}
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
bool ParserInterpolateExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
return ParserList(std::make_unique<ParserInterpolateElement>(), std::make_unique<ParserToken>(TokenType::Comma), true)
.parse(pos, node, expected);
}
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
bool ParserTTLExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
return ParserList(std::make_unique<ParserTTLElement>(), std::make_unique<ParserToken>(TokenType::Comma), false)
.parse(pos, node, expected);
}
bool ParserKeyValuePair::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ParserIdentifier id_parser;
ParserLiteral literal_parser;
ParserFunction func_parser;
2022-06-22 21:59:20 +00:00
2022-07-14 12:11:14 +00:00
ASTPtr identifier;
ASTPtr value;
bool with_brackets = false;
if (!id_parser.parse(pos, identifier, expected))
return false;
2022-06-22 21:59:20 +00:00
2022-07-14 12:11:14 +00:00
/// If it's neither literal, nor identifier, nor function, than it's possible list of pairs
if (!func_parser.parse(pos, value, expected) && !literal_parser.parse(pos, value, expected) && !id_parser.parse(pos, value, expected))
{
ParserKeyValuePairsList kv_pairs_list;
ParserToken open(TokenType::OpeningRoundBracket);
ParserToken close(TokenType::ClosingRoundBracket);
2022-06-22 21:59:20 +00:00
2022-07-14 12:11:14 +00:00
if (!open.ignore(pos))
return false;
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
if (!kv_pairs_list.parse(pos, value, expected))
return false;
2022-06-22 21:59:20 +00:00
2022-07-14 12:11:14 +00:00
if (!close.ignore(pos))
return false;
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
with_brackets = true;
}
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
auto pair = std::make_shared<ASTPair>(with_brackets);
pair->first = Poco::toLower(identifier->as<ASTIdentifier>()->name());
pair->set(pair->second, value);
node = pair;
return true;
}
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
bool ParserKeyValuePairsList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ParserList parser(std::make_unique<ParserKeyValuePair>(), std::make_unique<ParserNothing>(), true, 0);
return parser.parse(pos, node, expected);
}
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
enum class Action
{
OPERAND,
OPERATOR
};
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
/** Operator types are needed for special handling of certain operators.
* Operators can be grouped into some type if they have similar behaviour.
* Certain operators are unique in terms of their behaviour, so they are assigned a separate type.
*/
enum class OperatorType
{
None,
Comparison,
Mergeable,
ArrayElement,
TupleElement,
IsNull,
StartBetween,
StartNotBetween,
FinishBetween,
StartIf,
FinishIf,
Cast,
Lambda
2022-07-14 12:11:14 +00:00
};
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
/** Operator class stores parameters of the operator:
* - function_name name of the function that operator will create
* - priority priority of the operator relative to the other operators
* - arity the amount of arguments that operator will consume
* - type type of the operator that defines its behaviour
*/
class Operator
{
public:
Operator() = default;
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
Operator(String function_name_,
Int32 priority_,
Int32 arity_ = 2,
OperatorType type_ = OperatorType::None) : type(type_), priority(priority_), arity(arity_), function_name(function_name_)
{
2022-06-16 01:53:27 +00:00
}
2022-07-14 12:11:14 +00:00
OperatorType type;
Int32 priority;
Int32 arity;
2022-06-29 21:51:58 +00:00
String function_name;
2022-06-16 01:53:27 +00:00
};
2022-05-26 23:38:25 +00:00
2022-09-05 16:21:16 +00:00
enum class Checkpoint
{
None,
Interval,
Case
};
2022-07-14 12:11:14 +00:00
/** Layer is a class that represents context for parsing certain element,
* that consists of other elements e.g. f(x1, x2, x3)
*
* - Manages operands and operators for the future elements (arguments)
* - Combines operands and operator into one element
* - Parsers separators and endings
2022-08-10 04:58:59 +00:00
* - Combines resulting elements into a function
2022-07-14 12:11:14 +00:00
*/
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
class Layer
2022-06-16 01:53:27 +00:00
{
public:
2022-08-12 19:20:17 +00:00
explicit Layer(bool allow_alias_ = true, bool allow_alias_without_as_keyword_ = true) :
2022-08-10 04:58:59 +00:00
allow_alias(allow_alias_), allow_alias_without_as_keyword(allow_alias_without_as_keyword_)
{
}
2022-07-14 12:11:14 +00:00
virtual ~Layer() = default;
bool popOperator(Operator & op)
2022-06-16 01:53:27 +00:00
{
2022-07-14 12:11:14 +00:00
if (operators.empty())
return false;
op = std::move(operators.back());
operators.pop_back();
2022-06-16 01:53:27 +00:00
return true;
}
2022-07-14 12:11:14 +00:00
void pushOperator(Operator op)
2022-06-16 01:53:27 +00:00
{
2022-07-14 12:11:14 +00:00
operators.push_back(std::move(op));
}
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
bool popOperand(ASTPtr & op)
{
if (operands.empty())
return false;
2022-06-27 13:49:37 +00:00
2022-07-14 12:11:14 +00:00
op = std::move(operands.back());
operands.pop_back();
2022-06-16 01:53:27 +00:00
return true;
}
2022-07-14 12:11:14 +00:00
void pushOperand(ASTPtr op)
2022-06-16 01:53:27 +00:00
{
2022-07-14 12:11:14 +00:00
operands.push_back(std::move(op));
2022-06-16 01:53:27 +00:00
}
2022-07-14 12:11:14 +00:00
void pushResult(ASTPtr op)
2022-06-16 01:53:27 +00:00
{
2022-08-10 04:58:59 +00:00
elements.push_back(std::move(op));
2022-06-16 01:53:27 +00:00
}
2022-07-14 12:11:14 +00:00
virtual bool getResult(ASTPtr & op)
2022-06-16 01:53:27 +00:00
{
2022-08-10 04:58:59 +00:00
if (elements.size() == 1)
2022-07-14 12:11:14 +00:00
{
2022-08-10 04:58:59 +00:00
op = std::move(elements[0]);
2022-07-14 12:11:14 +00:00
return true;
}
return false;
2022-06-16 01:53:27 +00:00
}
2022-04-08 03:30:49 +00:00
2022-08-10 04:58:59 +00:00
virtual bool parse(IParser::Pos & /*pos*/, Expected & /*expected*/, Action & /*action*/) = 0;
2022-05-26 22:53:37 +00:00
2022-07-14 12:11:14 +00:00
bool isFinished() const
{
return finished;
}
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
int previousPriority() const
{
if (operators.empty())
return 0;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
return operators.back().priority;
}
2022-05-26 22:53:37 +00:00
2022-07-14 12:11:14 +00:00
OperatorType previousType() const
{
if (operators.empty())
return OperatorType::None;
2022-05-26 22:53:37 +00:00
2022-07-14 12:11:14 +00:00
return operators.back().type;
}
2022-05-26 22:53:37 +00:00
2022-07-14 12:11:14 +00:00
int empty() const
{
return operators.empty() && operands.empty();
}
2022-05-26 22:53:37 +00:00
2022-07-14 12:11:14 +00:00
bool popLastNOperands(ASTs & asts, size_t n)
{
if (n > operands.size())
return false;
2022-05-26 22:53:37 +00:00
asts.reserve(asts.size() + n);
2022-07-14 12:11:14 +00:00
auto start = operands.begin() + operands.size() - n;
asts.insert(asts.end(), std::make_move_iterator(start), std::make_move_iterator(operands.end()));
operands.erase(start, operands.end());
2022-05-26 22:53:37 +00:00
2022-07-14 12:11:14 +00:00
return true;
}
2022-05-26 22:53:37 +00:00
2022-08-10 04:58:59 +00:00
/// Merge operators and operands into a single element (column), then push it to 'elements' vector.
/// Operators are previously sorted in ascending order of priority
/// (operator with priority 1 has higher priority than operator with priority 2),
2022-07-14 12:11:14 +00:00
/// so we can just merge them with operands starting from the end.
///
/// If we fail here it means that the query was incorrect and we should return an error.
///
2022-08-10 04:58:59 +00:00
bool mergeElement(bool push_to_elements = true)
2022-07-14 12:11:14 +00:00
{
Operator cur_op;
while (popOperator(cur_op))
{
ASTPtr function;
2022-05-26 22:53:37 +00:00
2022-07-14 12:11:14 +00:00
// Special case of ternary operator
if (cur_op.type == OperatorType::StartIf)
return false;
2022-05-26 22:53:37 +00:00
2022-07-14 12:11:14 +00:00
if (cur_op.type == OperatorType::FinishIf)
{
Operator tmp;
if (!popOperator(tmp) || tmp.type != OperatorType::StartIf)
return false;
}
2022-05-26 22:53:37 +00:00
2022-07-14 12:11:14 +00:00
// Special case of a BETWEEN b AND c operator
if (cur_op.type == OperatorType::StartBetween || cur_op.type == OperatorType::StartNotBetween)
2022-05-26 22:53:37 +00:00
return false;
2022-07-14 12:11:14 +00:00
if (cur_op.type == OperatorType::FinishBetween)
2022-04-08 03:30:49 +00:00
{
2022-07-14 12:11:14 +00:00
Operator tmp_op;
if (!popOperator(tmp_op))
return false;
if (tmp_op.type != OperatorType::StartBetween && tmp_op.type != OperatorType::StartNotBetween)
return false;
bool negative = tmp_op.type == OperatorType::StartNotBetween;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
ASTs arguments;
if (!popLastNOperands(arguments, 3))
2022-04-08 03:30:49 +00:00
return false;
2022-07-14 12:11:14 +00:00
function = makeBetweenOperator(negative, arguments);
2022-04-08 03:30:49 +00:00
}
2022-07-14 12:11:14 +00:00
else
2022-04-08 03:30:49 +00:00
{
2022-07-14 12:11:14 +00:00
function = makeASTFunction(cur_op.function_name);
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
if (!popLastNOperands(function->children[0]->children, cur_op.arity))
return false;
2022-04-08 03:30:49 +00:00
}
2022-07-14 12:11:14 +00:00
pushOperand(function);
2022-04-08 03:30:49 +00:00
}
2022-07-14 12:11:14 +00:00
ASTPtr node;
if (!popOperand(node))
return false;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
bool res = empty();
2022-06-16 01:53:27 +00:00
2022-08-10 04:58:59 +00:00
if (push_to_elements)
2022-07-14 12:11:14 +00:00
pushResult(node);
2022-06-16 01:53:27 +00:00
else
2022-07-14 12:11:14 +00:00
pushOperand(node);
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
return res;
2022-06-16 01:53:27 +00:00
}
2022-07-14 12:11:14 +00:00
bool parseLambda()
2022-04-08 03:30:49 +00:00
{
2022-07-14 12:11:14 +00:00
// 0. If empty - create function tuple with 0 args
if (empty())
2022-04-08 03:30:49 +00:00
{
2022-07-14 12:11:14 +00:00
auto function = makeASTFunction("tuple");
pushOperand(function);
return true;
2022-04-08 03:30:49 +00:00
}
if (operands.size() != 1 || !operators.empty() || !mergeElement())
2022-07-14 12:11:14 +00:00
return false;
/// 1. If there is already tuple do nothing
2022-08-10 04:58:59 +00:00
if (tryGetFunctionName(elements.back()) == "tuple")
2022-04-08 03:30:49 +00:00
{
2022-08-10 04:58:59 +00:00
pushOperand(elements.back());
elements.pop_back();
2022-04-08 03:30:49 +00:00
}
2022-08-10 04:58:59 +00:00
/// 2. Put all elements in a single tuple
2022-07-14 12:11:14 +00:00
else
2022-04-08 03:30:49 +00:00
{
2022-08-10 04:58:59 +00:00
auto function = makeASTFunction("tuple", elements);
elements.clear();
2022-07-14 12:11:14 +00:00
pushOperand(function);
2022-04-08 03:30:49 +00:00
}
return true;
}
2022-08-04 10:06:18 +00:00
/// Put 'node' identifier into the last operand as its alias
2022-07-14 12:11:14 +00:00
bool insertAlias(ASTPtr node)
2022-04-08 03:30:49 +00:00
{
2022-07-14 12:11:14 +00:00
if (!mergeElement(false))
return false;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
if (operands.empty())
return false;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
if (auto * ast_with_alias = dynamic_cast<ASTWithAlias *>(operands.back().get()))
tryGetIdentifierNameInto(node, ast_with_alias->alias);
else
return false;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
return true;
}
2022-04-08 03:30:49 +00:00
2022-08-10 04:58:59 +00:00
/// 'AND' in operator '... BETWEEN ... AND ...' mirrors logical operator 'AND'.
/// In order to distinguish them we keep a counter of BETWEENs without matching ANDs.
int between_counter = 0;
2022-04-08 03:30:49 +00:00
2022-08-10 04:58:59 +00:00
bool allow_alias = true;
bool allow_alias_without_as_keyword = true;
2022-04-08 03:30:49 +00:00
2022-09-07 01:45:13 +00:00
std::optional<std::pair<IParser::Pos, Checkpoint>> saved_checkpoint;
Checkpoint current_checkpoint;
2022-09-05 16:21:16 +00:00
2022-07-14 12:11:14 +00:00
protected:
std::vector<Operator> operators;
ASTs operands;
2022-08-10 04:58:59 +00:00
ASTs elements;
2022-07-14 12:11:14 +00:00
bool finished = false;
int state = 0;
2022-08-10 04:58:59 +00:00
};
2022-07-14 12:11:14 +00:00
2022-08-10 04:58:59 +00:00
class SingleElementLayer : public Layer
{
public:
SingleElementLayer() : Layer(false, false)
{
}
bool getResult(ASTPtr & op) override
{
/// We can exit the main cycle outside the parse() function,
/// so we need to merge the element here
if (!mergeElement())
return false;
if (elements.size() == 1)
{
op = std::move(elements[0]);
return true;
}
return false;
}
bool parse(IParser::Pos & pos, Expected & /*expected*/, Action & /*action*/) override
{
if (pos->type == TokenType::Comma)
finished = true;
return true;
}
2022-07-14 12:11:14 +00:00
};
/// Basic layer for a function with certain separator and end tokens:
/// 1. If we parse a separator we should merge current operands and operators
2022-08-10 04:58:59 +00:00
/// into one element and push in to 'elements' vector.
/// 2. If we parse an ending token, we should merge everything as in (1) and
/// also set 'finished' flag.
2022-07-14 12:11:14 +00:00
template <TokenType separator, TokenType end>
class BaseLayer : public Layer
{
public:
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
{
if (ParserToken(separator).ignore(pos, expected))
2022-04-08 03:30:49 +00:00
{
2022-07-14 12:11:14 +00:00
action = Action::OPERAND;
return mergeElement();
}
if (ParserToken(end).ignore(pos, expected))
{
action = Action::OPERATOR;
2022-08-10 04:58:59 +00:00
if (!empty() || !elements.empty())
2022-07-14 12:11:14 +00:00
if (!mergeElement())
2022-04-08 03:30:49 +00:00
return false;
2022-07-14 12:11:14 +00:00
finished = true;
2022-04-08 03:30:49 +00:00
}
return true;
}
};
/// General function layer
2022-07-14 12:11:14 +00:00
class FunctionLayer : public Layer
2022-04-08 03:30:49 +00:00
{
public:
2022-07-14 12:11:14 +00:00
explicit FunctionLayer(String function_name_) : function_name(function_name_)
{
}
2022-04-08 03:30:49 +00:00
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
{
/// | 0 | 1 | 2 |
/// f(ALL ...)(ALL ...) FILTER ...
///
/// 0. Parse ALL and DISTINCT qualifiers (-> 1)
/// 1. Parse all the arguments and ending token (-> 2), possibly with parameters list (-> 1)
/// 2. Create function, possibly parse FILTER and OVER window definitions (finished)
2022-04-08 03:30:49 +00:00
if (state == 0)
{
2022-07-14 12:11:14 +00:00
state = 1;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
auto pos_after_bracket = pos;
auto old_expected = expected;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
ParserKeyword all("ALL");
ParserKeyword distinct("DISTINCT");
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
if (all.ignore(pos, expected))
has_all = true;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
if (distinct.ignore(pos, expected))
has_distinct = true;
if (!has_all && all.ignore(pos, expected))
has_all = true;
if (has_all && has_distinct)
return false;
if (has_all || has_distinct)
{
/// case f(ALL), f(ALL, x), f(DISTINCT), f(DISTINCT, x), ALL and DISTINCT should be treat as identifier
if (pos->type == TokenType::Comma || pos->type == TokenType::ClosingRoundBracket)
{
pos = pos_after_bracket;
expected = old_expected;
has_all = false;
has_distinct = false;
}
2022-04-08 03:30:49 +00:00
}
2022-07-14 12:11:14 +00:00
contents_begin = pos->begin;
2022-04-08 03:30:49 +00:00
}
2022-05-26 16:50:48 +00:00
if (state == 1)
{
if (ParserToken(TokenType::Comma).ignore(pos, expected))
{
action = Action::OPERAND;
2022-07-14 12:11:14 +00:00
return mergeElement();
2022-05-26 16:50:48 +00:00
}
2022-04-08 03:30:49 +00:00
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
{
2022-07-14 12:11:14 +00:00
action = Action::OPERATOR;
2022-04-08 03:30:49 +00:00
2022-08-10 04:58:59 +00:00
if (!empty() || !elements.empty())
2022-07-14 12:11:14 +00:00
if (!mergeElement())
return false;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
contents_end = pos->begin;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
/** Check for a common error case - often due to the complexity of quoting command-line arguments,
* an expression of the form toDate(2014-01-01) appears in the query instead of toDate('2014-01-01').
* If you do not report that the first option is an error, then the argument will be interpreted as 2014 - 01 - 01 - some number,
2022-08-10 04:58:59 +00:00
* and the query silently returns an unexpected elements.
2022-07-14 12:11:14 +00:00
*/
if (function_name == "toDate"
&& contents_end - contents_begin == strlen("2014-01-01")
&& contents_begin[0] >= '2' && contents_begin[0] <= '3'
&& contents_begin[1] >= '0' && contents_begin[1] <= '9'
&& contents_begin[2] >= '0' && contents_begin[2] <= '9'
&& contents_begin[3] >= '0' && contents_begin[3] <= '9'
&& contents_begin[4] == '-'
&& contents_begin[5] >= '0' && contents_begin[5] <= '9'
&& contents_begin[6] >= '0' && contents_begin[6] <= '9'
&& contents_begin[7] == '-'
&& contents_begin[8] >= '0' && contents_begin[8] <= '9'
&& contents_begin[9] >= '0' && contents_begin[9] <= '9')
{
std::string contents_str(contents_begin, contents_end - contents_begin);
throw Exception("Argument of function toDate is unquoted: toDate(" + contents_str + "), must be: toDate('" + contents_str + "')"
, ErrorCodes::SYNTAX_ERROR);
}
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
if (ParserToken(TokenType::OpeningRoundBracket).ignore(pos, expected))
{
parameters = std::make_shared<ASTExpressionList>();
2022-08-10 04:58:59 +00:00
std::swap(parameters->children, elements);
2022-07-14 12:11:14 +00:00
action = Action::OPERAND;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
/// Parametric aggregate functions cannot have DISTINCT in parameters list.
if (has_distinct)
return false;
2022-04-08 15:36:36 +00:00
2022-07-14 12:11:14 +00:00
auto pos_after_bracket = pos;
auto old_expected = expected;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
ParserKeyword all("ALL");
ParserKeyword distinct("DISTINCT");
2022-04-08 15:36:36 +00:00
2022-07-14 12:11:14 +00:00
if (all.ignore(pos, expected))
has_all = true;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
if (distinct.ignore(pos, expected))
has_distinct = true;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
if (!has_all && all.ignore(pos, expected))
has_all = true;
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
if (has_all && has_distinct)
return false;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
if (has_all || has_distinct)
{
/// case f(ALL), f(ALL, x), f(DISTINCT), f(DISTINCT, x), ALL and DISTINCT should be treat as identifier
if (pos->type == TokenType::Comma || pos->type == TokenType::ClosingRoundBracket)
{
pos = pos_after_bracket;
expected = old_expected;
has_distinct = false;
}
}
2022-04-08 03:30:49 +00:00
}
else
{
state = 2;
2022-07-14 12:11:14 +00:00
}
2022-04-08 03:30:49 +00:00
}
}
2022-07-14 12:11:14 +00:00
if (state == 2)
2022-04-08 03:30:49 +00:00
{
2022-07-14 12:11:14 +00:00
if (has_distinct)
function_name += "Distinct";
2022-04-08 03:30:49 +00:00
2022-08-10 04:58:59 +00:00
auto function_node = makeASTFunction(function_name, std::move(elements));
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
if (parameters)
{
function_node->parameters = parameters;
function_node->children.push_back(function_node->parameters);
2022-04-08 03:30:49 +00:00
}
2022-07-14 12:11:14 +00:00
ParserKeyword filter("FILTER");
ParserKeyword over("OVER");
if (filter.ignore(pos, expected))
2022-04-08 03:30:49 +00:00
{
2022-07-14 12:11:14 +00:00
// We are slightly breaking the parser interface by parsing the window
// definition into an existing ASTFunction. Normally it would take a
// reference to ASTPtr and assign it the new node. We only have a pointer
// of a different type, hence this workaround with a temporary pointer.
ASTPtr function_node_as_iast = function_node;
// Recursion
ParserFilterClause filter_parser;
if (!filter_parser.parse(pos, function_node_as_iast, expected))
2022-04-08 03:30:49 +00:00
return false;
2022-07-14 12:11:14 +00:00
}
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
if (over.ignore(pos, expected))
{
function_node->is_window_function = true;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
ASTPtr function_node_as_iast = function_node;
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
// Recursion
ParserWindowReference window_reference;
if (!window_reference.parse(pos, function_node_as_iast, expected))
return false;
2022-04-08 03:30:49 +00:00
}
2022-07-14 12:11:14 +00:00
2022-08-10 04:58:59 +00:00
elements = {function_node};
2022-07-14 12:11:14 +00:00
finished = true;
2022-04-08 03:30:49 +00:00
}
return true;
}
2022-07-14 12:11:14 +00:00
2022-04-08 03:30:49 +00:00
private:
2022-07-14 12:11:14 +00:00
bool has_all = false;
bool has_distinct = false;
const char * contents_begin;
const char * contents_end;
2022-04-08 03:30:49 +00:00
2022-06-29 21:51:58 +00:00
String function_name;
2022-07-14 12:11:14 +00:00
ASTPtr parameters;
2022-02-24 13:54:30 +00:00
};
/// Layer for priority brackets and tuple function
2022-07-14 12:11:14 +00:00
class RoundBracketsLayer : public Layer
2022-04-08 15:36:36 +00:00
{
public:
2022-07-14 12:11:14 +00:00
bool getResult(ASTPtr & op) override
2022-04-08 15:36:36 +00:00
{
2022-07-14 12:11:14 +00:00
// Round brackets can mean priority operator as well as function tuple()
2022-08-10 04:58:59 +00:00
if (!is_tuple && elements.size() == 1)
op = std::move(elements[0]);
2022-07-14 12:11:14 +00:00
else
2022-08-10 04:58:59 +00:00
op = makeASTFunction("tuple", std::move(elements));
2022-07-14 12:11:14 +00:00
return true;
2022-04-08 15:36:36 +00:00
}
2022-07-14 12:11:14 +00:00
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
2022-06-16 01:53:27 +00:00
{
2022-07-14 12:11:14 +00:00
if (ParserToken(TokenType::Comma).ignore(pos, expected))
2022-06-16 01:53:27 +00:00
{
2022-07-14 12:11:14 +00:00
action = Action::OPERAND;
is_tuple = true;
if (!mergeElement())
return false;
2022-06-16 01:53:27 +00:00
}
2022-07-14 12:11:14 +00:00
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
{
action = Action::OPERATOR;
if (!empty())
if (!mergeElement())
return false;
// Special case for (('a', 'b')) -> tuple(('a', 'b'))
2022-08-10 04:58:59 +00:00
if (!is_tuple && elements.size() == 1)
if (auto * literal = elements[0]->as<ASTLiteral>())
2022-07-14 12:11:14 +00:00
if (literal->value.getType() == Field::Types::Tuple)
is_tuple = true;
finished = true;
}
return true;
}
private:
bool is_tuple = false;
};
/// Layer for array square brackets operator
2022-07-14 12:11:14 +00:00
class ArrayLayer : public BaseLayer<TokenType::Comma, TokenType::ClosingSquareBracket>
{
public:
bool getResult(ASTPtr & op) override
{
2022-08-10 04:58:59 +00:00
op = makeASTFunction("array", std::move(elements));
2022-06-16 01:53:27 +00:00
return true;
}
2022-07-14 12:11:14 +00:00
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
{
return BaseLayer::parse(pos, expected, action);
}
};
/// Layer for arrayElement square brackets operator
/// This layer does not create a function, it is only needed to parse closing token
/// and return only one element.
2022-07-14 12:11:14 +00:00
class ArrayElementLayer : public BaseLayer<TokenType::Comma, TokenType::ClosingSquareBracket>
{
public:
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
{
return BaseLayer::parse(pos, expected, action);
}
};
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
class CastLayer : public Layer
{
public:
2022-04-08 15:36:36 +00:00
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
{
/// CAST(x [AS alias1], T [AS alias2]) or CAST(x [AS alias1] AS T)
///
/// 0. Parse all the cases (-> 1)
/// 1. Parse closing token (finished)
2022-07-14 12:11:14 +00:00
ParserKeyword as_keyword_parser("AS");
ASTPtr alias;
/// expr AS type
2022-04-08 15:36:36 +00:00
if (state == 0)
{
2022-07-14 12:11:14 +00:00
ASTPtr type_node;
2022-04-08 15:36:36 +00:00
2022-07-14 12:11:14 +00:00
if (as_keyword_parser.ignore(pos, expected))
2022-04-08 15:36:36 +00:00
{
2022-07-14 12:11:14 +00:00
auto old_pos = pos;
2022-04-08 15:36:36 +00:00
2022-07-14 12:11:14 +00:00
if (ParserIdentifier().parse(pos, alias, expected) &&
as_keyword_parser.ignore(pos, expected) &&
ParserDataType().parse(pos, type_node, expected) &&
ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
{
if (!insertAlias(alias))
return false;
if (!mergeElement())
return false;
2022-08-10 04:58:59 +00:00
elements = {createFunctionCast(elements[0], type_node)};
2022-07-14 12:11:14 +00:00
finished = true;
return true;
}
pos = old_pos;
if (ParserIdentifier().parse(pos, alias, expected) &&
ParserToken(TokenType::Comma).ignore(pos, expected))
{
action = Action::OPERAND;
if (!insertAlias(alias))
return false;
if (!mergeElement())
return false;
state = 1;
return true;
}
pos = old_pos;
if (ParserDataType().parse(pos, type_node, expected) &&
ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
{
if (!mergeElement())
return false;
2022-08-10 04:58:59 +00:00
elements = {createFunctionCast(elements[0], type_node)};
2022-07-14 12:11:14 +00:00
finished = true;
return true;
}
return false;
}
2022-04-08 15:36:36 +00:00
if (ParserToken(TokenType::Comma).ignore(pos, expected))
{
action = Action::OPERAND;
2022-07-14 12:11:14 +00:00
if (!mergeElement())
2022-04-08 15:36:36 +00:00
return false;
2022-07-14 12:11:14 +00:00
state = 1;
return true;
2022-04-08 15:36:36 +00:00
}
}
2022-07-14 12:11:14 +00:00
if (state == 1)
2022-04-08 15:36:36 +00:00
{
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
{
2022-07-14 12:11:14 +00:00
if (!mergeElement())
2022-04-08 15:36:36 +00:00
return false;
2022-08-10 04:58:59 +00:00
elements = {makeASTFunction("CAST", elements[0], elements[1])};
2022-07-14 12:11:14 +00:00
finished = true;
return true;
2022-04-08 15:36:36 +00:00
}
}
2022-07-14 12:11:14 +00:00
2022-04-08 15:36:36 +00:00
return true;
}
};
2022-07-14 12:11:14 +00:00
class ExtractLayer : public BaseLayer<TokenType::Comma, TokenType::ClosingRoundBracket>
2022-04-08 15:36:36 +00:00
{
public:
2022-06-16 01:53:27 +00:00
bool getResult(ASTPtr & op) override
2022-04-08 15:36:36 +00:00
{
if (state == 2)
2022-04-08 15:36:36 +00:00
{
2022-08-10 04:58:59 +00:00
if (elements.empty())
2022-06-16 01:53:27 +00:00
return false;
2022-07-14 12:11:14 +00:00
2022-08-10 04:58:59 +00:00
op = makeASTFunction(interval_kind.toNameOfFunctionExtractTimePart(), elements[0]);
2022-04-08 15:36:36 +00:00
}
2022-06-16 01:53:27 +00:00
else
{
2022-08-10 04:58:59 +00:00
op = makeASTFunction("extract", std::move(elements));
}
2022-07-14 12:11:14 +00:00
2022-06-16 01:53:27 +00:00
return true;
}
2022-04-08 15:36:36 +00:00
2022-06-16 01:53:27 +00:00
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
{
/// extract(haystack, pattern) or EXTRACT(DAY FROM Date)
///
/// 0. If we parse interval_kind and 'FROM' keyword (-> 2), otherwise (-> 1)
/// 1. Basic parser
/// 2. Parse closing bracket (finished)
2022-06-16 01:53:27 +00:00
if (state == 0)
2022-04-08 15:36:36 +00:00
{
2022-07-14 12:11:14 +00:00
IParser::Pos begin = pos;
ParserKeyword s_from("FROM");
if (parseIntervalKind(pos, expected, interval_kind) && s_from.ignore(pos, expected))
2022-04-08 15:36:36 +00:00
{
2022-07-14 12:11:14 +00:00
state = 2;
return true;
}
else
{
state = 1;
pos = begin;
2022-04-08 15:36:36 +00:00
}
2022-06-16 01:53:27 +00:00
}
2022-04-08 15:36:36 +00:00
2022-06-16 01:53:27 +00:00
if (state == 1)
{
2022-07-14 12:11:14 +00:00
return BaseLayer::parse(pos, expected, action);
}
if (state == 2)
{
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
{
if (!mergeElement())
return false;
finished = true;
return true;
}
2022-04-08 15:36:36 +00:00
}
return true;
}
private:
IntervalKind interval_kind;
};
2022-07-14 12:11:14 +00:00
class SubstringLayer : public Layer
2022-04-08 15:36:36 +00:00
{
public:
bool getResult(ASTPtr & op) override
{
2022-08-10 04:58:59 +00:00
op = makeASTFunction("substring", std::move(elements));
return true;
}
2022-07-14 12:11:14 +00:00
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
2022-04-08 15:36:36 +00:00
{
/// Either SUBSTRING(expr FROM start [FOR length]) or SUBSTRING(expr, start, length)
///
/// 0: Parse first separator: FROM or comma (-> 1)
/// 1: Parse second separator: FOR or comma (-> 2)
/// 1 or 2: Parse closing bracket (finished)
2022-07-14 12:11:14 +00:00
2022-04-08 15:36:36 +00:00
if (state == 0)
{
2022-07-14 12:11:14 +00:00
if (ParserToken(TokenType::Comma).ignore(pos, expected) ||
ParserKeyword("FROM").ignore(pos, expected))
2022-04-08 15:36:36 +00:00
{
2022-07-14 12:11:14 +00:00
action = Action::OPERAND;
2022-04-08 15:36:36 +00:00
2022-07-14 12:11:14 +00:00
if (!mergeElement())
return false;
2022-04-08 15:36:36 +00:00
2022-07-14 12:11:14 +00:00
state = 1;
2022-04-08 15:36:36 +00:00
}
}
if (state == 1)
{
2022-07-14 12:11:14 +00:00
if (ParserToken(TokenType::Comma).ignore(pos, expected) ||
ParserKeyword("FOR").ignore(pos, expected))
2022-04-08 15:36:36 +00:00
{
2022-07-14 12:11:14 +00:00
action = Action::OPERAND;
if (!mergeElement())
2022-04-08 15:36:36 +00:00
return false;
2022-07-14 12:11:14 +00:00
state = 2;
}
}
if (state == 1 || state == 2)
{
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
{
if (!mergeElement())
return false;
finished = true;
2022-04-08 15:36:36 +00:00
}
}
return true;
}
};
2022-07-14 12:11:14 +00:00
class PositionLayer : public Layer
2022-04-12 15:03:10 +00:00
{
public:
bool getResult(ASTPtr & op) override
{
if (state == 2)
2022-08-10 04:58:59 +00:00
std::swap(elements[1], elements[0]);
2022-08-10 04:58:59 +00:00
op = makeASTFunction("position", std::move(elements));
return true;
}
2022-04-12 15:03:10 +00:00
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
{
/// position(haystack, needle[, start_pos]) or position(needle IN haystack)
///
/// 0: Parse separator: comma (-> 1) or IN (-> 2)
/// 1: Parse second separator: comma
/// 1 or 2: Parse closing bracket (finished)
2022-04-12 15:03:10 +00:00
if (state == 0)
{
2022-07-14 12:11:14 +00:00
if (ParserToken(TokenType::Comma).ignore(pos, expected))
2022-04-12 15:03:10 +00:00
{
action = Action::OPERAND;
2022-07-14 12:11:14 +00:00
if (!mergeElement())
2022-04-12 15:03:10 +00:00
return false;
2022-07-14 12:11:14 +00:00
state = 1;
2022-04-12 15:03:10 +00:00
}
2022-07-14 12:11:14 +00:00
if (ParserKeyword("IN").ignore(pos, expected))
2022-04-12 15:03:10 +00:00
{
2022-07-14 12:11:14 +00:00
action = Action::OPERAND;
2022-04-12 15:03:10 +00:00
2022-07-14 12:11:14 +00:00
if (!mergeElement())
return false;
2022-04-12 15:03:10 +00:00
2022-07-14 12:11:14 +00:00
state = 2;
2022-04-12 15:03:10 +00:00
}
}
2022-07-14 12:11:14 +00:00
if (state == 1)
2022-04-12 15:03:10 +00:00
{
2022-07-14 12:11:14 +00:00
if (ParserToken(TokenType::Comma).ignore(pos, expected))
2022-04-12 15:03:10 +00:00
{
action = Action::OPERAND;
2022-07-14 12:11:14 +00:00
if (!mergeElement())
return false;
2022-04-12 15:03:10 +00:00
}
}
2022-07-14 12:11:14 +00:00
if (state == 1 || state == 2)
2022-04-12 15:03:10 +00:00
{
2022-07-14 12:11:14 +00:00
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
2022-04-12 15:03:10 +00:00
{
2022-07-14 12:11:14 +00:00
if (!mergeElement())
2022-04-12 15:03:10 +00:00
return false;
2022-07-14 12:11:14 +00:00
finished = true;
2022-04-12 15:03:10 +00:00
}
}
return true;
}
};
2022-07-14 12:11:14 +00:00
class ExistsLayer : public Layer
2022-02-24 13:54:30 +00:00
{
2022-07-14 12:11:14 +00:00
public:
bool parse(IParser::Pos & pos, Expected & expected, Action & /*action*/) override
{
ASTPtr node;
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
// Recursion
if (!ParserSelectWithUnionQuery().parse(pos, node, expected))
return false;
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
if (!ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
return false;
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
auto subquery = std::make_shared<ASTSubquery>();
subquery->children.push_back(node);
2022-08-10 04:58:59 +00:00
elements = {makeASTFunction("exists", subquery)};
2022-07-14 12:11:14 +00:00
finished = true;
return true;
2022-02-24 13:54:30 +00:00
}
2022-07-14 12:11:14 +00:00
};
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
class TrimLayer : public Layer
2022-02-24 13:54:30 +00:00
{
2022-07-14 12:11:14 +00:00
public:
TrimLayer(bool trim_left_, bool trim_right_) : trim_left(trim_left_), trim_right(trim_right_)
{
}
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
bool getResult(ASTPtr & op) override
2022-02-24 13:54:30 +00:00
{
2022-08-10 04:58:59 +00:00
op = makeASTFunction(function_name, std::move(elements));
2022-07-14 12:11:14 +00:00
return true;
2022-02-24 13:54:30 +00:00
}
2022-07-14 12:11:14 +00:00
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
{
/// Handles all possible TRIM/LTRIM/RTRIM call variants
///
/// 0: If flags 'trim_left' and 'trim_right' are set (-> 2).
/// If not, try to parse 'BOTH', 'LEADING', 'TRAILING' keywords,
/// then if char_override (-> 1), else (-> 2)
/// 1. Parse 'FROM' keyword (-> 2)
/// 2. Parse closing token, choose name, add arguments (finished)
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
if (state == 0)
{
if (!trim_left && !trim_right)
{
if (ParserKeyword("BOTH").ignore(pos, expected))
{
trim_left = true;
trim_right = true;
char_override = true;
}
else if (ParserKeyword("LEADING").ignore(pos, expected))
{
trim_left = true;
char_override = true;
}
else if (ParserKeyword("TRAILING").ignore(pos, expected))
{
trim_right = true;
char_override = true;
}
else
{
trim_left = true;
trim_right = true;
}
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
if (char_override)
state = 1;
else
state = 2;
}
else
{
state = 2;
}
}
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
if (state == 1)
{
if (ParserKeyword("FROM").ignore(pos, expected))
{
action = Action::OPERAND;
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
if (!mergeElement())
return false;
2022-02-24 13:54:30 +00:00
2022-08-10 04:58:59 +00:00
to_remove = makeASTFunction("regexpQuoteMeta", elements[0]);
elements.clear();
2022-07-14 12:11:14 +00:00
state = 2;
}
}
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
if (state == 2)
{
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
{
if (!mergeElement())
return false;
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
ASTPtr pattern_node;
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
if (char_override)
{
auto pattern_func_node = std::make_shared<ASTFunction>();
auto pattern_list_args = std::make_shared<ASTExpressionList>();
if (trim_left && trim_right)
{
pattern_list_args->children = {
std::make_shared<ASTLiteral>("^["),
to_remove,
std::make_shared<ASTLiteral>("]+|["),
to_remove,
std::make_shared<ASTLiteral>("]+$")
};
function_name = "replaceRegexpAll";
}
else
{
if (trim_left)
{
pattern_list_args->children = {
std::make_shared<ASTLiteral>("^["),
to_remove,
std::make_shared<ASTLiteral>("]+")
};
}
else
{
/// trim_right == false not possible
pattern_list_args->children = {
std::make_shared<ASTLiteral>("["),
to_remove,
std::make_shared<ASTLiteral>("]+$")
};
}
function_name = "replaceRegexpOne";
}
2022-06-29 21:51:58 +00:00
2022-07-14 12:11:14 +00:00
pattern_func_node->name = "concat";
pattern_func_node->arguments = std::move(pattern_list_args);
pattern_func_node->children.push_back(pattern_func_node->arguments);
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
pattern_node = std::move(pattern_func_node);
}
else
{
if (trim_left && trim_right)
{
function_name = "trimBoth";
}
else
{
if (trim_left)
function_name = "trimLeft";
else
function_name = "trimRight";
}
}
2022-07-14 12:11:14 +00:00
if (char_override)
{
2022-08-10 04:58:59 +00:00
elements.push_back(pattern_node);
elements.push_back(std::make_shared<ASTLiteral>(""));
2022-07-14 12:11:14 +00:00
}
2022-07-14 12:11:14 +00:00
finished = true;
}
}
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
return true;
}
private:
bool trim_left;
bool trim_right;
bool char_override = false;
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
ASTPtr to_remove;
String function_name;
};
2022-04-08 15:36:36 +00:00
2022-06-23 08:18:14 +00:00
2022-07-14 12:11:14 +00:00
class DateAddLayer : public BaseLayer<TokenType::Comma, TokenType::ClosingRoundBracket>
{
public:
explicit DateAddLayer(const char * function_name_) : function_name(function_name_)
{
}
bool getResult(ASTPtr & op) override
{
if (parsed_interval_kind)
2022-04-08 03:30:49 +00:00
{
2022-08-10 04:58:59 +00:00
elements[0] = makeASTFunction(interval_kind.toNameOfFunctionToIntervalDataType(), elements[0]);
op = makeASTFunction(function_name, elements[1], elements[0]);
2022-07-14 12:11:14 +00:00
}
else
2022-08-10 04:58:59 +00:00
op = makeASTFunction(function_name, std::move(elements));
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
return true;
}
2022-04-08 03:30:49 +00:00
2022-07-14 12:11:14 +00:00
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
{
/// DATEADD(YEAR, 1, date) or DATEADD(INTERVAL 1 YEAR, date);
///
/// 0. Try to parse interval_kind (-> 1)
/// 1. Basic parser
2022-07-14 12:11:14 +00:00
if (state == 0)
2022-02-24 13:54:30 +00:00
{
2022-07-14 12:11:14 +00:00
if (parseIntervalKind(pos, expected, interval_kind))
2022-02-24 13:54:30 +00:00
{
2022-07-14 12:11:14 +00:00
if (!ParserToken(TokenType::Comma).ignore(pos, expected))
return false;
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
action = Action::OPERAND;
parsed_interval_kind = true;
}
state = 1;
2022-07-14 12:11:14 +00:00
}
2022-06-23 08:18:14 +00:00
2022-07-14 12:11:14 +00:00
if (state == 1)
{
return BaseLayer::parse(pos, expected, action);
}
2022-06-23 08:18:14 +00:00
2022-07-14 12:11:14 +00:00
return true;
}
2022-07-14 12:11:14 +00:00
private:
IntervalKind interval_kind;
const char * function_name;
bool parsed_interval_kind = false;
};
2022-06-16 01:53:27 +00:00
2022-07-14 12:11:14 +00:00
class DateDiffLayer : public BaseLayer<TokenType::Comma, TokenType::ClosingRoundBracket>
{
public:
bool getResult(ASTPtr & op) override
{
if (parsed_interval_kind)
{
2022-08-10 04:58:59 +00:00
if (elements.size() == 2)
op = makeASTFunction("dateDiff", std::make_shared<ASTLiteral>(interval_kind.toDateDiffUnit()), elements[0], elements[1]);
else if (elements.size() == 3)
op = makeASTFunction("dateDiff", std::make_shared<ASTLiteral>(interval_kind.toDateDiffUnit()), elements[0], elements[1], elements[2]);
2022-02-24 13:54:30 +00:00
else
2022-07-14 12:11:14 +00:00
return false;
2022-02-24 13:54:30 +00:00
}
else
{
2022-08-10 04:58:59 +00:00
op = makeASTFunction("dateDiff", std::move(elements));
2022-07-14 12:11:14 +00:00
}
return true;
}
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
{
/// 0. Try to parse interval_kind (-> 1)
/// 1. Basic parser
2022-07-14 12:11:14 +00:00
if (state == 0)
{
if (parseIntervalKind(pos, expected, interval_kind))
2022-02-24 13:54:30 +00:00
{
2022-07-14 12:11:14 +00:00
parsed_interval_kind = true;
2022-05-26 23:38:25 +00:00
2022-07-14 12:11:14 +00:00
if (!ParserToken(TokenType::Comma).ignore(pos, expected))
return false;
}
2022-05-26 23:38:25 +00:00
2022-07-14 12:11:14 +00:00
state = 1;
}
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
if (state == 1)
{
return BaseLayer::parse(pos, expected, action);
}
2022-06-22 21:59:20 +00:00
2022-07-14 12:11:14 +00:00
return true;
}
2022-06-29 21:51:58 +00:00
2022-07-14 12:11:14 +00:00
private:
IntervalKind interval_kind;
bool parsed_interval_kind = false;
};
2022-06-22 21:59:20 +00:00
2022-07-14 12:11:14 +00:00
class IntervalLayer : public Layer
{
public:
2022-09-07 01:45:13 +00:00
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
2022-07-14 12:11:14 +00:00
{
/// INTERVAL 1 HOUR or INTERVAL expr HOUR
///
/// 0. Try to parse interval_kind (-> 1)
2022-08-04 10:06:18 +00:00
/// 1. Basic parser
2022-07-14 12:11:14 +00:00
if (state == 0)
{
auto begin = pos;
auto init_expected = expected;
ASTPtr string_literal;
//// A String literal followed INTERVAL keyword,
/// the literal can be a part of an expression or
/// include Number and INTERVAL TYPE at the same time
if (ParserStringLiteral{}.parse(pos, string_literal, expected))
{
String literal;
if (string_literal->as<ASTLiteral &>().value.tryGet(literal))
{
Tokens tokens(literal.data(), literal.data() + literal.size());
IParser::Pos token_pos(tokens, 0);
Expected token_expected;
ASTPtr expr;
2022-06-22 21:59:20 +00:00
2022-07-14 12:11:14 +00:00
if (!ParserNumber{}.parse(token_pos, expr, token_expected))
{
2022-07-14 12:11:14 +00:00
return false;
}
2022-06-22 21:59:20 +00:00
else
{
2022-07-14 12:11:14 +00:00
/// case: INTERVAL '1' HOUR
/// back to begin
if (!token_pos.isValid())
{
pos = begin;
expected = init_expected;
}
else
{
/// case: INTERVAL '1 HOUR'
if (!parseIntervalKind(token_pos, token_expected, interval_kind))
return false;
2022-06-22 21:59:20 +00:00
2022-08-10 04:58:59 +00:00
elements = {makeASTFunction(interval_kind.toNameOfFunctionToIntervalDataType(), expr)};
2022-07-14 12:11:14 +00:00
finished = true;
return true;
}
2022-06-22 21:59:20 +00:00
}
2022-02-24 13:54:30 +00:00
}
2022-07-14 12:11:14 +00:00
}
state = 1;
return true;
2022-07-14 12:11:14 +00:00
}
2022-05-26 16:50:48 +00:00
2022-07-14 12:11:14 +00:00
if (state == 1)
{
2022-09-07 01:45:13 +00:00
if (action == Action::OPERATOR && parseIntervalKind(pos, expected, interval_kind))
2022-07-14 12:11:14 +00:00
{
if (!mergeElement())
return false;
2022-08-10 04:58:59 +00:00
elements = {makeASTFunction(interval_kind.toNameOfFunctionToIntervalDataType(), elements)};
2022-07-14 12:11:14 +00:00
finished = true;
}
}
2022-05-26 23:38:25 +00:00
2022-07-14 12:11:14 +00:00
return true;
}
2022-04-12 15:03:10 +00:00
2022-07-14 12:11:14 +00:00
private:
IntervalKind interval_kind;
};
2022-04-12 15:03:10 +00:00
2022-07-14 12:11:14 +00:00
class CaseLayer : public Layer
{
public:
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
{
/// CASE [x] WHEN expr THEN expr [WHEN expr THEN expr [...]] [ELSE expr] END
///
/// 0. Check if we have case expression [x] (-> 1)
/// 1. Parse keywords: WHEN (-> 2), ELSE (-> 3), END (finished)
/// 2. Parse THEN keyword (-> 1)
/// 3. Parse END keyword (finished)
2022-07-14 12:11:14 +00:00
if (state == 0)
{
auto old_pos = pos;
has_case_expr = !ParserKeyword("WHEN").ignore(pos, expected);
pos = old_pos;
2022-04-17 20:59:03 +00:00
2022-07-14 12:11:14 +00:00
state = 1;
}
if (state == 1)
{
if (ParserKeyword("WHEN").ignore(pos, expected))
2022-04-29 15:07:42 +00:00
{
2022-08-10 04:58:59 +00:00
if ((has_case_expr || !elements.empty()) && !mergeElement())
2022-04-29 15:07:42 +00:00
return false;
2022-07-14 12:11:14 +00:00
action = Action::OPERAND;
state = 2;
2022-04-29 15:07:42 +00:00
}
2022-07-14 12:11:14 +00:00
else if (ParserKeyword("ELSE").ignore(pos, expected))
2022-02-24 13:54:30 +00:00
{
2022-07-14 12:11:14 +00:00
if (!mergeElement())
return false;
action = Action::OPERAND;
state = 3;
2022-02-24 13:54:30 +00:00
}
2022-07-14 12:11:14 +00:00
else if (ParserKeyword("END").ignore(pos, expected))
2022-02-24 13:54:30 +00:00
{
2022-07-14 12:11:14 +00:00
if (!mergeElement())
return false;
2022-07-14 12:11:14 +00:00
Field field_with_null;
ASTLiteral null_literal(field_with_null);
2022-08-10 04:58:59 +00:00
elements.push_back(std::make_shared<ASTLiteral>(null_literal));
2022-07-14 12:11:14 +00:00
if (has_case_expr)
2022-08-10 04:58:59 +00:00
elements = {makeASTFunction("caseWithExpression", elements)};
2022-07-14 12:11:14 +00:00
else
2022-08-10 04:58:59 +00:00
elements = {makeASTFunction("multiIf", elements)};
2022-07-14 12:11:14 +00:00
finished = true;
}
}
2022-07-14 12:11:14 +00:00
if (state == 2)
{
2022-07-14 12:11:14 +00:00
if (ParserKeyword("THEN").ignore(pos, expected))
{
if (!mergeElement())
return false;
2022-07-14 12:11:14 +00:00
action = Action::OPERAND;
state = 1;
}
}
2022-07-14 12:11:14 +00:00
if (state == 3)
2021-05-24 07:07:25 +00:00
{
2022-07-14 12:11:14 +00:00
if (ParserKeyword("END").ignore(pos, expected))
{
if (!mergeElement())
return false;
2022-07-14 12:11:14 +00:00
if (has_case_expr)
2022-08-10 04:58:59 +00:00
elements = {makeASTFunction("caseWithExpression", elements)};
2022-07-14 12:11:14 +00:00
else
2022-08-10 04:58:59 +00:00
elements = {makeASTFunction("multiIf", elements)};
2022-07-14 12:11:14 +00:00
finished = true;
}
2021-05-24 07:07:25 +00:00
}
2022-07-14 12:11:14 +00:00
return true;
}
2022-07-14 12:11:14 +00:00
private:
bool has_case_expr;
};
2010-06-24 19:12:10 +00:00
2022-07-14 12:11:14 +00:00
bool ParseCastExpression(IParser::Pos & pos, ASTPtr & node, Expected & expected)
2012-11-20 22:48:38 +00:00
{
2022-07-14 12:11:14 +00:00
IParser::Pos begin = pos;
2012-11-20 22:48:38 +00:00
2022-07-14 12:11:14 +00:00
if (ParserCastOperator().parse(pos, node, expected))
return true;
pos = begin;
/// As an exception, negative numbers should be parsed as literals, and not as an application of the operator.
if (pos->type == TokenType::Minus)
{
if (ParserLiteral().parse(pos, node, expected))
return true;
}
2022-07-14 12:11:14 +00:00
return false;
2012-11-20 22:48:38 +00:00
}
2022-07-14 12:11:14 +00:00
bool ParseDateOperatorExpression(IParser::Pos & pos, ASTPtr & node, Expected & expected)
2021-05-04 03:43:17 +00:00
{
2022-07-14 12:11:14 +00:00
auto begin = pos;
/// If no DATE keyword, go to the nested parser.
if (!ParserKeyword("DATE").ignore(pos, expected))
2021-05-04 03:43:17 +00:00
return false;
2022-07-14 12:11:14 +00:00
ASTPtr expr;
if (!ParserStringLiteral().parse(pos, expr, expected))
2021-05-04 03:43:17 +00:00
{
2022-07-14 12:11:14 +00:00
pos = begin;
return false;
2021-05-04 03:43:17 +00:00
}
2022-07-14 12:11:14 +00:00
node = makeASTFunction("toDate", expr);
2021-05-04 03:43:17 +00:00
return true;
}
2022-07-14 12:11:14 +00:00
bool ParseTimestampOperatorExpression(IParser::Pos & pos, ASTPtr & node, Expected & expected)
2010-06-24 19:12:10 +00:00
{
2022-07-14 12:11:14 +00:00
auto begin = pos;
2010-06-24 19:12:10 +00:00
2022-07-14 12:11:14 +00:00
/// If no TIMESTAMP keyword, go to the nested parser.
if (!ParserKeyword("TIMESTAMP").ignore(pos, expected))
return false;
2010-06-24 19:12:10 +00:00
2022-07-14 12:11:14 +00:00
ASTPtr expr;
if (!ParserStringLiteral().parse(pos, expr, expected))
{
pos = begin;
return false;
}
2010-06-24 19:12:10 +00:00
2022-07-14 12:11:14 +00:00
node = makeASTFunction("toDateTime", expr);
2022-02-24 13:54:30 +00:00
2022-07-14 12:11:14 +00:00
return true;
2011-09-04 05:14:52 +00:00
}
2022-09-07 21:41:37 +00:00
template<class Type>
2022-08-12 19:20:17 +00:00
struct ParserExpressionImpl
{
2022-09-05 16:21:16 +00:00
static std::vector<std::pair<const char *, Operator>> operators_table;
static std::vector<std::pair<const char *, Operator>> unary_operators_table;
static const char * overlapping_operators_to_skip[];
2022-08-12 19:20:17 +00:00
static Operator finish_between_operator;
ParserCompoundIdentifier identifier_parser{false, true};
ParserNumber number_parser;
ParserAsterisk asterisk_parser;
ParserLiteral literal_parser;
ParserTupleOfLiterals tuple_literal_parser;
ParserArrayOfLiterals array_literal_parser;
ParserSubstitution substitution_parser;
ParserMySQLGlobalVariable mysql_global_variable_parser;
ParserKeyword any_parser{"ANY"};
ParserKeyword all_parser{"ALL"};
// Recursion
ParserQualifiedAsterisk qualified_asterisk_parser;
ParserColumnsMatcher columns_matcher_parser;
ParserSubquery subquery_parser;
bool parse(IParser::Pos & pos, ASTPtr & node, Expected & expected);
enum class ParseResult
{
OPERAND,
OPERATOR,
ERROR,
END,
};
using Layers = std::vector<std::unique_ptr<Layer>>;
2022-09-05 16:21:16 +00:00
ParseResult tryParseOperand(Layers & layers, IParser::Pos & pos, Expected & expected);
static ParseResult tryParseOperator(Layers & layers, IParser::Pos & pos, Expected & expected);
2022-08-12 19:20:17 +00:00
};
2022-07-14 12:11:14 +00:00
bool ParserExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
2021-07-28 07:02:10 +00:00
{
2022-09-07 21:41:37 +00:00
return ParserExpressionImpl<SingleElementLayer>().parse(pos, node, expected);
2022-09-05 16:21:16 +00:00
}
bool ParserIntervalOperatorExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
return ParserKeyword("INTERVAL").parse(pos, node, expected)
2022-09-07 21:41:37 +00:00
&& ParserExpressionImpl<IntervalLayer>().parse(pos, node, expected);
2022-09-05 16:21:16 +00:00
}
2022-09-07 21:41:37 +00:00
template<class Type>
std::vector<std::pair<const char *, Operator>> ParserExpressionImpl<Type>::operators_table({
2022-09-05 16:21:16 +00:00
{"->", Operator("lambda", 1, 2, OperatorType::Lambda)},
{"?", Operator("", 2, 0, OperatorType::StartIf)},
{":", Operator("if", 3, 3, OperatorType::FinishIf)},
{"OR", Operator("or", 3, 2, OperatorType::Mergeable)},
{"AND", Operator("and", 4, 2, OperatorType::Mergeable)},
{"BETWEEN", Operator("", 6, 0, OperatorType::StartBetween)},
{"NOT BETWEEN", Operator("", 6, 0, OperatorType::StartNotBetween)},
{"IS NULL", Operator("isNull", 8, 1, OperatorType::IsNull)},
{"IS NOT NULL", Operator("isNotNull", 8, 1, OperatorType::IsNull)},
2022-07-14 12:11:14 +00:00
{"==", Operator("equals", 9, 2, OperatorType::Comparison)},
{"!=", Operator("notEquals", 9, 2, OperatorType::Comparison)},
{"<>", Operator("notEquals", 9, 2, OperatorType::Comparison)},
{"<=", Operator("lessOrEquals", 9, 2, OperatorType::Comparison)},
{">=", Operator("greaterOrEquals", 9, 2, OperatorType::Comparison)},
{"<", Operator("less", 9, 2, OperatorType::Comparison)},
{">", Operator("greater", 9, 2, OperatorType::Comparison)},
{"=", Operator("equals", 9, 2, OperatorType::Comparison)},
{"LIKE", Operator("like", 9)},
{"ILIKE", Operator("ilike", 9)},
{"NOT LIKE", Operator("notLike", 9)},
{"NOT ILIKE", Operator("notILike", 9)},
{"IN", Operator("in", 9)},
{"NOT IN", Operator("notIn", 9)},
{"GLOBAL IN", Operator("globalIn", 9)},
{"GLOBAL NOT IN", Operator("globalNotIn", 9)},
2022-09-05 16:21:16 +00:00
{"||", Operator("concat", 10, 2, OperatorType::Mergeable)},
{"+", Operator("plus", 11)},
{"-", Operator("minus", 11)},
{"*", Operator("multiply", 12)},
{"/", Operator("divide", 12)},
{"%", Operator("modulo", 12)},
{"MOD", Operator("modulo", 12)},
{"DIV", Operator("intDiv", 12)},
{".", Operator("tupleElement", 14, 2, OperatorType::TupleElement)},
2022-07-14 12:11:14 +00:00
{"[", Operator("arrayElement", 14, 2, OperatorType::ArrayElement)},
{"::", Operator("CAST", 14, 2, OperatorType::Cast)},
2022-07-14 12:11:14 +00:00
});
2022-09-07 21:41:37 +00:00
template<class Type>
std::vector<std::pair<const char *, Operator>> ParserExpressionImpl<Type>::unary_operators_table({
2022-07-14 12:11:14 +00:00
{"NOT", Operator("not", 5, 1)},
{"-", Operator("negate", 13, 1)}
});
2022-09-07 21:41:37 +00:00
template<class Type>
Operator ParserExpressionImpl<Type>::finish_between_operator = Operator("", 7, 0, OperatorType::FinishBetween);
2022-07-14 12:11:14 +00:00
2022-09-07 21:41:37 +00:00
template<class Type>
const char * ParserExpressionImpl<Type>::overlapping_operators_to_skip[] =
2022-09-05 16:21:16 +00:00
{
"IN PARTITION",
nullptr
};
2022-09-07 21:41:37 +00:00
template<class Type>
bool ParserExpressionImpl<Type>::parse(IParser::Pos & pos, ASTPtr & node, Expected & expected)
2022-08-12 19:20:17 +00:00
{
2022-07-14 12:11:14 +00:00
Action next = Action::OPERAND;
std::vector<std::unique_ptr<Layer>> layers;
2022-09-05 16:21:16 +00:00
layers.push_back(std::make_unique<Type>());
2022-07-14 12:11:14 +00:00
2022-09-05 16:21:16 +00:00
while (true)
2022-07-14 12:11:14 +00:00
{
2022-09-05 16:21:16 +00:00
while (pos.isValid())
2021-07-28 07:02:10 +00:00
{
2022-09-05 16:21:16 +00:00
if (!layers.back()->parse(pos, expected, next))
break;
2022-07-14 12:11:14 +00:00
2022-09-05 16:21:16 +00:00
if (layers.back()->isFinished())
{
if (layers.size() == 1)
break;
2021-07-28 07:02:10 +00:00
2022-09-05 16:21:16 +00:00
next = Action::OPERATOR;
2022-08-10 04:58:59 +00:00
2022-09-05 16:21:16 +00:00
ASTPtr res;
if (!layers.back()->getResult(res))
break;
layers.pop_back();
layers.back()->pushOperand(res);
continue;
2022-08-10 04:58:59 +00:00
}
2022-09-05 16:21:16 +00:00
ParseResult result;
2021-07-28 07:02:10 +00:00
2022-09-05 16:21:16 +00:00
if (next == Action::OPERAND)
result = tryParseOperand(layers, pos, expected);
else
result = tryParseOperator(layers, pos, expected);
2022-08-12 19:20:17 +00:00
2022-09-05 16:21:16 +00:00
if (result == ParseResult::END)
break;
else if (result == ParseResult::ERROR)
break;
else if (result == ParseResult::OPERATOR)
next = Action::OPERATOR;
else if (result == ParseResult::OPERAND)
next = Action::OPERAND;
}
2022-08-12 19:20:17 +00:00
2022-09-05 16:21:16 +00:00
/// When we exit the loop we should be on the 1st level
if (layers.size() == 1 && layers.back()->getResult(node))
return true;
2021-07-28 07:02:10 +00:00
2022-09-05 16:21:16 +00:00
layers.pop_back();
2021-07-28 07:02:10 +00:00
2022-09-07 01:45:13 +00:00
/// We try to check whether there was a checkpoint
while (!layers.empty() && !layers.back()->saved_checkpoint)
2022-09-05 16:21:16 +00:00
layers.pop_back();
2021-07-28 07:02:10 +00:00
2022-09-05 16:21:16 +00:00
if (layers.empty())
return false;
/// Currently all checkpoints are located in operand section
next = Action::OPERAND;
2022-09-07 01:45:13 +00:00
auto saved_checkpoint = layers.back()->saved_checkpoint.value();
layers.back()->saved_checkpoint.reset();
pos = saved_checkpoint.first;
layers.back()->current_checkpoint = saved_checkpoint.second;
2022-09-05 16:21:16 +00:00
}
2022-08-12 19:20:17 +00:00
}
2011-09-04 05:14:52 +00:00
2022-09-07 21:41:37 +00:00
template<class Type>
typename ParserExpressionImpl<Type>::ParseResult ParserExpressionImpl<Type>::tryParseOperand(Layers & layers, IParser::Pos & pos, Expected & expected)
2022-08-12 19:20:17 +00:00
{
ASTPtr tmp;
2022-08-12 19:20:17 +00:00
/// Special case for cast expression
if (layers.back()->previousType() != OperatorType::TupleElement &&
ParseCastExpression(pos, tmp, expected))
{
layers.back()->pushOperand(std::move(tmp));
return ParseResult::OPERATOR;
}
2022-08-12 19:20:17 +00:00
if (layers.back()->previousType() == OperatorType::Comparison)
{
SubqueryFunctionType subquery_function_type = SubqueryFunctionType::NONE;
2019-10-09 13:02:05 +00:00
2022-08-12 19:20:17 +00:00
if (any_parser.ignore(pos, expected) && subquery_parser.parse(pos, tmp, expected))
subquery_function_type = SubqueryFunctionType::ANY;
else if (all_parser.ignore(pos, expected) && subquery_parser.parse(pos, tmp, expected))
subquery_function_type = SubqueryFunctionType::ALL;
2019-10-09 13:02:05 +00:00
2022-08-12 19:20:17 +00:00
if (subquery_function_type != SubqueryFunctionType::NONE)
{
Operator prev_op;
ASTPtr function, argument;
2022-08-12 19:20:17 +00:00
if (!layers.back()->popOperator(prev_op))
return ParseResult::ERROR;
if (!layers.back()->popOperand(argument))
return ParseResult::ERROR;
2022-08-12 19:20:17 +00:00
function = makeASTFunction(prev_op.function_name, argument, tmp);
2022-08-12 19:20:17 +00:00
if (!modifyAST(function, subquery_function_type))
return ParseResult::ERROR;
2022-08-12 19:20:17 +00:00
layers.back()->pushOperand(std::move(function));
return ParseResult::OPERATOR;
}
}
2022-08-12 19:20:17 +00:00
/// Try to find any unary operators
2022-09-05 16:21:16 +00:00
auto cur_op = unary_operators_table.begin();
for (; cur_op != unary_operators_table.end(); ++cur_op)
2022-08-12 19:20:17 +00:00
{
if (parseOperator(pos, cur_op->first, expected))
break;
}
2022-09-05 16:21:16 +00:00
if (cur_op != unary_operators_table.end())
2022-08-12 19:20:17 +00:00
{
layers.back()->pushOperator(cur_op->second);
return ParseResult::OPERAND;
}
2022-08-12 19:20:17 +00:00
auto old_pos = pos;
2022-09-07 01:45:13 +00:00
auto current_checkpoint = layers.back()->current_checkpoint;
layers.back()->current_checkpoint = Checkpoint::None;
if (current_checkpoint != Checkpoint::Interval && parseOperator(pos, "INTERVAL", expected))
2022-08-12 19:20:17 +00:00
{
2022-09-07 01:45:13 +00:00
layers.back()->saved_checkpoint = {old_pos, Checkpoint::Interval};
2022-09-05 16:21:16 +00:00
layers.push_back(std::make_unique<IntervalLayer>());
return ParseResult::OPERAND;
}
2022-09-07 01:45:13 +00:00
else if (current_checkpoint != Checkpoint::Case && parseOperator(pos, "CASE", expected))
2022-09-05 16:21:16 +00:00
{
2022-09-07 01:45:13 +00:00
layers.back()->saved_checkpoint = {old_pos, Checkpoint::Case};
2022-09-05 16:21:16 +00:00
layers.push_back(std::make_unique<CaseLayer>());
return ParseResult::OPERAND;
}
2022-08-12 19:20:17 +00:00
if (ParseDateOperatorExpression(pos, tmp, expected) ||
ParseTimestampOperatorExpression(pos, tmp, expected) ||
tuple_literal_parser.parse(pos, tmp, expected) ||
2022-09-07 01:45:13 +00:00
(layers.size() == 1 && array_literal_parser.parse(pos, tmp, expected)) ||
2022-08-12 19:20:17 +00:00
number_parser.parse(pos, tmp, expected) ||
literal_parser.parse(pos, tmp, expected) ||
asterisk_parser.parse(pos, tmp, expected) ||
qualified_asterisk_parser.parse(pos, tmp, expected) ||
columns_matcher_parser.parse(pos, tmp, expected))
{
layers.back()->pushOperand(std::move(tmp));
}
else if (identifier_parser.parse(pos, tmp, expected))
{
if (pos->type == TokenType::OpeningRoundBracket)
{
++pos;
2022-08-12 19:20:17 +00:00
String function_name = getIdentifierName(tmp);
String function_name_lowercase = Poco::toLower(function_name);
if (function_name_lowercase == "cast")
layers.push_back(std::make_unique<CastLayer>());
else if (function_name_lowercase == "extract")
layers.push_back(std::make_unique<ExtractLayer>());
else if (function_name_lowercase == "substring")
layers.push_back(std::make_unique<SubstringLayer>());
else if (function_name_lowercase == "position")
layers.push_back(std::make_unique<PositionLayer>());
else if (function_name_lowercase == "exists")
layers.push_back(std::make_unique<ExistsLayer>());
else if (function_name_lowercase == "trim")
layers.push_back(std::make_unique<TrimLayer>(false, false));
else if (function_name_lowercase == "ltrim")
layers.push_back(std::make_unique<TrimLayer>(true, false));
else if (function_name_lowercase == "rtrim")
layers.push_back(std::make_unique<TrimLayer>(false, true));
else if (function_name_lowercase == "dateadd" || function_name_lowercase == "date_add"
|| function_name_lowercase == "timestampadd" || function_name_lowercase == "timestamp_add")
layers.push_back(std::make_unique<DateAddLayer>("plus"));
else if (function_name_lowercase == "datesub" || function_name_lowercase == "date_sub"
|| function_name_lowercase == "timestampsub" || function_name_lowercase == "timestamp_sub")
layers.push_back(std::make_unique<DateAddLayer>("minus"));
else if (function_name_lowercase == "datediff" || function_name_lowercase == "date_diff"
|| function_name_lowercase == "timestampdiff" || function_name_lowercase == "timestamp_diff")
layers.push_back(std::make_unique<DateDiffLayer>());
else if (function_name_lowercase == "grouping")
layers.push_back(std::make_unique<FunctionLayer>(function_name_lowercase));
else
layers.push_back(std::make_unique<FunctionLayer>(function_name));
2022-08-12 19:20:17 +00:00
return ParseResult::OPERAND;
}
else
{
layers.back()->pushOperand(std::move(tmp));
}
}
else if (substitution_parser.parse(pos, tmp, expected))
{
layers.back()->pushOperand(std::move(tmp));
}
else if (pos->type == TokenType::OpeningRoundBracket)
{
if (subquery_parser.parse(pos, tmp, expected))
{
layers.back()->pushOperand(std::move(tmp));
return ParseResult::OPERATOR;
}
2022-08-12 19:20:17 +00:00
++pos;
layers.push_back(std::make_unique<RoundBracketsLayer>());
return ParseResult::OPERAND;
}
else if (pos->type == TokenType::OpeningSquareBracket)
{
++pos;
layers.push_back(std::make_unique<ArrayLayer>());
return ParseResult::OPERAND;
}
else if (mysql_global_variable_parser.parse(pos, tmp, expected))
{
layers.back()->pushOperand(std::move(tmp));
}
else
{
return ParseResult::END;
}
2022-08-12 19:20:17 +00:00
return ParseResult::OPERATOR;
}
2022-09-07 21:41:37 +00:00
template<class Type>
typename ParserExpressionImpl<Type>::ParseResult ParserExpressionImpl<Type>::tryParseOperator(Layers & layers, IParser::Pos & pos, Expected & expected)
2022-08-12 19:20:17 +00:00
{
ASTPtr tmp;
2022-08-12 19:20:17 +00:00
/// ParserExpression can be called in this part of the query:
/// ALTER TABLE partition_all2 CLEAR INDEX [ p ] IN PARTITION ALL
///
/// 'IN PARTITION' here is not an 'IN' operator, so we should stop parsing immediately
Expected stub;
2022-09-05 16:21:16 +00:00
for (const char ** it = overlapping_operators_to_skip; *it; ++it)
if (ParserKeyword{*it}.checkWithoutMoving(pos, stub))
return ParseResult::END;
2022-09-05 16:21:16 +00:00
/// Try to find operators from 'operators_table'
auto cur_op = operators_table.begin();
for (; cur_op != operators_table.end(); ++cur_op)
2022-08-12 19:20:17 +00:00
{
2022-09-07 21:41:37 +00:00
if (parseOperator(pos, cur_op->first, expected))
2022-08-12 19:20:17 +00:00
break;
}
2022-09-05 16:21:16 +00:00
if (cur_op == operators_table.end())
2022-08-12 19:20:17 +00:00
{
if (layers.back()->allow_alias && ParserAlias(layers.back()->allow_alias_without_as_keyword).parse(pos, tmp, expected))
{
if (!layers.back()->insertAlias(tmp))
return ParseResult::ERROR;
2022-08-12 19:20:17 +00:00
return ParseResult::OPERAND;
}
2022-08-12 19:20:17 +00:00
return ParseResult::END;
}
2022-08-12 19:20:17 +00:00
auto op = cur_op->second;
2022-08-12 19:20:17 +00:00
if (op.type == OperatorType::Lambda)
{
if (!layers.back()->parseLambda())
return ParseResult::ERROR;
2022-08-12 19:20:17 +00:00
layers.back()->pushOperator(op);
return ParseResult::OPERAND;
}
2022-09-05 16:21:16 +00:00
/// 'AND' can be both boolean function and part of the '... BETWEEN ... AND ...' operator
2022-08-12 19:20:17 +00:00
if (op.function_name == "and" && layers.back()->between_counter)
{
layers.back()->between_counter--;
op = finish_between_operator;
}
2022-08-12 19:20:17 +00:00
while (layers.back()->previousPriority() >= op.priority)
{
ASTPtr function;
Operator prev_op;
layers.back()->popOperator(prev_op);
2022-08-12 19:20:17 +00:00
/// Mergeable operators are operators that are merged into one function:
/// For example: 'a OR b OR c' -> 'or(a, b, c)' and not 'or(or(a,b), c)'
if (prev_op.type == OperatorType::Mergeable && op.function_name == prev_op.function_name)
{
op.arity += prev_op.arity - 1;
break;
}
2022-08-12 19:20:17 +00:00
if (prev_op.type == OperatorType::FinishBetween)
{
Operator tmp_op;
if (!layers.back()->popOperator(tmp_op))
return ParseResult::ERROR;
2022-08-12 19:20:17 +00:00
if (tmp_op.type != OperatorType::StartBetween && tmp_op.type != OperatorType::StartNotBetween)
return ParseResult::ERROR;
2022-08-12 19:20:17 +00:00
bool negative = tmp_op.type == OperatorType::StartNotBetween;
ASTs arguments;
if (!layers.back()->popLastNOperands(arguments, 3))
return ParseResult::ERROR;
function = makeBetweenOperator(negative, arguments);
2020-10-14 15:02:51 +00:00
}
2022-08-12 19:20:17 +00:00
else
{
function = makeASTFunction(prev_op.function_name);
if (!layers.back()->popLastNOperands(function->children[0]->children, prev_op.arity))
return ParseResult::ERROR;
}
layers.back()->pushOperand(function);
2020-10-14 15:02:51 +00:00
}
2022-08-12 19:20:17 +00:00
layers.back()->pushOperator(op);
2022-08-12 19:20:17 +00:00
if (op.type == OperatorType::ArrayElement)
layers.push_back(std::make_unique<ArrayElementLayer>());
2019-10-07 16:23:16 +00:00
2019-10-08 09:47:17 +00:00
2022-08-12 19:20:17 +00:00
ParseResult next = ParseResult::OPERAND;
2022-09-05 16:21:16 +00:00
/// isNull & isNotNull are postfix unary operators
2022-08-12 19:20:17 +00:00
if (op.type == OperatorType::IsNull)
next = ParseResult::OPERATOR;
if (op.type == OperatorType::StartBetween || op.type == OperatorType::StartNotBetween)
layers.back()->between_counter++;
if (op.type == OperatorType::Cast)
{
next = ParseResult::OPERATOR;
ASTPtr type_ast;
if (!ParserDataType().parse(pos, type_ast, expected))
return ParseResult::ERROR;
layers.back()->pushOperand(std::make_shared<ASTLiteral>(queryToString(type_ast)));
}
return next;
2019-10-07 16:23:16 +00:00
}
2010-06-24 19:12:10 +00:00
}