mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
save TO table of a materialized view to the ATTACH query [#CLICKHOUSE-2]
This commit is contained in:
parent
b0f1227e90
commit
f2ebffb7f0
@ -27,6 +27,8 @@ String getTableDefinitionFromCreateQuery(const ASTPtr & query)
|
||||
/// We remove everything that is not needed for ATTACH from the query.
|
||||
create.attach = true;
|
||||
create.database.clear();
|
||||
create.as_database.clear();
|
||||
create.as_table.clear();
|
||||
create.if_not_exists = false;
|
||||
create.is_populate = false;
|
||||
|
||||
@ -34,13 +36,6 @@ String getTableDefinitionFromCreateQuery(const ASTPtr & query)
|
||||
if (!create.is_view && !create.is_materialized_view)
|
||||
create.select = nullptr;
|
||||
|
||||
/// For "MATERIALIZED VIEW x TO y" it's necessary to save destination table
|
||||
if (!create.is_materialized_view || create.storage)
|
||||
{
|
||||
create.as_database.clear();
|
||||
create.as_table.clear();
|
||||
}
|
||||
|
||||
std::ostringstream statement_stream;
|
||||
formatAST(create, statement_stream, 0, false);
|
||||
statement_stream << '\n';
|
||||
|
@ -480,12 +480,15 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create)
|
||||
create.attach = true;
|
||||
}
|
||||
|
||||
if (create.to_database.empty())
|
||||
create.to_database = current_database;
|
||||
|
||||
std::unique_ptr<InterpreterSelectQuery> interpreter_select;
|
||||
Block as_select_sample;
|
||||
/// For `view` type tables, you may need `sample_block` to get the columns.
|
||||
if (create.select && (!create.attach || (!create.columns && (create.is_view || create.is_materialized_view))))
|
||||
{
|
||||
create.select->setDatabaseIfNeeded(database_name);
|
||||
create.select->setDatabaseIfNeeded(current_database);
|
||||
interpreter_select = std::make_unique<InterpreterSelectQuery>(create.select->ptr(), context);
|
||||
as_select_sample = interpreter_select->getSampleBlock();
|
||||
}
|
||||
|
@ -88,6 +88,8 @@ public:
|
||||
String database;
|
||||
String table;
|
||||
ASTExpressionList * columns = nullptr;
|
||||
String to_database; /// For CREATE MATERIALIZED VIEW mv TO table.
|
||||
String to_table;
|
||||
ASTStorage * storage = nullptr;
|
||||
String as_database;
|
||||
String as_table;
|
||||
@ -166,11 +168,18 @@ protected:
|
||||
formatOnCluster(settings);
|
||||
}
|
||||
|
||||
if (!to_table.empty())
|
||||
{
|
||||
settings.ostr
|
||||
<< (settings.hilite ? hilite_keyword : "") << " TO " << (settings.hilite ? hilite_none : "")
|
||||
<< (!to_database.empty() ? backQuoteIfNeed(to_database) + "." : "") << backQuoteIfNeed(to_table);
|
||||
}
|
||||
|
||||
if (!as_table.empty())
|
||||
{
|
||||
std::string what = (!is_materialized_view ? " AS " : " TO ");
|
||||
settings.ostr << (settings.hilite ? hilite_keyword : "") << what << (settings.hilite ? hilite_none : "")
|
||||
<< (!as_database.empty() ? backQuoteIfNeed(as_database) + "." : "") << backQuoteIfNeed(as_table);
|
||||
settings.ostr
|
||||
<< (settings.hilite ? hilite_keyword : "") << " AS " << (settings.hilite ? hilite_none : "")
|
||||
<< (!as_database.empty() ? backQuoteIfNeed(as_database) + "." : "") << backQuoteIfNeed(as_table);
|
||||
}
|
||||
|
||||
if (columns)
|
||||
|
@ -208,6 +208,8 @@ bool ParserCreateQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
ASTPtr database;
|
||||
ASTPtr table;
|
||||
ASTPtr columns;
|
||||
ASTPtr to_database;
|
||||
ASTPtr to_table;
|
||||
ASTPtr storage;
|
||||
ASTPtr as_database;
|
||||
ASTPtr as_table;
|
||||
@ -219,7 +221,6 @@ bool ParserCreateQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
bool is_materialized_view = false;
|
||||
bool is_populate = false;
|
||||
bool is_temporary = false;
|
||||
bool to_table = false;
|
||||
|
||||
if (!s_create.ignore(pos, expected))
|
||||
{
|
||||
@ -362,17 +363,13 @@ bool ParserCreateQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
// TO [db.]table
|
||||
if (ParserKeyword{"TO"}.ignore(pos, expected))
|
||||
{
|
||||
to_table = true;
|
||||
|
||||
/// FIXME: as_table is ambiguous, it is set in AS clause also
|
||||
|
||||
if (!name_p.parse(pos, as_table, expected))
|
||||
if (!name_p.parse(pos, to_table, expected))
|
||||
return false;
|
||||
|
||||
if (s_dot.ignore(pos, expected))
|
||||
{
|
||||
as_database = as_table;
|
||||
if (!name_p.parse(pos, as_table, expected))
|
||||
to_database = to_table;
|
||||
if (!name_p.parse(pos, to_table, expected))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -422,6 +419,11 @@ bool ParserCreateQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
query->table = typeid_cast<ASTIdentifier &>(*table).name;
|
||||
query->cluster = cluster_str;
|
||||
|
||||
if (to_database)
|
||||
query->to_database = typeid_cast<ASTIdentifier &>(*to_database).name;
|
||||
if (to_table)
|
||||
query->to_table = typeid_cast<ASTIdentifier &>(*to_table).name;
|
||||
|
||||
query->set(query->columns, columns);
|
||||
query->set(query->storage, storage);
|
||||
if (as_database)
|
||||
|
@ -388,9 +388,6 @@ StoragePtr StorageFactory::get(
|
||||
checkAllTypesAreAllowedInTable(materialized_columns);
|
||||
checkAllTypesAreAllowedInTable(alias_columns);
|
||||
|
||||
if (!query.storage)
|
||||
throw Exception("Incorrect CREATE query: ENGINE required", ErrorCodes::ENGINE_REQUIRED);
|
||||
|
||||
if (query.is_materialized_view)
|
||||
{
|
||||
/// Pass local_context here to convey setting for inner table
|
||||
@ -400,6 +397,9 @@ StoragePtr StorageFactory::get(
|
||||
attach);
|
||||
}
|
||||
|
||||
if (!query.storage)
|
||||
throw Exception("Incorrect CREATE query: ENGINE required", ErrorCodes::ENGINE_REQUIRED);
|
||||
|
||||
ASTStorage & storage_def = *query.storage;
|
||||
const ASTFunction & engine_def = *storage_def.engine;
|
||||
|
||||
@ -423,7 +423,7 @@ StoragePtr StorageFactory::get(
|
||||
|
||||
auto check_arguments_empty = [&]
|
||||
{
|
||||
if (args_ptr)
|
||||
if (args_ptr && !args_ptr->empty())
|
||||
throw Exception(
|
||||
"Engine " + name + " doesn't support any arguments (" + toString(args_ptr->size()) + " given)",
|
||||
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||
|
@ -70,8 +70,10 @@ StorageMaterializedView::StorageMaterializedView(
|
||||
if (!query.select)
|
||||
throw Exception("SELECT query is not specified for " + getName(), ErrorCodes::INCORRECT_QUERY);
|
||||
|
||||
if (!query.storage && query.as_table.empty())
|
||||
throw Exception("ENGINE of MaterializedView should be specified explicitly", ErrorCodes::INCORRECT_QUERY);
|
||||
if (!query.storage && query.to_table.empty())
|
||||
throw Exception(
|
||||
"You must specify where to save results of a MaterializedView query: either ENGINE or an existing table in a TO clause",
|
||||
ErrorCodes::INCORRECT_QUERY);
|
||||
|
||||
extractDependentTable(*query.select, select_database_name, select_table_name);
|
||||
|
||||
@ -81,10 +83,10 @@ StorageMaterializedView::StorageMaterializedView(
|
||||
DatabaseAndTableName(database_name, table_name));
|
||||
|
||||
// If the destination table is not set, use inner table
|
||||
if (!query.as_table.empty())
|
||||
if (!query.to_table.empty())
|
||||
{
|
||||
target_database_name = query.as_database;
|
||||
target_table_name = query.as_table;
|
||||
target_database_name = query.to_database;
|
||||
target_table_name = query.to_table;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2,3 +2,9 @@
|
||||
2
|
||||
1
|
||||
2
|
||||
1
|
||||
2
|
||||
3
|
||||
1
|
||||
2
|
||||
3
|
||||
|
@ -5,16 +5,26 @@ DROP TABLE IF EXISTS test.mv;
|
||||
CREATE TABLE test.src (x UInt8) ENGINE = Null;
|
||||
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);
|
||||
USE test;
|
||||
|
||||
CREATE MATERIALIZED VIEW mv TO dst AS SELECT * FROM src;
|
||||
|
||||
INSERT INTO src VALUES (1), (2);
|
||||
SELECT * FROM mv;
|
||||
|
||||
-- Detach MV and see if the data is still readable
|
||||
DETACH TABLE test.mv;
|
||||
SELECT * FROM test.dst;
|
||||
DETACH TABLE mv;
|
||||
SELECT * FROM dst;
|
||||
|
||||
USE default;
|
||||
|
||||
-- Reattach MV (shortcut)
|
||||
ATTACH TABLE test.mv;
|
||||
|
||||
INSERT INTO test.src VALUES (3);
|
||||
|
||||
SELECT * FROM test.mv;
|
||||
|
||||
-- Drop the MV and see if the data is still readable
|
||||
DROP TABLE test.mv;
|
||||
SELECT * FROM test.dst;
|
||||
|
Loading…
Reference in New Issue
Block a user