diff --git a/src/Interpreters/InterpreterExistsQuery.cpp b/src/Interpreters/InterpreterExistsQuery.cpp index 94a31db2e99..aeb5c0f9bcf 100644 --- a/src/Interpreters/InterpreterExistsQuery.cpp +++ b/src/Interpreters/InterpreterExistsQuery.cpp @@ -53,6 +53,13 @@ BlockInputStreamPtr InterpreterExistsQuery::executeImpl() result = DatabaseCatalog::instance().isTableExist({database, exists_query->table}, context); } } + else if ((exists_query = query_ptr->as())) + { + String database = context.resolveDatabase(exists_query->database); + context.checkAccess(AccessType::SHOW_TABLES, database, exists_query->table); + auto tbl = DatabaseCatalog::instance().tryGetTable({database, exists_query->table}, context); + result = tbl != nullptr && tbl->isView(); + } else if ((exists_query = query_ptr->as())) { String database = context.resolveDatabase(exists_query->database); diff --git a/src/Interpreters/InterpreterFactory.cpp b/src/Interpreters/InterpreterFactory.cpp index 7c2e82e76c1..2f5493c3775 100644 --- a/src/Interpreters/InterpreterFactory.cpp +++ b/src/Interpreters/InterpreterFactory.cpp @@ -156,6 +156,10 @@ std::unique_ptr InterpreterFactory::get(ASTPtr & query, Context & { return std::make_unique(query, context); } + else if (query->as()) + { + return std::make_unique(query, context); + } else if (query->as()) { return std::make_unique(query, context); diff --git a/src/Parsers/ParserTablePropertiesQuery.cpp b/src/Parsers/ParserTablePropertiesQuery.cpp index dc080b2f13b..2b123138db9 100644 --- a/src/Parsers/ParserTablePropertiesQuery.cpp +++ b/src/Parsers/ParserTablePropertiesQuery.cpp @@ -21,6 +21,7 @@ bool ParserTablePropertiesQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & ParserKeyword s_create("CREATE"); ParserKeyword s_database("DATABASE"); ParserKeyword s_table("TABLE"); + ParserKeyword s_view("VIEW"); ParserKeyword s_dictionary("DICTIONARY"); ParserToken s_dot(TokenType::Dot); ParserIdentifier name_p; @@ -30,6 +31,7 @@ bool ParserTablePropertiesQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & std::shared_ptr query; bool parse_only_database_name = false; + bool exists_view = false; bool temporary = false; if (s_exists.ignore(pos, expected)) @@ -39,6 +41,11 @@ bool ParserTablePropertiesQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & query = std::make_shared(); parse_only_database_name = true; } + else if (s_view.ignore(pos, expected)) + { + query = std::make_shared(); + exists_view = true; + } else { if (s_temporary.ignore(pos, expected)) @@ -79,15 +86,16 @@ bool ParserTablePropertiesQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & } else { - if (temporary || s_temporary.ignore(pos, expected)) - query->temporary = true; - - if (!s_table.ignore(pos, expected)) - s_dictionary.ignore(pos, expected); + if (!exists_view) + { + if (temporary || s_temporary.ignore(pos, expected)) + query->temporary = true; + if (!s_table.ignore(pos, expected)) + s_dictionary.ignore(pos, expected); + } if (!name_p.parse(pos, table, expected)) return false; - if (s_dot.ignore(pos, expected)) { database = table; diff --git a/src/Parsers/TablePropertiesQueriesASTs.h b/src/Parsers/TablePropertiesQueriesASTs.h index 3e0798dbcbd..66c202433bd 100644 --- a/src/Parsers/TablePropertiesQueriesASTs.h +++ b/src/Parsers/TablePropertiesQueriesASTs.h @@ -22,6 +22,15 @@ struct ASTExistsTableQueryIDAndQueryNames static constexpr auto QueryTemporary = "EXISTS TEMPORARY TABLE"; }; +struct ASTExistsViewQueryIDAndQueryNames +{ + static constexpr auto ID = "ExistsViewQuery"; + static constexpr auto Query = "EXISTS VIEW"; + /// No temporary view are supported, just for parsing + static constexpr auto QueryTemporary = ""; +}; + + struct ASTExistsDictionaryQueryIDAndQueryNames { static constexpr auto ID = "ExistsDictionaryQuery"; @@ -61,6 +70,7 @@ struct ASTDescribeQueryExistsQueryIDAndQueryNames using ASTExistsDatabaseQuery = ASTQueryWithTableAndOutputImpl; using ASTExistsTableQuery = ASTQueryWithTableAndOutputImpl; +using ASTExistsViewQuery = ASTQueryWithTableAndOutputImpl; using ASTExistsDictionaryQuery = ASTQueryWithTableAndOutputImpl; using ASTShowCreateTableQuery = ASTQueryWithTableAndOutputImpl; using ASTShowCreateDictionaryQuery = ASTQueryWithTableAndOutputImpl; diff --git a/tests/queries/0_stateless/01048_exists_query.reference b/tests/queries/0_stateless/01048_exists_query.reference index f1db7c70e71..ede3b4cdea7 100644 --- a/tests/queries/0_stateless/01048_exists_query.reference +++ b/tests/queries/0_stateless/01048_exists_query.reference @@ -21,6 +21,13 @@ 0 0 0 +1 +0 +0 +0 +0 +0 +0 0 0 0 diff --git a/tests/queries/0_stateless/01048_exists_query.sql b/tests/queries/0_stateless/01048_exists_query.sql index fca2c233c64..239f865fa99 100644 --- a/tests/queries/0_stateless/01048_exists_query.sql +++ b/tests/queries/0_stateless/01048_exists_query.sql @@ -40,6 +40,20 @@ EXISTS db_01048.t_01048; EXISTS TABLE db_01048.t_01048; EXISTS DICTIONARY db_01048.t_01048; + +CREATE TABLE db_01048.t_01048_2 (x UInt8) ENGINE = Memory; +CREATE VIEW db_01048.v_01048 AS SELECT * FROM db_01048.t_01048_2; +EXISTS VIEW db_01048.v_01048; +EXISTS VIEW db_01048.t_01048_2; +EXISTS VIEW db_01048.v_not_exist; +DROP VIEW db_01048.v_01048; +EXISTS VIEW db_01048.v_01048; +EXISTS VIEW db_01048.t_01048_2; +EXISTS VIEW db_01048.v_not_exist; +EXISTS VIEW db_not_exists.v_not_exist; +DROP TABLE db_01048.t_01048_2; + + DROP DATABASE db_01048; EXISTS db_01048.t_01048; EXISTS TABLE db_01048.t_01048;