mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
Improve access rights: SHOW splitted into SHOW_DATABASES, SHOW_TABLES, SHOW_COLUMNS, SHOW_DICTIONARIES, EXISTS deleted.
This commit is contained in:
parent
66172cc2eb
commit
c1f5f8bc89
@ -63,15 +63,24 @@ public:
|
||||
/// Returns a list of keywords.
|
||||
std::vector<std::string_view> toKeywords() const;
|
||||
|
||||
/// Returns the access types which could be granted on the database level.
|
||||
/// For example, SELECT can be granted on the database level, but CREATE_USER cannot.
|
||||
static AccessFlags databaseLevel();
|
||||
/// Returns all the flags.
|
||||
/// These are the same as (allGlobalFlags() | allDatabaseFlags() | allTableFlags() | allColumnsFlags() | allDictionaryFlags()).
|
||||
static AccessFlags allFlags();
|
||||
|
||||
/// Returns the access types which could be granted on the table/dictionary level.
|
||||
static AccessFlags tableLevel();
|
||||
/// Returns all the global flags.
|
||||
static AccessFlags allGlobalFlags();
|
||||
|
||||
/// Returns the access types which could be granted on the column/attribute level.
|
||||
static AccessFlags columnLevel();
|
||||
/// Returns all the flags related to a database.
|
||||
static AccessFlags allDatabaseFlags();
|
||||
|
||||
/// Returns all the flags related to a table.
|
||||
static AccessFlags allTableFlags();
|
||||
|
||||
/// Returns all the flags related to a column.
|
||||
static AccessFlags allColumnFlags();
|
||||
|
||||
/// Returns all the flags related to a dictionary.
|
||||
static AccessFlags allDictionaryFlags();
|
||||
|
||||
private:
|
||||
static constexpr size_t NUM_FLAGS = 128;
|
||||
@ -158,22 +167,27 @@ public:
|
||||
return str;
|
||||
}
|
||||
|
||||
const Flags & getDatabaseLevelFlags() const { return all_grantable_on_level[DATABASE_LEVEL]; }
|
||||
const Flags & getTableLevelFlags() const { return all_grantable_on_level[TABLE_LEVEL]; }
|
||||
const Flags & getColumnLevelFlags() const { return all_grantable_on_level[COLUMN_LEVEL]; }
|
||||
const Flags & getAllFlags() const { return all_flags; }
|
||||
const Flags & getGlobalFlags() const { return all_flags_for_target[GLOBAL]; }
|
||||
const Flags & getDatabaseFlags() const { return all_flags_for_target[DATABASE]; }
|
||||
const Flags & getTableFlags() const { return all_flags_for_target[TABLE]; }
|
||||
const Flags & getColumnFlags() const { return all_flags_for_target[COLUMN]; }
|
||||
const Flags & getDictionaryFlags() const { return all_flags_for_target[DICTIONARY]; }
|
||||
|
||||
private:
|
||||
enum Level
|
||||
enum Target
|
||||
{
|
||||
UNKNOWN_LEVEL = -1,
|
||||
GLOBAL_LEVEL = 0,
|
||||
DATABASE_LEVEL = 1,
|
||||
TABLE_LEVEL = 2,
|
||||
VIEW_LEVEL = 2,
|
||||
DICTIONARY_LEVEL = 2,
|
||||
COLUMN_LEVEL = 3,
|
||||
UNKNOWN_TARGET,
|
||||
GLOBAL,
|
||||
DATABASE,
|
||||
TABLE,
|
||||
VIEW = TABLE,
|
||||
COLUMN,
|
||||
DICTIONARY,
|
||||
};
|
||||
|
||||
static constexpr size_t NUM_TARGETS = static_cast<size_t>(DICTIONARY) + 1;
|
||||
|
||||
struct Node;
|
||||
using NodePtr = std::unique_ptr<Node>;
|
||||
using Nodes = std::vector<NodePtr>;
|
||||
@ -191,11 +205,11 @@ private:
|
||||
std::string_view keyword;
|
||||
std::vector<String> aliases;
|
||||
Flags flags;
|
||||
Level level = UNKNOWN_LEVEL;
|
||||
Target target = UNKNOWN_TARGET;
|
||||
Nodes children;
|
||||
|
||||
Node(std::string_view keyword_, size_t flag_, Level level_)
|
||||
: keyword(keyword_), level(level_)
|
||||
Node(std::string_view keyword_, size_t flag_, Target target_)
|
||||
: keyword(keyword_), target(target_)
|
||||
{
|
||||
flags.set(flag_);
|
||||
}
|
||||
@ -229,216 +243,220 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
static void makeFlagsToKeywordTree(NodePtr & flags_to_keyword_tree_)
|
||||
static NodePtr makeFlagsToKeywordTree()
|
||||
{
|
||||
size_t next_flag = 0;
|
||||
Nodes all;
|
||||
|
||||
auto show = std::make_unique<Node>("SHOW", next_flag++, COLUMN_LEVEL);
|
||||
auto exists = std::make_unique<Node>("EXISTS", next_flag++, COLUMN_LEVEL);
|
||||
ext::push_back(all, std::move(show), std::move(exists));
|
||||
auto show_databases = std::make_unique<Node>("SHOW DATABASES", next_flag++, DATABASE);
|
||||
auto show_tables = std::make_unique<Node>("SHOW TABLES", next_flag++, TABLE);
|
||||
auto show_columns = std::make_unique<Node>("SHOW COLUMNS", next_flag++, COLUMN);
|
||||
auto show_dictionaries = std::make_unique<Node>("SHOW DICTIONARIES", next_flag++, DICTIONARY);
|
||||
auto show = std::make_unique<Node>("SHOW", std::move(show_databases), std::move(show_tables), std::move(show_columns), std::move(show_dictionaries));
|
||||
ext::push_back(all, std::move(show));
|
||||
|
||||
auto select = std::make_unique<Node>("SELECT", next_flag++, COLUMN_LEVEL);
|
||||
auto insert = std::make_unique<Node>("INSERT", next_flag++, COLUMN_LEVEL);
|
||||
auto select = std::make_unique<Node>("SELECT", next_flag++, COLUMN);
|
||||
auto insert = std::make_unique<Node>("INSERT", next_flag++, COLUMN);
|
||||
ext::push_back(all, std::move(select), std::move(insert));
|
||||
|
||||
auto update = std::make_unique<Node>("UPDATE", next_flag++, COLUMN_LEVEL);
|
||||
auto update = std::make_unique<Node>("UPDATE", next_flag++, COLUMN);
|
||||
ext::push_back(update->aliases, "ALTER UPDATE");
|
||||
auto delet = std::make_unique<Node>("DELETE", next_flag++, TABLE_LEVEL);
|
||||
auto delet = std::make_unique<Node>("DELETE", next_flag++, TABLE);
|
||||
ext::push_back(delet->aliases, "ALTER DELETE");
|
||||
|
||||
auto add_column = std::make_unique<Node>("ADD COLUMN", next_flag++, COLUMN_LEVEL);
|
||||
auto add_column = std::make_unique<Node>("ADD COLUMN", next_flag++, COLUMN);
|
||||
add_column->aliases.push_back("ALTER ADD COLUMN");
|
||||
auto modify_column = std::make_unique<Node>("MODIFY COLUMN", next_flag++, COLUMN_LEVEL);
|
||||
auto modify_column = std::make_unique<Node>("MODIFY COLUMN", next_flag++, COLUMN);
|
||||
modify_column->aliases.push_back("ALTER MODIFY COLUMN");
|
||||
auto drop_column = std::make_unique<Node>("DROP COLUMN", next_flag++, COLUMN_LEVEL);
|
||||
auto drop_column = std::make_unique<Node>("DROP COLUMN", next_flag++, COLUMN);
|
||||
drop_column->aliases.push_back("ALTER DROP COLUMN");
|
||||
auto comment_column = std::make_unique<Node>("COMMENT COLUMN", next_flag++, COLUMN_LEVEL);
|
||||
auto comment_column = std::make_unique<Node>("COMMENT COLUMN", next_flag++, COLUMN);
|
||||
comment_column->aliases.push_back("ALTER COMMENT COLUMN");
|
||||
auto clear_column = std::make_unique<Node>("CLEAR COLUMN", next_flag++, COLUMN_LEVEL);
|
||||
auto clear_column = std::make_unique<Node>("CLEAR COLUMN", next_flag++, COLUMN);
|
||||
clear_column->aliases.push_back("ALTER CLEAR COLUMN");
|
||||
auto alter_column = std::make_unique<Node>("ALTER COLUMN", std::move(add_column), std::move(modify_column), std::move(drop_column), std::move(comment_column), std::move(clear_column));
|
||||
|
||||
auto alter_order_by = std::make_unique<Node>("ALTER ORDER BY", next_flag++, TABLE_LEVEL);
|
||||
auto alter_order_by = std::make_unique<Node>("ALTER ORDER BY", next_flag++, TABLE);
|
||||
alter_order_by->aliases.push_back("MODIFY ORDER BY");
|
||||
alter_order_by->aliases.push_back("ALTER MODIFY ORDER BY");
|
||||
auto add_index = std::make_unique<Node>("ADD INDEX", next_flag++, TABLE_LEVEL);
|
||||
auto add_index = std::make_unique<Node>("ADD INDEX", next_flag++, TABLE);
|
||||
add_index->aliases.push_back("ALTER ADD INDEX");
|
||||
auto drop_index = std::make_unique<Node>("DROP INDEX", next_flag++, TABLE_LEVEL);
|
||||
auto drop_index = std::make_unique<Node>("DROP INDEX", next_flag++, TABLE);
|
||||
drop_index->aliases.push_back("ALTER DROP INDEX");
|
||||
auto materialize_index = std::make_unique<Node>("MATERIALIZE INDEX", next_flag++, TABLE_LEVEL);
|
||||
auto materialize_index = std::make_unique<Node>("MATERIALIZE INDEX", next_flag++, TABLE);
|
||||
materialize_index->aliases.push_back("ALTER MATERIALIZE INDEX");
|
||||
auto clear_index = std::make_unique<Node>("CLEAR INDEX", next_flag++, TABLE_LEVEL);
|
||||
auto clear_index = std::make_unique<Node>("CLEAR INDEX", next_flag++, TABLE);
|
||||
clear_index->aliases.push_back("ALTER CLEAR INDEX");
|
||||
auto index = std::make_unique<Node>("INDEX", std::move(alter_order_by), std::move(add_index), std::move(drop_index), std::move(materialize_index), std::move(clear_index));
|
||||
index->aliases.push_back("ALTER INDEX");
|
||||
|
||||
auto add_constraint = std::make_unique<Node>("ADD CONSTRAINT", next_flag++, TABLE_LEVEL);
|
||||
auto add_constraint = std::make_unique<Node>("ADD CONSTRAINT", next_flag++, TABLE);
|
||||
add_constraint->aliases.push_back("ALTER ADD CONSTRAINT");
|
||||
auto drop_constraint = std::make_unique<Node>("DROP CONSTRAINT", next_flag++, TABLE_LEVEL);
|
||||
auto drop_constraint = std::make_unique<Node>("DROP CONSTRAINT", next_flag++, TABLE);
|
||||
drop_constraint->aliases.push_back("ALTER DROP CONSTRAINT");
|
||||
auto alter_constraint = std::make_unique<Node>("CONSTRAINT", std::move(add_constraint), std::move(drop_constraint));
|
||||
alter_constraint->aliases.push_back("ALTER CONSTRAINT");
|
||||
|
||||
auto modify_ttl = std::make_unique<Node>("MODIFY TTL", next_flag++, TABLE_LEVEL);
|
||||
auto modify_ttl = std::make_unique<Node>("MODIFY TTL", next_flag++, TABLE);
|
||||
modify_ttl->aliases.push_back("ALTER MODIFY TTL");
|
||||
auto materialize_ttl = std::make_unique<Node>("MATERIALIZE TTL", next_flag++, TABLE_LEVEL);
|
||||
auto materialize_ttl = std::make_unique<Node>("MATERIALIZE TTL", next_flag++, TABLE);
|
||||
materialize_ttl->aliases.push_back("ALTER MATERIALIZE TTL");
|
||||
|
||||
auto modify_setting = std::make_unique<Node>("MODIFY SETTING", next_flag++, TABLE_LEVEL);
|
||||
auto modify_setting = std::make_unique<Node>("MODIFY SETTING", next_flag++, TABLE);
|
||||
modify_setting->aliases.push_back("ALTER MODIFY SETTING");
|
||||
|
||||
auto move_partition = std::make_unique<Node>("MOVE PARTITION", next_flag++, TABLE_LEVEL);
|
||||
auto move_partition = std::make_unique<Node>("MOVE PARTITION", next_flag++, TABLE);
|
||||
ext::push_back(move_partition->aliases, "ALTER MOVE PARTITION", "MOVE PART", "ALTER MOVE PART");
|
||||
auto fetch_partition = std::make_unique<Node>("FETCH PARTITION", next_flag++, TABLE_LEVEL);
|
||||
auto fetch_partition = std::make_unique<Node>("FETCH PARTITION", next_flag++, TABLE);
|
||||
ext::push_back(fetch_partition->aliases, "ALTER FETCH PARTITION");
|
||||
auto freeze_partition = std::make_unique<Node>("FREEZE PARTITION", next_flag++, TABLE_LEVEL);
|
||||
auto freeze_partition = std::make_unique<Node>("FREEZE PARTITION", next_flag++, TABLE);
|
||||
ext::push_back(freeze_partition->aliases, "ALTER FREEZE PARTITION");
|
||||
|
||||
auto alter_table = std::make_unique<Node>("ALTER TABLE", std::move(update), std::move(delet), std::move(alter_column), std::move(index), std::move(alter_constraint), std::move(modify_ttl), std::move(materialize_ttl), std::move(modify_setting), std::move(move_partition), std::move(fetch_partition), std::move(freeze_partition));
|
||||
|
||||
auto refresh_view = std::make_unique<Node>("REFRESH VIEW", next_flag++, VIEW_LEVEL);
|
||||
auto refresh_view = std::make_unique<Node>("REFRESH VIEW", next_flag++, VIEW);
|
||||
ext::push_back(refresh_view->aliases, "ALTER LIVE VIEW REFRESH");
|
||||
auto modify_view_query = std::make_unique<Node>("MODIFY VIEW QUERY", next_flag++, VIEW_LEVEL);
|
||||
auto modify_view_query = std::make_unique<Node>("MODIFY VIEW QUERY", next_flag++, VIEW);
|
||||
auto alter_view = std::make_unique<Node>("ALTER VIEW", std::move(refresh_view), std::move(modify_view_query));
|
||||
|
||||
auto alter = std::make_unique<Node>("ALTER", std::move(alter_table), std::move(alter_view));
|
||||
ext::push_back(all, std::move(alter));
|
||||
|
||||
auto create_database = std::make_unique<Node>("CREATE DATABASE", next_flag++, DATABASE_LEVEL);
|
||||
auto create_table = std::make_unique<Node>("CREATE TABLE", next_flag++, TABLE_LEVEL);
|
||||
auto create_view = std::make_unique<Node>("CREATE VIEW", next_flag++, VIEW_LEVEL);
|
||||
auto create_dictionary = std::make_unique<Node>("CREATE DICTIONARY", next_flag++, DICTIONARY_LEVEL);
|
||||
auto create_database = std::make_unique<Node>("CREATE DATABASE", next_flag++, DATABASE);
|
||||
auto create_table = std::make_unique<Node>("CREATE TABLE", next_flag++, TABLE);
|
||||
auto create_view = std::make_unique<Node>("CREATE VIEW", next_flag++, VIEW);
|
||||
auto create_dictionary = std::make_unique<Node>("CREATE DICTIONARY", next_flag++, DICTIONARY);
|
||||
auto create = std::make_unique<Node>("CREATE", std::move(create_database), std::move(create_table), std::move(create_view), std::move(create_dictionary));
|
||||
ext::push_back(all, std::move(create));
|
||||
|
||||
auto create_temporary_table = std::make_unique<Node>("CREATE TEMPORARY TABLE", next_flag++, GLOBAL_LEVEL);
|
||||
auto create_temporary_table = std::make_unique<Node>("CREATE TEMPORARY TABLE", next_flag++, GLOBAL);
|
||||
ext::push_back(all, std::move(create_temporary_table));
|
||||
|
||||
auto drop_database = std::make_unique<Node>("DROP DATABASE", next_flag++, DATABASE_LEVEL);
|
||||
auto drop_table = std::make_unique<Node>("DROP TABLE", next_flag++, TABLE_LEVEL);
|
||||
auto drop_view = std::make_unique<Node>("DROP VIEW", next_flag++, VIEW_LEVEL);
|
||||
auto drop_dictionary = std::make_unique<Node>("DROP DICTIONARY", next_flag++, DICTIONARY_LEVEL);
|
||||
auto drop_database = std::make_unique<Node>("DROP DATABASE", next_flag++, DATABASE);
|
||||
auto drop_table = std::make_unique<Node>("DROP TABLE", next_flag++, TABLE);
|
||||
auto drop_view = std::make_unique<Node>("DROP VIEW", next_flag++, VIEW);
|
||||
auto drop_dictionary = std::make_unique<Node>("DROP DICTIONARY", next_flag++, DICTIONARY);
|
||||
auto drop = std::make_unique<Node>("DROP", std::move(drop_database), std::move(drop_table), std::move(drop_view), std::move(drop_dictionary));
|
||||
ext::push_back(all, std::move(drop));
|
||||
|
||||
auto truncate_table = std::make_unique<Node>("TRUNCATE TABLE", next_flag++, TABLE_LEVEL);
|
||||
auto truncate_view = std::make_unique<Node>("TRUNCATE VIEW", next_flag++, VIEW_LEVEL);
|
||||
auto truncate_table = std::make_unique<Node>("TRUNCATE TABLE", next_flag++, TABLE);
|
||||
auto truncate_view = std::make_unique<Node>("TRUNCATE VIEW", next_flag++, VIEW);
|
||||
auto truncate = std::make_unique<Node>("TRUNCATE", std::move(truncate_table), std::move(truncate_view));
|
||||
ext::push_back(all, std::move(truncate));
|
||||
|
||||
auto optimize = std::make_unique<Node>("OPTIMIZE", next_flag++, TABLE_LEVEL);
|
||||
auto optimize = std::make_unique<Node>("OPTIMIZE", next_flag++, TABLE);
|
||||
optimize->aliases.push_back("OPTIMIZE TABLE");
|
||||
ext::push_back(all, std::move(optimize));
|
||||
|
||||
auto kill_query = std::make_unique<Node>("KILL QUERY", next_flag++, GLOBAL_LEVEL);
|
||||
auto kill_mutation = std::make_unique<Node>("KILL MUTATION", next_flag++, TABLE_LEVEL);
|
||||
auto kill_query = std::make_unique<Node>("KILL QUERY", next_flag++, GLOBAL);
|
||||
auto kill_mutation = std::make_unique<Node>("KILL MUTATION", next_flag++, TABLE);
|
||||
auto kill = std::make_unique<Node>("KILL", std::move(kill_query), std::move(kill_mutation));
|
||||
ext::push_back(all, std::move(kill));
|
||||
|
||||
auto create_user = std::make_unique<Node>("CREATE USER", next_flag++, GLOBAL_LEVEL);
|
||||
auto alter_user = std::make_unique<Node>("ALTER USER", next_flag++, GLOBAL_LEVEL);
|
||||
auto drop_user = std::make_unique<Node>("DROP USER", next_flag++, GLOBAL_LEVEL);
|
||||
auto create_role = std::make_unique<Node>("CREATE ROLE", next_flag++, GLOBAL_LEVEL);
|
||||
auto drop_role = std::make_unique<Node>("DROP ROLE", next_flag++, GLOBAL_LEVEL);
|
||||
auto create_policy = std::make_unique<Node>("CREATE POLICY", next_flag++, GLOBAL_LEVEL);
|
||||
auto alter_policy = std::make_unique<Node>("ALTER POLICY", next_flag++, GLOBAL_LEVEL);
|
||||
auto drop_policy = std::make_unique<Node>("DROP POLICY", next_flag++, GLOBAL_LEVEL);
|
||||
auto create_quota = std::make_unique<Node>("CREATE QUOTA", next_flag++, GLOBAL_LEVEL);
|
||||
auto alter_quota = std::make_unique<Node>("ALTER QUOTA", next_flag++, GLOBAL_LEVEL);
|
||||
auto drop_quota = std::make_unique<Node>("DROP QUOTA", next_flag++, GLOBAL_LEVEL);
|
||||
auto role_admin = std::make_unique<Node>("ROLE ADMIN", next_flag++, GLOBAL_LEVEL);
|
||||
auto create_user = std::make_unique<Node>("CREATE USER", next_flag++, GLOBAL);
|
||||
auto alter_user = std::make_unique<Node>("ALTER USER", next_flag++, GLOBAL);
|
||||
auto drop_user = std::make_unique<Node>("DROP USER", next_flag++, GLOBAL);
|
||||
auto create_role = std::make_unique<Node>("CREATE ROLE", next_flag++, GLOBAL);
|
||||
auto drop_role = std::make_unique<Node>("DROP ROLE", next_flag++, GLOBAL);
|
||||
auto create_policy = std::make_unique<Node>("CREATE POLICY", next_flag++, GLOBAL);
|
||||
auto alter_policy = std::make_unique<Node>("ALTER POLICY", next_flag++, GLOBAL);
|
||||
auto drop_policy = std::make_unique<Node>("DROP POLICY", next_flag++, GLOBAL);
|
||||
auto create_quota = std::make_unique<Node>("CREATE QUOTA", next_flag++, GLOBAL);
|
||||
auto alter_quota = std::make_unique<Node>("ALTER QUOTA", next_flag++, GLOBAL);
|
||||
auto drop_quota = std::make_unique<Node>("DROP QUOTA", next_flag++, GLOBAL);
|
||||
auto role_admin = std::make_unique<Node>("ROLE ADMIN", next_flag++, GLOBAL);
|
||||
ext::push_back(all, std::move(create_user), std::move(alter_user), std::move(drop_user), std::move(create_role), std::move(drop_role), std::move(create_policy), std::move(alter_policy), std::move(drop_policy), std::move(create_quota), std::move(alter_quota), std::move(drop_quota), std::move(role_admin));
|
||||
|
||||
auto shutdown = std::make_unique<Node>("SHUTDOWN", next_flag++, GLOBAL_LEVEL);
|
||||
auto shutdown = std::make_unique<Node>("SHUTDOWN", next_flag++, GLOBAL);
|
||||
ext::push_back(shutdown->aliases, "SYSTEM SHUTDOWN", "SYSTEM KILL");
|
||||
auto drop_cache = std::make_unique<Node>("DROP CACHE", next_flag++, GLOBAL_LEVEL);
|
||||
auto drop_cache = std::make_unique<Node>("DROP CACHE", next_flag++, GLOBAL);
|
||||
ext::push_back(drop_cache->aliases, "SYSTEM DROP CACHE", "DROP DNS CACHE", "SYSTEM DROP DNS CACHE", "DROP MARK CACHE", "SYSTEM DROP MARK CACHE", "DROP UNCOMPRESSED CACHE", "SYSTEM DROP UNCOMPRESSED CACHE", "DROP COMPILED EXPRESSION CACHE", "SYSTEM DROP COMPILED EXPRESSION CACHE");
|
||||
auto reload_config = std::make_unique<Node>("RELOAD CONFIG", next_flag++, GLOBAL_LEVEL);
|
||||
auto reload_config = std::make_unique<Node>("RELOAD CONFIG", next_flag++, GLOBAL);
|
||||
ext::push_back(reload_config->aliases, "SYSTEM RELOAD CONFIG");
|
||||
auto reload_dictionary = std::make_unique<Node>("RELOAD DICTIONARY", next_flag++, GLOBAL_LEVEL);
|
||||
auto reload_dictionary = std::make_unique<Node>("RELOAD DICTIONARY", next_flag++, GLOBAL);
|
||||
ext::push_back(reload_dictionary->aliases, "SYSTEM RELOAD DICTIONARY", "RELOAD DICTIONARIES", "SYSTEM RELOAD DICTIONARIES", "RELOAD EMBEDDED DICTIONARIES", "SYSTEM RELOAD EMBEDDED DICTIONARIES");
|
||||
auto stop_merges = std::make_unique<Node>("STOP MERGES", next_flag++, TABLE_LEVEL);
|
||||
auto stop_merges = std::make_unique<Node>("STOP MERGES", next_flag++, TABLE);
|
||||
ext::push_back(stop_merges->aliases, "SYSTEM STOP MERGES", "START MERGES", "SYSTEM START MERGES");
|
||||
auto stop_ttl_merges = std::make_unique<Node>("STOP TTL MERGES", next_flag++, TABLE_LEVEL);
|
||||
auto stop_ttl_merges = std::make_unique<Node>("STOP TTL MERGES", next_flag++, TABLE);
|
||||
ext::push_back(stop_ttl_merges->aliases, "SYSTEM STOP TTL MERGES", "START TTL MERGES", "SYSTEM START TTL MERGES");
|
||||
auto stop_fetches = std::make_unique<Node>("STOP FETCHES", next_flag++, TABLE_LEVEL);
|
||||
auto stop_fetches = std::make_unique<Node>("STOP FETCHES", next_flag++, TABLE);
|
||||
ext::push_back(stop_fetches->aliases, "SYSTEM STOP FETCHES", "START FETCHES", "SYSTEM START FETCHES");
|
||||
auto stop_moves = std::make_unique<Node>("STOP MOVES", next_flag++, TABLE_LEVEL);
|
||||
auto stop_moves = std::make_unique<Node>("STOP MOVES", next_flag++, TABLE);
|
||||
ext::push_back(stop_moves->aliases, "SYSTEM STOP MOVES", "START MOVES", "SYSTEM START MOVES");
|
||||
auto stop_distributed_sends = std::make_unique<Node>("STOP DISTRIBUTED SENDS", next_flag++, TABLE_LEVEL);
|
||||
auto stop_distributed_sends = std::make_unique<Node>("STOP DISTRIBUTED SENDS", next_flag++, TABLE);
|
||||
ext::push_back(stop_distributed_sends->aliases, "SYSTEM STOP DISTRIBUTED SENDS", "START DISTRIBUTED SENDS", "SYSTEM START DISTRIBUTED SENDS");
|
||||
auto stop_replicated_sends = std::make_unique<Node>("STOP REPLICATED SENDS", next_flag++, TABLE_LEVEL);
|
||||
auto stop_replicated_sends = std::make_unique<Node>("STOP REPLICATED SENDS", next_flag++, TABLE);
|
||||
ext::push_back(stop_replicated_sends->aliases, "SYSTEM STOP REPLICATED SENDS", "START REPLICATED SENDS", "SYSTEM START REPLICATED SENDS");
|
||||
auto stop_replication_queues = std::make_unique<Node>("STOP REPLICATION QUEUES", next_flag++, TABLE_LEVEL);
|
||||
auto stop_replication_queues = std::make_unique<Node>("STOP REPLICATION QUEUES", next_flag++, TABLE);
|
||||
ext::push_back(stop_replication_queues->aliases, "SYSTEM STOP REPLICATION QUEUES", "START REPLICATION QUEUES", "SYSTEM START REPLICATION QUEUES");
|
||||
auto sync_replica = std::make_unique<Node>("SYNC REPLICA", next_flag++, TABLE_LEVEL);
|
||||
auto sync_replica = std::make_unique<Node>("SYNC REPLICA", next_flag++, TABLE);
|
||||
ext::push_back(sync_replica->aliases, "SYSTEM SYNC REPLICA");
|
||||
auto restart_replica = std::make_unique<Node>("RESTART REPLICA", next_flag++, TABLE_LEVEL);
|
||||
auto restart_replica = std::make_unique<Node>("RESTART REPLICA", next_flag++, TABLE);
|
||||
ext::push_back(restart_replica->aliases, "SYSTEM RESTART REPLICA");
|
||||
auto flush_distributed = std::make_unique<Node>("FLUSH DISTRIBUTED", next_flag++, TABLE_LEVEL);
|
||||
auto flush_distributed = std::make_unique<Node>("FLUSH DISTRIBUTED", next_flag++, TABLE);
|
||||
ext::push_back(flush_distributed->aliases, "SYSTEM FLUSH DISTRIBUTED");
|
||||
auto flush_logs = std::make_unique<Node>("FLUSH LOGS", next_flag++, GLOBAL_LEVEL);
|
||||
auto flush_logs = std::make_unique<Node>("FLUSH LOGS", next_flag++, GLOBAL);
|
||||
ext::push_back(flush_logs->aliases, "SYSTEM FLUSH LOGS");
|
||||
auto system = std::make_unique<Node>("SYSTEM", std::move(shutdown), std::move(drop_cache), std::move(reload_config), std::move(reload_dictionary), std::move(stop_merges), std::move(stop_ttl_merges), std::move(stop_fetches), std::move(stop_moves), std::move(stop_distributed_sends), std::move(stop_replicated_sends), std::move(stop_replication_queues), std::move(sync_replica), std::move(restart_replica), std::move(flush_distributed), std::move(flush_logs));
|
||||
ext::push_back(all, std::move(system));
|
||||
|
||||
auto dict_get = std::make_unique<Node>("dictGet()", next_flag++, DICTIONARY_LEVEL);
|
||||
auto dict_get = std::make_unique<Node>("dictGet()", next_flag++, DICTIONARY);
|
||||
dict_get->aliases.push_back("dictHas()");
|
||||
dict_get->aliases.push_back("dictGetHierarchy()");
|
||||
dict_get->aliases.push_back("dictIsIn()");
|
||||
ext::push_back(all, std::move(dict_get));
|
||||
|
||||
auto address_to_line = std::make_unique<Node>("addressToLine()", next_flag++, GLOBAL_LEVEL);
|
||||
auto address_to_symbol = std::make_unique<Node>("addressToSymbol()", next_flag++, GLOBAL_LEVEL);
|
||||
auto demangle = std::make_unique<Node>("demangle()", next_flag++, GLOBAL_LEVEL);
|
||||
auto address_to_line = std::make_unique<Node>("addressToLine()", next_flag++, GLOBAL);
|
||||
auto address_to_symbol = std::make_unique<Node>("addressToSymbol()", next_flag++, GLOBAL);
|
||||
auto demangle = std::make_unique<Node>("demangle()", next_flag++, GLOBAL);
|
||||
auto introspection = std::make_unique<Node>("INTROSPECTION", std::move(address_to_line), std::move(address_to_symbol), std::move(demangle));
|
||||
ext::push_back(introspection->aliases, "INTROSPECTION FUNCTIONS");
|
||||
ext::push_back(all, std::move(introspection));
|
||||
|
||||
auto file = std::make_unique<Node>("file()", next_flag++, GLOBAL_LEVEL);
|
||||
auto url = std::make_unique<Node>("url()", next_flag++, GLOBAL_LEVEL);
|
||||
auto input = std::make_unique<Node>("input()", next_flag++, GLOBAL_LEVEL);
|
||||
auto values = std::make_unique<Node>("values()", next_flag++, GLOBAL_LEVEL);
|
||||
auto numbers = std::make_unique<Node>("numbers()", next_flag++, GLOBAL_LEVEL);
|
||||
auto zeros = std::make_unique<Node>("zeros()", next_flag++, GLOBAL_LEVEL);
|
||||
auto merge = std::make_unique<Node>("merge()", next_flag++, DATABASE_LEVEL);
|
||||
auto remote = std::make_unique<Node>("remote()", next_flag++, GLOBAL_LEVEL);
|
||||
auto file = std::make_unique<Node>("file()", next_flag++, GLOBAL);
|
||||
auto url = std::make_unique<Node>("url()", next_flag++, GLOBAL);
|
||||
auto input = std::make_unique<Node>("input()", next_flag++, GLOBAL);
|
||||
auto values = std::make_unique<Node>("values()", next_flag++, GLOBAL);
|
||||
auto numbers = std::make_unique<Node>("numbers()", next_flag++, GLOBAL);
|
||||
auto zeros = std::make_unique<Node>("zeros()", next_flag++, GLOBAL);
|
||||
auto merge = std::make_unique<Node>("merge()", next_flag++, DATABASE);
|
||||
auto remote = std::make_unique<Node>("remote()", next_flag++, GLOBAL);
|
||||
ext::push_back(remote->aliases, "remoteSecure()", "cluster()");
|
||||
auto mysql = std::make_unique<Node>("mysql()", next_flag++, GLOBAL_LEVEL);
|
||||
auto odbc = std::make_unique<Node>("odbc()", next_flag++, GLOBAL_LEVEL);
|
||||
auto jdbc = std::make_unique<Node>("jdbc()", next_flag++, GLOBAL_LEVEL);
|
||||
auto hdfs = std::make_unique<Node>("hdfs()", next_flag++, GLOBAL_LEVEL);
|
||||
auto s3 = std::make_unique<Node>("s3()", next_flag++, GLOBAL_LEVEL);
|
||||
auto mysql = std::make_unique<Node>("mysql()", next_flag++, GLOBAL);
|
||||
auto odbc = std::make_unique<Node>("odbc()", next_flag++, GLOBAL);
|
||||
auto jdbc = std::make_unique<Node>("jdbc()", next_flag++, GLOBAL);
|
||||
auto hdfs = std::make_unique<Node>("hdfs()", next_flag++, GLOBAL);
|
||||
auto s3 = std::make_unique<Node>("s3()", next_flag++, GLOBAL);
|
||||
auto table_functions = std::make_unique<Node>("TABLE FUNCTIONS", std::move(file), std::move(url), std::move(input), std::move(values), std::move(numbers), std::move(zeros), std::move(merge), std::move(remote), std::move(mysql), std::move(odbc), std::move(jdbc), std::move(hdfs), std::move(s3));
|
||||
ext::push_back(all, std::move(table_functions));
|
||||
|
||||
flags_to_keyword_tree_ = std::make_unique<Node>("ALL", std::move(all));
|
||||
flags_to_keyword_tree_->aliases.push_back("ALL PRIVILEGES");
|
||||
auto node_all = std::make_unique<Node>("ALL", std::move(all));
|
||||
node_all->aliases.push_back("ALL PRIVILEGES");
|
||||
return node_all;
|
||||
}
|
||||
|
||||
void makeKeywordToFlagsMap(std::unordered_map<std::string_view, Flags> & keyword_to_flags_map_, Node * start_node = nullptr)
|
||||
void makeKeywordToFlagsMap(Node * start_node = nullptr)
|
||||
{
|
||||
if (!start_node)
|
||||
{
|
||||
start_node = flags_to_keyword_tree.get();
|
||||
keyword_to_flags_map_["USAGE"] = {};
|
||||
keyword_to_flags_map_["NONE"] = {};
|
||||
keyword_to_flags_map_["NO PRIVILEGES"] = {};
|
||||
keyword_to_flags_map["USAGE"] = {};
|
||||
keyword_to_flags_map["NONE"] = {};
|
||||
keyword_to_flags_map["NO PRIVILEGES"] = {};
|
||||
}
|
||||
start_node->aliases.emplace_back(start_node->keyword);
|
||||
for (auto & alias : start_node->aliases)
|
||||
{
|
||||
boost::to_upper(alias);
|
||||
keyword_to_flags_map_[alias] = start_node->flags;
|
||||
keyword_to_flags_map[alias] = start_node->flags;
|
||||
}
|
||||
for (auto & child : start_node->children)
|
||||
makeKeywordToFlagsMap(keyword_to_flags_map_, child.get());
|
||||
makeKeywordToFlagsMap(child.get());
|
||||
}
|
||||
|
||||
void makeAccessTypeToFlagsMapping(std::vector<Flags> & access_type_to_flags_mapping_)
|
||||
void makeAccessTypeToFlagsMapping()
|
||||
{
|
||||
access_type_to_flags_mapping_.resize(MAX_ACCESS_TYPE);
|
||||
access_type_to_flags_mapping.resize(MAX_ACCESS_TYPE);
|
||||
for (auto access_type : ext::range_with_static_cast<AccessType>(0, MAX_ACCESS_TYPE))
|
||||
{
|
||||
auto str = toKeyword(access_type);
|
||||
@ -449,35 +467,36 @@ private:
|
||||
boost::to_upper(uppercased);
|
||||
it = keyword_to_flags_map.find(uppercased);
|
||||
}
|
||||
access_type_to_flags_mapping_[static_cast<size_t>(access_type)] = it->second;
|
||||
access_type_to_flags_mapping[static_cast<size_t>(access_type)] = it->second;
|
||||
}
|
||||
}
|
||||
|
||||
void collectAllGrantableOnLevel(std::vector<Flags> & all_grantable_on_level_, const Node * start_node = nullptr)
|
||||
void collectAllFlags(const Node * start_node = nullptr)
|
||||
{
|
||||
if (!start_node)
|
||||
{
|
||||
start_node = flags_to_keyword_tree.get();
|
||||
all_grantable_on_level.resize(COLUMN_LEVEL + 1);
|
||||
all_flags = start_node->flags;
|
||||
}
|
||||
for (int i = 0; i <= start_node->level; ++i)
|
||||
all_grantable_on_level_[i] |= start_node->flags;
|
||||
if (start_node->target != UNKNOWN_TARGET)
|
||||
all_flags_for_target[start_node->target] |= start_node->flags;
|
||||
for (const auto & child : start_node->children)
|
||||
collectAllGrantableOnLevel(all_grantable_on_level_, child.get());
|
||||
collectAllFlags(child.get());
|
||||
}
|
||||
|
||||
Impl()
|
||||
{
|
||||
makeFlagsToKeywordTree(flags_to_keyword_tree);
|
||||
makeKeywordToFlagsMap(keyword_to_flags_map);
|
||||
makeAccessTypeToFlagsMapping(access_type_to_flags_mapping);
|
||||
collectAllGrantableOnLevel(all_grantable_on_level);
|
||||
flags_to_keyword_tree = makeFlagsToKeywordTree();
|
||||
makeKeywordToFlagsMap();
|
||||
makeAccessTypeToFlagsMapping();
|
||||
collectAllFlags();
|
||||
}
|
||||
|
||||
std::unique_ptr<Node> flags_to_keyword_tree;
|
||||
std::unordered_map<std::string_view, Flags> keyword_to_flags_map;
|
||||
std::vector<Flags> access_type_to_flags_mapping;
|
||||
std::vector<Flags> all_grantable_on_level;
|
||||
Flags all_flags;
|
||||
Flags all_flags_for_target[NUM_TARGETS];
|
||||
};
|
||||
|
||||
|
||||
@ -487,9 +506,12 @@ inline AccessFlags::AccessFlags(const std::vector<std::string_view> & keywords)
|
||||
inline AccessFlags::AccessFlags(const Strings & keywords) : flags(Impl<>::instance().keywordsToFlags(keywords)) {}
|
||||
inline String AccessFlags::toString() const { return Impl<>::instance().flagsToString(flags); }
|
||||
inline std::vector<std::string_view> AccessFlags::toKeywords() const { return Impl<>::instance().flagsToKeywords(flags); }
|
||||
inline AccessFlags AccessFlags::databaseLevel() { return Impl<>::instance().getDatabaseLevelFlags(); }
|
||||
inline AccessFlags AccessFlags::tableLevel() { return Impl<>::instance().getTableLevelFlags(); }
|
||||
inline AccessFlags AccessFlags::columnLevel() { return Impl<>::instance().getColumnLevelFlags(); }
|
||||
inline AccessFlags AccessFlags::allFlags() { return Impl<>::instance().getAllFlags(); }
|
||||
inline AccessFlags AccessFlags::allGlobalFlags() { return Impl<>::instance().getGlobalFlags(); }
|
||||
inline AccessFlags AccessFlags::allDatabaseFlags() { return Impl<>::instance().getDatabaseFlags(); }
|
||||
inline AccessFlags AccessFlags::allTableFlags() { return Impl<>::instance().getTableFlags(); }
|
||||
inline AccessFlags AccessFlags::allColumnFlags() { return Impl<>::instance().getColumnFlags(); }
|
||||
inline AccessFlags AccessFlags::allDictionaryFlags() { return Impl<>::instance().getDictionaryFlags(); }
|
||||
|
||||
inline AccessFlags operator |(AccessType left, AccessType right) { return AccessFlags(left) | right; }
|
||||
inline AccessFlags operator &(AccessType left, AccessType right) { return AccessFlags(left) & right; }
|
||||
|
@ -31,12 +31,19 @@ namespace
|
||||
return res;
|
||||
}
|
||||
|
||||
const AccessFlags database_level_flags = AccessFlags::databaseLevel();
|
||||
const AccessFlags table_level_flags = AccessFlags::tableLevel();
|
||||
const AccessFlags column_level_flags = AccessFlags::columnLevel();
|
||||
const AccessFlags all_flags = AccessFlags::allFlags();
|
||||
const AccessFlags database_flags = AccessFlags::allDatabaseFlags();
|
||||
const AccessFlags table_flags = AccessFlags::allTableFlags();
|
||||
const AccessFlags column_flags = AccessFlags::allColumnFlags();
|
||||
const AccessFlags dictionary_flags = AccessFlags::allDictionaryFlags();
|
||||
const AccessFlags column_level_flags = column_flags;
|
||||
const AccessFlags table_level_flags = table_flags | dictionary_flags | column_level_flags;
|
||||
const AccessFlags database_level_flags = database_flags | table_level_flags;
|
||||
|
||||
const AccessFlags show_flag = AccessType::SHOW;
|
||||
const AccessFlags exists_flag = AccessType::EXISTS;
|
||||
const AccessFlags show_databases_flag = AccessType::SHOW_DATABASES;
|
||||
const AccessFlags show_tables_flag = AccessType::SHOW_TABLES;
|
||||
const AccessFlags show_columns_flag = AccessType::SHOW_COLUMNS;
|
||||
const AccessFlags show_dictionaries_flag = AccessType::SHOW_DICTIONARIES;
|
||||
const AccessFlags create_table_flag = AccessType::CREATE_TABLE;
|
||||
const AccessFlags create_view_flag = AccessType::CREATE_VIEW;
|
||||
const AccessFlags create_temporary_table_flag = AccessType::CREATE_TEMPORARY_TABLE;
|
||||
@ -367,25 +374,46 @@ private:
|
||||
void calculateFinalAccess(const Helper & helper)
|
||||
{
|
||||
/// Calculate min and max access among children.
|
||||
AccessFlags min_access_among_children = AccessType::ALL;
|
||||
AccessFlags min_access_among_children = helper.all_flags;
|
||||
AccessFlags max_access_among_children;
|
||||
if (children)
|
||||
{
|
||||
for (const auto & child : *children | boost::adaptors::map_values)
|
||||
{
|
||||
min_access &= child.min_access;
|
||||
max_access |= child.max_access;
|
||||
min_access_among_children &= child.min_access;
|
||||
max_access_among_children |= child.max_access;
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculate implicit access:
|
||||
AccessFlags implicit_access;
|
||||
if (access & helper.database_level_flags)
|
||||
implicit_access |= helper.show_flag | helper.exists_flag;
|
||||
else if ((level >= DATABASE_LEVEL) && children)
|
||||
implicit_access |= helper.exists_flag;
|
||||
|
||||
if ((level == GLOBAL_LEVEL) && (final_access & helper.create_table_flag))
|
||||
if (level <= DATABASE_LEVEL)
|
||||
{
|
||||
if (access & helper.database_flags)
|
||||
implicit_access |= helper.show_databases_flag;
|
||||
}
|
||||
if (level <= TABLE_LEVEL)
|
||||
{
|
||||
if (access & helper.table_flags)
|
||||
implicit_access |= helper.show_tables_flag;
|
||||
if (access & helper.dictionary_flags)
|
||||
implicit_access |= helper.show_dictionaries_flag;
|
||||
}
|
||||
if (level <= COLUMN_LEVEL)
|
||||
{
|
||||
if (access & helper.column_flags)
|
||||
implicit_access |= helper.show_columns_flag;
|
||||
}
|
||||
if (children && max_access_among_children)
|
||||
{
|
||||
if (level == DATABASE_LEVEL)
|
||||
implicit_access |= helper.show_databases_flag;
|
||||
else if (level == TABLE_LEVEL)
|
||||
implicit_access |= helper.show_tables_flag;
|
||||
}
|
||||
|
||||
if ((level == GLOBAL_LEVEL) && ((access | max_access_among_children) & helper.create_table_flag))
|
||||
implicit_access |= helper.create_temporary_table_flag;
|
||||
|
||||
if (level <= TABLE_LEVEL)
|
||||
|
@ -435,38 +435,37 @@ boost::shared_ptr<const AccessRights> AccessRightsContext::calculateResultAccess
|
||||
| AccessType::CREATE_QUOTA | AccessType::ALTER_USER | AccessType::ALTER_POLICY | AccessType::ALTER_QUOTA | AccessType::DROP_USER
|
||||
| AccessType::DROP_ROLE | AccessType::DROP_POLICY | AccessType::DROP_QUOTA | AccessType::ROLE_ADMIN;
|
||||
|
||||
/// Anyone has access to the "system" database.
|
||||
if (!result.isGranted(AccessType::SELECT, DatabaseCatalog::SYSTEM_DATABASE))
|
||||
result.grant(AccessType::SELECT, DatabaseCatalog::SYSTEM_DATABASE);
|
||||
|
||||
/// User has access to temporary or external table if such table was resolved in session or query context
|
||||
if (!result.isGranted(AccessType::SELECT, DatabaseCatalog::TEMPORARY_DATABASE))
|
||||
result.grant(AccessType::SELECT, DatabaseCatalog::TEMPORARY_DATABASE);
|
||||
|
||||
if (readonly_)
|
||||
result.revoke(write_table_access | all_dcl | AccessType::SYSTEM | AccessType::KILL);
|
||||
|
||||
if (readonly_ || !allow_ddl_)
|
||||
result.revoke(table_and_dictionary_ddl);
|
||||
|
||||
if (readonly_ && grant_option)
|
||||
result.revoke(AccessType::ALL);
|
||||
|
||||
if (readonly_ == 1)
|
||||
{
|
||||
/// Table functions are forbidden in readonly mode.
|
||||
/// For example, for readonly = 2 - allowed.
|
||||
result.revoke(AccessType::CREATE_TEMPORARY_TABLE | AccessType::TABLE_FUNCTIONS);
|
||||
}
|
||||
else if (readonly_ == 2)
|
||||
{
|
||||
/// Allow INSERT into temporary tables
|
||||
result.grant(AccessType::INSERT, DatabaseCatalog::TEMPORARY_DATABASE);
|
||||
}
|
||||
|
||||
if (!allow_introspection_)
|
||||
result.revoke(AccessType::INTROSPECTION);
|
||||
|
||||
/// Anyone has access to the "system" database.
|
||||
result.grant(AccessType::SELECT, DatabaseCatalog::SYSTEM_DATABASE);
|
||||
|
||||
if (readonly_ != 1)
|
||||
{
|
||||
/// User has access to temporary or external table if such table was resolved in session or query context
|
||||
result.grant(AccessFlags::allTableFlags() | AccessFlags::allColumnFlags(), DatabaseCatalog::TEMPORARY_DATABASE);
|
||||
}
|
||||
|
||||
if (readonly_ && grant_option)
|
||||
{
|
||||
/// No grant option in readonly mode.
|
||||
result.revoke(AccessType::ALL);
|
||||
}
|
||||
|
||||
result_access_cache[cache_index].store(result_ptr);
|
||||
|
||||
if (trace_log && (params.readonly == readonly_) && (params.allow_ddl == allow_ddl_) && (params.allow_introspection == allow_introspection_))
|
||||
|
@ -14,12 +14,11 @@ enum class AccessType
|
||||
NONE, /// no access
|
||||
ALL, /// full access
|
||||
|
||||
SHOW, /// allows to execute SHOW TABLES, SHOW CREATE TABLE, SHOW DATABASES and so on
|
||||
/// (granted implicitly with any other grant)
|
||||
|
||||
EXISTS, /// allows to execute EXISTS, USE, i.e. to check existence
|
||||
/// (granted implicitly on the database level with any other grant on the database and lower levels,
|
||||
/// e.g. "GRANT SELECT(x) ON db.table" also grants EXISTS on db.*)
|
||||
SHOW_DATABASES, /// allows to execute SHOW DATABASES, SHOW CREATE DATABASE, USE <database>
|
||||
SHOW_TABLES, /// allows to execute SHOW TABLES, EXISTS <table>, CHECK <table>
|
||||
SHOW_COLUMNS, /// allows to execute SHOW CREATE TABLE, DESCRIBE
|
||||
SHOW_DICTIONARIES, /// allows to execute SHOW DICTIONARIES, SHOW CREATE DICTIONARY, EXISTS <dictionary>
|
||||
SHOW, /// allows to execute SHOW, USE, EXISTS, CHECK, DESCRIBE
|
||||
|
||||
SELECT,
|
||||
INSERT,
|
||||
@ -179,8 +178,12 @@ namespace impl
|
||||
|
||||
ACCESS_TYPE_TO_KEYWORD_CASE(NONE);
|
||||
ACCESS_TYPE_TO_KEYWORD_CASE(ALL);
|
||||
|
||||
ACCESS_TYPE_TO_KEYWORD_CASE(SHOW_DATABASES);
|
||||
ACCESS_TYPE_TO_KEYWORD_CASE(SHOW_TABLES);
|
||||
ACCESS_TYPE_TO_KEYWORD_CASE(SHOW_COLUMNS);
|
||||
ACCESS_TYPE_TO_KEYWORD_CASE(SHOW_DICTIONARIES);
|
||||
ACCESS_TYPE_TO_KEYWORD_CASE(SHOW);
|
||||
ACCESS_TYPE_TO_KEYWORD_CASE(EXISTS);
|
||||
|
||||
ACCESS_TYPE_TO_KEYWORD_CASE(SELECT);
|
||||
ACCESS_TYPE_TO_KEYWORD_CASE(INSERT);
|
||||
|
@ -141,19 +141,18 @@ namespace
|
||||
|
||||
if (databases)
|
||||
{
|
||||
user->access.revoke(AccessFlags::databaseLevel());
|
||||
user->access.revoke(AccessFlags::allFlags() - AccessFlags::allGlobalFlags());
|
||||
user->access.grant(AccessFlags::allDictionaryFlags(), IDictionary::NO_DATABASE_TAG);
|
||||
for (const String & database : *databases)
|
||||
user->access.grant(AccessFlags::databaseLevel(), database);
|
||||
user->access.grant(AccessFlags::allFlags(), database);
|
||||
}
|
||||
|
||||
if (dictionaries)
|
||||
{
|
||||
user->access.revoke(AccessType::dictGet, IDictionary::NO_DATABASE_TAG);
|
||||
user->access.revoke(AccessFlags::allDictionaryFlags(), IDictionary::NO_DATABASE_TAG);
|
||||
for (const String & dictionary : *dictionaries)
|
||||
user->access.grant(AccessType::dictGet, IDictionary::NO_DATABASE_TAG, dictionary);
|
||||
user->access.grant(AccessFlags::allDictionaryFlags(), IDictionary::NO_DATABASE_TAG, dictionary);
|
||||
}
|
||||
else if (databases)
|
||||
user->access.grant(AccessType::dictGet, IDictionary::NO_DATABASE_TAG);
|
||||
|
||||
user->access_with_grant_option = user->access;
|
||||
|
||||
|
@ -40,7 +40,7 @@ BlockIO InterpreterCheckQuery::execute()
|
||||
const auto & check = query_ptr->as<ASTCheckQuery &>();
|
||||
auto table_id = context.resolveStorageID(check, Context::ResolveOrdinary);
|
||||
|
||||
context.checkAccess(AccessType::SHOW, table_id);
|
||||
context.checkAccess(AccessType::SHOW_TABLES, table_id);
|
||||
StoragePtr table = DatabaseCatalog::instance().getTable(table_id);
|
||||
auto check_results = table->checkData(query_ptr, context);
|
||||
|
||||
|
@ -85,8 +85,7 @@ BlockInputStreamPtr InterpreterDescribeQuery::executeImpl()
|
||||
else
|
||||
{
|
||||
auto table_id = context.resolveStorageID(table_expression.database_and_table_name);
|
||||
context.checkAccess(AccessType::SHOW, table_id);
|
||||
|
||||
context.checkAccess(AccessType::SHOW_COLUMNS, table_id);
|
||||
table = DatabaseCatalog::instance().getTable(table_id);
|
||||
}
|
||||
|
||||
|
@ -44,13 +44,12 @@ BlockInputStreamPtr InterpreterExistsQuery::executeImpl()
|
||||
{
|
||||
if (exists_query->temporary)
|
||||
{
|
||||
context.checkAccess(AccessType::EXISTS, "", exists_query->table);
|
||||
result = context.tryResolveStorageID({"", exists_query->table}, Context::ResolveExternal);
|
||||
}
|
||||
else
|
||||
{
|
||||
String database = context.resolveDatabase(exists_query->database);
|
||||
context.checkAccess(AccessType::EXISTS, database, exists_query->table);
|
||||
context.checkAccess(AccessType::SHOW_TABLES, database, exists_query->table);
|
||||
result = DatabaseCatalog::instance().isTableExist({database, exists_query->table});
|
||||
}
|
||||
}
|
||||
@ -59,7 +58,7 @@ BlockInputStreamPtr InterpreterExistsQuery::executeImpl()
|
||||
if (exists_query->temporary)
|
||||
throw Exception("Temporary dictionaries are not possible.", ErrorCodes::SYNTAX_ERROR);
|
||||
String database = context.resolveDatabase(exists_query->database);
|
||||
context.checkAccess(AccessType::EXISTS, database, exists_query->table);
|
||||
context.checkAccess(AccessType::SHOW_DICTIONARIES, database, exists_query->table);
|
||||
result = DatabaseCatalog::instance().isDictionaryExist({database, exists_query->table});
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ BlockInputStreamPtr InterpreterShowCreateQuery::executeImpl()
|
||||
{
|
||||
auto resolve_table_type = show_query->temporary ? Context::ResolveExternal : Context::ResolveOrdinary;
|
||||
auto table_id = context.resolveStorageID(*show_query, resolve_table_type);
|
||||
context.checkAccess(AccessType::SHOW, table_id);
|
||||
context.checkAccess(AccessType::SHOW_COLUMNS, table_id);
|
||||
create_query = DatabaseCatalog::instance().getDatabase(table_id.database_name)->getCreateTableQuery(context, table_id.table_name);
|
||||
}
|
||||
else if ((show_query = query_ptr->as<ASTShowCreateDatabaseQuery>()))
|
||||
@ -57,7 +57,7 @@ BlockInputStreamPtr InterpreterShowCreateQuery::executeImpl()
|
||||
if (show_query->temporary)
|
||||
throw Exception("Temporary databases are not possible.", ErrorCodes::SYNTAX_ERROR);
|
||||
show_query->database = context.resolveDatabase(show_query->database);
|
||||
context.checkAccess(AccessType::SHOW, show_query->database);
|
||||
context.checkAccess(AccessType::SHOW_DATABASES, show_query->database);
|
||||
create_query = DatabaseCatalog::instance().getDatabase(show_query->database)->getCreateDatabaseQuery(context);
|
||||
}
|
||||
else if ((show_query = query_ptr->as<ASTShowCreateDictionaryQuery>()))
|
||||
@ -65,7 +65,7 @@ BlockInputStreamPtr InterpreterShowCreateQuery::executeImpl()
|
||||
if (show_query->temporary)
|
||||
throw Exception("Temporary dictionaries are not possible.", ErrorCodes::SYNTAX_ERROR);
|
||||
show_query->database = context.resolveDatabase(show_query->database);
|
||||
context.checkAccess(AccessType::SHOW, show_query->database, show_query->table);
|
||||
context.checkAccess(AccessType::SHOW_DICTIONARIES, show_query->database, show_query->table);
|
||||
create_query = DatabaseCatalog::instance().getDatabase(show_query->database)->getCreateDictionaryQuery(context, show_query->table);
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ namespace DB
|
||||
BlockIO InterpreterUseQuery::execute()
|
||||
{
|
||||
const String & new_database = query_ptr->as<ASTUseQuery &>().database;
|
||||
context.checkAccess(AccessType::EXISTS, new_database);
|
||||
context.checkAccess(AccessType::SHOW_DATABASES, new_database);
|
||||
context.getSessionContext().setCurrentDatabase(new_database);
|
||||
return {};
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ protected:
|
||||
MutableColumns res_columns = getPort().getHeader().cloneEmptyColumns();
|
||||
size_t rows_count = 0;
|
||||
|
||||
const bool check_access_for_tables = !access_rights->isGranted(AccessType::SHOW);
|
||||
const bool check_access_for_tables = !access_rights->isGranted(AccessType::SHOW_COLUMNS);
|
||||
|
||||
while (rows_count < max_block_size && db_table_num < total_tables)
|
||||
{
|
||||
@ -128,14 +128,14 @@ protected:
|
||||
column_sizes = storage->getColumnSizes();
|
||||
}
|
||||
|
||||
bool check_access_for_columns = check_access_for_tables && !access_rights->isGranted(AccessType::SHOW, database_name, table_name);
|
||||
bool check_access_for_columns = check_access_for_tables && !access_rights->isGranted(AccessType::SHOW_COLUMNS, database_name, table_name);
|
||||
|
||||
for (const auto & column : columns)
|
||||
{
|
||||
if (column.is_virtual)
|
||||
continue;
|
||||
|
||||
if (check_access_for_columns && !access_rights->isGranted(AccessType::SHOW, database_name, table_name, column.name))
|
||||
if (check_access_for_columns && !access_rights->isGranted(AccessType::SHOW_COLUMNS, database_name, table_name, column.name))
|
||||
continue;
|
||||
|
||||
size_t src_index = 0;
|
||||
|
@ -21,12 +21,12 @@ NamesAndTypesList StorageSystemDatabases::getNamesAndTypes()
|
||||
void StorageSystemDatabases::fillData(MutableColumns & res_columns, const Context & context, const SelectQueryInfo &) const
|
||||
{
|
||||
const auto access_rights = context.getAccessRights();
|
||||
const bool check_access_for_databases = !access_rights->isGranted(AccessType::SHOW);
|
||||
const bool check_access_for_databases = !access_rights->isGranted(AccessType::SHOW_DATABASES);
|
||||
|
||||
auto databases = DatabaseCatalog::instance().getDatabases();
|
||||
for (const auto & database : databases)
|
||||
{
|
||||
if (check_access_for_databases && !access_rights->isGranted(AccessType::SHOW, database.first))
|
||||
if (check_access_for_databases && !access_rights->isGranted(AccessType::SHOW_DATABASES, database.first))
|
||||
continue;
|
||||
|
||||
res_columns[0]->insert(database.first);
|
||||
|
@ -50,7 +50,7 @@ NamesAndTypesList StorageSystemDictionaries::getNamesAndTypes()
|
||||
void StorageSystemDictionaries::fillData(MutableColumns & res_columns, const Context & context, const SelectQueryInfo & /*query_info*/) const
|
||||
{
|
||||
const auto access_rights = context.getAccessRights();
|
||||
const bool check_access_for_dictionaries = !access_rights->isGranted(AccessType::SHOW);
|
||||
const bool check_access_for_dictionaries = !access_rights->isGranted(AccessType::SHOW_DICTIONARIES);
|
||||
|
||||
const auto & external_dictionaries = context.getExternalDictionariesLoader();
|
||||
for (const auto & load_result : external_dictionaries.getCurrentLoadResults())
|
||||
@ -74,7 +74,7 @@ void StorageSystemDictionaries::fillData(MutableColumns & res_columns, const Con
|
||||
}
|
||||
|
||||
if (check_access_for_dictionaries
|
||||
&& !access_rights->isGranted(AccessType::SHOW, database.empty() ? IDictionary::NO_DATABASE_TAG : database, short_name))
|
||||
&& !access_rights->isGranted(AccessType::SHOW_DICTIONARIES, database.empty() ? IDictionary::NO_DATABASE_TAG : database, short_name))
|
||||
continue;
|
||||
|
||||
size_t i = 0;
|
||||
|
@ -37,11 +37,11 @@ NamesAndTypesList StorageSystemMerges::getNamesAndTypes()
|
||||
void StorageSystemMerges::fillData(MutableColumns & res_columns, const Context & context, const SelectQueryInfo &) const
|
||||
{
|
||||
const auto access_rights = context.getAccessRights();
|
||||
const bool check_access_for_tables = !access_rights->isGranted(AccessType::SHOW);
|
||||
const bool check_access_for_tables = !access_rights->isGranted(AccessType::SHOW_TABLES);
|
||||
|
||||
for (const auto & merge : context.getMergeList().get())
|
||||
{
|
||||
if (check_access_for_tables && !access_rights->isGranted(AccessType::SHOW, merge.database, merge.table))
|
||||
if (check_access_for_tables && !access_rights->isGranted(AccessType::SHOW_TABLES, merge.database, merge.table))
|
||||
continue;
|
||||
|
||||
size_t i = 0;
|
||||
|
@ -38,7 +38,7 @@ NamesAndTypesList StorageSystemMutations::getNamesAndTypes()
|
||||
void StorageSystemMutations::fillData(MutableColumns & res_columns, const Context & context, const SelectQueryInfo & query_info) const
|
||||
{
|
||||
const auto access_rights = context.getAccessRights();
|
||||
const bool check_access_for_databases = !access_rights->isGranted(AccessType::SHOW);
|
||||
const bool check_access_for_databases = !access_rights->isGranted(AccessType::SHOW_TABLES);
|
||||
|
||||
/// Collect a set of *MergeTree tables.
|
||||
std::map<String, std::map<String, StoragePtr>> merge_tree_tables;
|
||||
@ -48,14 +48,14 @@ void StorageSystemMutations::fillData(MutableColumns & res_columns, const Contex
|
||||
if (db.second->getEngineName() == "Lazy")
|
||||
continue;
|
||||
|
||||
const bool check_access_for_tables = check_access_for_databases && !access_rights->isGranted(AccessType::SHOW, db.first);
|
||||
const bool check_access_for_tables = check_access_for_databases && !access_rights->isGranted(AccessType::SHOW_TABLES, db.first);
|
||||
|
||||
for (auto iterator = db.second->getTablesIterator(context); iterator->isValid(); iterator->next())
|
||||
{
|
||||
if (!dynamic_cast<const MergeTreeData *>(iterator->table().get()))
|
||||
continue;
|
||||
|
||||
if (check_access_for_tables && !access_rights->isGranted(AccessType::SHOW, db.first, iterator->name()))
|
||||
if (check_access_for_tables && !access_rights->isGranted(AccessType::SHOW_TABLES, db.first, iterator->name()))
|
||||
continue;
|
||||
|
||||
merge_tree_tables[db.first][iterator->name()] = iterator->table();
|
||||
|
@ -74,7 +74,7 @@ StoragesInfoStream::StoragesInfoStream(const SelectQueryInfo & query_info, const
|
||||
MutableColumnPtr active_column_mut = ColumnUInt8::create();
|
||||
|
||||
const auto access_rights = context.getAccessRights();
|
||||
const bool check_access_for_tables = !access_rights->isGranted(AccessType::SHOW);
|
||||
const bool check_access_for_tables = !access_rights->isGranted(AccessType::SHOW_TABLES);
|
||||
|
||||
{
|
||||
Databases databases = DatabaseCatalog::instance().getDatabases();
|
||||
@ -119,7 +119,7 @@ StoragesInfoStream::StoragesInfoStream(const SelectQueryInfo & query_info, const
|
||||
if (!dynamic_cast<MergeTreeData *>(storage.get()))
|
||||
continue;
|
||||
|
||||
if (check_access_for_tables && !access_rights->isGranted(AccessType::SHOW, database_name, table_name))
|
||||
if (check_access_for_tables && !access_rights->isGranted(AccessType::SHOW_TABLES, database_name, table_name))
|
||||
continue;
|
||||
|
||||
storages[std::make_pair(database_name, iterator->name())] = storage;
|
||||
|
@ -66,7 +66,7 @@ Pipes StorageSystemReplicas::read(
|
||||
check(column_names);
|
||||
|
||||
const auto access_rights = context.getAccessRights();
|
||||
const bool check_access_for_databases = !access_rights->isGranted(AccessType::SHOW);
|
||||
const bool check_access_for_databases = !access_rights->isGranted(AccessType::SHOW_TABLES);
|
||||
|
||||
/// We collect a set of replicated tables.
|
||||
std::map<String, std::map<String, StoragePtr>> replicated_tables;
|
||||
@ -75,12 +75,12 @@ Pipes StorageSystemReplicas::read(
|
||||
/// Lazy database can not contain replicated tables
|
||||
if (db.second->getEngineName() == "Lazy")
|
||||
continue;
|
||||
const bool check_access_for_tables = check_access_for_databases && !access_rights->isGranted(AccessType::SHOW, db.first);
|
||||
const bool check_access_for_tables = check_access_for_databases && !access_rights->isGranted(AccessType::SHOW_TABLES, db.first);
|
||||
for (auto iterator = db.second->getTablesIterator(context); iterator->isValid(); iterator->next())
|
||||
{
|
||||
if (!dynamic_cast<const StorageReplicatedMergeTree *>(iterator->table().get()))
|
||||
continue;
|
||||
if (check_access_for_tables && !access_rights->isGranted(AccessType::SHOW, db.first, iterator->name()))
|
||||
if (check_access_for_tables && !access_rights->isGranted(AccessType::SHOW_TABLES, db.first, iterator->name()))
|
||||
continue;
|
||||
replicated_tables[db.first][iterator->name()] = iterator->table();
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ NamesAndTypesList StorageSystemReplicationQueue::getNamesAndTypes()
|
||||
void StorageSystemReplicationQueue::fillData(MutableColumns & res_columns, const Context & context, const SelectQueryInfo & query_info) const
|
||||
{
|
||||
const auto access_rights = context.getAccessRights();
|
||||
const bool check_access_for_databases = !access_rights->isGranted(AccessType::SHOW);
|
||||
const bool check_access_for_databases = !access_rights->isGranted(AccessType::SHOW_TABLES);
|
||||
|
||||
std::map<String, std::map<String, StoragePtr>> replicated_tables;
|
||||
for (const auto & db : DatabaseCatalog::instance().getDatabases())
|
||||
@ -58,13 +58,13 @@ void StorageSystemReplicationQueue::fillData(MutableColumns & res_columns, const
|
||||
if (db.second->getEngineName() == "Lazy")
|
||||
continue;
|
||||
|
||||
const bool check_access_for_tables = check_access_for_databases && !access_rights->isGranted(AccessType::SHOW, db.first);
|
||||
const bool check_access_for_tables = check_access_for_databases && !access_rights->isGranted(AccessType::SHOW_TABLES, db.first);
|
||||
|
||||
for (auto iterator = db.second->getTablesIterator(context); iterator->isValid(); iterator->next())
|
||||
{
|
||||
if (!dynamic_cast<const StorageReplicatedMergeTree *>(iterator->table().get()))
|
||||
continue;
|
||||
if (check_access_for_tables && !access_rights->isGranted(AccessType::SHOW, db.first, iterator->name()))
|
||||
if (check_access_for_tables && !access_rights->isGranted(AccessType::SHOW_TABLES, db.first, iterator->name()))
|
||||
continue;
|
||||
replicated_tables[db.first][iterator->name()] = iterator->table();
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ protected:
|
||||
MutableColumns res_columns = getPort().getHeader().cloneEmptyColumns();
|
||||
|
||||
const auto access_rights = context.getAccessRights();
|
||||
const bool check_access_for_databases = !access_rights->isGranted(AccessType::SHOW);
|
||||
const bool check_access_for_databases = !access_rights->isGranted(AccessType::SHOW_TABLES);
|
||||
|
||||
size_t rows_count = 0;
|
||||
while (rows_count < max_block_size)
|
||||
@ -196,7 +196,7 @@ protected:
|
||||
return Chunk(std::move(res_columns), num_rows);
|
||||
}
|
||||
|
||||
const bool check_access_for_tables = check_access_for_databases && !access_rights->isGranted(AccessType::SHOW, database_name);
|
||||
const bool check_access_for_tables = check_access_for_databases && !access_rights->isGranted(AccessType::SHOW_TABLES, database_name);
|
||||
|
||||
if (!tables_it || !tables_it->isValid())
|
||||
tables_it = database->getTablesWithDictionaryTablesIterator(context);
|
||||
@ -206,7 +206,7 @@ protected:
|
||||
for (; rows_count < max_block_size && tables_it->isValid(); tables_it->next())
|
||||
{
|
||||
auto table_name = tables_it->name();
|
||||
if (check_access_for_tables && !access_rights->isGranted(AccessType::SHOW, database_name, table_name))
|
||||
if (check_access_for_tables && !access_rights->isGranted(AccessType::SHOW_TABLES, database_name, table_name))
|
||||
continue;
|
||||
|
||||
StoragePtr table = nullptr;
|
||||
|
Loading…
Reference in New Issue
Block a user