ClickHouse/src/Parsers/ExpressionListParsers.cpp

1430 lines
41 KiB
C++
Raw Normal View History

2021-10-31 15:11:46 +00:00
#include <string_view>
#include <Parsers/ExpressionListParsers.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/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-02-24 13:54:30 +00:00
#include <base/logger_useful.h>
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
const char * ParserMultiplicativeExpression::operators[] =
{
"*", "multiply",
"/", "divide",
"%", "modulo",
"MOD", "modulo",
"DIV", "intDiv",
nullptr
};
2021-06-20 19:34:18 +00:00
const char * ParserUnaryExpression::operators[] =
{
"-", "negate",
2021-06-20 19:34:18 +00:00
"NOT", "not",
nullptr
};
const char * ParserAdditiveExpression::operators[] =
{
"+", "plus",
"-", "minus",
nullptr
};
const char * ParserComparisonExpression::operators[] =
{
"==", "equals",
"!=", "notEquals",
"<>", "notEquals",
"<=", "lessOrEquals",
">=", "greaterOrEquals",
"<", "less",
">", "greater",
"=", "equals",
"LIKE", "like",
"ILIKE", "ilike",
"NOT LIKE", "notLike",
"NOT ILIKE", "notILike",
"IN", "in",
"NOT IN", "notIn",
"GLOBAL IN", "globalIn",
"GLOBAL NOT IN", "globalNotIn",
nullptr
};
const char * ParserComparisonExpression::overlapping_operators_to_skip[] =
{
"IN PARTITION",
nullptr
};
const char * ParserLogicalNotExpression::operators[] =
{
"NOT", "not",
nullptr
};
const char * ParserArrayElementExpression::operators[] =
{
"[", "arrayElement",
nullptr
};
const char * ParserTupleElementExpression::operators[] =
{
".", "tupleElement",
nullptr
};
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;
};
/// Parse UNION type
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
{
// SELECT ... UNION ALL SELECT ...
2021-08-14 12:31:55 +00:00
if (s_all_parser.check(pos, expected))
2020-10-26 09:33:34 +00:00
{
union_modes.push_back(SelectUnionMode::ALL);
2020-10-26 09:33:34 +00:00
}
// SELECT ... UNION DISTINCT SELECT ...
2021-08-14 12:31:55 +00:00
else if (s_distinct_parser.check(pos, expected))
2020-10-26 09:33:34 +00:00
{
union_modes.push_back(SelectUnionMode::DISTINCT);
2020-10-26 09:33:34 +00:00
}
// SELECT ... UNION SELECT ...
else
2021-08-13 09:57:15 +00:00
{
union_modes.push_back(SelectUnionMode::Unspecified);
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
{
union_modes.push_back(SelectUnionMode::EXCEPT);
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))
{
union_modes.push_back(SelectUnionMode::INTERSECT);
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;
2021-08-15 06:55:43 +00:00
if (allow_any_all_operators && ParserKeyword("ANY").ignore(pos, expected))
2021-06-03 02:19:07 +00:00
subquery_function_type = SubqueryFunctionType::ANY;
2021-08-15 06:55:43 +00:00
else if (allow_any_all_operators && ParserKeyword("ALL").ignore(pos, expected))
2021-06-03 02:19:07 +00:00
subquery_function_type = SubqueryFunctionType::ALL;
2021-08-15 06:55:43 +00:00
else if (!(remaining_elem_parser ? remaining_elem_parser : first_elem_parser)->parse(pos, elem, expected))
2021-06-03 02:19:07 +00:00
return false;
if (subquery_function_type != SubqueryFunctionType::NONE && !ParserSubquery().parse(pos, elem, expected))
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);
2021-08-15 06:55:43 +00:00
if (allow_any_all_operators && 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
bool ParserBetweenExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
/// For the expression (subject [NOT] BETWEEN left AND right)
2021-12-21 09:39:31 +00:00
/// create an AST the same as for (subject >= left AND subject <= right).
2019-02-02 12:18:30 +00:00
ParserKeyword s_not("NOT");
ParserKeyword s_between("BETWEEN");
ParserKeyword s_and("AND");
ASTPtr subject;
ASTPtr left;
ASTPtr right;
if (!elem_parser.parse(pos, subject, expected))
return false;
2019-02-10 20:17:53 +00:00
bool negative = s_not.ignore(pos, expected);
if (!s_between.ignore(pos, expected))
2019-02-10 20:17:53 +00:00
{
2019-02-10 20:21:22 +00:00
if (negative)
2019-02-10 20:23:24 +00:00
--pos;
2019-02-10 20:21:22 +00:00
/// No operator was parsed, just return element.
node = subject;
2019-02-10 20:17:53 +00:00
}
else
{
if (!elem_parser.parse(pos, left, expected))
return false;
if (!s_and.ignore(pos, expected))
return false;
if (!elem_parser.parse(pos, right, expected))
return false;
2019-02-02 11:23:25 +00:00
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(subject);
args_left_expr->children.emplace_back(left);
args_right_expr->children.emplace_back(subject);
args_right_expr->children.emplace_back(right);
2019-02-10 20:17:53 +00:00
if (negative)
{
2019-02-10 20:17:53 +00:00
/// NOT BETWEEN
f_left_expr->name = "less";
f_right_expr->name = "greater";
f_combined_expression->name = "or";
}
else
{
2019-02-10 20:17:53 +00:00
/// 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);
2019-02-02 11:23:25 +00:00
f_combined_expression->arguments = args_combined_expression;
f_combined_expression->children.emplace_back(f_combined_expression->arguments);
2019-02-10 20:08:44 +00:00
node = f_combined_expression;
}
return true;
}
bool ParserTernaryOperatorExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ParserToken symbol1(TokenType::QuestionMark);
ParserToken symbol2(TokenType::Colon);
ASTPtr elem_cond;
ASTPtr elem_then;
ASTPtr elem_else;
if (!elem_parser.parse(pos, elem_cond, expected))
return false;
if (!symbol1.ignore(pos, expected))
node = elem_cond;
else
{
if (!elem_parser.parse(pos, elem_then, expected))
return false;
if (!symbol2.ignore(pos, expected))
return false;
if (!elem_parser.parse(pos, elem_else, expected))
return false;
2017-04-02 17:37:49 +00:00
/// the function corresponding to the operator
auto function = std::make_shared<ASTFunction>();
2017-04-02 17:37:49 +00:00
/// function arguments
auto exp_list = std::make_shared<ASTExpressionList>();
function->name = "if";
function->arguments = exp_list;
function->children.push_back(exp_list);
exp_list->children.push_back(elem_cond);
exp_list->children.push_back(elem_then);
exp_list->children.push_back(elem_else);
node = function;
}
return true;
}
bool ParserLambdaExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ParserToken arrow(TokenType::Arrow);
ParserToken open(TokenType::OpeningRoundBracket);
ParserToken close(TokenType::ClosingRoundBracket);
Pos begin = pos;
do
{
ASTPtr inner_arguments;
ASTPtr expression;
bool was_open = false;
if (open.ignore(pos, expected))
{
was_open = true;
}
if (!ParserList(std::make_unique<ParserIdentifier>(), std::make_unique<ParserToken>(TokenType::Comma)).parse(pos, inner_arguments, expected))
break;
if (was_open)
{
if (!close.ignore(pos, expected))
break;
}
if (!arrow.ignore(pos, expected))
break;
if (!elem_parser.parse(pos, expression, expected))
return false;
/// lambda(tuple(inner_arguments), expression)
auto lambda = std::make_shared<ASTFunction>();
node = lambda;
lambda->name = "lambda";
auto outer_arguments = std::make_shared<ASTExpressionList>();
lambda->arguments = outer_arguments;
lambda->children.push_back(lambda->arguments);
auto tuple = std::make_shared<ASTFunction>();
outer_arguments->children.push_back(tuple);
tuple->name = "tuple";
tuple->arguments = inner_arguments;
tuple->children.push_back(inner_arguments);
outer_arguments->children.push_back(expression);
return true;
}
while (false);
pos = begin;
return elem_parser.parse(pos, node, expected);
}
2022-02-24 13:54:30 +00:00
////////////////////////////////////////////////////////////////////////////////////////
// class Operator:
// - defines structure of certain operator
class Operator
{
public:
Operator()
{
}
Operator(String func_name_, Int32 priority_, Int32 arity_) : func_name(func_name_), priority(priority_), arity(arity_)
{
}
String func_name;
Int32 priority;
Int32 arity;
};
class Layer
{
public:
Layer(TokenType end_bracket_ = TokenType::Whitespace, String func_name_ = "") : end_bracket(end_bracket_), func_name(func_name_)
{
}
bool popOperator(Operator & op)
{
if (operators.size() == 0)
return false;
op = std::move(operators.back());
operators.pop_back();
return true;
}
void pushOperator(Operator op)
{
operators.push_back(std::move(op));
}
bool popOperand(ASTPtr & op)
{
if (operands.size() == 0)
return false;
op = std::move(operands.back());
operands.pop_back();
return true;
}
void pushOperand(ASTPtr op)
{
operands.push_back(std::move(op));
}
void pushResult(ASTPtr op)
{
result.push_back(std::move(op));
}
bool getResult(ASTPtr & op)
{
ASTs res;
std::swap(res, result);
if (!func_name.empty())
{
// Round brackets can mean priority operator together with function tuple()
if (func_name == "tuple" && res.size() == 1)
op = std::move(res[0]);
else
op = makeASTFunction(func_name, std::move(res));
return true;
}
if (res.size() == 1)
{
op = std::move(res[0]);
return true;
}
return false;
}
TokenType endBracket()
{
return end_bracket;
}
int previousPriority()
{
if (operators.empty())
return 0;
return operators.back().priority;
}
int empty()
{
return operators.empty() && operands.empty();
}
bool lastNOperands(ASTs & asts, size_t n)
{
if (n > operands.size())
return false;
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());
return true;
}
private:
std::vector<Operator> operators;
ASTs operands;
ASTs result;
TokenType end_bracket;
String func_name;
};
bool ParseCastExpression(IParser::Pos & pos, ASTPtr & node, Expected & expected)
{
IParser::Pos begin = pos;
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;
}
return false;
}
bool ParseDateOperatorExpression(IParser::Pos & pos, ASTPtr & node, Expected & expected)
{
auto begin = pos;
/// If no DATE keyword, go to the nested parser.
if (!ParserKeyword("DATE").ignore(pos, expected))
return false;
ASTPtr expr;
if (!ParserStringLiteral().parse(pos, expr, expected))
{
pos = begin;
return false;
}
node = makeASTFunction("toDate", expr);
return true;
}
bool ParseTimestampOperatorExpression(IParser::Pos & pos, ASTPtr & node, Expected & expected)
{
auto begin = pos;
/// If no TIMESTAMP keyword, go to the nested parser.
if (!ParserKeyword("TIMESTAMP").ignore(pos, expected))
return false;
ASTPtr expr;
if (!ParserStringLiteral().parse(pos, expr, expected))
{
pos = begin;
return false;
}
node = makeASTFunction("toDateTime", expr);
return true;
}
bool wrapLayer(Layer & layer)
{
Operator cur_op;
while (layer.popOperator(cur_op))
{
auto func = makeASTFunction(cur_op.func_name);
if (!layer.lastNOperands(func->children[0]->children, cur_op.arity))
return false;
layer.pushOperand(func);
}
ASTPtr res;
if (!layer.popOperand(res))
return false;
layer.pushResult(res);
return layer.empty();
}
enum Action
{
OPERAND,
OPERATOR
};
bool ParserExpression2::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
static std::vector<std::pair<const char *, Operator>> op_table({
{"+", Operator("plus", 20, 2)}, // Base arithmetic
2022-02-24 13:54:30 +00:00
{"-", Operator("minus", 20, 2)},
{"*", Operator("multiply", 30, 2)},
{"/", Operator("divide", 30, 2)},
{"%", Operator("modulo", 30, 2)},
{"MOD", Operator("modulo", 30, 2)},
{"DIV", Operator("intDiv", 30, 2)},
{"==", Operator("equals", 10, 2)}, // Base logic
{"!=", Operator("notEquals", 10, 2)},
{"<>", Operator("notEquals", 10, 2)},
{"<=", Operator("lessOrEquals", 10, 2)},
{">=", Operator("greaterOrEquals", 10, 2)},
{"<", Operator("less", 10, 2)},
{">", Operator("greater", 10, 2)},
{"=", Operator("equals", 10, 2)},
{"AND", Operator("and", 5, 2)}, // AND OR
{"OR", Operator("or", 4, 2)},
{"||", Operator("concat", 30, 2)}, // concat() func
{".", Operator("tupleElement", 40, 2)}, // tupleElement() func
{"IS NULL", Operator("isNull", 40, 1)}, // IS (NOT) NULL - correct priority ?
{"IS NOT NULL", Operator("isNotNull", 40, 1)},
{"LIKE", Operator("like", 10, 2)}, // LIKE funcs
{"ILIKE", Operator("ilike", 10, 2)},
{"NOT LIKE", Operator("notLike", 10, 2)},
{"NOT ILIKE", Operator("notILike", 10, 2)},
{"IN", Operator("in", 10, 2)}, // IN funcs
{"NOT IN", Operator("notIn", 10, 2)},
{"GLOBAL IN", Operator("globalIn", 10, 2)},
{"GLOBAL NOT IN", Operator("globalNotIn", 10, 2)},
});
static std::vector<std::pair<const char *, Operator>> op_table_unary({
{"-", Operator("negate", 40, 1)},
{"NOT", Operator("not", 9, 1)}
});
ParserCompoundIdentifier identifier_parser;
ParserNumber number_parser;
ParserAsterisk asterisk_parser;
ParserLiteral literal_parser;
ParserTupleOfLiterals tuple_literal_parser;
ParserArrayOfLiterals array_literal_parser;
2022-02-24 13:54:30 +00:00
Action next = Action::OPERAND;
std::vector<Layer> storage(1);
while (pos.isValid())
{
if (next == Action::OPERAND)
{
next = Action::OPERATOR;
ASTPtr tmp;
/// Special case for cast expression
if (ParseCastExpression(pos, tmp, expected))
{
storage.back().pushOperand(std::move(tmp));
continue;
}
/// Try to find any unary operators
auto cur_op = op_table_unary.begin();
for (; cur_op != op_table_unary.end(); ++cur_op)
{
if (parseOperator(pos, cur_op->first, expected))
break;
}
if (cur_op != op_table_unary.end())
{
next = Action::OPERAND;
storage.back().pushOperator(cur_op->second);
}
else if (ParseDateOperatorExpression(pos, tmp, expected) ||
ParseTimestampOperatorExpression(pos, tmp, expected) ||
tuple_literal_parser.parse(pos, tmp, expected) ||
array_literal_parser.parse(pos, tmp, expected) ||
number_parser.parse(pos, tmp, expected) ||
literal_parser.parse(pos, tmp, expected))
2022-02-24 13:54:30 +00:00
{
storage.back().pushOperand(std::move(tmp));
}
else if (identifier_parser.parse(pos, tmp, expected) ||
asterisk_parser.parse(pos, tmp, expected))
2022-02-24 13:54:30 +00:00
{
/// If the next token is '(' then it is a plain function, '[' - arrayElement function
if (pos->type == TokenType::OpeningRoundBracket)
{
++pos;
/// Special case for function with zero arguments: f()
if (pos->type == TokenType::ClosingRoundBracket)
{
++pos;
auto function = makeASTFunction(getIdentifierName(tmp));
storage.back().pushOperand(function);
}
else
{
next = Action::OPERAND;
storage.emplace_back(TokenType::ClosingRoundBracket, getIdentifierName(tmp));
}
2022-02-24 13:54:30 +00:00
}
else if (pos->type == TokenType::OpeningSquareBracket)
{
next = Action::OPERAND;
storage.back().pushOperand(std::move(tmp));
storage.back().pushOperator(Operator("arrayElement", 40, 2));
storage.emplace_back(TokenType::ClosingSquareBracket);
++pos;
}
else
{
storage.back().pushOperand(std::move(tmp));
}
}
else if (pos->type == TokenType::OpeningRoundBracket)
{
next = Action::OPERAND;
storage.emplace_back(TokenType::ClosingRoundBracket, "tuple");
++pos;
}
else if (pos->type == TokenType::OpeningSquareBracket)
{
++pos;
/// Special case for empty array: []
if (pos->type == TokenType::ClosingSquareBracket)
{
++pos;
auto function = makeASTFunction("array");
storage.back().pushOperand(function);
}
else
{
next = Action::OPERAND;
storage.emplace_back(TokenType::ClosingSquareBracket, "array");
}
2022-02-24 13:54:30 +00:00
}
else
{
break;
}
}
else
{
next = Action::OPERAND;
/// Try to find operators from 'op_table'
auto cur_op = op_table.begin();
for (; cur_op != op_table.end(); ++cur_op)
{
if (parseOperator(pos, cur_op->first, expected))
break;
}
if (cur_op != op_table.end())
{
while (storage.back().previousPriority() >= cur_op->second.priority)
{
Operator prev_op;
storage.back().popOperator(prev_op);
auto func = makeASTFunction(prev_op.func_name);
if (!storage.back().lastNOperands(func->children[0]->children, prev_op.arity))
return false;
storage.back().pushOperand(func);
}
storage.back().pushOperator(cur_op->second);
}
else if (pos->type == TokenType::Comma)
{
if (storage.size() == 1)
break;
if (!wrapLayer(storage.back()))
return false;
++pos;
}
else if (pos->type == TokenType::ClosingRoundBracket || pos->type == TokenType::ClosingSquareBracket)
{
next = Action::OPERATOR;
if (pos->type != storage.back().endBracket())
return false;
if (!wrapLayer(storage.back()))
return false;
ASTPtr res;
if (!storage.back().getResult(res))
return false;
storage.pop_back();
storage.back().pushOperand(res);
++pos;
}
else
{
break;
}
}
}
if (storage.size() > 1)
return false;
if (!wrapLayer(storage.back()))
return false;
if (!storage.back().getResult(node))
return false;
return true;
}
////////////////////////////////////////////////////////////////////////////////////////
bool ParserTableFunctionExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
if (ParserTableFunctionView().parse(pos, node, expected))
return true;
return elem_parser.parse(pos, node, expected);
}
bool ParserPrefixUnaryOperatorExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
2010-06-24 19:12:10 +00:00
{
2017-04-02 17:37:49 +00:00
/// try to find any of the valid operators
const char ** it;
for (it = operators; *it; it += 2)
{
if (parseOperator(pos, *it, expected))
break;
}
2017-04-02 17:37:49 +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.
*/
2021-05-24 07:07:25 +00:00
size_t count = 1;
if (it[0] && 0 == strncmp(it[0], "NOT", 3))
{
while (true)
{
2021-05-24 07:07:25 +00:00
const char ** jt;
for (jt = operators; *jt; jt += 2)
if (parseOperator(pos, *jt, expected))
break;
if (!*jt)
break;
2021-05-24 07:07:25 +00:00
++count;
}
}
ASTPtr elem;
if (!elem_parser->parse(pos, elem, expected))
return false;
if (!*it)
node = elem;
else
{
2021-05-24 07:07:25 +00:00
for (size_t i = 0; i < count; ++i)
{
/// the function corresponding to the operator
auto function = std::make_shared<ASTFunction>();
2021-05-24 07:07:25 +00:00
/// function arguments
auto exp_list = std::make_shared<ASTExpressionList>();
2021-05-24 07:07:25 +00:00
function->name = it[1];
function->arguments = exp_list;
function->children.push_back(exp_list);
2021-05-24 07:07:25 +00:00
if (node)
exp_list->children.push_back(node);
else
exp_list->children.push_back(elem);
2021-05-24 07:07:25 +00:00
node = function;
}
}
return true;
2010-06-24 19:12:10 +00:00
}
2021-06-20 19:34:18 +00:00
bool ParserUnaryExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
2012-11-20 22:48:38 +00:00
{
2017-04-02 17:37:49 +00:00
/// As an exception, negative numbers should be parsed as literals, and not as an application of the operator.
2012-11-20 22:48:38 +00:00
if (pos->type == TokenType::Minus)
{
Pos begin = pos;
if (ParserCastOperator().parse(pos, node, expected))
return true;
2012-11-20 22:48:38 +00:00
pos = begin;
if (ParserLiteral().parse(pos, node, expected))
return true;
2012-11-20 22:48:38 +00:00
pos = begin;
}
2012-11-20 22:48:38 +00:00
return operator_parser.parse(pos, node, expected);
2012-11-20 22:48:38 +00:00
}
2021-05-04 03:43:17 +00:00
bool ParserCastExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ASTPtr expr_ast;
if (!elem_parser->parse(pos, expr_ast, expected))
2021-05-04 03:43:17 +00:00
return false;
ASTPtr type_ast;
2021-05-06 18:21:10 +00:00
if (ParserToken(TokenType::DoubleColon).ignore(pos, expected)
2021-05-04 03:43:17 +00:00
&& ParserDataType().parse(pos, type_ast, expected))
{
node = createFunctionCast(expr_ast, type_ast);
}
else
{
node = expr_ast;
}
return true;
}
bool ParserArrayElementExpression::parseImpl(Pos & pos, ASTPtr & node, Expected &expected)
2010-06-24 19:12:10 +00:00
{
return ParserLeftAssociativeBinaryOperatorList{
operators,
std::make_unique<ParserCastExpression>(std::make_unique<ParserExpressionElement>()),
std::make_unique<ParserExpressionWithOptionalAlias>(false)
}.parse(pos, node, expected);
2010-06-24 19:12:10 +00:00
}
bool ParserTupleElementExpression::parseImpl(Pos & pos, ASTPtr & node, Expected &expected)
{
return ParserLeftAssociativeBinaryOperatorList{
operators,
std::make_unique<ParserCastExpression>(std::make_unique<ParserArrayElementExpression>()),
std::make_unique<ParserUnsignedInteger>()
}.parse(pos, node, expected);
}
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))
2011-11-06 20:47:07 +00:00
{
}
bool ParserExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
2010-06-24 19:12:10 +00:00
{
return ParserList(
std::make_unique<ParserExpressionWithOptionalAlias>(allow_alias_without_as_keyword, is_table_function),
std::make_unique<ParserToken>(TokenType::Comma))
.parse(pos, node, expected);
2010-06-24 19:12:10 +00:00
}
bool ParserNotEmptyExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
2010-06-24 19:12:10 +00:00
{
return nested_parser.parse(pos, node, expected) && !node->children.empty();
2010-06-24 19:12:10 +00:00
}
2022-02-24 13:54:30 +00:00
bool ParserNotEmptyExpressionList2::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
return nested_parser.parse(pos, node, expected) && !node->children.empty();
}
2021-12-25 17:30:31 +00:00
bool ParserOrderByExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
2011-09-04 05:14:52 +00:00
{
return ParserList(std::make_unique<ParserOrderByElement>(), std::make_unique<ParserToken>(TokenType::Comma), false)
.parse(pos, node, expected);
2011-09-04 05:14:52 +00:00
}
2019-10-09 13:02:05 +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 ParserNullityChecking::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ASTPtr node_comp;
2019-10-31 15:22:48 +00:00
if (!elem_parser.parse(pos, node_comp, expected))
return false;
ParserKeyword s_is{"IS"};
ParserKeyword s_not{"NOT"};
ParserKeyword s_null{"NULL"};
if (s_is.ignore(pos, expected))
{
bool is_not = false;
if (s_not.ignore(pos, expected))
is_not = true;
if (!s_null.ignore(pos, expected))
return false;
auto args = std::make_shared<ASTExpressionList>();
args->children.push_back(node_comp);
2018-02-26 03:37:08 +00:00
auto function = std::make_shared<ASTFunction>();
function->name = is_not ? "isNotNull" : "isNull";
function->arguments = args;
function->children.push_back(function->arguments);
node = function;
}
else
node = node_comp;
return true;
}
bool ParserDateOperatorExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
auto begin = pos;
/// If no DATE keyword, go to the nested parser.
if (!ParserKeyword("DATE").ignore(pos, expected))
return next_parser.parse(pos, node, expected);
ASTPtr expr;
if (!ParserStringLiteral().parse(pos, expr, expected))
{
pos = begin;
return next_parser.parse(pos, node, expected);
}
/// the function corresponding to the operator
auto function = std::make_shared<ASTFunction>();
/// function arguments
auto exp_list = std::make_shared<ASTExpressionList>();
/// the first argument of the function is the previous element, the second is the next one
function->name = "toDate";
function->arguments = exp_list;
function->children.push_back(exp_list);
exp_list->children.push_back(expr);
node = function;
return true;
}
bool ParserTimestampOperatorExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
auto begin = pos;
/// If no TIMESTAMP keyword, go to the nested parser.
if (!ParserKeyword("TIMESTAMP").ignore(pos, expected))
return next_parser.parse(pos, node, expected);
ASTPtr expr;
if (!ParserStringLiteral().parse(pos, expr, expected))
{
pos = begin;
return next_parser.parse(pos, node, expected);
}
/// the function corresponding to the operator
auto function = std::make_shared<ASTFunction>();
/// function arguments
auto exp_list = std::make_shared<ASTExpressionList>();
/// the first argument of the function is the previous element, the second is the next one
function->name = "toDateTime";
function->arguments = exp_list;
function->children.push_back(exp_list);
exp_list->children.push_back(expr);
node = function;
return true;
}
2020-10-15 07:18:38 +00:00
bool ParserIntervalOperatorExpression::parseArgumentAndIntervalKind(
Pos & pos, ASTPtr & expr, IntervalKind & interval_kind, Expected & expected)
{
auto begin = pos;
2020-10-15 07:18:38 +00:00
auto init_expected = expected;
2020-10-14 15:02:51 +00:00
ASTPtr string_literal;
2020-10-15 07:18:38 +00:00
//// 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))
2020-10-14 15:02:51 +00:00
{
String literal;
2020-10-15 07:18:38 +00:00
if (string_literal->as<ASTLiteral &>().value.tryGet(literal))
2020-10-14 15:02:51 +00:00
{
2020-10-15 07:18:38 +00:00
Tokens tokens(literal.data(), literal.data() + literal.size());
Pos token_pos(tokens, 0);
Expected token_expected;
2020-10-14 15:02:51 +00:00
2020-10-15 07:18:38 +00:00
if (!ParserNumber{}.parse(token_pos, expr, token_expected))
2020-10-14 15:02:51 +00:00
return false;
2020-10-15 07:18:38 +00:00
else
{
/// case: INTERVAL '1' HOUR
/// back to begin
if (!token_pos.isValid())
{
pos = begin;
expected = init_expected;
}
else
/// case: INTERVAL '1 HOUR'
return parseIntervalKind(token_pos, token_expected, interval_kind);
}
2020-10-14 15:02:51 +00:00
}
}
2020-10-15 07:18:38 +00:00
// case: INTERVAL expr HOUR
if (!ParserExpressionWithOptionalAlias(false).parse(pos, expr, expected))
2020-10-15 07:18:38 +00:00
return false;
return parseIntervalKind(pos, expected, interval_kind);
}
bool ParserIntervalOperatorExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
auto begin = pos;
/// If no INTERVAL keyword, go to the nested parser.
if (!ParserKeyword("INTERVAL").ignore(pos, expected))
return next_parser.parse(pos, node, expected);
ASTPtr expr;
IntervalKind interval_kind;
2020-10-15 07:18:38 +00:00
if (!parseArgumentAndIntervalKind(pos, expr, interval_kind, expected))
{
pos = begin;
return next_parser.parse(pos, node, expected);
}
/// the function corresponding to the operator
auto function = std::make_shared<ASTFunction>();
/// function arguments
auto exp_list = std::make_shared<ASTExpressionList>();
/// the first argument of the function is the previous element, the second is the next one
function->name = interval_kind.toNameOfFunctionToIntervalDataType();
function->arguments = exp_list;
function->children.push_back(exp_list);
exp_list->children.push_back(expr);
node = function;
return true;
}
2019-10-07 16:23:16 +00:00
bool ParserKeyValuePair::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ParserIdentifier id_parser;
ParserLiteral literal_parser;
2020-11-17 13:24:13 +00:00
ParserFunction func_parser;
2019-10-07 16:23:16 +00:00
ASTPtr identifier;
ASTPtr value;
2019-10-08 09:47:17 +00:00
bool with_brackets = false;
2019-10-07 16:23:16 +00:00
if (!id_parser.parse(pos, identifier, expected))
return false;
2020-11-17 13:24:13 +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))
2019-10-08 09:47:17 +00:00
{
ParserKeyValuePairsList kv_pairs_list;
ParserToken open(TokenType::OpeningRoundBracket);
ParserToken close(TokenType::ClosingRoundBracket);
if (!open.ignore(pos))
return false;
if (!kv_pairs_list.parse(pos, value, expected))
return false;
if (!close.ignore(pos))
return false;
with_brackets = true;
}
2019-10-07 16:23:16 +00:00
2019-10-08 09:47:17 +00:00
auto pair = std::make_shared<ASTPair>(with_brackets);
pair->first = Poco::toLower(identifier->as<ASTIdentifier>()->name());
2020-08-05 02:21:33 +00:00
pair->set(pair->second, value);
2019-10-07 16:23:16 +00:00
node = pair;
return true;
}
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);
}
2010-06-24 19:12:10 +00:00
}