mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-12 09:22:05 +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)
|
std::shared_ptr<const IDictionaryBase> getDictionary(const String & dictionary_name)
|
||||||
{
|
{
|
||||||
String resolved_name = DatabaseCatalog::instance().resolveDictionaryName(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)
|
if (!access_checked)
|
||||||
{
|
{
|
||||||
context.checkAccess(AccessType::dictGet, dict->getDatabaseOrNoDatabaseTag(), dict->getDictionaryID().getTableName());
|
context.checkAccess(AccessType::dictGet, dict->getDatabaseOrNoDatabaseTag(), dict->getDictionaryID().getTableName());
|
||||||
access_checked = true;
|
access_checked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,14 +137,29 @@ public:
|
|||||||
DictionaryStructure getDictionaryStructure(const String & dictionary_name) const
|
DictionaryStructure getDictionaryStructure(const String & dictionary_name) const
|
||||||
{
|
{
|
||||||
String resolved_name = DatabaseCatalog::instance().resolveDictionaryName(dictionary_name);
|
String resolved_name = DatabaseCatalog::instance().resolveDictionaryName(dictionary_name);
|
||||||
|
|
||||||
auto load_result = external_loader.getLoadResult(resolved_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)
|
if (!load_result.config)
|
||||||
throw Exception("Dictionary " + backQuote(dictionary_name) + " not found", ErrorCodes::BAD_ARGUMENTS);
|
throw Exception("Dictionary " + backQuote(dictionary_name) + " not found", ErrorCodes::BAD_ARGUMENTS);
|
||||||
|
|
||||||
return ExternalDictionariesLoader::getDictionaryStructure(*load_result.config);
|
return ExternalDictionariesLoader::getDictionaryStructure(*load_result.config);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
const Context & context;
|
const Context & context;
|
||||||
|
private:
|
||||||
const ExternalDictionariesLoader & external_loader;
|
const ExternalDictionariesLoader & external_loader;
|
||||||
/// Access cannot be not granted, since in this case checkAccess() will throw and access_checked will not be updated.
|
/// 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;
|
std::atomic<bool> access_checked = false;
|
||||||
@ -296,10 +330,13 @@ public:
|
|||||||
|
|
||||||
DataTypes types;
|
DataTypes types;
|
||||||
|
|
||||||
|
auto current_database_name = helper.context.getCurrentDatabase();
|
||||||
|
auto dictionary_structure = helper.getDictionaryStructure(dictionary_name);
|
||||||
|
|
||||||
for (auto & attribute_name : attribute_names)
|
for (auto & attribute_name : attribute_names)
|
||||||
{
|
{
|
||||||
/// We're extracting the return type from the dictionary's config, without loading the dictionary.
|
/// 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);
|
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