Merge pull request #8860 from Avogar/json_each_row

Allow data in square brackets in JSONEachRowFormat.
This commit is contained in:
alexey-milovidov 2020-01-31 04:06:27 +03:00 committed by GitHub
commit dedf513aa3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 1 deletions

View File

@ -216,6 +216,18 @@ void JSONEachRowRowInputFormat::readNestedData(const String & name, MutableColum
bool JSONEachRowRowInputFormat::readRow(MutableColumns & columns, RowReadExtension & ext)
{
/// Set flag data_in_square_brackets if data starts with '['.
if (!in.eof() && parsing_stage == ParsingStages::START)
{
parsing_stage = ParsingStages::PROCESS;
skipWhitespaceIfAny(in);
if (*in.position() == '[')
{
data_in_square_brackets = true;
++in.position();
}
}
skipWhitespaceIfAny(in);
/// We consume ;, or \n before scanning a new row, instead scanning to next row at the end.
@ -227,9 +239,23 @@ bool JSONEachRowRowInputFormat::readRow(MutableColumns & columns, RowReadExtensi
if (!in.eof() && (*in.position() == ',' || *in.position() == ';'))
++in.position();
/// Finish reading rows if data is in square brackets and ']' received.
skipWhitespaceIfAny(in);
if (in.eof())
if (!in.eof() && *in.position() == ']' && data_in_square_brackets)
{
data_in_square_brackets = false;
parsing_stage = ParsingStages::FINISH;
++in.position();
return false;
}
skipWhitespaceIfAny(in);
if (in.eof() || parsing_stage == ParsingStages::FINISH)
{
if (data_in_square_brackets)
throw Exception("Unexpected end of data: received end of stream instead of ']'.", ErrorCodes::INCORRECT_DATA);
return false;
}
size_t num_columns = columns.size();

View File

@ -9,6 +9,13 @@
namespace DB
{
enum ParsingStages
{
START,
PROCESS,
FINISH
};
class ReadBuffer;
@ -69,6 +76,12 @@ private:
/// Cached search results for previous row (keyed as index in JSON object) - used as a hint.
std::vector<NameMap::LookupResult> prev_positions;
/// This flag is needed to know if data is in square brackets.
bool data_in_square_brackets = false;
/// This flag is needed to know the stage of parsing.
size_t parsing_stage = ParsingStages::START;
};
}

View File

@ -0,0 +1,2 @@
1 name1
2 name2

View File

@ -0,0 +1,6 @@
DROP TABLE IF EXISTS json_square_brackets;
CREATE TABLE json_square_brackets (id UInt32, name String) ENGINE = Memory;
INSERT INTO json_square_brackets FORMAT JSONEachRow [{"id": 1, "name": "name1"}, {"id": 2, "name": "name2"}]
SELECT * FROM json_square_brackets ORDER BY id;
DROP TABLE IF EXISTS json_square_brackets;