mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 23:52:03 +00:00
Merge pull request #49587 from xbthink/master
automatically choose the "complex key" layout variant
This commit is contained in:
commit
9732998111
@ -17,13 +17,13 @@ namespace ErrorCodes
|
||||
extern const int UNKNOWN_ELEMENT_IN_CONFIG;
|
||||
}
|
||||
|
||||
void DictionaryFactory::registerLayout(const std::string & layout_type, LayoutCreateFunction create_layout, bool is_layout_complex)
|
||||
void DictionaryFactory::registerLayout(const std::string & layout_type, LayoutCreateFunction create_layout, bool is_layout_complex, bool has_layout_complex)
|
||||
{
|
||||
auto it = registered_layouts.find(layout_type);
|
||||
if (it != registered_layouts.end())
|
||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "DictionaryFactory: the layout name '{}' is not unique", layout_type);
|
||||
|
||||
RegisteredLayout layout { .layout_create_function = create_layout, .is_layout_complex = is_layout_complex };
|
||||
RegisteredLayout layout { .layout_create_function = create_layout, .is_layout_complex = is_layout_complex, .has_layout_complex = has_layout_complex };
|
||||
registered_layouts.emplace(layout_type, std::move(layout));
|
||||
}
|
||||
|
||||
@ -89,6 +89,25 @@ bool DictionaryFactory::isComplex(const std::string & layout_type) const
|
||||
return it->second.is_layout_complex;
|
||||
}
|
||||
|
||||
bool DictionaryFactory::convertToComplex(std::string & layout_type) const
|
||||
{
|
||||
auto it = registered_layouts.find(layout_type);
|
||||
|
||||
if (it == registered_layouts.end())
|
||||
{
|
||||
throw Exception(ErrorCodes::UNKNOWN_ELEMENT_IN_CONFIG,
|
||||
"Unknown dictionary layout type: {}",
|
||||
layout_type);
|
||||
}
|
||||
|
||||
if (!it->second.is_layout_complex && it->second.has_layout_complex)
|
||||
{
|
||||
layout_type = "complex_key_" + layout_type;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
DictionaryFactory & DictionaryFactory::instance()
|
||||
{
|
||||
|
@ -55,13 +55,18 @@ public:
|
||||
|
||||
bool isComplex(const std::string & layout_type) const;
|
||||
|
||||
void registerLayout(const std::string & layout_type, LayoutCreateFunction create_layout, bool is_layout_complex);
|
||||
/// If the argument `layout_type` is not complex layout and has corresponding complex layout,
|
||||
/// change `layout_type` to corresponding complex and return true; otherwise do nothing and return false.
|
||||
bool convertToComplex(std::string & layout_type) const;
|
||||
|
||||
void registerLayout(const std::string & layout_type, LayoutCreateFunction create_layout, bool is_layout_complex, bool has_layout_complex = true);
|
||||
|
||||
private:
|
||||
struct RegisteredLayout
|
||||
{
|
||||
LayoutCreateFunction layout_create_function;
|
||||
bool is_layout_complex;
|
||||
bool has_layout_complex;
|
||||
};
|
||||
|
||||
using LayoutRegistry = std::unordered_map<std::string, RegisteredLayout>;
|
||||
|
@ -683,7 +683,7 @@ void registerDictionaryFlat(DictionaryFactory & factory)
|
||||
return std::make_unique<FlatDictionary>(dict_id, dict_struct, std::move(source_ptr), configuration);
|
||||
};
|
||||
|
||||
factory.registerLayout("flat", create_layout, false);
|
||||
factory.registerLayout("flat", create_layout, false, false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Common/isLocalAddress.h>
|
||||
#include <Interpreters/Context.h>
|
||||
#include <DataTypes/DataTypeFactory.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -614,6 +615,16 @@ getDictionaryConfigurationFromAST(const ASTCreateQuery & query, ContextPtr conte
|
||||
|
||||
checkPrimaryKey(all_attr_names_and_types, pk_attrs);
|
||||
|
||||
/// If the pk size is 1 and pk's DataType is not number, we should convert to complex.
|
||||
/// NOTE: the data type of Numeric key(simple layout) is UInt64, so if the type is not under UInt64, type casting will lead to precision loss.
|
||||
DataTypePtr first_key_type = DataTypeFactory::instance().get(all_attr_names_and_types.find(pk_attrs[0])->second.type);
|
||||
if ((pk_attrs.size() > 1 || (pk_attrs.size() == 1 && !isNumber(first_key_type)))
|
||||
&& !complex
|
||||
&& DictionaryFactory::instance().convertToComplex(dictionary_layout->layout_type))
|
||||
{
|
||||
complex = true;
|
||||
}
|
||||
|
||||
buildPrimaryKeyConfiguration(xml_document, structure_element, complex, pk_attrs, query.dictionary_attributes_list);
|
||||
|
||||
buildLayoutConfiguration(xml_document, current_dictionary, query.dictionary->dict_settings, dictionary_layout);
|
||||
|
@ -4,4 +4,3 @@
|
||||
2
|
||||
2
|
||||
2
|
||||
2
|
||||
|
@ -9,21 +9,6 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "DROP DICTIONARY IF EXISTS dict1"
|
||||
|
||||
# Simple layout, but with two keys
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
CREATE DICTIONARY dict1
|
||||
(
|
||||
key1 UInt64,
|
||||
key2 UInt64,
|
||||
value String
|
||||
)
|
||||
PRIMARY KEY key1, key2
|
||||
LAYOUT(HASHED())
|
||||
SOURCE(CLICKHOUSE(HOST 'localhost' PORT tcpPort() USER 'default' TABLE 'table_for_dict1' DB '$CLICKHOUSE_DATABASE'))
|
||||
LIFETIME(MIN 1 MAX 10)
|
||||
" 2>&1 | grep -c 'Primary key for simple dictionary must contain exactly one element'
|
||||
|
||||
|
||||
# Simple layout, but with non existing key
|
||||
$CLICKHOUSE_CLIENT -q "
|
||||
CREATE DICTIONARY dict1
|
||||
|
@ -89,7 +89,7 @@ SOURCE(CLICKHOUSE(TABLE test_table_string))
|
||||
LAYOUT(SPARSE_HASHED(SHARDS 10))
|
||||
LIFETIME(0);
|
||||
|
||||
SYSTEM RELOAD DICTIONARY test_dictionary_10_shards_string; -- { serverError CANNOT_PARSE_TEXT }
|
||||
SYSTEM RELOAD DICTIONARY test_dictionary_10_shards_string;
|
||||
|
||||
DROP DICTIONARY test_dictionary_10_shards_string;
|
||||
|
||||
|
@ -0,0 +1,5 @@
|
||||
dict_flat_simple Flat
|
||||
dict_hashed_simple_Decimal128 Hashed
|
||||
dict_hashed_simple_Float32 Hashed
|
||||
dict_hashed_simple_String ComplexKeyHashed
|
||||
dict_hashed_simple_auto_convert ComplexKeyHashed
|
@ -0,0 +1,35 @@
|
||||
DROP DICTIONARY IF EXISTS dict_flat_simple;
|
||||
DROP DICTIONARY IF EXISTS dict_hashed_simple_Decimal128;
|
||||
DROP DICTIONARY IF EXISTS dict_hashed_simple_Float32;
|
||||
DROP DICTIONARY IF EXISTS dict_hashed_simple_String;
|
||||
DROP DICTIONARY IF EXISTS dict_hashed_simple_auto_convert;
|
||||
DROP TABLE IF EXISTS dict_data;
|
||||
|
||||
CREATE TABLE dict_data (v0 UInt16, v1 Int16, v2 Float32, v3 Decimal128(10), v4 String) engine=Memory() AS SELECT number, number%65535, number*1.1, number*1.1, 'foo' FROM numbers(10);;
|
||||
|
||||
CREATE DICTIONARY dict_flat_simple (v0 UInt16, v1 UInt16, v2 UInt16) PRIMARY KEY v0 SOURCE(CLICKHOUSE(TABLE 'dict_data')) LIFETIME(0) LAYOUT(flat());
|
||||
SYSTEM RELOAD DICTIONARY dict_flat_simple;
|
||||
SELECT name, type FROM system.dictionaries WHERE database = currentDatabase() AND name = 'dict_flat_simple';
|
||||
DROP DICTIONARY dict_flat_simple;
|
||||
|
||||
CREATE DICTIONARY dict_hashed_simple_Decimal128 (v3 Decimal128(10), v1 UInt16, v2 Float32) PRIMARY KEY v3 SOURCE(CLICKHOUSE(TABLE 'dict_data')) LIFETIME(0) LAYOUT(hashed());
|
||||
SYSTEM RELOAD DICTIONARY dict_hashed_simple_Decimal128;
|
||||
SELECT name, type FROM system.dictionaries WHERE database = currentDatabase() AND name = 'dict_hashed_simple_Decimal128';
|
||||
DROP DICTIONARY dict_hashed_simple_Decimal128;
|
||||
|
||||
CREATE DICTIONARY dict_hashed_simple_Float32 (v2 Float32, v3 Decimal128(10), v4 String) PRIMARY KEY v2 SOURCE(CLICKHOUSE(TABLE 'dict_data')) LIFETIME(0) LAYOUT(hashed());
|
||||
SYSTEM RELOAD DICTIONARY dict_hashed_simple_Float32;
|
||||
SELECT name, type FROM system.dictionaries WHERE database = currentDatabase() AND name = 'dict_hashed_simple_Float32';
|
||||
DROP DICTIONARY dict_hashed_simple_Float32;
|
||||
|
||||
CREATE DICTIONARY dict_hashed_simple_String (v4 String, v3 Decimal128(10), v2 Float32) PRIMARY KEY v4 SOURCE(CLICKHOUSE(TABLE 'dict_data')) LIFETIME(0) LAYOUT(hashed());
|
||||
SYSTEM RELOAD DICTIONARY dict_hashed_simple_String;
|
||||
SELECT name, type FROM system.dictionaries WHERE database = currentDatabase() AND name = 'dict_hashed_simple_String';
|
||||
DROP DICTIONARY dict_hashed_simple_String;
|
||||
|
||||
CREATE DICTIONARY dict_hashed_simple_auto_convert (v0 UInt16, v1 Int16, v2 UInt16) PRIMARY KEY v0,v1 SOURCE(CLICKHOUSE(TABLE 'dict_data')) LIFETIME(0) LAYOUT(hashed());
|
||||
SYSTEM RELOAD DICTIONARY dict_hashed_simple_auto_convert;
|
||||
SELECT name, type FROM system.dictionaries WHERE database = currentDatabase() AND name = 'dict_hashed_simple_auto_convert';
|
||||
DROP DICTIONARY dict_hashed_simple_auto_convert;
|
||||
|
||||
DROP TABLE dict_data;
|
Loading…
Reference in New Issue
Block a user