Merge pull request #19571 from kitaisreal/create-simple-dictionary-id-expression-fix

Query CREATE DICTIONARY id expression fix
This commit is contained in:
Maksim Kita 2021-01-26 12:43:49 +03:00 committed by GitHub
commit 16eb7b01b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 83 additions and 21 deletions

View File

@ -180,6 +180,32 @@ Names getPrimaryKeyColumns(const ASTExpressionList * primary_key)
return result;
}
void buildAttributeExpressionIfNeeded(
AutoPtr<Document> doc,
AutoPtr<Element> root,
const ASTDictionaryAttributeDeclaration * dict_attr)
{
if (dict_attr->expression != nullptr)
{
AutoPtr<Element> expression_element(doc->createElement("expression"));
/// EXPRESSION PROPERTY should be expression or string
String expression_str;
if (const auto * literal = dict_attr->expression->as<ASTLiteral>();
literal && literal->value.getType() == Field::Types::String)
{
expression_str = getFieldAsString(literal->value);
}
else
expression_str = queryToString(dict_attr->expression);
AutoPtr<Text> expression(doc->createTextNode(expression_str));
expression_element->appendChild(expression);
root->appendChild(expression_element);
}
}
/**
* Transofrms single dictionary attribute to configuration
* third_column UInt8 DEFAULT 2 EXPRESSION rand() % 100 * 77
@ -217,25 +243,7 @@ void buildSingleAttribute(
null_value_element->appendChild(null_value);
attribute_element->appendChild(null_value_element);
if (dict_attr->expression != nullptr)
{
AutoPtr<Element> expression_element(doc->createElement("expression"));
/// EXPRESSION PROPERTY should be expression or string
String expression_str;
if (const auto * literal = dict_attr->expression->as<ASTLiteral>();
literal && literal->value.getType() == Field::Types::String)
{
expression_str = getFieldAsString(literal->value);
}
else
expression_str = queryToString(dict_attr->expression);
AutoPtr<Text> expression(doc->createTextNode(expression_str));
expression_element->appendChild(expression);
attribute_element->appendChild(expression_element);
}
buildAttributeExpressionIfNeeded(doc, attribute_element, dict_attr);
if (dict_attr->hierarchical)
{
@ -286,6 +294,8 @@ void buildPrimaryKeyConfiguration(
const Names & key_names,
const ASTExpressionList * dictionary_attributes)
{
const auto & children = dictionary_attributes->children;
if (!complex)
{
if (key_names.size() != 1)
@ -296,12 +306,16 @@ void buildPrimaryKeyConfiguration(
root->appendChild(id_element);
AutoPtr<Element> name_element(doc->createElement("name"));
id_element->appendChild(name_element);
AutoPtr<Text> name(doc->createTextNode(*key_names.begin()));
const ASTDictionaryAttributeDeclaration * dict_attr = children.front()->as<const ASTDictionaryAttributeDeclaration>();
AutoPtr<Text> name(doc->createTextNode(dict_attr->name));
name_element->appendChild(name);
buildAttributeExpressionIfNeeded(doc, id_element, dict_attr);
}
else
{
const auto & children = dictionary_attributes->children;
if (children.size() < key_names.size())
throw Exception(
"Primary key fields count is more, than dictionary attributes count.", ErrorCodes::INCORRECT_DICTIONARY_DEFINITION);

View File

@ -0,0 +1,8 @@
Simple
5791441145865411458 Test2
3450587330153346914 Test1
3111929972906540512 Test3
Complex
3111929972906540512 5 Test3
5791441145865411458 5 Test2
3450587330153346914 5 Test1

View File

@ -0,0 +1,40 @@
CREATE DATABASE database_dictionary_test_key_expression;
CREATE TABLE database_dictionary_test_key_expression.test_for_dictionary (value String) ENGINE=TinyLog;
INSERT INTO database_dictionary_test_key_expression.test_for_dictionary VALUES ('Test1'), ('Test2'), ('Test3');
SELECT 'Simple';
CREATE DICTIONARY database_dictionary_test_key_expression.test_query_log_dictionary_simple
(
`value_id` UInt64 EXPRESSION cityHash64(value),
`value` String
)
PRIMARY KEY value_id
SOURCE(CLICKHOUSE(HOST 'localhost' PORT tcpPort() USER 'default' TABLE 'test_for_dictionary' DB 'database_dictionary_test_key_expression'))
LIFETIME(MIN 1 MAX 10)
LAYOUT(HASHED());
SELECT * FROM database_dictionary_test_key_expression.test_query_log_dictionary_simple;
DROP DICTIONARY IF EXISTS database_dictionary_test_key_expression.test_query_log_dictionary_simple;
SELECT 'Complex';
CREATE DICTIONARY database_dictionary_test_key_expression.test_query_log_dictionary_complex
(
`value_id` UInt64 EXPRESSION cityHash64(value),
`value_length` UInt64 EXPRESSION length(value),
`value` String
)
PRIMARY KEY value_id, value_length
SOURCE(CLICKHOUSE(HOST 'localhost' PORT tcpPort() USER 'default' TABLE 'test_for_dictionary' DB 'database_dictionary_test_key_expression'))
LIFETIME(MIN 1 MAX 10)
LAYOUT(COMPLEX_KEY_HASHED());
SELECT * FROM database_dictionary_test_key_expression.test_query_log_dictionary_complex;
DROP DICTIONARY IF EXISTS database_dictionary_test_key_expression.test_query_log_dictionary_complex;
DROP TABLE IF EXISTS database_dictionary_test_key_expression.test_for_dictionary;
DROP DATABASE IF EXISTS database_dictionary_test_key_expression;