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;
```
This commit is contained in:
Marek Vavruša 2017-10-21 13:38:39 -07:00
parent 975a7ada42
commit 5f53df7dbe
5 changed files with 41 additions and 0 deletions

View File

@ -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<const ASTCreateQuery &>(*query);
create = as_create; // Copy the saved create query, but use ATTACH instead of CREATE
create.attach = true;
}
std::unique_ptr<InterpreterSelectQuery> interpreter_select;
Block as_select_sample;
/// For `view` type tables, you may need `sample_block` to get the columns.

View File

@ -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<ASTCreateQuery>(StringRange(begin, pos));
node = query;
query->attach = attach;
query->if_not_exists = if_not_exists;
if (database)
query->database = typeid_cast<ASTIdentifier &>(*database).name;
if (table)
query->table = typeid_cast<ASTIdentifier &>(*table).name;
return true;
}
/// List of columns.
if (s_lparen.ignore(pos, expected))
{

View File

@ -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;

View File

@ -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