mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-30 19:42:00 +00:00
Fixes
This commit is contained in:
parent
f8b1a6d185
commit
6981eb64ac
@ -41,7 +41,7 @@ public:
|
|||||||
class Executor
|
class Executor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static ColumnPtr run(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count)
|
static ColumnPtr run(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count, uint32_t parse_depth)
|
||||||
{
|
{
|
||||||
MutableColumnPtr to{result_type->createColumn()};
|
MutableColumnPtr to{result_type->createColumn()};
|
||||||
to->reserve(input_rows_count);
|
to->reserve(input_rows_count);
|
||||||
@ -76,23 +76,10 @@ public:
|
|||||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If argument is successfully cast to (ColumnConst *) then it is quoted string
|
|
||||||
/// Example:
|
|
||||||
/// SomeFunction('some string argument')
|
|
||||||
///
|
|
||||||
/// Otherwise it is a column
|
|
||||||
/// Example:
|
|
||||||
/// SomeFunction(database.table.column)
|
|
||||||
|
|
||||||
const ColumnPtr & arg_jsonpath = first_column.column;
|
const ColumnPtr & arg_jsonpath = first_column.column;
|
||||||
const auto * arg_jsonpath_const = typeid_cast<const ColumnConst *>(arg_jsonpath.get());
|
const auto * arg_jsonpath_const = typeid_cast<const ColumnConst *>(arg_jsonpath.get());
|
||||||
const auto * arg_jsonpath_string = typeid_cast<const ColumnString *>(arg_jsonpath_const->getDataColumnPtr().get());
|
const auto * arg_jsonpath_string = typeid_cast<const ColumnString *>(arg_jsonpath_const->getDataColumnPtr().get());
|
||||||
|
|
||||||
if (!arg_jsonpath_string)
|
|
||||||
{
|
|
||||||
throw Exception{"Illegal column " + arg_jsonpath->getName(), ErrorCodes::ILLEGAL_COLUMN};
|
|
||||||
}
|
|
||||||
|
|
||||||
const ColumnPtr & arg_json = second_column.column;
|
const ColumnPtr & arg_json = second_column.column;
|
||||||
const auto * col_json_const = typeid_cast<const ColumnConst *>(arg_json.get());
|
const auto * col_json_const = typeid_cast<const ColumnConst *>(arg_json.get());
|
||||||
const auto * col_json_string
|
const auto * col_json_string
|
||||||
@ -102,14 +89,14 @@ public:
|
|||||||
const ColumnString::Chars & chars_path = arg_jsonpath_string->getChars();
|
const ColumnString::Chars & chars_path = arg_jsonpath_string->getChars();
|
||||||
const ColumnString::Offsets & offsets_path = arg_jsonpath_string->getOffsets();
|
const ColumnString::Offsets & offsets_path = arg_jsonpath_string->getOffsets();
|
||||||
|
|
||||||
/// Get data and offsets for 1 argument (JSON)
|
/// Prepare to parse 1 argument (JSONPath)
|
||||||
const char * query_begin = reinterpret_cast<const char *>(&chars_path[0]);
|
const char * query_begin = reinterpret_cast<const char *>(&chars_path[0]);
|
||||||
const char * query_end = query_begin + offsets_path[0] - 1;
|
const char * query_end = query_begin + offsets_path[0] - 1;
|
||||||
|
|
||||||
/// Tokenize query
|
/// Tokenize query
|
||||||
Tokens tokens(query_begin, query_end);
|
Tokens tokens(query_begin, query_end);
|
||||||
/// Max depth 0 indicates that depth is not limited
|
/// Max depth 0 indicates that depth is not limited
|
||||||
IParser::Pos token_iterator(tokens, 0);
|
IParser::Pos token_iterator(tokens, parse_depth);
|
||||||
|
|
||||||
/// Parse query and create AST tree
|
/// Parse query and create AST tree
|
||||||
Expected expected;
|
Expected expected;
|
||||||
@ -121,7 +108,7 @@ public:
|
|||||||
throw Exception{"Unable to parse JSONPath", ErrorCodes::BAD_ARGUMENTS};
|
throw Exception{"Unable to parse JSONPath", ErrorCodes::BAD_ARGUMENTS};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get data and offsets for 1 argument (JSON)
|
/// Get data and offsets for 2 argument (JSON)
|
||||||
const ColumnString::Chars & chars_json = col_json_string->getChars();
|
const ColumnString::Chars & chars_json = col_json_string->getChars();
|
||||||
const ColumnString::Offsets & offsets_json = col_json_string->getOffsets();
|
const ColumnString::Offsets & offsets_json = col_json_string->getOffsets();
|
||||||
|
|
||||||
@ -179,12 +166,13 @@ public:
|
|||||||
/// 1. Lexer(path) -> Tokens
|
/// 1. Lexer(path) -> Tokens
|
||||||
/// 2. Create ASTPtr
|
/// 2. Create ASTPtr
|
||||||
/// 3. Parser(Tokens, ASTPtr) -> complete AST
|
/// 3. Parser(Tokens, ASTPtr) -> complete AST
|
||||||
/// 4. Execute functions, call interpreter for each json (in function)
|
/// 4. Execute functions: call getNextItem on generator and handle each item
|
||||||
|
uint32_t parse_depth = getContext()->getSettingsRef().max_parser_depth;
|
||||||
#if USE_SIMDJSON
|
#if USE_SIMDJSON
|
||||||
if (getContext()->getSettingsRef().allow_simdjson)
|
if (getContext()->getSettingsRef().allow_simdjson)
|
||||||
return FunctionSQLJSONHelpers::Executor<Name, Impl, SimdJSONParser>::run(arguments, result_type, input_rows_count);
|
return FunctionSQLJSONHelpers::Executor<Name, Impl, SimdJSONParser>::run(arguments, result_type, input_rows_count, parse_depth);
|
||||||
#endif
|
#endif
|
||||||
return FunctionSQLJSONHelpers::Executor<Name, Impl, DummyJSONParser>::run(arguments, result_type, input_rows_count);
|
return FunctionSQLJSONHelpers::Executor<Name, Impl, DummyJSONParser>::run(arguments, result_type, input_rows_count, parse_depth);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -325,6 +313,8 @@ public:
|
|||||||
else if (status == VisitorStatus::Error)
|
else if (status == VisitorStatus::Error)
|
||||||
{
|
{
|
||||||
/// ON ERROR
|
/// ON ERROR
|
||||||
|
/// Here it is possible to handle errors with ON ERROR (as described in ISO/IEC TR 19075-6),
|
||||||
|
/// however this functionality is not implemented yet
|
||||||
}
|
}
|
||||||
current_element = root;
|
current_element = root;
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,8 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/// Ranges to lookup in json array ($[0, 1, 2, 4 to 9])
|
/// Ranges to lookup in json array ($[0, 1, 2, 4 to 9])
|
||||||
/// Range is represented as <start, end>
|
/// Range is represented as <start, end (non-inclusive)>
|
||||||
/// Single index is represented as <start, start>
|
/// Single index is represented as <start, start + 1>
|
||||||
std::vector<std::pair<UInt32, UInt32>> ranges;
|
std::vector<std::pair<UInt32, UInt32>> ranges;
|
||||||
bool is_star = false;
|
bool is_star = false;
|
||||||
};
|
};
|
||||||
|
@ -73,7 +73,8 @@ public:
|
|||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
auto root = element;
|
/// element passed to us actually is root, so here we assign current to root
|
||||||
|
auto current = element;
|
||||||
if (current_visitor < 0)
|
if (current_visitor < 0)
|
||||||
{
|
{
|
||||||
return VisitorStatus::Exhausted;
|
return VisitorStatus::Exhausted;
|
||||||
@ -81,13 +82,13 @@ public:
|
|||||||
|
|
||||||
for (int i = 0; i < current_visitor; ++i)
|
for (int i = 0; i < current_visitor; ++i)
|
||||||
{
|
{
|
||||||
visitors[i]->apply(root);
|
visitors[i]->apply(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
VisitorStatus status = VisitorStatus::Error;
|
VisitorStatus status = VisitorStatus::Error;
|
||||||
for (size_t i = current_visitor; i < visitors.size(); ++i)
|
for (size_t i = current_visitor; i < visitors.size(); ++i)
|
||||||
{
|
{
|
||||||
status = visitors[i]->visit(root);
|
status = visitors[i]->visit(current);
|
||||||
current_visitor = i;
|
current_visitor = i;
|
||||||
if (status == VisitorStatus::Error || status == VisitorStatus::Ignore)
|
if (status == VisitorStatus::Error || status == VisitorStatus::Ignore)
|
||||||
{
|
{
|
||||||
@ -98,7 +99,7 @@ public:
|
|||||||
|
|
||||||
if (status != VisitorStatus::Ignore)
|
if (status != VisitorStatus::Ignore)
|
||||||
{
|
{
|
||||||
element = root;
|
element = current;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user