From 5f53df7dbe2778b5dc71ac938973e8b1c1a605ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Vavrus=CC=8Ca?= Date: Sat, 21 Oct 2017 13:38:39 -0700 Subject: [PATCH] ParserCreateQuery: allow ATTACH TABLE x shorthand statement Allow `ATTACH TABLE [db.]name` if the table was previously detached, an the table structure can be read from disk. This makes reattaching tables less cumbersome: ``` CREATE TABLE test.t (x UInt8) ENGINE = Null; DETACH TABLE test.t; ATTACH TABLE test.t; ``` --- .../src/Interpreters/InterpreterCreateQuery.cpp | 9 +++++++++ dbms/src/Parsers/ParserCreateQuery.cpp | 17 +++++++++++++++++ .../00508_materialized_view_to.reference | 2 ++ .../0_stateless/00508_materialized_view_to.sql | 7 +++++++ docs/en/query_language/queries.rst | 6 ++++++ 5 files changed, 41 insertions(+) diff --git a/dbms/src/Interpreters/InterpreterCreateQuery.cpp b/dbms/src/Interpreters/InterpreterCreateQuery.cpp index 176ac41eedb..9469506f9d4 100644 --- a/dbms/src/Interpreters/InterpreterCreateQuery.cpp +++ b/dbms/src/Interpreters/InterpreterCreateQuery.cpp @@ -489,6 +489,15 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create) String data_path = path + "data/" + database_name_escaped + "/"; String metadata_path = path + "metadata/" + database_name_escaped + "/" + table_name_escaped + ".sql"; + // If this is a stub ATTACH query, read the query definition from the database + if (create.attach && !create.storage && !create.columns) + { + auto query = context.getCreateQuery(database_name, table_name); + auto & as_create = typeid_cast(*query); + create = as_create; // Copy the saved create query, but use ATTACH instead of CREATE + create.attach = true; + } + std::unique_ptr interpreter_select; Block as_select_sample; /// For `view` type tables, you may need `sample_block` to get the columns. diff --git a/dbms/src/Parsers/ParserCreateQuery.cpp b/dbms/src/Parsers/ParserCreateQuery.cpp index a467b83a1e3..bdd72198213 100644 --- a/dbms/src/Parsers/ParserCreateQuery.cpp +++ b/dbms/src/Parsers/ParserCreateQuery.cpp @@ -214,6 +214,23 @@ bool ParserCreateQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) return false; } + // Shortcut for ATTACH a previously detached table + if (attach && (!pos.isValid() || pos.get().type == TokenType::Semicolon)) + { + auto query = std::make_shared(StringRange(begin, pos)); + node = query; + + query->attach = attach; + query->if_not_exists = if_not_exists; + + if (database) + query->database = typeid_cast(*database).name; + if (table) + query->table = typeid_cast(*table).name; + + return true; + } + /// List of columns. if (s_lparen.ignore(pos, expected)) { diff --git a/dbms/tests/queries/0_stateless/00508_materialized_view_to.reference b/dbms/tests/queries/0_stateless/00508_materialized_view_to.reference index 1191247b6d9..099b7d91c92 100644 --- a/dbms/tests/queries/0_stateless/00508_materialized_view_to.reference +++ b/dbms/tests/queries/0_stateless/00508_materialized_view_to.reference @@ -1,2 +1,4 @@ 1 2 +1 +2 diff --git a/dbms/tests/queries/0_stateless/00508_materialized_view_to.sql b/dbms/tests/queries/0_stateless/00508_materialized_view_to.sql index 70f8b98d32b..d2a819ec623 100644 --- a/dbms/tests/queries/0_stateless/00508_materialized_view_to.sql +++ b/dbms/tests/queries/0_stateless/00508_materialized_view_to.sql @@ -8,6 +8,13 @@ CREATE TABLE test.dst (x UInt8) ENGINE = Memory(); CREATE MATERIALIZED VIEW test.mv TO test.dst AS SELECT * FROM test.src; INSERT INTO test.src VALUES (1), (2); +-- Detach MV and see if the data is still readable +DETACH TABLE test.mv; +SELECT * FROM test.dst; + +-- Reattach MV (shortcut) +ATTACH TABLE test.mv; + -- Drop the MV and see if the data is still readable DROP TABLE test.mv; SELECT * FROM test.dst; diff --git a/docs/en/query_language/queries.rst b/docs/en/query_language/queries.rst index d0bded7c604..8c07866db1c 100644 --- a/docs/en/query_language/queries.rst +++ b/docs/en/query_language/queries.rst @@ -155,6 +155,12 @@ The query is exactly the same as CREATE, except - The query doesn't create data on the disk, but assumes that data is already in the appropriate places, and just adds information about the table to the server. After executing an ATTACH query, the server will know about the existence of the table. +If the table has been previously detached and it's structure is known, it's possible to use shorthand form and omit structure definition: + +.. code-block:: sql + + ATTACH TABLE [IF NOT EXISTS] [db.]name + This query is used when starting the server. The server stores table metadata as files with ATTACH queries, which it simply runs at launch (with the exception of system tables, which are explicitly created on the server). DROP