2017-08-04 15:54:00 +00:00
|
|
|
#include <Parsers/ParserSystemQuery.h>
|
|
|
|
#include <Parsers/ASTSystemQuery.h>
|
|
|
|
#include <Parsers/CommonParsers.h>
|
2019-12-15 13:48:11 +00:00
|
|
|
#include <Parsers/ExpressionElementParsers.h>
|
2020-06-05 07:03:51 +00:00
|
|
|
#include <Parsers/ASTIdentifier.h>
|
2019-12-15 13:48:11 +00:00
|
|
|
#include <Parsers/ASTLiteral.h>
|
2018-05-21 13:49:54 +00:00
|
|
|
#include <Parsers/parseDatabaseAndTableName.h>
|
2023-11-29 02:32:41 +00:00
|
|
|
#include <IO/ReadBufferFromString.h>
|
|
|
|
#include <IO/ReadHelpers.h>
|
2017-08-04 15:54:00 +00:00
|
|
|
|
2021-09-20 18:33:25 +00:00
|
|
|
#include <magic_enum.hpp>
|
2017-08-04 15:54:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2023-12-14 11:47:11 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int SUPPORT_IS_DISABLED;
|
|
|
|
}
|
|
|
|
|
2022-12-19 16:36:27 +00:00
|
|
|
[[nodiscard]] static bool parseQueryWithOnClusterAndMaybeTable(std::shared_ptr<ASTSystemQuery> & res, IParser::Pos & pos,
|
2021-06-20 08:24:43 +00:00
|
|
|
Expected & expected, bool require_table, bool allow_string_literal)
|
|
|
|
{
|
|
|
|
/// Better form for user: SYSTEM <ACTION> table ON CLUSTER cluster
|
|
|
|
/// Query rewritten form + form while executing on cluster: SYSTEM <ACTION> ON CLUSTER cluster table
|
|
|
|
/// Need to support both
|
|
|
|
String cluster;
|
|
|
|
bool parsed_on_cluster = false;
|
|
|
|
|
|
|
|
if (ParserKeyword{"ON"}.ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!ASTQueryWithOnCluster::parse(pos, cluster, expected))
|
|
|
|
return false;
|
|
|
|
parsed_on_cluster = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool parsed_table = false;
|
|
|
|
if (allow_string_literal)
|
|
|
|
{
|
|
|
|
ASTPtr ast;
|
|
|
|
if (ParserStringLiteral{}.parse(pos, ast, expected))
|
|
|
|
{
|
2021-10-12 18:11:00 +00:00
|
|
|
res->setTable(ast->as<ASTLiteral &>().value.safeGet<String>());
|
2021-06-20 08:24:43 +00:00
|
|
|
parsed_table = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!parsed_table)
|
2021-11-16 08:58:28 +00:00
|
|
|
parsed_table = parseDatabaseAndTableAsAST(pos, expected, res->database, res->table);
|
2021-06-20 08:24:43 +00:00
|
|
|
|
|
|
|
if (!parsed_table && require_table)
|
2022-01-30 05:46:11 +00:00
|
|
|
return false;
|
2021-06-20 08:24:43 +00:00
|
|
|
|
|
|
|
if (!parsed_on_cluster && ParserKeyword{"ON"}.ignore(pos, expected))
|
|
|
|
if (!ASTQueryWithOnCluster::parse(pos, cluster, expected))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
res->cluster = cluster;
|
2021-10-12 18:11:00 +00:00
|
|
|
|
|
|
|
if (res->database)
|
|
|
|
res->children.push_back(res->database);
|
|
|
|
if (res->table)
|
|
|
|
res->children.push_back(res->table);
|
|
|
|
|
2021-06-20 08:24:43 +00:00
|
|
|
return true;
|
|
|
|
}
|
2017-08-04 15:54:00 +00:00
|
|
|
|
2022-02-17 19:41:41 +00:00
|
|
|
enum class SystemQueryTargetType
|
|
|
|
{
|
2022-08-31 18:54:43 +00:00
|
|
|
Model,
|
2022-02-17 19:41:41 +00:00
|
|
|
Function,
|
2022-12-30 13:47:30 +00:00
|
|
|
Disk,
|
2022-02-17 19:41:41 +00:00
|
|
|
};
|
|
|
|
|
2022-12-19 16:36:27 +00:00
|
|
|
[[nodiscard]] static bool parseQueryWithOnClusterAndTarget(std::shared_ptr<ASTSystemQuery> & res, IParser::Pos & pos, Expected & expected, SystemQueryTargetType target_type)
|
2022-02-17 19:41:41 +00:00
|
|
|
{
|
|
|
|
/// Better form for user: SYSTEM <ACTION> target_name ON CLUSTER cluster
|
|
|
|
/// Query rewritten form + form while executing on cluster: SYSTEM <ACTION> ON CLUSTER cluster target_name
|
|
|
|
/// Need to support both
|
|
|
|
|
|
|
|
String cluster;
|
|
|
|
bool parsed_on_cluster = false;
|
|
|
|
|
|
|
|
if (ParserKeyword{"ON"}.ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!ASTQueryWithOnCluster::parse(pos, cluster, expected))
|
|
|
|
return false;
|
|
|
|
parsed_on_cluster = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
String target;
|
|
|
|
ASTPtr temporary_string_literal;
|
|
|
|
|
|
|
|
if (ParserStringLiteral{}.parse(pos, temporary_string_literal, expected))
|
|
|
|
{
|
|
|
|
target = temporary_string_literal->as<ASTLiteral &>().value.safeGet<String>();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ParserIdentifier identifier_parser;
|
|
|
|
ASTPtr identifier;
|
|
|
|
|
|
|
|
if (!identifier_parser.parse(pos, identifier, expected))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!tryGetIdentifierNameInto(identifier, target))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!parsed_on_cluster && ParserKeyword{"ON"}.ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!ASTQueryWithOnCluster::parse(pos, cluster, expected))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
res->cluster = cluster;
|
|
|
|
|
|
|
|
switch (target_type)
|
|
|
|
{
|
2022-08-31 18:54:43 +00:00
|
|
|
case SystemQueryTargetType::Model:
|
|
|
|
{
|
|
|
|
res->target_model = std::move(target);
|
|
|
|
break;
|
|
|
|
}
|
2022-02-17 19:41:41 +00:00
|
|
|
case SystemQueryTargetType::Function:
|
|
|
|
{
|
|
|
|
res->target_function = std::move(target);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case SystemQueryTargetType::Disk:
|
|
|
|
{
|
|
|
|
res->disk = std::move(target);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-12-19 16:36:27 +00:00
|
|
|
[[nodiscard]] static bool parseQueryWithOnCluster(std::shared_ptr<ASTSystemQuery> & res, IParser::Pos & pos,
|
2022-01-30 05:46:11 +00:00
|
|
|
Expected & expected)
|
2022-01-26 09:40:00 +00:00
|
|
|
{
|
|
|
|
String cluster_str;
|
|
|
|
if (ParserKeyword{"ON"}.ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!ASTQueryWithOnCluster::parse(pos, cluster_str, expected))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
res->cluster = cluster_str;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-12-29 14:34:11 +00:00
|
|
|
[[nodiscard]] static bool parseDropReplica(std::shared_ptr<ASTSystemQuery> & res, IParser::Pos & pos, Expected & expected, bool database)
|
|
|
|
{
|
|
|
|
if (!parseQueryWithOnCluster(res, pos, expected))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
ASTPtr ast;
|
|
|
|
if (!ParserStringLiteral{}.parse(pos, ast, expected))
|
|
|
|
return false;
|
|
|
|
res->replica = ast->as<ASTLiteral &>().value.safeGet<String>();
|
2023-04-07 16:26:23 +00:00
|
|
|
|
|
|
|
if (ParserKeyword{"FROM SHARD"}.ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!ParserStringLiteral{}.parse(pos, ast, expected))
|
|
|
|
return false;
|
|
|
|
res->shard = ast->as<ASTLiteral &>().value.safeGet<String>();
|
|
|
|
}
|
|
|
|
|
2022-12-29 14:34:11 +00:00
|
|
|
if (ParserKeyword{"FROM"}.ignore(pos, expected))
|
|
|
|
{
|
|
|
|
// way 1. parse replica database
|
|
|
|
// way 2. parse replica table
|
|
|
|
// way 3. parse replica zkpath
|
|
|
|
if (ParserKeyword{"DATABASE"}.ignore(pos, expected))
|
|
|
|
{
|
|
|
|
ParserIdentifier database_parser;
|
|
|
|
if (!database_parser.parse(pos, res->database, expected))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else if (!database && ParserKeyword{"TABLE"}.ignore(pos, expected))
|
|
|
|
{
|
|
|
|
parseDatabaseAndTableAsAST(pos, expected, res->database, res->table);
|
|
|
|
}
|
|
|
|
else if (ParserKeyword{"ZKPATH"}.ignore(pos, expected))
|
|
|
|
{
|
|
|
|
ASTPtr path_ast;
|
|
|
|
if (!ParserStringLiteral{}.parse(pos, path_ast, expected))
|
|
|
|
return false;
|
|
|
|
String zk_path = path_ast->as<ASTLiteral &>().value.safeGet<String>();
|
|
|
|
if (!zk_path.empty() && zk_path[zk_path.size() - 1] == '/')
|
|
|
|
zk_path.pop_back();
|
|
|
|
res->replica_zk_path = zk_path;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
res->is_drop_whole_replica = true;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-08-04 15:54:00 +00:00
|
|
|
bool ParserSystemQuery::parseImpl(IParser::Pos & pos, ASTPtr & node, Expected & expected)
|
|
|
|
{
|
2019-12-07 23:05:57 +00:00
|
|
|
if (!ParserKeyword{"SYSTEM"}.ignore(pos, expected))
|
2017-08-04 15:54:00 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
using Type = ASTSystemQuery::Type;
|
|
|
|
|
|
|
|
auto res = std::make_shared<ASTSystemQuery>();
|
|
|
|
|
|
|
|
bool found = false;
|
2021-09-06 14:24:03 +00:00
|
|
|
|
2021-09-20 15:15:23 +00:00
|
|
|
for (const auto & type : magic_enum::enum_values<Type>())
|
2017-08-04 15:54:00 +00:00
|
|
|
{
|
2021-09-20 15:15:23 +00:00
|
|
|
if (ParserKeyword{ASTSystemQuery::typeToString(type)}.ignore(pos, expected))
|
2017-08-04 15:54:00 +00:00
|
|
|
{
|
2021-09-20 15:15:23 +00:00
|
|
|
res->type = type;
|
2017-08-04 15:54:00 +00:00
|
|
|
found = true;
|
2021-09-06 14:24:03 +00:00
|
|
|
break;
|
2017-08-04 15:54:00 +00:00
|
|
|
}
|
2021-09-20 18:33:25 +00:00
|
|
|
}
|
2017-08-04 15:54:00 +00:00
|
|
|
|
|
|
|
if (!found)
|
|
|
|
return false;
|
|
|
|
|
2018-05-21 13:49:54 +00:00
|
|
|
switch (res->type)
|
2017-08-04 15:54:00 +00:00
|
|
|
{
|
2018-05-21 13:49:54 +00:00
|
|
|
case Type::RELOAD_DICTIONARY:
|
2019-12-15 13:48:11 +00:00
|
|
|
{
|
2021-06-20 08:24:43 +00:00
|
|
|
if (!parseQueryWithOnClusterAndMaybeTable(res, pos, expected, /* require table = */ true, /* allow_string_literal = */ true))
|
2018-05-21 13:49:54 +00:00
|
|
|
return false;
|
|
|
|
break;
|
2019-12-15 13:48:11 +00:00
|
|
|
}
|
2022-08-31 18:54:43 +00:00
|
|
|
case Type::RELOAD_MODEL:
|
|
|
|
{
|
|
|
|
if (!parseQueryWithOnClusterAndTarget(res, pos, expected, SystemQueryTargetType::Model))
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
}
|
2021-09-17 13:04:44 +00:00
|
|
|
case Type::RELOAD_FUNCTION:
|
|
|
|
{
|
2022-02-17 19:41:41 +00:00
|
|
|
if (!parseQueryWithOnClusterAndTarget(res, pos, expected, SystemQueryTargetType::Function))
|
|
|
|
return false;
|
2021-04-16 09:56:40 +00:00
|
|
|
break;
|
|
|
|
}
|
2022-12-29 14:34:11 +00:00
|
|
|
|
2020-05-17 12:44:22 +00:00
|
|
|
case Type::DROP_REPLICA:
|
|
|
|
{
|
2022-12-29 14:34:11 +00:00
|
|
|
if (!parseDropReplica(res, pos, expected, /* database */ false))
|
2022-12-19 16:36:27 +00:00
|
|
|
return false;
|
2022-12-29 14:34:11 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Type::DROP_DATABASE_REPLICA:
|
|
|
|
{
|
|
|
|
if (!parseDropReplica(res, pos, expected, /* database */ true))
|
2020-05-17 12:44:22 +00:00
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
}
|
2023-04-25 20:07:04 +00:00
|
|
|
case Type::ENABLE_FAILPOINT:
|
|
|
|
case Type::DISABLE_FAILPOINT:
|
|
|
|
{
|
|
|
|
ASTPtr ast;
|
|
|
|
if (ParserIdentifier{}.parse(pos, ast, expected))
|
|
|
|
res->fail_point_name = ast->as<ASTIdentifier &>().name();
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
}
|
2020-05-17 12:44:22 +00:00
|
|
|
|
2018-05-21 13:49:54 +00:00
|
|
|
case Type::RESTART_REPLICA:
|
|
|
|
case Type::SYNC_REPLICA:
|
2022-12-12 14:33:42 +00:00
|
|
|
case Type::WAIT_LOADING_PARTS:
|
2022-01-26 09:40:00 +00:00
|
|
|
{
|
2022-12-19 16:36:27 +00:00
|
|
|
if (!parseQueryWithOnCluster(res, pos, expected))
|
|
|
|
return false;
|
2021-11-16 08:58:28 +00:00
|
|
|
if (!parseDatabaseAndTableAsAST(pos, expected, res->database, res->table))
|
2020-06-03 18:51:49 +00:00
|
|
|
return false;
|
2023-03-27 23:39:36 +00:00
|
|
|
if (res->type == Type::SYNC_REPLICA)
|
|
|
|
{
|
|
|
|
if (ParserKeyword{"STRICT"}.ignore(pos, expected))
|
|
|
|
res->sync_replica_mode = SyncReplicaMode::STRICT;
|
|
|
|
else if (ParserKeyword{"LIGHTWEIGHT"}.ignore(pos, expected))
|
2023-12-21 16:57:04 +00:00
|
|
|
{
|
2024-01-05 15:17:15 +00:00
|
|
|
res->sync_replica_mode = SyncReplicaMode::LIGHTWEIGHT;
|
|
|
|
if (ParserKeyword{"FROM"}.ignore(pos, expected))
|
2023-12-22 15:10:23 +00:00
|
|
|
{
|
2024-01-05 15:17:15 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
ASTPtr replica_ast;
|
|
|
|
if (!ParserStringLiteral{}.parse(pos, replica_ast, expected))
|
|
|
|
return false;
|
|
|
|
res->src_replicas.insert(replica_ast->as<ASTLiteral &>().value.safeGet<String>());
|
|
|
|
} while (ParserToken{TokenType::Comma}.ignore(pos, expected));
|
|
|
|
}
|
2023-12-21 16:57:04 +00:00
|
|
|
}
|
2023-03-27 23:39:36 +00:00
|
|
|
else if (ParserKeyword{"PULL"}.ignore(pos, expected))
|
|
|
|
res->sync_replica_mode = SyncReplicaMode::PULL;
|
|
|
|
}
|
2020-06-03 18:51:49 +00:00
|
|
|
break;
|
2022-01-26 09:40:00 +00:00
|
|
|
}
|
2020-06-03 18:51:49 +00:00
|
|
|
|
2022-05-01 13:40:18 +00:00
|
|
|
case Type::SYNC_DATABASE_REPLICA:
|
|
|
|
{
|
2022-12-19 16:36:27 +00:00
|
|
|
if (!parseQueryWithOnCluster(res, pos, expected))
|
|
|
|
return false;
|
2022-05-01 13:40:18 +00:00
|
|
|
if (!parseDatabaseAsAST(pos, expected, res->database))
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
}
|
2021-04-21 09:53:46 +00:00
|
|
|
case Type::RESTART_DISK:
|
|
|
|
{
|
2022-02-17 19:41:41 +00:00
|
|
|
if (!parseQueryWithOnClusterAndTarget(res, pos, expected, SystemQueryTargetType::Disk))
|
2021-04-21 09:53:46 +00:00
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
}
|
2021-06-20 08:24:43 +00:00
|
|
|
/// FLUSH DISTRIBUTED requires table
|
|
|
|
/// START/STOP DISTRIBUTED SENDS does not require table
|
2020-06-03 18:51:49 +00:00
|
|
|
case Type::STOP_DISTRIBUTED_SENDS:
|
|
|
|
case Type::START_DISTRIBUTED_SENDS:
|
2021-06-20 08:24:43 +00:00
|
|
|
{
|
|
|
|
if (!parseQueryWithOnClusterAndMaybeTable(res, pos, expected, /* require table = */ false, /* allow_string_literal = */ false))
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-05-10 04:19:02 +00:00
|
|
|
case Type::FLUSH_DISTRIBUTED:
|
2021-06-20 08:24:43 +00:00
|
|
|
case Type::RESTORE_REPLICA:
|
2020-06-03 18:51:49 +00:00
|
|
|
{
|
2021-06-20 08:24:43 +00:00
|
|
|
if (!parseQueryWithOnClusterAndMaybeTable(res, pos, expected, /* require table = */ true, /* allow_string_literal = */ false))
|
|
|
|
return false;
|
2018-05-21 13:49:54 +00:00
|
|
|
break;
|
2020-06-03 18:51:49 +00:00
|
|
|
}
|
2018-05-21 13:49:54 +00:00
|
|
|
|
|
|
|
case Type::STOP_MERGES:
|
|
|
|
case Type::START_MERGES:
|
2020-10-20 15:10:24 +00:00
|
|
|
{
|
|
|
|
String storage_policy_str;
|
|
|
|
String volume_str;
|
|
|
|
|
2022-01-28 06:30:57 +00:00
|
|
|
auto parse_on_volume = [&]() -> bool
|
2020-10-20 15:10:24 +00:00
|
|
|
{
|
|
|
|
ASTPtr ast;
|
|
|
|
if (ParserIdentifier{}.parse(pos, ast, expected))
|
2020-10-24 18:46:10 +00:00
|
|
|
storage_policy_str = ast->as<ASTIdentifier &>().name();
|
2020-10-20 15:10:24 +00:00
|
|
|
else
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!ParserToken{TokenType::Dot}.ignore(pos, expected))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (ParserIdentifier{}.parse(pos, ast, expected))
|
2020-10-24 18:46:10 +00:00
|
|
|
volume_str = ast->as<ASTIdentifier &>().name();
|
2020-10-20 15:10:24 +00:00
|
|
|
else
|
|
|
|
return false;
|
2022-01-28 06:30:57 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
if (ParserKeyword{"ON VOLUME"}.ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!parse_on_volume())
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-12-19 16:36:27 +00:00
|
|
|
if (!parseQueryWithOnCluster(res, pos, expected))
|
|
|
|
return false;
|
2022-01-28 06:30:57 +00:00
|
|
|
if (ParserKeyword{"ON VOLUME"}.ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (!parse_on_volume())
|
|
|
|
return false;
|
|
|
|
}
|
2020-10-20 15:10:24 +00:00
|
|
|
}
|
2022-01-28 06:30:57 +00:00
|
|
|
|
2020-10-20 15:10:24 +00:00
|
|
|
res->storage_policy = storage_policy_str;
|
|
|
|
res->volume = volume_str;
|
|
|
|
if (res->volume.empty() && res->storage_policy.empty())
|
2021-11-16 08:58:28 +00:00
|
|
|
parseDatabaseAndTableAsAST(pos, expected, res->database, res->table);
|
2020-10-20 15:10:24 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-08-01 15:36:12 +00:00
|
|
|
case Type::STOP_TTL_MERGES:
|
|
|
|
case Type::START_TTL_MERGES:
|
2019-09-03 14:50:49 +00:00
|
|
|
case Type::STOP_MOVES:
|
|
|
|
case Type::START_MOVES:
|
2018-05-21 13:49:54 +00:00
|
|
|
case Type::STOP_FETCHES:
|
|
|
|
case Type::START_FETCHES:
|
|
|
|
case Type::STOP_REPLICATED_SENDS:
|
2019-02-02 11:28:43 +00:00
|
|
|
case Type::START_REPLICATED_SENDS:
|
2018-05-21 13:49:54 +00:00
|
|
|
case Type::STOP_REPLICATION_QUEUES:
|
|
|
|
case Type::START_REPLICATION_QUEUES:
|
2023-08-03 10:34:43 +00:00
|
|
|
case Type::STOP_PULLING_REPLICATION_LOG:
|
|
|
|
case Type::START_PULLING_REPLICATION_LOG:
|
2023-09-20 16:10:00 +00:00
|
|
|
case Type::STOP_CLEANUP:
|
|
|
|
case Type::START_CLEANUP:
|
2022-12-19 16:36:27 +00:00
|
|
|
if (!parseQueryWithOnCluster(res, pos, expected))
|
|
|
|
return false;
|
2021-11-16 08:58:28 +00:00
|
|
|
parseDatabaseAndTableAsAST(pos, expected, res->database, res->table);
|
2018-05-21 13:49:54 +00:00
|
|
|
break;
|
|
|
|
|
2023-02-12 19:17:55 +00:00
|
|
|
case Type::REFRESH_VIEW:
|
|
|
|
case Type::START_VIEW:
|
|
|
|
case Type::STOP_VIEW:
|
|
|
|
case Type::CANCEL_VIEW:
|
|
|
|
if (!parseDatabaseAndTableAsAST(pos, expected, res->database, res->table))
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Type::START_VIEWS:
|
|
|
|
case Type::STOP_VIEWS:
|
|
|
|
break;
|
|
|
|
|
2023-11-29 02:32:41 +00:00
|
|
|
case Type::TEST_VIEW:
|
|
|
|
{
|
|
|
|
if (!parseDatabaseAndTableAsAST(pos, expected, res->database, res->table))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (ParserKeyword{"UNSET FAKE TIME"}.ignore(pos, expected))
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (!ParserKeyword{"SET FAKE TIME"}.ignore(pos, expected))
|
|
|
|
return false;
|
|
|
|
ASTPtr ast;
|
|
|
|
if (!ParserStringLiteral{}.parse(pos, ast, expected))
|
|
|
|
return false;
|
|
|
|
String time_str = ast->as<ASTLiteral &>().value.get<const String &>();
|
|
|
|
ReadBufferFromString buf(time_str);
|
|
|
|
time_t time;
|
|
|
|
readDateTimeText(time, buf);
|
|
|
|
res->fake_time_for_view = Int64(time);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-01-07 19:19:33 +00:00
|
|
|
case Type::SUSPEND:
|
|
|
|
{
|
2022-12-19 16:36:27 +00:00
|
|
|
if (!parseQueryWithOnCluster(res, pos, expected))
|
|
|
|
return false;
|
2022-01-26 09:40:00 +00:00
|
|
|
|
2021-01-07 19:19:33 +00:00
|
|
|
ASTPtr seconds;
|
|
|
|
if (!(ParserKeyword{"FOR"}.ignore(pos, expected)
|
|
|
|
&& ParserUnsignedInteger().parse(pos, seconds, expected)
|
|
|
|
&& ParserKeyword{"SECOND"}.ignore(pos, expected))) /// SECOND, not SECONDS to be consistent with INTERVAL parsing in SQL
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
res->seconds = seconds->as<ASTLiteral>()->value.get<UInt64>();
|
|
|
|
break;
|
|
|
|
}
|
2022-04-25 16:49:00 +00:00
|
|
|
case Type::DROP_FILESYSTEM_CACHE:
|
|
|
|
{
|
|
|
|
ParserLiteral path_parser;
|
|
|
|
ASTPtr ast;
|
|
|
|
if (path_parser.parse(pos, ast, expected))
|
2023-07-30 11:39:54 +00:00
|
|
|
{
|
2023-04-15 11:08:49 +00:00
|
|
|
res->filesystem_cache_name = ast->as<ASTLiteral>()->value.safeGet<String>();
|
2023-07-30 11:39:54 +00:00
|
|
|
if (ParserKeyword{"KEY"}.ignore(pos, expected) && ParserIdentifier().parse(pos, ast, expected))
|
|
|
|
{
|
|
|
|
res->key_to_drop = ast->as<ASTIdentifier>()->name();
|
|
|
|
if (ParserKeyword{"OFFSET"}.ignore(pos, expected) && ParserLiteral().parse(pos, ast, expected))
|
|
|
|
res->offset_to_drop = ast->as<ASTLiteral>()->value.safeGet<UInt64>();
|
|
|
|
}
|
|
|
|
}
|
2022-12-19 16:36:27 +00:00
|
|
|
if (!parseQueryWithOnCluster(res, pos, expected))
|
|
|
|
return false;
|
2022-04-25 16:49:00 +00:00
|
|
|
break;
|
|
|
|
}
|
2023-06-29 14:41:36 +00:00
|
|
|
case Type::SYNC_FILESYSTEM_CACHE:
|
|
|
|
{
|
|
|
|
ParserLiteral path_parser;
|
|
|
|
ASTPtr ast;
|
|
|
|
if (path_parser.parse(pos, ast, expected))
|
|
|
|
res->filesystem_cache_name = ast->as<ASTLiteral>()->value.safeGet<String>();
|
|
|
|
if (!parseQueryWithOnCluster(res, pos, expected))
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
}
|
2023-12-14 11:47:11 +00:00
|
|
|
case Type::DROP_DISK_METADATA_CACHE:
|
|
|
|
{
|
|
|
|
throw Exception(ErrorCodes::SUPPORT_IS_DISABLED, "Not implemented");
|
|
|
|
}
|
2022-08-05 16:20:15 +00:00
|
|
|
case Type::DROP_SCHEMA_CACHE:
|
|
|
|
{
|
|
|
|
if (ParserKeyword{"FOR"}.ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (ParserKeyword{"FILE"}.ignore(pos, expected))
|
|
|
|
res->schema_cache_storage = "FILE";
|
|
|
|
else if (ParserKeyword{"S3"}.ignore(pos, expected))
|
|
|
|
res->schema_cache_storage = "S3";
|
|
|
|
else if (ParserKeyword{"HDFS"}.ignore(pos, expected))
|
|
|
|
res->schema_cache_storage = "HDFS";
|
|
|
|
else if (ParserKeyword{"URL"}.ignore(pos, expected))
|
|
|
|
res->schema_cache_storage = "URL";
|
2023-08-22 11:59:59 +00:00
|
|
|
else if (ParserKeyword{"AZURE"}.ignore(pos, expected))
|
|
|
|
res->schema_cache_storage = "AZURE";
|
2022-08-05 16:20:15 +00:00
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2023-09-27 16:21:10 +00:00
|
|
|
case Type::DROP_FORMAT_SCHEMA_CACHE:
|
|
|
|
{
|
2023-10-29 01:07:24 +00:00
|
|
|
if (ParserKeyword{"FOR"}.ignore(pos, expected))
|
|
|
|
{
|
|
|
|
if (ParserKeyword{"Protobuf"}.ignore(pos, expected))
|
|
|
|
res->schema_cache_format = "Protobuf";
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
break;
|
2023-09-27 16:21:10 +00:00
|
|
|
}
|
2022-06-08 12:09:59 +00:00
|
|
|
case Type::UNFREEZE:
|
|
|
|
{
|
|
|
|
ASTPtr ast;
|
|
|
|
if (ParserKeyword{"WITH NAME"}.ignore(pos, expected) && ParserStringLiteral{}.parse(pos, ast, expected))
|
|
|
|
{
|
|
|
|
res->backup_name = ast->as<ASTLiteral &>().value.get<const String &>();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-07-26 17:58:41 +00:00
|
|
|
case Type::START_LISTEN:
|
|
|
|
case Type::STOP_LISTEN:
|
|
|
|
{
|
|
|
|
if (!parseQueryWithOnCluster(res, pos, expected))
|
|
|
|
return false;
|
|
|
|
|
2023-08-10 16:10:33 +00:00
|
|
|
auto parse_server_type = [&](ServerType::Type & type, std::string & custom_name) -> bool
|
2023-07-26 17:58:41 +00:00
|
|
|
{
|
2023-08-10 16:10:33 +00:00
|
|
|
type = ServerType::Type::END;
|
|
|
|
custom_name = "";
|
|
|
|
|
|
|
|
for (const auto & cur_type : magic_enum::enum_values<ServerType::Type>())
|
2023-07-26 17:58:41 +00:00
|
|
|
{
|
2023-08-10 16:10:33 +00:00
|
|
|
if (ParserKeyword{ServerType::serverTypeToString(cur_type)}.ignore(pos, expected))
|
|
|
|
{
|
|
|
|
type = cur_type;
|
|
|
|
break;
|
|
|
|
}
|
2023-07-26 17:58:41 +00:00
|
|
|
}
|
|
|
|
|
2023-08-10 16:10:33 +00:00
|
|
|
if (type == ServerType::Type::END)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (type == ServerType::CUSTOM)
|
|
|
|
{
|
|
|
|
ASTPtr ast;
|
|
|
|
|
|
|
|
if (!ParserStringLiteral{}.parse(pos, ast, expected))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
custom_name = ast->as<ASTLiteral &>().value.get<const String &>();
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
ServerType::Type base_type;
|
|
|
|
std::string base_custom_name;
|
|
|
|
|
|
|
|
ServerType::Types exclude_type;
|
|
|
|
ServerType::CustomNames exclude_custom_names;
|
|
|
|
|
|
|
|
if (!parse_server_type(base_type, base_custom_name))
|
2023-07-26 17:58:41 +00:00
|
|
|
return false;
|
|
|
|
|
2023-08-10 16:10:33 +00:00
|
|
|
if (ParserKeyword{"EXCEPT"}.ignore(pos, expected))
|
2023-07-26 17:58:41 +00:00
|
|
|
{
|
2023-08-10 16:10:33 +00:00
|
|
|
if (base_type != ServerType::Type::QUERIES_ALL &&
|
|
|
|
base_type != ServerType::Type::QUERIES_DEFAULT &&
|
|
|
|
base_type != ServerType::Type::QUERIES_CUSTOM)
|
2023-07-26 17:58:41 +00:00
|
|
|
return false;
|
|
|
|
|
2023-08-10 16:10:33 +00:00
|
|
|
ServerType::Type current_type;
|
|
|
|
std::string current_custom_name;
|
|
|
|
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
if (!exclude_type.empty() && !ParserToken(TokenType::Comma).ignore(pos, expected))
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (!parse_server_type(current_type, current_custom_name))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
exclude_type.insert(current_type);
|
|
|
|
|
|
|
|
if (current_type == ServerType::Type::CUSTOM)
|
|
|
|
exclude_custom_names.insert(current_custom_name);
|
|
|
|
}
|
2023-07-26 17:58:41 +00:00
|
|
|
}
|
|
|
|
|
2023-08-10 16:10:33 +00:00
|
|
|
res->server_type = ServerType(base_type, base_custom_name, exclude_type, exclude_custom_names);
|
2023-07-26 17:58:41 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-05-21 13:49:54 +00:00
|
|
|
default:
|
2022-01-26 09:40:00 +00:00
|
|
|
{
|
2022-12-19 16:36:27 +00:00
|
|
|
if (!parseQueryWithOnCluster(res, pos, expected))
|
|
|
|
return false;
|
2018-05-21 13:49:54 +00:00
|
|
|
break;
|
2022-01-26 09:40:00 +00:00
|
|
|
}
|
2017-08-04 15:54:00 +00:00
|
|
|
}
|
|
|
|
|
2021-10-12 18:11:00 +00:00
|
|
|
if (res->database)
|
|
|
|
res->children.push_back(res->database);
|
|
|
|
if (res->table)
|
|
|
|
res->children.push_back(res->table);
|
|
|
|
|
2017-08-04 15:54:00 +00:00
|
|
|
node = std::move(res);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|