mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 16:42:05 +00:00
DROP VIEW support. (#9831)
This commit is contained in:
parent
38cbf3e6f7
commit
0744606fc3
@ -50,7 +50,7 @@ BlockIO InterpreterDropQuery::execute()
|
|||||||
else if (!drop.database.empty())
|
else if (!drop.database.empty())
|
||||||
return executeToDatabase(drop.database, drop.kind, drop.if_exists);
|
return executeToDatabase(drop.database, drop.kind, drop.if_exists);
|
||||||
else
|
else
|
||||||
throw Exception("Nothing to drop, both names are empty.", ErrorCodes::LOGICAL_ERROR);
|
throw Exception("Nothing to drop, both names are empty", ErrorCodes::LOGICAL_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ BlockIO InterpreterDropQuery::executeToTable(
|
|||||||
{
|
{
|
||||||
if (if_exists)
|
if (if_exists)
|
||||||
return {};
|
return {};
|
||||||
throw Exception("Temporary table " + backQuoteIfNeed(table_name) + " doesn't exist.",
|
throw Exception("Temporary table " + backQuoteIfNeed(table_name) + " doesn't exist",
|
||||||
ErrorCodes::UNKNOWN_TABLE);
|
ErrorCodes::UNKNOWN_TABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,6 +84,9 @@ BlockIO InterpreterDropQuery::executeToTable(
|
|||||||
|
|
||||||
if (database && table)
|
if (database && table)
|
||||||
{
|
{
|
||||||
|
if (query_ptr->as<ASTDropQuery &>().is_view && !table->isView())
|
||||||
|
throw Exception("Table " + backQuoteIfNeed(table_name) + " is not a View", ErrorCodes::LOGICAL_ERROR);
|
||||||
|
|
||||||
auto table_id = table->getStorageID();
|
auto table_id = table->getStorageID();
|
||||||
if (kind == ASTDropQuery::Kind::Detach)
|
if (kind == ASTDropQuery::Kind::Detach)
|
||||||
{
|
{
|
||||||
@ -242,7 +245,7 @@ BlockIO InterpreterDropQuery::executeToDatabase(const String & database_name, AS
|
|||||||
{
|
{
|
||||||
if (kind == ASTDropQuery::Kind::Truncate)
|
if (kind == ASTDropQuery::Kind::Truncate)
|
||||||
{
|
{
|
||||||
throw Exception("Unable to truncate database.", ErrorCodes::SYNTAX_ERROR);
|
throw Exception("Unable to truncate database", ErrorCodes::SYNTAX_ERROR);
|
||||||
}
|
}
|
||||||
else if (kind == ASTDropQuery::Kind::Detach || kind == ASTDropQuery::Kind::Drop)
|
else if (kind == ASTDropQuery::Kind::Detach || kind == ASTDropQuery::Kind::Drop)
|
||||||
{
|
{
|
||||||
@ -279,7 +282,7 @@ DatabaseAndTable InterpreterDropQuery::tryGetDatabaseAndTable(const String & dat
|
|||||||
{
|
{
|
||||||
StoragePtr table = database->tryGetTable(context, table_name);
|
StoragePtr table = database->tryGetTable(context, table_name);
|
||||||
if (!table && !if_exists)
|
if (!table && !if_exists)
|
||||||
throw Exception("Table " + backQuoteIfNeed(database_name) + "." + backQuoteIfNeed(table_name) + " doesn't exist.",
|
throw Exception("Table " + backQuoteIfNeed(database_name) + "." + backQuoteIfNeed(table_name) + " doesn't exist",
|
||||||
ErrorCodes::UNKNOWN_TABLE);
|
ErrorCodes::UNKNOWN_TABLE);
|
||||||
|
|
||||||
return {std::move(database), std::move(table)};
|
return {std::move(database), std::move(table)};
|
||||||
|
@ -47,10 +47,12 @@ void ASTDropQuery::formatQueryImpl(const FormatSettings & settings, FormatState
|
|||||||
|
|
||||||
if (table.empty() && !database.empty())
|
if (table.empty() && !database.empty())
|
||||||
settings.ostr << "DATABASE ";
|
settings.ostr << "DATABASE ";
|
||||||
else if (!is_dictionary)
|
else if (is_dictionary)
|
||||||
settings.ostr << "TABLE ";
|
|
||||||
else
|
|
||||||
settings.ostr << "DICTIONARY ";
|
settings.ostr << "DICTIONARY ";
|
||||||
|
else if (is_view)
|
||||||
|
settings.ostr << "VIEW ";
|
||||||
|
else
|
||||||
|
settings.ostr << "TABLE ";
|
||||||
|
|
||||||
if (if_exists)
|
if (if_exists)
|
||||||
settings.ostr << "IF EXISTS ";
|
settings.ostr << "IF EXISTS ";
|
||||||
|
@ -28,6 +28,9 @@ public:
|
|||||||
/// We dropping dictionary, so print correct word
|
/// We dropping dictionary, so print correct word
|
||||||
bool is_dictionary{false};
|
bool is_dictionary{false};
|
||||||
|
|
||||||
|
/// Same as above
|
||||||
|
bool is_view{false};
|
||||||
|
|
||||||
/** Get the text that identifies this element. */
|
/** Get the text that identifies this element. */
|
||||||
String getID(char) const override;
|
String getID(char) const override;
|
||||||
ASTPtr clone() const override;
|
ASTPtr clone() const override;
|
||||||
|
@ -16,6 +16,7 @@ bool parseDropQuery(IParser::Pos & pos, ASTPtr & node, Expected & expected)
|
|||||||
ParserKeyword s_temporary("TEMPORARY");
|
ParserKeyword s_temporary("TEMPORARY");
|
||||||
ParserKeyword s_table("TABLE");
|
ParserKeyword s_table("TABLE");
|
||||||
ParserKeyword s_dictionary("DICTIONARY");
|
ParserKeyword s_dictionary("DICTIONARY");
|
||||||
|
ParserKeyword s_view("VIEW");
|
||||||
ParserKeyword s_database("DATABASE");
|
ParserKeyword s_database("DATABASE");
|
||||||
ParserToken s_dot(TokenType::Dot);
|
ParserToken s_dot(TokenType::Dot);
|
||||||
ParserKeyword s_if_exists("IF EXISTS");
|
ParserKeyword s_if_exists("IF EXISTS");
|
||||||
@ -27,6 +28,7 @@ bool parseDropQuery(IParser::Pos & pos, ASTPtr & node, Expected & expected)
|
|||||||
bool if_exists = false;
|
bool if_exists = false;
|
||||||
bool temporary = false;
|
bool temporary = false;
|
||||||
bool is_dictionary = false;
|
bool is_dictionary = false;
|
||||||
|
bool is_view = false;
|
||||||
|
|
||||||
if (s_database.ignore(pos, expected))
|
if (s_database.ignore(pos, expected))
|
||||||
{
|
{
|
||||||
@ -44,14 +46,16 @@ bool parseDropQuery(IParser::Pos & pos, ASTPtr & node, Expected & expected)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (s_temporary.ignore(pos, expected))
|
if (s_view.ignore(pos, expected))
|
||||||
|
is_view = true;
|
||||||
|
else if (s_dictionary.ignore(pos, expected))
|
||||||
|
is_dictionary = true;
|
||||||
|
else if (s_temporary.ignore(pos, expected))
|
||||||
temporary = true;
|
temporary = true;
|
||||||
|
|
||||||
if (!s_table.ignore(pos, expected))
|
if (!is_view && !is_dictionary && !s_table.ignore(pos, expected))
|
||||||
{
|
{
|
||||||
if (!s_dictionary.ignore(pos, expected))
|
return false;
|
||||||
return false;
|
|
||||||
is_dictionary = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_if_exists.ignore(pos, expected))
|
if (s_if_exists.ignore(pos, expected))
|
||||||
@ -81,6 +85,7 @@ bool parseDropQuery(IParser::Pos & pos, ASTPtr & node, Expected & expected)
|
|||||||
query->if_exists = if_exists;
|
query->if_exists = if_exists;
|
||||||
query->temporary = temporary;
|
query->temporary = temporary;
|
||||||
query->is_dictionary = is_dictionary;
|
query->is_dictionary = is_dictionary;
|
||||||
|
query->is_view = is_view;
|
||||||
|
|
||||||
tryGetIdentifierNameInto(database, query->database);
|
tryGetIdentifierNameInto(database, query->database);
|
||||||
tryGetIdentifierNameInto(table, query->table);
|
tryGetIdentifierNameInto(table, query->table);
|
||||||
|
9
dbms/tests/queries/0_stateless/01210_drop_view.sql
Normal file
9
dbms/tests/queries/0_stateless/01210_drop_view.sql
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
DROP VIEW IF EXISTS v_01210;
|
||||||
|
DROP TABLE IF EXISTS mv_01210;
|
||||||
|
DROP TABLE IF EXISTS `.inner.mv_01210`;
|
||||||
|
|
||||||
|
CREATE VIEW IF NOT EXISTS v_01210 AS SELECT 1;
|
||||||
|
CREATE MATERIALIZED VIEW IF NOT EXISTS mv_01210 ENGINE Log AS SELECT 1;
|
||||||
|
|
||||||
|
DROP VIEW v_01210;
|
||||||
|
DROP VIEW mv_01210;
|
Loading…
Reference in New Issue
Block a user