mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
support operations with views in antlr parser
This commit is contained in:
parent
11f459ad03
commit
9c9e2a5936
@ -10,7 +10,6 @@
|
|||||||
#include <Access/AccessFlags.h>
|
#include <Access/AccessFlags.h>
|
||||||
#include <Common/typeid_cast.h>
|
#include <Common/typeid_cast.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -40,6 +39,7 @@ BlockInputStreamPtr InterpreterExistsQuery::executeImpl()
|
|||||||
{
|
{
|
||||||
ASTQueryWithTableAndOutput * exists_query;
|
ASTQueryWithTableAndOutput * exists_query;
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if ((exists_query = query_ptr->as<ASTExistsTableQuery>()))
|
if ((exists_query = query_ptr->as<ASTExistsTableQuery>()))
|
||||||
{
|
{
|
||||||
if (exists_query->temporary)
|
if (exists_query->temporary)
|
||||||
@ -57,8 +57,8 @@ BlockInputStreamPtr InterpreterExistsQuery::executeImpl()
|
|||||||
{
|
{
|
||||||
String database = context.resolveDatabase(exists_query->database);
|
String database = context.resolveDatabase(exists_query->database);
|
||||||
context.checkAccess(AccessType::SHOW_TABLES, database, exists_query->table);
|
context.checkAccess(AccessType::SHOW_TABLES, database, exists_query->table);
|
||||||
auto tbl = DatabaseCatalog::instance().tryGetTable({database, exists_query->table}, context);
|
auto table = DatabaseCatalog::instance().tryGetTable({database, exists_query->table}, context);
|
||||||
result = tbl != nullptr && tbl->isView();
|
result = table && table->isView();
|
||||||
}
|
}
|
||||||
else if ((exists_query = query_ptr->as<ASTExistsDatabaseQuery>()))
|
else if ((exists_query = query_ptr->as<ASTExistsDatabaseQuery>()))
|
||||||
{
|
{
|
||||||
|
@ -41,6 +41,16 @@ DropQuery::createDropTable(bool detach, bool if_exists, bool temporary, PtrTo<Ta
|
|||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
PtrTo<DropQuery>
|
||||||
|
DropQuery::createDropView(bool detach, bool if_exists, PtrTo<TableIdentifier> identifier, PtrTo<ClusterClause> cluster)
|
||||||
|
{
|
||||||
|
auto query = PtrTo<DropQuery>(new DropQuery(cluster, QueryType::VIEW, {identifier}));
|
||||||
|
query->detach = detach;
|
||||||
|
query->if_exists = if_exists;
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
DropQuery::DropQuery(PtrTo<ClusterClause> cluster, QueryType type, PtrList exprs) : DDLQuery(cluster, exprs), query_type(type)
|
DropQuery::DropQuery(PtrTo<ClusterClause> cluster, QueryType type, PtrList exprs) : DDLQuery(cluster, exprs), query_type(type)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -73,6 +83,14 @@ ASTPtr DropQuery::convertToOld() const
|
|||||||
query->database = database->getName();
|
query->database = database->getName();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case QueryType::VIEW:
|
||||||
|
{
|
||||||
|
query->is_view = true;
|
||||||
|
query->table = get<TableIdentifier>(NAME)->getName();
|
||||||
|
if (auto database = get<TableIdentifier>(NAME)->getDatabase())
|
||||||
|
query->database = database->getName();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
convertToOldPartially(query);
|
convertToOldPartially(query);
|
||||||
@ -100,6 +118,8 @@ antlrcpp::Any ParseTreeVisitor::visitDropTableStmt(ClickHouseParser::DropTableSt
|
|||||||
return DropQuery::createDropTable(!!ctx->DETACH(), !!ctx->EXISTS(), !!ctx->TEMPORARY(), visit(ctx->tableIdentifier()), cluster);
|
return DropQuery::createDropTable(!!ctx->DETACH(), !!ctx->EXISTS(), !!ctx->TEMPORARY(), visit(ctx->tableIdentifier()), cluster);
|
||||||
if (ctx->DICTIONARY())
|
if (ctx->DICTIONARY())
|
||||||
return DropQuery::createDropDictionary(!!ctx->DETACH(), !!ctx->EXISTS(), visit(ctx->tableIdentifier()), cluster);
|
return DropQuery::createDropDictionary(!!ctx->DETACH(), !!ctx->EXISTS(), visit(ctx->tableIdentifier()), cluster);
|
||||||
|
if (ctx->VIEW())
|
||||||
|
return DropQuery::createDropView(!!ctx->DETACH(), !!ctx->EXISTS(), visit(ctx->tableIdentifier()), cluster);
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@ class DropQuery : public DDLQuery
|
|||||||
createDropTable(bool detach, bool if_exists, bool temporary, PtrTo<TableIdentifier> identifier, PtrTo<ClusterClause> cluster);
|
createDropTable(bool detach, bool if_exists, bool temporary, PtrTo<TableIdentifier> identifier, PtrTo<ClusterClause> cluster);
|
||||||
static PtrTo<DropQuery>
|
static PtrTo<DropQuery>
|
||||||
createDropDictionary(bool detach, bool if_exists, PtrTo<TableIdentifier> identifier, PtrTo<ClusterClause> cluster);
|
createDropDictionary(bool detach, bool if_exists, PtrTo<TableIdentifier> identifier, PtrTo<ClusterClause> cluster);
|
||||||
|
static PtrTo<DropQuery>
|
||||||
|
createDropView(bool detach, bool if_exists, PtrTo<TableIdentifier> identifier, PtrTo<ClusterClause> cluster);
|
||||||
|
|
||||||
ASTPtr convertToOld() const override;
|
ASTPtr convertToOld() const override;
|
||||||
|
|
||||||
@ -29,6 +31,7 @@ class DropQuery : public DDLQuery
|
|||||||
DATABASE,
|
DATABASE,
|
||||||
DICTIONARY,
|
DICTIONARY,
|
||||||
TABLE,
|
TABLE,
|
||||||
|
VIEW,
|
||||||
};
|
};
|
||||||
|
|
||||||
const QueryType query_type;
|
const QueryType query_type;
|
||||||
|
@ -10,31 +10,51 @@
|
|||||||
namespace DB::AST
|
namespace DB::AST
|
||||||
{
|
{
|
||||||
|
|
||||||
ExistsQuery::ExistsQuery(QueryType type, bool temporary_, PtrTo<TableIdentifier> identifier)
|
ExistsQuery::ExistsQuery(QueryType type, bool temporary_, PtrList exprs)
|
||||||
: Query{identifier}, query_type(type), temporary(temporary_)
|
: Query(exprs), query_type(type), temporary(temporary_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
PtrTo<ExistsQuery> ExistsQuery::createTable(QueryType type, bool temporary, PtrTo<TableIdentifier> identifier)
|
||||||
|
{
|
||||||
|
return PtrTo<ExistsQuery>(new ExistsQuery(type, temporary, {identifier}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
PtrTo<ExistsQuery> ExistsQuery::createDatabase(PtrTo<DatabaseIdentifier> identifier)
|
||||||
|
{
|
||||||
|
return PtrTo<ExistsQuery>(new ExistsQuery(QueryType::DATABASE, false, {identifier}));
|
||||||
|
}
|
||||||
|
|
||||||
ASTPtr ExistsQuery::convertToOld() const
|
ASTPtr ExistsQuery::convertToOld() const
|
||||||
{
|
{
|
||||||
std::shared_ptr<ASTQueryWithTableAndOutput> query;
|
std::shared_ptr<ASTQueryWithTableAndOutput> query;
|
||||||
|
|
||||||
switch(query_type)
|
switch(query_type)
|
||||||
{
|
{
|
||||||
|
case QueryType::DATABASE:
|
||||||
|
query = std::make_shared<ASTExistsDatabaseQuery>();
|
||||||
|
tryGetIdentifierNameInto(get<DatabaseIdentifier>(IDENTIFIER)->convertToOld(), query->database);
|
||||||
|
return query;
|
||||||
|
|
||||||
case QueryType::DICTIONARY:
|
case QueryType::DICTIONARY:
|
||||||
query = std::make_shared<ASTExistsDictionaryQuery>();
|
query = std::make_shared<ASTExistsDictionaryQuery>();
|
||||||
break;
|
break;
|
||||||
case QueryType::TABLE:
|
case QueryType::TABLE:
|
||||||
query = std::make_shared<ASTExistsTableQuery>();
|
query = std::make_shared<ASTExistsTableQuery>();
|
||||||
query->temporary = temporary;
|
break;
|
||||||
|
case QueryType::VIEW:
|
||||||
|
query = std::make_shared<ASTExistsViewQuery>();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: this won't work if table doesn't exist
|
// FIXME: this won't work if table doesn't exist
|
||||||
auto table_id = getTableIdentifier(get(TABLE)->convertToOld());
|
auto table_id = getTableIdentifier(get<TableIdentifier>(IDENTIFIER)->convertToOld());
|
||||||
query->database = table_id.database_name;
|
query->database = table_id.database_name;
|
||||||
query->table = table_id.table_name;
|
query->table = table_id.table_name;
|
||||||
query->uuid = table_id.uuid;
|
query->uuid = table_id.uuid;
|
||||||
|
query->temporary = temporary;
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
@ -46,10 +66,22 @@ namespace DB
|
|||||||
|
|
||||||
using namespace AST;
|
using namespace AST;
|
||||||
|
|
||||||
antlrcpp::Any ParseTreeVisitor::visitExistsStmt(ClickHouseParser::ExistsStmtContext *ctx)
|
antlrcpp::Any ParseTreeVisitor::visitExistsTableStmt(ClickHouseParser::ExistsTableStmtContext *ctx)
|
||||||
{
|
{
|
||||||
auto type = ctx->TABLE() ? ExistsQuery::QueryType::TABLE : ExistsQuery::QueryType::DICTIONARY;
|
ExistsQuery::QueryType type;
|
||||||
return std::make_shared<ExistsQuery>(type, !!ctx->TEMPORARY(), visit(ctx->tableIdentifier()));
|
if (ctx->DICTIONARY())
|
||||||
|
type = ExistsQuery::QueryType::DICTIONARY;
|
||||||
|
else if (ctx->VIEW())
|
||||||
|
type = ExistsQuery::QueryType::VIEW;
|
||||||
|
else // Query 'EXISTS <table_name>' is interptered as 'EXISTS TABLE <table_name>'
|
||||||
|
type = ExistsQuery::QueryType::TABLE;
|
||||||
|
|
||||||
|
return ExistsQuery::createTable(type, !!ctx->TEMPORARY(), visit(ctx->tableIdentifier()));
|
||||||
|
}
|
||||||
|
|
||||||
|
antlrcpp::Any ParseTreeVisitor::visitExistsDatabaseStmt(ClickHouseParser::ExistsDatabaseStmtContext *ctx)
|
||||||
|
{
|
||||||
|
return ExistsQuery::createDatabase(visit(ctx->databaseIdentifier()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,16 +13,21 @@ class ExistsQuery : public Query
|
|||||||
{
|
{
|
||||||
DICTIONARY,
|
DICTIONARY,
|
||||||
TABLE,
|
TABLE,
|
||||||
|
VIEW,
|
||||||
|
DATABASE,
|
||||||
};
|
};
|
||||||
|
|
||||||
ExistsQuery(QueryType type, bool temporary, PtrTo<TableIdentifier> identifier);
|
static PtrTo<ExistsQuery> createTable(QueryType type, bool temporary, PtrTo<TableIdentifier> identifier);
|
||||||
|
static PtrTo<ExistsQuery> createDatabase(PtrTo<DatabaseIdentifier> identifier);
|
||||||
|
|
||||||
|
ExistsQuery(QueryType type, bool temporary, PtrList exprs);
|
||||||
|
|
||||||
ASTPtr convertToOld() const override;
|
ASTPtr convertToOld() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum ChildIndex : UInt8
|
enum ChildIndex : UInt8
|
||||||
{
|
{
|
||||||
TABLE = 0, // TableIdentifier
|
IDENTIFIER = 0, // DatabaseIdentifier or TableIdentifier
|
||||||
};
|
};
|
||||||
|
|
||||||
const QueryType query_type;
|
const QueryType query_type;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -173,12 +173,15 @@ describeStmt: (DESCRIBE | DESC) TABLE? tableExpr;
|
|||||||
|
|
||||||
dropStmt
|
dropStmt
|
||||||
: (DETACH | DROP) DATABASE (IF EXISTS)? databaseIdentifier clusterClause? # DropDatabaseStmt
|
: (DETACH | DROP) DATABASE (IF EXISTS)? databaseIdentifier clusterClause? # DropDatabaseStmt
|
||||||
| (DETACH | DROP) (DICTIONARY | TEMPORARY? TABLE) (IF EXISTS)? tableIdentifier clusterClause? (NO DELAY)? # DropTableStmt
|
| (DETACH | DROP) (DICTIONARY | TEMPORARY? TABLE | VIEW) (IF EXISTS)? tableIdentifier clusterClause? (NO DELAY)? # DropTableStmt
|
||||||
;
|
;
|
||||||
|
|
||||||
// EXISTS statement
|
// EXISTS statement
|
||||||
|
|
||||||
existsStmt: EXISTS (DICTIONARY | TEMPORARY? TABLE)? tableIdentifier;
|
existsStmt
|
||||||
|
: EXISTS DATABASE databaseIdentifier # ExistsDatabaseStmt
|
||||||
|
| EXISTS (DICTIONARY | TEMPORARY? TABLE | VIEW)? tableIdentifier # ExistsTableStmt
|
||||||
|
;
|
||||||
|
|
||||||
// EXPLAIN statement
|
// EXPLAIN statement
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -164,7 +164,9 @@ public:
|
|||||||
|
|
||||||
virtual antlrcpp::Any visitDropTableStmt(ClickHouseParser::DropTableStmtContext *context) = 0;
|
virtual antlrcpp::Any visitDropTableStmt(ClickHouseParser::DropTableStmtContext *context) = 0;
|
||||||
|
|
||||||
virtual antlrcpp::Any visitExistsStmt(ClickHouseParser::ExistsStmtContext *context) = 0;
|
virtual antlrcpp::Any visitExistsDatabaseStmt(ClickHouseParser::ExistsDatabaseStmtContext *context) = 0;
|
||||||
|
|
||||||
|
virtual antlrcpp::Any visitExistsTableStmt(ClickHouseParser::ExistsTableStmtContext *context) = 0;
|
||||||
|
|
||||||
virtual antlrcpp::Any visitExplainStmt(ClickHouseParser::ExplainStmtContext *context) = 0;
|
virtual antlrcpp::Any visitExplainStmt(ClickHouseParser::ExplainStmtContext *context) = 0;
|
||||||
|
|
||||||
|
@ -136,7 +136,8 @@ public:
|
|||||||
antlrcpp::Any visitTtlExpr(ClickHouseParser::TtlExprContext * ctx) override;
|
antlrcpp::Any visitTtlExpr(ClickHouseParser::TtlExprContext * ctx) override;
|
||||||
|
|
||||||
// ExistsQuery
|
// ExistsQuery
|
||||||
antlrcpp::Any visitExistsStmt(ClickHouseParser::ExistsStmtContext * ctx) override;
|
antlrcpp::Any visitExistsTableStmt(ClickHouseParser::ExistsTableStmtContext * ctx) override;
|
||||||
|
antlrcpp::Any visitExistsDatabaseStmt(ClickHouseParser::ExistsDatabaseStmtContext * ctx) override;
|
||||||
|
|
||||||
// ExplainQuery
|
// ExplainQuery
|
||||||
antlrcpp::Any visitExplainStmt(ClickHouseParser::ExplainStmtContext * ctx) override;
|
antlrcpp::Any visitExplainStmt(ClickHouseParser::ExplainStmtContext * ctx) override;
|
||||||
|
@ -76,7 +76,6 @@ struct ASTDescribeQueryExistsQueryIDAndQueryNames
|
|||||||
static constexpr auto QueryTemporary = "DESCRIBE TEMPORARY TABLE";
|
static constexpr auto QueryTemporary = "DESCRIBE TEMPORARY TABLE";
|
||||||
};
|
};
|
||||||
|
|
||||||
using ASTExistsDatabaseQuery = ASTQueryWithTableAndOutputImpl<ASTExistsDatabaseQueryIDAndQueryNames>;
|
|
||||||
using ASTExistsTableQuery = ASTQueryWithTableAndOutputImpl<ASTExistsTableQueryIDAndQueryNames>;
|
using ASTExistsTableQuery = ASTQueryWithTableAndOutputImpl<ASTExistsTableQueryIDAndQueryNames>;
|
||||||
using ASTExistsViewQuery = ASTQueryWithTableAndOutputImpl<ASTExistsViewQueryIDAndQueryNames>;
|
using ASTExistsViewQuery = ASTQueryWithTableAndOutputImpl<ASTExistsViewQueryIDAndQueryNames>;
|
||||||
using ASTExistsDictionaryQuery = ASTQueryWithTableAndOutputImpl<ASTExistsDictionaryQueryIDAndQueryNames>;
|
using ASTExistsDictionaryQuery = ASTQueryWithTableAndOutputImpl<ASTExistsDictionaryQueryIDAndQueryNames>;
|
||||||
@ -84,6 +83,16 @@ using ASTShowCreateTableQuery = ASTQueryWithTableAndOutputImpl<ASTShowCreateTabl
|
|||||||
using ASTShowCreateViewQuery = ASTQueryWithTableAndOutputImpl<ASTShowCreateViewQueryIDAndQueryNames>;
|
using ASTShowCreateViewQuery = ASTQueryWithTableAndOutputImpl<ASTShowCreateViewQueryIDAndQueryNames>;
|
||||||
using ASTShowCreateDictionaryQuery = ASTQueryWithTableAndOutputImpl<ASTShowCreateDictionaryQueryIDAndQueryNames>;
|
using ASTShowCreateDictionaryQuery = ASTQueryWithTableAndOutputImpl<ASTShowCreateDictionaryQueryIDAndQueryNames>;
|
||||||
|
|
||||||
|
class ASTExistsDatabaseQuery : public ASTQueryWithTableAndOutputImpl<ASTExistsDatabaseQueryIDAndQueryNames>
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void formatQueryImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const override
|
||||||
|
{
|
||||||
|
settings.ostr << (settings.hilite ? hilite_keyword : "") << ASTExistsDatabaseQueryIDAndQueryNames::Query
|
||||||
|
<< " " << (settings.hilite ? hilite_none : "") << backQuoteIfNeed(database);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class ASTShowCreateDatabaseQuery : public ASTQueryWithTableAndOutputImpl<ASTShowCreateDatabaseQueryIDAndQueryNames>
|
class ASTShowCreateDatabaseQuery : public ASTQueryWithTableAndOutputImpl<ASTShowCreateDatabaseQueryIDAndQueryNames>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -28,7 +28,7 @@ EXISTS t_01048; -- Does not work for temporary tables. Maybe have to fix.
|
|||||||
EXISTS TABLE t_01048;
|
EXISTS TABLE t_01048;
|
||||||
EXISTS DICTIONARY t_01048;
|
EXISTS DICTIONARY t_01048;
|
||||||
|
|
||||||
CREATE DICTIONARY db_01048.t_01048 (k UInt64, v String) PRIMARY KEY k LAYOUT(FLAT()) SOURCE(HTTP(URL 'http://example.test/' FORMAT TSV)) LIFETIME(1000);
|
CREATE DICTIONARY db_01048.t_01048 (k UInt64, v String) PRIMARY KEY k LAYOUT(FLAT()) SOURCE(HTTP(URL 'http://example.test/' FORMAT 'TSV')) LIFETIME(1000);
|
||||||
EXISTS db_01048.t_01048;
|
EXISTS db_01048.t_01048;
|
||||||
EXISTS TABLE db_01048.t_01048; -- Dictionaries are tables as well. But not all tables are dictionaries.
|
EXISTS TABLE db_01048.t_01048; -- Dictionaries are tables as well. But not all tables are dictionaries.
|
||||||
EXISTS DICTIONARY db_01048.t_01048;
|
EXISTS DICTIONARY db_01048.t_01048;
|
||||||
|
@ -162,7 +162,6 @@
|
|||||||
"01039_test_setting_parse",
|
"01039_test_setting_parse",
|
||||||
"01042_system_reload_dictionary_reloads_completely",
|
"01042_system_reload_dictionary_reloads_completely",
|
||||||
"01045_dictionaries_restrictions",
|
"01045_dictionaries_restrictions",
|
||||||
"01048_exists_query",
|
|
||||||
"01055_compact_parts_1",
|
"01055_compact_parts_1",
|
||||||
"01056_create_table_as",
|
"01056_create_table_as",
|
||||||
"01066_bit_count",
|
"01066_bit_count",
|
||||||
@ -197,7 +196,6 @@
|
|||||||
"01190_full_attach_syntax",
|
"01190_full_attach_syntax",
|
||||||
"01191_rename_dictionary",
|
"01191_rename_dictionary",
|
||||||
"01192_rename_database_zookeeper",
|
"01192_rename_database_zookeeper",
|
||||||
"01210_drop_view",
|
|
||||||
"01213_alter_rename_column",
|
"01213_alter_rename_column",
|
||||||
"01232_untuple",
|
"01232_untuple",
|
||||||
"01244_optimize_distributed_group_by_sharding_key",
|
"01244_optimize_distributed_group_by_sharding_key",
|
||||||
@ -209,7 +207,6 @@
|
|||||||
"01269_create_with_null",
|
"01269_create_with_null",
|
||||||
"01271_show_privileges",
|
"01271_show_privileges",
|
||||||
"01272_offset_without_limit",
|
"01272_offset_without_limit",
|
||||||
"01275_parallel_mv",
|
|
||||||
"01277_alter_rename_column_constraint_zookeeper",
|
"01277_alter_rename_column_constraint_zookeeper",
|
||||||
"01278_min_insert_block_size_rows_for_materialized_views",
|
"01278_min_insert_block_size_rows_for_materialized_views",
|
||||||
"01280_min_map_max_map",
|
"01280_min_map_max_map",
|
||||||
|
Loading…
Reference in New Issue
Block a user