Fixed style issues

This commit is contained in:
Larry Luo 2023-01-17 13:08:33 -08:00 committed by Yong Wang
parent 6aa084379e
commit 707fd10544
49 changed files with 1803 additions and 1637 deletions

View File

@ -178,7 +178,7 @@ bool ParserSubquery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
bool ParserIdentifier::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
/// 'kql(' is used for subuquery in Kusto, should not be treated as an identifier if kql followd by (
/// 'kql(' is used for subuquery in Kusto, should not be treated as an identifier if kql followed by (
ParserKeyword s_kql("KQL");
if (s_kql.ignore(pos, expected))
{

View File

@ -188,7 +188,7 @@ Please note that functions returning arrays with set semantics may return them i
- [set_has_element](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/sethaselementfunction)
`print set_has_element(dynamic(["this", "is", "an", "example"]), "example") == true`
`print set_has_element(dynamic(["this", "is", "an", "example"]), "examplee") == false`
`print set_has_element(dynamic(["this", "is", "an", "example"]), "test") == false`
`print set_has_element(dynamic([1, 2, 3]), 2) == true`
`print set_has_element(dynamic([1, 2, 3, 4.2]), 4) == false`
@ -709,7 +709,7 @@ https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/make-seriesoper
# August 1, 2022
**The config setting to allow modify dialect setting**.
- Set dialect setting in server configuration XML at user level(` users.xml `). This sets the ` dialect ` at server startup and CH will do query parsing for all users with ` default ` profile acording to dialect value.
- Set dialect setting in server configuration XML at user level(` users.xml `). This sets the ` dialect ` at server startup and CH will do query parsing for all users with ` default ` profile according to dialect value.
For example:
` <profiles>
@ -795,7 +795,7 @@ Please note that the functions listed below only take constant parameters for no
## string functions
- **support subquery for `in` orerator** (https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/in-cs-operator)
(subquery need to be wraped with bracket inside bracket)
(subquery need to be wrapped with bracket inside bracket)
`Customers | where Age in ((Customers|project Age|where Age < 30))`
Note: case-insensitive not supported yet

View File

@ -27,10 +27,10 @@
namespace DB::ErrorCodes
{
extern const int NOT_IMPLEMENTED;
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
extern const int SYNTAX_ERROR;
extern const int UNKNOWN_FUNCTION;
extern const int NOT_IMPLEMENTED;
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
extern const int SYNTAX_ERROR;
extern const int UNKNOWN_FUNCTION;
}
namespace
@ -155,7 +155,9 @@ String IParserKQLFunction::getConvertedArgument(const String & fn_name, IParser:
{
tokens.push_back(IParserKQLFunction::getExpression(pos));
}
else if (pos->type == TokenType::Comma || pos->type == TokenType::ClosingRoundBracket || pos->type == TokenType::ClosingSquareBracket)
else if (
pos->type == TokenType::Comma || pos->type == TokenType::ClosingRoundBracket
|| pos->type == TokenType::ClosingSquareBracket)
{
break;
}
@ -163,7 +165,7 @@ String IParserKQLFunction::getConvertedArgument(const String & fn_name, IParser:
{
String token;
if (pos->type == TokenType::QuotedIdentifier)
token = "'" + String(pos->begin + 1,pos->end - 1) + "'";
token = "'" + String(pos->begin + 1, pos->end - 1) + "'";
else if (pos->type == TokenType::OpeningSquareBracket)
{
++pos;
@ -186,7 +188,7 @@ String IParserKQLFunction::getConvertedArgument(const String & fn_name, IParser:
break;
}
for (auto token : tokens)
converted_arg = converted_arg.empty() ? token : converted_arg + " " + token ;
converted_arg = converted_arg.empty() ? token : converted_arg + " " + token;
return converted_arg;
}
@ -321,7 +323,7 @@ String IParserKQLFunction::getExpression(IParser::Pos & pos)
}
}
else if (pos->type == TokenType::QuotedIdentifier)
arg = "'" + String(pos->begin + 1,pos->end - 1) + "'";
arg = "'" + String(pos->begin + 1, pos->end - 1) + "'";
else if (pos->type == TokenType::OpeningSquareBracket)
{
++pos;
@ -337,16 +339,17 @@ String IParserKQLFunction::getExpression(IParser::Pos & pos)
return arg;
}
int IParserKQLFunction::getNullCounts(String arg){
int IParserKQLFunction::getNullCounts(String arg)
{
size_t index = 0;
int nullCounts = 0;
for(size_t i = 0; i < arg.size(); i++)
for (size_t i = 0; i < arg.size(); i++)
{
if(arg[i] == 'n')
if (arg[i] == 'n')
arg[i] = 'N';
if(arg[i] == 'u')
if (arg[i] == 'u')
arg[i] = 'U';
if(arg[i] == 'l')
if (arg[i] == 'l')
arg[i] = 'L';
}
while ((index = arg.find("NULL", index)) != std::string::npos)
@ -361,9 +364,9 @@ int IParserKQLFunction::IParserKQLFunction::getArrayLength(String arg)
{
int array_length = 0;
bool comma_found = false;
for(size_t i = 0; i < arg.size(); i++)
for (size_t i = 0; i < arg.size(); i++)
{
if(arg[i] == ',')
if (arg[i] == ',')
{
comma_found = true;
array_length += 1;
@ -372,7 +375,7 @@ int IParserKQLFunction::IParserKQLFunction::getArrayLength(String arg)
return comma_found ? array_length + 1 : 0;
}
String IParserKQLFunction::ArraySortHelper(String & out,IParser::Pos & pos, bool ascending)
String IParserKQLFunction::ArraySortHelper(String & out, IParser::Pos & pos, bool ascending)
{
String fn_name = getKQLFunctionName(pos);
if (fn_name.empty())
@ -382,29 +385,30 @@ String IParserKQLFunction::ArraySortHelper(String & out,IParser::Pos & pos, bool
String second_arg;
String expr;
if(!ascending)
if (!ascending)
reverse = "Reverse";
++pos;
String first_arg = getConvertedArgument(fn_name, pos);
int nullCount = getNullCounts(first_arg);
if(pos->type == TokenType::Comma)
if (pos->type == TokenType::Comma)
++pos;
out = "array( ";
if(pos->type != TokenType::ClosingRoundBracket && String(pos->begin, pos->end) != "dynamic")
if (pos->type != TokenType::ClosingRoundBracket && String(pos->begin, pos->end) != "dynamic")
{
second_arg = getConvertedArgument(fn_name, pos);
out += "if (" + second_arg + ", array" + reverse + "Sort(" + first_arg + "), concat( arraySlice(array" + reverse + "Sort(" + first_arg + ") as as1, indexOf(as1, NULL) as len1 ), arraySlice( as1, 1, len1-1)))";
out += "if (" + second_arg + ", array" + reverse + "Sort(" + first_arg + "), concat( arraySlice(array" + reverse + "Sort("
+ first_arg + ") as as1, indexOf(as1, NULL) as len1 ), arraySlice( as1, 1, len1-1)))";
out += " )";
return out;
}
--pos;
std::vector<String> argument_list;
if(pos->type != TokenType::ClosingRoundBracket)
if (pos->type != TokenType::ClosingRoundBracket)
{
while(pos->type != TokenType::ClosingRoundBracket)
while (pos->type != TokenType::ClosingRoundBracket)
{
++pos;
if(String(pos->begin, pos->end) != "dynamic")
if (String(pos->begin, pos->end) != "dynamic")
{
expr = getConvertedArgument(fn_name, pos);
break;
@ -416,30 +420,35 @@ String IParserKQLFunction::ArraySortHelper(String & out,IParser::Pos & pos, bool
else
{
++pos;
out += "array"+ reverse +"Sort(" + first_arg + ")";
out += "array" + reverse + "Sort(" + first_arg + ")";
}
if(argument_list.size() > 0)
if (argument_list.size() > 0)
{
String temp_first_arg = first_arg;
int first_arg_length = getArrayLength(temp_first_arg);
if(nullCount > 0 && expr.empty())
if (nullCount > 0 && expr.empty())
expr = "true";
if(nullCount > 0)
first_arg = "if (" + expr + ", array" + reverse + "Sort(" + first_arg + "), concat( arraySlice(array" + reverse + "Sort(" + first_arg + ") as as1, indexOf(as1, NULL) as len1 ), arraySlice( as1, 1, len1-1) ) )";
if (nullCount > 0)
first_arg = "if (" + expr + ", array" + reverse + "Sort(" + first_arg + "), concat( arraySlice(array" + reverse + "Sort("
+ first_arg + ") as as1, indexOf(as1, NULL) as len1 ), arraySlice( as1, 1, len1-1) ) )";
else
first_arg = "array" + reverse + "Sort(" + first_arg + ")";
out += first_arg;
for(size_t i = 0; i < argument_list.size(); i++)
for (size_t i = 0; i < argument_list.size(); i++)
{
out += " , ";
if(first_arg_length != getArrayLength(argument_list[i]))
if (first_arg_length != getArrayLength(argument_list[i]))
out += "array(NULL)";
else if(nullCount > 0)
out += "If ( " + expr + "," + "array" + reverse + "Sort((x, y) -> y, " + argument_list[i] + "," + temp_first_arg + "), arrayConcat( arraySlice( " + "array" + reverse + "Sort((x, y) -> y, " + argument_list[i] + "," + temp_first_arg + ") , length(" + temp_first_arg + ") - " + std::to_string(nullCount) + " + 1) , arraySlice( " + "array" + reverse + "Sort((x, y) -> y, " + argument_list[i] + "," + temp_first_arg + ") , 1, length( " + temp_first_arg + ") - " + std::to_string(nullCount) + ") ) )";
else if (nullCount > 0)
out += "If ( " + expr + "," + "array" + reverse + "Sort((x, y) -> y, " + argument_list[i] + "," + temp_first_arg
+ "), arrayConcat( arraySlice( " + "array" + reverse + "Sort((x, y) -> y, " + argument_list[i] + "," + temp_first_arg
+ ") , length(" + temp_first_arg + ") - " + std::to_string(nullCount) + " + 1) , arraySlice( " + "array" + reverse
+ "Sort((x, y) -> y, " + argument_list[i] + "," + temp_first_arg + ") , 1, length( " + temp_first_arg + ") - "
+ std::to_string(nullCount) + ") ) )";
else
out += "array" + reverse + "Sort((x, y) -> y, " + argument_list[i] + "," + temp_first_arg + ")";
}

View File

@ -1,226 +1,231 @@
#include <Parsers/IParserBase.h>
#include <Parsers/ParserSetQuery.h>
#include <Parsers/ASTExpressionList.h>
#include <Parsers/ASTSelectWithUnionQuery.h>
#include <Parsers/IParserBase.h>
#include <Parsers/Kusto/KustoFunctions/IParserKQLFunction.h>
#include <Parsers/Kusto/KustoFunctions/KQLAggregationFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLBinaryFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLCastingFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLDateTimeFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLDynamicFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLGeneralFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLIPFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLStringFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLTimeSeriesFunctions.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLStatement.h>
#include <Parsers/Kusto/KustoFunctions/IParserKQLFunction.h>
#include <Parsers/Kusto/KustoFunctions/KQLDateTimeFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLStringFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLDynamicFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLCastingFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLAggregationFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLTimeSeriesFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLIPFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLBinaryFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLGeneralFunctions.h>
#include <Parsers/ParserSetQuery.h>
#include <Common/StringUtils/StringUtils.h>
namespace DB
{
bool ArgMax::convertImpl(String & out,IParser::Pos & pos)
bool ArgMax::convertImpl(String & out, IParser::Pos & pos)
{
return directMapping(out,pos,"argMax");
return directMapping(out, pos, "argMax");
}
bool ArgMin::convertImpl(String & out,IParser::Pos & pos)
bool ArgMin::convertImpl(String & out, IParser::Pos & pos)
{
return directMapping(out,pos,"argMin");
return directMapping(out, pos, "argMin");
}
bool Avg::convertImpl(String & out,IParser::Pos & pos)
bool Avg::convertImpl(String & out, IParser::Pos & pos)
{
return directMapping(out,pos,"avg");
return directMapping(out, pos, "avg");
}
bool AvgIf::convertImpl(String & out,IParser::Pos & pos)
bool AvgIf::convertImpl(String & out, IParser::Pos & pos)
{
return directMapping(out,pos,"avgIf");
return directMapping(out, pos, "avgIf");
}
bool BinaryAllAnd::convertImpl(String & out,IParser::Pos & pos)
bool BinaryAllAnd::convertImpl(String & out, IParser::Pos & pos)
{
return directMapping(out,pos,"groupBitAnd");
return directMapping(out, pos, "groupBitAnd");
}
bool BinaryAllOr::convertImpl(String & out,IParser::Pos & pos)
bool BinaryAllOr::convertImpl(String & out, IParser::Pos & pos)
{
return directMapping(out,pos,"groupBitOr");
return directMapping(out, pos, "groupBitOr");
}
bool BinaryAllXor::convertImpl(String & out,IParser::Pos & pos)
bool BinaryAllXor::convertImpl(String & out, IParser::Pos & pos)
{
return directMapping(out,pos,"groupBitXor");
return directMapping(out, pos, "groupBitXor");
}
bool BuildSchema::convertImpl(String & out,IParser::Pos & pos)
bool BuildSchema::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool Count::convertImpl(String & out,IParser::Pos & pos)
bool Count::convertImpl(String & out, IParser::Pos & pos)
{
return directMapping(out,pos,"count");
return directMapping(out, pos, "count");
}
bool CountIf::convertImpl(String & out,IParser::Pos & pos)
bool CountIf::convertImpl(String & out, IParser::Pos & pos)
{
return directMapping(out,pos,"countIf");
return directMapping(out, pos, "countIf");
}
bool DCount::convertImpl(String & out,IParser::Pos & pos)
bool DCount::convertImpl(String & out, IParser::Pos & pos)
{
String fn_name = getKQLFunctionName(pos);
if (fn_name.empty())
return false;
++pos;
String value = getConvertedArgument(fn_name,pos);
String value = getConvertedArgument(fn_name, pos);
out = "count ( DISTINCT " + value + " ) ";
return true;
}
bool DCountIf::convertImpl(String & out,IParser::Pos & pos)
bool DCountIf::convertImpl(String & out, IParser::Pos & pos)
{
String fn_name = getKQLFunctionName(pos);
if (fn_name.empty())
return false;
++pos;
String value = getConvertedArgument(fn_name,pos);
String value = getConvertedArgument(fn_name, pos);
++pos;
String condition = getConvertedArgument(fn_name,pos);
String condition = getConvertedArgument(fn_name, pos);
out = "countIf ( DISTINCT " + value + " , " + condition + " ) ";
return true;
}
bool MakeBag::convertImpl(String & out,IParser::Pos & pos)
bool MakeBag::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool MakeBagIf::convertImpl(String & out,IParser::Pos & pos)
bool MakeBagIf::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool MakeList::convertImpl(String & out,IParser::Pos & pos)
bool MakeList::convertImpl(String & out, IParser::Pos & pos)
{
String fn_name = getKQLFunctionName(pos);
if (fn_name.empty())
return false;
++pos;
const auto expr = getConvertedArgument(fn_name,pos);
const auto expr = getConvertedArgument(fn_name, pos);
if (pos->type == TokenType::Comma)
{
++pos;
const auto max_size = getConvertedArgument(fn_name,pos);
const auto max_size = getConvertedArgument(fn_name, pos);
out = "groupArrayIf(" + max_size + ")(" + expr + " , " + expr + " IS NOT NULL)";
} else
}
else
out = "groupArrayIf(" + expr + " , " + expr + " IS NOT NULL)";
return true;
}
bool MakeListIf::convertImpl(String & out,IParser::Pos & pos)
bool MakeListIf::convertImpl(String & out, IParser::Pos & pos)
{
String fn_name = getKQLFunctionName(pos);
if (fn_name.empty())
return false;
++pos;
const auto expr = getConvertedArgument(fn_name,pos);
const auto expr = getConvertedArgument(fn_name, pos);
++pos;
const auto predicate = getConvertedArgument(fn_name,pos);
const auto predicate = getConvertedArgument(fn_name, pos);
if (pos->type == TokenType::Comma)
{
++pos;
const auto max_size = getConvertedArgument(fn_name,pos);
out = "groupArrayIf(" + max_size + ")(" + expr + " , " + predicate+ " )";
} else
out = "groupArrayIf(" + expr + " , " + predicate+ " )";
const auto max_size = getConvertedArgument(fn_name, pos);
out = "groupArrayIf(" + max_size + ")(" + expr + " , " + predicate + " )";
}
else
out = "groupArrayIf(" + expr + " , " + predicate + " )";
return true;
}
bool MakeListWithNulls::convertImpl(String & out,IParser::Pos & pos)
bool MakeListWithNulls::convertImpl(String & out, IParser::Pos & pos)
{
String fn_name = getKQLFunctionName(pos);
if (fn_name.empty())
return false;
++pos;
const auto column_name = getConvertedArgument(fn_name,pos);
out = "arrayConcat(groupArray(" + column_name + "), arrayMap(x -> null, range(0, toUInt32(count(*)-length( groupArray(" + column_name + ") )),1)))";
const auto column_name = getConvertedArgument(fn_name, pos);
out = "arrayConcat(groupArray(" + column_name + "), arrayMap(x -> null, range(0, toUInt32(count(*)-length( groupArray(" + column_name
+ ") )),1)))";
return true;
}
bool MakeSet::convertImpl(String & out,IParser::Pos & pos)
bool MakeSet::convertImpl(String & out, IParser::Pos & pos)
{
String fn_name = getKQLFunctionName(pos);
if (fn_name.empty())
return false;
++pos;
const auto expr = getConvertedArgument(fn_name,pos);
const auto expr = getConvertedArgument(fn_name, pos);
if (pos->type == TokenType::Comma)
{
++pos;
const auto max_size = getConvertedArgument(fn_name,pos);
const auto max_size = getConvertedArgument(fn_name, pos);
out = "groupUniqArray(" + max_size + ")(" + expr + ")";
} else
}
else
out = "groupUniqArray(" + expr + ")";
return true;
}
bool MakeSetIf::convertImpl(String & out,IParser::Pos & pos)
bool MakeSetIf::convertImpl(String & out, IParser::Pos & pos)
{
String fn_name = getKQLFunctionName(pos);
if (fn_name.empty())
return false;
++pos;
const auto expr = getConvertedArgument(fn_name,pos);
const auto expr = getConvertedArgument(fn_name, pos);
++pos;
const auto predicate = getConvertedArgument(fn_name,pos);
const auto predicate = getConvertedArgument(fn_name, pos);
if (pos->type == TokenType::Comma)
{
++pos;
const auto max_size = getConvertedArgument(fn_name,pos);
out = "groupUniqArrayIf(" + max_size + ")(" + expr + " , " + predicate+ " )";
} else
out = "groupUniqArrayIf(" + expr + " , " + predicate+ " )";
const auto max_size = getConvertedArgument(fn_name, pos);
out = "groupUniqArrayIf(" + max_size + ")(" + expr + " , " + predicate + " )";
}
else
out = "groupUniqArrayIf(" + expr + " , " + predicate + " )";
return true;
}
bool Max::convertImpl(String & out,IParser::Pos & pos)
bool Max::convertImpl(String & out, IParser::Pos & pos)
{
return directMapping(out,pos,"max");
return directMapping(out, pos, "max");
}
bool MaxIf::convertImpl(String & out,IParser::Pos & pos)
bool MaxIf::convertImpl(String & out, IParser::Pos & pos)
{
return directMapping(out,pos,"maxIf");
return directMapping(out, pos, "maxIf");
}
bool Min::convertImpl(String & out,IParser::Pos & pos)
bool Min::convertImpl(String & out, IParser::Pos & pos)
{
return directMapping(out,pos,"min");
return directMapping(out, pos, "min");
}
bool MinIf::convertImpl(String & out,IParser::Pos & pos)
bool MinIf::convertImpl(String & out, IParser::Pos & pos)
{
return directMapping(out,pos,"minIf");
return directMapping(out, pos, "minIf");
}
bool Percentile::convertImpl(String & out,IParser::Pos & pos)
bool Percentile::convertImpl(String & out, IParser::Pos & pos)
{
String fn_name = getKQLFunctionName(pos);
@ -228,18 +233,18 @@ bool Percentile::convertImpl(String & out,IParser::Pos & pos)
return false;
++pos;
String column_name = getConvertedArgument(fn_name,pos);
String column_name = getConvertedArgument(fn_name, pos);
trim(column_name);
++pos;
String value = getConvertedArgument(fn_name,pos);
String value = getConvertedArgument(fn_name, pos);
trim(value);
out = "quantile(" + value + "/100)(" + column_name + ")";
return true;
}
bool Percentilew::convertImpl(String & out,IParser::Pos & pos)
bool Percentilew::convertImpl(String & out, IParser::Pos & pos)
{
String fn_name = getKQLFunctionName(pos);
@ -247,22 +252,22 @@ bool Percentilew::convertImpl(String & out,IParser::Pos & pos)
return false;
++pos;
String bucket_column = getConvertedArgument(fn_name,pos);
String bucket_column = getConvertedArgument(fn_name, pos);
trim(bucket_column);
++pos;
String frequency_column = getConvertedArgument(fn_name,pos);
String frequency_column = getConvertedArgument(fn_name, pos);
trim(frequency_column);
++pos;
String value = getConvertedArgument(fn_name,pos);
String value = getConvertedArgument(fn_name, pos);
trim(value);
out = "quantileExactWeighted( " + value + "/100)(" + bucket_column + "," + frequency_column + ")";
return true;
}
bool Percentiles::convertImpl(String & out,IParser::Pos & pos)
bool Percentiles::convertImpl(String & out, IParser::Pos & pos)
{
String fn_name = getKQLFunctionName(pos);
@ -270,18 +275,18 @@ bool Percentiles::convertImpl(String & out,IParser::Pos & pos)
return false;
++pos;
String column_name = getConvertedArgument(fn_name,pos);
String column_name = getConvertedArgument(fn_name, pos);
trim(column_name);
String expr = "quantiles(";
String value;
while(pos->type != TokenType::ClosingRoundBracket)
while (pos->type != TokenType::ClosingRoundBracket)
{
if(pos->type != TokenType::Comma)
if (pos->type != TokenType::Comma)
{
value = String(pos->begin, pos->end);
expr = expr + value + "/100";
++pos;
if(pos->type != TokenType::ClosingRoundBracket)
if (pos->type != TokenType::ClosingRoundBracket)
expr += ", ";
}
else
@ -291,7 +296,7 @@ bool Percentiles::convertImpl(String & out,IParser::Pos & pos)
return true;
}
bool PercentilesArray::convertImpl(String & out,IParser::Pos & pos)
bool PercentilesArray::convertImpl(String & out, IParser::Pos & pos)
{
String fn_name = getKQLFunctionName(pos);
@ -299,20 +304,19 @@ bool PercentilesArray::convertImpl(String & out,IParser::Pos & pos)
return false;
++pos;
String column_name = getConvertedArgument(fn_name,pos);
String column_name = getConvertedArgument(fn_name, pos);
trim(column_name);
String expr = "quantiles(";
String value;
while(pos->type != TokenType::ClosingRoundBracket)
while (pos->type != TokenType::ClosingRoundBracket)
{
if (pos->type != TokenType::Comma && String(pos->begin, pos->end) != "dynamic" && pos->type != TokenType::OpeningRoundBracket
&& pos->type != TokenType::OpeningSquareBracket && pos->type != TokenType::ClosingSquareBracket)
{
if(pos->type != TokenType::Comma && String(pos->begin, pos->end) != "dynamic"
&& pos->type != TokenType::OpeningRoundBracket && pos->type != TokenType::OpeningSquareBracket
&& pos->type != TokenType::ClosingSquareBracket){
value = String(pos->begin, pos->end);
expr = expr + value + "/100";
if(pos->type != TokenType::Comma && pos->type != TokenType::OpeningRoundBracket && pos->type != TokenType::OpeningSquareBracket
if (pos->type != TokenType::Comma && pos->type != TokenType::OpeningRoundBracket && pos->type != TokenType::OpeningSquareBracket
&& pos->type != TokenType::ClosingSquareBracket)
expr += ", ";
++pos;
@ -321,10 +325,9 @@ bool PercentilesArray::convertImpl(String & out,IParser::Pos & pos)
{
++pos;
}
}
++pos;
if(pos->type != TokenType::ClosingRoundBracket)
if (pos->type != TokenType::ClosingRoundBracket)
--pos;
expr.pop_back();
@ -334,7 +337,7 @@ bool PercentilesArray::convertImpl(String & out,IParser::Pos & pos)
return true;
}
bool Percentilesw::convertImpl(String & out,IParser::Pos & pos)
bool Percentilesw::convertImpl(String & out, IParser::Pos & pos)
{
String fn_name = getKQLFunctionName(pos);
@ -342,24 +345,24 @@ bool Percentilesw::convertImpl(String & out,IParser::Pos & pos)
return false;
++pos;
String bucket_column = getConvertedArgument(fn_name,pos);
String bucket_column = getConvertedArgument(fn_name, pos);
trim(bucket_column);
++pos;
String frequency_column = getConvertedArgument(fn_name,pos);
String frequency_column = getConvertedArgument(fn_name, pos);
trim(frequency_column);
String expr = "quantilesExactWeighted( ";
String value;
while(pos->type != TokenType::ClosingRoundBracket)
while (pos->type != TokenType::ClosingRoundBracket)
{
if(pos->type != TokenType::Comma)
if (pos->type != TokenType::Comma)
{
value = String(pos->begin, pos->end);
expr = expr + value + "/100";
++pos;
if(pos->type != TokenType::ClosingRoundBracket)
if (pos->type != TokenType::ClosingRoundBracket)
expr += ", ";
}
else
@ -370,7 +373,7 @@ bool Percentilesw::convertImpl(String & out,IParser::Pos & pos)
return true;
}
bool PercentileswArray::convertImpl(String & out,IParser::Pos & pos)
bool PercentileswArray::convertImpl(String & out, IParser::Pos & pos)
{
String fn_name = getKQLFunctionName(pos);
@ -378,26 +381,24 @@ bool PercentileswArray::convertImpl(String & out,IParser::Pos & pos)
return false;
++pos;
String bucket_column = getConvertedArgument(fn_name,pos);
String bucket_column = getConvertedArgument(fn_name, pos);
trim(bucket_column);
++pos;
String frequency_column = getConvertedArgument(fn_name,pos);
String frequency_column = getConvertedArgument(fn_name, pos);
trim(frequency_column);
String expr = "quantilesExactWeighted(";
String value;
while(pos->type != TokenType::ClosingRoundBracket)
while (pos->type != TokenType::ClosingRoundBracket)
{
if(pos->type != TokenType::Comma && String(pos->begin, pos->end) != "dynamic"
&& pos->type != TokenType::OpeningRoundBracket && pos->type != TokenType::OpeningSquareBracket
&& pos->type != TokenType::ClosingSquareBracket)
if (pos->type != TokenType::Comma && String(pos->begin, pos->end) != "dynamic" && pos->type != TokenType::OpeningRoundBracket
&& pos->type != TokenType::OpeningSquareBracket && pos->type != TokenType::ClosingSquareBracket)
{
value = String(pos->begin, pos->end);
expr = expr + value + "/100";
if(pos->type != TokenType::Comma && pos->type != TokenType::OpeningRoundBracket && pos->type != TokenType::OpeningSquareBracket
if (pos->type != TokenType::Comma && pos->type != TokenType::OpeningRoundBracket && pos->type != TokenType::OpeningSquareBracket
&& pos->type != TokenType::ClosingSquareBracket)
expr += ", ";
++pos;
@ -406,82 +407,81 @@ bool PercentileswArray::convertImpl(String & out,IParser::Pos & pos)
{
++pos;
}
}
++pos;
if(pos->type != TokenType::ClosingRoundBracket)
if (pos->type != TokenType::ClosingRoundBracket)
--pos;
expr.pop_back();
expr.pop_back();
expr = expr + ")(" + bucket_column + ","+frequency_column + ")";
expr = expr + ")(" + bucket_column + "," + frequency_column + ")";
out = expr;
return true;
}
bool Stdev::convertImpl(String & out,IParser::Pos & pos)
bool Stdev::convertImpl(String & out, IParser::Pos & pos)
{
String fn_name = getKQLFunctionName(pos);
if (fn_name.empty())
return false;
++pos;
const auto expr = getConvertedArgument(fn_name,pos);
const auto expr = getConvertedArgument(fn_name, pos);
out = "sqrt(varSamp(" + expr + "))";
return true;
}
bool StdevIf::convertImpl(String & out,IParser::Pos & pos)
bool StdevIf::convertImpl(String & out, IParser::Pos & pos)
{
String fn_name = getKQLFunctionName(pos);
if (fn_name.empty())
return false;
++pos;
const auto expr = getConvertedArgument(fn_name,pos);
const auto expr = getConvertedArgument(fn_name, pos);
if (pos->type != TokenType::Comma)
return false;
++pos;
const auto predicate = getConvertedArgument(fn_name,pos);
const auto predicate = getConvertedArgument(fn_name, pos);
out = "sqrt(varSampIf(" + expr + ", " + predicate + "))";
return true;
}
bool Sum::convertImpl(String & out,IParser::Pos & pos)
bool Sum::convertImpl(String & out, IParser::Pos & pos)
{
return directMapping(out,pos,"sum");
return directMapping(out, pos, "sum");
}
bool SumIf::convertImpl(String & out,IParser::Pos & pos)
bool SumIf::convertImpl(String & out, IParser::Pos & pos)
{
return directMapping(out,pos,"sumIf");
return directMapping(out, pos, "sumIf");
}
bool TakeAny::convertImpl(String & out,IParser::Pos & pos)
bool TakeAny::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool TakeAnyIf::convertImpl(String & out,IParser::Pos & pos)
bool TakeAnyIf::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool Variance::convertImpl(String & out,IParser::Pos & pos)
bool Variance::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool VarianceIf::convertImpl(String & out,IParser::Pos & pos)
bool VarianceIf::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}

View File

@ -8,261 +8,260 @@ class ArgMax : public IParserKQLFunction
{
protected:
const char * getName() const override { return "arg_max()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ArgMin : public IParserKQLFunction
{
protected:
const char * getName() const override { return "arg_min()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Avg : public IParserKQLFunction
{
protected:
const char * getName() const override { return "avg()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class AvgIf : public IParserKQLFunction
{
protected:
const char * getName() const override { return "avgif()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class BinaryAllAnd : public IParserKQLFunction
{
protected:
const char * getName() const override { return "binary_all_and()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class BinaryAllOr : public IParserKQLFunction
{
protected:
const char * getName() const override { return "binary_all_or()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class BinaryAllXor : public IParserKQLFunction
{
protected:
const char * getName() const override { return "binary_all_xor()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class BuildSchema : public IParserKQLFunction
{
protected:
const char * getName() const override { return "buildschema()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Count : public IParserKQLFunction
{
protected:
const char * getName() const override { return "count()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class CountIf : public IParserKQLFunction
{
protected:
const char * getName() const override { return "countif()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class DCount : public IParserKQLFunction
{
protected:
const char * getName() const override { return "dcount()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class DCountIf : public IParserKQLFunction
{
protected:
const char * getName() const override { return "dcountif()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class MakeBag : public IParserKQLFunction
{
protected:
const char * getName() const override { return "make_bag()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class MakeBagIf : public IParserKQLFunction
{
protected:
const char * getName() const override { return "make_bag_if()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class MakeList : public IParserKQLFunction
{
protected:
const char * getName() const override { return "make_list()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class MakeListIf : public IParserKQLFunction
{
protected:
const char * getName() const override { return "make_list_if()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class MakeListWithNulls : public IParserKQLFunction
{
protected:
const char * getName() const override { return "make_list_with_nulls()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class MakeSet : public IParserKQLFunction
{
protected:
const char * getName() const override { return "make_set()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class MakeSetIf : public IParserKQLFunction
{
protected:
const char * getName() const override { return "make_set_if()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Max : public IParserKQLFunction
{
protected:
const char * getName() const override { return "max()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class MaxIf : public IParserKQLFunction
{
protected:
const char * getName() const override { return "maxif()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Min : public IParserKQLFunction
{
protected:
const char * getName() const override { return "min()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class MinIf : public IParserKQLFunction
{
protected:
const char * getName() const override { return "minif()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Percentile : public IParserKQLFunction
{
protected:
const char * getName() const override { return "percentile()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Percentilew : public IParserKQLFunction
{
protected:
const char * getName() const override { return "percentilew()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Percentiles : public IParserKQLFunction
{
protected:
const char * getName() const override { return "percentiles()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class PercentilesArray : public IParserKQLFunction
{
protected:
const char * getName() const override { return "percentiles_array()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Percentilesw : public IParserKQLFunction
{
protected:
const char * getName() const override { return "percentilesw()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class PercentileswArray : public IParserKQLFunction
{
protected:
const char * getName() const override { return "percentilesw_array()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Stdev : public IParserKQLFunction
{
protected:
const char * getName() const override { return "stdev()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class StdevIf : public IParserKQLFunction
{
protected:
const char * getName() const override { return "stdevif()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Sum : public IParserKQLFunction
{
protected:
const char * getName() const override { return "sum()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SumIf : public IParserKQLFunction
{
protected:
const char * getName() const override { return "sumif()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class TakeAny : public IParserKQLFunction
{
protected:
const char * getName() const override { return "take_any()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class TakeAnyIf : public IParserKQLFunction
{
protected:
const char * getName() const override { return "take_anyif()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Variance : public IParserKQLFunction
{
protected:
const char * getName() const override { return "variance()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class VarianceIf : public IParserKQLFunction
{
protected:
const char * getName() const override { return "varianceif()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
}

View File

@ -8,50 +8,49 @@ class BinaryAnd : public IParserKQLFunction
{
protected:
const char * getName() const override { return "binary_and()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class BinaryNot : public IParserKQLFunction
{
protected:
const char * getName() const override { return "binary_not()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class BinaryOr : public IParserKQLFunction
{
protected:
const char * getName() const override { return "binary_or()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class BinaryShiftLeft : public IParserKQLFunction
{
protected:
const char * getName() const override { return "binary_shift_left()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class BinaryShiftRight : public IParserKQLFunction
{
protected:
const char * getName() const override { return "binary_shift_right()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class BinaryXor : public IParserKQLFunction
{
protected:
const char * getName() const override { return "binary_xor()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class BitsetCountOnes : public IParserKQLFunction
{
protected:
const char * getName() const override { return "bitset_count_ones()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
}

View File

@ -4,18 +4,12 @@
#include <Parsers/Kusto/KustoFunctions/KQLFunctionFactory.h>
#include <format>
#include <regex>
#include <Poco/String.h>
#include<regex>
namespace DB
{
namespace ErrorCodes
{
extern const int BAD_ARGUMENTS;
}
bool ToBool::convertImpl(String & out, IParser::Pos & pos)
{
const auto function_name = getKQLFunctionName(pos);
@ -106,15 +100,15 @@ bool ToTimeSpan::convertImpl(String & out, IParser::Pos & pos)
try
{
auto result = kqlCallToExpression("time", {arg}, pos.max_depth);
out = std::format("{}" , result);
out = std::format("{}", result);
}
catch(...)
catch (...)
{
out = "NULL";
}
}
else
out = std::format("{}" , arg);
out = std::format("{}", arg);
return true;
}
@ -132,7 +126,7 @@ bool ToDecimal::convertImpl(String & out, IParser::Pos & pos)
if (pos->type == TokenType::QuotedIdentifier || pos->type == TokenType::StringLiteral)
{
res = String(pos->begin+1, pos->end -1);
res = String(pos->begin + 1, pos->end - 1);
++pos;
precision = 34;
}

View File

@ -9,7 +9,7 @@
#include <Parsers/ParserSetQuery.h>
#include <format>
#include<regex>
#include <regex>
namespace DB
{
@ -39,10 +39,13 @@ bool DatatypeDatetime::convertImpl(String & out, IParser::Pos & pos)
else if (pos->type == TokenType::BareWord)
{
datetime_str = getConvertedArgument(fn_name, pos);
if(Poco::toUpper(datetime_str) == "NULL")
if (Poco::toUpper(datetime_str) == "NULL")
out = "NULL";
else
out = std::format("if(toTypeName({0}) = 'Int64' OR toTypeName({0}) = 'Int32'OR toTypeName({0}) = 'Float64' OR toTypeName({0}) = 'UInt32' OR toTypeName({0}) = 'UInt64', toDateTime64({0},9,'UTC'), parseDateTime64BestEffortOrNull({0}::String,9,'UTC'))", datetime_str);
out = std::format(
"if(toTypeName({0}) = 'Int64' OR toTypeName({0}) = 'Int32'OR toTypeName({0}) = 'Float64' OR toTypeName({0}) = 'UInt32' OR "
" toTypeName({0}) = 'UInt64', toDateTime64({0},9,'UTC'), parseDateTime64BestEffortOrNull({0}::String,9,'UTC'))",
datetime_str);
return true;
}
else
@ -221,19 +224,19 @@ bool DatatypeDecimal::convertImpl(String & out, IParser::Pos & pos)
--pos;
arg = getArgument(fn_name, pos);
//NULL expr returns NULL not execption
//NULL expr returns NULL not exception
static const std::regex expr{"^[0-9]+e[+-]?[0-9]+"};
bool is_string = std::any_of(arg.begin(), arg.end(), ::isalpha) && Poco::toUpper(arg) != "NULL" && !(std::regex_match(arg , expr));
bool is_string = std::any_of(arg.begin(), arg.end(), ::isalpha) && Poco::toUpper(arg) != "NULL" && !(std::regex_match(arg, expr));
if (is_string)
throw Exception("Failed to parse String as decimal Literal: " + fn_name, ErrorCodes::BAD_ARGUMENTS);
if (std::regex_match(arg , expr))
if (std::regex_match(arg, expr))
{
auto exponential_pos = arg.find("e");
if(arg[exponential_pos +1] == '+' || arg[exponential_pos +1] == '-' )
scale = std::stoi(arg.substr(exponential_pos+2,arg.length()));
if (arg[exponential_pos + 1] == '+' || arg[exponential_pos + 1] == '-')
scale = std::stoi(arg.substr(exponential_pos + 2, arg.length()));
else
scale = std::stoi(arg.substr(exponential_pos+1 , arg.length()));
scale = std::stoi(arg.substr(exponential_pos + 1, arg.length()));
out = std::format("toDecimal128({}::String,{})", arg, scale);
return true;

View File

@ -8,71 +8,70 @@ class DatatypeBool : public IParserKQLFunction
{
protected:
const char * getName() const override { return "bool(),boolean()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class DatatypeDatetime : public IParserKQLFunction
{
protected:
const char * getName() const override { return "datetime(),date()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class DatatypeDynamic : public IParserKQLFunction
{
protected:
const char * getName() const override { return "dynamic()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class DatatypeGuid : public IParserKQLFunction
{
protected:
const char * getName() const override { return "guid()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class DatatypeInt : public IParserKQLFunction
{
protected:
const char * getName() const override { return "int()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class DatatypeLong : public IParserKQLFunction
{
protected:
const char * getName() const override { return "long()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class DatatypeReal : public IParserKQLFunction
{
protected:
const char * getName() const override { return "real(),double()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class DatatypeString : public IParserKQLFunction
{
protected:
const char * getName() const override { return "string()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class DatatypeTimespan : public IParserKQLFunction
{
protected:
const char * getName() const override { return "timespan(), time()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class DatatypeDecimal : public IParserKQLFunction
{
protected:
const char * getName() const override { return "decimal()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
}

View File

@ -1,25 +1,26 @@
#include <Parsers/IParserBase.h>
#include <Parsers/ParserSetQuery.h>
#include <regex>
#include <Parsers/ASTExpressionList.h>
#include <Parsers/ASTSelectWithUnionQuery.h>
#include <Parsers/IParserBase.h>
#include <Parsers/Kusto/KustoFunctions/IParserKQLFunction.h>
#include <Parsers/Kusto/KustoFunctions/KQLAggregationFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLBinaryFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLCastingFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLDateTimeFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLDynamicFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLGeneralFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLIPFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLStringFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLTimeSeriesFunctions.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLStatement.h>
#include <Parsers/Kusto/KustoFunctions/IParserKQLFunction.h>
#include <Parsers/Kusto/KustoFunctions/KQLDateTimeFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLStringFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLDynamicFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLCastingFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLAggregationFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLTimeSeriesFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLIPFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLBinaryFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLGeneralFunctions.h>
#include <Parsers/ParserSetQuery.h>
#include <format>
#include <regex>
namespace DB::ErrorCodes
{
extern const int SYNTAX_ERROR;
extern const int BAD_ARGUMENTS;
extern const int SYNTAX_ERROR;
}
namespace DB
{
@ -61,18 +62,17 @@ bool DatetimeAdd::convertImpl(String & out, IParser::Pos & pos)
if (period.front() == '\"' || period.front() == '\'')
{
//period.remove
period.erase( 0, 1); // erase the first quote
period.erase( period.size() - 1); // erase the last quote
period.erase(0, 1); // erase the first quote
period.erase(period.size() - 1); // erase the last quote
}
++pos;
const String offset = getConvertedArgument(fn_name, pos);
++pos;
const String datetime = getConvertedArgument(fn_name, pos);
out = std::format("date_add({}, {}, {})",period,offset,datetime);
out = std::format("date_add({}, {}, {})", period, offset, datetime);
return true;
};
bool DatetimePart::convertImpl(String & out, IParser::Pos & pos)
@ -87,8 +87,8 @@ bool DatetimePart::convertImpl(String & out, IParser::Pos & pos)
if (part.front() == '\"' || part.front() == '\'')
{
//period.remove
part.erase( 0, 1); // erase the first quote
part.erase( part.size() - 1); // erase the last quote
part.erase(0, 1); // erase the first quote
part.erase(part.size() - 1); // erase the last quote
}
String date;
if (pos->type == TokenType::Comma)
@ -137,7 +137,7 @@ bool DatetimeDiff::convertImpl(String & out, IParser::Pos & pos)
++pos;
arguments = arguments + getConvertedArgument(fn_name, pos);
out = std::format("DateDiff({}) * -1",arguments);
out = std::format("DateDiff({}) * -1", arguments);
return true;
}
@ -154,7 +154,7 @@ bool DayOfWeek::convertImpl(String & out, IParser::Pos & pos)
++pos;
const String datetime_str = getConvertedArgument(fn_name, pos);
out = std::format("concat((toDayOfWeek({})%7)::String , '.00:00:00')",datetime_str);
out = std::format("concat((toDayOfWeek({})%7)::String , '.00:00:00')", datetime_str);
return true;
}
@ -165,7 +165,6 @@ bool DayOfYear::convertImpl(String & out, IParser::Pos & pos)
bool EndOfMonth::convertImpl(String & out, IParser::Pos & pos)
{
const String fn_name = getKQLFunctionName(pos);
if (fn_name.empty())
return false;
@ -178,17 +177,20 @@ bool EndOfMonth::convertImpl(String & out, IParser::Pos & pos)
{
++pos;
offset = getConvertedArgument(fn_name, pos);
if(offset.empty())
if (offset.empty())
throw Exception("Number of arguments do not match in function:" + fn_name, ErrorCodes::SYNTAX_ERROR);
}
out = std::format("toDateTime(toLastDayOfMonth(toDateTime({}, 9, 'UTC') + toIntervalMonth({})), 9, 'UTC') + toIntervalHour(23) + toIntervalMinute(59) + toIntervalSecond(60) - toIntervalMicrosecond(1)", datetime_str, toString(offset));
out = std::format(
"toDateTime(toLastDayOfMonth(toDateTime({}, 9, 'UTC') + toIntervalMonth({})), 9, 'UTC') + toIntervalHour(23) + "
"toIntervalMinute(59) + toIntervalSecond(60) - toIntervalMicrosecond(1)",
datetime_str,
toString(offset));
return true;
}
bool EndOfDay::convertImpl(String & out, IParser::Pos & pos)
{
const String fn_name = getKQLFunctionName(pos);
if (fn_name.empty())
return false;
@ -202,15 +204,14 @@ bool EndOfDay::convertImpl(String & out, IParser::Pos & pos)
++pos;
offset = getConvertedArgument(fn_name, pos);
}
out = std::format("toDateTime(toStartOfDay({}),9,'UTC') + (INTERVAL {} +1 DAY) - (INTERVAL 1 microsecond)", datetime_str, toString(offset));
out = std::format(
"toDateTime(toStartOfDay({}),9,'UTC') + (INTERVAL {} +1 DAY) - (INTERVAL 1 microsecond)", datetime_str, toString(offset));
return true;
}
bool EndOfWeek::convertImpl(String & out, IParser::Pos & pos)
{
const String fn_name = getKQLFunctionName(pos);
if (fn_name.empty())
return false;
@ -224,7 +225,8 @@ bool EndOfWeek::convertImpl(String & out, IParser::Pos & pos)
++pos;
offset = getConvertedArgument(fn_name, pos);
}
out = std::format("toDateTime(toStartOfDay({}),9,'UTC') + (INTERVAL {} +1 WEEK) - (INTERVAL 1 microsecond)", datetime_str, toString(offset));
out = std::format(
"toDateTime(toStartOfDay({}),9,'UTC') + (INTERVAL {} +1 WEEK) - (INTERVAL 1 microsecond)", datetime_str, toString(offset));
return true;
}
@ -238,7 +240,7 @@ bool EndOfYear::convertImpl(String & out, IParser::Pos & pos)
++pos;
const String datetime_str = getConvertedArgument(fn_name, pos);
if(datetime_str.empty())
if (datetime_str.empty())
throw Exception("Number of arguments do not match in function:" + fn_name, ErrorCodes::SYNTAX_ERROR);
String offset = "0";
@ -246,12 +248,17 @@ bool EndOfYear::convertImpl(String & out, IParser::Pos & pos)
{
++pos;
offset = getConvertedArgument(fn_name, pos);
if(offset.empty())
if (offset.empty())
throw Exception("Number of arguments do not match in function:" + fn_name, ErrorCodes::SYNTAX_ERROR);
offset.erase(remove(offset.begin(), offset.end(), ' '), offset.end());
}
out = std::format("(((((toDateTime(toString(toLastDayOfMonth(toDateTime({0}, 9, 'UTC') + toIntervalYear({1}) + toIntervalMonth(12 - toInt8(substring(toString(toDateTime({0}, 9, 'UTC')), 6, 2))))), 9, 'UTC') + toIntervalHour(23)) + toIntervalMinute(59)) + toIntervalSecond(60)) - toIntervalMicrosecond(1)))", datetime_str, toString(offset));
out = std::format(
"(((((toDateTime(toString(toLastDayOfMonth(toDateTime({0}, 9, 'UTC') + toIntervalYear({1}) + toIntervalMonth(12 - "
"toInt8(substring(toString(toDateTime({0}, 9, 'UTC')), 6, 2))))), 9, 'UTC') + toIntervalHour(23)) + toIntervalMinute(59)) + "
"toIntervalSecond(60)) - toIntervalMicrosecond(1)))",
datetime_str,
toString(offset));
return true;
}
@ -271,24 +278,24 @@ bool FormatDateTime::convertImpl(String & out, IParser::Pos & pos)
//remove quotes and end space from format argument.
if (format.front() == '\"' || format.front() == '\'')
{
format.erase( 0, 1); // erase the first quote
format.erase( format.size() - 1); // erase the last quote
format.erase(0, 1); // erase the first quote
format.erase(format.size() - 1); // erase the last quote
}
std::vector<String> res;
getTokens(format, res);
std::string::size_type i = 0;
size_t decimal =0;
size_t decimal = 0;
while (i < format.size())
{
char c = format[i];
if (!isalpha(c))
{
//delimeter
//delimiter
if (c == ' ' || c == '-' || c == '_' || c == '[' || c == ']' || c == '/' || c == ',' || c == '.' || c == ':')
formatspecifier = formatspecifier + c;
else
throw Exception("Invalid format delimeter in function:" + fn_name, ErrorCodes::SYNTAX_ERROR);
throw Exception("Invalid format delimiter in function:" + fn_name, ErrorCodes::SYNTAX_ERROR);
++i;
}
else
@ -326,14 +333,18 @@ bool FormatDateTime::convertImpl(String & out, IParser::Pos & pos)
}
if (decimal > 0 && formatspecifier.find('.') != String::npos)
{
out = std::format("concat("
out = std::format(
"concat("
"substring(toString(formatDateTime( {0} , '{1}')),1, position(toString(formatDateTime({0},'{1}')),'.')) ,"
"substring(substring(toString({0}), position(toString({0}),'.')+1),1,{2}),"
"substring(toString(formatDateTime( {0},'{1}')), position(toString(formatDateTime({0},'{1}')),'.')+1 ,length (toString(formatDateTime({0},'{1}'))))) ", datetime, formatspecifier,decimal);
"substring(toString(formatDateTime( {0},'{1}')), position(toString(formatDateTime({0},'{1}')),'.')+1 ,length "
"(toString(formatDateTime({0},'{1}'))))) ",
datetime,
formatspecifier,
decimal);
}
else
out = std::format("formatDateTime( {0},'{1}')",datetime, formatspecifier);
out = std::format("formatDateTime( {0},'{1}')", datetime, formatspecifier);
return true;
}
@ -370,11 +381,11 @@ bool FormatTimeSpan::convertImpl(String & out, IParser::Pos & pos)
char c = format[i];
if (!isalpha(c))
{
//delimeter
//delimiter
if (c == ' ' || c == '-' || c == '_' || c == '[' || c == ']' || c == '/' || c == ',' || c == '.' || c == ':')
formatspecifier = formatspecifier + c;
else
throw Exception("Invalid format delimeter in function:" + fn_name, ErrorCodes::SYNTAX_ERROR);
throw Exception("Invalid format delimiter in function:" + fn_name, ErrorCodes::SYNTAX_ERROR);
++i;
}
else
@ -408,31 +419,75 @@ bool FormatTimeSpan::convertImpl(String & out, IParser::Pos & pos)
i = i + arg.size();
}
}
auto last_delim = formatspecifier.substr(formatspecifier.length()-1, formatspecifier.length());
auto last_delim = formatspecifier.substr(formatspecifier.length() - 1, formatspecifier.length());
if (!is_day_in_format)
{
if (decimal > 0)
{
if (format.substr(format.length()- decimal -1, 1) == last_delim)
out = std::format("concat(substring(toString(formatDateTime( toDateTime64({0},9,'UTC') ,'{1}')),1, length(toString(formatDateTime( toDateTime64({0},9,'UTC'),'{1}'))) - position( reverse(toString(formatDateTime(toDateTime64({0},9,'UTC'),'{1}'))),'{3}')+1),substring(SUBSTRING(toString(toDateTime64({0},9,'UTC')),position(toString(toDateTime64({0},9,'UTC')),'.')+1),1,{2}))", datetime, formatspecifier, decimal, last_delim);
if (format.substr(format.length() - decimal - 1, 1) == last_delim)
out = std::format(
"concat(substring(toString(formatDateTime( toDateTime64({0},9,'UTC') ,'{1}')),1, length(toString(formatDateTime( "
"toDateTime64({0},9,'UTC'),'{1}'))) - position( "
"reverse(toString(formatDateTime(toDateTime64({0},9,'UTC'),'{1}'))),'{3}')+1),substring(SUBSTRING(toString("
"toDateTime64({0},9,'UTC')),position(toString(toDateTime64({0},9,'UTC')),'.')+1),1,{2}))",
datetime,
formatspecifier,
decimal,
last_delim);
else
out = std::format("concat(substring(toString(formatDateTime( toDateTime64({0},9,'UTC') ,'{1}')),1, length(toString(formatDateTime( toDateTime64({0},9,'UTC'),'{1}'))) - position( reverse(toString(formatDateTime(toDateTime64({0},9,'UTC'),'{1}'))),'{3}')),substring(SUBSTRING(toString(toDateTime64({0},9,'UTC')),position(toString(toDateTime64({0},9,'UTC')),'.')+1),1,{2}))", datetime, formatspecifier, decimal, last_delim);
out = std::format(
"concat(substring(toString(formatDateTime( toDateTime64({0},9,'UTC') ,'{1}')),1, length(toString(formatDateTime( "
"toDateTime64({0},9,'UTC'),'{1}'))) - position( "
"reverse(toString(formatDateTime(toDateTime64({0},9,'UTC'),'{1}'))),'{3}')),substring(SUBSTRING(toString(toDateTime64({"
"0},9,'UTC')),position(toString(toDateTime64({0},9,'UTC')),'.')+1),1,{2}))",
datetime,
formatspecifier,
decimal,
last_delim);
}
else
out = std::format("formatDateTime(toDateTime64({0},9,'UTC'),'{1}')", datetime,formatspecifier);
out = std::format("formatDateTime(toDateTime64({0},9,'UTC'),'{1}')", datetime, formatspecifier);
}
else
{
if (decimal > 0)
{
if (format.substr(format.length()- decimal - 1, 1) == last_delim)
out = std::format("concat( leftPad('{5}' , {3} ,'0'),substring(toString(formatDateTime( toDateTime64({0},9,'UTC'),'{1}')),1, length(toString(formatDateTime( toDateTime64({0},9,'UTC'),'{1}'))) - position( reverse(toString(formatDateTime(toDateTime64({0},9,'UTC'),'{1}'))),'{4}') +1),substring(SUBSTRING(toString(toDateTime64({0},9,'UTC')),position(toString(toDateTime64({0},9,'UTC')),'.')+1),1,{2}))", datetime, formatspecifier, decimal,pad, last_delim, day_val);
if (format.substr(format.length() - decimal - 1, 1) == last_delim)
out = std::format(
"concat( leftPad('{5}' , {3} ,'0'),substring(toString(formatDateTime( toDateTime64({0},9,'UTC'),'{1}')),1, "
"length(toString(formatDateTime( toDateTime64({0},9,'UTC'),'{1}'))) - position( "
"reverse(toString(formatDateTime(toDateTime64({0},9,'UTC'),'{1}'))),'{4}') "
"+1),substring(SUBSTRING(toString(toDateTime64({0},9,'UTC')),position(toString(toDateTime64({0},9,'UTC')),'.')+1),1,{2}"
"))",
datetime,
formatspecifier,
decimal,
pad,
last_delim,
day_val);
else
out = std::format("concat( leftPad('{5}' , {3} ,'0') ,substring(toString(formatDateTime( toDateTime64({0},9,'UTC'),'{1}')),1, length(toString(formatDateTime( toDateTime64({0},9,'UTC'),'{1}'))) - position( reverse(toString(formatDateTime(toDateTime64({0},9,'UTC'),'{1}'))),'{4}')),substring(SUBSTRING(toString(toDateTime64({0},9,'UTC')),position(toString(toDateTime64({0},9,'UTC')),'.')+1),1,{2}),substring(toString(formatDateTime(toDateTime64({0},9,'UTC'),'{1}')),position( toString(formatDateTime( toDateTime64({0},9,'UTC'),'{1}')),'{4}'),length(toString(formatDateTime( toDateTime64({0},9,'UTC'),'{1}')))))", datetime, formatspecifier, decimal, pad, last_delim, day_val);
out = std::format(
"concat( leftPad('{5}' , {3} ,'0') ,substring(toString(formatDateTime( toDateTime64({0},9,'UTC'),'{1}')),1, "
"length(toString(formatDateTime( toDateTime64({0},9,'UTC'),'{1}'))) - position( "
"reverse(toString(formatDateTime(toDateTime64({0},9,'UTC'),'{1}'))),'{4}')),substring(SUBSTRING(toString(toDateTime64({"
"0},9,'UTC')),position(toString(toDateTime64({0},9,'UTC')),'.')+1),1,{2}),substring(toString(formatDateTime("
"toDateTime64({0},9,'UTC'),'{1}')),position( toString(formatDateTime( "
"toDateTime64({0},9,'UTC'),'{1}')),'{4}'),length(toString(formatDateTime( toDateTime64({0},9,'UTC'),'{1}')))))",
datetime,
formatspecifier,
decimal,
pad,
last_delim,
day_val);
}
else if (decimal == 0)
out = std::format("concat( leftPad('{3}' , {2} ,'0'),toString(formatDateTime(toDateTime64({0},9,'UTC') ,'{1}')))", datetime,formatspecifier,pad,day_val);
out = std::format(
"concat( leftPad('{3}' , {2} ,'0'),toString(formatDateTime(toDateTime64({0},9,'UTC') ,'{1}')))",
datetime,
formatspecifier,
pad,
day_val);
}
return true;
}
@ -461,16 +516,16 @@ bool MakeTimeSpan::convertImpl(String & out, IParser::Pos & pos)
++pos;
String datetime_str;
String hour ;
String day ;
String minute ;
String second ;
String hour;
String day;
String minute;
String second;
int arg_count = 0;
std::vector<String> args;
while (!pos->isEnd() && pos->type != TokenType::ClosingRoundBracket)
{
String arg = getConvertedArgument(fn_name, pos);
args.insert(args.begin(),arg);
args.insert(args.begin(), arg);
if (pos->type == TokenType::Comma)
++pos;
++arg_count;
@ -485,7 +540,7 @@ bool MakeTimeSpan::convertImpl(String & out, IParser::Pos & pos)
args.pop_back();
minute = args.back();
args.pop_back();
datetime_str = hour + ":" + minute ;
datetime_str = hour + ":" + minute;
}
else if (arg_count == 3)
{
@ -518,7 +573,8 @@ bool MakeTimeSpan::convertImpl(String & out, IParser::Pos & pos)
//Add dummy yyyy-mm-dd to parse datetime in CH
datetime_str = "0000-00-00 " + datetime_str;
out = std::format("CONCAT('{}',toString(SUBSTRING(toString(toTime(parseDateTime64BestEffortOrNull('{}', 9 ,'UTC'))),12)))" ,day ,datetime_str);
out = std::format(
"CONCAT('{}',toString(SUBSTRING(toString(toTime(parseDateTime64BestEffortOrNull('{}', 9 ,'UTC'))),12)))", day, datetime_str);
return true;
}
@ -547,12 +603,12 @@ bool MakeDateTime::convertImpl(String & out, IParser::Pos & pos)
if (arg_count < 7)
{
for (int i = arg_count;i < 7; ++i)
for (int i = arg_count; i < 7; ++i)
arguments = arguments + "0 ,";
}
arguments = arguments + "7,'UTC'";
out = std::format("makeDateTime64({})",arguments);
out = std::format("makeDateTime64({})", arguments);
return true;
}
@ -589,7 +645,6 @@ bool StartOfDay::convertImpl(String & out, IParser::Pos & pos)
{
++pos;
offset = getConvertedArgument(fn_name, pos);
}
out = std::format("date_add(DAY,{}, parseDateTime64BestEffortOrNull(toString((toStartOfDay({}))) , 9 , 'UTC')) ", offset, datetime_str);
return true;
@ -609,9 +664,9 @@ bool StartOfMonth::convertImpl(String & out, IParser::Pos & pos)
{
++pos;
offset = getConvertedArgument(fn_name, pos);
}
out = std::format("date_add(MONTH,{}, parseDateTime64BestEffortOrNull(toString((toStartOfMonth({}))) , 9 , 'UTC')) ", offset, datetime_str);
out = std::format(
"date_add(MONTH,{}, parseDateTime64BestEffortOrNull(toString((toStartOfMonth({}))) , 9 , 'UTC')) ", offset, datetime_str);
return true;
}
@ -629,9 +684,9 @@ bool StartOfWeek::convertImpl(String & out, IParser::Pos & pos)
{
++pos;
offset = getConvertedArgument(fn_name, pos);
}
out = std::format("date_add(Week,{}, parseDateTime64BestEffortOrNull(toString((toStartOfWeek({}))) , 9 , 'UTC')) ", offset, datetime_str);
out = std::format(
"date_add(Week,{}, parseDateTime64BestEffortOrNull(toString((toStartOfWeek({}))) , 9 , 'UTC')) ", offset, datetime_str);
return true;
}
@ -650,7 +705,8 @@ bool StartOfYear::convertImpl(String & out, IParser::Pos & pos)
++pos;
offset = getConvertedArgument(fn_name, pos);
}
out = std::format("date_add(YEAR,{}, parseDateTime64BestEffortOrNull(toString((toStartOfYear({}, 'UTC'))) , 9 , 'UTC'))", offset, datetime_str);
out = std::format(
"date_add(YEAR,{}, parseDateTime64BestEffortOrNull(toString((toStartOfYear({}, 'UTC'))) , 9 , 'UTC'))", offset, datetime_str);
return true;
}
@ -701,10 +757,15 @@ bool UnixTimeSecondsToDateTime::convertImpl(String & out, IParser::Pos & pos)
++pos;
if (pos->type == TokenType::QuotedIdentifier || pos->type == TokenType::StringLiteral)
throw Exception(fn_name + " accepts only long, int and double type of arguments " , ErrorCodes::BAD_ARGUMENTS);
throw Exception(fn_name + " accepts only long, int and double type of arguments ", ErrorCodes::BAD_ARGUMENTS);
String expression = getConvertedArgument(fn_name, pos);
out = std::format(" if(toTypeName({0}) = 'Int64' OR toTypeName({0}) = 'Int32'OR toTypeName({0}) = 'Float64' OR toTypeName({0}) = 'UInt32' OR toTypeName({0}) = 'UInt64', toDateTime64({0}, 9, 'UTC') , toDateTime64(throwIf(true, '{1} only accepts Int , Long and double type of arguments'),9,'UTC'))", expression, fn_name);
out = std::format(
" if(toTypeName({0}) = 'Int64' OR toTypeName({0}) = 'Int32'OR toTypeName({0}) = 'Float64' OR toTypeName({0}) = 'UInt32' OR "
"toTypeName({0}) = 'UInt64', toDateTime64({0}, 9, 'UTC') , toDateTime64(throwIf(true, '{1} only accepts Int , Long and double type "
"of arguments'),9,'UTC'))",
expression,
fn_name);
return true;
}
@ -726,4 +787,3 @@ bool MonthOfYear::convertImpl(String & out, IParser::Pos & pos)
}
}

View File

@ -9,7 +9,7 @@ class TimeSpan : public IParserKQLFunction
{
protected:
const char * getName() const override { return "timespan()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
/*
class DateTime : public IParserKQLFunction
@ -24,206 +24,206 @@ class Ago : public IParserKQLFunction
{
protected:
const char * getName() const override { return "ago()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class DatetimeAdd : public IParserKQLFunction
{
protected:
const char * getName() const override { return "datetime_add()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class DatetimePart : public IParserKQLFunction
{
protected:
const char * getName() const override { return "datetime_part()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class DatetimeDiff : public IParserKQLFunction
{
protected:
const char * getName() const override { return "datetime_diff()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class DayOfMonth : public IParserKQLFunction
{
protected:
const char * getName() const override { return "dayofmonth()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class DayOfWeek : public IParserKQLFunction
{
protected:
const char * getName() const override { return "dayofweek()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class DayOfYear : public IParserKQLFunction
{
protected:
const char * getName() const override { return "dayofyear()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class EndOfDay : public IParserKQLFunction
{
protected:
const char * getName() const override { return "endofday()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class EndOfMonth : public IParserKQLFunction
{
protected:
const char * getName() const override { return "endofmonth()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class EndOfWeek : public IParserKQLFunction
{
protected:
const char * getName() const override { return "endofweek()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class EndOfYear : public IParserKQLFunction
{
protected:
const char * getName() const override { return "endofyear()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class FormatDateTime : public IParserKQLFunction
{
protected:
const char * getName() const override { return "format_datetime()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class FormatTimeSpan : public IParserKQLFunction
{
protected:
const char * getName() const override { return "format_timespan()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class GetMonth : public IParserKQLFunction
{
protected:
const char * getName() const override { return "getmonth()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class GetYear : public IParserKQLFunction
{
protected:
const char * getName() const override { return "getyear()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class HoursOfDay : public IParserKQLFunction
{
protected:
const char * getName() const override { return "hourofday()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class MakeTimeSpan : public IParserKQLFunction
{
protected:
const char * getName() const override { return "make_timespan()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class MakeDateTime : public IParserKQLFunction
{
protected:
const char * getName() const override { return "make_datetime()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Now : public IParserKQLFunction
{
protected:
const char * getName() const override { return "now()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class StartOfDay : public IParserKQLFunction
{
protected:
const char * getName() const override { return "startofday()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class StartOfMonth : public IParserKQLFunction
{
protected:
const char * getName() const override { return "startofmonth()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class StartOfWeek : public IParserKQLFunction
{
protected:
const char * getName() const override { return "startofweek()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class StartOfYear : public IParserKQLFunction
{
protected:
const char * getName() const override { return "startofyear()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class UnixTimeMicrosecondsToDateTime : public IParserKQLFunction
{
protected:
const char * getName() const override { return "unixtime_microseconds_todatetime()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class UnixTimeMillisecondsToDateTime : public IParserKQLFunction
{
protected:
const char * getName() const override { return "unixtime_milliseconds_todatetime()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class UnixTimeNanosecondsToDateTime : public IParserKQLFunction
{
protected:
const char * getName() const override { return "unixtime_nanoseconds_todatetime()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class UnixTimeSecondsToDateTime : public IParserKQLFunction
{
protected:
const char * getName() const override { return "unixtime_seconds_todatetime()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class WeekOfYear : public IParserKQLFunction
{
protected:
const char * getName() const override { return "week_of_year()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class MonthOfYear : public IParserKQLFunction
{
protected:
const char * getName() const override { return "monthofyear()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
void inline getTokens(String format, std::vector<String> & res )
void inline getTokens(String format, std::vector<String> & res)
{
String str = format;
String token;
@ -236,7 +236,7 @@ void inline getTokens(String format, std::vector<String> & res )
token = str.substr(0, pos);
res.insert(res.begin(), token);
}
str.erase(0, pos+1); // Always remove pos+1 to get rid of delimiter
str.erase(0, pos + 1); // Always remove pos+1 to get rid of delimiter
pos = str.find_first_not_of("abcdefghijklmnopqrstuvwxyzQWERTYUIOPASDFGHJKLZXCVBNM");
}
// Cover the last (or only) token
@ -248,4 +248,3 @@ void inline getTokens(String format, std::vector<String> & res )
}
}

View File

@ -276,7 +276,7 @@ bool Repeat::convertImpl(String & out, IParser::Pos & pos)
value.erase(remove(value.begin(), value.end(), ' '), value.end());
count.erase(remove(count.begin(), count.end(), ' '), count.end());
if(count.empty())
if (count.empty())
throw Exception("number of arguments do not match in function: " + function_name, ErrorCodes::SYNTAX_ERROR);
else
out = "if(" + count + " < 0, [NULL], " + std::format("arrayWithConstant(abs({1}), {0}))", value, count);

View File

@ -8,197 +8,196 @@ class ArrayConcat : public IParserKQLFunction
{
protected:
const char * getName() const override { return "array_concat()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ArrayIif : public IParserKQLFunction
{
protected:
const char * getName() const override { return "array_iif()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ArrayIndexOf : public IParserKQLFunction
{
protected:
const char * getName() const override { return "array_index_of()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ArrayLength : public IParserKQLFunction
{
protected:
const char * getName() const override { return "array_length()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ArrayReverse : public IParserKQLFunction
{
protected:
const char * getName() const override { return "array_reverse()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ArrayRotateLeft : public IParserKQLFunction
{
protected:
const char * getName() const override { return "array_rotate_left()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ArrayRotateRight : public IParserKQLFunction
{
protected:
const char * getName() const override { return "array_rotate_right()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ArrayShiftLeft : public IParserKQLFunction
{
protected:
const char * getName() const override { return "array_shift_left()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ArrayShiftRight : public IParserKQLFunction
{
protected:
const char * getName() const override { return "array_shift_right()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ArraySlice : public IParserKQLFunction
{
protected:
const char * getName() const override { return "array_slice()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ArraySortAsc : public IParserKQLFunction
{
protected:
const char * getName() const override { return "array_sort_asc()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ArraySortDesc : public IParserKQLFunction
{
protected:
const char * getName() const override { return "array_sort_desc()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ArraySplit : public IParserKQLFunction
{
protected:
const char * getName() const override { return "array_split()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ArraySum : public IParserKQLFunction
{
protected:
const char * getName() const override { return "array_sum()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class BagKeys : public IParserKQLFunction
{
protected:
const char * getName() const override { return "bag_keys()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class BagMerge : public IParserKQLFunction
{
protected:
const char * getName() const override { return "bag_merge()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class BagRemoveKeys : public IParserKQLFunction
{
protected:
const char * getName() const override { return "bag_remove_keys()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class JaccardIndex : public IParserKQLFunction
{
protected:
const char * getName() const override { return "jaccard_index()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Pack : public IParserKQLFunction
{
protected:
const char * getName() const override { return "pack()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class PackAll : public IParserKQLFunction
{
protected:
const char * getName() const override { return "pack_all()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class PackArray : public IParserKQLFunction
{
protected:
const char * getName() const override { return "pack_array()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Repeat : public IParserKQLFunction
{
protected:
const char * getName() const override { return "repeat()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SetDifference : public IParserKQLFunction
{
protected:
const char * getName() const override { return "set_difference()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SetHasElement : public IParserKQLFunction
{
protected:
const char * getName() const override { return "set_has_element()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SetIntersect : public IParserKQLFunction
{
protected:
const char * getName() const override { return "set_intersect()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SetUnion : public IParserKQLFunction
{
protected:
const char * getName() const override { return "set_union()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class TreePath : public IParserKQLFunction
{
protected:
const char * getName() const override { return "treepath()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Zip : public IParserKQLFunction
{
protected:
const char * getName() const override { return "zip()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
}

View File

@ -1,28 +1,27 @@
#include <Parsers/IParserBase.h>
#include <Parsers/ParserSetQuery.h>
#include <Parsers/ASTExpressionList.h>
#include <Parsers/ASTSelectWithUnionQuery.h>
#include <Parsers/IParserBase.h>
#include <Parsers/Kusto/KustoFunctions/IParserKQLFunction.h>
#include <Parsers/Kusto/KustoFunctions/KQLAggregationFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLBinaryFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLCastingFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLDataTypeFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLDateTimeFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLDynamicFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLFunctionFactory.h>
#include <Parsers/Kusto/KustoFunctions/KQLGeneralFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLIPFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLMathematicalFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLStringFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLTimeSeriesFunctions.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLStatement.h>
#include <Parsers/Kusto/KustoFunctions/IParserKQLFunction.h>
#include <Parsers/Kusto/KustoFunctions/KQLDateTimeFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLStringFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLDynamicFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLCastingFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLAggregationFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLTimeSeriesFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLIPFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLBinaryFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLGeneralFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLFunctionFactory.h>
#include <Parsers/Kusto/KustoFunctions/KQLDataTypeFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLMathematicalFunctions.h>
#include <Parsers/ParserSetQuery.h>
namespace DB
{
std::unordered_map <String,KQLFunctionValue> KQLFunctionFactory::kql_functions =
{
{"ago", KQLFunctionValue::ago},
std::unordered_map<String, KQLFunctionValue> KQLFunctionFactory::kql_functions
= {{"ago", KQLFunctionValue::ago},
{"datetime_add", KQLFunctionValue::datetime_add},
{"datetime_part", KQLFunctionValue::datetime_part},
{"datetime_diff", KQLFunctionValue::datetime_diff},
@ -229,11 +228,10 @@ namespace DB
{"string", KQLFunctionValue::datatype_string},
{"timespan", KQLFunctionValue::datatype_timespan},
{"time", KQLFunctionValue::datatype_timespan},
{"decimal", KQLFunctionValue::datatype_decimal}
};
{"decimal", KQLFunctionValue::datatype_decimal}};
std::unique_ptr<IParserKQLFunction> KQLFunctionFactory::get(String &kql_function)
std::unique_ptr<IParserKQLFunction> KQLFunctionFactory::get(String & kql_function)
{
if (kql_functions.find(kql_function) == kql_functions.end())
return nullptr;
@ -813,7 +811,6 @@ std::unique_ptr<IParserKQLFunction> KQLFunctionFactory::get(String &kql_function
case KQLFunctionValue::datatype_decimal:
return std::make_unique<DatatypeDecimal>();
}
}

View File

@ -1,12 +1,13 @@
#pragma once
#include <unordered_map>
#include <Parsers/IParserBase.h>
#include <Parsers/Kusto/KustoFunctions/IParserKQLFunction.h>
#include <unordered_map>
namespace DB
{
enum class KQLFunctionValue : uint16_t
{ none,
enum class KQLFunctionValue : uint16_t
{
none,
timespan,
// datetime,
ago,
@ -206,15 +207,14 @@ namespace DB
datatype_string,
datatype_timespan,
datatype_decimal
};
};
class KQLFunctionFactory
{
public:
static std::unique_ptr<IParserKQLFunction> get(String &kql_function);
static std::unique_ptr<IParserKQLFunction> get(String & kql_function);
protected:
static std::unordered_map <String,KQLFunctionValue> kql_functions;
static std::unordered_map<String, KQLFunctionValue> kql_functions;
};
}

View File

@ -1,28 +1,27 @@
#include <Parsers/IParserBase.h>
#include <Parsers/ParserSetQuery.h>
#include <Parsers/ASTExpressionList.h>
#include <Parsers/ASTSelectWithUnionQuery.h>
#include <Parsers/IParserBase.h>
#include <Parsers/Kusto/KustoFunctions/IParserKQLFunction.h>
#include <Parsers/Kusto/KustoFunctions/KQLAggregationFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLBinaryFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLCastingFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLDateTimeFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLDynamicFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLGeneralFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLIPFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLStringFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLTimeSeriesFunctions.h>
#include <Parsers/Kusto/ParserKQLDateTypeTimespan.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLStatement.h>
#include <Parsers/Kusto/KustoFunctions/IParserKQLFunction.h>
#include <Parsers/Kusto/KustoFunctions/KQLDateTimeFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLStringFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLDynamicFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLCastingFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLAggregationFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLTimeSeriesFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLIPFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLBinaryFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLGeneralFunctions.h>
#include <Parsers/Kusto/ParserKQLDateTypeTimespan.h>
#include <format>
#include <Parsers/ParserSetQuery.h>
#include <boost/lexical_cast.hpp>
#include <format>
namespace DB
{
bool Bin::convertImpl(String & out,IParser::Pos & pos)
bool Bin::convertImpl(String & out, IParser::Pos & pos)
{
double bin_size;
const String fn_name = getKQLFunctionName(pos);
@ -37,7 +36,7 @@ bool Bin::convertImpl(String & out,IParser::Pos & pos)
String round_to = getConvertedArgument(fn_name, pos);
//remove sapce between minus and number
round_to.erase(std::remove_if(round_to.begin(), round_to.end(), isspace) , round_to.end());
round_to.erase(std::remove_if(round_to.begin(), round_to.end(), isspace), round_to.end());
auto t = std::format("toFloat64({})", value);
@ -47,10 +46,12 @@ bool Bin::convertImpl(String & out,IParser::Pos & pos)
{
out = std::format("toDateTime64(toInt64({0} / {1} ) * {1}, 9, 'UTC')", t, bin_size);
}
else if (origal_expr == "timespan" || origal_expr =="time" || ParserKQLDateTypeTimespan().parseConstKQLTimespan(origal_expr))
else if (origal_expr == "timespan" || origal_expr == "time" || ParserKQLDateTypeTimespan().parseConstKQLTimespan(origal_expr))
{
String bin_value = std::format(" toInt64({0} / {1} ) * {1}", t, bin_size);
out = std::format("concat(toString( toInt32((({}) as x) / 3600)),':', toString( toInt32(x % 3600 / 60)),':',toString( toInt32(x % 3600 % 60)))", bin_value);
out = std::format(
"concat(toString( toInt32((({}) as x) / 3600)),':', toString( toInt32(x % 3600 / 60)),':',toString( toInt32(x % 3600 % 60)))",
bin_value);
}
else
{
@ -59,7 +60,7 @@ bool Bin::convertImpl(String & out,IParser::Pos & pos)
return true;
}
bool BinAt::convertImpl(String & out,IParser::Pos & pos)
bool BinAt::convertImpl(String & out, IParser::Pos & pos)
{
double bin_size;
const String fn_name = getKQLFunctionName(pos);
@ -85,10 +86,12 @@ bool BinAt::convertImpl(String & out,IParser::Pos & pos)
{
out = std::format("toDateTime64({} + toInt64(({} - {}) / {} + {}) * {}, 9, 'UTC')", t1, t2, t1, bin_size, dir, bin_size);
}
else if (origal_expr == "timespan" || origal_expr =="time" || ParserKQLDateTypeTimespan().parseConstKQLTimespan(origal_expr))
else if (origal_expr == "timespan" || origal_expr == "time" || ParserKQLDateTypeTimespan().parseConstKQLTimespan(origal_expr))
{
String bin_value = std::format("{} + toInt64(({} - {}) / {} + {}) * {}", t1, t2, t1, bin_size, dir, bin_size);
out = std::format("concat(toString( toInt32((({}) as x) / 3600)),':', toString( toInt32(x % 3600 / 60)),':',toString( toInt32(x % 3600 % 60)))", bin_value);
out = std::format(
"concat(toString( toInt32((({}) as x) / 3600)),':', toString( toInt32(x % 3600 / 60)),':',toString( toInt32(x % 3600 % 60)))",
bin_value);
}
else
{

View File

@ -8,15 +8,14 @@ class Bin : public IParserKQLFunction
{
protected:
const char * getName() const override { return "bin()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class BinAt : public IParserKQLFunction
{
protected:
const char * getName() const override { return "bin_at()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
}

View File

@ -14,7 +14,6 @@
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLStatement.h>
#include <Parsers/ParserSetQuery.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <format>

View File

@ -8,92 +8,91 @@ class Ipv4Compare : public IParserKQLFunction
{
protected:
const char * getName() const override { return "ipv4_compare()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Ipv4IsInRange : public IParserKQLFunction
{
protected:
const char * getName() const override { return "ipv4_is_in_range()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Ipv4IsMatch : public IParserKQLFunction
{
protected:
const char * getName() const override { return "ipv4_is_match()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Ipv4IsPrivate : public IParserKQLFunction
{
protected:
const char * getName() const override { return "ipv4_is_private()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Ipv4NetmaskSuffix : public IParserKQLFunction
{
protected:
const char * getName() const override { return "ipv4_netmask_suffix()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ParseIpv4 : public IParserKQLFunction
{
protected:
const char * getName() const override { return "parse_ipv4()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ParseIpv4Mask : public IParserKQLFunction
{
protected:
const char * getName() const override { return "parse_ipv4_mask()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Ipv6Compare : public IParserKQLFunction
{
protected:
const char * getName() const override { return "ipv6_compare()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Ipv6IsMatch : public IParserKQLFunction
{
protected:
const char * getName() const override { return "ipv6_is_match()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ParseIpv6 : public IParserKQLFunction
{
protected:
const char * getName() const override { return "parse_ipv6()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ParseIpv6Mask : public IParserKQLFunction
{
protected:
const char * getName() const override { return "parse_ipv6_mask()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class FormatIpv4 : public IParserKQLFunction
{
protected:
const char * getName() const override { return "format_ipv4()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class FormatIpv4Mask : public IParserKQLFunction
{
protected:
const char * getName() const override { return "format_ipv4_mask()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
}

View File

@ -1,3 +1,5 @@
#pragma once
#include "IParserKQLFunction.h"
namespace DB

View File

@ -4,8 +4,8 @@
#include <Parsers/Kusto/KustoFunctions/KQLFunctionFactory.h>
#include <Parsers/Kusto/KustoFunctions/KQLStringFunctions.h>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <Poco/String.h>
#include <format>
@ -14,7 +14,6 @@
namespace DB::ErrorCodes
{
extern const int SYNTAX_ERROR;
extern const int UNKNOWN_TYPE;
extern const int BAD_ARGUMENTS;
extern const int UNKNOWN_TYPE;
@ -90,16 +89,15 @@ bool CountOf::convertImpl(String & out, IParser::Pos & pos)
if (pos->type == TokenType::Comma)
{
++pos;
kind = getConvertedArgument(fn_name,pos);
kind = getConvertedArgument(fn_name, pos);
}
assert (kind =="'normal'" || kind =="'regex'");
assert(kind == "'normal'" || kind == "'regex'");
if (kind == "'normal'")
out = "countSubstrings(" + source + ", " + search + ")";
else
out = "countMatches("+ source + ", " + search + ")";
out = "countMatches(" + source + ", " + search + ")";
return true;
}
bool Extract::convertImpl(String & out, IParser::Pos & pos)
@ -109,8 +107,8 @@ bool Extract::convertImpl(String & out, IParser::Pos & pos)
ParserToken close_bracket(TokenType::ClosingRoundBracket);
Expected expected;
std::unordered_map<String,String> type_cast =
{ {"bool", "Boolean"},
std::unordered_map<String, String> type_cast
= {{"bool", "Boolean"},
{"boolean", "Boolean"},
{"datetime", "DateTime"},
{"date", "DateTime"},
@ -120,8 +118,7 @@ bool Extract::convertImpl(String & out, IParser::Pos & pos)
{"real", "Float64"},
{"double", "Float64"},
{"string", "String"},
{"decimal", "Decimal"}
};
{"decimal", "Decimal"}};
const String fn_name = getKQLFunctionName(pos);
if (fn_name.empty())
@ -147,7 +144,7 @@ bool Extract::convertImpl(String & out, IParser::Pos & pos)
if (!open_bracket.ignore(pos, expected))
throw Exception("Syntax error near typeof", ErrorCodes::SYNTAX_ERROR);
type_literal= String(pos->begin, pos->end);
type_literal = String(pos->begin, pos->end);
if (type_cast.find(type_literal) == type_cast.end())
throw Exception(type_literal + " is not a supported kusto data type for extract", ErrorCodes::UNKNOWN_TYPE);
@ -251,9 +248,8 @@ bool ExtractJson::convertImpl(String & out, IParser::Pos & pos)
ParserToken close_bracket(TokenType::ClosingRoundBracket);
Expected expected;
std::unordered_map<String,String> type_cast =
{
{"bool", "Boolean"},
std::unordered_map<String, String> type_cast
= {{"bool", "Boolean"},
{"boolean", "Boolean"},
{"datetime", "DateTime"},
{"date", "DateTime"},
@ -264,8 +260,7 @@ bool ExtractJson::convertImpl(String & out, IParser::Pos & pos)
{"real", "Float64"},
{"double", "Float64"},
{"string", "String"},
{"decimal", "Decimal"}
};
{"decimal", "Decimal"}};
const String fn_name = getKQLFunctionName(pos);
if (fn_name.empty())
@ -283,7 +278,7 @@ bool ExtractJson::convertImpl(String & out, IParser::Pos & pos)
if (!open_bracket.ignore(pos, expected))
throw Exception("Syntax error near typeof", ErrorCodes::SYNTAX_ERROR);
datatype= String(pos->begin, pos->end);
datatype = String(pos->begin, pos->end);
if (type_cast.find(datatype) == type_cast.end())
throw Exception(datatype + " is not a supported kusto data type for " + fn_name, ErrorCodes::UNKNOWN_TYPE);
@ -324,7 +319,10 @@ bool HasAnyIndex::convertImpl(String & out, IParser::Pos & pos)
++pos;
const String lookup = getConvertedArgument(fn_name, pos);
String src_array = std::format("splitByChar(' ',{})", source);
out = std::format("if (empty({1}), -1, indexOf(arrayMap ( x -> (x in {0}), if (empty({1}),[''], arrayMap(x->(toString(x)),{1}))),1) - 1)", src_array, lookup);
out = std::format(
"if (empty({1}), -1, indexOf(arrayMap ( x -> (x in {0}), if (empty({1}),[''], arrayMap(x->(toString(x)),{1}))),1) - 1)",
src_array,
lookup);
return true;
}
@ -368,7 +366,6 @@ bool IndexOf::convertImpl(String & out, IParser::Pos & pos)
out = "position(" + source + ", " + lookup + ", " + std::to_string(start_index + 1) + ") - 1";
else
{
}
return true;
@ -407,7 +404,9 @@ bool ParseCommandLine::convertImpl(String & out, IParser::Pos & pos)
if (type != "'windows'")
throw Exception("Supported type argument is windows for " + fn_name, ErrorCodes::BAD_ARGUMENTS);
out = std::format("if(empty({0}) OR hasAll(splitByChar(' ', {0}) , ['']) , arrayMap(x->null, splitByChar(' ', '')), splitByChar(' ', {0}))" , json_string);
out = std::format(
"if(empty({0}) OR hasAll(splitByChar(' ', {0}) , ['']) , arrayMap(x->null, splitByChar(' ', '')), splitByChar(' ', {0}))",
json_string);
return true;
}
@ -425,7 +424,10 @@ bool ParseCSV::convertImpl(String & out, IParser::Pos & pos)
++pos;
String csv_string = getConvertedArgument(fn_name, pos);
out = std::format("if(position({0} ,'\n')::UInt8, (splitByChar(',', substring({0}, 1, position({0},'\n') -1))), (splitByChar(',', substring({0}, 1, length({0})))))", csv_string);
out = std::format(
"if(position({0} ,'\n')::UInt8, (splitByChar(',', substring({0}, 1, position({0},'\n') -1))), (splitByChar(',', substring({0}, 1, "
"length({0})))))",
csv_string);
return true;
}
@ -439,14 +441,14 @@ bool ParseJson::convertImpl(String & out, IParser::Pos & pos)
if (String(pos->begin, pos->end) == "dynamic")
{
--pos;
auto arg = getArgument(fn_name,pos);
auto arg = getArgument(fn_name, pos);
auto result = kqlCallToExpression("dynamic", {arg}, pos.max_depth);
out = std::format("{}", result);
}
else
{
auto arg = getConvertedArgument(fn_name, pos);
out = std::format("if (isValidJSON({0}) , JSON_QUERY({0}, '$') , toJSONString({0}))" , arg);
out = std::format("if (isValidJSON({0}) , JSON_QUERY({0}, '$') , toJSONString({0}))", arg);
}
return true;
}
@ -460,18 +462,30 @@ bool ParseURL::convertImpl(String & out, IParser::Pos & pos)
++pos;
const String url = getConvertedArgument(fn_name, pos);
const String scheme = std::format("concat('\"Scheme\":\"', protocol({0}),'\"')",url);
const String host = std::format("concat('\"Host\":\"', domain({0}),'\"')",url);
const String port = std::format("concat('\"Port\":\"', toString(port({0})),'\"')",url);
const String path = std::format("concat('\"Path\":\"', path({0}),'\"')",url);
const String username_pwd = std::format("netloc({0})",url);
const String query_string = std::format("queryString({0})",url);
const String fragment = std::format("concat('\"Fragment\":\"',fragment({0}),'\"')",url);
const String username = std::format("concat('\"Username\":\"', arrayElement(splitByChar(':',arrayElement(splitByChar('@',{0}) ,1)),1),'\"')", username_pwd);
const String password = std::format("concat('\"Password\":\"', arrayElement(splitByChar(':',arrayElement(splitByChar('@',{0}) ,1)),2),'\"')", username_pwd);
const String query_parameters = std::format("concat('\"Query Parameters\":', concat('{{\"', replace(replace({}, '=', '\":\"'),'&','\",\"') ,'\"}}'))", query_string);
const String scheme = std::format("concat('\"Scheme\":\"', protocol({0}),'\"')", url);
const String host = std::format("concat('\"Host\":\"', domain({0}),'\"')", url);
const String port = std::format("concat('\"Port\":\"', toString(port({0})),'\"')", url);
const String path = std::format("concat('\"Path\":\"', path({0}),'\"')", url);
const String username_pwd = std::format("netloc({0})", url);
const String query_string = std::format("queryString({0})", url);
const String fragment = std::format("concat('\"Fragment\":\"',fragment({0}),'\"')", url);
const String username = std::format(
"concat('\"Username\":\"', arrayElement(splitByChar(':',arrayElement(splitByChar('@',{0}) ,1)),1),'\"')", username_pwd);
const String password = std::format(
"concat('\"Password\":\"', arrayElement(splitByChar(':',arrayElement(splitByChar('@',{0}) ,1)),2),'\"')", username_pwd);
const String query_parameters = std::format(
"concat('\"Query Parameters\":', concat('{{\"', replace(replace({}, '=', '\":\"'),'&','\",\"') ,'\"}}'))", query_string);
out = std::format("concat('{{',{},',',{},',',{},',',{},',',{},',',{},',',{},',',{},'}}')",scheme, host, port, path, username, password, query_parameters,fragment);
out = std::format(
"concat('{{',{},',',{},',',{},',',{},',',{},',',{},',',{},',',{},'}}')",
scheme,
host,
port,
path,
username,
password,
query_parameters,
fragment);
return true;
}
@ -484,8 +498,9 @@ bool ParseURLQuery::convertImpl(String & out, IParser::Pos & pos)
const String query = getConvertedArgument(fn_name, pos);
const String query_string = std::format("if (position({},'?') > 0, queryString({}), {})", query, query, query);
const String query_parameters = std::format("concat('\"Query Parameters\":', concat('{{\"', replace(replace({}, '=', '\":\"'),'&','\",\"') ,'\"}}'))", query_string);
out = std::format("concat('{{',{},'}}')",query_parameters);
const String query_parameters = std::format(
"concat('\"Query Parameters\":', concat('{{\"', replace(replace({}, '=', '\":\"'),'&','\",\"') ,'\"}}'))", query_string);
out = std::format("concat('{{',{},'}}')", query_parameters);
return true;
}
@ -494,10 +509,14 @@ bool ParseVersion::convertImpl(String & out, IParser::Pos & pos)
const String fn_name = getKQLFunctionName(pos);
if (fn_name.empty())
return false;
String arg ;
String arg;
++pos;
arg = getConvertedArgument(fn_name, pos);
out = std::format("length(splitByChar('.', {0})) > 4 OR length(splitByChar('.', {0})) < 1 OR match({0}, '.*[a-zA-Z]+.*') = 1 ? toDecimal128OrNull('NULL' , 0) : toDecimal128OrNull(substring(arrayStringConcat(arrayMap(x -> leftPad(x, 8, '0'), arrayMap(x -> if(empty(x), '0', x), arrayResize(splitByChar('.', {0}), 4)))), 8),0)", arg);
out = std::format(
"length(splitByChar('.', {0})) > 4 OR length(splitByChar('.', {0})) < 1 OR match({0}, '.*[a-zA-Z]+.*') = 1 ? "
"toDecimal128OrNull('NULL' , 0) : toDecimal128OrNull(substring(arrayStringConcat(arrayMap(x -> leftPad(x, 8, '0'), arrayMap(x -> "
"if(empty(x), '0', x), arrayResize(splitByChar('.', {0}), 4)))), 8),0)",
arg);
return true;
}
@ -543,7 +562,11 @@ bool Split::convertImpl(String & out, IParser::Pos & pos)
arg.erase(remove_if(arg.begin(), arg.end(), isspace), arg.end());
requested_index = std::stoi(arg);
requested_index += 1;
out = std::format("multiIf(length({0}) >= {1} AND {1} > 0 , arrayPushBack([],arrayElement({0}, {1})) , {1}=0 ,{0} , arrayPushBack([] ,arrayElement(NULL,1)))", split_res, requested_index);
out = std::format(
"multiIf(length({0}) >= {1} AND {1} > 0 , arrayPushBack([],arrayElement({0}, {1})) , {1}=0 ,{0} , arrayPushBack([] "
",arrayElement(NULL,1)))",
split_res,
requested_index);
}
else
out = split_res;
@ -623,11 +646,11 @@ bool StrRep::convertImpl(String & out, IParser::Pos & pos)
{
++pos;
const String delimiter = getConvertedArgument(fn_name, pos);
const String repeated_str = "repeat(concat("+value+"," + delimiter + ")," + multiplier + ")";
out = "substr("+ repeated_str + ", 1, length(" + repeated_str + ") - length(" + delimiter + "))";
const String repeated_str = "repeat(concat(" + value + "," + delimiter + ")," + multiplier + ")";
out = "substr(" + repeated_str + ", 1, length(" + repeated_str + ") - length(" + delimiter + "))";
}
else
out = "repeat("+ value + ", " + multiplier + ")";
out = "repeat(" + value + ", " + multiplier + ")";
return true;
}
@ -650,13 +673,15 @@ bool SubString::convertImpl(String & out, IParser::Pos & pos)
++pos;
auto length = getConvertedArgument(fn_name, pos);
if(startingIndex.empty())
if (startingIndex.empty())
throw Exception("number of arguments do not match in function: " + fn_name, ErrorCodes::SYNTAX_ERROR);
else
out = "if(toInt64(length(" + source + ")) <= 0, '', substr("+ source + ", " + "((" + startingIndex + "% toInt64(length(" + source + ")) + toInt64(length(" + source + "))) % toInt64(length(" + source + "))) + 1, " + length + ") )";
out = "if(toInt64(length(" + source + ")) <= 0, '', substr(" + source + ", " + "((" + startingIndex + "% toInt64(length("
+ source + ")) + toInt64(length(" + source + "))) % toInt64(length(" + source + "))) + 1, " + length + ") )";
}
else
out = "if(toInt64(length(" + source + ")) <= 0, '', substr("+ source + "," + "((" + startingIndex + "% toInt64(length(" + source + ")) + toInt64(length(" + source + "))) % toInt64(length(" + source + "))) + 1))";
out = "if(toInt64(length(" + source + ")) <= 0, '', substr(" + source + "," + "((" + startingIndex + "% toInt64(length(" + source
+ ")) + toInt64(length(" + source + "))) % toInt64(length(" + source + "))) + 1))";
return true;
}
@ -686,8 +711,12 @@ bool Translate::convertImpl(String & out, IParser::Pos & pos)
String source = getConvertedArgument(fn_name, pos);
String len_diff = std::format("length({}) - length({})", from, to);
String to_str = std::format("multiIf(length({1}) = 0, {0}, {2} > 0, concat({1},repeat(substr({1},length({1}),1),toUInt16({2}))),{2} < 0 , substr({1},1,length({0})),{1})",
from, to, len_diff);
String to_str = std::format(
"multiIf(length({1}) = 0, {0}, {2} > 0, concat({1},repeat(substr({1},length({1}),1),toUInt16({2}))),{2} < 0 , "
"substr({1},1,length({0})),{1})",
from,
to,
len_diff);
out = std::format("if (length({3}) = 0,'',translate({0},{1},{2}))", source, from, to_str, to);
return true;
}

View File

@ -10,267 +10,266 @@ class Base64EncodeToString : public IParserKQLFunction
{
protected:
const char * getName() const override { return "base64_encode_tostring()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Base64EncodeFromGuid : public IParserKQLFunction
{
protected:
const char * getName() const override { return "base64_encode_fromguid()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Base64DecodeToString : public IParserKQLFunction
{
protected:
const char * getName() const override { return "base64_decode_tostring()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Base64DecodeToArray : public IParserKQLFunction
{
protected:
const char * getName() const override { return "base64_decode_toarray()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Base64DecodeToGuid : public IParserKQLFunction
{
protected:
const char * getName() const override { return "base64_decode_toguid()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class CountOf : public IParserKQLFunction
{
protected:
const char * getName() const override { return "countof()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Extract : public IParserKQLFunction
{
protected:
const char * getName() const override { return "extract()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ExtractAll : public IParserKQLFunction
{
protected:
const char * getName() const override { return "extract_all()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ExtractJson : public IParserKQLFunction
{
protected:
const char * getName() const override { return "extract_json(), extractjson()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class HasAnyIndex : public IParserKQLFunction
{
protected:
const char * getName() const override { return "has_any_index()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class IndexOf : public IParserKQLFunction
{
protected:
const char * getName() const override { return "indexof()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class IsEmpty : public IParserKQLFunction
{
protected:
const char * getName() const override { return "isempty()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class IsNotEmpty : public IParserKQLFunction
{
protected:
const char * getName() const override { return "isnotempty()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class IsNotNull : public IParserKQLFunction
{
protected:
const char * getName() const override { return "isnotnull()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class IsNull : public IParserKQLFunction
{
protected:
const char * getName() const override { return "isnull()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ParseCommandLine : public IParserKQLFunction
{
protected:
const char * getName() const override { return "parse_command_line()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ParseCSV : public IParserKQLFunction
{
protected:
const char * getName() const override { return "parse_csv()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ParseJson : public IParserKQLFunction
{
protected:
const char * getName() const override { return "parse_json()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ParseURL : public IParserKQLFunction
{
protected:
const char * getName() const override { return "parse_url()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ParseURLQuery : public IParserKQLFunction
{
protected:
const char * getName() const override { return "parse_urlquery()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ParseVersion : public IParserKQLFunction
{
protected:
const char * getName() const override { return "parse_version()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ReplaceRegex : public IParserKQLFunction
{
protected:
const char * getName() const override { return "replace_regex()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Reverse : public IParserKQLFunction
{
protected:
const char * getName() const override { return "reverse()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Split : public IParserKQLFunction
{
protected:
const char * getName() const override { return "split()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class StrCat : public IParserKQLFunction
{
protected:
const char * getName() const override { return "strcat()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class StrCatDelim : public IParserKQLFunction
{
protected:
const char * getName() const override { return "strcat_delim()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class StrCmp : public IParserKQLFunction
{
protected:
const char * getName() const override { return "strcmp()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class StrLen : public IParserKQLFunction
{
protected:
const char * getName() const override { return "strlen()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class StrRep : public IParserKQLFunction
{
protected:
const char * getName() const override { return "strrep()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SubString : public IParserKQLFunction
{
protected:
const char * getName() const override { return "substring()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ToLower : public IParserKQLFunction
{
protected:
const char * getName() const override { return "tolower()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class ToUpper : public IParserKQLFunction
{
protected:
const char * getName() const override { return "toupper()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Translate : public IParserKQLFunction
{
protected:
const char * getName() const override { return "translate()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class Trim : public IParserKQLFunction
{
protected:
const char * getName() const override { return "trim()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class TrimEnd : public IParserKQLFunction
{
protected:
const char * getName() const override { return "trim_end()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class TrimStart : public IParserKQLFunction
{
protected:
const char * getName() const override { return "trim_start()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class URLDecode : public IParserKQLFunction
{
protected:
const char * getName() const override { return "url_decode()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class URLEncode : public IParserKQLFunction
{
protected:
const char * getName() const override { return "url_encode()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
}

View File

@ -1,124 +1,124 @@
#include <Parsers/IParserBase.h>
#include <Parsers/ParserSetQuery.h>
#include <Parsers/ASTExpressionList.h>
#include <Parsers/ASTSelectWithUnionQuery.h>
#include <Parsers/IParserBase.h>
#include <Parsers/Kusto/KustoFunctions/IParserKQLFunction.h>
#include <Parsers/Kusto/KustoFunctions/KQLAggregationFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLBinaryFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLCastingFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLDateTimeFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLDynamicFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLGeneralFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLIPFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLStringFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLTimeSeriesFunctions.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLStatement.h>
#include <Parsers/Kusto/KustoFunctions/IParserKQLFunction.h>
#include <Parsers/Kusto/KustoFunctions/KQLDateTimeFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLStringFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLDynamicFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLCastingFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLAggregationFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLTimeSeriesFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLIPFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLBinaryFunctions.h>
#include <Parsers/Kusto/KustoFunctions/KQLGeneralFunctions.h>
#include <Parsers/ParserSetQuery.h>
namespace DB
{
bool SeriesFir::convertImpl(String &out,IParser::Pos &pos)
bool SeriesFir::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool SeriesIir::convertImpl(String &out,IParser::Pos &pos)
bool SeriesIir::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool SeriesFitLine::convertImpl(String &out,IParser::Pos &pos)
bool SeriesFitLine::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool SeriesFitLineDynamic::convertImpl(String &out,IParser::Pos &pos)
bool SeriesFitLineDynamic::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool SeriesFit2lines::convertImpl(String &out,IParser::Pos &pos)
bool SeriesFit2lines::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool SeriesFit2linesDynamic::convertImpl(String &out,IParser::Pos &pos)
bool SeriesFit2linesDynamic::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool SeriesOutliers::convertImpl(String &out,IParser::Pos &pos)
bool SeriesOutliers::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool SeriesPeriodsDetect::convertImpl(String &out,IParser::Pos &pos)
bool SeriesPeriodsDetect::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool SeriesPeriodsValidate::convertImpl(String &out,IParser::Pos &pos)
bool SeriesPeriodsValidate::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool SeriesStatsDynamic::convertImpl(String &out,IParser::Pos &pos)
bool SeriesStatsDynamic::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool SeriesStats::convertImpl(String &out,IParser::Pos &pos)
bool SeriesStats::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool SeriesFillBackward::convertImpl(String &out,IParser::Pos &pos)
bool SeriesFillBackward::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool SeriesFillConst::convertImpl(String &out,IParser::Pos &pos)
bool SeriesFillConst::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool SeriesFillForward::convertImpl(String &out,IParser::Pos &pos)
bool SeriesFillForward::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}
bool SeriesFillLinear::convertImpl(String &out,IParser::Pos &pos)
bool SeriesFillLinear::convertImpl(String & out, IParser::Pos & pos)
{
String res = String(pos->begin,pos->end);
String res = String(pos->begin, pos->end);
out = res;
return false;
}

View File

@ -8,106 +8,105 @@ class SeriesFir : public IParserKQLFunction
{
protected:
const char * getName() const override { return "series_fir()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SeriesIir : public IParserKQLFunction
{
protected:
const char * getName() const override { return "series_iir()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SeriesFitLine : public IParserKQLFunction
{
protected:
const char * getName() const override { return "series_fit_line()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SeriesFitLineDynamic : public IParserKQLFunction
{
protected:
const char * getName() const override { return "series_fit_line_dynamic()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SeriesFit2lines : public IParserKQLFunction
{
protected:
const char * getName() const override { return "series_fit_2lines()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SeriesFit2linesDynamic : public IParserKQLFunction
{
protected:
const char * getName() const override { return "series_fit_2lines_dynamic()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SeriesOutliers : public IParserKQLFunction
{
protected:
const char * getName() const override { return "series_outliers()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SeriesPeriodsDetect : public IParserKQLFunction
{
protected:
const char * getName() const override { return "series_periods_detect()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SeriesPeriodsValidate : public IParserKQLFunction
{
protected:
const char * getName() const override { return "series_periods_validate()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SeriesStatsDynamic : public IParserKQLFunction
{
protected:
const char * getName() const override { return "series_stats_dynamic()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SeriesStats : public IParserKQLFunction
{
protected:
const char * getName() const override { return "series_stats()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SeriesFillBackward : public IParserKQLFunction
{
protected:
const char * getName() const override { return "series_fill_backward()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SeriesFillConst : public IParserKQLFunction
{
protected:
const char * getName() const override { return "series_fill_const()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SeriesFillForward : public IParserKQLFunction
{
protected:
const char * getName() const override { return "series_fill_forward()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
class SeriesFillLinear : public IParserKQLFunction
{
protected:
const char * getName() const override { return "series_fill_linear()"; }
bool convertImpl(String &out,IParser::Pos &pos) override;
bool convertImpl(String & out, IParser::Pos & pos) override;
};
}

View File

@ -1,24 +1,24 @@
#include <Parsers/IParserBase.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLDateTypeTimespan.h>
#include <Common/StringUtils/StringUtils.h>
#include <cstdlib>
#include <unordered_map>
#include <format>
#include <unordered_map>
#include <math.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/IParserBase.h>
#include <Parsers/Kusto/ParserKQLDateTypeTimespan.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Common/StringUtils/StringUtils.h>
namespace DB
{
bool ParserKQLDateTypeTimespan :: parseImpl(Pos & pos, [[maybe_unused]] ASTPtr & node, Expected & expected)
bool ParserKQLDateTypeTimespan ::parseImpl(Pos & pos, [[maybe_unused]] ASTPtr & node, Expected & expected)
{
String token;
const char * current_word = pos->begin;
expected.add(pos, current_word);
if (pos->type == TokenType::QuotedIdentifier || pos->type == TokenType::StringLiteral )
token = String(pos->begin + 1, pos->end -1);
if (pos->type == TokenType::QuotedIdentifier || pos->type == TokenType::StringLiteral)
token = String(pos->begin + 1, pos->end - 1);
else
token = String(pos->begin, pos->end);
if (!parseConstKQLTimespan(token))
@ -27,7 +27,7 @@ bool ParserKQLDateTypeTimespan :: parseImpl(Pos & pos, [[maybe_unused]] ASTPtr
return true;
}
double ParserKQLDateTypeTimespan :: toSeconds()
double ParserKQLDateTypeTimespan ::toSeconds()
{
switch (time_span_unit)
{
@ -38,7 +38,7 @@ double ParserKQLDateTypeTimespan :: toSeconds()
case KQLTimespanUint::minute:
return time_span * 60;
case KQLTimespanUint::second:
return time_span ;
return time_span;
case KQLTimespanUint::millisec:
return time_span / 1000.0;
case KQLTimespanUint::microsec:
@ -50,11 +50,10 @@ double ParserKQLDateTypeTimespan :: toSeconds()
}
}
bool ParserKQLDateTypeTimespan :: parseConstKQLTimespan(const String & text)
bool ParserKQLDateTypeTimespan ::parseConstKQLTimespan(const String & text)
{
std::unordered_map <String, KQLTimespanUint> TimespanSuffixes =
{
{"d", KQLTimespanUint::day},
std::unordered_map<String, KQLTimespanUint> TimespanSuffixes
= {{"d", KQLTimespanUint::day},
{"day", KQLTimespanUint::day},
{"days", KQLTimespanUint::day},
{"h", KQLTimespanUint::hour},
@ -87,8 +86,7 @@ bool ParserKQLDateTypeTimespan :: parseConstKQLTimespan(const String & text)
{"nanosecond", KQLTimespanUint::nanosec},
{"nanoseconds", KQLTimespanUint::nanosec},
{"tick", KQLTimespanUint::tick},
{"ticks", KQLTimespanUint::tick}
};
{"ticks", KQLTimespanUint::tick}};
int days = 0, hours = 0, minutes = 0, seconds = 0, sec_scale_len = 0;
double nanoseconds = 00.00;
@ -96,7 +94,7 @@ bool ParserKQLDateTypeTimespan :: parseConstKQLTimespan(const String & text)
const char * ptr = text.c_str();
bool sign = false;
auto scanDigit = [&](const char *start) -> int
auto scanDigit = [&](const char * start) -> int
{
auto index = start;
while (isdigit(*index))
@ -126,7 +124,7 @@ bool ParserKQLDateTypeTimespan :: parseConstKQLTimespan(const String & text)
else if (*(ptr + number_len) == '\0')
{
if (sign)
time_span = -(std::stoi(String(ptr, ptr + number_len))) * 86400 ;
time_span = -(std::stoi(String(ptr, ptr + number_len))) * 86400;
else
time_span = std::stoi(String(ptr, ptr + number_len)) * 86400;
@ -148,7 +146,7 @@ bool ParserKQLDateTypeTimespan :: parseConstKQLTimespan(const String & text)
return false;
time_span = std::stod(String(ptr, ptr + number_len));
time_span_unit = TimespanSuffixes[timespan_suffix] ;
time_span_unit = TimespanSuffixes[timespan_suffix];
return true;
}
@ -189,12 +187,12 @@ bool ParserKQLDateTypeTimespan :: parseConstKQLTimespan(const String & text)
}
}
auto exponent = 9 - sec_scale_len; // max supported length of fraction of seconds is 9
nanoseconds = nanoseconds * pow(10, exponent );
nanoseconds = nanoseconds * pow(10, exponent);
if (sign)
time_span = -(days * 86400 + hours * 3600 + minutes * 60 + seconds + (nanoseconds /1000000000 ));
time_span = -(days * 86400 + hours * 3600 + minutes * 60 + seconds + (nanoseconds / 1000000000));
else
time_span = days * 86400 + hours * 3600 + minutes * 60 + seconds + (nanoseconds /1000000000 );
time_span = days * 86400 + hours * 3600 + minutes * 60 + seconds + (nanoseconds / 1000000000);
time_span_unit = KQLTimespanUint::second;

View File

@ -9,7 +9,7 @@ namespace DB
class ParserKQLDateTypeTimespan : public ParserKQLBase
{
public:
enum class KQLTimespanUint: uint8_t
enum class KQLTimespanUint : uint8_t
{
day,
hour,
@ -20,7 +20,7 @@ public:
nanosec,
tick
};
bool parseConstKQLTimespan(const String &text);
bool parseConstKQLTimespan(const String & text);
double toSeconds();
protected:
@ -33,4 +33,3 @@ private:
};
}

View File

@ -1,6 +1,6 @@
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLDistinct.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
namespace DB
{

View File

@ -8,7 +8,6 @@ namespace DB
class ParserKQLDistinct : public ParserKQLBase
{
protected:
const char * getName() const override { return "KQL distinct"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;

View File

@ -1,18 +1,18 @@
#include <format>
#include <Parsers/ASTLiteral.h>
#include <Parsers/IParserBase.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/ParserTablesInSelectQuery.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/IParserBase.h>
#include <Parsers/Kusto/ParserKQLExtend.h>
#include <Parsers/Kusto/ParserKQLMakeSeries.h>
#include <Parsers/Kusto/ParserKQLOperators.h>
#include <Parsers/Kusto/ParserKQLExtend.h>
#include <Parsers/Kusto/ParserKQLProject.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/ParserSelectQuery.h>
#include <format>
#include <Parsers/ParserTablesInSelectQuery.h>
namespace DB
{
bool ParserKQLExtend :: parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
bool ParserKQLExtend ::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ASTPtr select_query;
int32_t new_column_index = 1;
@ -26,7 +26,7 @@ bool ParserKQLExtend :: parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
String alias;
auto apply_alias =[&]
auto apply_alias = [&]
{
if (alias.empty())
{

View File

@ -1,16 +1,14 @@
#pragma once
#include <Parsers/IParserBase.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLProject.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
namespace DB
{
class ParserKQLExtend : public ParserKQLBase
{
protected:
const char * getName() const override { return "KQL extend"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;

View File

@ -1,9 +1,9 @@
#include <Parsers/ASTLiteral.h>
#include <Parsers/IParserBase.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/IParserBase.h>
#include <Parsers/Kusto/ParserKQLFilter.h>
#include <Parsers/Kusto/ParserKQLOperators.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
namespace DB
{
@ -13,7 +13,7 @@ bool ParserKQLFilter::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
String expr = getExprFromToken(pos);
ASTPtr where_expression;
Tokens token_filter(expr.c_str(), expr.c_str()+expr.size());
Tokens token_filter(expr.c_str(), expr.c_str() + expr.size());
IParser::Pos pos_filter(token_filter, pos.max_depth);
if (!ParserExpressionWithOptionalAlias(false).parse(pos_filter, where_expression, expected))
return false;

View File

@ -1,8 +1,8 @@
#include <Parsers/IParserBase.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLLimit.h>
#include <cstdlib>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/IParserBase.h>
#include <Parsers/Kusto/ParserKQLLimit.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
namespace DB
{

View File

@ -1,15 +1,15 @@
#include <Parsers/ASTLiteral.h>
#include <Parsers/IParserBase.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/ParserTablesInSelectQuery.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLMakeSeries.h>
#include <Parsers/Kusto/ParserKQLOperators.h>
#include <Parsers/Kusto/ParserKQLMVExpand.h>
#include <Parsers/ParserSetQuery.h>
#include <Parsers/ParserSelectQuery.h>
#include <format>
#include <unordered_map>
#include <Parsers/ASTLiteral.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/IParserBase.h>
#include <Parsers/Kusto/ParserKQLMVExpand.h>
#include <Parsers/Kusto/ParserKQLMakeSeries.h>
#include <Parsers/Kusto/ParserKQLOperators.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/ParserSelectQuery.h>
#include <Parsers/ParserSetQuery.h>
#include <Parsers/ParserTablesInSelectQuery.h>
namespace DB::ErrorCodes
{
@ -19,8 +19,8 @@ extern const int UNKNOWN_TYPE;
namespace DB
{
std::unordered_map<String,String> ParserKQLMVExpand::type_cast =
{ {"bool", "Boolean"},
std::unordered_map<String, String> ParserKQLMVExpand::type_cast
= {{"bool", "Boolean"},
{"boolean", "Boolean"},
{"datetime", "DateTime"},
{"date", "DateTime"},
@ -29,8 +29,7 @@ std::unordered_map<String,String> ParserKQLMVExpand::type_cast =
{"long", "Int64"},
{"real", "Float64"},
{"double", "Float64"},
{"string", "String"}
};
{"string", "String"}};
bool ParserKQLMVExpand::parseColumnArrayExprs(ColumnArrayExprs & column_array_exprs, Pos & pos, Expected & expected)
{
@ -52,13 +51,13 @@ bool ParserKQLMVExpand::parseColumnArrayExprs(ColumnArrayExprs & column_array_ex
while (!pos->isEnd() && pos->type != TokenType::PipeMark && pos->type != TokenType::Semicolon)
{
if(pos->type == TokenType::OpeningRoundBracket)
if (pos->type == TokenType::OpeningRoundBracket)
++bracket_count;
if(pos->type == TokenType::ClosingRoundBracket)
if (pos->type == TokenType::ClosingRoundBracket)
--bracket_count;
if (String(pos->begin,pos->end) == "=")
if (String(pos->begin, pos->end) == "=")
{
--pos;
alias = String(pos->begin, pos->end);
@ -73,7 +72,7 @@ bool ParserKQLMVExpand::parseColumnArrayExprs(ColumnArrayExprs & column_array_ex
if (alias.empty())
{
alias = expr_begin_pos == expr_end_pos ? column_array_expr : String(expr_begin_pos->begin,expr_begin_pos->end) + "_";
alias = expr_begin_pos == expr_end_pos ? column_array_expr : String(expr_begin_pos->begin, expr_begin_pos->end) + "_";
}
column_array_exprs.push_back(ColumnArrayExpr(alias, column_array_expr, to_type));
};
@ -102,7 +101,8 @@ bool ParserKQLMVExpand::parseColumnArrayExprs(ColumnArrayExprs & column_array_ex
return false;
}
if ((pos->type == TokenType::Comma && bracket_count == 0) || String(pos->begin, pos->end) == "limit" || pos->type == TokenType::Semicolon)
if ((pos->type == TokenType::Comma && bracket_count == 0) || String(pos->begin, pos->end) == "limit"
|| pos->type == TokenType::Semicolon)
{
if (column_array_expr.empty())
{
@ -190,8 +190,8 @@ bool ParserKQLMVExpand::parserMVExpand(KQLMVExpand & kql_mv_expand, Pos & pos, E
bool ParserKQLMVExpand::genQuery(KQLMVExpand & kql_mv_expand, ASTPtr & select_node, int32_t max_depth)
{
String expand_str;
String cast_type_column_remove, cast_type_column_rename ;
String cast_type_column_restore, cast_type_column_restore_name ;
String cast_type_column_remove, cast_type_column_rename;
String cast_type_column_restore, cast_type_column_restore_name;
String row_count_str;
String extra_columns;
String input = "dummy_input";
@ -201,28 +201,35 @@ bool ParserKQLMVExpand::genQuery(KQLMVExpand & kql_mv_expand, ASTPtr & select_no
expand_str = expand_str.empty() ? String("ARRAY JOIN ") + column.alias : expand_str + "," + column.alias;
else
{
expand_str = expand_str.empty() ? std::format("ARRAY JOIN {} AS {} ", column.column_array_expr, column.alias): expand_str + std::format(", {} AS {}", column.column_array_expr, column.alias);
expand_str = expand_str.empty() ? std::format("ARRAY JOIN {} AS {} ", column.column_array_expr, column.alias)
: expand_str + std::format(", {} AS {}", column.column_array_expr, column.alias);
extra_columns = extra_columns + ", " + column.alias;
}
if (!column.to_type.empty())
{
cast_type_column_remove = cast_type_column_remove.empty() ? " Except " + column.alias : cast_type_column_remove + " Except " + column.alias ;
cast_type_column_remove
= cast_type_column_remove.empty() ? " Except " + column.alias : cast_type_column_remove + " Except " + column.alias;
String rename_str;
if (type_cast[column.to_type] == "Boolean")
rename_str = std::format("accurateCastOrNull(toInt64OrNull(toString({0})),'{1}') as {0}_ali",column.alias, type_cast[column.to_type]);
rename_str = std::format(
"accurateCastOrNull(toInt64OrNull(toString({0})),'{1}') as {0}_ali", column.alias, type_cast[column.to_type]);
else
rename_str = std::format("accurateCastOrNull({0},'{1}') as {0}_ali",column.alias, type_cast[column.to_type]);
rename_str = std::format("accurateCastOrNull({0},'{1}') as {0}_ali", column.alias, type_cast[column.to_type]);
cast_type_column_rename = cast_type_column_rename.empty() ? rename_str : cast_type_column_rename + "," + rename_str;
cast_type_column_restore = cast_type_column_restore.empty() ? std::format(" Except {}_ali ", column.alias) : cast_type_column_restore + std::format(" Except {}_ali ", column.alias);
cast_type_column_restore_name = cast_type_column_restore_name.empty() ? std::format("{0}_ali as {0}", column.alias ) :cast_type_column_restore_name + std::format(", {0}_ali as {0}", column.alias);
cast_type_column_restore = cast_type_column_restore.empty()
? std::format(" Except {}_ali ", column.alias)
: cast_type_column_restore + std::format(" Except {}_ali ", column.alias);
cast_type_column_restore_name = cast_type_column_restore_name.empty()
? std::format("{0}_ali as {0}", column.alias)
: cast_type_column_restore_name + std::format(", {0}_ali as {0}", column.alias);
}
if (!kql_mv_expand.with_itemindex.empty())
{
row_count_str = row_count_str.empty() ? "length("+column.alias+")" : row_count_str + ", length("+column.alias+")";
row_count_str = row_count_str.empty() ? "length(" + column.alias + ")" : row_count_str + ", length(" + column.alias + ")";
}
}

View File

@ -8,20 +8,23 @@ namespace DB
class ParserKQLMVExpand : public ParserKQLBase
{
protected:
static std::unordered_map<String,String> type_cast;
static std::unordered_map<String, String> type_cast;
struct ColumnArrayExpr {
struct ColumnArrayExpr
{
String alias;
String column_array_expr;
String to_type;
ColumnArrayExpr(String alias_, String column_array_expr_, String to_type_)
:alias(alias_), column_array_expr(column_array_expr_), to_type(to_type_){}
: alias(alias_), column_array_expr(column_array_expr_), to_type(to_type_)
{
}
};
using ColumnArrayExprs = std::vector<ColumnArrayExpr>;
struct KQLMVExpand {
struct KQLMVExpand
{
ColumnArrayExprs column_array_exprs;
String bagexpansion;
String with_itemindex;

View File

@ -1,22 +1,21 @@
#include <format>
#include <Parsers/ASTLiteral.h>
#include <Parsers/IParserBase.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/ParserTablesInSelectQuery.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/IParserBase.h>
#include <Parsers/Kusto/ParserKQLDateTypeTimespan.h>
#include <Parsers/Kusto/ParserKQLMakeSeries.h>
#include <Parsers/Kusto/ParserKQLOperators.h>
#include <Parsers/Kusto/ParserKQLDateTypeTimespan.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/ParserSelectQuery.h>
#include <format>
#include <Parsers/ParserTablesInSelectQuery.h>
namespace DB
{
bool ParserKQLMakeSeries :: parseAggregationColumns(AggregationColumns & aggregation_columns, Pos & pos)
bool ParserKQLMakeSeries ::parseAggregationColumns(AggregationColumns & aggregation_columns, Pos & pos)
{
std::unordered_set<String> allowed_aggregation
({
"avg",
std::unordered_set<String> allowed_aggregation(
{"avg",
"avgif",
"count",
"countif",
@ -31,8 +30,7 @@ bool ParserKQLMakeSeries :: parseAggregationColumns(AggregationColumns & aggrega
"stdev",
"sum",
"sumif",
"variance"
});
"variance"});
Expected expected;
ParserKeyword s_default("default");
@ -48,13 +46,13 @@ bool ParserKQLMakeSeries :: parseAggregationColumns(AggregationColumns & aggrega
String column;
double default_value = 0;
String first_token(pos->begin,pos->end);
String first_token(pos->begin, pos->end);
++pos;
if (equals.ignore(pos, expected))
{
alias = std::move(first_token);
aggregation_fun = String(pos->begin,pos->end);
aggregation_fun = String(pos->begin, pos->end);
++pos;
}
else
@ -64,7 +62,7 @@ bool ParserKQLMakeSeries :: parseAggregationColumns(AggregationColumns & aggrega
return false;
if (open_bracket.ignore(pos, expected))
column = String(pos->begin,pos->end);
column = String(pos->begin, pos->end);
else
return false;
@ -77,7 +75,7 @@ bool ParserKQLMakeSeries :: parseAggregationColumns(AggregationColumns & aggrega
if (!equals.ignore(pos, expected))
return false;
default_value = std::stod(String(pos->begin,pos->end));
default_value = std::stod(String(pos->begin, pos->end));
++pos;
}
if (alias.empty())
@ -90,7 +88,7 @@ bool ParserKQLMakeSeries :: parseAggregationColumns(AggregationColumns & aggrega
return true;
}
bool ParserKQLMakeSeries :: parseFromToStepClause(FromToStepClause & from_to_step, Pos & pos)
bool ParserKQLMakeSeries ::parseFromToStepClause(FromToStepClause & from_to_step, Pos & pos)
{
auto begin = pos;
auto from_pos = begin;
@ -100,13 +98,13 @@ bool ParserKQLMakeSeries :: parseFromToStepClause(FromToStepClause & from_to_ste
while (!pos->isEnd() && pos->type != TokenType::PipeMark && pos->type != TokenType::Semicolon)
{
if ( String(pos->begin, pos->end) == "from")
if (String(pos->begin, pos->end) == "from")
from_pos = pos;
if ( String(pos->begin, pos->end) == "to")
if (String(pos->begin, pos->end) == "to")
to_pos = pos;
if ( String(pos->begin, pos->end) == "step")
if (String(pos->begin, pos->end) == "step")
step_pos = pos;
if ( String(pos->begin, pos->end) == "by")
if (String(pos->begin, pos->end) == "by")
{
end_pos = pos;
break;
@ -129,7 +127,8 @@ bool ParserKQLMakeSeries :: parseFromToStepClause(FromToStepClause & from_to_ste
}
if (String(to_pos->begin, to_pos->end) == "to")
{ ++to_pos;
{
++to_pos;
--step_pos;
from_to_step.to_str = String(to_pos->begin, step_pos->end);
++step_pos;
@ -138,7 +137,8 @@ bool ParserKQLMakeSeries :: parseFromToStepClause(FromToStepClause & from_to_ste
++step_pos;
from_to_step.step_str = String(step_pos->begin, end_pos->end);
if (String(step_pos->begin, step_pos->end) == "time" || String(step_pos->begin, step_pos->end) == "timespan" || ParserKQLDateTypeTimespan().parseConstKQLTimespan(from_to_step.step_str))
if (String(step_pos->begin, step_pos->end) == "time" || String(step_pos->begin, step_pos->end) == "timespan"
|| ParserKQLDateTypeTimespan().parseConstKQLTimespan(from_to_step.step_str))
{
from_to_step.is_timespan = true;
from_to_step.step = std::stod(getExprFromToken(from_to_step.step_str, pos.max_depth));
@ -149,9 +149,10 @@ bool ParserKQLMakeSeries :: parseFromToStepClause(FromToStepClause & from_to_ste
return true;
}
bool ParserKQLMakeSeries :: makeSeries(KQLMakeSeries & kql_make_series, ASTPtr & select_node, const uint32_t & max_depth)
bool ParserKQLMakeSeries ::makeSeries(KQLMakeSeries & kql_make_series, ASTPtr & select_node, const uint32_t & max_depth)
{
const uint64_t era_diff = 62135596800; // this magic number is the differicen is second form 0001-01-01 (Azure start time ) and 1970-01-01 (CH start time)
const uint64_t era_diff
= 62135596800; // this magic number is the differicen is second form 0001-01-01 (Azure start time ) and 1970-01-01 (CH start time)
String start_str, end_str;
String sub_query, main_query;
@ -169,7 +170,7 @@ bool ParserKQLMakeSeries :: makeSeries(KQLMakeSeries & kql_make_series, ASTPtr &
if (!kql_make_series.from_to_step.to_str.empty())
end_str = getExprFromToken(from_to_step.to_str, max_depth);
auto date_type_cast = [&] (String & src)
auto date_type_cast = [&](String & src)
{
Tokens tokens(src.c_str(), src.c_str() + src.size());
IParser::Pos pos(tokens, max_depth);
@ -178,7 +179,7 @@ bool ParserKQLMakeSeries :: makeSeries(KQLMakeSeries & kql_make_series, ASTPtr &
{
String tmp = String(pos->begin, pos->end);
if (tmp == "parseDateTime64BestEffortOrNull")
tmp ="toDateTime64";
tmp = "toDateTime64";
res = res.empty() ? tmp : res + " " + tmp;
++pos;
@ -230,8 +231,12 @@ bool ParserKQLMakeSeries :: makeSeries(KQLMakeSeries & kql_make_series, ASTPtr &
if (!start_str.empty()) // has from
{
bin_str = std::format(" toFloat64({0}) + (toInt64((({1} - toFloat64({0})) / {2}) ) * {2}) AS {3}_ali ",
start_str, axis_column_format, step, axis_column);
bin_str = std::format(
" toFloat64({0}) + (toInt64((({1} - toFloat64({0})) / {2}) ) * {2}) AS {3}_ali ",
start_str,
axis_column_format,
step,
axis_column);
start = std::format("toUInt64({})", start_str);
}
else
@ -271,9 +276,22 @@ bool ParserKQLMakeSeries :: makeSeries(KQLMakeSeries & kql_make_series, ASTPtr &
String sub_sub_query;
if (group_expression.empty())
sub_sub_query = std::format(" (Select {0}, {1} FROM {2} {4} GROUP BY {3}_ali ORDER BY {3}_ali) ", subquery_columns, bin_str, "table_name", axis_column, condition);
sub_sub_query = std::format(
" (Select {0}, {1} FROM {2} {4} GROUP BY {3}_ali ORDER BY {3}_ali) ",
subquery_columns,
bin_str,
"table_name",
axis_column,
condition);
else
sub_sub_query = std::format(" (Select {0}, {1}, {2} FROM {3} {5} GROUP BY {0}, {4}_ali ORDER BY {4}_ali) ", group_expression, subquery_columns, bin_str, "table_name", axis_column, condition);
sub_sub_query = std::format(
" (Select {0}, {1}, {2} FROM {3} {5} GROUP BY {0}, {4}_ali ORDER BY {4}_ali) ",
group_expression,
subquery_columns,
bin_str,
"table_name",
axis_column,
condition);
ASTPtr sub_query_node;
@ -285,12 +303,18 @@ bool ParserKQLMakeSeries :: makeSeries(KQLMakeSeries & kql_make_series, ASTPtr &
main_query = std::format("{} ", group_expression_alias);
auto axis_and_agg_alias_list = axis_column;
auto final_axis_agg_alias_list =std::format("tupleElement(zipped,1) AS {}", axis_column);
auto final_axis_agg_alias_list = std::format("tupleElement(zipped,1) AS {}", axis_column);
int idx = 2;
for (auto agg_column : aggregation_columns)
{
String agg_group_column = std::format("arrayConcat(groupArray ({}_ali) as ga, arrayMap(x -> ({}),range(0,toUInt32 ({} - length(ga) < 0 ? 0 : {} - length(ga)),1) )) as {}",
agg_column.alias, agg_column.default_value, range_len, range_len, agg_column.alias);
String agg_group_column = std::format(
"arrayConcat(groupArray ({}_ali) as ga, arrayMap(x -> ({}),range(0,toUInt32 ({} - length(ga) < 0 ? 0 : {} - length(ga)),1) )) "
"as {}",
agg_column.alias,
agg_column.default_value,
range_len,
range_len,
agg_column.alias);
main_query = main_query.empty() ? agg_group_column : main_query + ", " + agg_group_column;
axis_and_agg_alias_list += ", " + agg_column.alias;
@ -298,17 +322,28 @@ bool ParserKQLMakeSeries :: makeSeries(KQLMakeSeries & kql_make_series, ASTPtr &
}
if (from_to_step.is_timespan)
axis_str = std::format("arrayDistinct(arrayConcat(groupArray(toDateTime64({0}_ali - {1},9,'UTC')), arrayMap( x->(toDateTime64(x - {1} ,9,'UTC')), {2}) )) as {0}",
axis_column, diff, range);
axis_str = std::format(
"arrayDistinct(arrayConcat(groupArray(toDateTime64({0}_ali - {1},9,'UTC')), arrayMap( x->(toDateTime64(x - {1} ,9,'UTC')), "
"{2}) )) as {0}",
axis_column,
diff,
range);
else
axis_str = std::format("arrayDistinct(arrayConcat(groupArray({0}_ali), arrayMap( x->(toFloat64(x)), {1}) )) as {0}",
axis_column, range);
axis_str
= std::format("arrayDistinct(arrayConcat(groupArray({0}_ali), arrayMap( x->(toFloat64(x)), {1}) )) as {0}", axis_column, range);
main_query += ", " + axis_str;
auto sub_group_by = group_expression.empty() ? "" : std::format("GROUP BY {}", group_expression_alias);
sub_query = std::format("( SELECT toUInt64(min({}_ali)) AS low, toUInt64(max({}_ali))+ {} AS high, arraySort(arrayZip({})) as zipped, {} FROM {} {} )",
axis_column, axis_column,step, axis_and_agg_alias_list, main_query, sub_sub_query, sub_group_by);
sub_query = std::format(
"( SELECT toUInt64(min({}_ali)) AS low, toUInt64(max({}_ali))+ {} AS high, arraySort(arrayZip({})) as zipped, {} FROM {} {} )",
axis_column,
axis_column,
step,
axis_and_agg_alias_list,
main_query,
sub_sub_query,
sub_group_by);
if (group_expression.empty())
main_query = std::format("{}", final_axis_agg_alias_list);
@ -325,7 +360,7 @@ bool ParserKQLMakeSeries :: makeSeries(KQLMakeSeries & kql_make_series, ASTPtr &
return true;
}
bool ParserKQLMakeSeries :: parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
bool ParserKQLMakeSeries ::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
auto begin = pos;
ParserKeyword s_on("on");
@ -372,7 +407,7 @@ bool ParserKQLMakeSeries :: parseImpl(Pos & pos, ASTPtr & node, Expected & expec
if (subquery_columns.empty())
subquery_columns = column_str;
else
subquery_columns += ", "+ column_str;
subquery_columns += ", " + column_str;
}
makeSeries(kql_make_series, node, pos.max_depth);

View File

@ -8,19 +8,22 @@ namespace DB
class ParserKQLMakeSeries : public ParserKQLBase
{
protected:
struct AggregationColumn {
struct AggregationColumn
{
String alias;
String aggregation_fun;
String column;
double default_value;
AggregationColumn(String alias_, String aggregation_fun_, String column_, double default_value_ )
:alias(alias_), aggregation_fun(aggregation_fun_), column(column_), default_value(default_value_){}
AggregationColumn(String alias_, String aggregation_fun_, String column_, double default_value_)
: alias(alias_), aggregation_fun(aggregation_fun_), column(column_), default_value(default_value_)
{
}
};
using AggregationColumns = std::vector<AggregationColumn>;
struct FromToStepClause {
struct FromToStepClause
{
String from_str;
String to_str;
String step_str;
@ -28,7 +31,8 @@ protected:
double step;
};
struct KQLMakeSeries {
struct KQLMakeSeries
{
AggregationColumns aggregation_columns;
FromToStepClause from_to_step;
String axis_column;
@ -44,7 +48,6 @@ protected:
const char * getName() const override { return "KQL make-series"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
};
}

View File

@ -1,10 +1,10 @@
#include <Parsers/ASTLiteral.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLOperators.h>
#include <Parsers/CommonParsers.h>
#include <Parsers/Kusto/KustoFunctions/IParserKQLFunction.h>
#include <Parsers/Kusto/KustoFunctions/KQLFunctionFactory.h>
#include <Parsers/Kusto/ParserKQLOperators.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLStatement.h>
#include <Parsers/CommonParsers.h>
namespace DB
{
@ -14,7 +14,7 @@ namespace ErrorCodes
extern const int SYNTAX_ERROR;
}
String KQLOperators::genHasAnyAllOpExpr(std::vector<String> &tokens, IParser::Pos &token_pos,String kql_op, String ch_op)
String KQLOperators::genHasAnyAllOpExpr(std::vector<String> & tokens, IParser::Pos & token_pos, String kql_op, String ch_op)
{
String new_expr;
Expected expected;
@ -31,7 +31,7 @@ String KQLOperators::genHasAnyAllOpExpr(std::vector<String> &tokens, IParser::Po
while (!token_pos->isEnd() && token_pos->type != TokenType::PipeMark && token_pos->type != TokenType::Semicolon)
{
auto tmp_arg = IParserKQLFunction::getExpression(token_pos);
if (token_pos->type == TokenType::Comma )
if (token_pos->type == TokenType::Comma)
new_expr = new_expr + logic_op;
else
new_expr = new_expr + ch_op + "(" + haystack + "," + tmp_arg + ")";
@ -39,14 +39,13 @@ String KQLOperators::genHasAnyAllOpExpr(std::vector<String> &tokens, IParser::Po
++token_pos;
if (token_pos->type == TokenType::ClosingRoundBracket)
break;
}
tokens.pop_back();
return new_expr;
}
String KQLOperators::genInOpExpr(IParser::Pos &token_pos, String kql_op, String ch_op)
String KQLOperators::genInOpExpr(IParser::Pos & token_pos, String kql_op, String ch_op)
{
ParserKQLTaleFunction kqlfun_p;
String new_expr;
@ -61,13 +60,13 @@ String KQLOperators::genInOpExpr(IParser::Pos &token_pos, String kql_op, String
throw Exception("Syntax error near " + kql_op, ErrorCodes::SYNTAX_ERROR);
auto pos = token_pos;
if (kqlfun_p.parse(pos,select,expected))
if (kqlfun_p.parse(pos, select, expected))
{
new_expr = ch_op + " kql";
auto tmp_pos = token_pos;
while (tmp_pos != pos)
{
new_expr = new_expr + " " + String(tmp_pos->begin,tmp_pos->end);
new_expr = new_expr + " " + String(tmp_pos->begin, tmp_pos->end);
++tmp_pos;
}
@ -81,10 +80,10 @@ String KQLOperators::genInOpExpr(IParser::Pos &token_pos, String kql_op, String
--token_pos;
--token_pos;
return ch_op;
}
String KQLOperators::genHaystackOpExpr(std::vector<String> &tokens,IParser::Pos &token_pos,String kql_op, String ch_op, WildcardsPos wildcards_pos, WildcardsPos space_pos)
String KQLOperators::genHaystackOpExpr(
std::vector<String> & tokens, IParser::Pos & token_pos, String kql_op, String ch_op, WildcardsPos wildcards_pos, WildcardsPos space_pos)
{
String new_expr, left_wildcards, right_wildcards, left_space, right_space;
@ -178,11 +177,13 @@ String KQLOperators::genHaystackOpExpr(std::vector<String> &tokens,IParser::Pos
++token_pos;
if (!tokens.empty() && ((token_pos)->type == TokenType::StringLiteral || token_pos->type == TokenType::QuotedIdentifier))
new_expr = ch_op + "(" + tokens.back() + ", '" + left_wildcards + left_space + String(token_pos->begin + 1, token_pos->end - 1) + right_space + right_wildcards + "')";
new_expr = ch_op + "(" + tokens.back() + ", '" + left_wildcards + left_space + String(token_pos->begin + 1, token_pos->end - 1)
+ right_space + right_wildcards + "')";
else if (!tokens.empty() && ((token_pos)->type == TokenType::BareWord))
{
auto tmp_arg = IParserKQLFunction::getExpression(token_pos);
new_expr = ch_op + "(" + tokens.back() +", concat('" + left_wildcards + left_space + "', " + tmp_arg +", '"+ right_space + right_wildcards + "'))";
new_expr = ch_op + "(" + tokens.back() + ", concat('" + left_wildcards + left_space + "', " + tmp_arg + ", '" + right_space
+ right_wildcards + "'))";
}
else
throw Exception(ErrorCodes::SYNTAX_ERROR, "Syntax error near {}", kql_op);
@ -190,7 +191,7 @@ String KQLOperators::genHaystackOpExpr(std::vector<String> &tokens,IParser::Pos
return new_expr;
}
bool KQLOperators::convert(std::vector<String> &tokens,IParser::Pos &pos)
bool KQLOperators::convert(std::vector<String> & tokens, IParser::Pos & pos)
{
auto begin = pos;
@ -250,7 +251,7 @@ bool KQLOperators::convert(std::vector<String> &tokens,IParser::Pos &pos)
else
{
if (tokens.empty())
throw Exception("Syntax error near " + op , ErrorCodes::SYNTAX_ERROR);
throw Exception("Syntax error near " + op, ErrorCodes::SYNTAX_ERROR);
auto last_op = tokens.back();
auto last_pos = pos;

View File

@ -1,18 +1,18 @@
#pragma once
#include <unordered_map>
#include <Parsers/IParserBase.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <unordered_map>
namespace DB
{
class KQLOperators
{
public:
bool convert(std::vector<String> &tokens,IParser::Pos &pos);
protected:
bool convert(std::vector<String> & tokens, IParser::Pos & pos);
enum class WildcardsPos:uint8_t
protected:
enum class WildcardsPos : uint8_t
{
none,
left,
@ -60,47 +60,52 @@ protected:
not_startswith_cs,
};
std::unordered_map <String,KQLOperatorValue> KQLOperator =
{
{"contains" , KQLOperatorValue::contains},
{"!contains" , KQLOperatorValue::not_contains},
{"contains_cs" , KQLOperatorValue::contains_cs},
{"!contains_cs" , KQLOperatorValue::not_contains_cs},
{"endswith" , KQLOperatorValue::endswith},
{"!endswith" , KQLOperatorValue::not_endswith},
{"endswith_cs" , KQLOperatorValue::endswith_cs},
{"!endswith_cs" , KQLOperatorValue::not_endswith_cs},
{"=~" , KQLOperatorValue::equal},
{"!~" , KQLOperatorValue::not_equal},
{"==" , KQLOperatorValue::equal_cs},
{"!=" , KQLOperatorValue::not_equal_cs},
{"has" , KQLOperatorValue::has},
{"!has" , KQLOperatorValue::not_has},
{"has_all" , KQLOperatorValue::has_all},
{"has_any" , KQLOperatorValue::has_any},
{"has_cs" , KQLOperatorValue::has_cs},
{"!has_cs" , KQLOperatorValue::not_has_cs},
{"hasprefix" , KQLOperatorValue::hasprefix},
{"!hasprefix" , KQLOperatorValue::not_hasprefix},
{"hasprefix_cs" , KQLOperatorValue::hasprefix_cs},
{"!hasprefix_cs" , KQLOperatorValue::not_hasprefix_cs},
{"hassuffix" , KQLOperatorValue::hassuffix},
{"!hassuffix" , KQLOperatorValue::not_hassuffix},
{"hassuffix_cs" , KQLOperatorValue::hassuffix_cs},
{"!hassuffix_cs" , KQLOperatorValue::not_hassuffix_cs},
{"in" , KQLOperatorValue::in_cs},
{"!in" , KQLOperatorValue::not_in_cs},
{"in~" , KQLOperatorValue::in},
{"!in~" , KQLOperatorValue::not_in},
{"matches regex" , KQLOperatorValue::matches_regex},
{"startswith" , KQLOperatorValue::startswith},
{"!startswith" , KQLOperatorValue::not_startswith},
{"startswith_cs" , KQLOperatorValue::startswith_cs},
{"!startswith_cs" , KQLOperatorValue::not_startswith_cs},
std::unordered_map<String, KQLOperatorValue> KQLOperator = {
{"contains", KQLOperatorValue::contains},
{"!contains", KQLOperatorValue::not_contains},
{"contains_cs", KQLOperatorValue::contains_cs},
{"!contains_cs", KQLOperatorValue::not_contains_cs},
{"endswith", KQLOperatorValue::endswith},
{"!endswith", KQLOperatorValue::not_endswith},
{"endswith_cs", KQLOperatorValue::endswith_cs},
{"!endswith_cs", KQLOperatorValue::not_endswith_cs},
{"=~", KQLOperatorValue::equal},
{"!~", KQLOperatorValue::not_equal},
{"==", KQLOperatorValue::equal_cs},
{"!=", KQLOperatorValue::not_equal_cs},
{"has", KQLOperatorValue::has},
{"!has", KQLOperatorValue::not_has},
{"has_all", KQLOperatorValue::has_all},
{"has_any", KQLOperatorValue::has_any},
{"has_cs", KQLOperatorValue::has_cs},
{"!has_cs", KQLOperatorValue::not_has_cs},
{"hasprefix", KQLOperatorValue::hasprefix},
{"!hasprefix", KQLOperatorValue::not_hasprefix},
{"hasprefix_cs", KQLOperatorValue::hasprefix_cs},
{"!hasprefix_cs", KQLOperatorValue::not_hasprefix_cs},
{"hassuffix", KQLOperatorValue::hassuffix},
{"!hassuffix", KQLOperatorValue::not_hassuffix},
{"hassuffix_cs", KQLOperatorValue::hassuffix_cs},
{"!hassuffix_cs", KQLOperatorValue::not_hassuffix_cs},
{"in", KQLOperatorValue::in_cs},
{"!in", KQLOperatorValue::not_in_cs},
{"in~", KQLOperatorValue::in},
{"!in~", KQLOperatorValue::not_in},
{"matches regex", KQLOperatorValue::matches_regex},
{"startswith", KQLOperatorValue::startswith},
{"!startswith", KQLOperatorValue::not_startswith},
{"startswith_cs", KQLOperatorValue::startswith_cs},
{"!startswith_cs", KQLOperatorValue::not_startswith_cs},
};
static String genHaystackOpExpr(std::vector<String> &tokens,IParser::Pos &token_pos,String kql_op, String ch_op, WildcardsPos wildcards_pos, WildcardsPos space_pos = WildcardsPos::none);
static String genInOpExpr(IParser::Pos &token_pos,String kql_op, String ch_op);
static String genHasAnyAllOpExpr(std::vector<String> &tokens,IParser::Pos &token_pos,String kql_op, String ch_op);
static String genHaystackOpExpr(
std::vector<String> & tokens,
IParser::Pos & token_pos,
String kql_op,
String ch_op,
WildcardsPos wildcards_pos,
WildcardsPos space_pos = WildcardsPos::none);
static String genInOpExpr(IParser::Pos & token_pos, String kql_op, String ch_op);
static String genHasAnyAllOpExpr(std::vector<String> & tokens, IParser::Pos & token_pos, String kql_op, String ch_op);
};
}

View File

@ -1,6 +1,6 @@
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLPrint.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
namespace DB
{

View File

@ -1,17 +1,17 @@
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLProject.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
namespace DB
{
bool ParserKQLProject :: parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
bool ParserKQLProject ::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ASTPtr select_expression_list;
String expr;
expr = getExprFromToken(pos);
Tokens tokens(expr.c_str(), expr.c_str()+expr.size());
Tokens tokens(expr.c_str(), expr.c_str() + expr.size());
IParser::Pos new_pos(tokens, pos.max_depth);
if (!ParserNotEmptyExpressionList(false).parse(new_pos, select_expression_list, expected))

View File

@ -8,7 +8,6 @@ namespace DB
class ParserKQLProject : public ParserKQLBase
{
protected:
const char * getName() const override { return "KQL project"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;

View File

@ -1,27 +1,27 @@
#include <Parsers/ASTLiteral.h>
#include <Parsers/ASTSelectQuery.h>
#include <Parsers/ASTSelectWithUnionQuery.h>
#include <Parsers/ASTSubquery.h>
#include <Parsers/ASTTablesInSelectQuery.h>
#include <Parsers/CommonParsers.h>
#include <Parsers/IParserBase.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLTable.h>
#include <Parsers/Kusto/ParserKQLProject.h>
#include <Parsers/Kusto/ParserKQLDistinct.h>
#include <Parsers/Kusto/ParserKQLFilter.h>
#include <Parsers/Kusto/ParserKQLSort.h>
#include <Parsers/Kusto/ParserKQLSummarize.h>
#include <Parsers/Kusto/ParserKQLLimit.h>
#include <Parsers/Kusto/ParserKQLStatement.h>
#include <Parsers/Kusto/KustoFunctions/KQLFunctionFactory.h>
#include <Parsers/Kusto/ParserKQLDistinct.h>
#include <Parsers/Kusto/ParserKQLExtend.h>
#include <Parsers/Kusto/ParserKQLFilter.h>
#include <Parsers/Kusto/ParserKQLLimit.h>
#include <Parsers/Kusto/ParserKQLMVExpand.h>
#include <Parsers/Kusto/ParserKQLMakeSeries.h>
#include <Parsers/Kusto/ParserKQLOperators.h>
#include <Parsers/Kusto/ParserKQLPrint.h>
#include <Parsers/Kusto/ParserKQLMakeSeries.h>
#include <Parsers/Kusto/ParserKQLMVExpand.h>
#include <Parsers/Kusto/ParserKQLExtend.h>
#include <Parsers/ParserTablesInSelectQuery.h>
#include <Parsers/CommonParsers.h>
#include <Parsers/ASTTablesInSelectQuery.h>
#include <Parsers/ASTSubquery.h>
#include <Parsers/Kusto/ParserKQLProject.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLSort.h>
#include <Parsers/Kusto/ParserKQLStatement.h>
#include <Parsers/Kusto/ParserKQLSummarize.h>
#include <Parsers/Kusto/ParserKQLTable.h>
#include <Parsers/ParserSelectWithUnionQuery.h>
#include <Parsers/ASTSelectWithUnionQuery.h>
#include <Parsers/ParserTablesInSelectQuery.h>
#include <format>
namespace DB
@ -29,7 +29,6 @@ namespace DB
namespace ErrorCodes
{
extern const int UNKNOWN_FUNCTION;
extern const int SYNTAX_ERROR;
}
@ -57,33 +56,63 @@ bool ParserKQLBase::setSubQuerySource(ASTPtr & select_query, ASTPtr & source, bo
ASTPtr table_expr;
if (!dest_is_subquery)
{
if (!select_query || !select_query->as<ASTSelectQuery>()->tables() || select_query->as<ASTSelectQuery>()->tables()->as<ASTTablesInSelectQuery>()->children.empty())
if (!select_query || !select_query->as<ASTSelectQuery>()->tables()
|| select_query->as<ASTSelectQuery>()->tables()->as<ASTTablesInSelectQuery>()->children.empty())
return false;
table_expr = select_query->as<ASTSelectQuery>()->tables()->as<ASTTablesInSelectQuery>()->children[0];
table_expr->as<ASTTablesInSelectQueryElement>()->table_expression = source->as<ASTSelectQuery>()->tables()->children[0]->as<ASTTablesInSelectQueryElement>()-> table_expression;
table_expr->as<ASTTablesInSelectQueryElement>()->table_expression
= source->as<ASTSelectQuery>()->tables()->children[0]->as<ASTTablesInSelectQueryElement>()->table_expression;
return true;
}
if (!select_query || select_query->as<ASTTablesInSelectQuery>()->children.empty() ||
!select_query->as<ASTTablesInSelectQuery>()->children[0]->as<ASTTablesInSelectQueryElement>()->table_expression ||
select_query->as<ASTTablesInSelectQuery>()->children[0]->as<ASTTablesInSelectQueryElement>()->table_expression->as<ASTTableExpression>()->subquery->children.empty() ||
select_query->as<ASTTablesInSelectQuery>()->children[0]->as<ASTTablesInSelectQueryElement>()->table_expression->as<ASTTableExpression>()->subquery->children[0]->as<ASTSelectWithUnionQuery>()->list_of_selects->children.empty() ||
select_query->as<ASTTablesInSelectQuery>()->children[0]->as<ASTTablesInSelectQueryElement>()->table_expression->as<ASTTableExpression>()->subquery->children[0]->as<ASTSelectWithUnionQuery>()->list_of_selects->children[0]->as<ASTSelectQuery>()->tables()->as<ASTTablesInSelectQuery>()->children.empty())
if (!select_query || select_query->as<ASTTablesInSelectQuery>()->children.empty()
|| !select_query->as<ASTTablesInSelectQuery>()->children[0]->as<ASTTablesInSelectQueryElement>()->table_expression
|| select_query->as<ASTTablesInSelectQuery>()
->children[0]
->as<ASTTablesInSelectQueryElement>()
->table_expression->as<ASTTableExpression>()
->subquery->children.empty()
|| select_query->as<ASTTablesInSelectQuery>()
->children[0]
->as<ASTTablesInSelectQueryElement>()
->table_expression->as<ASTTableExpression>()
->subquery->children[0]
->as<ASTSelectWithUnionQuery>()
->list_of_selects->children.empty()
|| select_query->as<ASTTablesInSelectQuery>()
->children[0]
->as<ASTTablesInSelectQueryElement>()
->table_expression->as<ASTTableExpression>()
->subquery->children[0]
->as<ASTSelectWithUnionQuery>()
->list_of_selects->children[0]
->as<ASTSelectQuery>()
->tables()
->as<ASTTablesInSelectQuery>()
->children.empty())
return false;
table_expr = select_query->as<ASTTablesInSelectQuery>()->children[0]->as<ASTTablesInSelectQueryElement>()
->table_expression->as<ASTTableExpression>()->subquery->children[0]->as<ASTSelectWithUnionQuery>()
->list_of_selects->children[0]->as<ASTSelectQuery>()->tables()->as<ASTTablesInSelectQuery>()->children[0];
table_expr = select_query->as<ASTTablesInSelectQuery>()
->children[0]
->as<ASTTablesInSelectQueryElement>()
->table_expression->as<ASTTableExpression>()
->subquery->children[0]
->as<ASTSelectWithUnionQuery>()
->list_of_selects->children[0]
->as<ASTSelectQuery>()
->tables()
->as<ASTTablesInSelectQuery>()
->children[0];
if (!src_is_subquery)
{
table_expr->as<ASTTablesInSelectQueryElement>()->table_expression =
source->as<ASTSelectQuery>()->tables()->children[0]->as<ASTTablesInSelectQueryElement>()-> table_expression;
table_expr->as<ASTTablesInSelectQueryElement>()->table_expression
= source->as<ASTSelectQuery>()->tables()->children[0]->as<ASTTablesInSelectQueryElement>()->table_expression;
}
else
{
table_expr->as<ASTTablesInSelectQueryElement>()->table_expression =
source ->children[0]->as<ASTTablesInSelectQueryElement>()-> table_expression;
table_expr->as<ASTTablesInSelectQueryElement>()->table_expression
= source->children[0]->as<ASTTablesInSelectQueryElement>()->table_expression;
}
return true;
@ -128,12 +157,12 @@ String ParserKQLBase::getExprFromToken(Pos & pos)
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 (token == "=")
{
++pos;
if (String(pos->begin,pos->end) != "~" )
if (String(pos->begin, pos->end) != "~")
{
if (tokens.empty())
throw Exception("Syntax error near equal symbol", ErrorCodes::SYNTAX_ERROR);
@ -142,11 +171,10 @@ String ParserKQLBase::getExprFromToken(Pos & pos)
tokens.pop_back();
if (alias[0] == '\'' || alias[0] == '\"')
throw Exception(alias + " Quoted string is not a valid alias", ErrorCodes::SYNTAX_ERROR);
}
--pos;
}
else if (!KQLOperators().convert(tokens,pos))
else if (!KQLOperators().convert(tokens, pos))
{
token = IParserKQLFunction::getExpression(pos);
tokens.push_back(token);
@ -169,8 +197,8 @@ String ParserKQLBase::getExprFromToken(Pos & pos)
tokens.push_back(alias);
}
for (auto token:tokens)
res = res.empty()? token : res +" " + token;
for (auto token : tokens)
res = res.empty() ? token : res + " " + token;
return res;
}
@ -216,9 +244,8 @@ bool ParserKQLQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
node = select_query;
ASTPtr tables;
std::unordered_map<std::string, KQLOperatorDataFlowState> kql_parser =
{
{"filter", {"filter", false, false, 3}},
std::unordered_map<std::string, KQLOperatorDataFlowState> kql_parser
= {{"filter", {"filter", false, false, 3}},
{"where", {"filter", false, false, 3}},
{"limit", {"limit", false, true, 3}},
{"take", {"limit", false, true, 3}},
@ -231,8 +258,7 @@ bool ParserKQLQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{"print", {"print", false, true, 3}},
{"summarize", {"summarize", true, true, 3}},
{"make-series", {"make-series", true, true, 5}},
{"mv-expand", {"mv-expand", true, true, 5}}
};
{"mv-expand", {"mv-expand", true, true, 5}}};
std::vector<std::pair<String, Pos>> operation_pos;
@ -265,17 +291,18 @@ bool ParserKQLQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
++pos;
ParserKeyword s_by("by");
if (s_by.ignore(pos,expected))
if (s_by.ignore(pos, expected))
{
kql_operator = "order by";
--pos;
}
}
else
{ auto op_pos_begin = pos;
{
auto op_pos_begin = pos;
++pos;
ParserToken s_dash(TokenType::Minus);
if (s_dash.ignore(pos,expected))
if (s_dash.ignore(pos, expected))
{
String tmp_op(op_pos_begin->begin, pos->end);
kql_operator = tmp_op;
@ -330,7 +357,6 @@ bool ParserKQLQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
npos = operation_pos.back().second;
if (!kql_operator_p->parse(npos, node, expected))
return false;
}
else
{
@ -338,7 +364,7 @@ bool ParserKQLQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
auto last_pos = operation_pos.back().second;
auto last_op = operation_pos.back().first;
auto set_main_query_clause =[&](String & op, Pos & op_pos)
auto set_main_query_clause = [&](String & op, Pos & op_pos)
{
auto op_str = ParserKQLBase::getExprFromPipe(op_pos);
if (op == "project")
@ -396,7 +422,7 @@ bool ParserKQLQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
if (!kql_operator_p->parse(npos, node, expected))
return false;
auto set_query_clasue =[&](String op_str, String op_calsue)
auto set_query_clasue = [&](String op_str, String op_calsue)
{
auto oprator = getOperator(op_str);
if (oprator)
@ -434,7 +460,7 @@ bool ParserKQLQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
if (!node->as<ASTSelectQuery>()->select())
{
auto expr = String("*");
Tokens tokens(expr.c_str(), expr.c_str()+expr.size());
Tokens tokens(expr.c_str(), expr.c_str() + expr.size());
IParser::Pos new_pos(tokens, pos.max_depth);
if (!std::make_unique<ParserKQLProject>()->parse(new_pos, node, expected))
return false;
@ -488,7 +514,8 @@ bool ParserSimpleCHSubquery::parseImpl(Pos & pos, ASTPtr & node, Expected & expe
if (parent_select_node && parent_select_node->as<ASTSelectQuery>()->tables())
{
auto select_query = sub_select_node->as<ASTSelectWithUnionQuery>()->list_of_selects->children[0];
select_query->as<ASTSelectQuery>()->setExpression(ASTSelectQuery::Expression::TABLES, parent_select_node->as<ASTSelectQuery>()->tables());
select_query->as<ASTSelectQuery>()->setExpression(
ASTSelectQuery::Expression::TABLES, parent_select_node->as<ASTSelectQuery>()->tables());
}
ASTPtr node_subquery = std::make_shared<ASTSubquery>();

View File

@ -1,7 +1,7 @@
#pragma once
#include <Parsers/IParserBase.h>
#include <Parsers/ASTSelectQuery.h>
#include <Parsers/IParserBase.h>
namespace DB
{
@ -18,9 +18,8 @@ public:
class ParserKQLQuery : public IParserBase
{
protected:
static std::unique_ptr<IParserBase> getOperator(String &op_name);
static std::unique_ptr<IParserBase> getOperator(String & op_name);
const char * getName() const override { return "KQL query"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
};
@ -35,7 +34,8 @@ protected:
class ParserSimpleCHSubquery : public ParserKQLBase
{
public:
ParserSimpleCHSubquery(ASTPtr parent_select_node_ = nullptr) {parent_select_node = parent_select_node_;}
ParserSimpleCHSubquery(ASTPtr parent_select_node_ = nullptr) { parent_select_node = parent_select_node_; }
protected:
const char * getName() const override { return "Simple ClickHouse subquery"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;

View File

@ -1,7 +1,7 @@
#include <Parsers/ASTLiteral.h>
#include <Parsers/IParserBase.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/ASTOrderByElement.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/IParserBase.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLSort.h>
@ -11,7 +11,7 @@ namespace DB
bool ParserKQLSort::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
bool has_dir = false;
std::vector <bool> has_directions;
std::vector<bool> has_directions;
ParserOrderByExpressionList order_list;
ASTPtr order_expression_list;
@ -44,7 +44,7 @@ bool ParserKQLSort::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
if (!has_directions[i])
{
auto *order_expr = order_expression_list->children[i]->as<ASTOrderByElement>();
auto * order_expr = order_expression_list->children[i]->as<ASTOrderByElement>();
order_expr->direction = -1; // default desc
if (!order_expr->nulls_direction_was_explicitly_specified)
order_expr->nulls_direction = -1;

View File

@ -1,11 +1,11 @@
#include <Parsers/IParserBase.h>
#include <Parsers/ParserSetQuery.h>
#include <Parsers/ASTExpressionList.h>
#include <Parsers/ASTSelectWithUnionQuery.h>
#include <Parsers/CommonParsers.h>
#include <Parsers/IParserBase.h>
#include <Parsers/Kusto/KustoFunctions/KQLFunctionFactory.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLStatement.h>
#include <Parsers/Kusto/KustoFunctions/KQLFunctionFactory.h>
#include <Parsers/CommonParsers.h>
#include <Parsers/ParserSetQuery.h>
namespace DB
{
@ -15,8 +15,7 @@ bool ParserKQLStatement::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
ParserKQLWithOutput query_with_output_p(end, allow_settings_after_format_in_insert);
ParserSetQuery set_p;
bool res = query_with_output_p.parse(pos, node, expected)
|| set_p.parse(pos, node, expected);
bool res = query_with_output_p.parse(pos, node, expected) || set_p.parse(pos, node, expected);
return res;
}
@ -67,7 +66,7 @@ bool ParserKQLTaleFunction::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
ParserToken s_lparen(TokenType::OpeningRoundBracket);
auto begin = pos;
auto paren_count = 0 ;
auto paren_count = 0;
String kql_statement;
if (s_lparen.ignore(pos, expected))

View File

@ -12,11 +12,12 @@ private:
bool allow_settings_after_format_in_insert;
const char * getName() const override { return "KQL Statement"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
public:
explicit ParserKQLStatement(const char * end_, bool allow_settings_after_format_in_insert_ = false)
: end(end_)
, allow_settings_after_format_in_insert(allow_settings_after_format_in_insert_)
{}
: end(end_), allow_settings_after_format_in_insert(allow_settings_after_format_in_insert_)
{
}
};
class ParserKQLWithOutput : public IParserBase
@ -26,11 +27,12 @@ protected:
bool allow_settings_after_format_in_insert;
const char * getName() const override { return "KQL with output"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
public:
explicit ParserKQLWithOutput(const char * end_, bool allow_settings_after_format_in_insert_ = false)
: end(end_)
, allow_settings_after_format_in_insert(allow_settings_after_format_in_insert_)
{}
: end(end_), allow_settings_after_format_in_insert(allow_settings_after_format_in_insert_)
{
}
};
class ParserKQLWithUnionQuery : public IParserBase
@ -48,4 +50,3 @@ protected:
};
}

View File

@ -20,7 +20,6 @@
#include <Parsers/ParserSetQuery.h>
#include <Parsers/ParserTablesInSelectQuery.h>
#include <Parsers/ParserWithElement.h>
#include <vector>
#include <format>
namespace DB
@ -43,25 +42,53 @@ bool ParserKQLSummarize::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
std::vector<String> expr_aggregations;
std::vector<String> expr_groupbys;
std::unordered_set<String> aggregate_functions
({
"arg_max", "arg_min", "avg", "avgif", "binary_all_and", "binary_all_or",
"binary_all_xor", "buildschema", "count", "countif", "dcount", "dcountif",
"make_bag", "make_bag_if", "make_list", "make_list_if", "make_list_with_nulls", "make_set",
"make_set_if", "max", "maxif", "min", "minif", "percentile",
"percentilew", "percentiles", "percentiles_array","percentilesw", "percentilesw_array", "stdev",
"stdevif", "sum", "sumif", "take_any", "take_anyif", "variance",
"varianceif"
});
std::unordered_set<String> aggregate_functions(
{"arg_max",
"arg_min",
"avg",
"avgif",
"binary_all_and",
"binary_all_or",
"binary_all_xor",
"buildschema",
"count",
"countif",
"dcount",
"dcountif",
"make_bag",
"make_bag_if",
"make_list",
"make_list_if",
"make_list_with_nulls",
"make_set",
"make_set_if",
"max",
"maxif",
"min",
"minif",
"percentile",
"percentilew",
"percentiles",
"percentiles_array",
"percentilesw",
"percentilesw_array",
"stdev",
"stdevif",
"sum",
"sumif",
"take_any",
"take_anyif",
"variance",
"varianceif"});
auto apply_aliais =[&](Pos & begin_pos, Pos & end_pos, bool is_groupby)
auto apply_aliais = [&](Pos & begin_pos, Pos & end_pos, bool is_groupby)
{
auto expr = String(begin_pos->begin, end_pos->end);
auto equal_pos = begin_pos;
++equal_pos;
if (!is_groupby)
{
if (String(equal_pos->begin , equal_pos->end) != "=")
if (String(equal_pos->begin, equal_pos->end) != "=")
{
String alias;
String aggregate_fun = String(begin_pos->begin, begin_pos->end);
@ -93,7 +120,8 @@ bool ParserKQLSummarize::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
if (String(equal_pos->begin, equal_pos->end) != "=")
{
String groupby_fun = String(begin_pos->begin, begin_pos->end);
if (equal_pos->isEnd() || equal_pos->type == TokenType::Comma || equal_pos->type == TokenType::Semicolon || equal_pos->type == TokenType::PipeMark)
if (equal_pos->isEnd() || equal_pos->type == TokenType::Comma || equal_pos->type == TokenType::Semicolon
|| equal_pos->type == TokenType::PipeMark)
{
expr = groupby_fun;
}
@ -125,13 +153,13 @@ bool ParserKQLSummarize::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
while (!pos->isEnd() && pos->type != TokenType::PipeMark && pos->type != TokenType::Semicolon)
{
if(pos->type == TokenType::OpeningRoundBracket)
if (pos->type == TokenType::OpeningRoundBracket)
++bracket_count;
if(pos->type == TokenType::ClosingRoundBracket)
if (pos->type == TokenType::ClosingRoundBracket)
--bracket_count;
if ((bracket_count ==0 and pos->type == TokenType::Comma) || String(pos->begin, pos->end) == "by")
if ((bracket_count == 0 and pos->type == TokenType::Comma) || String(pos->begin, pos->end) == "by")
{
auto end_pos = pos;
--end_pos;

View File

@ -1,45 +1,23 @@
#include <unordered_set>
#include <Parsers/ASTLiteral.h>
#include <Parsers/IParserBase.h>
#include <Parsers/ParserTablesInSelectQuery.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLTable.h>
#include <unordered_set>
#include <Parsers/ParserTablesInSelectQuery.h>
namespace DB
{
bool ParserKQLTable :: parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
bool ParserKQLTable ::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
std::unordered_set<String> sql_keywords
({
"SELECT",
"INSERT",
"CREATE",
"ALTER",
"SYSTEM",
"SHOW",
"GRANT",
"REVOKE",
"ATTACH",
"CHECK",
"DESCRIBE",
"DESC",
"DETACH",
"DROP",
"EXISTS",
"KILL",
"OPTIMIZE",
"RENAME",
"SET",
"TRUNCATE",
"USE",
"EXPLAIN"
});
std::unordered_set<String> sql_keywords({"SELECT", "INSERT", "CREATE", "ALTER", "SYSTEM", "SHOW", "GRANT", "REVOKE",
"ATTACH", "CHECK", "DESCRIBE", "DESC", "DETACH", "DROP", "EXISTS", "KILL",
"OPTIMIZE", "RENAME", "SET", "TRUNCATE", "USE", "EXPLAIN"});
ASTPtr tables;
String table_name(pos->begin,pos->end);
String table_name(pos->begin, pos->end);
String table_name_upcase(table_name);
std::transform(table_name_upcase.begin(), table_name_upcase.end(),table_name_upcase.begin(), toupper);
std::transform(table_name_upcase.begin(), table_name_upcase.end(), table_name_upcase.begin(), toupper);
if (sql_keywords.find(table_name_upcase) != sql_keywords.end())
return false;

View File

@ -11,7 +11,6 @@ class ParserKQLTable : public ParserKQLBase
protected:
const char * getName() const override { return "KQL Table"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
};
}