Kusto-phase2: add kusto_auto dialect

This commit is contained in:
Yong Wang 2022-06-23 14:26:37 -07:00
parent 145b2bd45e
commit 760fd6759e
4 changed files with 74 additions and 40 deletions

View File

@ -328,12 +328,15 @@ void ClientBase::setupSignalHandler()
ASTPtr ClientBase::parseQuery(const char *& pos, const char * end, bool allow_multi_statements) const ASTPtr ClientBase::parseQuery(const char *& pos, const char * end, bool allow_multi_statements) const
{ {
std::unique_ptr<IParserBase> parser; std::shared_ptr<IParserBase> parser;
ParserKQLStatement kql_parser(end, global_context->getSettings().allow_settings_after_format_in_insert);
ASTPtr res; ASTPtr res;
const auto & settings = global_context->getSettingsRef(); const auto & settings = global_context->getSettingsRef();
size_t max_length = 0; size_t max_length = 0;
auto begin = pos;
if (!allow_multi_statements) if (!allow_multi_statements)
max_length = settings.max_query_size; max_length = settings.max_query_size;
@ -353,13 +356,22 @@ ASTPtr ClientBase::parseQuery(const char *& pos, const char * end, bool allow_mu
if (!res) if (!res)
{ {
std::cerr << std::endl << message << std::endl << std::endl; if (sql_dialect != "kusto")
return nullptr; res = tryParseQuery(kql_parser, begin, end, message, true, "", allow_multi_statements, max_length, settings.max_parser_depth);
if (!res)
{
std::cerr << std::endl << message << std::endl << std::endl;
return nullptr;
}
} }
} }
else else
{ {
res = parseQueryAndMovePosition(*parser, pos, end, "", allow_multi_statements, max_length, settings.max_parser_depth); res = parseQueryAndMovePosition(*parser, pos, end, "", allow_multi_statements, max_length, settings.max_parser_depth);
if (!res && sql_dialect != "kusto")
res = parseQueryAndMovePosition(kql_parser, begin, end, "", allow_multi_statements, max_length, settings.max_parser_depth);
} }
if (is_interactive) if (is_interactive)

View File

@ -701,12 +701,27 @@ static std::tuple<ASTPtr, BlockIO> executeQueryImpl(
/// Parse the query from string. /// Parse the query from string.
try try
{ {
if (settings.dialect == Dialect::kusto && !internal) const String & sql_dialect = settings.sql_dialect;
assert(sql_dialect == "clickhouse" || sql_dialect == "kusto" || sql_dialect == "kusto_auto");
if (sql_dialect == "kusto" && !internal)
{ {
ParserKQLStatement parser(end, settings.allow_settings_after_format_in_insert); ParserKQLStatement parser(end, settings.allow_settings_after_format_in_insert);
ast = parseQuery(parser, begin, end, "", max_query_size, settings.max_parser_depth);
}
else if (sql_dialect == "kusto_auto" && !internal)
{
try {
ParserQuery parser(end, settings.allow_settings_after_format_in_insert);
/// TODO: parser should fail early when max_query_size limit is reached. /// TODO: parser should fail early when max_query_size limit is reached.
ast = parseQuery(parser, begin, end, "", max_query_size, settings.max_parser_depth); ast = parseQuery(parser, begin, end, "", max_query_size, settings.max_parser_depth);
}
catch(...)
{
ParserKQLStatement parser(end, settings.allow_settings_after_format_in_insert);
ast = parseQuery(parser, begin, end, "", max_query_size, settings.max_parser_depth);
}
} }
else if (settings.dialect == Dialect::prql && !internal) else if (settings.dialect == Dialect::prql && !internal)
{ {

View File

@ -15,6 +15,7 @@
#include <Parsers/Kusto/KustoFunctions/KQLBinaryFunctions.h> #include <Parsers/Kusto/KustoFunctions/KQLBinaryFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLGeneralFunctions.h> #include <Parsers/Kusto/KustoFunctions/KQLGeneralFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLFunctionFactory.h> #include <Parsers/Kusto/KustoFunctions/KQLFunctionFactory.h>
#include <Parsers/Kusto/ParserKQLOperators.h>
namespace DB namespace DB
{ {
@ -38,41 +39,36 @@ bool IParserKQLFunction::convert(String &out,IParser::Pos &pos)
bool IParserKQLFunction::directMapping(String &out,IParser::Pos &pos,const String &ch_fn) bool IParserKQLFunction::directMapping(String &out,IParser::Pos &pos,const String &ch_fn)
{ {
std::unique_ptr<IParserKQLFunction> fun; std::vector<String> arguments;
std::vector<String> args;
String res =ch_fn + "("; String fn_name = getKQLFunctionName(pos);
out = res;
auto begin = pos;
++pos; if (fn_name.empty())
if (pos->type != TokenType::OpeningRoundBracket)
{
pos = begin;
return false; return false;
}
String res;
auto begin = pos;
++pos;
while (!pos->isEnd() && pos->type != TokenType::PipeMark && pos->type != TokenType::Semicolon) while (!pos->isEnd() && pos->type != TokenType::PipeMark && pos->type != TokenType::Semicolon)
{ {
++pos; String argument = getConvertedArgument(fn_name,pos);
String tmp_arg = String(pos->begin,pos->end); arguments.push_back(argument);
if (pos->type == TokenType::BareWord )
{
String new_arg;
fun = KQLFunctionFactory::get(tmp_arg);
if (fun && fun->convert(new_arg,pos))
tmp_arg = new_arg;
}
else if (pos->type == TokenType::ClosingRoundBracket)
{
for (auto arg : args)
res+=arg;
if (pos->type == TokenType::ClosingRoundBracket)
{
for (auto arg : arguments)
{
if (res.empty())
res = ch_fn + "(" + arg;
else
res = res + ", "+ arg;
}
res += ")"; res += ")";
out = res; out = res;
return true; return true;
} }
args.push_back(tmp_arg); ++pos;
} }
pos = begin; pos = begin;
@ -82,6 +78,7 @@ bool IParserKQLFunction::directMapping(String &out,IParser::Pos &pos,const Strin
String IParserKQLFunction::getConvertedArgument(const String &fn_name, IParser::Pos &pos) String IParserKQLFunction::getConvertedArgument(const String &fn_name, IParser::Pos &pos)
{ {
String converted_arg; String converted_arg;
std::vector<String> tokens;
std::unique_ptr<IParserKQLFunction> fun; std::unique_ptr<IParserKQLFunction> fun;
if (pos->type == TokenType::ClosingRoundBracket) if (pos->type == TokenType::ClosingRoundBracket)
@ -93,23 +90,32 @@ String IParserKQLFunction::getConvertedArgument(const String &fn_name, IParser::
while (!pos->isEnd() && pos->type != TokenType::PipeMark && pos->type != TokenType::Semicolon) while (!pos->isEnd() && pos->type != TokenType::PipeMark && pos->type != TokenType::Semicolon)
{ {
String token = String(pos->begin,pos->end); String token = String(pos->begin,pos->end);
if (pos->type == TokenType::BareWord ) String new_token;
if (!KQLOperators().convert(tokens,pos))
{ {
String converted; if (pos->type == TokenType::BareWord )
fun = KQLFunctionFactory::get(token); {
if ( fun && fun->convert(converted,pos)) String converted;
converted_arg += converted; fun = KQLFunctionFactory::get(token);
if ( fun && fun->convert(converted,pos))
tokens.push_back(converted);
else
tokens.push_back(token);
}
else if (pos->type == TokenType::Comma || pos->type == TokenType::ClosingRoundBracket)
{
break;
}
else else
converted_arg += token; tokens.push_back(token);
} }
else if (pos->type == TokenType::Comma ||pos->type == TokenType::ClosingRoundBracket)
{
break;
}
else
converted_arg += token;
++pos; ++pos;
if (pos->type == TokenType::Comma || pos->type == TokenType::ClosingRoundBracket)
break;
} }
for (auto token : tokens)
converted_arg = converted_arg + token +" ";
return converted_arg; return converted_arg;
} }

View File

@ -297,6 +297,7 @@ bool KQLOperators::convert(std::vector<String> &tokens,IParser::Pos &pos)
} }
return true; return true;
} }
pos = begin;
return false; return false;
} }