Add JSONExtractKeys function

This commit is contained in:
Vitaly Orlov 2021-10-12 18:00:25 +03:00
parent 5ac0d36392
commit 65c6605c2c
No known key found for this signature in database
GPG Key ID: 58F48CDD37483DA0
6 changed files with 49 additions and 0 deletions

View File

@ -73,6 +73,7 @@ void registerFunctionsJSON(FunctionFactory & factory)
factory.registerFunction<JSONOverloadResolver<NameJSONExtractRaw, JSONExtractRawImpl>>(); factory.registerFunction<JSONOverloadResolver<NameJSONExtractRaw, JSONExtractRawImpl>>();
factory.registerFunction<JSONOverloadResolver<NameJSONExtractArrayRaw, JSONExtractArrayRawImpl>>(); factory.registerFunction<JSONOverloadResolver<NameJSONExtractArrayRaw, JSONExtractArrayRawImpl>>();
factory.registerFunction<JSONOverloadResolver<NameJSONExtractKeysAndValuesRaw, JSONExtractKeysAndValuesRawImpl>>(); factory.registerFunction<JSONOverloadResolver<NameJSONExtractKeysAndValuesRaw, JSONExtractKeysAndValuesRawImpl>>();
factory.registerFunction<JSONOverloadResolver<NameJSONExtractKeys, JSONExtractKeysImpl>>();
} }
} }

View File

@ -433,6 +433,7 @@ struct NameJSONExtractKeysAndValues { static constexpr auto name{"JSONExtractKey
struct NameJSONExtractRaw { static constexpr auto name{"JSONExtractRaw"}; }; struct NameJSONExtractRaw { static constexpr auto name{"JSONExtractRaw"}; };
struct NameJSONExtractArrayRaw { static constexpr auto name{"JSONExtractArrayRaw"}; }; struct NameJSONExtractArrayRaw { static constexpr auto name{"JSONExtractArrayRaw"}; };
struct NameJSONExtractKeysAndValuesRaw { static constexpr auto name{"JSONExtractKeysAndValuesRaw"}; }; struct NameJSONExtractKeysAndValuesRaw { static constexpr auto name{"JSONExtractKeysAndValuesRaw"}; };
struct NameJSONExtractKeys { static constexpr auto name{"JSONExtractKeys"}; };
template <typename JSONParser> template <typename JSONParser>
@ -1353,4 +1354,38 @@ public:
} }
}; };
template <typename JSONParser>
class JSONExtractKeysImpl
{
public:
using Element = typename JSONParser::Element;
static DataTypePtr getReturnType(const char *, const ColumnsWithTypeAndName &)
{
return std::make_unique<DataTypeString>();
}
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
{
if (!element.isObject())
return false;
auto object = element.getObject();
auto & col_arr = assert_cast<ColumnArray &>(dest);
auto & col_tuple = assert_cast<ColumnTuple &>(col_arr.getData());
auto & col_key = assert_cast<ColumnString &>(col_tuple.getColumn(0));
for (auto [key, value] : object)
{
col_key.insertData(key.data(), key.size());
}
col_arr.getOffsets().push_back(col_arr.getOffsets().back() + object.size());
return true;
}
};
} }

View File

@ -650,6 +650,7 @@
"JSONExtractInt" "JSONExtractInt"
"JSONExtractKeysAndValues" "JSONExtractKeysAndValues"
"JSONExtractKeysAndValuesRaw" "JSONExtractKeysAndValuesRaw"
"JSONExtractKeys"
"JSONExtractRaw" "JSONExtractRaw"
"JSONExtractString" "JSONExtractString"
"JSONExtractUInt" "JSONExtractUInt"

View File

@ -31,6 +31,7 @@
"toJSONString" "toJSONString"
"JSON_VALUE" "JSON_VALUE"
"JSONExtractKeysAndValuesRaw" "JSONExtractKeysAndValuesRaw"
"JSONExtractKeys"
"JSONExtractString" "JSONExtractString"
"JSONType" "JSONType"
"JSONKey" "JSONKey"

View File

@ -101,6 +101,11 @@ hello
[('a','"hello"'),('b','[-100,200,300]')] [('a','"hello"'),('b','[-100,200,300]')]
[('a','"hello"'),('b','[-100,200,300]'),('c','{"d":[121,144]}')] [('a','"hello"'),('b','[-100,200,300]'),('c','{"d":[121,144]}')]
[('d','[121,144]')] [('d','[121,144]')]
--JSONExtractKeys--
['a','b']
[]
[]
['d']
--const/non-const mixed-- --const/non-const mixed--
a a
b b

View File

@ -231,6 +231,12 @@ SELECT JSONExtractKeysAndValuesRaw('{"a": "hello", "b": [-100, 200.0, 300]}');
SELECT JSONExtractKeysAndValuesRaw('{"a": "hello", "b": [-100, 200.0, 300], "c":{"d":[121,144]}}'); SELECT JSONExtractKeysAndValuesRaw('{"a": "hello", "b": [-100, 200.0, 300], "c":{"d":[121,144]}}');
SELECT JSONExtractKeysAndValuesRaw('{"a": "hello", "b": [-100, 200.0, 300], "c":{"d":[121,144]}}', 'c'); SELECT JSONExtractKeysAndValuesRaw('{"a": "hello", "b": [-100, 200.0, 300], "c":{"d":[121,144]}}', 'c');
SELECT '--JSONExtractKeys--';
SELECT JSONExtractKeys('{"a": "hello", "b": [-100, 200.0, 300]}');
SELECT JSONExtractKeysAndValuesRaw('{"a": "hello", "b": [-100, 200.0, 300]}', 'b');
SELECT JSONExtractKeysAndValuesRaw('{"a": "hello", "b": [-100, 200.0, 300]}', 'a');
SELECT JSONExtractKeysAndValuesRaw('{"a": "hello", "b": [-100, 200.0, 300], "c":{"d":[121,144]}}', 'c');
SELECT '--const/non-const mixed--'; SELECT '--const/non-const mixed--';
SELECT JSONExtractString('["a", "b", "c", "d", "e"]', idx) FROM (SELECT arrayJoin([1,2,3,4,5]) AS idx); SELECT JSONExtractString('["a", "b", "c", "d", "e"]', idx) FROM (SELECT arrayJoin([1,2,3,4,5]) AS idx);
SELECT JSONExtractString(json, 's') FROM (SELECT arrayJoin(['{"s":"u"}', '{"s":"v"}']) AS json); SELECT JSONExtractString(json, 's') FROM (SELECT arrayJoin(['{"s":"u"}', '{"s":"v"}']) AS json);