mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
fixed bug & created functional test for new layout
This commit is contained in:
parent
97496048d6
commit
25d7f76e4f
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -0,0 +1,7 @@
|
||||
INITIALIZING DICTIONARY
|
||||
[3,2,1]
|
||||
1
|
||||
0
|
||||
1
|
||||
0
|
||||
END
|
82
tests/queries/0_stateless/01268_dictionary_direct_layout.sql
Normal file
82
tests/queries/0_stateless/01268_dictionary_direct_layout.sql
Normal 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;
|
Loading…
Reference in New Issue
Block a user