Implement tcpPort() function literal

This commit is contained in:
Ivan Lezhankin 2020-11-17 16:24:13 +03:00
parent bef6463cb4
commit 1787cd89a7
6 changed files with 32 additions and 15 deletions

View File

@ -14,6 +14,7 @@
#include <Parsers/ASTFunctionWithKeyValueArguments.h> #include <Parsers/ASTFunctionWithKeyValueArguments.h>
#include <Parsers/ASTDictionaryAttributeDeclaration.h> #include <Parsers/ASTDictionaryAttributeDeclaration.h>
#include <Dictionaries/DictionaryFactory.h> #include <Dictionaries/DictionaryFactory.h>
#include <Functions/FunctionFactory.h>
namespace DB namespace DB
{ {
@ -356,7 +357,8 @@ NamesToTypeNames buildDictionaryAttributesConfiguration(
void buildConfigurationFromFunctionWithKeyValueArguments( void buildConfigurationFromFunctionWithKeyValueArguments(
AutoPtr<Document> doc, AutoPtr<Document> doc,
AutoPtr<Element> root, AutoPtr<Element> root,
const ASTExpressionList * ast_expr_list) const ASTExpressionList * ast_expr_list,
const Context & context)
{ {
const auto & children = ast_expr_list->children; const auto & children = ast_expr_list->children;
for (size_t i = 0; i != children.size(); ++i) for (size_t i = 0; i != children.size(); ++i)
@ -365,19 +367,30 @@ void buildConfigurationFromFunctionWithKeyValueArguments(
AutoPtr<Element> current_xml_element(doc->createElement(pair->first)); AutoPtr<Element> current_xml_element(doc->createElement(pair->first));
root->appendChild(current_xml_element); root->appendChild(current_xml_element);
if (const auto * identifier = pair->second->as<const ASTIdentifier>(); identifier) if (const auto * identifier = pair->second->as<const ASTIdentifier>())
{ {
AutoPtr<Text> value(doc->createTextNode(identifier->name())); AutoPtr<Text> value(doc->createTextNode(identifier->name()));
current_xml_element->appendChild(value); current_xml_element->appendChild(value);
} }
else if (const auto * literal = pair->second->as<const ASTLiteral>(); literal) else if (const auto * literal = pair->second->as<const ASTLiteral>())
{ {
AutoPtr<Text> value(doc->createTextNode(getFieldAsString(literal->value))); AutoPtr<Text> value(doc->createTextNode(getFieldAsString(literal->value)));
current_xml_element->appendChild(value); current_xml_element->appendChild(value);
} }
else if (const auto * list = pair->second->as<const ASTExpressionList>(); list) else if (const auto * list = pair->second->as<const ASTExpressionList>())
{ {
buildConfigurationFromFunctionWithKeyValueArguments(doc, current_xml_element, list); buildConfigurationFromFunctionWithKeyValueArguments(doc, current_xml_element, list, context);
}
else if (const auto * func = pair->second->as<ASTFunction>())
{
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> text_value(doc->createTextNode(getFieldAsString(value)));
current_xml_element->appendChild(text_value);
} }
else else
{ {
@ -406,13 +419,14 @@ void buildSourceConfiguration(
AutoPtr<Document> doc, AutoPtr<Document> doc,
AutoPtr<Element> root, AutoPtr<Element> root,
const ASTFunctionWithKeyValueArguments * source, const ASTFunctionWithKeyValueArguments * source,
const ASTDictionarySettings * settings) const ASTDictionarySettings * settings,
const Context & context)
{ {
AutoPtr<Element> outer_element(doc->createElement("source")); AutoPtr<Element> outer_element(doc->createElement("source"));
root->appendChild(outer_element); root->appendChild(outer_element);
AutoPtr<Element> source_element(doc->createElement(source->name)); AutoPtr<Element> source_element(doc->createElement(source->name));
outer_element->appendChild(source_element); outer_element->appendChild(source_element);
buildConfigurationFromFunctionWithKeyValueArguments(doc, source_element, source->elements->as<const ASTExpressionList>()); buildConfigurationFromFunctionWithKeyValueArguments(doc, source_element, source->elements->as<const ASTExpressionList>(), context);
if (settings != nullptr) 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); checkAST(query);
@ -510,7 +525,7 @@ DictionaryConfigurationPtr getDictionaryConfigurationFromAST(const ASTCreateQuer
buildPrimaryKeyConfiguration(xml_document, structure_element, complex, pk_attrs, query.dictionary_attributes_list); buildPrimaryKeyConfiguration(xml_document, structure_element, complex, pk_attrs, query.dictionary_attributes_list);
buildLayoutConfiguration(xml_document, current_dictionary, dictionary_layout); 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); buildLifetimeConfiguration(xml_document, current_dictionary, query.dictionary->lifetime);
if (query.dictionary->range) if (query.dictionary->range)

View File

@ -10,5 +10,6 @@ using DictionaryConfigurationPtr = Poco::AutoPtr<Poco::Util::AbstractConfigurati
/// Convert dictionary AST to Poco::AbstractConfiguration /// Convert dictionary AST to Poco::AbstractConfiguration
/// This function is necessary because all loadable objects configuration are Poco::AbstractConfiguration /// This function is necessary because all loadable objects configuration are Poco::AbstractConfiguration
/// Can throw exception if query is ill-formed /// Can throw exception if query is ill-formed
DictionaryConfigurationPtr getDictionaryConfigurationFromAST(const ASTCreateQuery & query, const std::string & database_ = ""); DictionaryConfigurationPtr
getDictionaryConfigurationFromAST(const ASTCreateQuery & query, const Context & context, const std::string & database_ = "");
} }

View File

@ -857,7 +857,7 @@ BlockIO InterpreterCreateQuery::createDictionary(ASTCreateQuery & create)
if (create.attach) if (create.attach)
{ {
auto config = getDictionaryConfigurationFromAST(create); auto config = getDictionaryConfigurationFromAST(create, context);
auto modification_time = database->getObjectMetadataModificationTime(dictionary_name); auto modification_time = database->getObjectMetadataModificationTime(dictionary_name);
database->attachDictionary(dictionary_name, DictionaryAttachInfo{query_ptr, config, modification_time}); database->attachDictionary(dictionary_name, DictionaryAttachInfo{query_ptr, config, modification_time});
} }

View File

@ -735,6 +735,7 @@ bool ParserKeyValuePair::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
{ {
ParserIdentifier id_parser; ParserIdentifier id_parser;
ParserLiteral literal_parser; ParserLiteral literal_parser;
ParserFunction func_parser;
ASTPtr identifier; ASTPtr identifier;
ASTPtr value; ASTPtr value;
@ -742,8 +743,8 @@ bool ParserKeyValuePair::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
if (!id_parser.parse(pos, identifier, expected)) if (!id_parser.parse(pos, identifier, expected))
return false; return false;
/// If it's not literal or identifier, than it's possible list of pairs /// If it's neither literal, nor identifier, nor function, than it's possible list of pairs
if (!literal_parser.parse(pos, value, expected) && !id_parser.parse(pos, value, expected)) if (!func_parser.parse(pos, value, expected) && !literal_parser.parse(pos, value, expected) && !id_parser.parse(pos, value, expected))
{ {
ParserKeyValuePairsList kv_pairs_list; ParserKeyValuePairsList kv_pairs_list;
ParserToken open(TokenType::OpeningRoundBracket); ParserToken open(TokenType::OpeningRoundBracket);

View File

@ -1,5 +1,5 @@
=DICTIONARY in Ordinary DB =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 dict1
1 1
db_01018 dict1 db_01018 dict1

View File

@ -32,7 +32,7 @@ CREATE DICTIONARY db_01018.dict1
third_column String DEFAULT 'qqq' third_column String DEFAULT 'qqq'
) )
PRIMARY KEY key_column 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) LIFETIME(MIN 1 MAX 10)
LAYOUT(FLAT()); LAYOUT(FLAT());