2021-10-31 15:11:46 +00:00
|
|
|
|
#include <string_view>
|
2023-02-21 02:41:58 +00:00
|
|
|
|
#include <unordered_map>
|
2021-10-31 15:11:46 +00:00
|
|
|
|
|
2020-10-24 18:46:10 +00:00
|
|
|
|
#include <Parsers/ExpressionListParsers.h>
|
2022-07-28 17:54:46 +00:00
|
|
|
|
#include <Parsers/ParserSetQuery.h>
|
2020-10-24 18:46:10 +00:00
|
|
|
|
|
2021-06-03 02:19:07 +00:00
|
|
|
|
#include <Parsers/ASTAsterisk.h>
|
2022-11-02 06:11:37 +00:00
|
|
|
|
#include <Parsers/ASTColumnsMatcher.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>
|
2022-07-28 17:54:46 +00:00
|
|
|
|
#include <Parsers/ASTSetQuery.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>
|
2023-03-24 02:44:52 +00:00
|
|
|
|
#include <Common/assert_cast.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-05-04 21:05:25 +00:00
|
|
|
|
#include <Common/logger_useful.h>
|
2022-04-12 15:03:10 +00:00
|
|
|
|
#include <Parsers/queryToString.h>
|
2023-02-21 02:41:58 +00:00
|
|
|
|
#include <Parsers/CommonParsers.h>
|
2023-04-03 01:14:09 +00:00
|
|
|
|
#include <Parsers/Kusto/ParserKQLStatement.h>
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2023-11-22 16:17:28 +00:00
|
|
|
|
#include <AggregateFunctions/AggregateFunctionFactory.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
|
|
|
|
|
2022-06-29 21:51:58 +00:00
|
|
|
|
namespace ErrorCodes
|
|
|
|
|
{
|
|
|
|
|
extern const int SYNTAX_ERROR;
|
2023-11-22 16:17:28 +00:00
|
|
|
|
extern const int UNKNOWN_AGGREGATE_FUNCTION;
|
2022-06-29 21:51:58 +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 = [&]
|
2011-08-18 18:48:00 +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
|
|
|
|
|
2022-10-14 13:24:47 +00:00
|
|
|
|
elements.push_back(std::move(element));
|
2020-06-05 21:31:37 +00:00
|
|
|
|
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
|
|
|
|
|
2022-10-14 13:24:47 +00:00
|
|
|
|
node = std::make_shared<ASTExpressionList>(result_separator);
|
|
|
|
|
node->children = std::move(elements);
|
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;
|
|
|
|
|
|
2022-10-14 13:24:47 +00:00
|
|
|
|
elements.push_back(std::move(element));
|
2020-10-26 09:33:34 +00:00
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
|
2022-08-30 10:09:01 +00:00
|
|
|
|
/// Parse UNION / INTERSECT / EXCEPT mode
|
|
|
|
|
/// The mode can be DEFAULT (unspecified) / DISTINCT / ALL
|
2020-10-26 09:33:34 +00:00
|
|
|
|
auto parse_separator = [&]
|
|
|
|
|
{
|
2021-08-14 12:31:55 +00:00
|
|
|
|
if (s_union_parser.ignore(pos, expected))
|
2020-10-26 09:33:34 +00:00
|
|
|
|
{
|
2021-08-14 12:31:55 +00:00
|
|
|
|
if (s_all_parser.check(pos, expected))
|
2022-08-30 10:09:01 +00:00
|
|
|
|
union_modes.push_back(SelectUnionMode::UNION_ALL);
|
2021-08-14 12:31:55 +00:00
|
|
|
|
else if (s_distinct_parser.check(pos, expected))
|
2022-08-30 10:09:01 +00:00
|
|
|
|
union_modes.push_back(SelectUnionMode::UNION_DISTINCT);
|
2020-10-26 09:33:34 +00:00
|
|
|
|
else
|
2022-08-30 10:09:01 +00:00
|
|
|
|
union_modes.push_back(SelectUnionMode::UNION_DEFAULT);
|
2021-08-13 09:57:15 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2021-08-14 12:31:55 +00:00
|
|
|
|
else if (s_except_parser.check(pos, expected))
|
2021-08-13 09:57:15 +00:00
|
|
|
|
{
|
2022-08-30 10:09:01 +00:00
|
|
|
|
if (s_all_parser.check(pos, expected))
|
|
|
|
|
union_modes.push_back(SelectUnionMode::EXCEPT_ALL);
|
|
|
|
|
else if (s_distinct_parser.check(pos, expected))
|
|
|
|
|
union_modes.push_back(SelectUnionMode::EXCEPT_DISTINCT);
|
|
|
|
|
else
|
|
|
|
|
union_modes.push_back(SelectUnionMode::EXCEPT_DEFAULT);
|
2020-10-26 09:33:34 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2021-08-14 12:31:55 +00:00
|
|
|
|
else if (s_intersect_parser.check(pos, expected))
|
|
|
|
|
{
|
2022-08-30 10:09:01 +00:00
|
|
|
|
if (s_all_parser.check(pos, expected))
|
|
|
|
|
union_modes.push_back(SelectUnionMode::INTERSECT_ALL);
|
|
|
|
|
else if (s_distinct_parser.check(pos, expected))
|
|
|
|
|
union_modes.push_back(SelectUnionMode::INTERSECT_DISTINCT);
|
|
|
|
|
else
|
|
|
|
|
union_modes.push_back(SelectUnionMode::INTERSECT_DEFAULT);
|
2021-08-14 12:31:55 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2020-10-26 09:33:34 +00:00
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (!parseUtil(pos, parse_element, parse_separator))
|
|
|
|
|
return false;
|
|
|
|
|
|
2022-10-14 13:24:47 +00:00
|
|
|
|
node = std::make_shared<ASTExpressionList>();
|
|
|
|
|
node->children = std::move(elements);
|
2020-10-26 09:33:34 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2011-08-18 18:48:00 +00:00
|
|
|
|
|
2023-04-12 18:15:08 +00:00
|
|
|
|
static bool parseOperator(IParser::Pos & pos, std::string_view op, Expected & expected)
|
2017-07-10 03:28:12 +00:00
|
|
|
|
{
|
2023-04-06 16:20:34 +00:00
|
|
|
|
if (!op.empty() && isWordCharASCII(op.front()))
|
2017-07-10 03:28:12 +00:00
|
|
|
|
{
|
2017-07-13 04:20:56 +00:00
|
|
|
|
return ParserKeyword(op).ignore(pos, expected);
|
2017-07-10 03:28:12 +00:00
|
|
|
|
}
|
2023-04-06 16:20:34 +00:00
|
|
|
|
else if (op.length() == pos->size() && 0 == memcmp(op.data(), pos->begin, pos->size()))
|
2017-07-10 03:28:12 +00:00
|
|
|
|
{
|
2023-04-06 16:20:34 +00:00
|
|
|
|
++pos;
|
|
|
|
|
return true;
|
2017-07-10 03:28:12 +00:00
|
|
|
|
}
|
2023-04-06 16:20:34 +00:00
|
|
|
|
|
|
|
|
|
return false;
|
2017-07-10 03:28:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
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)
|
2022-11-30 02:14:04 +00:00
|
|
|
|
auto aggregate_function = makeASTFunction(aggregate_function_name, std::make_shared<ASTAsterisk>());
|
2021-08-14 17:04:21 +00:00
|
|
|
|
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;
|
2022-09-13 20:31:08 +00:00
|
|
|
|
if (!elem_parser->parse(pos, elem, expected))
|
2021-06-03 02:19:07 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
2022-10-14 13:24:47 +00:00
|
|
|
|
node = std::move(elem);
|
2021-06-03 02:19:07 +00:00
|
|
|
|
first = false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/// try to find any of the valid operators
|
|
|
|
|
const char ** it;
|
|
|
|
|
for (it = operators; *it; it += 2)
|
|
|
|
|
if (parseOperator(pos, *it, expected))
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (!*it)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
ASTPtr elem;
|
2022-03-30 18:16:41 +00:00
|
|
|
|
|
2022-09-13 20:31:08 +00:00
|
|
|
|
if (!elem_parser->parse(pos, elem, expected))
|
2021-06-03 02:19:07 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
/// the first argument of the function is the previous element, the second is the next one
|
2022-09-13 20:31:08 +00:00
|
|
|
|
auto function = makeASTFunction(it[1], node, elem);
|
2021-06-03 02:19:07 +00:00
|
|
|
|
|
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)
|
2010-06-24 19:12:10 +00:00
|
|
|
|
{
|
2017-07-10 03:28:12 +00:00
|
|
|
|
if (pos->type != TokenType::ClosingSquareBracket)
|
2010-06-24 19:12:10 +00:00
|
|
|
|
return false;
|
2017-07-10 03:28:12 +00:00
|
|
|
|
++pos;
|
2010-06-24 19:12:10 +00:00
|
|
|
|
}
|
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();
|
2016-05-28 15:42:22 +00:00
|
|
|
|
node = function;
|
2010-06-24 19:12:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-04-01 07:20:54 +00:00
|
|
|
|
|
2019-08-10 17:08:14 +00:00
|
|
|
|
pos.depth = current_depth;
|
2010-06-24 19:12:10 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-13 11:05:51 +00:00
|
|
|
|
|
2022-06-22 21:59:20 +00:00
|
|
|
|
ASTPtr makeBetweenOperator(bool negative, ASTs arguments)
|
|
|
|
|
{
|
2022-09-15 00:48:14 +00:00
|
|
|
|
// SUBJECT = arguments[0], LEFT = arguments[1], RIGHT = arguments[2]
|
2022-06-22 21:59:20 +00:00
|
|
|
|
|
|
|
|
|
if (negative)
|
|
|
|
|
{
|
2022-09-15 00:48:14 +00:00
|
|
|
|
auto f_left_expr = makeASTFunction("less", arguments[0], arguments[1]);
|
|
|
|
|
auto f_right_expr = makeASTFunction("greater", arguments[0], arguments[2]);
|
|
|
|
|
return makeASTFunction("or", f_left_expr, f_right_expr);
|
2022-06-22 21:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-09-15 00:48:14 +00:00
|
|
|
|
auto f_left_expr = makeASTFunction("greaterOrEquals", arguments[0], arguments[1]);
|
|
|
|
|
auto f_right_expr = makeASTFunction("lessOrEquals", arguments[0], arguments[2]);
|
|
|
|
|
return makeASTFunction("and", f_left_expr, f_right_expr);
|
2022-06-22 21:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-05 18:08:56 +00:00
|
|
|
|
ParserExpressionWithOptionalAlias::ParserExpressionWithOptionalAlias(bool allow_alias_without_as_keyword, bool is_table_function, bool allow_trailing_commas)
|
2022-09-16 03:29:34 +00:00
|
|
|
|
: impl(std::make_unique<ParserWithOptionalAlias>(
|
2023-04-05 18:08:56 +00:00
|
|
|
|
is_table_function ? ParserPtr(std::make_unique<ParserTableFunctionExpression>()) : ParserPtr(std::make_unique<ParserExpression>(allow_trailing_commas)),
|
2022-09-16 03:29:34 +00:00
|
|
|
|
allow_alias_without_as_keyword))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool ParserExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
|
|
|
|
{
|
|
|
|
|
return ParserList(
|
2023-04-05 18:08:56 +00:00
|
|
|
|
std::make_unique<ParserExpressionWithOptionalAlias>(allow_alias_without_as_keyword, is_table_function, allow_trailing_commas),
|
2022-09-16 03:29:34 +00:00
|
|
|
|
std::make_unique<ParserToken>(TokenType::Comma))
|
|
|
|
|
.parse(pos, node, expected);
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool ParserNotEmptyExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
|
|
|
|
{
|
|
|
|
|
return nested_parser.parse(pos, node, expected) && !node->children.empty();
|
|
|
|
|
}
|
2022-06-02 22:07:14 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool ParserOrderByExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
|
|
|
|
{
|
|
|
|
|
return ParserList(std::make_unique<ParserOrderByElement>(), std::make_unique<ParserToken>(TokenType::Comma), false)
|
|
|
|
|
.parse(pos, node, expected);
|
|
|
|
|
}
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool ParserGroupingSetsExpressionListElements::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
|
|
|
|
{
|
|
|
|
|
auto command_list = std::make_shared<ASTExpressionList>();
|
|
|
|
|
node = command_list;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
ParserToken s_comma(TokenType::Comma);
|
|
|
|
|
ParserToken s_open(TokenType::OpeningRoundBracket);
|
|
|
|
|
ParserToken s_close(TokenType::ClosingRoundBracket);
|
|
|
|
|
ParserExpressionWithOptionalAlias p_expression(false);
|
|
|
|
|
ParserList p_command(std::make_unique<ParserExpressionWithOptionalAlias>(false),
|
|
|
|
|
std::make_unique<ParserToken>(TokenType::Comma), true);
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
do
|
2022-04-17 20:59:03 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
Pos begin = pos;
|
|
|
|
|
ASTPtr command;
|
|
|
|
|
if (!s_open.ignore(pos, expected))
|
2022-04-17 20:59:03 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
pos = begin;
|
|
|
|
|
if (!p_expression.parse(pos, command, expected))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
auto list = std::make_shared<ASTExpressionList>(',');
|
|
|
|
|
list->children.push_back(command);
|
|
|
|
|
command = std::move(list);
|
2022-04-17 20:59:03 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!p_command.parse(pos, command, expected))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (!s_close.ignore(pos, expected))
|
|
|
|
|
break;
|
2022-04-17 20:59:03 +00:00
|
|
|
|
}
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
|
|
|
|
command_list->children.push_back(command);
|
2022-04-17 20:59:03 +00:00
|
|
|
|
}
|
2022-07-14 12:11:14 +00:00
|
|
|
|
while (s_comma.ignore(pos, expected));
|
2022-04-17 20:59:03 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool ParserGroupingSetsExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
|
|
|
|
{
|
|
|
|
|
ParserGroupingSetsExpressionListElements grouping_sets_elements;
|
|
|
|
|
return grouping_sets_elements.parse(pos, node, expected);
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
}
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool ParserInterpolateExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
|
|
|
|
{
|
|
|
|
|
return ParserList(std::make_unique<ParserInterpolateElement>(), std::make_unique<ParserToken>(TokenType::Comma), true)
|
|
|
|
|
.parse(pos, node, expected);
|
|
|
|
|
}
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool ParserTTLExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
|
|
|
|
{
|
|
|
|
|
return ParserList(std::make_unique<ParserTTLElement>(), std::make_unique<ParserToken>(TokenType::Comma), false)
|
|
|
|
|
.parse(pos, node, expected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool ParserKeyValuePair::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
|
|
|
|
{
|
|
|
|
|
ParserIdentifier id_parser;
|
|
|
|
|
ParserLiteral literal_parser;
|
|
|
|
|
ParserFunction func_parser;
|
2022-06-22 21:59:20 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
ASTPtr identifier;
|
|
|
|
|
ASTPtr value;
|
|
|
|
|
bool with_brackets = false;
|
|
|
|
|
if (!id_parser.parse(pos, identifier, expected))
|
|
|
|
|
return false;
|
2022-06-22 21:59:20 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
/// If it's neither literal, nor identifier, nor function, than it's possible list of pairs
|
|
|
|
|
if (!func_parser.parse(pos, value, expected) && !literal_parser.parse(pos, value, expected) && !id_parser.parse(pos, value, expected))
|
|
|
|
|
{
|
|
|
|
|
ParserKeyValuePairsList kv_pairs_list;
|
|
|
|
|
ParserToken open(TokenType::OpeningRoundBracket);
|
|
|
|
|
ParserToken close(TokenType::ClosingRoundBracket);
|
2022-06-22 21:59:20 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!open.ignore(pos))
|
|
|
|
|
return false;
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!kv_pairs_list.parse(pos, value, expected))
|
|
|
|
|
return false;
|
2022-06-22 21:59:20 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!close.ignore(pos))
|
|
|
|
|
return false;
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
with_brackets = true;
|
|
|
|
|
}
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
auto pair = std::make_shared<ASTPair>(with_brackets);
|
|
|
|
|
pair->first = Poco::toLower(identifier->as<ASTIdentifier>()->name());
|
|
|
|
|
pair->set(pair->second, value);
|
|
|
|
|
node = pair;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool ParserKeyValuePairsList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
|
|
|
|
{
|
|
|
|
|
ParserList parser(std::make_unique<ParserKeyValuePair>(), std::make_unique<ParserNothing>(), true, 0);
|
|
|
|
|
return parser.parse(pos, node, expected);
|
|
|
|
|
}
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
enum class Action
|
|
|
|
|
{
|
2022-09-15 21:54:37 +00:00
|
|
|
|
NONE,
|
2022-07-14 12:11:14 +00:00
|
|
|
|
OPERAND,
|
|
|
|
|
OPERATOR
|
|
|
|
|
};
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
/** Operator types are needed for special handling of certain operators.
|
|
|
|
|
* Operators can be grouped into some type if they have similar behaviour.
|
|
|
|
|
* Certain operators are unique in terms of their behaviour, so they are assigned a separate type.
|
|
|
|
|
*/
|
|
|
|
|
enum class OperatorType
|
|
|
|
|
{
|
|
|
|
|
None,
|
|
|
|
|
Comparison,
|
|
|
|
|
Mergeable,
|
|
|
|
|
ArrayElement,
|
|
|
|
|
TupleElement,
|
|
|
|
|
IsNull,
|
|
|
|
|
StartBetween,
|
|
|
|
|
StartNotBetween,
|
|
|
|
|
FinishBetween,
|
|
|
|
|
StartIf,
|
|
|
|
|
FinishIf,
|
2022-08-04 09:32:14 +00:00
|
|
|
|
Cast,
|
|
|
|
|
Lambda
|
2022-07-14 12:11:14 +00:00
|
|
|
|
};
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-09-13 21:07:15 +00:00
|
|
|
|
/** Operator struct stores parameters of the operator:
|
2022-07-14 12:11:14 +00:00
|
|
|
|
* - function_name name of the function that operator will create
|
|
|
|
|
* - priority priority of the operator relative to the other operators
|
|
|
|
|
* - arity the amount of arguments that operator will consume
|
|
|
|
|
* - type type of the operator that defines its behaviour
|
|
|
|
|
*/
|
2022-09-13 21:07:15 +00:00
|
|
|
|
struct Operator
|
2022-07-14 12:11:14 +00:00
|
|
|
|
{
|
|
|
|
|
Operator() = default;
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-10-19 23:38:44 +00:00
|
|
|
|
Operator(const std::string & function_name_,
|
|
|
|
|
int priority_,
|
|
|
|
|
int arity_,
|
|
|
|
|
OperatorType type_ = OperatorType::None)
|
2022-09-13 21:07:15 +00:00
|
|
|
|
: type(type_), priority(priority_), arity(arity_), function_name(function_name_) {}
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
OperatorType type;
|
2022-09-14 09:44:51 +00:00
|
|
|
|
int priority;
|
|
|
|
|
int arity;
|
|
|
|
|
std::string function_name;
|
2022-06-16 01:53:27 +00:00
|
|
|
|
};
|
2022-05-26 23:38:25 +00:00
|
|
|
|
|
2022-10-04 18:43:33 +00:00
|
|
|
|
template <typename... Args>
|
|
|
|
|
static std::shared_ptr<ASTFunction> makeASTFunction(Operator & op, Args &&... args)
|
|
|
|
|
{
|
|
|
|
|
auto ast_function = makeASTFunction(op.function_name, std::forward<Args>(args)...);
|
2022-11-11 15:26:04 +00:00
|
|
|
|
|
|
|
|
|
if (op.type == OperatorType::Lambda)
|
|
|
|
|
{
|
|
|
|
|
ast_function->is_lambda_function = true;
|
|
|
|
|
ast_function->kind = ASTFunction::Kind::LAMBDA_FUNCTION;
|
|
|
|
|
}
|
2022-10-04 18:43:33 +00:00
|
|
|
|
return ast_function;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-05 16:21:16 +00:00
|
|
|
|
enum class Checkpoint
|
|
|
|
|
{
|
|
|
|
|
None,
|
|
|
|
|
Interval,
|
|
|
|
|
Case
|
|
|
|
|
};
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
/** Layer is a class that represents context for parsing certain element,
|
|
|
|
|
* that consists of other elements e.g. f(x1, x2, x3)
|
|
|
|
|
*
|
|
|
|
|
* - Manages operands and operators for the future elements (arguments)
|
|
|
|
|
* - Combines operands and operator into one element
|
|
|
|
|
* - Parsers separators and endings
|
2022-08-10 04:58:59 +00:00
|
|
|
|
* - Combines resulting elements into a function
|
2022-07-14 12:11:14 +00:00
|
|
|
|
*/
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
class Layer
|
2022-06-16 01:53:27 +00:00
|
|
|
|
{
|
|
|
|
|
public:
|
2022-10-19 23:39:35 +00:00
|
|
|
|
explicit Layer(bool allow_alias_ = true, bool allow_alias_without_as_keyword_ = false) :
|
2022-10-19 23:38:44 +00:00
|
|
|
|
allow_alias(allow_alias_), allow_alias_without_as_keyword(allow_alias_without_as_keyword_) {}
|
2022-08-10 04:58:59 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
virtual ~Layer() = default;
|
|
|
|
|
|
|
|
|
|
bool popOperator(Operator & op)
|
2022-06-16 01:53:27 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (operators.empty())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
op = std::move(operators.back());
|
|
|
|
|
operators.pop_back();
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
void pushOperator(Operator op)
|
2022-06-16 01:53:27 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
operators.push_back(std::move(op));
|
|
|
|
|
}
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool popOperand(ASTPtr & op)
|
|
|
|
|
{
|
|
|
|
|
if (operands.empty())
|
|
|
|
|
return false;
|
2022-06-27 13:49:37 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
op = std::move(operands.back());
|
|
|
|
|
operands.pop_back();
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
void pushOperand(ASTPtr op)
|
2022-06-16 01:53:27 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
operands.push_back(std::move(op));
|
2022-06-16 01:53:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
void pushResult(ASTPtr op)
|
2022-06-16 01:53:27 +00:00
|
|
|
|
{
|
2022-08-10 04:58:59 +00:00
|
|
|
|
elements.push_back(std::move(op));
|
2022-06-16 01:53:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-09-13 20:31:08 +00:00
|
|
|
|
virtual bool getResult(ASTPtr & node)
|
2022-06-16 01:53:27 +00:00
|
|
|
|
{
|
2022-10-27 10:03:03 +00:00
|
|
|
|
if (!finished)
|
|
|
|
|
return false;
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
2022-10-27 10:03:03 +00:00
|
|
|
|
return getResultImpl(node);
|
2022-06-16 01:53:27 +00:00
|
|
|
|
}
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-08-10 04:58:59 +00:00
|
|
|
|
virtual bool parse(IParser::Pos & /*pos*/, Expected & /*expected*/, Action & /*action*/) = 0;
|
2022-05-26 22:53:37 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool isFinished() const
|
|
|
|
|
{
|
|
|
|
|
return finished;
|
|
|
|
|
}
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
int previousPriority() const
|
|
|
|
|
{
|
|
|
|
|
if (operators.empty())
|
|
|
|
|
return 0;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
return operators.back().priority;
|
|
|
|
|
}
|
2022-05-26 22:53:37 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
OperatorType previousType() const
|
|
|
|
|
{
|
|
|
|
|
if (operators.empty())
|
|
|
|
|
return OperatorType::None;
|
2022-05-26 22:53:37 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
return operators.back().type;
|
|
|
|
|
}
|
2022-05-26 22:53:37 +00:00
|
|
|
|
|
2022-09-15 00:48:14 +00:00
|
|
|
|
int isCurrentElementEmpty() const
|
2022-07-14 12:11:14 +00:00
|
|
|
|
{
|
|
|
|
|
return operators.empty() && operands.empty();
|
|
|
|
|
}
|
2022-05-26 22:53:37 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool popLastNOperands(ASTs & asts, size_t n)
|
|
|
|
|
{
|
|
|
|
|
if (n > operands.size())
|
|
|
|
|
return false;
|
2022-05-26 22:53:37 +00:00
|
|
|
|
|
2022-08-04 09:32:14 +00:00
|
|
|
|
asts.reserve(asts.size() + n);
|
|
|
|
|
|
2022-10-18 09:40:12 +00:00
|
|
|
|
auto * start = operands.begin() + operands.size() - n;
|
2022-07-14 12:11:14 +00:00
|
|
|
|
asts.insert(asts.end(), std::make_move_iterator(start), std::make_move_iterator(operands.end()));
|
|
|
|
|
operands.erase(start, operands.end());
|
2022-05-26 22:53:37 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-05-26 22:53:37 +00:00
|
|
|
|
|
2022-08-10 04:58:59 +00:00
|
|
|
|
/// Merge operators and operands into a single element (column), then push it to 'elements' vector.
|
2022-08-04 09:32:14 +00:00
|
|
|
|
/// Operators are previously sorted in ascending order of priority
|
|
|
|
|
/// (operator with priority 1 has higher priority than operator with priority 2),
|
2022-07-14 12:11:14 +00:00
|
|
|
|
/// so we can just merge them with operands starting from the end.
|
|
|
|
|
///
|
2022-08-04 09:32:14 +00:00
|
|
|
|
/// If we fail here it means that the query was incorrect and we should return an error.
|
|
|
|
|
///
|
2022-08-10 04:58:59 +00:00
|
|
|
|
bool mergeElement(bool push_to_elements = true)
|
2022-07-14 12:11:14 +00:00
|
|
|
|
{
|
2022-10-21 00:16:24 +00:00
|
|
|
|
parsed_alias = false;
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
Operator cur_op;
|
|
|
|
|
while (popOperator(cur_op))
|
|
|
|
|
{
|
|
|
|
|
ASTPtr function;
|
2022-05-26 22:53:37 +00:00
|
|
|
|
|
2022-10-21 00:16:24 +00:00
|
|
|
|
// We should not meet the starting part of the operator while finishing an element
|
|
|
|
|
if (cur_op.type == OperatorType::StartIf ||
|
|
|
|
|
cur_op.type == OperatorType::StartBetween ||
|
|
|
|
|
cur_op.type == OperatorType::StartNotBetween)
|
2022-07-14 12:11:14 +00:00
|
|
|
|
return false;
|
2022-05-26 22:53:37 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (cur_op.type == OperatorType::FinishIf)
|
|
|
|
|
{
|
|
|
|
|
Operator tmp;
|
|
|
|
|
if (!popOperator(tmp) || tmp.type != OperatorType::StartIf)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-05-26 22:53:37 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (cur_op.type == OperatorType::FinishBetween)
|
2022-04-08 03:30:49 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
Operator tmp_op;
|
|
|
|
|
if (!popOperator(tmp_op))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (tmp_op.type != OperatorType::StartBetween && tmp_op.type != OperatorType::StartNotBetween)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
bool negative = tmp_op.type == OperatorType::StartNotBetween;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
ASTs arguments;
|
|
|
|
|
if (!popLastNOperands(arguments, 3))
|
2022-04-08 03:30:49 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
function = makeBetweenOperator(negative, arguments);
|
2022-04-08 03:30:49 +00:00
|
|
|
|
}
|
2022-07-14 12:11:14 +00:00
|
|
|
|
else
|
2022-04-08 03:30:49 +00:00
|
|
|
|
{
|
2023-04-03 01:14:09 +00:00
|
|
|
|
/// enable using subscript operator for kql_array_sort
|
|
|
|
|
if (cur_op.function_name == "arrayElement" && !operands.empty())
|
|
|
|
|
{
|
|
|
|
|
auto* first_arg_as_node = operands.front()->as<ASTFunction>();
|
|
|
|
|
if (first_arg_as_node)
|
|
|
|
|
{
|
|
|
|
|
if (first_arg_as_node->name == "kql_array_sort_asc" || first_arg_as_node->name == "kql_array_sort_desc")
|
|
|
|
|
{
|
|
|
|
|
cur_op.function_name = "tupleElement";
|
|
|
|
|
cur_op.type = OperatorType::TupleElement;
|
|
|
|
|
}
|
|
|
|
|
else if (first_arg_as_node->name == "arrayElement" && !first_arg_as_node->arguments->children.empty())
|
|
|
|
|
{
|
|
|
|
|
auto *arg_inside = first_arg_as_node->arguments->children[0]->as<ASTFunction>();
|
|
|
|
|
if (arg_inside && (arg_inside->name == "kql_array_sort_asc" || arg_inside->name == "kql_array_sort_desc"))
|
|
|
|
|
first_arg_as_node->name = "tupleElement";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-04 18:43:33 +00:00
|
|
|
|
function = makeASTFunction(cur_op);
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!popLastNOperands(function->children[0]->children, cur_op.arity))
|
|
|
|
|
return false;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
}
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
|
|
|
|
pushOperand(function);
|
2022-04-08 03:30:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
ASTPtr node;
|
|
|
|
|
if (!popOperand(node))
|
|
|
|
|
return false;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-09-15 00:48:14 +00:00
|
|
|
|
bool res = isCurrentElementEmpty();
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-08-10 04:58:59 +00:00
|
|
|
|
if (push_to_elements)
|
2022-07-14 12:11:14 +00:00
|
|
|
|
pushResult(node);
|
2022-06-16 01:53:27 +00:00
|
|
|
|
else
|
2022-07-14 12:11:14 +00:00
|
|
|
|
pushOperand(node);
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
return res;
|
2022-06-16 01:53:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool parseLambda()
|
2022-04-08 03:30:49 +00:00
|
|
|
|
{
|
2022-11-05 01:30:07 +00:00
|
|
|
|
// 1. If empty - create function tuple with 0 args
|
2022-09-15 00:48:14 +00:00
|
|
|
|
if (isCurrentElementEmpty())
|
2022-04-08 03:30:49 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
auto function = makeASTFunction("tuple");
|
|
|
|
|
pushOperand(function);
|
|
|
|
|
return true;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-08-04 09:32:14 +00:00
|
|
|
|
if (operands.size() != 1 || !operators.empty() || !mergeElement())
|
2022-07-14 12:11:14 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
2022-11-05 01:30:07 +00:00
|
|
|
|
/// 2. If there is already tuple do nothing
|
2022-08-10 04:58:59 +00:00
|
|
|
|
if (tryGetFunctionName(elements.back()) == "tuple")
|
2022-04-08 03:30:49 +00:00
|
|
|
|
{
|
2022-12-27 14:49:41 +00:00
|
|
|
|
pushOperand(std::move(elements.back()));
|
2022-08-10 04:58:59 +00:00
|
|
|
|
elements.pop_back();
|
2022-04-08 03:30:49 +00:00
|
|
|
|
}
|
2022-11-05 01:30:07 +00:00
|
|
|
|
/// 3. Put all elements in a single tuple
|
2022-07-14 12:11:14 +00:00
|
|
|
|
else
|
2022-04-08 03:30:49 +00:00
|
|
|
|
{
|
2022-11-05 01:30:07 +00:00
|
|
|
|
auto function = makeASTFunction("tuple", std::move(elements));
|
2022-08-10 04:58:59 +00:00
|
|
|
|
elements.clear();
|
2022-07-14 12:11:14 +00:00
|
|
|
|
pushOperand(function);
|
2022-04-08 03:30:49 +00:00
|
|
|
|
}
|
2022-12-27 14:49:41 +00:00
|
|
|
|
|
|
|
|
|
/// We must check that tuple arguments are identifiers
|
|
|
|
|
auto * func_ptr = operands.back()->as<ASTFunction>();
|
|
|
|
|
auto * args_ptr = func_ptr->arguments->as<ASTExpressionList>();
|
|
|
|
|
|
|
|
|
|
for (const auto & child : args_ptr->children)
|
|
|
|
|
{
|
|
|
|
|
if (typeid_cast<ASTIdentifier *>(child.get()))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-04 10:06:18 +00:00
|
|
|
|
/// Put 'node' identifier into the last operand as its alias
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool insertAlias(ASTPtr node)
|
2022-04-08 03:30:49 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!mergeElement(false))
|
|
|
|
|
return false;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (operands.empty())
|
|
|
|
|
return false;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (auto * ast_with_alias = dynamic_cast<ASTWithAlias *>(operands.back().get()))
|
2022-09-16 02:36:11 +00:00
|
|
|
|
{
|
2022-09-16 03:29:34 +00:00
|
|
|
|
tryGetIdentifierNameInto(node, ast_with_alias->alias);
|
|
|
|
|
return true;
|
2022-09-16 02:36:11 +00:00
|
|
|
|
}
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-09-16 02:36:11 +00:00
|
|
|
|
return false;
|
2022-07-14 12:11:14 +00:00
|
|
|
|
}
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-09-13 20:31:08 +00:00
|
|
|
|
bool is_table_function = false;
|
|
|
|
|
|
2022-08-10 04:58:59 +00:00
|
|
|
|
/// 'AND' in operator '... BETWEEN ... AND ...' mirrors logical operator 'AND'.
|
|
|
|
|
/// In order to distinguish them we keep a counter of BETWEENs without matching ANDs.
|
|
|
|
|
int between_counter = 0;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-10-21 00:16:24 +00:00
|
|
|
|
/// Flag we set when we parsed alias to avoid parsing next element as alias
|
|
|
|
|
bool parsed_alias = false;
|
|
|
|
|
|
2022-08-10 04:58:59 +00:00
|
|
|
|
bool allow_alias = true;
|
|
|
|
|
bool allow_alias_without_as_keyword = true;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-09-07 01:45:13 +00:00
|
|
|
|
std::optional<std::pair<IParser::Pos, Checkpoint>> saved_checkpoint;
|
2022-09-15 00:48:14 +00:00
|
|
|
|
Checkpoint current_checkpoint = Checkpoint::None;
|
2022-09-05 16:21:16 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
protected:
|
2022-10-27 10:03:03 +00:00
|
|
|
|
virtual bool getResultImpl(ASTPtr & node)
|
|
|
|
|
{
|
|
|
|
|
if (elements.size() == 1)
|
|
|
|
|
{
|
|
|
|
|
node = std::move(elements[0]);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
std::vector<Operator> operators;
|
|
|
|
|
ASTs operands;
|
2022-08-10 04:58:59 +00:00
|
|
|
|
ASTs elements;
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool finished = false;
|
|
|
|
|
int state = 0;
|
2022-08-10 04:58:59 +00:00
|
|
|
|
};
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
2023-04-09 12:52:23 +00:00
|
|
|
|
struct ParserExpressionImpl
|
|
|
|
|
{
|
2023-04-12 18:15:08 +00:00
|
|
|
|
static const std::vector<std::pair<std::string_view, Operator>> operators_table;
|
|
|
|
|
static const std::vector<std::pair<std::string_view, Operator>> unary_operators_table;
|
|
|
|
|
static const std::array<std::string_view, 1> overlapping_operators_to_skip;
|
2023-04-09 12:52:23 +00:00
|
|
|
|
|
2023-04-12 18:15:08 +00:00
|
|
|
|
static const Operator finish_between_operator;
|
2023-04-09 12:52:23 +00:00
|
|
|
|
|
|
|
|
|
ParserCompoundIdentifier identifier_parser{false, true};
|
|
|
|
|
ParserNumber number_parser;
|
|
|
|
|
ParserAsterisk asterisk_parser;
|
|
|
|
|
ParserLiteral literal_parser;
|
|
|
|
|
ParserTupleOfLiterals tuple_literal_parser;
|
|
|
|
|
ParserArrayOfLiterals array_literal_parser;
|
|
|
|
|
ParserSubstitution substitution_parser;
|
|
|
|
|
ParserMySQLGlobalVariable mysql_global_variable_parser;
|
|
|
|
|
|
|
|
|
|
ParserKeyword any_parser{"ANY"};
|
|
|
|
|
ParserKeyword all_parser{"ALL"};
|
|
|
|
|
|
|
|
|
|
// Recursion
|
|
|
|
|
ParserQualifiedAsterisk qualified_asterisk_parser;
|
|
|
|
|
ParserColumnsMatcher columns_matcher_parser;
|
|
|
|
|
ParserQualifiedColumnsMatcher qualified_columns_matcher_parser;
|
|
|
|
|
ParserSubquery subquery_parser;
|
|
|
|
|
|
|
|
|
|
bool parse(std::unique_ptr<Layer> start, IParser::Pos & pos, ASTPtr & node, Expected & expected);
|
|
|
|
|
|
|
|
|
|
using Layers = std::vector<std::unique_ptr<Layer>>;
|
|
|
|
|
|
|
|
|
|
Action tryParseOperand(Layers & layers, IParser::Pos & pos, Expected & expected);
|
|
|
|
|
Action tryParseOperator(Layers & layers, IParser::Pos & pos, Expected & expected);
|
|
|
|
|
};
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
2022-09-15 21:54:37 +00:00
|
|
|
|
class ExpressionLayer : public Layer
|
2022-08-10 04:58:59 +00:00
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
2023-04-05 18:08:56 +00:00
|
|
|
|
explicit ExpressionLayer(bool is_table_function_, bool allow_trailing_commas_ = false)
|
|
|
|
|
: Layer(false, false)
|
2022-08-10 04:58:59 +00:00
|
|
|
|
{
|
2022-09-15 21:54:37 +00:00
|
|
|
|
is_table_function = is_table_function_;
|
2023-04-05 18:08:56 +00:00
|
|
|
|
allow_trailing_commas = allow_trailing_commas_;
|
2022-08-10 04:58:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-09-13 20:31:08 +00:00
|
|
|
|
bool getResult(ASTPtr & node) override
|
2022-08-10 04:58:59 +00:00
|
|
|
|
{
|
|
|
|
|
/// We can exit the main cycle outside the parse() function,
|
2022-10-27 10:03:03 +00:00
|
|
|
|
/// so we need to merge the element here.
|
|
|
|
|
/// Because of this 'finished' flag can also not be set.
|
2022-08-10 04:58:59 +00:00
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
|
|
|
|
|
2022-10-27 10:03:03 +00:00
|
|
|
|
return Layer::getResultImpl(node);
|
2022-08-10 04:58:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool parse(IParser::Pos & pos, Expected & /*expected*/, Action & /*action*/) override
|
|
|
|
|
{
|
|
|
|
|
if (pos->type == TokenType::Comma)
|
2023-04-05 18:08:56 +00:00
|
|
|
|
{
|
2022-08-10 04:58:59 +00:00
|
|
|
|
finished = true;
|
|
|
|
|
|
2023-04-05 18:08:56 +00:00
|
|
|
|
if (!allow_trailing_commas)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
/// We support trailing commas at the end of the column declaration:
|
|
|
|
|
/// - SELECT a, b, c, FROM table
|
|
|
|
|
/// - SELECT 1,
|
|
|
|
|
|
2023-04-09 12:52:23 +00:00
|
|
|
|
/// For this purpose we need to eliminate the following cases:
|
2023-04-05 18:08:56 +00:00
|
|
|
|
/// 1. WITH 1 AS from SELECT 2, from
|
|
|
|
|
/// 2. SELECT to, from FROM table
|
|
|
|
|
/// 3. SELECT to, from AS alias FROM table
|
2023-04-09 12:52:23 +00:00
|
|
|
|
/// 4. SELECT to, from + to, from IN [1,2,3], FROM table
|
2023-04-05 18:08:56 +00:00
|
|
|
|
|
2023-04-09 12:52:23 +00:00
|
|
|
|
Expected test_expected;
|
2023-04-05 18:08:56 +00:00
|
|
|
|
auto test_pos = pos;
|
|
|
|
|
++test_pos;
|
|
|
|
|
|
2023-04-09 12:52:23 +00:00
|
|
|
|
/// End of query
|
2023-04-05 18:08:56 +00:00
|
|
|
|
if (test_pos.isValid() && test_pos->type != TokenType::Semicolon)
|
|
|
|
|
{
|
2023-04-09 12:52:23 +00:00
|
|
|
|
/// If we can't parse FROM then return
|
|
|
|
|
if (!ParserKeyword("FROM").ignore(test_pos, test_expected))
|
2023-04-05 18:08:56 +00:00
|
|
|
|
return true;
|
|
|
|
|
|
2023-08-29 07:20:23 +00:00
|
|
|
|
// If there is a comma after 'from' then the first one was a name of a column
|
|
|
|
|
if (test_pos->type == TokenType::Comma)
|
|
|
|
|
return true;
|
|
|
|
|
|
2023-04-09 12:52:23 +00:00
|
|
|
|
/// If we parse a second FROM then the first one was a name of a column
|
|
|
|
|
if (ParserKeyword("FROM").ignore(test_pos, test_expected))
|
2023-04-05 18:08:56 +00:00
|
|
|
|
return true;
|
|
|
|
|
|
2023-04-09 12:52:23 +00:00
|
|
|
|
/// If we parse an explicit alias to FROM, then it was a name of a column
|
|
|
|
|
if (ParserAlias(false).ignore(test_pos, test_expected))
|
2023-04-05 18:08:56 +00:00
|
|
|
|
return true;
|
|
|
|
|
|
2023-04-09 12:52:23 +00:00
|
|
|
|
/// If we parse an operator after FROM then it was a name of a column
|
|
|
|
|
auto cur_op = ParserExpressionImpl::operators_table.begin();
|
|
|
|
|
for (; cur_op != ParserExpressionImpl::operators_table.end(); ++cur_op)
|
|
|
|
|
{
|
|
|
|
|
if (parseOperator(test_pos, cur_op->first, test_expected))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cur_op != ParserExpressionImpl::operators_table.end())
|
2023-04-05 18:08:56 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
++pos;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-10 04:58:59 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2023-04-05 18:08:56 +00:00
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
bool allow_trailing_commas;
|
2022-07-14 12:11:14 +00:00
|
|
|
|
};
|
|
|
|
|
|
2022-08-04 09:32:14 +00:00
|
|
|
|
/// Basic layer for a function with certain separator and end tokens:
|
|
|
|
|
/// 1. If we parse a separator we should merge current operands and operators
|
2022-08-10 04:58:59 +00:00
|
|
|
|
/// into one element and push in to 'elements' vector.
|
2022-08-04 09:32:14 +00:00
|
|
|
|
/// 2. If we parse an ending token, we should merge everything as in (1) and
|
|
|
|
|
/// also set 'finished' flag.
|
2022-07-14 12:11:14 +00:00
|
|
|
|
template <TokenType separator, TokenType end>
|
2022-10-25 09:24:42 +00:00
|
|
|
|
class LayerWithSeparator : public Layer
|
2022-07-14 12:11:14 +00:00
|
|
|
|
{
|
|
|
|
|
public:
|
2022-10-25 09:24:42 +00:00
|
|
|
|
explicit LayerWithSeparator(bool allow_alias_ = true, bool allow_alias_without_as_keyword_ = false) :
|
2022-10-21 00:16:24 +00:00
|
|
|
|
Layer(allow_alias_, allow_alias_without_as_keyword_) {}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
|
{
|
|
|
|
|
if (ParserToken(separator).ignore(pos, expected))
|
2022-04-08 03:30:49 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
action = Action::OPERAND;
|
|
|
|
|
return mergeElement();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ParserToken(end).ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
action = Action::OPERATOR;
|
|
|
|
|
|
2022-09-15 00:48:14 +00:00
|
|
|
|
if (!isCurrentElementEmpty() || !elements.empty())
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!mergeElement())
|
2022-04-08 03:30:49 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
finished = true;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2022-10-21 00:16:24 +00:00
|
|
|
|
/// Layer for regular and aggregate functions without syntax sugar
|
2022-10-19 23:38:44 +00:00
|
|
|
|
class FunctionLayer : public Layer
|
2022-04-08 03:30:49 +00:00
|
|
|
|
{
|
|
|
|
|
public:
|
2022-11-16 11:27:08 +00:00
|
|
|
|
explicit FunctionLayer(String function_name_, bool allow_function_parameters_ = true, bool is_compound_name_ = false)
|
|
|
|
|
: function_name(function_name_), allow_function_parameters(allow_function_parameters_), is_compound_name(is_compound_name_){}
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
|
{
|
2022-08-04 09:32:14 +00:00
|
|
|
|
/// | 0 | 1 | 2 |
|
|
|
|
|
/// f(ALL ...)(ALL ...) FILTER ...
|
|
|
|
|
///
|
|
|
|
|
/// 0. Parse ALL and DISTINCT qualifiers (-> 1)
|
|
|
|
|
/// 1. Parse all the arguments and ending token (-> 2), possibly with parameters list (-> 1)
|
|
|
|
|
/// 2. Create function, possibly parse FILTER and OVER window definitions (finished)
|
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
|
if (state == 0)
|
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
state = 1;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
auto pos_after_bracket = pos;
|
|
|
|
|
auto old_expected = expected;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
ParserKeyword all("ALL");
|
|
|
|
|
ParserKeyword distinct("DISTINCT");
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (all.ignore(pos, expected))
|
|
|
|
|
has_all = true;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (distinct.ignore(pos, expected))
|
|
|
|
|
has_distinct = true;
|
|
|
|
|
|
|
|
|
|
if (!has_all && all.ignore(pos, expected))
|
|
|
|
|
has_all = true;
|
|
|
|
|
|
|
|
|
|
if (has_all && has_distinct)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (has_all || has_distinct)
|
|
|
|
|
{
|
|
|
|
|
/// case f(ALL), f(ALL, x), f(DISTINCT), f(DISTINCT, x), ALL and DISTINCT should be treat as identifier
|
|
|
|
|
if (pos->type == TokenType::Comma || pos->type == TokenType::ClosingRoundBracket)
|
|
|
|
|
{
|
|
|
|
|
pos = pos_after_bracket;
|
|
|
|
|
expected = old_expected;
|
|
|
|
|
has_all = false;
|
|
|
|
|
has_distinct = false;
|
|
|
|
|
}
|
2022-04-08 03:30:49 +00:00
|
|
|
|
}
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
|
|
|
|
contents_begin = pos->begin;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-26 16:50:48 +00:00
|
|
|
|
if (state == 1)
|
|
|
|
|
{
|
|
|
|
|
if (ParserToken(TokenType::Comma).ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
action = Action::OPERAND;
|
2022-07-14 12:11:14 +00:00
|
|
|
|
return mergeElement();
|
2022-05-26 16:50:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
|
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
action = Action::OPERATOR;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-09-15 00:48:14 +00:00
|
|
|
|
if (!isCurrentElementEmpty() || !elements.empty())
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
contents_end = pos->begin;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
/** Check for a common error case - often due to the complexity of quoting command-line arguments,
|
|
|
|
|
* an expression of the form toDate(2014-01-01) appears in the query instead of toDate('2014-01-01').
|
|
|
|
|
* If you do not report that the first option is an error, then the argument will be interpreted as 2014 - 01 - 01 - some number,
|
2022-08-10 04:58:59 +00:00
|
|
|
|
* and the query silently returns an unexpected elements.
|
2022-07-14 12:11:14 +00:00
|
|
|
|
*/
|
|
|
|
|
if (function_name == "toDate"
|
|
|
|
|
&& contents_end - contents_begin == strlen("2014-01-01")
|
|
|
|
|
&& contents_begin[0] >= '2' && contents_begin[0] <= '3'
|
|
|
|
|
&& contents_begin[1] >= '0' && contents_begin[1] <= '9'
|
|
|
|
|
&& contents_begin[2] >= '0' && contents_begin[2] <= '9'
|
|
|
|
|
&& contents_begin[3] >= '0' && contents_begin[3] <= '9'
|
|
|
|
|
&& contents_begin[4] == '-'
|
|
|
|
|
&& contents_begin[5] >= '0' && contents_begin[5] <= '9'
|
|
|
|
|
&& contents_begin[6] >= '0' && contents_begin[6] <= '9'
|
|
|
|
|
&& contents_begin[7] == '-'
|
|
|
|
|
&& contents_begin[8] >= '0' && contents_begin[8] <= '9'
|
|
|
|
|
&& contents_begin[9] >= '0' && contents_begin[9] <= '9')
|
|
|
|
|
{
|
|
|
|
|
std::string contents_str(contents_begin, contents_end - contents_begin);
|
2023-01-23 21:13:58 +00:00
|
|
|
|
throw Exception(ErrorCodes::SYNTAX_ERROR, "Argument of function toDate is unquoted: "
|
|
|
|
|
"toDate({}), must be: toDate('{}')" , contents_str, contents_str);
|
2022-07-14 12:11:14 +00:00
|
|
|
|
}
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-11-18 01:16:28 +00:00
|
|
|
|
if (allow_function_parameters && !parameters && ParserToken(TokenType::OpeningRoundBracket).ignore(pos, expected))
|
2022-07-14 12:11:14 +00:00
|
|
|
|
{
|
|
|
|
|
parameters = std::make_shared<ASTExpressionList>();
|
2022-08-10 04:58:59 +00:00
|
|
|
|
std::swap(parameters->children, elements);
|
2022-07-14 12:11:14 +00:00
|
|
|
|
action = Action::OPERAND;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
/// Parametric aggregate functions cannot have DISTINCT in parameters list.
|
|
|
|
|
if (has_distinct)
|
|
|
|
|
return false;
|
2022-04-08 15:36:36 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
auto pos_after_bracket = pos;
|
|
|
|
|
auto old_expected = expected;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
ParserKeyword all("ALL");
|
|
|
|
|
ParserKeyword distinct("DISTINCT");
|
2022-04-08 15:36:36 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (all.ignore(pos, expected))
|
|
|
|
|
has_all = true;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (distinct.ignore(pos, expected))
|
|
|
|
|
has_distinct = true;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!has_all && all.ignore(pos, expected))
|
|
|
|
|
has_all = true;
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (has_all && has_distinct)
|
|
|
|
|
return false;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (has_all || has_distinct)
|
|
|
|
|
{
|
|
|
|
|
/// case f(ALL), f(ALL, x), f(DISTINCT), f(DISTINCT, x), ALL and DISTINCT should be treat as identifier
|
|
|
|
|
if (pos->type == TokenType::Comma || pos->type == TokenType::ClosingRoundBracket)
|
|
|
|
|
{
|
|
|
|
|
pos = pos_after_bracket;
|
|
|
|
|
expected = old_expected;
|
|
|
|
|
has_distinct = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-04-08 03:30:49 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
state = 2;
|
2022-07-14 12:11:14 +00:00
|
|
|
|
}
|
2022-04-08 03:30:49 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (state == 2)
|
2022-04-08 03:30:49 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (has_distinct)
|
|
|
|
|
function_name += "Distinct";
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-08-10 04:58:59 +00:00
|
|
|
|
auto function_node = makeASTFunction(function_name, std::move(elements));
|
2022-11-16 11:27:08 +00:00
|
|
|
|
function_node->is_compound_name = is_compound_name;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (parameters)
|
|
|
|
|
{
|
2022-10-19 23:38:44 +00:00
|
|
|
|
function_node->parameters = std::move(parameters);
|
2022-07-14 12:11:14 +00:00
|
|
|
|
function_node->children.push_back(function_node->parameters);
|
2022-04-08 03:30:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
ParserKeyword filter("FILTER");
|
|
|
|
|
ParserKeyword over("OVER");
|
2023-02-21 02:41:58 +00:00
|
|
|
|
ParserKeyword respect_nulls("RESPECT NULLS");
|
|
|
|
|
ParserKeyword ignore_nulls("IGNORE NULLS");
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
|
|
|
|
if (filter.ignore(pos, expected))
|
2022-04-08 03:30:49 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
// We are slightly breaking the parser interface by parsing the window
|
|
|
|
|
// definition into an existing ASTFunction. Normally it would take a
|
|
|
|
|
// reference to ASTPtr and assign it the new node. We only have a pointer
|
|
|
|
|
// of a different type, hence this workaround with a temporary pointer.
|
|
|
|
|
ASTPtr function_node_as_iast = function_node;
|
|
|
|
|
|
|
|
|
|
// Recursion
|
|
|
|
|
ParserFilterClause filter_parser;
|
|
|
|
|
if (!filter_parser.parse(pos, function_node_as_iast, expected))
|
2022-04-08 03:30:49 +00:00
|
|
|
|
return false;
|
2022-07-14 12:11:14 +00:00
|
|
|
|
}
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2023-04-19 11:22:36 +00:00
|
|
|
|
NullsAction nulls_action = NullsAction::EMPTY;
|
2023-02-21 02:41:58 +00:00
|
|
|
|
if (respect_nulls.ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
nulls_action = NullsAction::RESPECT_NULLS;
|
|
|
|
|
}
|
|
|
|
|
if (ignore_nulls.ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
nulls_action = NullsAction::IGNORE_NULLS;
|
|
|
|
|
}
|
2023-11-22 16:17:28 +00:00
|
|
|
|
|
|
|
|
|
if (nulls_action != NullsAction::EMPTY)
|
2023-11-22 12:08:45 +00:00
|
|
|
|
function_node->name = transformFunctionNameForRespectNulls(function_node->name, nulls_action);
|
2023-02-21 02:41:58 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (over.ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
function_node->is_window_function = true;
|
2022-11-11 15:26:04 +00:00
|
|
|
|
function_node->kind = ASTFunction::Kind::WINDOW_FUNCTION;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
ASTPtr function_node_as_iast = function_node;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
// Recursion
|
|
|
|
|
ParserWindowReference window_reference;
|
|
|
|
|
if (!window_reference.parse(pos, function_node_as_iast, expected))
|
|
|
|
|
return false;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
}
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
2022-10-19 23:38:44 +00:00
|
|
|
|
elements = {std::move(function_node)};
|
2022-07-14 12:11:14 +00:00
|
|
|
|
finished = true;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
2022-04-08 03:30:49 +00:00
|
|
|
|
private:
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool has_all = false;
|
|
|
|
|
bool has_distinct = false;
|
|
|
|
|
|
|
|
|
|
const char * contents_begin;
|
|
|
|
|
const char * contents_end;
|
2022-04-08 03:30:49 +00:00
|
|
|
|
|
2022-06-29 21:51:58 +00:00
|
|
|
|
String function_name;
|
2022-07-14 12:11:14 +00:00
|
|
|
|
ASTPtr parameters;
|
2022-09-12 15:26:45 +00:00
|
|
|
|
|
|
|
|
|
bool allow_function_parameters;
|
2022-11-16 11:27:08 +00:00
|
|
|
|
bool is_compound_name;
|
2023-02-21 02:41:58 +00:00
|
|
|
|
|
|
|
|
|
enum NullsAction
|
|
|
|
|
{
|
2023-04-19 11:22:36 +00:00
|
|
|
|
EMPTY = 0,
|
2023-02-21 02:41:58 +00:00
|
|
|
|
RESPECT_NULLS = 1,
|
|
|
|
|
IGNORE_NULLS = 2,
|
|
|
|
|
};
|
2023-11-22 12:08:45 +00:00
|
|
|
|
static String transformFunctionNameForRespectNulls(const String & original_function_name, NullsAction nulls_action)
|
2023-02-21 02:41:58 +00:00
|
|
|
|
{
|
2023-11-22 16:17:28 +00:00
|
|
|
|
const auto & factory = AggregateFunctionFactory::instance();
|
|
|
|
|
auto names = factory.tryGetNameAndOriginalNameWithoutCombinators(original_function_name);
|
|
|
|
|
if (!names)
|
2023-04-19 11:22:36 +00:00
|
|
|
|
{
|
2023-11-22 16:17:28 +00:00
|
|
|
|
auto hints = factory.getHints(original_function_name);
|
|
|
|
|
if (!hints.empty())
|
|
|
|
|
throw Exception(
|
|
|
|
|
ErrorCodes::UNKNOWN_AGGREGATE_FUNCTION,
|
|
|
|
|
"Unknown aggregate function {}. Maybe you meant: {}",
|
|
|
|
|
original_function_name,
|
|
|
|
|
toString(hints));
|
2023-04-19 11:22:36 +00:00
|
|
|
|
else
|
2023-11-22 16:17:28 +00:00
|
|
|
|
throw Exception(ErrorCodes::UNKNOWN_AGGREGATE_FUNCTION, "Unknown aggregate function {}", original_function_name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String name_without_combinators;
|
|
|
|
|
String unaliased_name;
|
|
|
|
|
std::tie(name_without_combinators, unaliased_name) = *names;
|
|
|
|
|
|
|
|
|
|
if (nulls_action == NullsAction::RESPECT_NULLS)
|
|
|
|
|
{
|
|
|
|
|
static const std::unordered_set<String> functions_that_support_respect_nulls = {"any", "anyLast"};
|
|
|
|
|
if (!functions_that_support_respect_nulls.contains(unaliased_name))
|
|
|
|
|
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Function {} does not support RESPECT NULLS", name_without_combinators);
|
|
|
|
|
|
|
|
|
|
return unaliased_name + "_respect_nulls"
|
|
|
|
|
+ original_function_name.substr(name_without_combinators.size(), original_function_name.size());
|
|
|
|
|
}
|
|
|
|
|
else if (nulls_action == NullsAction::IGNORE_NULLS)
|
|
|
|
|
{
|
|
|
|
|
if (name_without_combinators.ends_with("_respect_nulls"))
|
|
|
|
|
{
|
|
|
|
|
return name_without_combinators.substr(0, name_without_combinators.size() - String{"_respect_nulls"}.size())
|
|
|
|
|
+ original_function_name.substr(name_without_combinators.size(), original_function_name.size());
|
|
|
|
|
}
|
2023-04-19 11:22:36 +00:00
|
|
|
|
}
|
2023-11-22 16:17:28 +00:00
|
|
|
|
|
|
|
|
|
return original_function_name;
|
2023-02-21 02:41:58 +00:00
|
|
|
|
}
|
2022-02-24 13:54:30 +00:00
|
|
|
|
};
|
|
|
|
|
|
2022-08-04 09:32:14 +00:00
|
|
|
|
/// Layer for priority brackets and tuple function
|
2022-07-14 12:11:14 +00:00
|
|
|
|
class RoundBracketsLayer : public Layer
|
2022-04-08 15:36:36 +00:00
|
|
|
|
{
|
|
|
|
|
public:
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
2022-06-16 01:53:27 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (ParserToken(TokenType::Comma).ignore(pos, expected))
|
2022-06-16 01:53:27 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
action = Action::OPERAND;
|
|
|
|
|
is_tuple = true;
|
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
2022-06-16 01:53:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
action = Action::OPERATOR;
|
|
|
|
|
|
2022-09-15 00:48:14 +00:00
|
|
|
|
if (!isCurrentElementEmpty())
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
|
|
|
|
|
2022-08-10 04:58:59 +00:00
|
|
|
|
if (!is_tuple && elements.size() == 1)
|
2022-11-07 13:44:05 +00:00
|
|
|
|
{
|
|
|
|
|
// Special case for (('a', 'b')) = tuple(('a', 'b'))
|
2022-08-10 04:58:59 +00:00
|
|
|
|
if (auto * literal = elements[0]->as<ASTLiteral>())
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (literal->value.getType() == Field::Types::Tuple)
|
|
|
|
|
is_tuple = true;
|
|
|
|
|
|
2022-11-07 13:44:05 +00:00
|
|
|
|
// Special case for f(x, (y) -> z) = f(x, tuple(y) -> z)
|
2022-12-27 14:49:41 +00:00
|
|
|
|
if (pos->type == TokenType::Arrow)
|
2022-11-07 13:44:05 +00:00
|
|
|
|
is_tuple = true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
finished = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-10-27 10:03:03 +00:00
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
bool getResultImpl(ASTPtr & node) override
|
|
|
|
|
{
|
|
|
|
|
// Round brackets can mean priority operator as well as function tuple()
|
|
|
|
|
if (!is_tuple && elements.size() == 1)
|
|
|
|
|
node = std::move(elements[0]);
|
|
|
|
|
else
|
|
|
|
|
node = makeASTFunction("tuple", std::move(elements));
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
private:
|
|
|
|
|
bool is_tuple = false;
|
|
|
|
|
};
|
|
|
|
|
|
2022-08-04 09:32:14 +00:00
|
|
|
|
/// Layer for array square brackets operator
|
2022-10-25 09:24:42 +00:00
|
|
|
|
class ArrayLayer : public LayerWithSeparator<TokenType::Comma, TokenType::ClosingSquareBracket>
|
2022-07-14 12:11:14 +00:00
|
|
|
|
{
|
|
|
|
|
public:
|
2022-10-27 10:03:03 +00:00
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
2022-07-14 12:11:14 +00:00
|
|
|
|
{
|
2022-10-27 10:03:03 +00:00
|
|
|
|
return LayerWithSeparator::parse(pos, expected, action);
|
2022-06-16 01:53:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-10-27 10:03:03 +00:00
|
|
|
|
protected:
|
|
|
|
|
bool getResultImpl(ASTPtr & node) override
|
2022-07-14 12:11:14 +00:00
|
|
|
|
{
|
2022-10-27 10:03:03 +00:00
|
|
|
|
node = makeASTFunction("array", std::move(elements));
|
|
|
|
|
return true;
|
2022-07-14 12:11:14 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2022-08-04 09:32:14 +00:00
|
|
|
|
/// Layer for arrayElement square brackets operator
|
|
|
|
|
/// This layer does not create a function, it is only needed to parse closing token
|
|
|
|
|
/// and return only one element.
|
2022-10-25 09:24:42 +00:00
|
|
|
|
class ArrayElementLayer : public LayerWithSeparator<TokenType::Comma, TokenType::ClosingSquareBracket>
|
2022-07-14 12:11:14 +00:00
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
|
{
|
2022-10-25 09:24:42 +00:00
|
|
|
|
return LayerWithSeparator::parse(pos, expected, action);
|
2022-07-14 12:11:14 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
class CastLayer : public Layer
|
|
|
|
|
{
|
|
|
|
|
public:
|
2022-10-24 19:52:51 +00:00
|
|
|
|
CastLayer() : Layer(/*allow_alias*/ true, /*allow_alias_without_as_keyword*/ true) {}
|
2022-10-21 00:16:24 +00:00
|
|
|
|
|
2022-04-08 15:36:36 +00:00
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
|
{
|
2022-08-04 09:32:14 +00:00
|
|
|
|
/// CAST(x [AS alias1], T [AS alias2]) or CAST(x [AS alias1] AS T)
|
|
|
|
|
///
|
|
|
|
|
/// 0. Parse all the cases (-> 1)
|
|
|
|
|
/// 1. Parse closing token (finished)
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
ParserKeyword as_keyword_parser("AS");
|
|
|
|
|
ASTPtr alias;
|
|
|
|
|
|
|
|
|
|
/// expr AS type
|
2022-04-08 15:36:36 +00:00
|
|
|
|
if (state == 0)
|
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
ASTPtr type_node;
|
2022-04-08 15:36:36 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (as_keyword_parser.ignore(pos, expected))
|
2022-04-08 15:36:36 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
auto old_pos = pos;
|
2022-04-08 15:36:36 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (ParserIdentifier().parse(pos, alias, expected) &&
|
|
|
|
|
as_keyword_parser.ignore(pos, expected) &&
|
|
|
|
|
ParserDataType().parse(pos, type_node, expected) &&
|
|
|
|
|
ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
if (!insertAlias(alias))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
|
|
|
|
|
2022-08-10 04:58:59 +00:00
|
|
|
|
elements = {createFunctionCast(elements[0], type_node)};
|
2022-07-14 12:11:14 +00:00
|
|
|
|
finished = true;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pos = old_pos;
|
|
|
|
|
|
|
|
|
|
if (ParserIdentifier().parse(pos, alias, expected) &&
|
|
|
|
|
ParserToken(TokenType::Comma).ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
action = Action::OPERAND;
|
|
|
|
|
if (!insertAlias(alias))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
state = 1;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pos = old_pos;
|
|
|
|
|
|
|
|
|
|
if (ParserDataType().parse(pos, type_node, expected) &&
|
|
|
|
|
ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
|
|
|
|
|
2022-08-10 04:58:59 +00:00
|
|
|
|
elements = {createFunctionCast(elements[0], type_node)};
|
2022-07-14 12:11:14 +00:00
|
|
|
|
finished = true;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-04-08 15:36:36 +00:00
|
|
|
|
|
|
|
|
|
if (ParserToken(TokenType::Comma).ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
action = Action::OPERAND;
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!mergeElement())
|
2022-04-08 15:36:36 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
state = 1;
|
|
|
|
|
return true;
|
2022-04-08 15:36:36 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (state == 1)
|
2022-04-08 15:36:36 +00:00
|
|
|
|
{
|
|
|
|
|
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!mergeElement())
|
2022-04-08 15:36:36 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
2022-11-05 01:10:51 +00:00
|
|
|
|
if (elements.size() != 2)
|
|
|
|
|
return false;
|
|
|
|
|
|
2022-08-10 04:58:59 +00:00
|
|
|
|
elements = {makeASTFunction("CAST", elements[0], elements[1])};
|
2022-07-14 12:11:14 +00:00
|
|
|
|
finished = true;
|
|
|
|
|
return true;
|
2022-04-08 15:36:36 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
2022-04-08 15:36:36 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2022-10-25 09:24:42 +00:00
|
|
|
|
class ExtractLayer : public LayerWithSeparator<TokenType::Comma, TokenType::ClosingRoundBracket>
|
2022-04-08 15:36:36 +00:00
|
|
|
|
{
|
|
|
|
|
public:
|
2022-10-25 09:24:42 +00:00
|
|
|
|
ExtractLayer() : LayerWithSeparator(/*allow_alias*/ true, /*allow_alias_without_as_keyword*/ true) {}
|
2022-10-21 00:16:24 +00:00
|
|
|
|
|
2022-06-16 01:53:27 +00:00
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
|
{
|
2022-08-04 09:32:14 +00:00
|
|
|
|
/// extract(haystack, pattern) or EXTRACT(DAY FROM Date)
|
|
|
|
|
///
|
|
|
|
|
/// 0. If we parse interval_kind and 'FROM' keyword (-> 2), otherwise (-> 1)
|
|
|
|
|
/// 1. Basic parser
|
|
|
|
|
/// 2. Parse closing bracket (finished)
|
|
|
|
|
|
2022-06-16 01:53:27 +00:00
|
|
|
|
if (state == 0)
|
2022-04-08 15:36:36 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
IParser::Pos begin = pos;
|
|
|
|
|
ParserKeyword s_from("FROM");
|
|
|
|
|
|
|
|
|
|
if (parseIntervalKind(pos, expected, interval_kind) && s_from.ignore(pos, expected))
|
2022-04-08 15:36:36 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
state = 2;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
state = 1;
|
|
|
|
|
pos = begin;
|
2022-04-08 15:36:36 +00:00
|
|
|
|
}
|
2022-06-16 01:53:27 +00:00
|
|
|
|
}
|
2022-04-08 15:36:36 +00:00
|
|
|
|
|
2022-06-16 01:53:27 +00:00
|
|
|
|
if (state == 1)
|
|
|
|
|
{
|
2022-10-25 09:24:42 +00:00
|
|
|
|
return LayerWithSeparator::parse(pos, expected, action);
|
2022-07-14 12:11:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (state == 2)
|
|
|
|
|
{
|
|
|
|
|
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
finished = true;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-04-08 15:36:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-27 10:03:03 +00:00
|
|
|
|
protected:
|
|
|
|
|
bool getResultImpl(ASTPtr & node) override
|
|
|
|
|
{
|
|
|
|
|
if (state == 2)
|
|
|
|
|
{
|
|
|
|
|
if (elements.empty())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
node = makeASTFunction(interval_kind.toNameOfFunctionExtractTimePart(), elements[0]);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
node = makeASTFunction("extract", std::move(elements));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2022-04-08 15:36:36 +00:00
|
|
|
|
private:
|
|
|
|
|
IntervalKind interval_kind;
|
|
|
|
|
};
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
class SubstringLayer : public Layer
|
2022-04-08 15:36:36 +00:00
|
|
|
|
{
|
|
|
|
|
public:
|
2022-10-24 19:52:51 +00:00
|
|
|
|
SubstringLayer() : Layer(/*allow_alias*/ true, /*allow_alias_without_as_keyword*/ true) {}
|
2022-10-21 00:16:24 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
2022-04-08 15:36:36 +00:00
|
|
|
|
{
|
2022-08-04 09:32:14 +00:00
|
|
|
|
/// Either SUBSTRING(expr FROM start [FOR length]) or SUBSTRING(expr, start, length)
|
|
|
|
|
///
|
|
|
|
|
/// 0: Parse first separator: FROM or comma (-> 1)
|
|
|
|
|
/// 1: Parse second separator: FOR or comma (-> 2)
|
|
|
|
|
/// 1 or 2: Parse closing bracket (finished)
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
2022-04-08 15:36:36 +00:00
|
|
|
|
if (state == 0)
|
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (ParserToken(TokenType::Comma).ignore(pos, expected) ||
|
|
|
|
|
ParserKeyword("FROM").ignore(pos, expected))
|
2022-04-08 15:36:36 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
action = Action::OPERAND;
|
2022-04-08 15:36:36 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
2022-04-08 15:36:36 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
state = 1;
|
2022-04-08 15:36:36 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (state == 1)
|
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (ParserToken(TokenType::Comma).ignore(pos, expected) ||
|
|
|
|
|
ParserKeyword("FOR").ignore(pos, expected))
|
2022-04-08 15:36:36 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
action = Action::OPERAND;
|
|
|
|
|
|
|
|
|
|
if (!mergeElement())
|
2022-04-08 15:36:36 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
state = 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (state == 1 || state == 2)
|
|
|
|
|
{
|
|
|
|
|
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
finished = true;
|
2022-04-08 15:36:36 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-10-27 10:03:03 +00:00
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
bool getResultImpl(ASTPtr & node) override
|
|
|
|
|
{
|
|
|
|
|
node = makeASTFunction("substring", std::move(elements));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-04-08 15:36:36 +00:00
|
|
|
|
};
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
class PositionLayer : public Layer
|
2022-04-12 15:03:10 +00:00
|
|
|
|
{
|
|
|
|
|
public:
|
2022-10-24 19:52:51 +00:00
|
|
|
|
PositionLayer() : Layer(/*allow_alias*/ true, /*allow_alias_without_as_keyword*/ true) {}
|
2022-10-21 00:16:24 +00:00
|
|
|
|
|
2022-04-12 15:03:10 +00:00
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
|
{
|
2022-08-04 09:32:14 +00:00
|
|
|
|
/// position(haystack, needle[, start_pos]) or position(needle IN haystack)
|
|
|
|
|
///
|
|
|
|
|
/// 0: Parse separator: comma (-> 1) or IN (-> 2)
|
|
|
|
|
/// 1: Parse second separator: comma
|
|
|
|
|
/// 1 or 2: Parse closing bracket (finished)
|
|
|
|
|
|
2022-04-12 15:03:10 +00:00
|
|
|
|
if (state == 0)
|
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (ParserToken(TokenType::Comma).ignore(pos, expected))
|
2022-04-12 15:03:10 +00:00
|
|
|
|
{
|
|
|
|
|
action = Action::OPERAND;
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
|
|
|
|
if (!mergeElement())
|
2022-04-12 15:03:10 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
state = 1;
|
2022-04-12 15:03:10 +00:00
|
|
|
|
}
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (ParserKeyword("IN").ignore(pos, expected))
|
2022-04-12 15:03:10 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
action = Action::OPERAND;
|
2022-04-12 15:03:10 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
2022-04-12 15:03:10 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
state = 2;
|
2022-04-12 15:03:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (state == 1)
|
2022-04-12 15:03:10 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (ParserToken(TokenType::Comma).ignore(pos, expected))
|
2022-04-12 15:03:10 +00:00
|
|
|
|
{
|
|
|
|
|
action = Action::OPERAND;
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
2022-04-12 15:03:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (state == 1 || state == 2)
|
2022-04-12 15:03:10 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
2022-04-12 15:03:10 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!mergeElement())
|
2022-04-12 15:03:10 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
finished = true;
|
2022-04-12 15:03:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-10-27 10:03:03 +00:00
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
bool getResultImpl(ASTPtr & node) override
|
|
|
|
|
{
|
2022-11-05 01:10:51 +00:00
|
|
|
|
if (state == 2 && elements.size() == 2)
|
2022-10-27 10:03:03 +00:00
|
|
|
|
std::swap(elements[1], elements[0]);
|
|
|
|
|
|
|
|
|
|
node = makeASTFunction("position", std::move(elements));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-04-12 15:03:10 +00:00
|
|
|
|
};
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
class ExistsLayer : public Layer
|
2022-02-24 13:54:30 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
public:
|
2022-10-24 19:52:51 +00:00
|
|
|
|
ExistsLayer() : Layer(/*allow_alias*/ true, /*allow_alias_without_as_keyword*/ true) {}
|
2022-10-21 00:16:24 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & /*action*/) override
|
|
|
|
|
{
|
|
|
|
|
ASTPtr node;
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
// Recursion
|
|
|
|
|
if (!ParserSelectWithUnionQuery().parse(pos, node, expected))
|
|
|
|
|
return false;
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
|
return false;
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
auto subquery = std::make_shared<ASTSubquery>();
|
2022-10-14 13:24:47 +00:00
|
|
|
|
subquery->children.push_back(std::move(node));
|
2022-08-10 04:58:59 +00:00
|
|
|
|
elements = {makeASTFunction("exists", subquery)};
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
|
|
|
|
finished = true;
|
|
|
|
|
|
|
|
|
|
return true;
|
2022-02-24 13:54:30 +00:00
|
|
|
|
}
|
2022-07-14 12:11:14 +00:00
|
|
|
|
};
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
class TrimLayer : public Layer
|
2022-02-24 13:54:30 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
public:
|
2022-10-21 00:16:24 +00:00
|
|
|
|
TrimLayer(bool trim_left_, bool trim_right_)
|
2022-10-24 19:52:51 +00:00
|
|
|
|
: Layer(/*allow_alias*/ true, /*allow_alias_without_as_keyword*/ true), trim_left(trim_left_), trim_right(trim_right_) {}
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
|
{
|
|
|
|
|
/// Handles all possible TRIM/LTRIM/RTRIM call variants
|
2022-08-04 09:32:14 +00:00
|
|
|
|
///
|
|
|
|
|
/// 0: If flags 'trim_left' and 'trim_right' are set (-> 2).
|
|
|
|
|
/// If not, try to parse 'BOTH', 'LEADING', 'TRAILING' keywords,
|
|
|
|
|
/// then if char_override (-> 1), else (-> 2)
|
|
|
|
|
/// 1. Parse 'FROM' keyword (-> 2)
|
|
|
|
|
/// 2. Parse closing token, choose name, add arguments (finished)
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (state == 0)
|
|
|
|
|
{
|
|
|
|
|
if (!trim_left && !trim_right)
|
|
|
|
|
{
|
|
|
|
|
if (ParserKeyword("BOTH").ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
trim_left = true;
|
|
|
|
|
trim_right = true;
|
|
|
|
|
char_override = true;
|
|
|
|
|
}
|
|
|
|
|
else if (ParserKeyword("LEADING").ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
trim_left = true;
|
|
|
|
|
char_override = true;
|
|
|
|
|
}
|
|
|
|
|
else if (ParserKeyword("TRAILING").ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
trim_right = true;
|
|
|
|
|
char_override = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
trim_left = true;
|
|
|
|
|
trim_right = true;
|
|
|
|
|
}
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (char_override)
|
|
|
|
|
state = 1;
|
|
|
|
|
else
|
|
|
|
|
state = 2;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
state = 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (state == 1)
|
|
|
|
|
{
|
|
|
|
|
if (ParserKeyword("FROM").ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
action = Action::OPERAND;
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-08-10 04:58:59 +00:00
|
|
|
|
to_remove = makeASTFunction("regexpQuoteMeta", elements[0]);
|
|
|
|
|
elements.clear();
|
2022-07-14 12:11:14 +00:00
|
|
|
|
state = 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (state == 2)
|
|
|
|
|
{
|
|
|
|
|
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
ASTPtr pattern_node;
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (char_override)
|
|
|
|
|
{
|
|
|
|
|
auto pattern_func_node = std::make_shared<ASTFunction>();
|
|
|
|
|
auto pattern_list_args = std::make_shared<ASTExpressionList>();
|
|
|
|
|
if (trim_left && trim_right)
|
|
|
|
|
{
|
|
|
|
|
pattern_list_args->children = {
|
|
|
|
|
std::make_shared<ASTLiteral>("^["),
|
|
|
|
|
to_remove,
|
|
|
|
|
std::make_shared<ASTLiteral>("]+|["),
|
|
|
|
|
to_remove,
|
|
|
|
|
std::make_shared<ASTLiteral>("]+$")
|
|
|
|
|
};
|
|
|
|
|
function_name = "replaceRegexpAll";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (trim_left)
|
|
|
|
|
{
|
|
|
|
|
pattern_list_args->children = {
|
|
|
|
|
std::make_shared<ASTLiteral>("^["),
|
|
|
|
|
to_remove,
|
|
|
|
|
std::make_shared<ASTLiteral>("]+")
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/// trim_right == false not possible
|
|
|
|
|
pattern_list_args->children = {
|
|
|
|
|
std::make_shared<ASTLiteral>("["),
|
|
|
|
|
to_remove,
|
|
|
|
|
std::make_shared<ASTLiteral>("]+$")
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
function_name = "replaceRegexpOne";
|
|
|
|
|
}
|
2022-06-29 21:51:58 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
pattern_func_node->name = "concat";
|
|
|
|
|
pattern_func_node->arguments = std::move(pattern_list_args);
|
|
|
|
|
pattern_func_node->children.push_back(pattern_func_node->arguments);
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
pattern_node = std::move(pattern_func_node);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (trim_left && trim_right)
|
|
|
|
|
{
|
|
|
|
|
function_name = "trimBoth";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (trim_left)
|
|
|
|
|
function_name = "trimLeft";
|
|
|
|
|
else
|
|
|
|
|
function_name = "trimRight";
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-06-02 22:07:14 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (char_override)
|
|
|
|
|
{
|
2022-08-10 04:58:59 +00:00
|
|
|
|
elements.push_back(pattern_node);
|
|
|
|
|
elements.push_back(std::make_shared<ASTLiteral>(""));
|
2022-07-14 12:11:14 +00:00
|
|
|
|
}
|
2022-05-04 18:54:04 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
finished = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-10-27 10:03:03 +00:00
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
bool getResultImpl(ASTPtr & node) override
|
|
|
|
|
{
|
|
|
|
|
node = makeASTFunction(function_name, std::move(elements));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
private:
|
|
|
|
|
bool trim_left;
|
|
|
|
|
bool trim_right;
|
|
|
|
|
bool char_override = false;
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
ASTPtr to_remove;
|
|
|
|
|
String function_name;
|
|
|
|
|
};
|
2022-04-08 15:36:36 +00:00
|
|
|
|
|
2022-10-25 09:24:42 +00:00
|
|
|
|
class DateAddLayer : public LayerWithSeparator<TokenType::Comma, TokenType::ClosingRoundBracket>
|
2022-07-14 12:11:14 +00:00
|
|
|
|
{
|
|
|
|
|
public:
|
2022-10-21 00:16:24 +00:00
|
|
|
|
explicit DateAddLayer(const char * function_name_)
|
2022-10-25 09:24:42 +00:00
|
|
|
|
: LayerWithSeparator(/*allow_alias*/ true, /*allow_alias_without_as_keyword*/ true), function_name(function_name_) {}
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
|
{
|
2022-08-04 09:32:14 +00:00
|
|
|
|
/// DATEADD(YEAR, 1, date) or DATEADD(INTERVAL 1 YEAR, date);
|
|
|
|
|
///
|
|
|
|
|
/// 0. Try to parse interval_kind (-> 1)
|
|
|
|
|
/// 1. Basic parser
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (state == 0)
|
2022-02-24 13:54:30 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (parseIntervalKind(pos, expected, interval_kind))
|
2022-02-24 13:54:30 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!ParserToken(TokenType::Comma).ignore(pos, expected))
|
|
|
|
|
return false;
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
action = Action::OPERAND;
|
|
|
|
|
parsed_interval_kind = true;
|
|
|
|
|
}
|
2022-08-04 09:32:14 +00:00
|
|
|
|
|
|
|
|
|
state = 1;
|
2022-07-14 12:11:14 +00:00
|
|
|
|
}
|
2022-06-23 08:18:14 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (state == 1)
|
|
|
|
|
{
|
2022-10-25 09:24:42 +00:00
|
|
|
|
return LayerWithSeparator::parse(pos, expected, action);
|
2022-07-14 12:11:14 +00:00
|
|
|
|
}
|
2022-06-23 08:18:14 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-06-02 22:07:14 +00:00
|
|
|
|
|
2022-10-27 10:03:03 +00:00
|
|
|
|
protected:
|
|
|
|
|
bool getResultImpl(ASTPtr & node) override
|
|
|
|
|
{
|
|
|
|
|
if (parsed_interval_kind)
|
|
|
|
|
{
|
|
|
|
|
if (elements.size() < 2)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
elements[0] = makeASTFunction(interval_kind.toNameOfFunctionToIntervalDataType(), elements[0]);
|
|
|
|
|
node = makeASTFunction(function_name, elements[1], elements[0]);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
node = makeASTFunction(function_name, std::move(elements));
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
private:
|
|
|
|
|
IntervalKind interval_kind;
|
|
|
|
|
const char * function_name;
|
|
|
|
|
bool parsed_interval_kind = false;
|
|
|
|
|
};
|
2022-06-16 01:53:27 +00:00
|
|
|
|
|
2022-10-25 09:24:42 +00:00
|
|
|
|
class DateDiffLayer : public LayerWithSeparator<TokenType::Comma, TokenType::ClosingRoundBracket>
|
2022-07-14 12:11:14 +00:00
|
|
|
|
{
|
|
|
|
|
public:
|
2022-10-25 09:24:42 +00:00
|
|
|
|
DateDiffLayer() : LayerWithSeparator(/*allow_alias*/ true, /*allow_alias_without_as_keyword*/ true) {}
|
2022-10-21 00:16:24 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
|
{
|
2022-08-04 09:32:14 +00:00
|
|
|
|
/// 0. Try to parse interval_kind (-> 1)
|
|
|
|
|
/// 1. Basic parser
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (state == 0)
|
|
|
|
|
{
|
|
|
|
|
if (parseIntervalKind(pos, expected, interval_kind))
|
2022-02-24 13:54:30 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
parsed_interval_kind = true;
|
2022-05-26 23:38:25 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!ParserToken(TokenType::Comma).ignore(pos, expected))
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-05-26 23:38:25 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
state = 1;
|
|
|
|
|
}
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (state == 1)
|
|
|
|
|
{
|
2022-10-25 09:24:42 +00:00
|
|
|
|
return LayerWithSeparator::parse(pos, expected, action);
|
2022-07-14 12:11:14 +00:00
|
|
|
|
}
|
2022-06-22 21:59:20 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-06-29 21:51:58 +00:00
|
|
|
|
|
2022-10-27 10:03:03 +00:00
|
|
|
|
protected:
|
|
|
|
|
bool getResultImpl(ASTPtr & node) override
|
|
|
|
|
{
|
|
|
|
|
if (parsed_interval_kind)
|
|
|
|
|
{
|
|
|
|
|
if (elements.size() == 2)
|
|
|
|
|
node = makeASTFunction("dateDiff", std::make_shared<ASTLiteral>(interval_kind.toDateDiffUnit()), elements[0], elements[1]);
|
|
|
|
|
else if (elements.size() == 3)
|
|
|
|
|
node = makeASTFunction("dateDiff", std::make_shared<ASTLiteral>(interval_kind.toDateDiffUnit()), elements[0], elements[1], elements[2]);
|
|
|
|
|
else
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
node = makeASTFunction("dateDiff", std::move(elements));
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
private:
|
|
|
|
|
IntervalKind interval_kind;
|
|
|
|
|
bool parsed_interval_kind = false;
|
|
|
|
|
};
|
2022-06-22 21:59:20 +00:00
|
|
|
|
|
2022-12-27 14:49:41 +00:00
|
|
|
|
class TupleLayer : public LayerWithSeparator<TokenType::Comma, TokenType::ClosingRoundBracket>
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
|
{
|
|
|
|
|
bool result = LayerWithSeparator::parse(pos, expected, action);
|
|
|
|
|
|
|
|
|
|
/// Check that after the tuple() function there is no lambdas operator
|
|
|
|
|
if (finished && pos->type == TokenType::Arrow)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
bool getResultImpl(ASTPtr & node) override
|
|
|
|
|
{
|
|
|
|
|
node = makeASTFunction("tuple", std::move(elements));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
class IntervalLayer : public Layer
|
|
|
|
|
{
|
|
|
|
|
public:
|
2022-10-24 19:52:51 +00:00
|
|
|
|
IntervalLayer() : Layer(/*allow_alias*/ true, /*allow_alias_without_as_keyword*/ true) {}
|
2022-10-21 00:16:24 +00:00
|
|
|
|
|
2022-09-07 01:45:13 +00:00
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
2022-07-14 12:11:14 +00:00
|
|
|
|
{
|
2022-08-04 09:32:14 +00:00
|
|
|
|
/// INTERVAL 1 HOUR or INTERVAL expr HOUR
|
|
|
|
|
///
|
|
|
|
|
/// 0. Try to parse interval_kind (-> 1)
|
2022-08-04 10:06:18 +00:00
|
|
|
|
/// 1. Basic parser
|
2022-08-04 09:32:14 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (state == 0)
|
|
|
|
|
{
|
2022-10-09 00:00:14 +00:00
|
|
|
|
state = 1;
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
auto begin = pos;
|
|
|
|
|
auto init_expected = expected;
|
|
|
|
|
ASTPtr string_literal;
|
2022-10-09 00:00:14 +00:00
|
|
|
|
String literal;
|
|
|
|
|
|
2022-07-14 12:11:14 +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
|
2022-10-09 00:00:14 +00:00
|
|
|
|
if (ParserStringLiteral{}.parse(pos, string_literal, expected)
|
|
|
|
|
&& string_literal->as<ASTLiteral &>().value.tryGet(literal))
|
2022-07-14 12:11:14 +00:00
|
|
|
|
{
|
2022-10-09 00:00:14 +00:00
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
/// case: INTERVAL '1' HOUR
|
|
|
|
|
/// back to begin
|
|
|
|
|
if (!token_pos.isValid())
|
2022-07-14 12:11:14 +00:00
|
|
|
|
{
|
2022-10-09 00:00:14 +00:00
|
|
|
|
pos = begin;
|
|
|
|
|
expected = init_expected;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-06-22 21:59:20 +00:00
|
|
|
|
|
2022-10-09 00:00:14 +00:00
|
|
|
|
/// case: INTERVAL '1 HOUR'
|
|
|
|
|
if (!parseIntervalKind(token_pos, token_expected, interval_kind))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
pushResult(makeASTFunction(interval_kind.toNameOfFunctionToIntervalDataType(), expr));
|
|
|
|
|
|
|
|
|
|
/// case: INTERVAL '1 HOUR 1 SECOND ...'
|
|
|
|
|
while (token_pos.isValid())
|
|
|
|
|
{
|
|
|
|
|
if (!ParserNumber{}.parse(token_pos, expr, token_expected) ||
|
|
|
|
|
!parseIntervalKind(token_pos, token_expected, interval_kind))
|
2022-07-14 12:11:14 +00:00
|
|
|
|
return false;
|
2022-06-22 21:59:20 +00:00
|
|
|
|
|
2022-10-09 00:00:14 +00:00
|
|
|
|
pushResult(makeASTFunction(interval_kind.toNameOfFunctionToIntervalDataType(), expr));
|
2022-02-24 13:54:30 +00:00
|
|
|
|
}
|
2022-10-09 00:00:14 +00:00
|
|
|
|
|
|
|
|
|
finished = true;
|
2022-07-14 12:11:14 +00:00
|
|
|
|
}
|
2022-08-04 09:32:14 +00:00
|
|
|
|
return true;
|
2022-07-14 12:11:14 +00:00
|
|
|
|
}
|
2022-05-26 16:50:48 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (state == 1)
|
|
|
|
|
{
|
2022-09-07 01:45:13 +00:00
|
|
|
|
if (action == Action::OPERATOR && parseIntervalKind(pos, expected, interval_kind))
|
2022-07-14 12:11:14 +00:00
|
|
|
|
{
|
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
2022-06-02 22:07:14 +00:00
|
|
|
|
|
2022-08-10 04:58:59 +00:00
|
|
|
|
elements = {makeASTFunction(interval_kind.toNameOfFunctionToIntervalDataType(), elements)};
|
2022-07-14 12:11:14 +00:00
|
|
|
|
finished = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-05-26 23:38:25 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-04-12 15:03:10 +00:00
|
|
|
|
|
2022-11-04 23:09:43 +00:00
|
|
|
|
protected:
|
|
|
|
|
bool getResultImpl(ASTPtr & node) override
|
2022-09-13 20:31:08 +00:00
|
|
|
|
{
|
2022-11-04 23:09:43 +00:00
|
|
|
|
if (elements.size() == 1)
|
|
|
|
|
node = elements[0];
|
2022-09-13 20:31:08 +00:00
|
|
|
|
else
|
2022-11-04 23:09:43 +00:00
|
|
|
|
node = makeASTFunction("tuple", std::move(elements));
|
2022-09-13 20:31:08 +00:00
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
private:
|
|
|
|
|
IntervalKind interval_kind;
|
|
|
|
|
};
|
2022-06-02 22:07:14 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
class CaseLayer : public Layer
|
|
|
|
|
{
|
|
|
|
|
public:
|
2022-10-24 19:52:51 +00:00
|
|
|
|
CaseLayer() : Layer(/*allow_alias*/ true, /*allow_alias_without_as_keyword*/ true) {}
|
2022-10-21 00:16:24 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
|
|
|
|
{
|
2022-08-04 09:32:14 +00:00
|
|
|
|
/// CASE [x] WHEN expr THEN expr [WHEN expr THEN expr [...]] [ELSE expr] END
|
|
|
|
|
///
|
|
|
|
|
/// 0. Check if we have case expression [x] (-> 1)
|
|
|
|
|
/// 1. Parse keywords: WHEN (-> 2), ELSE (-> 3), END (finished)
|
|
|
|
|
/// 2. Parse THEN keyword (-> 1)
|
|
|
|
|
/// 3. Parse END keyword (finished)
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (state == 0)
|
|
|
|
|
{
|
|
|
|
|
auto old_pos = pos;
|
|
|
|
|
has_case_expr = !ParserKeyword("WHEN").ignore(pos, expected);
|
|
|
|
|
pos = old_pos;
|
2022-04-17 20:59:03 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
state = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (state == 1)
|
|
|
|
|
{
|
|
|
|
|
if (ParserKeyword("WHEN").ignore(pos, expected))
|
2022-04-29 15:07:42 +00:00
|
|
|
|
{
|
2022-08-10 04:58:59 +00:00
|
|
|
|
if ((has_case_expr || !elements.empty()) && !mergeElement())
|
2022-04-29 15:07:42 +00:00
|
|
|
|
return false;
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
|
|
|
|
action = Action::OPERAND;
|
|
|
|
|
state = 2;
|
2022-04-29 15:07:42 +00:00
|
|
|
|
}
|
2022-07-14 12:11:14 +00:00
|
|
|
|
else if (ParserKeyword("ELSE").ignore(pos, expected))
|
2022-02-24 13:54:30 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
action = Action::OPERAND;
|
|
|
|
|
state = 3;
|
2022-02-24 13:54:30 +00:00
|
|
|
|
}
|
2022-07-14 12:11:14 +00:00
|
|
|
|
else if (ParserKeyword("END").ignore(pos, expected))
|
2022-02-24 13:54:30 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
2021-02-13 05:18:14 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
Field field_with_null;
|
|
|
|
|
ASTLiteral null_literal(field_with_null);
|
2022-08-10 04:58:59 +00:00
|
|
|
|
elements.push_back(std::make_shared<ASTLiteral>(null_literal));
|
2021-02-13 05:18:14 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (has_case_expr)
|
2022-08-10 04:58:59 +00:00
|
|
|
|
elements = {makeASTFunction("caseWithExpression", elements)};
|
2022-07-14 12:11:14 +00:00
|
|
|
|
else
|
2022-08-10 04:58:59 +00:00
|
|
|
|
elements = {makeASTFunction("multiIf", elements)};
|
2022-07-14 12:11:14 +00:00
|
|
|
|
finished = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-04-01 07:20:54 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (state == 2)
|
2015-05-28 01:41:40 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (ParserKeyword("THEN").ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
2017-04-01 07:20:54 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
action = Action::OPERAND;
|
|
|
|
|
state = 1;
|
|
|
|
|
}
|
2015-05-28 01:41:40 +00:00
|
|
|
|
}
|
2017-04-01 07:20:54 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (state == 3)
|
2021-05-24 07:07:25 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (ParserKeyword("END").ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
2017-04-01 07:20:54 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (has_case_expr)
|
2022-08-10 04:58:59 +00:00
|
|
|
|
elements = {makeASTFunction("caseWithExpression", elements)};
|
2022-07-14 12:11:14 +00:00
|
|
|
|
else
|
2022-08-10 04:58:59 +00:00
|
|
|
|
elements = {makeASTFunction("multiIf", elements)};
|
2017-04-01 07:20:54 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
finished = true;
|
|
|
|
|
}
|
2021-05-24 07:07:25 +00:00
|
|
|
|
}
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
|
|
|
|
return true;
|
2010-06-24 19:37:23 +00:00
|
|
|
|
}
|
2017-04-01 07:20:54 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
private:
|
|
|
|
|
bool has_case_expr;
|
|
|
|
|
};
|
2010-06-24 19:12:10 +00:00
|
|
|
|
|
2022-10-21 00:16:24 +00:00
|
|
|
|
/// Layer for table function 'view' and 'viewIfPermitted'
|
|
|
|
|
class ViewLayer : public Layer
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
explicit ViewLayer(bool if_permitted_) : if_permitted(if_permitted_) {}
|
|
|
|
|
|
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & /*action*/) override
|
|
|
|
|
{
|
|
|
|
|
/// view(SELECT ...)
|
|
|
|
|
/// viewIfPermitted(SELECT ... ELSE func(...))
|
|
|
|
|
///
|
|
|
|
|
/// 0. Parse the SELECT query and if 'if_permitted' parse 'ELSE' keyword (-> 1) else (finished)
|
|
|
|
|
/// 1. Parse closing token
|
|
|
|
|
|
|
|
|
|
if (state == 0)
|
|
|
|
|
{
|
|
|
|
|
ASTPtr query;
|
|
|
|
|
|
|
|
|
|
bool maybe_an_subquery = pos->type == TokenType::OpeningRoundBracket;
|
|
|
|
|
|
|
|
|
|
if (!ParserSelectWithUnionQuery().parse(pos, query, expected))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
auto & select_ast = query->as<ASTSelectWithUnionQuery &>();
|
|
|
|
|
if (select_ast.list_of_selects->children.size() == 1 && maybe_an_subquery)
|
|
|
|
|
{
|
|
|
|
|
// It's an subquery. Bail out.
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pushResult(query);
|
|
|
|
|
|
|
|
|
|
if (!if_permitted)
|
|
|
|
|
{
|
|
|
|
|
if (!ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
finished = true;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ParserKeyword{"ELSE"}.ignore(pos, expected))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
state = 1;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (state == 1)
|
|
|
|
|
{
|
|
|
|
|
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
finished = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-27 10:03:03 +00:00
|
|
|
|
protected:
|
|
|
|
|
bool getResultImpl(ASTPtr & node) override
|
|
|
|
|
{
|
|
|
|
|
if (if_permitted)
|
|
|
|
|
node = makeASTFunction("viewIfPermitted", std::move(elements));
|
|
|
|
|
else
|
|
|
|
|
node = makeASTFunction("view", std::move(elements));
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-21 00:16:24 +00:00
|
|
|
|
private:
|
|
|
|
|
bool if_permitted;
|
|
|
|
|
};
|
|
|
|
|
|
2023-04-10 12:44:16 +00:00
|
|
|
|
/// Layer for table function 'kql'
|
2023-04-03 01:14:09 +00:00
|
|
|
|
class KustoLayer : public Layer
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
KustoLayer() : Layer(/*allow_alias*/ true, /*allow_alias_without_as_keyword*/ true) {}
|
|
|
|
|
|
|
|
|
|
bool parse(IParser::Pos & pos, Expected & expected, Action & /*action*/) override
|
|
|
|
|
{
|
|
|
|
|
/// kql(table|project ...)
|
|
|
|
|
/// 0. Parse the kql query
|
|
|
|
|
/// 1. Parse closing token
|
|
|
|
|
if (state == 0)
|
|
|
|
|
{
|
|
|
|
|
ASTPtr query;
|
|
|
|
|
--pos;
|
|
|
|
|
if (!ParserKQLTableFunction().parse(pos, query, expected))
|
|
|
|
|
return false;
|
|
|
|
|
--pos;
|
|
|
|
|
pushResult(query);
|
|
|
|
|
|
|
|
|
|
if (!ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
finished = true;
|
2023-05-16 04:28:13 +00:00
|
|
|
|
state = 1;
|
2023-04-03 01:14:09 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (state == 1)
|
|
|
|
|
{
|
|
|
|
|
if (ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
if (!mergeElement())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
finished = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
bool getResultImpl(ASTPtr & node) override
|
|
|
|
|
{
|
|
|
|
|
node = makeASTFunction("view", std::move(elements)); // reuse view function for kql
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
};
|
2010-06-24 19:12:10 +00:00
|
|
|
|
|
2022-09-13 20:31:08 +00:00
|
|
|
|
std::unique_ptr<Layer> getFunctionLayer(ASTPtr identifier, bool is_table_function, bool allow_function_parameters_ = true)
|
2022-09-12 15:26:45 +00:00
|
|
|
|
{
|
|
|
|
|
/// Special cases for expressions that look like functions but contain some syntax sugar:
|
|
|
|
|
|
|
|
|
|
/// CAST, EXTRACT, POSITION, EXISTS
|
|
|
|
|
/// DATE_ADD, DATEADD, TIMESTAMPADD, DATE_SUB, DATESUB, TIMESTAMPSUB,
|
|
|
|
|
/// DATE_DIFF, DATEDIFF, TIMESTAMPDIFF, TIMESTAMP_DIFF,
|
|
|
|
|
/// SUBSTRING, TRIM, LTRIM, RTRIM, POSITION
|
|
|
|
|
|
|
|
|
|
/// Can be parsed as a composition of functions, but the contents must be unwrapped:
|
|
|
|
|
/// POSITION(x IN y) -> POSITION(in(x, y)) -> POSITION(y, x)
|
|
|
|
|
|
|
|
|
|
/// Can be parsed as a function, but not always:
|
|
|
|
|
/// CAST(x AS type) - alias has to be unwrapped
|
|
|
|
|
/// CAST(x AS type(params))
|
|
|
|
|
|
|
|
|
|
/// Can be parsed as a function, but some identifier arguments have special meanings.
|
|
|
|
|
/// DATE_ADD(MINUTE, x, y) -> addMinutes(x, y)
|
|
|
|
|
/// DATE_DIFF(MINUTE, x, y)
|
|
|
|
|
|
|
|
|
|
/// Have keywords that have to processed explicitly:
|
|
|
|
|
/// EXTRACT(x FROM y)
|
|
|
|
|
/// TRIM(BOTH|LEADING|TRAILING x FROM y)
|
|
|
|
|
/// SUBSTRING(x FROM a)
|
|
|
|
|
/// SUBSTRING(x FROM a FOR b)
|
|
|
|
|
|
|
|
|
|
String function_name = getIdentifierName(identifier);
|
|
|
|
|
String function_name_lowercase = Poco::toLower(function_name);
|
|
|
|
|
|
2022-09-13 20:31:08 +00:00
|
|
|
|
if (is_table_function)
|
|
|
|
|
{
|
|
|
|
|
if (function_name_lowercase == "view")
|
|
|
|
|
return std::make_unique<ViewLayer>(false);
|
|
|
|
|
else if (function_name_lowercase == "viewifpermitted")
|
|
|
|
|
return std::make_unique<ViewLayer>(true);
|
2023-04-03 01:14:09 +00:00
|
|
|
|
else if (function_name_lowercase == "kql")
|
|
|
|
|
return std::make_unique<KustoLayer>();
|
2022-09-13 20:31:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-12-27 14:49:41 +00:00
|
|
|
|
if (function_name == "tuple")
|
|
|
|
|
return std::make_unique<TupleLayer>();
|
|
|
|
|
|
2022-09-12 15:26:45 +00:00
|
|
|
|
if (function_name_lowercase == "cast")
|
|
|
|
|
return std::make_unique<CastLayer>();
|
|
|
|
|
else if (function_name_lowercase == "extract")
|
|
|
|
|
return std::make_unique<ExtractLayer>();
|
|
|
|
|
else if (function_name_lowercase == "substring")
|
|
|
|
|
return std::make_unique<SubstringLayer>();
|
|
|
|
|
else if (function_name_lowercase == "position")
|
|
|
|
|
return std::make_unique<PositionLayer>();
|
|
|
|
|
else if (function_name_lowercase == "exists")
|
|
|
|
|
return std::make_unique<ExistsLayer>();
|
|
|
|
|
else if (function_name_lowercase == "trim")
|
|
|
|
|
return std::make_unique<TrimLayer>(false, false);
|
|
|
|
|
else if (function_name_lowercase == "ltrim")
|
|
|
|
|
return std::make_unique<TrimLayer>(true, false);
|
|
|
|
|
else if (function_name_lowercase == "rtrim")
|
|
|
|
|
return std::make_unique<TrimLayer>(false, true);
|
|
|
|
|
else if (function_name_lowercase == "dateadd" || function_name_lowercase == "date_add"
|
|
|
|
|
|| function_name_lowercase == "timestampadd" || function_name_lowercase == "timestamp_add")
|
|
|
|
|
return 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")
|
|
|
|
|
return 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")
|
|
|
|
|
return std::make_unique<DateDiffLayer>();
|
|
|
|
|
else if (function_name_lowercase == "grouping")
|
2022-10-19 23:38:44 +00:00
|
|
|
|
return std::make_unique<FunctionLayer>(function_name_lowercase, allow_function_parameters_);
|
2022-09-12 15:26:45 +00:00
|
|
|
|
else
|
2022-11-07 14:22:45 +00:00
|
|
|
|
return std::make_unique<FunctionLayer>(function_name, allow_function_parameters_, identifier->as<ASTIdentifier>()->compound());
|
2022-09-12 15:26:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool ParseCastExpression(IParser::Pos & pos, ASTPtr & node, Expected & expected)
|
2012-11-20 22:48:38 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
IParser::Pos begin = pos;
|
2012-11-20 22:48:38 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
if (ParserCastOperator().parse(pos, node, expected))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
pos = begin;
|
|
|
|
|
|
|
|
|
|
/// As an exception, negative numbers should be parsed as literals, and not as an application of the operator.
|
2017-07-10 03:28:12 +00:00
|
|
|
|
if (pos->type == TokenType::Minus)
|
2012-11-20 22:48:38 +00:00
|
|
|
|
{
|
2021-08-19 15:15:44 +00:00
|
|
|
|
if (ParserLiteral().parse(pos, node, expected))
|
2012-11-20 22:48:38 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-07-14 12:11:14 +00:00
|
|
|
|
return false;
|
2012-11-20 22:48:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool ParseDateOperatorExpression(IParser::Pos & pos, ASTPtr & node, Expected & expected)
|
2021-05-04 03:43:17 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
auto begin = pos;
|
|
|
|
|
|
|
|
|
|
/// If no DATE keyword, go to the nested parser.
|
|
|
|
|
if (!ParserKeyword("DATE").ignore(pos, expected))
|
2021-05-04 03:43:17 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
ASTPtr expr;
|
|
|
|
|
if (!ParserStringLiteral().parse(pos, expr, expected))
|
2021-05-04 03:43:17 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
pos = begin;
|
|
|
|
|
return false;
|
2021-05-04 03:43:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
node = makeASTFunction("toDate", expr);
|
2021-05-04 03:43:17 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool ParseTimestampOperatorExpression(IParser::Pos & pos, ASTPtr & node, Expected & expected)
|
2010-06-24 19:12:10 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
auto begin = pos;
|
2010-06-24 19:12:10 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
/// If no TIMESTAMP keyword, go to the nested parser.
|
|
|
|
|
if (!ParserKeyword("TIMESTAMP").ignore(pos, expected))
|
|
|
|
|
return false;
|
2010-06-24 19:12:10 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
ASTPtr expr;
|
|
|
|
|
if (!ParserStringLiteral().parse(pos, expr, expected))
|
|
|
|
|
{
|
|
|
|
|
pos = begin;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2010-06-24 19:12:10 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
node = makeASTFunction("toDateTime", expr);
|
2022-02-24 13:54:30 +00:00
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
return true;
|
2011-09-04 05:14:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 12:11:14 +00:00
|
|
|
|
bool ParserExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
2021-07-28 07:02:10 +00:00
|
|
|
|
{
|
2023-04-05 18:08:56 +00:00
|
|
|
|
auto start = std::make_unique<ExpressionLayer>(false, allow_trailing_commas);
|
2022-09-12 15:26:45 +00:00
|
|
|
|
return ParserExpressionImpl().parse(std::move(start), pos, node, expected);
|
2022-09-05 16:21:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-09-13 20:31:08 +00:00
|
|
|
|
bool ParserTableFunctionExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
|
|
|
|
{
|
2022-09-16 03:29:34 +00:00
|
|
|
|
auto start = std::make_unique<ExpressionLayer>(true);
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return ParserExpressionImpl().parse(std::move(start), pos, node, expected);
|
2022-09-05 16:21:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 18:40:39 +00:00
|
|
|
|
bool ParserArray::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
|
|
|
|
{
|
2022-09-12 15:26:45 +00:00
|
|
|
|
auto start = std::make_unique<ArrayLayer>();
|
2022-09-09 18:40:39 +00:00
|
|
|
|
return ParserToken(TokenType::OpeningSquareBracket).ignore(pos, expected)
|
2022-09-12 15:26:45 +00:00
|
|
|
|
&& ParserExpressionImpl().parse(std::move(start), pos, node, expected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ParserFunction::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
|
|
|
|
{
|
|
|
|
|
ASTPtr identifier;
|
|
|
|
|
|
2022-10-05 09:48:14 +00:00
|
|
|
|
if (ParserCompoundIdentifier(false,true).parse(pos, identifier, expected)
|
2022-09-12 15:26:45 +00:00
|
|
|
|
&& ParserToken(TokenType::OpeningRoundBracket).ignore(pos, expected))
|
|
|
|
|
{
|
2022-09-13 20:31:08 +00:00
|
|
|
|
auto start = getFunctionLayer(identifier, is_table_function, allow_function_parameters);
|
|
|
|
|
start->is_table_function = is_table_function;
|
2022-09-12 15:26:45 +00:00
|
|
|
|
return ParserExpressionImpl().parse(std::move(start), pos, node, expected);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-09-09 18:40:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-12 18:15:08 +00:00
|
|
|
|
const std::vector<std::pair<std::string_view, Operator>> ParserExpressionImpl::operators_table
|
|
|
|
|
{
|
|
|
|
|
{"->", Operator("lambda", 1, 2, OperatorType::Lambda)},
|
|
|
|
|
{"?", Operator("", 2, 0, OperatorType::StartIf)},
|
|
|
|
|
{":", Operator("if", 3, 3, OperatorType::FinishIf)},
|
|
|
|
|
{"OR", Operator("or", 3, 2, OperatorType::Mergeable)},
|
|
|
|
|
{"AND", Operator("and", 4, 2, OperatorType::Mergeable)},
|
2023-08-30 13:12:43 +00:00
|
|
|
|
{"IS NOT DISTINCT FROM", Operator("isNotDistinctFrom", 6, 2)},
|
2023-05-30 12:18:56 +00:00
|
|
|
|
{"IS NULL", Operator("isNull", 6, 1, OperatorType::IsNull)},
|
|
|
|
|
{"IS NOT NULL", Operator("isNotNull", 6, 1, OperatorType::IsNull)},
|
2023-05-29 19:09:07 +00:00
|
|
|
|
{"BETWEEN", Operator("", 7, 0, OperatorType::StartBetween)},
|
|
|
|
|
{"NOT BETWEEN", Operator("", 7, 0, OperatorType::StartNotBetween)},
|
|
|
|
|
{"==", Operator("equals", 9, 2, OperatorType::Comparison)},
|
|
|
|
|
{"!=", Operator("notEquals", 9, 2, OperatorType::Comparison)},
|
2023-08-30 13:12:43 +00:00
|
|
|
|
{"<=>", Operator("isNotDistinctFrom", 9, 2, OperatorType::Comparison)},
|
2023-05-29 19:09:07 +00:00
|
|
|
|
{"<>", Operator("notEquals", 9, 2, OperatorType::Comparison)},
|
|
|
|
|
{"<=", Operator("lessOrEquals", 9, 2, OperatorType::Comparison)},
|
|
|
|
|
{">=", Operator("greaterOrEquals", 9, 2, OperatorType::Comparison)},
|
|
|
|
|
{"<", Operator("less", 9, 2, OperatorType::Comparison)},
|
|
|
|
|
{">", Operator("greater", 9, 2, OperatorType::Comparison)},
|
|
|
|
|
{"=", Operator("equals", 9, 2, OperatorType::Comparison)},
|
|
|
|
|
{"LIKE", Operator("like", 9, 2)},
|
|
|
|
|
{"ILIKE", Operator("ilike", 9, 2)},
|
|
|
|
|
{"NOT LIKE", Operator("notLike", 9, 2)},
|
|
|
|
|
{"NOT ILIKE", Operator("notILike", 9, 2)},
|
|
|
|
|
{"REGEXP", Operator("match", 9, 2)},
|
|
|
|
|
{"IN", Operator("in", 9, 2)},
|
|
|
|
|
{"NOT IN", Operator("notIn", 9, 2)},
|
|
|
|
|
{"GLOBAL IN", Operator("globalIn", 9, 2)},
|
|
|
|
|
{"GLOBAL NOT IN", Operator("globalNotIn", 9, 2)},
|
2023-05-30 12:18:56 +00:00
|
|
|
|
{"||", Operator("concat", 10, 2, OperatorType::Mergeable)},
|
2023-05-29 19:09:07 +00:00
|
|
|
|
{"+", Operator("plus", 11, 2)},
|
|
|
|
|
{"-", Operator("minus", 11, 2)},
|
2023-08-31 02:56:47 +00:00
|
|
|
|
{"−", Operator("minus", 11, 2)},
|
2023-05-29 19:09:07 +00:00
|
|
|
|
{"*", Operator("multiply", 12, 2)},
|
|
|
|
|
{"/", Operator("divide", 12, 2)},
|
|
|
|
|
{"%", Operator("modulo", 12, 2)},
|
|
|
|
|
{"MOD", Operator("modulo", 12, 2)},
|
|
|
|
|
{"DIV", Operator("intDiv", 12, 2)},
|
|
|
|
|
{".", Operator("tupleElement", 14, 2, OperatorType::TupleElement)},
|
|
|
|
|
{"[", Operator("arrayElement", 14, 2, OperatorType::ArrayElement)},
|
|
|
|
|
{"::", Operator("CAST", 14, 2, OperatorType::Cast)},
|
2023-04-12 18:15:08 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const std::vector<std::pair<std::string_view, Operator>> ParserExpressionImpl::unary_operators_table
|
2022-09-05 16:21:16 +00:00
|
|
|
|
{
|
2023-04-12 18:15:08 +00:00
|
|
|
|
{"NOT", Operator("not", 5, 1)},
|
2023-08-31 02:56:47 +00:00
|
|
|
|
{"-", Operator("negate", 13, 1)},
|
|
|
|
|
{"−", Operator("negate", 13, 1)}
|
2023-04-12 18:15:08 +00:00
|
|
|
|
};
|
|
|
|
|
|
2023-05-30 12:18:56 +00:00
|
|
|
|
const Operator ParserExpressionImpl::finish_between_operator("", 8, 0, OperatorType::FinishBetween);
|
2023-04-12 18:15:08 +00:00
|
|
|
|
|
|
|
|
|
const std::array<std::string_view, 1> ParserExpressionImpl::overlapping_operators_to_skip
|
2022-09-05 16:21:16 +00:00
|
|
|
|
{
|
2023-04-12 18:15:08 +00:00
|
|
|
|
"IN PARTITION"
|
2022-09-05 16:21:16 +00:00
|
|
|
|
};
|
|
|
|
|
|
2022-09-12 15:26:45 +00:00
|
|
|
|
bool ParserExpressionImpl::parse(std::unique_ptr<Layer> start, IParser::Pos & pos, ASTPtr & node, Expected & expected)
|
2022-08-12 19:20:17 +00:00
|
|
|
|
{
|
2022-07-14 12:11:14 +00:00
|
|
|
|
Action next = Action::OPERAND;
|
|
|
|
|
|
2022-09-13 21:07:15 +00:00
|
|
|
|
Layers layers;
|
2022-09-12 15:26:45 +00:00
|
|
|
|
layers.push_back(std::move(start));
|
2022-07-14 12:11:14 +00:00
|
|
|
|
|
2022-09-05 16:21:16 +00:00
|
|
|
|
while (true)
|
2022-07-14 12:11:14 +00:00
|
|
|
|
{
|
2022-09-05 16:21:16 +00:00
|
|
|
|
while (pos.isValid())
|
2021-07-28 07:02:10 +00:00
|
|
|
|
{
|
2022-09-05 16:21:16 +00:00
|
|
|
|
if (!layers.back()->parse(pos, expected, next))
|
|
|
|
|
break;
|
2023-05-30 12:18:56 +00:00
|
|
|
|
|
2022-09-05 16:21:16 +00:00
|
|
|
|
if (layers.back()->isFinished())
|
|
|
|
|
{
|
|
|
|
|
if (layers.size() == 1)
|
|
|
|
|
break;
|
2021-07-28 07:02:10 +00:00
|
|
|
|
|
2022-09-05 16:21:16 +00:00
|
|
|
|
next = Action::OPERATOR;
|
2022-08-10 04:58:59 +00:00
|
|
|
|
|
2022-09-05 16:21:16 +00:00
|
|
|
|
ASTPtr res;
|
|
|
|
|
if (!layers.back()->getResult(res))
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
layers.pop_back();
|
|
|
|
|
layers.back()->pushOperand(res);
|
|
|
|
|
continue;
|
2022-08-10 04:58:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-09-05 16:21:16 +00:00
|
|
|
|
if (next == Action::OPERAND)
|
2022-09-15 21:54:37 +00:00
|
|
|
|
next = tryParseOperand(layers, pos, expected);
|
2022-09-05 16:21:16 +00:00
|
|
|
|
else
|
2022-09-15 21:54:37 +00:00
|
|
|
|
next = tryParseOperator(layers, pos, expected);
|
2022-08-12 19:20:17 +00:00
|
|
|
|
|
2022-09-15 21:54:37 +00:00
|
|
|
|
if (next == Action::NONE)
|
2022-09-05 16:21:16 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
2022-08-12 19:20:17 +00:00
|
|
|
|
|
2022-09-05 16:21:16 +00:00
|
|
|
|
/// When we exit the loop we should be on the 1st level
|
|
|
|
|
if (layers.size() == 1 && layers.back()->getResult(node))
|
|
|
|
|
return true;
|
2021-07-28 07:02:10 +00:00
|
|
|
|
|
2022-09-05 16:21:16 +00:00
|
|
|
|
layers.pop_back();
|
2021-07-28 07:02:10 +00:00
|
|
|
|
|
2022-09-07 01:45:13 +00:00
|
|
|
|
/// We try to check whether there was a checkpoint
|
|
|
|
|
while (!layers.empty() && !layers.back()->saved_checkpoint)
|
2022-09-05 16:21:16 +00:00
|
|
|
|
layers.pop_back();
|
2021-07-28 07:02:10 +00:00
|
|
|
|
|
2022-09-05 16:21:16 +00:00
|
|
|
|
if (layers.empty())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
/// Currently all checkpoints are located in operand section
|
|
|
|
|
next = Action::OPERAND;
|
2022-09-07 01:45:13 +00:00
|
|
|
|
|
|
|
|
|
auto saved_checkpoint = layers.back()->saved_checkpoint.value();
|
|
|
|
|
layers.back()->saved_checkpoint.reset();
|
|
|
|
|
|
|
|
|
|
pos = saved_checkpoint.first;
|
|
|
|
|
layers.back()->current_checkpoint = saved_checkpoint.second;
|
2022-09-05 16:21:16 +00:00
|
|
|
|
}
|
2022-08-12 19:20:17 +00:00
|
|
|
|
}
|
2011-09-04 05:14:52 +00:00
|
|
|
|
|
2022-09-15 21:54:37 +00:00
|
|
|
|
Action ParserExpressionImpl::tryParseOperand(Layers & layers, IParser::Pos & pos, Expected & expected)
|
2022-08-12 19:20:17 +00:00
|
|
|
|
{
|
|
|
|
|
ASTPtr tmp;
|
2022-03-17 05:51:35 +00:00
|
|
|
|
|
2022-09-14 09:44:51 +00:00
|
|
|
|
if (layers.front()->is_table_function)
|
2022-09-13 20:31:08 +00:00
|
|
|
|
{
|
2023-04-03 01:14:09 +00:00
|
|
|
|
if (typeid_cast<ViewLayer *>(layers.back().get()) || typeid_cast<KustoLayer *>(layers.back().get()))
|
2022-09-14 09:44:51 +00:00
|
|
|
|
{
|
|
|
|
|
if (identifier_parser.parse(pos, tmp, expected)
|
|
|
|
|
&& ParserToken(TokenType::OpeningRoundBracket).ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
layers.push_back(getFunctionLayer(tmp, layers.front()->is_table_function));
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::OPERAND;
|
2022-09-14 09:44:51 +00:00
|
|
|
|
}
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::NONE;
|
2022-09-14 09:44:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Current element should be empty (there should be no other operands or operators)
|
|
|
|
|
/// to parse SETTINGS in table function
|
2022-09-15 00:48:14 +00:00
|
|
|
|
if (layers.back()->isCurrentElementEmpty())
|
2022-09-13 20:31:08 +00:00
|
|
|
|
{
|
2022-09-14 09:44:51 +00:00
|
|
|
|
auto old_pos = pos;
|
|
|
|
|
ParserKeyword s_settings("SETTINGS");
|
|
|
|
|
if (s_settings.ignore(pos, expected))
|
|
|
|
|
{
|
|
|
|
|
ParserSetQuery parser_settings(true);
|
|
|
|
|
if (parser_settings.parse(pos, tmp, expected))
|
|
|
|
|
{
|
|
|
|
|
layers.back()->pushOperand(tmp);
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::OPERAND;
|
2022-09-14 09:44:51 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pos = old_pos;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-09-13 20:31:08 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
/// Special case for cast expression
|
|
|
|
|
if (layers.back()->previousType() != OperatorType::TupleElement &&
|
|
|
|
|
ParseCastExpression(pos, tmp, expected))
|
|
|
|
|
{
|
|
|
|
|
layers.back()->pushOperand(std::move(tmp));
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::OPERATOR;
|
2022-08-12 19:20:17 +00:00
|
|
|
|
}
|
2022-03-17 05:51:35 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
if (layers.back()->previousType() == OperatorType::Comparison)
|
|
|
|
|
{
|
2022-12-28 14:08:09 +00:00
|
|
|
|
auto old_pos = pos;
|
2022-08-12 19:20:17 +00:00
|
|
|
|
SubqueryFunctionType subquery_function_type = SubqueryFunctionType::NONE;
|
2019-10-09 13:02:05 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
if (any_parser.ignore(pos, expected) && subquery_parser.parse(pos, tmp, expected))
|
|
|
|
|
subquery_function_type = SubqueryFunctionType::ANY;
|
|
|
|
|
else if (all_parser.ignore(pos, expected) && subquery_parser.parse(pos, tmp, expected))
|
|
|
|
|
subquery_function_type = SubqueryFunctionType::ALL;
|
2019-10-09 13:02:05 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
if (subquery_function_type != SubqueryFunctionType::NONE)
|
|
|
|
|
{
|
|
|
|
|
Operator prev_op;
|
|
|
|
|
ASTPtr function, argument;
|
2016-07-18 16:12:29 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
if (!layers.back()->popOperator(prev_op))
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::NONE;
|
2022-08-12 19:20:17 +00:00
|
|
|
|
if (!layers.back()->popOperand(argument))
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::NONE;
|
2016-07-18 16:12:29 +00:00
|
|
|
|
|
2022-10-04 18:43:33 +00:00
|
|
|
|
function = makeASTFunction(prev_op, argument, tmp);
|
2022-08-04 09:32:14 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
if (!modifyAST(function, subquery_function_type))
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::NONE;
|
2022-08-04 09:32:14 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
layers.back()->pushOperand(std::move(function));
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::OPERATOR;
|
2022-08-12 19:20:17 +00:00
|
|
|
|
}
|
2022-12-28 14:08:09 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pos = old_pos;
|
|
|
|
|
}
|
2022-08-12 19:20:17 +00:00
|
|
|
|
}
|
2022-08-04 09:32:14 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
/// Try to find any unary operators
|
2022-09-05 16:21:16 +00:00
|
|
|
|
auto cur_op = unary_operators_table.begin();
|
|
|
|
|
for (; cur_op != unary_operators_table.end(); ++cur_op)
|
2022-08-12 19:20:17 +00:00
|
|
|
|
{
|
|
|
|
|
if (parseOperator(pos, cur_op->first, expected))
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-08-04 09:32:14 +00:00
|
|
|
|
|
2022-09-05 16:21:16 +00:00
|
|
|
|
if (cur_op != unary_operators_table.end())
|
2022-08-12 19:20:17 +00:00
|
|
|
|
{
|
|
|
|
|
layers.back()->pushOperator(cur_op->second);
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::OPERAND;
|
2022-08-12 19:20:17 +00:00
|
|
|
|
}
|
2022-08-04 09:32:14 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
auto old_pos = pos;
|
2022-09-07 01:45:13 +00:00
|
|
|
|
auto current_checkpoint = layers.back()->current_checkpoint;
|
|
|
|
|
layers.back()->current_checkpoint = Checkpoint::None;
|
|
|
|
|
|
|
|
|
|
if (current_checkpoint != Checkpoint::Interval && parseOperator(pos, "INTERVAL", expected))
|
2022-08-12 19:20:17 +00:00
|
|
|
|
{
|
2022-09-07 01:45:13 +00:00
|
|
|
|
layers.back()->saved_checkpoint = {old_pos, Checkpoint::Interval};
|
2022-09-05 16:21:16 +00:00
|
|
|
|
layers.push_back(std::make_unique<IntervalLayer>());
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::OPERAND;
|
2022-09-05 16:21:16 +00:00
|
|
|
|
}
|
2022-09-07 01:45:13 +00:00
|
|
|
|
else if (current_checkpoint != Checkpoint::Case && parseOperator(pos, "CASE", expected))
|
2022-09-05 16:21:16 +00:00
|
|
|
|
{
|
2022-09-07 01:45:13 +00:00
|
|
|
|
layers.back()->saved_checkpoint = {old_pos, Checkpoint::Case};
|
2022-09-05 16:21:16 +00:00
|
|
|
|
layers.push_back(std::make_unique<CaseLayer>());
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::OPERAND;
|
2022-09-05 16:21:16 +00:00
|
|
|
|
}
|
2016-07-18 16:12:29 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
if (ParseDateOperatorExpression(pos, tmp, expected) ||
|
|
|
|
|
ParseTimestampOperatorExpression(pos, tmp, expected) ||
|
|
|
|
|
tuple_literal_parser.parse(pos, tmp, expected) ||
|
2022-09-09 18:40:39 +00:00
|
|
|
|
array_literal_parser.parse(pos, tmp, expected) ||
|
2022-08-12 19:20:17 +00:00
|
|
|
|
number_parser.parse(pos, tmp, expected) ||
|
|
|
|
|
literal_parser.parse(pos, tmp, expected) ||
|
|
|
|
|
asterisk_parser.parse(pos, tmp, expected) ||
|
|
|
|
|
qualified_asterisk_parser.parse(pos, tmp, expected) ||
|
2022-10-04 18:43:33 +00:00
|
|
|
|
columns_matcher_parser.parse(pos, tmp, expected) ||
|
|
|
|
|
qualified_columns_matcher_parser.parse(pos, tmp, expected))
|
2022-08-12 19:20:17 +00:00
|
|
|
|
{
|
|
|
|
|
layers.back()->pushOperand(std::move(tmp));
|
|
|
|
|
}
|
|
|
|
|
else if (identifier_parser.parse(pos, tmp, expected))
|
|
|
|
|
{
|
|
|
|
|
if (pos->type == TokenType::OpeningRoundBracket)
|
|
|
|
|
{
|
|
|
|
|
++pos;
|
2022-09-13 20:31:08 +00:00
|
|
|
|
layers.push_back(getFunctionLayer(tmp, layers.front()->is_table_function));
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::OPERAND;
|
2022-08-12 19:20:17 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
layers.back()->pushOperand(std::move(tmp));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (substitution_parser.parse(pos, tmp, expected))
|
|
|
|
|
{
|
|
|
|
|
layers.back()->pushOperand(std::move(tmp));
|
|
|
|
|
}
|
|
|
|
|
else if (pos->type == TokenType::OpeningRoundBracket)
|
|
|
|
|
{
|
2022-10-19 20:04:42 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
if (subquery_parser.parse(pos, tmp, expected))
|
|
|
|
|
{
|
|
|
|
|
layers.back()->pushOperand(std::move(tmp));
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::OPERATOR;
|
2022-08-12 19:20:17 +00:00
|
|
|
|
}
|
2020-03-17 21:56:47 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
++pos;
|
|
|
|
|
layers.push_back(std::make_unique<RoundBracketsLayer>());
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::OPERAND;
|
2022-08-12 19:20:17 +00:00
|
|
|
|
}
|
|
|
|
|
else if (pos->type == TokenType::OpeningSquareBracket)
|
|
|
|
|
{
|
|
|
|
|
++pos;
|
|
|
|
|
layers.push_back(std::make_unique<ArrayLayer>());
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::OPERAND;
|
2022-08-12 19:20:17 +00:00
|
|
|
|
}
|
|
|
|
|
else if (mysql_global_variable_parser.parse(pos, tmp, expected))
|
|
|
|
|
{
|
|
|
|
|
layers.back()->pushOperand(std::move(tmp));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::NONE;
|
2022-08-12 19:20:17 +00:00
|
|
|
|
}
|
2022-08-04 09:32:14 +00:00
|
|
|
|
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::OPERATOR;
|
2022-08-12 19:20:17 +00:00
|
|
|
|
}
|
2022-08-04 09:32:14 +00:00
|
|
|
|
|
2022-09-15 21:54:37 +00:00
|
|
|
|
Action ParserExpressionImpl::tryParseOperator(Layers & layers, IParser::Pos & pos, Expected & expected)
|
2022-08-12 19:20:17 +00:00
|
|
|
|
{
|
|
|
|
|
/// ParserExpression can be called in this part of the query:
|
|
|
|
|
/// ALTER TABLE partition_all2 CLEAR INDEX [ p ] IN PARTITION ALL
|
|
|
|
|
///
|
|
|
|
|
/// 'IN PARTITION' here is not an 'IN' operator, so we should stop parsing immediately
|
|
|
|
|
Expected stub;
|
2023-04-06 16:20:34 +00:00
|
|
|
|
for (const auto & it : overlapping_operators_to_skip)
|
|
|
|
|
if (ParserKeyword{it}.checkWithoutMoving(pos, stub))
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::NONE;
|
2020-03-17 21:56:47 +00:00
|
|
|
|
|
2022-09-05 16:21:16 +00:00
|
|
|
|
/// Try to find operators from 'operators_table'
|
|
|
|
|
auto cur_op = operators_table.begin();
|
|
|
|
|
for (; cur_op != operators_table.end(); ++cur_op)
|
2022-08-12 19:20:17 +00:00
|
|
|
|
{
|
2022-09-07 21:41:37 +00:00
|
|
|
|
if (parseOperator(pos, cur_op->first, expected))
|
2022-08-12 19:20:17 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
2020-03-17 21:56:47 +00:00
|
|
|
|
|
2022-09-05 16:21:16 +00:00
|
|
|
|
if (cur_op == operators_table.end())
|
2022-08-12 19:20:17 +00:00
|
|
|
|
{
|
2023-04-05 18:08:56 +00:00
|
|
|
|
if (!layers.back()->allow_alias || layers.back()->parsed_alias)
|
|
|
|
|
return Action::NONE;
|
|
|
|
|
|
2022-11-02 06:11:37 +00:00
|
|
|
|
ASTPtr alias;
|
2022-10-21 00:16:24 +00:00
|
|
|
|
ParserAlias alias_parser(layers.back()->allow_alias_without_as_keyword);
|
2022-11-02 06:11:37 +00:00
|
|
|
|
|
2023-04-05 18:08:56 +00:00
|
|
|
|
if (!alias_parser.parse(pos, alias, expected) || !layers.back()->insertAlias(alias))
|
|
|
|
|
return Action::NONE;
|
|
|
|
|
|
|
|
|
|
layers.back()->parsed_alias = true;
|
|
|
|
|
return Action::OPERATOR;
|
2022-08-12 19:20:17 +00:00
|
|
|
|
}
|
2020-03-17 21:56:47 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
auto op = cur_op->second;
|
2020-03-17 21:56:47 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
if (op.type == OperatorType::Lambda)
|
|
|
|
|
{
|
|
|
|
|
if (!layers.back()->parseLambda())
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::NONE;
|
2020-03-17 21:56:47 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
layers.back()->pushOperator(op);
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::OPERAND;
|
2022-08-12 19:20:17 +00:00
|
|
|
|
}
|
2020-03-17 21:56:47 +00:00
|
|
|
|
|
2022-09-05 16:21:16 +00:00
|
|
|
|
/// 'AND' can be both boolean function and part of the '... BETWEEN ... AND ...' operator
|
2022-08-12 19:20:17 +00:00
|
|
|
|
if (op.function_name == "and" && layers.back()->between_counter)
|
|
|
|
|
{
|
|
|
|
|
layers.back()->between_counter--;
|
|
|
|
|
op = finish_between_operator;
|
|
|
|
|
}
|
2020-03-17 21:56:47 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
while (layers.back()->previousPriority() >= op.priority)
|
|
|
|
|
{
|
|
|
|
|
ASTPtr function;
|
|
|
|
|
Operator prev_op;
|
|
|
|
|
layers.back()->popOperator(prev_op);
|
2020-03-17 21:56:47 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
/// Mergeable operators are operators that are merged into one function:
|
|
|
|
|
/// For example: 'a OR b OR c' -> 'or(a, b, c)' and not 'or(or(a,b), c)'
|
|
|
|
|
if (prev_op.type == OperatorType::Mergeable && op.function_name == prev_op.function_name)
|
|
|
|
|
{
|
|
|
|
|
op.arity += prev_op.arity - 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-03-17 21:56:47 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
if (prev_op.type == OperatorType::FinishBetween)
|
|
|
|
|
{
|
|
|
|
|
Operator tmp_op;
|
|
|
|
|
if (!layers.back()->popOperator(tmp_op))
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::NONE;
|
2020-03-17 21:56:47 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
if (tmp_op.type != OperatorType::StartBetween && tmp_op.type != OperatorType::StartNotBetween)
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::NONE;
|
2016-07-18 16:12:29 +00:00
|
|
|
|
|
2022-08-12 19:20:17 +00:00
|
|
|
|
bool negative = tmp_op.type == OperatorType::StartNotBetween;
|
|
|
|
|
|
|
|
|
|
ASTs arguments;
|
|
|
|
|
if (!layers.back()->popLastNOperands(arguments, 3))
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::NONE;
|
2022-08-12 19:20:17 +00:00
|
|
|
|
|
|
|
|
|
function = makeBetweenOperator(negative, arguments);
|
2020-10-14 15:02:51 +00:00
|
|
|
|
}
|
2022-08-12 19:20:17 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
2022-10-04 18:43:33 +00:00
|
|
|
|
function = makeASTFunction(prev_op);
|
2022-08-12 19:20:17 +00:00
|
|
|
|
|
|
|
|
|
if (!layers.back()->popLastNOperands(function->children[0]->children, prev_op.arity))
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::NONE;
|
2022-08-12 19:20:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
layers.back()->pushOperand(function);
|
2020-10-14 15:02:51 +00:00
|
|
|
|
}
|
2022-09-15 21:54:37 +00:00
|
|
|
|
|
2022-11-02 06:11:37 +00:00
|
|
|
|
/// Dot (TupleElement operator) can be a beginning of a .* or .COLUMNS expressions
|
|
|
|
|
if (op.type == OperatorType::TupleElement)
|
|
|
|
|
{
|
|
|
|
|
ASTPtr tmp;
|
|
|
|
|
if (asterisk_parser.parse(pos, tmp, expected) ||
|
|
|
|
|
columns_matcher_parser.parse(pos, tmp, expected))
|
|
|
|
|
{
|
|
|
|
|
if (auto * asterisk = tmp->as<ASTAsterisk>())
|
|
|
|
|
{
|
|
|
|
|
if (!layers.back()->popOperand(asterisk->expression))
|
|
|
|
|
return Action::NONE;
|
|
|
|
|
}
|
|
|
|
|
else if (auto * columns_list_matcher = tmp->as<ASTColumnsListMatcher>())
|
|
|
|
|
{
|
|
|
|
|
if (!layers.back()->popOperand(columns_list_matcher->expression))
|
|
|
|
|
return Action::NONE;
|
|
|
|
|
}
|
|
|
|
|
else if (auto * columns_regexp_matcher = tmp->as<ASTColumnsRegexpMatcher>())
|
|
|
|
|
{
|
|
|
|
|
if (!layers.back()->popOperand(columns_regexp_matcher->expression))
|
|
|
|
|
return Action::NONE;
|
|
|
|
|
}
|
2019-10-07 16:23:16 +00:00
|
|
|
|
|
2022-11-02 06:11:37 +00:00
|
|
|
|
layers.back()->pushOperand(std::move(tmp));
|
|
|
|
|
return Action::OPERATOR;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-10-08 09:47:17 +00:00
|
|
|
|
|
2022-09-05 16:21:16 +00:00
|
|
|
|
/// isNull & isNotNull are postfix unary operators
|
2022-08-12 19:20:17 +00:00
|
|
|
|
if (op.type == OperatorType::IsNull)
|
2023-05-30 17:13:28 +00:00
|
|
|
|
{
|
|
|
|
|
ASTPtr function = makeASTFunction(op);
|
|
|
|
|
|
|
|
|
|
if (!layers.back()->popLastNOperands(function->children[0]->children, 1))
|
|
|
|
|
return Action::NONE;
|
|
|
|
|
|
|
|
|
|
layers.back()->pushOperand(std::move(function));
|
2022-11-02 06:11:37 +00:00
|
|
|
|
return Action::OPERATOR;
|
2023-05-30 17:13:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
layers.back()->pushOperator(op);
|
2022-08-12 19:20:17 +00:00
|
|
|
|
|
|
|
|
|
if (op.type == OperatorType::Cast)
|
|
|
|
|
{
|
|
|
|
|
ASTPtr type_ast;
|
|
|
|
|
if (!ParserDataType().parse(pos, type_ast, expected))
|
2022-09-15 21:54:37 +00:00
|
|
|
|
return Action::NONE;
|
2022-08-12 19:20:17 +00:00
|
|
|
|
|
|
|
|
|
layers.back()->pushOperand(std::make_shared<ASTLiteral>(queryToString(type_ast)));
|
2022-11-02 06:11:37 +00:00
|
|
|
|
return Action::OPERATOR;
|
2022-08-12 19:20:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-02 06:11:37 +00:00
|
|
|
|
if (op.type == OperatorType::ArrayElement)
|
|
|
|
|
layers.push_back(std::make_unique<ArrayElementLayer>());
|
|
|
|
|
|
|
|
|
|
if (op.type == OperatorType::StartBetween || op.type == OperatorType::StartNotBetween)
|
|
|
|
|
layers.back()->between_counter++;
|
|
|
|
|
|
|
|
|
|
return Action::OPERAND;
|
2019-10-07 16:23:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
}
|