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
{
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;
const auto & settings = global_context->getSettingsRef();
size_t max_length = 0;
auto begin = pos;
if (!allow_multi_statements)
max_length = settings.max_query_size;
@ -353,13 +356,22 @@ ASTPtr ClientBase::parseQuery(const char *& pos, const char * end, bool allow_mu
if (!res)
{
std::cerr << std::endl << message << std::endl << std::endl;
return nullptr;
if (sql_dialect != "kusto")
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
{
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)

View File

@ -701,12 +701,27 @@ static std::tuple<ASTPtr, BlockIO> executeQueryImpl(
/// Parse the query from string.
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);
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.
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)
{

View File

@ -15,6 +15,7 @@
#include <Parsers/Kusto/KustoFunctions/KQLBinaryFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLGeneralFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLFunctionFactory.h>
#include <Parsers/Kusto/ParserKQLOperators.h>
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)
{
std::unique_ptr<IParserKQLFunction> fun;
std::vector<String> args;
std::vector<String> arguments;
String res =ch_fn + "(";
out = res;
auto begin = pos;
String fn_name = getKQLFunctionName(pos);
++pos;
if (pos->type != TokenType::OpeningRoundBracket)
{
pos = begin;
if (fn_name.empty())
return false;
}
String res;
auto begin = pos;
++pos;
while (!pos->isEnd() && pos->type != TokenType::PipeMark && pos->type != TokenType::Semicolon)
{
++pos;
String tmp_arg = String(pos->begin,pos->end);
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;
String argument = getConvertedArgument(fn_name,pos);
arguments.push_back(argument);
if (pos->type == TokenType::ClosingRoundBracket)
{
for (auto arg : arguments)
{
if (res.empty())
res = ch_fn + "(" + arg;
else
res = res + ", "+ arg;
}
res += ")";
out = res;
return true;
}
args.push_back(tmp_arg);
++pos;
}
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 converted_arg;
std::vector<String> tokens;
std::unique_ptr<IParserKQLFunction> fun;
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)
{
String token = String(pos->begin,pos->end);
if (pos->type == TokenType::BareWord )
String new_token;
if (!KQLOperators().convert(tokens,pos))
{
String converted;
fun = KQLFunctionFactory::get(token);
if ( fun && fun->convert(converted,pos))
converted_arg += converted;
if (pos->type == TokenType::BareWord )
{
String 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
converted_arg += token;
tokens.push_back(token);
}
else if (pos->type == TokenType::Comma ||pos->type == TokenType::ClosingRoundBracket)
{
break;
}
else
converted_arg += token;
++pos;
if (pos->type == TokenType::Comma || pos->type == TokenType::ClosingRoundBracket)
break;
}
for (auto token : tokens)
converted_arg = converted_arg + token +" ";
return converted_arg;
}

View File

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