ISSUES-2973 support nested json struct for visitParamExtractRaw

This commit is contained in:
zhang2014 2018-08-31 11:36:22 +08:00
parent 918d17ffeb
commit a1f2b9ae0c
4 changed files with 28 additions and 26 deletions

View File

@ -87,45 +87,47 @@ struct ExtractBool
struct ExtractRaw struct ExtractRaw
{ {
inline static void skipAfterQuotationIfNeed(const UInt8 *& pos, const UInt8 * end, ColumnString::Chars_t & res_data) static constexpr size_t bytes_on_stack = 64;
{ using ExpectChars = PODArray<char, bytes_on_stack, AllocatorWithStackMemory<Allocator<false>, bytes_on_stack>>;
if (pos + 1 < end && pos[1] == '"')
{
res_data.push_back(*pos);
++pos;
}
}
static void extract(const UInt8 * pos, const UInt8 * end, ColumnString::Chars_t & res_data) static void extract(const UInt8 * pos, const UInt8 * end, ColumnString::Chars_t & res_data)
{ {
std::vector<char> expect_end; ExpectChars expects_end;
UInt8 current_expect_end = 0;
for (; pos != end; ++pos) for (auto extract_begin = pos; pos != end; ++pos)
{ {
if (!expect_end.empty() && *pos == expect_end.back()) if (*pos == current_expect_end)
expect_end.pop_back(); {
expects_end.pop_back();
current_expect_end = (UInt8) (expects_end.empty() ? 0 : expects_end.back());
}
else else
{ {
switch (*pos) switch(*pos)
{ {
case '[': case '[':
expect_end.push_back(']'); expects_end.push_back((current_expect_end = ']'));
break; break;
case '{': case '{':
expect_end.push_back('}'); expects_end.push_back((current_expect_end = '}'));
break; break;
case '"': case '"' :
expect_end.push_back('"'); expects_end.push_back((current_expect_end = '"'));
break; break;
case '\\': case '\\':
skipAfterQuotationIfNeed(pos, end, res_data); /// skip backslash
if (pos + 1 < end && pos[1] == '"')
pos++;
break; break;
default: default:
if (expect_end.empty() && (*pos == ',' || *pos == '}')) if (!current_expect_end && (*pos == ',' || *pos == '}'))
{
res_data.insert(extract_begin, pos);
return; return;
} }
} }
res_data.push_back(*pos); }
} }
} }
}; };

View File

@ -27,5 +27,5 @@
</substitution> </substitution>
</substitutions> </substitutions>
<query>SELECT count() FROM system.numbers WHERE NOT ignore(visitParamExtractRaw({param}, 'myparam'))</query> <query>SELECT count() FROM system.numbers WHERE NOT ignore(visitParamExtractRaw(materialize({param}), 'myparam'))</query>
</test> </test>

View File

@ -9,5 +9,5 @@ test"string
"test_string" "test_string"
"test\\"string" "test\\"string"
"test\\"string" "test\\"string"
[1,2,3] ["]", "2", "3"]
{"nested" : [1,2,3]} {"nested" : [1,2,3]}

View File

@ -11,5 +11,5 @@ SELECT visitParamExtractRaw('{"myparam":"test_string"}', 'myparam');
SELECT visitParamExtractRaw('{"myparam": "test_string"}', 'myparam'); SELECT visitParamExtractRaw('{"myparam": "test_string"}', 'myparam');
SELECT visitParamExtractRaw('{"myparam": "test\\"string"}', 'myparam'); SELECT visitParamExtractRaw('{"myparam": "test\\"string"}', 'myparam');
SELECT visitParamExtractRaw('{"myparam": "test\\"string", "other":123}', 'myparam'); SELECT visitParamExtractRaw('{"myparam": "test\\"string", "other":123}', 'myparam');
SELECT visitParamExtractRaw('{"myparam": [1,2,3], "other":123}', 'myparam'); SELECT visitParamExtractRaw('{"myparam": ["]", "2", "3"], "other":123}', 'myparam');
SELECT visitParamExtractRaw('{"myparam": {"nested" : [1,2,3]}, "other":123}', 'myparam'); SELECT visitParamExtractRaw('{"myparam": {"nested" : [1,2,3]}, "other":123}', 'myparam');