From 1787cd89a73e37665bb586196b7514d50b771e68 Mon Sep 17 00:00:00 2001 From: Ivan Lezhankin Date: Tue, 17 Nov 2020 16:24:13 +0300 Subject: [PATCH] Implement tcpPort() function literal --- .../getDictionaryConfigurationFromAST.cpp | 33 ++++++++++++++----- .../getDictionaryConfigurationFromAST.h | 3 +- src/Interpreters/InterpreterCreateQuery.cpp | 2 +- src/Parsers/ExpressionListParsers.cpp | 5 +-- .../01018_ddl_dictionaries_create.reference | 2 +- .../01018_ddl_dictionaries_create.sql | 2 +- 6 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/Dictionaries/getDictionaryConfigurationFromAST.cpp b/src/Dictionaries/getDictionaryConfigurationFromAST.cpp index 430c1d591dd..40e86d590c4 100644 --- a/src/Dictionaries/getDictionaryConfigurationFromAST.cpp +++ b/src/Dictionaries/getDictionaryConfigurationFromAST.cpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace DB { @@ -356,7 +357,8 @@ NamesToTypeNames buildDictionaryAttributesConfiguration( void buildConfigurationFromFunctionWithKeyValueArguments( AutoPtr doc, AutoPtr root, - const ASTExpressionList * ast_expr_list) + const ASTExpressionList * ast_expr_list, + const Context & context) { const auto & children = ast_expr_list->children; for (size_t i = 0; i != children.size(); ++i) @@ -365,19 +367,30 @@ void buildConfigurationFromFunctionWithKeyValueArguments( AutoPtr current_xml_element(doc->createElement(pair->first)); root->appendChild(current_xml_element); - if (const auto * identifier = pair->second->as(); identifier) + if (const auto * identifier = pair->second->as()) { AutoPtr value(doc->createTextNode(identifier->name())); current_xml_element->appendChild(value); } - else if (const auto * literal = pair->second->as(); literal) + else if (const auto * literal = pair->second->as()) { AutoPtr value(doc->createTextNode(getFieldAsString(literal->value))); current_xml_element->appendChild(value); } - else if (const auto * list = pair->second->as(); list) + else if (const auto * list = pair->second->as()) { - buildConfigurationFromFunctionWithKeyValueArguments(doc, current_xml_element, list); + buildConfigurationFromFunctionWithKeyValueArguments(doc, current_xml_element, list, context); + } + else if (const auto * func = pair->second->as()) + { + auto builder = FunctionFactory::instance().tryGet(func->name, context); + auto function = builder->build({}); + auto result = function->execute({}, {}, 0); + + Field value; + result->get(0, value); + AutoPtr text_value(doc->createTextNode(getFieldAsString(value))); + current_xml_element->appendChild(text_value); } else { @@ -406,13 +419,14 @@ void buildSourceConfiguration( AutoPtr doc, AutoPtr root, const ASTFunctionWithKeyValueArguments * source, - const ASTDictionarySettings * settings) + const ASTDictionarySettings * settings, + const Context & context) { AutoPtr outer_element(doc->createElement("source")); root->appendChild(outer_element); AutoPtr source_element(doc->createElement(source->name)); outer_element->appendChild(source_element); - buildConfigurationFromFunctionWithKeyValueArguments(doc, source_element, source->elements->as()); + buildConfigurationFromFunctionWithKeyValueArguments(doc, source_element, source->elements->as(), context); if (settings != nullptr) { @@ -466,7 +480,8 @@ void checkPrimaryKey(const NamesToTypeNames & all_attrs, const Names & key_attrs } -DictionaryConfigurationPtr getDictionaryConfigurationFromAST(const ASTCreateQuery & query, const std::string & database_) +DictionaryConfigurationPtr +getDictionaryConfigurationFromAST(const ASTCreateQuery & query, const Context & context, const std::string & database_) { checkAST(query); @@ -510,7 +525,7 @@ DictionaryConfigurationPtr getDictionaryConfigurationFromAST(const ASTCreateQuer buildPrimaryKeyConfiguration(xml_document, structure_element, complex, pk_attrs, query.dictionary_attributes_list); buildLayoutConfiguration(xml_document, current_dictionary, dictionary_layout); - buildSourceConfiguration(xml_document, current_dictionary, query.dictionary->source, query.dictionary->dict_settings); + buildSourceConfiguration(xml_document, current_dictionary, query.dictionary->source, query.dictionary->dict_settings, context); buildLifetimeConfiguration(xml_document, current_dictionary, query.dictionary->lifetime); if (query.dictionary->range) diff --git a/src/Dictionaries/getDictionaryConfigurationFromAST.h b/src/Dictionaries/getDictionaryConfigurationFromAST.h index 3038f450914..5132e3c77e0 100644 --- a/src/Dictionaries/getDictionaryConfigurationFromAST.h +++ b/src/Dictionaries/getDictionaryConfigurationFromAST.h @@ -10,5 +10,6 @@ using DictionaryConfigurationPtr = Poco::AutoPtrgetObjectMetadataModificationTime(dictionary_name); database->attachDictionary(dictionary_name, DictionaryAttachInfo{query_ptr, config, modification_time}); } diff --git a/src/Parsers/ExpressionListParsers.cpp b/src/Parsers/ExpressionListParsers.cpp index 0f06a0d2480..c1ec00befaf 100644 --- a/src/Parsers/ExpressionListParsers.cpp +++ b/src/Parsers/ExpressionListParsers.cpp @@ -735,6 +735,7 @@ bool ParserKeyValuePair::parseImpl(Pos & pos, ASTPtr & node, Expected & expected { ParserIdentifier id_parser; ParserLiteral literal_parser; + ParserFunction func_parser; ASTPtr identifier; ASTPtr value; @@ -742,8 +743,8 @@ bool ParserKeyValuePair::parseImpl(Pos & pos, ASTPtr & node, Expected & expected if (!id_parser.parse(pos, identifier, expected)) return false; - /// If it's not literal or identifier, than it's possible list of pairs - if (!literal_parser.parse(pos, value, expected) && !id_parser.parse(pos, value, expected)) + /// If it's neither literal, nor identifier, nor function, than it's possible list of pairs + if (!func_parser.parse(pos, value, expected) && !literal_parser.parse(pos, value, expected) && !id_parser.parse(pos, value, expected)) { ParserKeyValuePairsList kv_pairs_list; ParserToken open(TokenType::OpeningRoundBracket); diff --git a/tests/queries/0_stateless/01018_ddl_dictionaries_create.reference b/tests/queries/0_stateless/01018_ddl_dictionaries_create.reference index 5b020911d2e..e591300eddc 100644 --- a/tests/queries/0_stateless/01018_ddl_dictionaries_create.reference +++ b/tests/queries/0_stateless/01018_ddl_dictionaries_create.reference @@ -1,5 +1,5 @@ =DICTIONARY in Ordinary DB -CREATE DICTIONARY db_01018.dict1\n(\n `key_column` UInt64 DEFAULT 0,\n `second_column` UInt8 DEFAULT 1,\n `third_column` String DEFAULT \'qqq\'\n)\nPRIMARY KEY key_column\nSOURCE(CLICKHOUSE(HOST \'localhost\' PORT 9000 USER \'default\' TABLE \'table_for_dict\' PASSWORD \'\' DB \'database_for_dict_01018\'))\nLIFETIME(MIN 1 MAX 10)\nLAYOUT(FLAT()) +CREATE DICTIONARY db_01018.dict1\n(\n `key_column` UInt64 DEFAULT 0,\n `second_column` UInt8 DEFAULT 1,\n `third_column` String DEFAULT \'qqq\'\n)\nPRIMARY KEY key_column\nSOURCE(CLICKHOUSE(HOST \'localhost\' PORT tcpPort() USER \'default\' TABLE \'table_for_dict\' PASSWORD \'\' DB \'database_for_dict_01018\'))\nLIFETIME(MIN 1 MAX 10)\nLAYOUT(FLAT()) dict1 1 db_01018 dict1 diff --git a/tests/queries/0_stateless/01018_ddl_dictionaries_create.sql b/tests/queries/0_stateless/01018_ddl_dictionaries_create.sql index 3261b1e61d1..1a3733fd5cb 100644 --- a/tests/queries/0_stateless/01018_ddl_dictionaries_create.sql +++ b/tests/queries/0_stateless/01018_ddl_dictionaries_create.sql @@ -32,7 +32,7 @@ CREATE DICTIONARY db_01018.dict1 third_column String DEFAULT 'qqq' ) PRIMARY KEY key_column -SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'default' TABLE 'table_for_dict' PASSWORD '' DB 'database_for_dict_01018')) +SOURCE(CLICKHOUSE(HOST 'localhost' PORT tcpPort() USER 'default' TABLE 'table_for_dict' PASSWORD '' DB 'database_for_dict_01018')) LIFETIME(MIN 1 MAX 10) LAYOUT(FLAT());