mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-03 13:02:00 +00:00
DDL dictionary use current database name
This commit is contained in:
parent
f1223e7548
commit
0f95bcac0b
@ -80,12 +80,31 @@ public:
|
||||
std::shared_ptr<const IDictionaryBase> getDictionary(const String & dictionary_name)
|
||||
{
|
||||
String resolved_name = DatabaseCatalog::instance().resolveDictionaryName(dictionary_name);
|
||||
auto dict = external_loader.getDictionary(resolved_name);
|
||||
|
||||
auto dict = external_loader.tryGetDictionary(resolved_name);
|
||||
|
||||
if (!dict)
|
||||
{
|
||||
/// If dictionary not found. And database was not implicitly specified
|
||||
/// we can qualify dictionary name with current database name.
|
||||
/// It will help if dictionary is created with DDL and is in current database.
|
||||
if (dictionary_name.find('.') == std::string::npos)
|
||||
{
|
||||
String dictionary_name_with_database = context.getCurrentDatabase() + '.' + dictionary_name;
|
||||
resolved_name = DatabaseCatalog::instance().resolveDictionaryName(dictionary_name_with_database);
|
||||
dict = external_loader.tryGetDictionary(resolved_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!dict)
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "External dictionary ({}) not found", dictionary_name);
|
||||
|
||||
if (!access_checked)
|
||||
{
|
||||
context.checkAccess(AccessType::dictGet, dict->getDatabaseOrNoDatabaseTag(), dict->getDictionaryID().getTableName());
|
||||
access_checked = true;
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
@ -118,14 +137,29 @@ public:
|
||||
DictionaryStructure getDictionaryStructure(const String & dictionary_name) const
|
||||
{
|
||||
String resolved_name = DatabaseCatalog::instance().resolveDictionaryName(dictionary_name);
|
||||
|
||||
auto load_result = external_loader.getLoadResult(resolved_name);
|
||||
if (!load_result.config)
|
||||
{
|
||||
/// If dictionary not found. And database was not implicitly specified
|
||||
/// we can qualify dictionary name with current database name.
|
||||
/// It will help if dictionary is created with DDL and is in current database.
|
||||
if (dictionary_name.find('.') == std::string::npos)
|
||||
{
|
||||
String dictionary_name_with_database = context.getCurrentDatabase() + '.' + dictionary_name;
|
||||
resolved_name = DatabaseCatalog::instance().resolveDictionaryName(dictionary_name_with_database);
|
||||
load_result = external_loader.getLoadResult(resolved_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!load_result.config)
|
||||
throw Exception("Dictionary " + backQuote(dictionary_name) + " not found", ErrorCodes::BAD_ARGUMENTS);
|
||||
|
||||
return ExternalDictionariesLoader::getDictionaryStructure(*load_result.config);
|
||||
}
|
||||
|
||||
private:
|
||||
const Context & context;
|
||||
private:
|
||||
const ExternalDictionariesLoader & external_loader;
|
||||
/// Access cannot be not granted, since in this case checkAccess() will throw and access_checked will not be updated.
|
||||
std::atomic<bool> access_checked = false;
|
||||
@ -296,10 +330,13 @@ public:
|
||||
|
||||
DataTypes types;
|
||||
|
||||
auto current_database_name = helper.context.getCurrentDatabase();
|
||||
auto dictionary_structure = helper.getDictionaryStructure(dictionary_name);
|
||||
|
||||
for (auto & attribute_name : attribute_names)
|
||||
{
|
||||
/// We're extracting the return type from the dictionary's config, without loading the dictionary.
|
||||
auto attribute = helper.getDictionaryStructure(dictionary_name).getAttribute(attribute_name);
|
||||
auto attribute = dictionary_structure.getAttribute(attribute_name);
|
||||
types.emplace_back(attribute.type);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,8 @@
|
||||
dictGet
|
||||
0
|
||||
1
|
||||
0
|
||||
dictHas
|
||||
1
|
||||
1
|
||||
0
|
@ -0,0 +1,26 @@
|
||||
DROP TABLE IF EXISTS ddl_dictonary_test_source;
|
||||
CREATE TABLE ddl_dictonary_test_source
|
||||
(
|
||||
id UInt64,
|
||||
value UInt64
|
||||
)
|
||||
ENGINE = TinyLog;
|
||||
|
||||
INSERT INTO ddl_dictonary_test_source VALUES (0, 0);
|
||||
INSERT INTO ddl_dictonary_test_source VALUES (1, 1);
|
||||
|
||||
DROP DICTIONARY IF EXISTS ddl_dictionary_test;
|
||||
CREATE DICTIONARY ddl_dictionary_test
|
||||
(
|
||||
id UInt64,
|
||||
value UInt64 DEFAULT 0
|
||||
)
|
||||
PRIMARY KEY id
|
||||
SOURCE(CLICKHOUSE(HOST 'localhost' PORT tcpPort() USER 'default' TABLE 'ddl_dictonary_test_source'))
|
||||
LAYOUT(DIRECT());
|
||||
|
||||
SELECT 'dictGet';
|
||||
SELECT dictGet('ddl_dictionary_test', 'value', number) FROM system.numbers LIMIT 3;
|
||||
|
||||
SELECT 'dictHas';
|
||||
SELECT dictHas('ddl_dictionary_test', number) FROM system.numbers LIMIT 3;
|
Loading…
Reference in New Issue
Block a user