From 02f0bcb17f01eb47da59d07598b36e5dc0b25ce4 Mon Sep 17 00:00:00 2001 From: Vitaliy Lyudvichenko Date: Tue, 22 Aug 2017 22:51:03 +0300 Subject: [PATCH] Fixed incorrect assertion in INSERT queries with binary formats. [#CLICKHOUSE-3242] --- dbms/src/Parsers/ParserInsertQuery.cpp | 23 +++++++-------- .../00497_whitespaces_in_insert.reference | 9 ++++++ .../00497_whitespaces_in_insert.sh | 28 +++++++++++++++++++ 3 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00497_whitespaces_in_insert.reference create mode 100755 dbms/tests/queries/0_stateless/00497_whitespaces_in_insert.sh diff --git a/dbms/src/Parsers/ParserInsertQuery.cpp b/dbms/src/Parsers/ParserInsertQuery.cpp index 1bb43d47f3d..709e9e79233 100644 --- a/dbms/src/Parsers/ParserInsertQuery.cpp +++ b/dbms/src/Parsers/ParserInsertQuery.cpp @@ -80,22 +80,23 @@ bool ParserInsertQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) if (!name_p.parse(pos, format, expected)) return false; - if (pos->type == TokenType::Semicolon) - throw Exception("You have excessive ';' symbol before data for INSERT.\n" - "Example:\n\n" - "INSERT INTO t (x, y) FORMAT TabSeparated\n" - "1\tHello\n" - "2\tWorld\n" - "\n" - "Note that there is no ';' in first line.", ErrorCodes::SYNTAX_ERROR); - - /// Data starts after the first newline, if there is one, or after all the whitespace characters, otherwise. - data = name_pos->end; + if (data < end && *data == ';') + throw Exception("You have excessive ';' symbol before data for INSERT.\n" + "Example:\n\n" + "INSERT INTO t (x, y) FORMAT TabSeparated\n" + ";\tHello\n" + "2\tWorld\n" + "\n" + "Note that there is no ';' just after format name, " + "you need to put at least one whitespace symbol before the data.", ErrorCodes::SYNTAX_ERROR); + while (data < end && (*data == ' ' || *data == '\t' || *data == '\f')) ++data; + /// Data starts after the first newline, if there is one, or after all the whitespace characters, otherwise. + if (data < end && *data == '\r') ++data; diff --git a/dbms/tests/queries/0_stateless/00497_whitespaces_in_insert.reference b/dbms/tests/queries/0_stateless/00497_whitespaces_in_insert.reference new file mode 100644 index 00000000000..9055e59470d --- /dev/null +++ b/dbms/tests/queries/0_stateless/00497_whitespaces_in_insert.reference @@ -0,0 +1,9 @@ +59 +59 +32 +59 +32 +59 + +; +; diff --git a/dbms/tests/queries/0_stateless/00497_whitespaces_in_insert.sh b/dbms/tests/queries/0_stateless/00497_whitespaces_in_insert.sh new file mode 100755 index 00000000000..09d1aa3de88 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00497_whitespaces_in_insert.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +clickhouse-client -q "DROP TABLE IF EXISTS test.ws"; +clickhouse-client -q "CREATE TABLE test.ws (i UInt8) ENGINE = Memory"; + +clickhouse-client -q "INSERT INTO test.ws FORMAT RowBinary ;"; +clickhouse-client -q "INSERT INTO test.ws FORMAT RowBinary ; "; +clickhouse-client -q "INSERT INTO test.ws FORMAT RowBinary +; "; +echo -n ";" | clickhouse-client -q "INSERT INTO test.ws FORMAT RowBinary"; + +clickhouse-client --max_threads=1 -q "SELECT * FROM test.ws"; +clickhouse-client -q "DROP TABLE test.ws"; + + +clickhouse-client -q "SELECT ''"; + + +clickhouse-client -q "CREATE TABLE test.ws (s String) ENGINE = Memory"; +clickhouse-client -q "INSERT INTO test.ws FORMAT TSV ; +"; +echo ";" | clickhouse-client -q "INSERT INTO test.ws FORMAT TSV" +if clickhouse-client -q "INSERT INTO test.ws FORMAT TSV;" 1>/dev/null 2>/dev/null; then + echo ERROR; +fi +clickhouse-client --max_threads=1 -q "SELECT * FROM test.ws"; + +clickhouse-client -q "DROP TABLE test.ws";