Skip to content

Commit 2eca762

Browse files
authored
Merge pull request ClickHouse#57134 from vitlibar/check-dictionary-source-type-on-creation
Check dictionary source type on creation
2 parents 6545775 + e0c9661 commit 2eca762

File tree

5 files changed

+38
-3
lines changed

5 files changed

+38
-3
lines changed

src/Dictionaries/DictionarySourceFactory.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,18 @@ DictionarySourcePtr DictionarySourceFactory::create(
108108
source_type);
109109
}
110110

111+
void DictionarySourceFactory::checkSourceAvailable(const std::string & source_type, const std::string & dictionary_name, const ContextPtr & /* context */) const
112+
{
113+
const auto found = registered_sources.find(source_type);
114+
if (found == registered_sources.end())
115+
{
116+
throw Exception(ErrorCodes::UNKNOWN_ELEMENT_IN_CONFIG,
117+
"{}: unknown dictionary source type: {}",
118+
dictionary_name,
119+
source_type);
120+
}
121+
}
122+
111123
DictionarySourceFactory & DictionarySourceFactory::instance()
112124
{
113125
static DictionarySourceFactory instance;

src/Dictionaries/DictionarySourceFactory.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ class DictionarySourceFactory : private boost::noncopyable
5252
const std::string & default_database,
5353
bool check_config) const;
5454

55+
/// Checks that a specified source exists and available for the current user.
56+
void checkSourceAvailable(const std::string & source_type, const std::string & dictionary_name, const ContextPtr & context) const;
57+
5558
private:
5659
using SourceRegistry = std::unordered_map<std::string, Creator>;
5760
SourceRegistry registered_sources;

src/Dictionaries/getDictionaryConfigurationFromAST.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <Parsers/ASTFunctionWithKeyValueArguments.h>
1717
#include <Parsers/ASTDictionaryAttributeDeclaration.h>
1818
#include <Dictionaries/DictionaryFactory.h>
19+
#include <Dictionaries/DictionarySourceFactory.h>
1920
#include <Functions/FunctionFactory.h>
2021
#include <Common/isLocalAddress.h>
2122
#include <Interpreters/Context.h>
@@ -518,8 +519,11 @@ void buildSourceConfiguration(
518519
AutoPtr<Element> root,
519520
const ASTFunctionWithKeyValueArguments * source,
520521
const ASTDictionarySettings * settings,
522+
const String & dictionary_name,
521523
ContextPtr context)
522524
{
525+
DictionarySourceFactory::instance().checkSourceAvailable(source->name, dictionary_name, context);
526+
523527
AutoPtr<Element> outer_element(doc->createElement("source"));
524528
root->appendChild(outer_element);
525529
AutoPtr<Element> source_element(doc->createElement(source->name));
@@ -591,6 +595,10 @@ getDictionaryConfigurationFromAST(const ASTCreateQuery & query, ContextPtr conte
591595
checkAST(query);
592596
checkLifetime(query);
593597

598+
String dictionary_name = query.getTable();
599+
String db_name = !database_.empty() ? database_ : query.getDatabase();
600+
String full_dictionary_name = (!db_name.empty() ? (db_name + ".") : "") + dictionary_name;
601+
594602
AutoPtr<Poco::XML::Document> xml_document(new Poco::XML::Document());
595603
AutoPtr<Poco::XML::Element> document_root(xml_document->createElement("dictionaries"));
596604
xml_document->appendChild(document_root);
@@ -600,12 +608,12 @@ getDictionaryConfigurationFromAST(const ASTCreateQuery & query, ContextPtr conte
600608

601609
AutoPtr<Poco::XML::Element> name_element(xml_document->createElement("name"));
602610
current_dictionary->appendChild(name_element);
603-
AutoPtr<Text> name(xml_document->createTextNode(query.getTable()));
611+
AutoPtr<Text> name(xml_document->createTextNode(dictionary_name));
604612
name_element->appendChild(name);
605613

606614
AutoPtr<Poco::XML::Element> database_element(xml_document->createElement("database"));
607615
current_dictionary->appendChild(database_element);
608-
AutoPtr<Text> database(xml_document->createTextNode(!database_.empty() ? database_ : query.getDatabase()));
616+
AutoPtr<Text> database(xml_document->createTextNode(db_name));
609617
database_element->appendChild(database);
610618

611619
if (query.uuid != UUIDHelpers::Nil)
@@ -641,7 +649,7 @@ getDictionaryConfigurationFromAST(const ASTCreateQuery & query, ContextPtr conte
641649
buildPrimaryKeyConfiguration(xml_document, structure_element, complex, pk_attrs, query.dictionary_attributes_list);
642650

643651
buildLayoutConfiguration(xml_document, current_dictionary, query.dictionary->dict_settings, dictionary_layout);
644-
buildSourceConfiguration(xml_document, current_dictionary, query.dictionary->source, query.dictionary->dict_settings, context);
652+
buildSourceConfiguration(xml_document, current_dictionary, query.dictionary->source, query.dictionary->dict_settings, full_dictionary_name, context);
645653
buildLifetimeConfiguration(xml_document, current_dictionary, query.dictionary->lifetime);
646654

647655
if (query.dictionary->range)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
DROP DICTIONARY IF EXISTS id_value_dictionary;
2+
DROP TABLE IF EXISTS source_table;
3+
4+
CREATE TABLE source_table(id UInt64, value String) ENGINE = MergeTree ORDER BY tuple();
5+
6+
-- There is no "CLICKHOUSEX" dictionary source, so the next query must fail even if `dictionaries_lazy_load` is enabled.
7+
CREATE DICTIONARY id_value_dictionary(id UInt64, value String) PRIMARY KEY id SOURCE(CLICKHOUSEX(TABLE 'source_table')) LIFETIME(MIN 0 MAX 1000) LAYOUT(FLAT()); -- { serverError UNKNOWN_ELEMENT_IN_CONFIG }
8+
9+
SELECT count() FROM system.dictionaries WHERE name=='id_value_dictionary' AND database==currentDatabase();
10+
11+
DROP TABLE source_table;

0 commit comments

Comments
 (0)