diff --git a/.gitmodules b/.gitmodules index bff1289e443..035359e7597 100644 --- a/.gitmodules +++ b/.gitmodules @@ -43,12 +43,12 @@ [submodule "contrib/unixodbc"] path = contrib/unixodbc url = https://github.com/ClickHouse-Extras/UnixODBC.git -[submodule "contrib/libhdfs3"] - path = contrib/libhdfs3 - url = https://github.com/chenxing-xc/ClickHouse-Extras-libhdfs3.git [submodule "contrib/protobuf"] path = contrib/protobuf - url = https://github.com/chenxing-xc/ClickHouse-Extras-protobuf.git + url = https://github.com/ClickHouse-Extras/protobuf.git +[submodule "contrib/libhdfs3"] + path = contrib/libhdfs3 + url = https://github.com/ClickHouse-Extras/libhdfs3.git [submodule "contrib/boost"] path = contrib/boost - url = https://github.com/chenxing-xc/ClickHouse-Extras-boost.git + url = https://github.com/ClickHouse-Extras/boost-extra.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 833cddef772..094fe8c7b06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,7 @@ endif () option (TEST_COVERAGE "Enables flags for test coverage" OFF) option (ENABLE_TESTS "Enables tests" ON) +option (ENABLE_INSERT_INFILE "Enables INSERT INFILE syntax" OFF) if (CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x86_64") option (USE_INTERNAL_MEMCPY "Use internal implementation of 'memcpy' function instead of provided by libc. Only for x86_64." ON) @@ -212,6 +213,10 @@ if (ENABLE_TESTS) enable_testing() endif () +if (ENABLE_INSERT_INFILE) + message (STATUS "INSERT INFILE SYNTAX support") +endif () + # when installing to /usr - place configs to /etc but for /usr/local place to /usr/local/etc if (CMAKE_INSTALL_PREFIX STREQUAL "/usr") set (CLICKHOUSE_ETC_DIR "/etc") diff --git a/dbms/programs/client/Client.cpp b/dbms/programs/client/Client.cpp index 0845b05a45c..5a6f2b9bf28 100644 --- a/dbms/programs/client/Client.cpp +++ b/dbms/programs/client/Client.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -801,8 +802,11 @@ private: const ASTInsertQuery * insert = typeid_cast(&*parsed_query); connection->forceConnected(); - +#if ENABLE_INSERT_INFILE if (insert && !insert->select && !insert->in_file) +#else + if (insert && !insert->select) +#endif processInsertQuery(); else processOrdinaryQuery(); diff --git a/dbms/src/Common/config.h.in b/dbms/src/Common/config.h.in index af12cc525f7..27c5e965240 100644 --- a/dbms/src/Common/config.h.in +++ b/dbms/src/Common/config.h.in @@ -15,3 +15,4 @@ #cmakedefine01 USE_POCO_MONGODB #cmakedefine01 USE_POCO_NETSSL #cmakedefine01 CLICKHOUSE_SPLIT_BINARY +#cmakedefine01 ENABLE_INSERT_INFILE diff --git a/dbms/src/Interpreters/InterpreterInsertQuery.cpp b/dbms/src/Interpreters/InterpreterInsertQuery.cpp index 5ef5a28cd85..5b5bd27430a 100644 --- a/dbms/src/Interpreters/InterpreterInsertQuery.cpp +++ b/dbms/src/Interpreters/InterpreterInsertQuery.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -149,6 +150,7 @@ BlockIO InterpreterInsertQuery::execute() throw Exception("Cannot insert column " + name_type.name + ", because it is MATERIALIZED column.", ErrorCodes::ILLEGAL_COLUMN); } } +#if ENABLE_INSERT_INFILE else if (query.in_file) { // read data stream from in_file, and copy it to out @@ -228,6 +230,7 @@ BlockIO InterpreterInsertQuery::execute() res.out = nullptr; } +#endif return res; } diff --git a/dbms/src/Parsers/ASTInsertQuery.cpp b/dbms/src/Parsers/ASTInsertQuery.cpp index 7e1538bd810..0f5b6a727c9 100644 --- a/dbms/src/Parsers/ASTInsertQuery.cpp +++ b/dbms/src/Parsers/ASTInsertQuery.cpp @@ -1,5 +1,6 @@ #include #include +#include namespace DB @@ -36,20 +37,24 @@ void ASTInsertQuery::formatImpl(const FormatSettings & settings, FormatState & s if (!format.empty()) { settings.ostr << (settings.hilite ? hilite_keyword : "") << " FORMAT " << (settings.hilite ? hilite_none : "") << format; +#if ENABLE_INSERT_INFILE if (in_file) { settings.ostr << (settings.hilite ? hilite_keyword : "") << " INFILE " << (settings.hilite ? hilite_none : ""); in_file->formatImpl(settings, state, frame); } +#endif } else { +#if ENABLE_INSERT_INFILE if (in_file) { settings.ostr << (settings.hilite ? hilite_keyword : "") << " INFILE " << (settings.hilite ? hilite_none : ""); in_file->formatImpl(settings, state, frame); } else +#endif { settings.ostr << (settings.hilite ? hilite_keyword : "") << " VALUES" << (settings.hilite ? hilite_none : ""); } diff --git a/dbms/src/Parsers/ASTInsertQuery.h b/dbms/src/Parsers/ASTInsertQuery.h index dd93b84cbbd..0b3a69050bc 100644 --- a/dbms/src/Parsers/ASTInsertQuery.h +++ b/dbms/src/Parsers/ASTInsertQuery.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace DB @@ -18,7 +19,10 @@ public: String format; ASTPtr select; ASTPtr table_function; + +#if ENABLE_INSERT_INFILE ASTPtr in_file; +#endif // Set to true if the data should only be inserted into attached views bool no_destination = false; @@ -41,12 +45,12 @@ public: { res->table_function = table_function->clone(); res->children.push_back(res->table_function); } - +#if ENABLE_INSERT_INFILE if (in_file) { res->in_file = in_file->clone(); res->children.push_back(res->in_file); } - +#endif return res; } diff --git a/dbms/src/Parsers/ParserInsertQuery.cpp b/dbms/src/Parsers/ParserInsertQuery.cpp index f9d9c2762a7..df0d2ab6afa 100644 --- a/dbms/src/Parsers/ParserInsertQuery.cpp +++ b/dbms/src/Parsers/ParserInsertQuery.cpp @@ -10,6 +10,7 @@ #include #include +#include namespace DB @@ -31,7 +32,6 @@ bool ParserInsertQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) ParserKeyword s_format("FORMAT"); ParserKeyword s_select("SELECT"); ParserKeyword s_with("WITH"); - ParserKeyword s_infile("INFILE"); ParserToken s_lparen(TokenType::OpeningRoundBracket); ParserToken s_rparen(TokenType::ClosingRoundBracket); ParserIdentifier name_p; @@ -44,7 +44,11 @@ bool ParserInsertQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) ASTPtr format; ASTPtr select; ASTPtr table_function; + +#if ENABLE_INSERT_INFILE + ParserKeyword s_infile("INFILE"); ASTPtr in_file; +#endif /// Insertion data const char * data = nullptr; @@ -95,6 +99,7 @@ bool ParserInsertQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) if (!name_p.parse(pos, format, expected)) return false; +#if ENABLE_INSERT_INFILE // there are two case after FORMAT xx: // case 1: data_set. // case 2: INFILE xx clause. @@ -108,8 +113,8 @@ bool ParserInsertQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) } else { +#endif data = name_pos->end; - if (data < end && *data == ';') throw Exception("You have excessive ';' symbol before data for INSERT.\n" "Example:\n\n" @@ -130,7 +135,9 @@ bool ParserInsertQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) if (data < end && *data == '\n') ++data; +#if ENABLE_INSERT_INFILE } +#endif } else if (s_select.ignore(pos, expected) || s_with.ignore(pos,expected)) { @@ -138,12 +145,14 @@ bool ParserInsertQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) ParserSelectWithUnionQuery select_p; select_p.parse(pos, select, expected); } +#if ENABLE_INSERT_INFILE else if (s_infile.ignore(pos, expected)) { ParserStringLiteral in_file_p; if (!in_file_p.parse(pos, in_file, expected)) return false; } +#endif else { return false; @@ -169,11 +178,13 @@ bool ParserInsertQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) query->columns = columns; query->select = select; - query->in_file = in_file; +#if ENABLE_INSERT_INFILE + query->in_file = in_file; if (query->in_file) query->data = nullptr; else +#endif query->data = data != end ? data : nullptr; query->end = end; @@ -181,9 +192,10 @@ bool ParserInsertQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) query->children.push_back(columns); if (select) query->children.push_back(select); - +#if ENABLE_INSERT_INFILE if (in_file) query->children.push_back(in_file); +#endif return true; } diff --git a/dbms/src/Parsers/ParserInsertQuery.h b/dbms/src/Parsers/ParserInsertQuery.h index 65d04e17d8f..913649210b9 100644 --- a/dbms/src/Parsers/ParserInsertQuery.h +++ b/dbms/src/Parsers/ParserInsertQuery.h @@ -22,6 +22,7 @@ namespace DB * INSERT INTO [db.]table (c1, c2, c3) SELECT ... * INSERT INTO [db.]table SELECT ... + * This syntax is controversial, not open for now. * #4 Insert of data in an arbitrary form from file(a bit variant of #2) * INSERT INTO [db.]table (c1, c2, c3) FORMAT format INFILE 'url' */