From 0744606fc3c1173fad7230db8d3a9a348e59dd1e Mon Sep 17 00:00:00 2001 From: Amos Bird Date: Tue, 24 Mar 2020 06:28:30 +0800 Subject: [PATCH] DROP VIEW support. (#9831) --- dbms/src/Interpreters/InterpreterDropQuery.cpp | 11 +++++++---- dbms/src/Parsers/ASTDropQuery.cpp | 8 +++++--- dbms/src/Parsers/ASTDropQuery.h | 3 +++ dbms/src/Parsers/ParserDropQuery.cpp | 15 ++++++++++----- .../queries/0_stateless/01210_drop_view.reference | 0 .../tests/queries/0_stateless/01210_drop_view.sql | 9 +++++++++ 6 files changed, 34 insertions(+), 12 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/01210_drop_view.reference create mode 100644 dbms/tests/queries/0_stateless/01210_drop_view.sql diff --git a/dbms/src/Interpreters/InterpreterDropQuery.cpp b/dbms/src/Interpreters/InterpreterDropQuery.cpp index 12a39e5aac4..42d9528abd5 100644 --- a/dbms/src/Interpreters/InterpreterDropQuery.cpp +++ b/dbms/src/Interpreters/InterpreterDropQuery.cpp @@ -50,7 +50,7 @@ BlockIO InterpreterDropQuery::execute() else if (!drop.database.empty()) return executeToDatabase(drop.database, drop.kind, drop.if_exists); 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) return {}; - throw Exception("Temporary table " + backQuoteIfNeed(table_name) + " doesn't exist.", + throw Exception("Temporary table " + backQuoteIfNeed(table_name) + " doesn't exist", ErrorCodes::UNKNOWN_TABLE); } @@ -84,6 +84,9 @@ BlockIO InterpreterDropQuery::executeToTable( if (database && table) { + if (query_ptr->as().is_view && !table->isView()) + throw Exception("Table " + backQuoteIfNeed(table_name) + " is not a View", ErrorCodes::LOGICAL_ERROR); + auto table_id = table->getStorageID(); if (kind == ASTDropQuery::Kind::Detach) { @@ -242,7 +245,7 @@ BlockIO InterpreterDropQuery::executeToDatabase(const String & database_name, AS { 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) { @@ -279,7 +282,7 @@ DatabaseAndTable InterpreterDropQuery::tryGetDatabaseAndTable(const String & dat { StoragePtr table = database->tryGetTable(context, table_name); 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); return {std::move(database), std::move(table)}; diff --git a/dbms/src/Parsers/ASTDropQuery.cpp b/dbms/src/Parsers/ASTDropQuery.cpp index 56d0878ceed..da25ddcf34e 100644 --- a/dbms/src/Parsers/ASTDropQuery.cpp +++ b/dbms/src/Parsers/ASTDropQuery.cpp @@ -47,10 +47,12 @@ void ASTDropQuery::formatQueryImpl(const FormatSettings & settings, FormatState if (table.empty() && !database.empty()) settings.ostr << "DATABASE "; - else if (!is_dictionary) - settings.ostr << "TABLE "; - else + else if (is_dictionary) settings.ostr << "DICTIONARY "; + else if (is_view) + settings.ostr << "VIEW "; + else + settings.ostr << "TABLE "; if (if_exists) settings.ostr << "IF EXISTS "; diff --git a/dbms/src/Parsers/ASTDropQuery.h b/dbms/src/Parsers/ASTDropQuery.h index 52112aa4154..f31634e67c6 100644 --- a/dbms/src/Parsers/ASTDropQuery.h +++ b/dbms/src/Parsers/ASTDropQuery.h @@ -28,6 +28,9 @@ public: /// We dropping dictionary, so print correct word bool is_dictionary{false}; + /// Same as above + bool is_view{false}; + /** Get the text that identifies this element. */ String getID(char) const override; ASTPtr clone() const override; diff --git a/dbms/src/Parsers/ParserDropQuery.cpp b/dbms/src/Parsers/ParserDropQuery.cpp index b4ff0cb3804..1d2a63bdcd8 100644 --- a/dbms/src/Parsers/ParserDropQuery.cpp +++ b/dbms/src/Parsers/ParserDropQuery.cpp @@ -16,6 +16,7 @@ bool parseDropQuery(IParser::Pos & pos, ASTPtr & node, Expected & expected) ParserKeyword s_temporary("TEMPORARY"); ParserKeyword s_table("TABLE"); ParserKeyword s_dictionary("DICTIONARY"); + ParserKeyword s_view("VIEW"); ParserKeyword s_database("DATABASE"); ParserToken s_dot(TokenType::Dot); ParserKeyword s_if_exists("IF EXISTS"); @@ -27,6 +28,7 @@ bool parseDropQuery(IParser::Pos & pos, ASTPtr & node, Expected & expected) bool if_exists = false; bool temporary = false; bool is_dictionary = false; + bool is_view = false; if (s_database.ignore(pos, expected)) { @@ -44,14 +46,16 @@ bool parseDropQuery(IParser::Pos & pos, ASTPtr & node, Expected & expected) } 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; - if (!s_table.ignore(pos, expected)) + if (!is_view && !is_dictionary && !s_table.ignore(pos, expected)) { - if (!s_dictionary.ignore(pos, expected)) - return false; - is_dictionary = true; + return false; } 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->temporary = temporary; query->is_dictionary = is_dictionary; + query->is_view = is_view; tryGetIdentifierNameInto(database, query->database); tryGetIdentifierNameInto(table, query->table); diff --git a/dbms/tests/queries/0_stateless/01210_drop_view.reference b/dbms/tests/queries/0_stateless/01210_drop_view.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dbms/tests/queries/0_stateless/01210_drop_view.sql b/dbms/tests/queries/0_stateless/01210_drop_view.sql new file mode 100644 index 00000000000..eccf4252e0d --- /dev/null +++ b/dbms/tests/queries/0_stateless/01210_drop_view.sql @@ -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;