From 3c045e1545798ddc662f50c526a0732649d73699 Mon Sep 17 00:00:00 2001 From: Vitaliy Lyudvichenko Date: Wed, 28 Sep 2016 16:11:03 +0300 Subject: [PATCH] Added ability to skip plain JSON arrays. [#METR-22801] --- dbms/include/DB/IO/ReadHelpers.h | 2 +- dbms/src/IO/ReadHelpers.cpp | 34 ++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/dbms/include/DB/IO/ReadHelpers.h b/dbms/include/DB/IO/ReadHelpers.h index 65d6b0bd1bd..d9bbcc9525d 100644 --- a/dbms/include/DB/IO/ReadHelpers.h +++ b/dbms/include/DB/IO/ReadHelpers.h @@ -810,7 +810,7 @@ inline void skipWhitespaceIfAny(ReadBuffer & buf) ++buf.position(); } -/// Skip json value (except array and object). +/// Skips json value. If the value contains objects (i.e. {...} sequence), an exception will be thrown. void skipJSONFieldPlain(ReadBuffer & buf, const String & name_of_filed = ""); diff --git a/dbms/src/IO/ReadHelpers.cpp b/dbms/src/IO/ReadHelpers.cpp index b5a93653ef6..5c7f7020eb4 100644 --- a/dbms/src/IO/ReadHelpers.cpp +++ b/dbms/src/IO/ReadHelpers.cpp @@ -595,11 +595,41 @@ void skipJSONFieldPlain(ReadBuffer & buf, const String & name_of_filed) { assertString("true", buf); } - else if (*buf.position() == 'f')/// skip false + else if (*buf.position() == 'f') /// skip false { assertString("false", buf); } - else if (*buf.position() == '{' || *buf.position() == '[') /// fail on nested objects + else if (*buf.position() == '[') + { + ++buf.position(); + skipWhitespaceIfAny(buf); + + if (!buf.eof() && *buf.position() == ']') /// skip empty array + { + ++buf.position(); + return; + } + + while (true) + { + skipJSONFieldPlain(buf, name_of_filed); + skipWhitespaceIfAny(buf); + + if (!buf.eof() && *buf.position() == ',') + { + ++buf.position(); + skipWhitespaceIfAny(buf); + } + else if (!buf.eof() && *buf.position() == ']') + { + ++buf.position(); + break; + } + else + throw Exception("Unexpected symbol for key '" + name_of_filed + "'", ErrorCodes::INCORRECT_DATA); + } + } + else if (*buf.position() == '{') /// fail on objects { throw Exception("Unexpected nested field for key '" + name_of_filed + "'", ErrorCodes::INCORRECT_DATA); }