2021-10-31 15:11:46 +00:00
|
|
|
#include <string_view>
|
|
|
|
|
2020-10-24 18:46:10 +00:00
|
|
|
#include <Parsers/ExpressionListParsers.h>
|
|
|
|
|
2021-06-03 02:19:07 +00:00
|
|
|
#include <Parsers/ASTAsterisk.h>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Parsers/ASTExpressionList.h>
|
|
|
|
#include <Parsers/ASTFunction.h>
|
2020-10-24 18:46:10 +00:00
|
|
|
#include <Parsers/ASTFunctionWithKeyValueArguments.h>
|
2021-11-26 15:49:40 +00:00
|
|
|
#include <Parsers/ASTIdentifier.h>
|
2021-11-26 16:54:57 +00:00
|
|
|
#include <Parsers/ASTLiteral.h>
|
2021-06-03 02:19:07 +00:00
|
|
|
#include <Parsers/ASTSelectQuery.h>
|
2021-11-26 18:27:16 +00:00
|
|
|
#include <Parsers/ASTSelectWithUnionQuery.h>
|
2021-06-03 02:19:07 +00:00
|
|
|
#include <Parsers/ASTSubquery.h>
|
|
|
|
#include <Parsers/ASTTablesInSelectQuery.h>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Parsers/ParserCreateQuery.h>
|
2021-08-14 12:31:55 +00:00
|
|
|
#include <Parsers/ParserUnionQueryElement.h>
|
2021-11-26 15:49:40 +00:00
|
|
|
#include <Parsers/parseIntervalKind.h>
|
2018-01-15 19:07:47 +00:00
|
|
|
#include <Common/StringUtils/StringUtils.h>
|
2017-07-10 03:28:12 +00:00
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
#include <Parsers/ParserSelectWithUnionQuery.h>
|
|
|
|
|
2022-02-24 13:54:30 +00:00
|
|
|
#include <base/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
|
|
|
|
2014-03-10 14:47:04 +00:00
|
|
|
const char * ParserMultiplicativeExpression::operators[] =
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
"*", "multiply",
|
|
|
|
"/", "divide",
|
|
|
|
"%", "modulo",
|
2021-01-05 05:03:19 +00:00
|
|
|
"MOD", "modulo",
|
|
|
|
"DIV", "intDiv",
|
2017-04-01 07:20:54 +00:00
|
|
|
nullptr
|
2014-03-10 14:47:04 +00:00
|
|
|
};
|
|
|
|
|
2021-06-20 19:34:18 +00:00
|
|
|
const char * ParserUnaryExpression::operators[] =
|
2014-03-10 14:47:04 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
"-", "negate",
|
2021-06-20 19:34:18 +00:00
|
|
|
"NOT", "not",
|
2017-04-01 07:20:54 +00:00
|
|
|
nullptr
|
2014-03-10 14:47:04 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const char * ParserAdditiveExpression::operators[] =
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
"+", "plus",
|
|
|
|
"-", "minus",
|
|
|
|
nullptr
|
2014-03-10 14:47:04 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const char * ParserComparisonExpression::operators[] =
|
|
|
|
{
|
2017-07-10 03:28:12 +00:00
|
|
|
"==", "equals",
|
|
|
|
"!=", "notEquals",
|
|
|
|
"<>", "notEquals",
|
|
|
|
"<=", "lessOrEquals",
|
|
|
|
">=", "greaterOrEquals",
|
|
|
|
"<", "less",
|
|
|
|
">", "greater",
|
|
|
|
"=", "equals",
|
|
|
|
"LIKE", "like",
|
2020-07-05 15:57:59 +00:00
|
|
|
"ILIKE", "ilike",
|
2017-07-10 03:28:12 +00:00
|
|
|
"NOT LIKE", "notLike",
|
2020-07-05 15:57:59 +00:00
|
|
|
"NOT ILIKE", "notILike",
|
2017-07-10 03:28:12 +00:00
|
|
|
"IN", "in",
|
|
|
|
"NOT IN", "notIn",
|
|
|
|
"GLOBAL IN", "globalIn",
|
|
|
|
"GLOBAL NOT IN", "globalNotIn",
|
2017-04-01 07:20:54 +00:00
|
|
|
nullptr
|
2014-03-10 14:47:04 +00:00
|
|
|
};
|
|
|
|
|
2020-11-10 10:23:46 +00:00
|
|
|
const char * ParserComparisonExpression::overlapping_operators_to_skip[] =
|
|
|
|
{
|
|
|
|
"IN PARTITION",
|
|
|
|
nullptr
|
|
|
|
};
|
|
|
|
|
2014-03-10 14:47:04 +00:00
|
|
|
const char * ParserLogicalNotExpression::operators[] =
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
"NOT", "not",
|
|
|
|
nullptr
|
2014-03-10 14:47:04 +00:00
|
|
|
};
|
|
|
|
|
2015-11-07 23:18:39 +00:00
|
|
|
const char * ParserArrayElementExpression::operators[] =
|
2014-03-10 14:47:04 +00:00
|
|
|
{
|
2017-07-10 03:28:12 +00:00
|
|
|
"[", "arrayElement",
|
2017-04-01 07:20:54 +00:00
|
|
|
nullptr
|
2014-03-10 14:47:04 +00:00
|
|
|
};
|
|
|
|
|
2015-11-07 23:18:39 +00:00
|
|
|
const char * ParserTupleElementExpression::operators[] =
|
|
|
|
{
|
2017-07-10 03:28:12 +00:00
|
|
|
".", "tupleElement",
|
2017-04-01 07:20:54 +00:00
|
|
|
nullptr
|
2015-11-07 23:18:39 +00:00
|
|
|
};
|
|
|
|
|
2014-03-10 14:47:04 +00:00
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
bool ParserList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
2011-08-18 18:48:00 +00:00
|
|
|
{
|
2020-06-05 21:31:37 +00:00
|
|
|
ASTs elements;
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2020-06-05 21:31:37 +00:00
|
|
|
auto parse_element = [&]
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
2020-06-05 21:31:37 +00:00
|
|
|
ASTPtr element;
|
|
|
|
if (!elem_parser->parse(pos, element, expected))
|
|
|
|
return false;
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2020-06-05 21:31:37 +00:00
|
|
|
elements.push_back(element);
|
|
|
|
return true;
|
|
|
|
};
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2020-06-05 21:31:37 +00:00
|
|
|
if (!parseUtil(pos, expected, parse_element, *separator_parser, allow_empty))
|
|
|
|
return false;
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2020-06-05 21:31:37 +00:00
|
|
|
auto list = std::make_shared<ASTExpressionList>(result_separator);
|
|
|
|
list->children = std::move(elements);
|
|
|
|
node = list;
|
2020-11-02 06:05:53 +00:00
|
|
|
|
2020-06-05 21:31:37 +00:00
|
|
|
return true;
|
2011-08-18 18:48:00 +00:00
|
|
|
}
|
2014-06-26 00:58:14 +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
|
|
|
{
|
2021-11-26 18:27:16 +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
|
|
|
{
|
2021-11-26 18:27:16 +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
|
|
|
{
|
2021-11-26 18:27:16 +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
|
|
|
{
|
2021-11-26 18:27:16 +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))
|
|
|
|
{
|
2021-11-26 18:27:16 +00:00
|
|
|
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
|
|
|
|
2017-07-13 04:20:56 +00:00
|
|
|
static bool parseOperator(IParser::Pos & pos, const char * op, Expected & expected)
|
2017-07-10 03:28:12 +00:00
|
|
|
{
|
|
|
|
if (isWordCharASCII(*op))
|
|
|
|
{
|
2017-07-13 04:20:56 +00:00
|
|
|
return ParserKeyword(op).ignore(pos, expected);
|
2017-07-10 03:28:12 +00:00
|
|
|
}
|
|
|
|
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
|
2017-07-10 03:28:12 +00:00
|
|
|
* contains the infix part '[' and the suffix ''] '(specified as' [')
|
|
|
|
*/
|
2021-10-31 15:11:46 +00:00
|
|
|
if (it[0] == "["sv)
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
2017-07-10 03:28:12 +00:00
|
|
|
if (pos->type != TokenType::ClosingSquareBracket)
|
2017-04-01 07:20:54 +00:00
|
|
|
return false;
|
2017-07-10 03:28:12 +00:00
|
|
|
++pos;
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
|
|
|
|
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();
|
2017-04-01 07:20:54 +00:00
|
|
|
node = function;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-10 17:08:14 +00:00
|
|
|
pos.depth = current_depth;
|
2017-04-01 07:20:54 +00:00
|
|
|
return true;
|
2010-06-24 19:12:10 +00:00
|
|
|
}
|
|
|
|
|
2014-02-13 11:05:51 +00:00
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
bool ParserVariableArityOperatorList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
ASTPtr arguments;
|
2014-02-13 11:05:51 +00:00
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
if (!elem_parser->parse(pos, node, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
return false;
|
2014-02-13 11:05:51 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
while (true)
|
|
|
|
{
|
2017-07-13 04:20:56 +00:00
|
|
|
if (!parseOperator(pos, infix, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
break;
|
2014-02-13 11:05:51 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
if (!arguments)
|
|
|
|
{
|
|
|
|
node = makeASTFunction(function_name, node);
|
2019-03-15 16:14:13 +00:00
|
|
|
arguments = node->as<ASTFunction &>().arguments;
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
2014-02-13 11:05:51 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
ASTPtr elem;
|
2017-07-10 03:28:12 +00:00
|
|
|
if (!elem_parser->parse(pos, elem, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
return false;
|
2014-02-13 11:05:51 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
arguments->children.push_back(elem);
|
|
|
|
}
|
2014-02-13 11:05:51 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
return true;
|
2014-02-13 11:05:51 +00:00
|
|
|
}
|
2010-06-24 19:12:10 +00:00
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
bool ParserBetweenExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
2016-04-03 01:15:53 +00:00
|
|
|
{
|
2019-02-02 15:29:37 +00:00
|
|
|
/// 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).
|
2016-04-03 01:15:53 +00:00
|
|
|
|
2019-02-02 12:18:30 +00:00
|
|
|
ParserKeyword s_not("NOT");
|
2017-06-18 03:07:03 +00:00
|
|
|
ParserKeyword s_between("BETWEEN");
|
|
|
|
ParserKeyword s_and("AND");
|
2016-04-03 01:15:53 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
ASTPtr subject;
|
|
|
|
ASTPtr left;
|
|
|
|
ASTPtr right;
|
2016-04-03 01:15:53 +00:00
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
if (!elem_parser.parse(pos, subject, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
return false;
|
2016-04-03 01:15:53 +00:00
|
|
|
|
2019-02-10 20:17:53 +00:00
|
|
|
bool negative = s_not.ignore(pos, expected);
|
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
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.
|
2017-04-01 07:20:54 +00:00
|
|
|
node = subject;
|
2019-02-10 20:17:53 +00:00
|
|
|
}
|
2017-04-01 07:20:54 +00:00
|
|
|
else
|
|
|
|
{
|
2017-07-10 03:28:12 +00:00
|
|
|
if (!elem_parser.parse(pos, left, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
return false;
|
2016-04-03 01:15:53 +00:00
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
if (!s_and.ignore(pos, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
return false;
|
2016-04-03 01:15:53 +00:00
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
if (!elem_parser.parse(pos, right, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
return false;
|
2016-04-03 01:15:53 +00:00
|
|
|
|
2019-02-02 11:23:25 +00:00
|
|
|
auto f_combined_expression = std::make_shared<ASTFunction>();
|
|
|
|
auto args_combined_expression = std::make_shared<ASTExpressionList>();
|
2016-04-03 01:15:53 +00:00
|
|
|
|
2019-02-02 15:29:37 +00:00
|
|
|
/// [NOT] BETWEEN left AND right
|
|
|
|
auto f_left_expr = std::make_shared<ASTFunction>();
|
|
|
|
auto args_left_expr = std::make_shared<ASTExpressionList>();
|
2016-04-03 01:15:53 +00:00
|
|
|
|
2019-02-02 15:29:37 +00:00
|
|
|
auto f_right_expr = std::make_shared<ASTFunction>();
|
|
|
|
auto args_right_expr = std::make_shared<ASTExpressionList>();
|
2016-04-03 01:15:53 +00:00
|
|
|
|
2019-02-02 15:29:37 +00:00
|
|
|
args_left_expr->children.emplace_back(subject);
|
|
|
|
args_left_expr->children.emplace_back(left);
|
2016-04-03 01:15:53 +00:00
|
|
|
|
2019-02-02 15:29:37 +00:00
|
|
|
args_right_expr->children.emplace_back(subject);
|
|
|
|
args_right_expr->children.emplace_back(right);
|
2016-04-03 01:15:53 +00:00
|
|
|
|
2019-02-10 20:17:53 +00:00
|
|
|
if (negative)
|
2019-02-02 15:29:37 +00:00
|
|
|
{
|
2019-02-10 20:17:53 +00:00
|
|
|
/// NOT BETWEEN
|
2019-02-02 15:29:37 +00:00
|
|
|
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
|
2019-02-02 15:29:37 +00:00
|
|
|
f_left_expr->name = "greaterOrEquals";
|
|
|
|
f_right_expr->name = "lessOrEquals";
|
|
|
|
f_combined_expression->name = "and";
|
|
|
|
}
|
2016-04-03 01:15:53 +00:00
|
|
|
|
2019-02-02 15:29:37 +00:00
|
|
|
f_left_expr->arguments = args_left_expr;
|
|
|
|
f_left_expr->children.emplace_back(f_left_expr->arguments);
|
2016-04-03 01:15:53 +00:00
|
|
|
|
2019-02-02 15:29:37 +00:00
|
|
|
f_right_expr->arguments = args_right_expr;
|
|
|
|
f_right_expr->children.emplace_back(f_right_expr->arguments);
|
2016-04-03 01:15:53 +00:00
|
|
|
|
2019-02-02 15:29:37 +00:00
|
|
|
args_combined_expression->children.emplace_back(f_left_expr);
|
|
|
|
args_combined_expression->children.emplace_back(f_right_expr);
|
2016-04-03 01:15:53 +00:00
|
|
|
|
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);
|
2016-04-03 01:15:53 +00:00
|
|
|
|
2019-02-10 20:08:44 +00:00
|
|
|
node = f_combined_expression;
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
2016-04-03 01:15:53 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
return true;
|
2016-04-03 01:15:53 +00:00
|
|
|
}
|
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
bool ParserTernaryOperatorExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
2012-09-23 06:16:42 +00:00
|
|
|
{
|
2017-07-10 03:28:12 +00:00
|
|
|
ParserToken symbol1(TokenType::QuestionMark);
|
|
|
|
ParserToken symbol2(TokenType::Colon);
|
2012-09-23 06:16:42 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
ASTPtr elem_cond;
|
|
|
|
ASTPtr elem_then;
|
|
|
|
ASTPtr elem_else;
|
2012-09-23 06:16:42 +00:00
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
if (!elem_parser.parse(pos, elem_cond, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
return false;
|
2012-09-23 06:16:42 +00:00
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
if (!symbol1.ignore(pos, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
node = elem_cond;
|
|
|
|
else
|
|
|
|
{
|
2017-07-10 03:28:12 +00:00
|
|
|
if (!elem_parser.parse(pos, elem_then, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
return false;
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
if (!symbol2.ignore(pos, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
return false;
|
2012-09-23 06:16:42 +00:00
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
if (!elem_parser.parse(pos, elem_else, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
return false;
|
2012-09-23 06:16:42 +00:00
|
|
|
|
2017-04-02 17:37:49 +00:00
|
|
|
/// the function corresponding to the operator
|
2017-04-01 07:20:54 +00:00
|
|
|
auto function = std::make_shared<ASTFunction>();
|
2012-09-23 06:16:42 +00:00
|
|
|
|
2017-04-02 17:37:49 +00:00
|
|
|
/// function arguments
|
2017-04-01 07:20:54 +00:00
|
|
|
auto exp_list = std::make_shared<ASTExpressionList>();
|
2016-05-28 15:42:22 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
function->name = "if";
|
|
|
|
function->arguments = exp_list;
|
|
|
|
function->children.push_back(exp_list);
|
2016-05-28 15:42:22 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
exp_list->children.push_back(elem_cond);
|
|
|
|
exp_list->children.push_back(elem_then);
|
|
|
|
exp_list->children.push_back(elem_else);
|
2016-05-28 15:42:22 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
node = function;
|
|
|
|
}
|
2012-09-23 06:16:42 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
return true;
|
2012-09-23 06:16:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
bool ParserLambdaExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
2013-05-08 09:52:02 +00:00
|
|
|
{
|
2017-07-10 03:28:12 +00:00
|
|
|
ParserToken arrow(TokenType::Arrow);
|
|
|
|
ParserToken open(TokenType::OpeningRoundBracket);
|
|
|
|
ParserToken close(TokenType::ClosingRoundBracket);
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
Pos begin = pos;
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
ASTPtr inner_arguments;
|
|
|
|
ASTPtr expression;
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
bool was_open = false;
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
if (open.ignore(pos, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
|
|
|
was_open = true;
|
|
|
|
}
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
if (!ParserList(std::make_unique<ParserIdentifier>(), std::make_unique<ParserToken>(TokenType::Comma)).parse(pos, inner_arguments, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
break;
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
if (was_open)
|
|
|
|
{
|
2017-07-10 03:28:12 +00:00
|
|
|
if (!close.ignore(pos, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
break;
|
|
|
|
}
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
if (!arrow.ignore(pos, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
break;
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
if (!elem_parser.parse(pos, expression, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
return false;
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
/// lambda(tuple(inner_arguments), expression)
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
auto lambda = std::make_shared<ASTFunction>();
|
|
|
|
node = lambda;
|
|
|
|
lambda->name = "lambda";
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
auto outer_arguments = std::make_shared<ASTExpressionList>();
|
|
|
|
lambda->arguments = outer_arguments;
|
|
|
|
lambda->children.push_back(lambda->arguments);
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
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);
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
outer_arguments->children.push_back(expression);
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
while (false);
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
pos = begin;
|
2017-07-10 03:28:12 +00:00
|
|
|
return elem_parser.parse(pos, node, expected);
|
2013-05-08 09:52:02 +00:00
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
enum Action
|
|
|
|
{
|
|
|
|
OPERAND,
|
|
|
|
OPERATOR
|
|
|
|
};
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
|
|
class Layer
|
|
|
|
{
|
|
|
|
public:
|
2022-04-12 15:03:10 +00:00
|
|
|
Layer(TokenType end_bracket_ = TokenType::Whitespace, String func_name_ = "", bool layer_zero_ = false) :
|
2022-04-08 15:36:36 +00:00
|
|
|
end_bracket(end_bracket_),
|
|
|
|
func_name(func_name_),
|
|
|
|
layer_zero(layer_zero_)
|
2022-02-24 13:54:30 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
virtual ~Layer() = default;
|
|
|
|
|
2022-02-24 13:54:30 +00:00
|
|
|
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())
|
|
|
|
{
|
2022-04-17 20:59:03 +00:00
|
|
|
// Round brackets can mean priority operator as well as function tuple()
|
2022-02-24 13:54:30 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
virtual bool parse(IParser::Pos & pos, Expected & expected, Action & action)
|
|
|
|
{
|
2022-04-08 15:36:36 +00:00
|
|
|
if (!layer_zero && ParserToken(TokenType::Comma).ignore(pos, expected))
|
2022-04-08 03:30:49 +00:00
|
|
|
{
|
|
|
|
action = Action::OPERAND;
|
|
|
|
return wrapLayer();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (end_bracket != TokenType::Whitespace && ParserToken(end_bracket).ignore(pos, expected))
|
|
|
|
{
|
|
|
|
finished = true;
|
2022-04-08 15:36:36 +00:00
|
|
|
return wrapLayer();
|
2022-04-08 03:30:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isFinished()
|
2022-02-24 13:54:30 +00:00
|
|
|
{
|
2022-04-08 03:30:49 +00:00
|
|
|
return finished;
|
2022-02-24 13:54:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
bool wrapLayer()
|
|
|
|
{
|
|
|
|
Operator cur_op;
|
|
|
|
while (popOperator(cur_op))
|
|
|
|
{
|
2022-04-21 11:31:01 +00:00
|
|
|
if (cur_op.func_name == "if_pre")
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (cur_op.func_name == "if")
|
|
|
|
{
|
|
|
|
Operator tmp;
|
|
|
|
if (!popOperator(tmp) || tmp.func_name != "if_pre")
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
auto func = makeASTFunction(cur_op.func_name);
|
|
|
|
|
|
|
|
if (!lastNOperands(func->children[0]->children, cur_op.arity))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
pushOperand(func);
|
|
|
|
}
|
|
|
|
|
|
|
|
ASTPtr res;
|
|
|
|
if (!popOperand(res))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
pushResult(res);
|
|
|
|
|
|
|
|
return empty();
|
|
|
|
}
|
|
|
|
|
2022-04-17 20:59:03 +00:00
|
|
|
bool parseLambda()
|
|
|
|
{
|
|
|
|
// 0. If empty - create function tuple with 0 args
|
|
|
|
if (empty())
|
|
|
|
{
|
|
|
|
auto func = makeASTFunction("tuple");
|
|
|
|
pushOperand(func);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
/// 1. If there is already tuple do nothing
|
2022-04-21 11:31:01 +00:00
|
|
|
if (tryGetFunctionName(result.back()) == "tuple")
|
2022-04-17 20:59:03 +00:00
|
|
|
{
|
|
|
|
pushOperand(result.back());
|
|
|
|
result.pop_back();
|
|
|
|
}
|
|
|
|
/// 2. Put all result in a single tuple
|
|
|
|
else
|
|
|
|
{
|
|
|
|
auto func = makeASTFunction("tuple", result);
|
|
|
|
result.clear();
|
|
|
|
pushOperand(func);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
protected:
|
2022-02-24 13:54:30 +00:00
|
|
|
std::vector<Operator> operators;
|
|
|
|
ASTs operands;
|
|
|
|
ASTs result;
|
|
|
|
TokenType end_bracket;
|
|
|
|
String func_name;
|
2022-04-08 03:30:49 +00:00
|
|
|
bool finished = false;
|
2022-04-08 15:36:36 +00:00
|
|
|
bool layer_zero;
|
2022-04-08 03:30:49 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class CastLayer : public Layer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
{
|
|
|
|
/// expr AS type
|
|
|
|
if (state == 0)
|
|
|
|
{
|
|
|
|
if (ParserKeyword("AS").ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
ASTPtr type_node;
|
|
|
|
|
|
|
|
if (ParserDataType().parse(pos, type_node, expected) && ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
{
|
|
|
|
result[0] = createFunctionCast(result[0], type_node);
|
|
|
|
finished = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ParserToken(TokenType::Comma).ignore(pos, expected))
|
|
|
|
{
|
|
|
|
action = Action::OPERAND;
|
|
|
|
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
state = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (state == 1)
|
|
|
|
{
|
|
|
|
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
result[0] = makeASTFunction("CAST", result[0], result[1]);
|
|
|
|
result.pop_back();
|
|
|
|
finished = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
int state = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
class ExtractLayer : public Layer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
{
|
|
|
|
if (state == 0)
|
|
|
|
{
|
|
|
|
IParser::Pos begin = pos;
|
|
|
|
ParserKeyword s_from("FROM");
|
|
|
|
|
|
|
|
if (parseIntervalKind(pos, expected, interval_kind) && s_from.ignore(pos, expected))
|
|
|
|
{
|
|
|
|
state = 2;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
state = 1;
|
|
|
|
pos = begin;
|
|
|
|
func_name = "extract";
|
|
|
|
end_bracket = TokenType::ClosingRoundBracket;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 1)
|
|
|
|
{
|
|
|
|
return Layer::parse(pos, expected, action);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 2)
|
|
|
|
{
|
|
|
|
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
result[0] = makeASTFunction(interval_kind.toNameOfFunctionExtractTimePart(), result[0]);
|
|
|
|
finished = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
int state = 0;
|
|
|
|
IntervalKind interval_kind;
|
|
|
|
};
|
|
|
|
|
|
|
|
class SubstringLayer : public Layer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
{
|
|
|
|
/// Either SUBSTRING(expr FROM start) or SUBSTRING(expr FROM start FOR length) or SUBSTRING(expr, start, length)
|
|
|
|
/// The latter will be parsed normally as a function later.
|
|
|
|
|
|
|
|
if (state == 0)
|
|
|
|
{
|
|
|
|
if (ParserToken(TokenType::Comma).ignore(pos, expected) ||
|
|
|
|
ParserKeyword("FROM").ignore(pos, expected))
|
|
|
|
{
|
|
|
|
action = Action::OPERAND;
|
|
|
|
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
state = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 1)
|
|
|
|
{
|
|
|
|
if (ParserToken(TokenType::Comma).ignore(pos, expected) ||
|
|
|
|
ParserKeyword("FOR").ignore(pos, expected))
|
|
|
|
{
|
|
|
|
action = Action::OPERAND;
|
|
|
|
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
state = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 1 || state == 2)
|
|
|
|
{
|
|
|
|
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
result = {makeASTFunction("substring", result)};
|
|
|
|
finished = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
int state = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PositionLayer : public Layer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
{
|
|
|
|
if (state == 0)
|
|
|
|
{
|
|
|
|
if (ParserToken(TokenType::Comma).ignore(pos, expected))
|
|
|
|
{
|
|
|
|
action = Action::OPERAND;
|
|
|
|
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
state = 1;
|
|
|
|
}
|
|
|
|
if (ParserKeyword("IN").ignore(pos, expected))
|
|
|
|
{
|
|
|
|
action = Action::OPERAND;
|
|
|
|
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
state = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 1 || 2)
|
|
|
|
{
|
|
|
|
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (state == 1)
|
|
|
|
result = {makeASTFunction("position", result)};
|
|
|
|
else
|
|
|
|
result = {makeASTFunction("position", result[1], result[0])};
|
2022-04-08 15:36:36 +00:00
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
finished = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
int state = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class ExistsLayer : public Layer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & /*action*/) override
|
|
|
|
{
|
|
|
|
ASTPtr node;
|
|
|
|
|
2022-04-08 15:36:36 +00:00
|
|
|
// Recursion :'(
|
2022-04-08 03:30:49 +00:00
|
|
|
if (!ParserSelectWithUnionQuery().parse(pos, node, expected))
|
|
|
|
return false;
|
|
|
|
|
2022-04-08 15:36:36 +00:00
|
|
|
if (!ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
return false;
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
auto subquery = std::make_shared<ASTSubquery>();
|
|
|
|
subquery->children.push_back(node);
|
|
|
|
result = {makeASTFunction("exists", subquery)};
|
|
|
|
|
2022-04-08 15:36:36 +00:00
|
|
|
finished = true;
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class TrimLayer : public Layer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
TrimLayer(bool trim_left_, bool trim_right_) : trim_left(trim_left_), trim_right(trim_right_)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
{
|
|
|
|
/// Handles all possible TRIM/LTRIM/RTRIM call variants
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (char_override)
|
|
|
|
state = 1;
|
|
|
|
else
|
|
|
|
state = 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
state = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 1)
|
|
|
|
{
|
|
|
|
if (ParserKeyword("FROM").ignore(pos, expected))
|
|
|
|
{
|
|
|
|
action = Action::OPERAND;
|
|
|
|
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
to_remove = makeASTFunction("regexpQuoteMeta", result[0]);
|
|
|
|
result.clear();
|
|
|
|
state = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 2)
|
|
|
|
{
|
|
|
|
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
ASTPtr pattern_node;
|
|
|
|
|
|
|
|
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>("]+$")
|
|
|
|
};
|
|
|
|
func_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>("]+$")
|
|
|
|
};
|
|
|
|
}
|
|
|
|
func_name = "replaceRegexpOne";
|
|
|
|
}
|
|
|
|
|
|
|
|
pattern_func_node->name = "concat";
|
|
|
|
pattern_func_node->arguments = std::move(pattern_list_args);
|
|
|
|
pattern_func_node->children.push_back(pattern_func_node->arguments);
|
|
|
|
|
|
|
|
pattern_node = std::move(pattern_func_node);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (trim_left && trim_right)
|
|
|
|
{
|
|
|
|
func_name = "trimBoth";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (trim_left)
|
|
|
|
{
|
|
|
|
func_name = "trimLeft";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/// trim_right == false not possible
|
|
|
|
func_name = "trimRight";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (char_override)
|
|
|
|
{
|
|
|
|
result.push_back(pattern_node);
|
|
|
|
result.push_back(std::make_shared<ASTLiteral>(""));
|
|
|
|
}
|
|
|
|
|
|
|
|
finished = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
int state = 0;
|
|
|
|
|
|
|
|
bool trim_left;
|
|
|
|
bool trim_right;
|
|
|
|
bool char_override = false;
|
|
|
|
|
|
|
|
ASTPtr to_remove;
|
2022-02-24 13:54:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2022-04-08 15:36:36 +00:00
|
|
|
class DateAddLayer : public Layer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
DateAddLayer(const char * function_name_) : function_name(function_name_)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
{
|
|
|
|
if (state == 0)
|
|
|
|
{
|
|
|
|
if (parseIntervalKind(pos, expected, interval_kind))
|
|
|
|
{
|
|
|
|
if (!ParserToken(TokenType::Comma).ignore(pos, expected))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
action = Action::OPERAND;
|
|
|
|
state = 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
func_name = function_name;
|
|
|
|
end_bracket = TokenType::ClosingRoundBracket;
|
|
|
|
state = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 1)
|
|
|
|
{
|
|
|
|
return Layer::parse(pos, expected, action);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 2)
|
|
|
|
{
|
|
|
|
if (ParserToken(TokenType::Comma).ignore(pos, expected))
|
|
|
|
{
|
|
|
|
action = Action::OPERAND;
|
|
|
|
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
state = 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 3)
|
|
|
|
{
|
|
|
|
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
result[0] = makeASTFunction(interval_kind.toNameOfFunctionToIntervalDataType(), result[0]);
|
|
|
|
result = {makeASTFunction(function_name, result[1], result[0])};
|
|
|
|
finished = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
int state = 0;
|
|
|
|
IntervalKind interval_kind;
|
|
|
|
const char * function_name;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class DateDiffLayer : public Layer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
{
|
|
|
|
if (state == 0)
|
|
|
|
{
|
|
|
|
if (!parseIntervalKind(pos, expected, interval_kind))
|
|
|
|
{
|
|
|
|
func_name = "dateDiff";
|
|
|
|
end_bracket = TokenType::ClosingRoundBracket;
|
|
|
|
state = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!ParserToken(TokenType::Comma).ignore(pos, expected))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
state = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 1)
|
|
|
|
{
|
|
|
|
return Layer::parse(pos, expected, action);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 2)
|
|
|
|
{
|
|
|
|
if (ParserToken(TokenType::Comma).ignore(pos, expected))
|
|
|
|
{
|
|
|
|
action = Action::OPERAND;
|
|
|
|
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
state = 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 3)
|
|
|
|
{
|
|
|
|
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (result.size() != 2)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
result = {makeASTFunction("dateDiff", std::make_shared<ASTLiteral>(interval_kind.toDateDiffUnit()), result[0], result[1])};
|
|
|
|
finished = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
int state = 0;
|
|
|
|
IntervalKind interval_kind;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class IntervalLayer : public Layer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & /*action*/) override
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
|
|
|
if (!ParserNumber{}.parse(token_pos, expr, token_expected))
|
|
|
|
return false;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/// 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;
|
|
|
|
|
|
|
|
result = {makeASTFunction(interval_kind.toNameOfFunctionToIntervalDataType(), expr)};
|
|
|
|
finished = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
state = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 1)
|
|
|
|
{
|
|
|
|
if (parseIntervalKind(pos, expected, interval_kind))
|
|
|
|
{
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
result = {makeASTFunction(interval_kind.toNameOfFunctionToIntervalDataType(), result)};
|
|
|
|
finished = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
int state = 0;
|
|
|
|
IntervalKind interval_kind;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2022-04-12 15:03:10 +00:00
|
|
|
class CaseLayer : public Layer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
{
|
|
|
|
if (state == 0)
|
|
|
|
{
|
|
|
|
auto old_pos = pos;
|
|
|
|
has_case_expr = !ParserKeyword("WHEN").ignore(pos, expected);
|
|
|
|
pos = old_pos;
|
|
|
|
|
|
|
|
state = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 1)
|
|
|
|
{
|
|
|
|
if (ParserKeyword("WHEN").ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if ((has_case_expr || result.size() > 0) && !wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
action = Action::OPERAND;
|
|
|
|
state = 2;
|
|
|
|
}
|
|
|
|
else if (ParserKeyword("ELSE").ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
action = Action::OPERAND;
|
|
|
|
state = 3;
|
|
|
|
}
|
|
|
|
else if (ParserKeyword("END").ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
Field field_with_null;
|
|
|
|
ASTLiteral null_literal(field_with_null);
|
|
|
|
result.push_back(std::make_shared<ASTLiteral>(null_literal));
|
|
|
|
|
|
|
|
if (has_case_expr)
|
|
|
|
result = {makeASTFunction("caseWithExpression", result)};
|
|
|
|
else
|
|
|
|
result = {makeASTFunction("multiIf", result)};
|
|
|
|
finished = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 2)
|
|
|
|
{
|
|
|
|
if (ParserKeyword("THEN").ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
action = Action::OPERAND;
|
|
|
|
state = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 3)
|
|
|
|
{
|
|
|
|
if (ParserKeyword("END").ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!wrapLayer())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (has_case_expr)
|
|
|
|
result = {makeASTFunction("caseWithExpression", result)};
|
|
|
|
else
|
|
|
|
result = {makeASTFunction("multiIf", result)};
|
|
|
|
|
|
|
|
finished = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
int state = 0;
|
|
|
|
bool has_case_expr;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2022-02-24 13:54:30 +00:00
|
|
|
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 ParserExpression2::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
|
|
|
{
|
|
|
|
static std::vector<std::pair<const char *, Operator>> op_table({
|
2022-02-25 10:46:28 +00:00
|
|
|
{"+", 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)},
|
2022-04-21 11:31:01 +00:00
|
|
|
{"?", Operator("if_pre", 3, 0)},
|
|
|
|
{":", Operator("if", 4, 3)},
|
2022-02-24 13:54:30 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
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;
|
2022-02-25 10:46:28 +00:00
|
|
|
ParserLiteral literal_parser;
|
|
|
|
ParserTupleOfLiterals tuple_literal_parser;
|
|
|
|
ParserArrayOfLiterals array_literal_parser;
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
|
|
Action next = Action::OPERAND;
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
std::vector<std::unique_ptr<Layer>> storage;
|
2022-04-08 15:36:36 +00:00
|
|
|
storage.push_back(std::make_unique<Layer>(TokenType::Whitespace, "", true));
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
|
|
while (pos.isValid())
|
|
|
|
{
|
2022-04-08 03:30:49 +00:00
|
|
|
// LOG_FATAL(&Poco::Logger::root(), "#pos: {}", String(pos->begin, pos->size()));
|
|
|
|
if (!storage.back()->parse(pos, expected, next))
|
|
|
|
return false;
|
2022-04-08 15:36:36 +00:00
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
if (storage.back()->isFinished())
|
|
|
|
{
|
|
|
|
next = Action::OPERATOR;
|
|
|
|
|
|
|
|
ASTPtr res;
|
|
|
|
if (!storage.back()->getResult(res))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
storage.pop_back();
|
|
|
|
storage.back()->pushOperand(res);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-02-24 13:54:30 +00:00
|
|
|
if (next == Action::OPERAND)
|
|
|
|
{
|
|
|
|
next = Action::OPERATOR;
|
|
|
|
ASTPtr tmp;
|
|
|
|
|
|
|
|
/// Special case for cast expression
|
|
|
|
if (ParseCastExpression(pos, tmp, expected))
|
|
|
|
{
|
2022-04-08 03:30:49 +00:00
|
|
|
storage.back()->pushOperand(std::move(tmp));
|
2022-02-24 13:54:30 +00:00
|
|
|
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;
|
2022-04-08 03:30:49 +00:00
|
|
|
storage.back()->pushOperator(cur_op->second);
|
2022-02-24 13:54:30 +00:00
|
|
|
}
|
2022-04-08 15:36:36 +00:00
|
|
|
else if (parseOperator(pos, "INTERVAL", expected))
|
|
|
|
{
|
|
|
|
next = Action::OPERAND;
|
|
|
|
storage.push_back(std::make_unique<IntervalLayer>());
|
|
|
|
}
|
2022-04-12 15:03:10 +00:00
|
|
|
else if (parseOperator(pos, "CASE", expected))
|
|
|
|
{
|
|
|
|
next = Action::OPERAND; // ???
|
|
|
|
storage.push_back(std::make_unique<CaseLayer>());
|
|
|
|
}
|
2022-02-24 13:54:30 +00:00
|
|
|
else if (ParseDateOperatorExpression(pos, tmp, expected) ||
|
2022-02-25 10:46:28 +00:00
|
|
|
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
|
|
|
{
|
2022-04-08 03:30:49 +00:00
|
|
|
storage.back()->pushOperand(std::move(tmp));
|
2022-02-24 13:54:30 +00:00
|
|
|
}
|
|
|
|
else if (identifier_parser.parse(pos, tmp, expected) ||
|
2022-02-25 10:46:28 +00:00
|
|
|
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;
|
2022-02-25 10:46:28 +00:00
|
|
|
|
|
|
|
/// Special case for function with zero arguments: f()
|
|
|
|
if (pos->type == TokenType::ClosingRoundBracket)
|
|
|
|
{
|
|
|
|
++pos;
|
|
|
|
auto function = makeASTFunction(getIdentifierName(tmp));
|
2022-04-08 03:30:49 +00:00
|
|
|
storage.back()->pushOperand(function);
|
2022-02-25 10:46:28 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
next = Action::OPERAND;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
|
|
String function_name = getIdentifierName(tmp);
|
|
|
|
String function_name_lowercase = Poco::toLower(function_name);
|
|
|
|
|
|
|
|
if (function_name_lowercase == "cast")
|
|
|
|
storage.push_back(std::make_unique<CastLayer>());
|
|
|
|
else if (function_name_lowercase == "extract")
|
|
|
|
storage.push_back(std::make_unique<ExtractLayer>());
|
|
|
|
else if (function_name_lowercase == "substring")
|
|
|
|
storage.push_back(std::make_unique<SubstringLayer>());
|
|
|
|
else if (function_name_lowercase == "position")
|
|
|
|
storage.push_back(std::make_unique<PositionLayer>());
|
|
|
|
else if (function_name_lowercase == "exists")
|
|
|
|
storage.push_back(std::make_unique<ExistsLayer>());
|
|
|
|
else if (function_name_lowercase == "trim")
|
|
|
|
storage.push_back(std::make_unique<TrimLayer>(false, false));
|
|
|
|
else if (function_name_lowercase == "ltrim")
|
|
|
|
storage.push_back(std::make_unique<TrimLayer>(true, false));
|
|
|
|
else if (function_name_lowercase == "rtrim")
|
|
|
|
storage.push_back(std::make_unique<TrimLayer>(false, true));
|
2022-04-08 15:36:36 +00:00
|
|
|
else if (function_name_lowercase == "dateadd" || function_name_lowercase == "date_add"
|
|
|
|
|| function_name_lowercase == "timestampadd" || function_name_lowercase == "timestamp_add")
|
|
|
|
storage.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")
|
|
|
|
storage.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")
|
|
|
|
storage.push_back(std::make_unique<DateDiffLayer>());
|
2022-04-08 03:30:49 +00:00
|
|
|
else
|
|
|
|
storage.push_back(std::make_unique<Layer>(TokenType::ClosingRoundBracket, function_name));
|
2022-02-25 10:46:28 +00:00
|
|
|
}
|
2022-02-24 13:54:30 +00:00
|
|
|
}
|
|
|
|
else if (pos->type == TokenType::OpeningSquareBracket)
|
|
|
|
{
|
|
|
|
next = Action::OPERAND;
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
storage.back()->pushOperand(std::move(tmp));
|
|
|
|
storage.back()->pushOperator(Operator("arrayElement", 40, 2));
|
|
|
|
storage.push_back(std::make_unique<Layer>(TokenType::ClosingSquareBracket));
|
2022-02-24 13:54:30 +00:00
|
|
|
++pos;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-04-08 03:30:49 +00:00
|
|
|
storage.back()->pushOperand(std::move(tmp));
|
2022-02-24 13:54:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (pos->type == TokenType::OpeningRoundBracket)
|
|
|
|
{
|
|
|
|
next = Action::OPERAND;
|
2022-04-08 03:30:49 +00:00
|
|
|
storage.push_back(std::make_unique<Layer>(TokenType::ClosingRoundBracket, "tuple"));
|
2022-02-24 13:54:30 +00:00
|
|
|
++pos;
|
|
|
|
}
|
|
|
|
else if (pos->type == TokenType::OpeningSquareBracket)
|
|
|
|
{
|
|
|
|
++pos;
|
2022-02-25 10:46:28 +00:00
|
|
|
|
|
|
|
/// Special case for empty array: []
|
|
|
|
if (pos->type == TokenType::ClosingSquareBracket)
|
|
|
|
{
|
|
|
|
++pos;
|
|
|
|
auto function = makeASTFunction("array");
|
2022-04-08 03:30:49 +00:00
|
|
|
storage.back()->pushOperand(function);
|
2022-02-25 10:46:28 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
next = Action::OPERAND;
|
2022-04-08 03:30:49 +00:00
|
|
|
storage.push_back(std::make_unique<Layer>(TokenType::ClosingSquareBracket, "array"));
|
2022-02-25 10:46:28 +00:00
|
|
|
}
|
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())
|
|
|
|
{
|
2022-04-08 03:30:49 +00:00
|
|
|
while (storage.back()->previousPriority() >= cur_op->second.priority)
|
2022-02-24 13:54:30 +00:00
|
|
|
{
|
|
|
|
Operator prev_op;
|
2022-04-08 03:30:49 +00:00
|
|
|
storage.back()->popOperator(prev_op);
|
2022-02-24 13:54:30 +00:00
|
|
|
auto func = makeASTFunction(prev_op.func_name);
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
if (!storage.back()->lastNOperands(func->children[0]->children, prev_op.arity))
|
2022-02-24 13:54:30 +00:00
|
|
|
return false;
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
storage.back()->pushOperand(func);
|
2022-02-24 13:54:30 +00:00
|
|
|
}
|
2022-04-08 03:30:49 +00:00
|
|
|
storage.back()->pushOperator(cur_op->second);
|
2022-02-24 13:54:30 +00:00
|
|
|
}
|
2022-04-12 15:03:10 +00:00
|
|
|
else if (parseOperator(pos, "::", expected))
|
|
|
|
{
|
|
|
|
next = Action::OPERATOR;
|
|
|
|
|
|
|
|
ASTPtr type_ast;
|
|
|
|
if (!ParserDataType().parse(pos, type_ast, expected))
|
|
|
|
return false; // ???
|
|
|
|
|
|
|
|
storage.back()->pushOperator(Operator("CAST", 50, 2));
|
|
|
|
storage.back()->pushOperand(std::make_shared<ASTLiteral>(queryToString(type_ast)));
|
|
|
|
}
|
2022-04-17 20:59:03 +00:00
|
|
|
else if (parseOperator(pos, "->", expected))
|
|
|
|
{
|
|
|
|
if (!storage.back()->parseLambda())
|
|
|
|
return false;
|
|
|
|
|
2022-04-21 11:31:01 +00:00
|
|
|
storage.back()->pushOperator(Operator("lambda", 2, 2));
|
2022-04-17 20:59:03 +00:00
|
|
|
}
|
2022-02-24 13:54:30 +00:00
|
|
|
else if (pos->type == TokenType::Comma)
|
|
|
|
{
|
|
|
|
if (storage.size() == 1)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (storage.size() > 1)
|
|
|
|
return false;
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
if (!storage.back()->wrapLayer())
|
2022-02-24 13:54:30 +00:00
|
|
|
return false;
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
if (!storage.back()->getResult(node))
|
2022-02-24 13:54:30 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
2013-05-08 09:52:02 +00:00
|
|
|
|
2021-02-13 05:18:14 +00:00
|
|
|
bool ParserTableFunctionExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
|
|
|
{
|
|
|
|
if (ParserTableFunctionView().parse(pos, node, expected))
|
|
|
|
return true;
|
|
|
|
return elem_parser.parse(pos, node, expected);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
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
|
2017-04-01 07:20:54 +00:00
|
|
|
const char ** it;
|
|
|
|
for (it = operators; *it; it += 2)
|
|
|
|
{
|
2017-07-13 04:20:56 +00:00
|
|
|
if (parseOperator(pos, *it, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
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.
|
2017-04-01 07:20:54 +00:00
|
|
|
*/
|
2021-05-24 07:07:25 +00:00
|
|
|
size_t count = 1;
|
2017-04-01 07:20:54 +00:00
|
|
|
if (it[0] && 0 == strncmp(it[0], "NOT", 3))
|
|
|
|
{
|
|
|
|
while (true)
|
|
|
|
{
|
2021-05-24 07:07:25 +00:00
|
|
|
const char ** jt;
|
2017-04-01 07:20:54 +00:00
|
|
|
for (jt = operators; *jt; jt += 2)
|
2017-07-13 04:20:56 +00:00
|
|
|
if (parseOperator(pos, *jt, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
if (!*jt)
|
|
|
|
break;
|
|
|
|
|
2021-05-24 07:07:25 +00:00
|
|
|
++count;
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ASTPtr elem;
|
2017-07-10 03:28:12 +00:00
|
|
|
if (!elem_parser->parse(pos, elem, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
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>();
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2021-05-24 07:07:25 +00:00
|
|
|
/// function arguments
|
|
|
|
auto exp_list = std::make_shared<ASTExpressionList>();
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2021-05-24 07:07:25 +00:00
|
|
|
function->name = it[1];
|
|
|
|
function->arguments = exp_list;
|
|
|
|
function->children.push_back(exp_list);
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2021-05-24 07:07:25 +00:00
|
|
|
if (node)
|
|
|
|
exp_list->children.push_back(node);
|
|
|
|
else
|
|
|
|
exp_list->children.push_back(elem);
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2021-05-24 07:07:25 +00:00
|
|
|
node = function;
|
|
|
|
}
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
if (pos->type == TokenType::Minus)
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
|
|
|
Pos begin = pos;
|
2021-08-19 15:15:44 +00:00
|
|
|
if (ParserCastOperator().parse(pos, node, expected))
|
|
|
|
return true;
|
2012-11-20 22:48:38 +00:00
|
|
|
|
2021-08-19 15:15:44 +00:00
|
|
|
pos = begin;
|
|
|
|
if (ParserLiteral().parse(pos, node, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
return true;
|
2012-11-20 22:48:38 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
pos = begin;
|
|
|
|
}
|
2012-11-20 22:48:38 +00:00
|
|
|
|
2017-07-10 03:28:12 +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;
|
2022-02-01 15:56:03 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
bool ParserArrayElementExpression::parseImpl(Pos & pos, ASTPtr & node, Expected &expected)
|
2010-06-24 19:12:10 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
return ParserLeftAssociativeBinaryOperatorList{
|
|
|
|
operators,
|
2022-02-01 15:56:03 +00:00
|
|
|
std::make_unique<ParserCastExpression>(std::make_unique<ParserExpressionElement>()),
|
2017-04-01 07:20:54 +00:00
|
|
|
std::make_unique<ParserExpressionWithOptionalAlias>(false)
|
2017-07-10 03:28:12 +00:00
|
|
|
}.parse(pos, node, expected);
|
2010-06-24 19:12:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
bool ParserTupleElementExpression::parseImpl(Pos & pos, ASTPtr & node, Expected &expected)
|
2015-11-07 23:18:39 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
return ParserLeftAssociativeBinaryOperatorList{
|
|
|
|
operators,
|
2022-02-01 15:56:03 +00:00
|
|
|
std::make_unique<ParserCastExpression>(std::make_unique<ParserArrayElementExpression>()),
|
2017-04-01 07:20:54 +00:00
|
|
|
std::make_unique<ParserUnsignedInteger>()
|
2017-07-10 03:28:12 +00:00
|
|
|
}.parse(pos, node, expected);
|
2015-11-07 23:18:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-13 05:18: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))
|
2011-11-06 20:47:07 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
bool ParserExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
2010-06-24 19:12:10 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
return ParserList(
|
2021-02-13 05:18:14 +00:00
|
|
|
std::make_unique<ParserExpressionWithOptionalAlias>(allow_alias_without_as_keyword, is_table_function),
|
2017-07-10 03:28:12 +00:00
|
|
|
std::make_unique<ParserToken>(TokenType::Comma))
|
|
|
|
.parse(pos, node, expected);
|
2010-06-24 19:12:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
bool ParserNotEmptyExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
2010-06-24 19:12:10 +00:00
|
|
|
{
|
2019-03-11 12:49:39 +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
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
bool ParserOrderByExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
2011-09-04 05:14:52 +00:00
|
|
|
{
|
2017-07-10 03:28:12 +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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
bool ParserNullityChecking::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
2016-07-18 16:12:29 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
ASTPtr node_comp;
|
2019-10-31 15:22:48 +00:00
|
|
|
if (!elem_parser.parse(pos, node_comp, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
return false;
|
2016-07-18 16:12:29 +00:00
|
|
|
|
2017-06-18 03:07:03 +00:00
|
|
|
ParserKeyword s_is{"IS"};
|
|
|
|
ParserKeyword s_not{"NOT"};
|
|
|
|
ParserKeyword s_null{"NULL"};
|
2016-07-18 16:12:29 +00:00
|
|
|
|
2017-07-10 03:28:12 +00:00
|
|
|
if (s_is.ignore(pos, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
|
|
|
bool is_not = false;
|
2017-07-10 03:28:12 +00:00
|
|
|
if (s_not.ignore(pos, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
is_not = true;
|
2017-07-10 03:28:12 +00:00
|
|
|
|
|
|
|
if (!s_null.ignore(pos, expected))
|
2017-04-01 07:20:54 +00:00
|
|
|
return false;
|
2016-07-18 16:12:29 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
auto args = std::make_shared<ASTExpressionList>();
|
|
|
|
args->children.push_back(node_comp);
|
2016-07-18 16:12:29 +00:00
|
|
|
|
2018-02-26 03:37:08 +00:00
|
|
|
auto function = std::make_shared<ASTFunction>();
|
2017-04-01 07:20:54 +00:00
|
|
|
function->name = is_not ? "isNotNull" : "isNull";
|
|
|
|
function->arguments = args;
|
|
|
|
function->children.push_back(function->arguments);
|
2016-07-18 16:12:29 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
node = function;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
node = node_comp;
|
2016-07-18 16:12:29 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
return true;
|
2016-07-18 16:12:29 +00:00
|
|
|
}
|
|
|
|
|
2020-03-17 21:56:47 +00:00
|
|
|
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;
|
|
|
|
}
|
2016-07-18 16:12:29 +00:00
|
|
|
|
2020-10-15 07:18:38 +00:00
|
|
|
bool ParserIntervalOperatorExpression::parseArgumentAndIntervalKind(
|
|
|
|
Pos & pos, ASTPtr & expr, IntervalKind & interval_kind, Expected & expected)
|
2017-10-30 02:18:06 +00:00
|
|
|
{
|
2020-03-05 14:55:53 +00:00
|
|
|
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
|
2017-10-30 02:18:06 +00:00
|
|
|
if (!ParserExpressionWithOptionalAlias(false).parse(pos, expr, expected))
|
2020-10-15 07:18:38 +00:00
|
|
|
return false;
|
|
|
|
return parseIntervalKind(pos, expected, interval_kind);
|
|
|
|
}
|
|
|
|
|
2017-10-30 02:18:06 +00:00
|
|
|
bool ParserIntervalOperatorExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
|
|
|
{
|
2020-03-05 14:55:53 +00:00
|
|
|
auto begin = pos;
|
|
|
|
|
|
|
|
/// If no INTERVAL keyword, go to the nested parser.
|
2017-10-30 02:18:06 +00:00
|
|
|
if (!ParserKeyword("INTERVAL").ignore(pos, expected))
|
|
|
|
return next_parser.parse(pos, node, expected);
|
|
|
|
|
|
|
|
ASTPtr expr;
|
2019-11-16 13:54:52 +00:00
|
|
|
IntervalKind interval_kind;
|
2020-10-15 07:18:38 +00:00
|
|
|
if (!parseArgumentAndIntervalKind(pos, expr, interval_kind, expected))
|
2020-03-05 14:55:53 +00:00
|
|
|
{
|
|
|
|
pos = begin;
|
|
|
|
return next_parser.parse(pos, node, expected);
|
|
|
|
}
|
2017-10-30 02:18:06 +00:00
|
|
|
|
|
|
|
/// 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
|
2019-11-16 13:54:52 +00:00
|
|
|
function->name = interval_kind.toNameOfFunctionToIntervalDataType();
|
2017-10-30 02:18:06 +00:00
|
|
|
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);
|
2020-10-24 18:46:10 +00:00
|
|
|
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);
|
|
|
|
}
|
2017-10-30 02:18:06 +00:00
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
}
|