fixed bug & created functional test for new layout

This commit is contained in:
Артем Стрельцов 2020-05-02 04:03:29 +03:00
parent 97496048d6
commit 25d7f76e4f
4 changed files with 100 additions and 11 deletions

View File

@ -310,7 +310,8 @@ void DirectDictionary::createAttributes()
for (const auto & attribute : dict_struct.attributes)
{
attribute_index_by_name.emplace(attribute.name, attributes.size());
attributes.push_back(createAttributeWithType(attribute.underlying_type, attribute.null_value));
attribute_name_by_index.emplace(attributes.size(), attribute.name);
attributes.push_back(createAttributeWithType(attribute.underlying_type, attribute.null_value, attribute.name));
if (attribute.hierarchical)
{
@ -351,9 +352,9 @@ void DirectDictionary::createAttributeImpl<String>(Attribute & attribute, const
}
DirectDictionary::Attribute DirectDictionary::createAttributeWithType(const AttributeUnderlyingType type, const Field & null_value)
DirectDictionary::Attribute DirectDictionary::createAttributeWithType(const AttributeUnderlyingType type, const Field & null_value, const std::string & attr_name)
{
Attribute attr{type, {}, {}};
Attribute attr{type, {}, {}, attr_name};
switch (type)
{
@ -411,7 +412,7 @@ DirectDictionary::Attribute DirectDictionary::createAttributeWithType(const Attr
template <typename AttributeType, typename OutputType, typename ValueSetter, typename DefaultGetter>
void DirectDictionary::getItemsImpl(
const Attribute &, const PaddedPODArray<Key> & ids, ValueSetter && set_value, DefaultGetter && get_default) const
const Attribute & attribute, const PaddedPODArray<Key> & ids, ValueSetter && set_value, DefaultGetter && get_default) const
{
const auto rows = ext::size(ids);
@ -431,10 +432,9 @@ void DirectDictionary::getItemsImpl(
const auto key = id_column[row_idx].get<UInt64>();
for (const auto row : ext::range(0, rows)) {
if (key == ids[row]) {
if (key == ids[row] && attribute.name == attribute_name_by_index.at(attribute_idx)) {
is_found[row] = true;
set_value(row, static_cast<OutputType>(attribute_column[row_idx].get<AttributeType>()));
// break;
}
}
}
@ -453,7 +453,7 @@ void DirectDictionary::getItemsImpl(
template <typename AttributeType, typename OutputType, typename ValueSetter, typename DefaultGetter>
void DirectDictionary::getItemsStringImpl(
const Attribute &, const PaddedPODArray<Key> & ids, ValueSetter && set_value, DefaultGetter && get_default) const
const Attribute & attribute, const PaddedPODArray<Key> & ids, ValueSetter && set_value, DefaultGetter && get_default) const
{
const auto rows = ext::size(ids);
@ -472,14 +472,13 @@ void DirectDictionary::getItemsStringImpl(
for (const auto row_idx : ext::range(0, id_column.size())) {
const auto key = id_column[row_idx].get<UInt64>();
for (const auto row : ext::range(0, rows)) {
if (key == ids[row]) {
if (key == ids[row] && attribute.name == attribute_name_by_index.at(attribute_idx)) {
is_found[row] = true;
const String from_source = attribute_column[row_idx].get<String>();
const auto * string_in_arena = temp_arena->insert(from_source.data(), from_source.size());
const auto reference = StringRef{string_in_arena, from_source.size()};
set_value(row, reference);
break;
}
}
}
@ -526,7 +525,6 @@ void DirectDictionary::has(const Attribute &, const PaddedPODArray<Key> & ids, P
for (const auto row : ext::range(0, rows)) {
if (key == ids[row]) {
out[row] = 1;
// break;
}
}
}

View File

@ -168,6 +168,7 @@ private:
StringRef>
null_values;
std::unique_ptr<Arena> string_arena;
std::string name;
};
void createAttributes();
@ -180,7 +181,7 @@ private:
template <typename T>
void createAttributeImpl(Attribute & attribute, const Field & null_value);
Attribute createAttributeWithType(const AttributeUnderlyingType type, const Field & null_value);
Attribute createAttributeWithType(const AttributeUnderlyingType type, const Field & null_value, const std::string & name);
template <typename AttributeType, typename OutputType, typename ValueSetter, typename DefaultGetter>
void getItemsStringImpl(
@ -218,6 +219,7 @@ private:
const DictionaryLifetime dict_lifetime;
std::map<std::string, size_t> attribute_index_by_name;
std::map<size_t, std::string> attribute_name_by_index;
std::vector<Attribute> attributes;
const Attribute * hierarchical_attribute = nullptr;

View File

@ -0,0 +1,7 @@
INITIALIZING DICTIONARY
[3,2,1]
1
0
1
0
END

View File

@ -0,0 +1,82 @@
DROP DATABASE IF EXISTS database_for_dict;
CREATE DATABASE database_for_dict Engine = Ordinary;
DROP TABLE IF EXISTS database_for_dict.table_for_dict1;
DROP TABLE IF EXISTS database_for_dict.table_for_dict2;
CREATE TABLE database_for_dict.table_for_dict1
(
key_column UInt64,
second_column UInt64,
third_column String
)
ENGINE = MergeTree()
ORDER BY key_column;
INSERT INTO database_for_dict.table_for_dict1 VALUES (100500, 10000000, 'Hello world');
CREATE TABLE database_for_dict.table_for_dict2
(
region_id UInt64,
parent_region UInt64,
region_name String
)
ENGINE = MergeTree()
ORDER BY region_id;
INSERT INTO database_for_dict.table_for_dict2 VALUES (1, 0, 'Russia');
INSERT INTO database_for_dict.table_for_dict2 VALUES (2, 1, 'Moscow');
INSERT INTO database_for_dict.table_for_dict2 VALUES (3, 2, 'Center');
INSERT INTO database_for_dict.table_for_dict2 VALUES (4, 0, 'Great Britain');
INSERT INTO database_for_dict.table_for_dict2 VALUES (5, 4, 'London');
DROP DATABASE IF EXISTS ordinary_db;
CREATE DATABASE ordinary_db ENGINE = Ordinary;
DROP DICTIONARY IF EXISTS ordinary_db.dict1;
CREATE DICTIONARY ordinary_db.dict1
(
key_column UInt64 DEFAULT 0,
second_column UInt64 DEFAULT 1,
third_column String DEFAULT 'qqq'
)
PRIMARY KEY key_column
SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'default' TABLE 'table_for_dict1' PASSWORD '' DB 'database_for_dict'))
LIFETIME(MIN 600 MAX 600)
LAYOUT(DIRECT()) SETTINGS(max_result_bytes=1);
CREATE DICTIONARY ordinary_db.dict2
(
region_id UInt64 DEFAULT 0,
parent_region UInt64 DEFAULT 0 HIERARCHICAL,
region_name String DEFAULT ''
)
PRIMARY KEY region_id
SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'default' TABLE 'table_for_dict2' PASSWORD '' DB 'database_for_dict'))
LIFETIME(MIN 600 MAX 600)
LAYOUT(DIRECT());
SELECT 'INITIALIZING DICTIONARY';
SELECT dictGetHierarchy('ordinary_db.dict2', toUInt64(3));
SELECT dictHas('ordinary_db.dict2', toUInt64(3));
SELECT dictHas('ordinary_db.dict2', toUInt64(45));
SELECT dictIsIn('ordinary_db.dict2', toUInt64(3), toUInt64(1));
SELECT dictIsIn('ordinary_db.dict2', toUInt64(1), toUInt64(3));
SELECT dictGetUInt64('ordinary_db.dict1', 'second_column', toUInt64(100500)); -- { serverError 396 }
SELECT 'END';
DROP DICTIONARY IF EXISTS ordinary_db.dict1;
DROP DICTIONARY IF EXISTS ordinary_db.dict2;
DROP DATABASE IF EXISTS ordinary_db;
DROP TABLE IF EXISTS database_for_dict.table_for_dict1;
DROP TABLE IF EXISTS database_for_dict.table_for_dict2;
DROP DATABASE IF EXISTS database_for_dict;