diff --git a/dbms/src/Core/Types.h b/dbms/src/Core/Types.h index 1209b1b1d72..813f28a8ce1 100644 --- a/dbms/src/Core/Types.h +++ b/dbms/src/Core/Types.h @@ -170,6 +170,46 @@ template <> struct NativeType { using Type = Int32; }; template <> struct NativeType { using Type = Int64; }; template <> struct NativeType { using Type = Int128; }; +inline const char * getTypeName(TypeIndex idx) +{ + switch (idx) + { + case TypeIndex::Nothing: return "Nothing"; + case TypeIndex::UInt8: return TypeName::get(); + case TypeIndex::UInt16: return TypeName::get(); + case TypeIndex::UInt32: return TypeName::get(); + case TypeIndex::UInt64: return TypeName::get(); + case TypeIndex::UInt128: return "UInt128"; + case TypeIndex::Int8: return TypeName::get(); + case TypeIndex::Int16: return TypeName::get(); + case TypeIndex::Int32: return TypeName::get(); + case TypeIndex::Int64: return TypeName::get(); + case TypeIndex::Int128: return TypeName::get(); + case TypeIndex::Float32: return TypeName::get(); + case TypeIndex::Float64: return TypeName::get(); + case TypeIndex::Date: return "Date"; + case TypeIndex::DateTime: return "DateTime"; + case TypeIndex::String: return TypeName::get(); + case TypeIndex::FixedString: return "FixedString"; + case TypeIndex::Enum8: return "Enum8"; + case TypeIndex::Enum16: return "Enum16"; + case TypeIndex::Decimal32: return TypeName::get(); + case TypeIndex::Decimal64: return TypeName::get(); + case TypeIndex::Decimal128: return TypeName::get(); + case TypeIndex::UUID: return "UUID"; + case TypeIndex::Array: return "Array"; + case TypeIndex::Tuple: return "Tuple"; + case TypeIndex::Set: return "Set"; + case TypeIndex::Interval: return "Interval"; + case TypeIndex::Nullable: return "Nullable"; + case TypeIndex::Function: return "Function"; + case TypeIndex::AggregateFunction: return "AggregateFunction"; + case TypeIndex::LowCardinality: return "LowCardinality"; + } + + __builtin_unreachable(); +} + } /// Specialization of `std::hash` for the Decimal types. diff --git a/dbms/src/Dictionaries/FlatDictionary.cpp b/dbms/src/Dictionaries/FlatDictionary.cpp index f8f4486e09f..628178c8542 100644 --- a/dbms/src/Dictionaries/FlatDictionary.cpp +++ b/dbms/src/Dictionaries/FlatDictionary.cpp @@ -660,10 +660,10 @@ void FlatDictionary::setAttributeValue(Attribute & attribute, const Key id, cons break; case AttributeUnderlyingType::Decimal32: - setAttributeValueImpl(attribute, id, value.get()); + setAttributeValueImpl(attribute, id, value.get()); break; case AttributeUnderlyingType::Decimal64: - setAttributeValueImpl(attribute, id, value.get()); + setAttributeValueImpl(attribute, id, value.get()); break; case AttributeUnderlyingType::Decimal128: setAttributeValueImpl(attribute, id, value.get()); diff --git a/dbms/src/Functions/FunctionsExternalDictionaries.h b/dbms/src/Functions/FunctionsExternalDictionaries.h index 12fa4c1293d..9ff77eb8d92 100644 --- a/dbms/src/Functions/FunctionsExternalDictionaries.h +++ b/dbms/src/Functions/FunctionsExternalDictionaries.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -661,21 +662,77 @@ DECLARE_DICT_GET_TRAITS(UInt32, DataTypeDateTime) DECLARE_DICT_GET_TRAITS(UInt128, DataTypeUUID) #undef DECLARE_DICT_GET_TRAITS +template struct DictGetTraits> +{ + static constexpr bool is_dec32 = std::is_same_v; + static constexpr bool is_dec64 = std::is_same_v; + static constexpr bool is_dec128 = std::is_same_v; + + template + static void get(const DictionaryType * dict, const std::string & name, const PaddedPODArray & ids, + DecimalPaddedPODArray & out) + { + if constexpr (is_dec32) dict->getDecimal32(name, ids, out); + if constexpr (is_dec64) dict->getDecimal64(name, ids, out); + if constexpr (is_dec128) dict->getDecimal128(name, ids, out); + } + + template + static void get(const DictionaryType * dict, const std::string & name, const Columns & key_columns, const DataTypes & key_types, + DecimalPaddedPODArray & out) + { + if constexpr (is_dec32) dict->getDecimal32(name, key_columns, key_types, out); + if constexpr (is_dec64) dict->getDecimal64(name, key_columns, key_types, out); + if constexpr (is_dec128) dict->getDecimal128(name, key_columns, key_types, out); + } + + template + static void get(const DictionaryType * dict, const std::string & name, const PaddedPODArray & ids, + const PaddedPODArray & dates, DecimalPaddedPODArray & out) + { + if constexpr (is_dec32) dict->getDecimal32(name, ids, dates, out); + if constexpr (is_dec64) dict->getDecimal64(name, ids, dates, out); + if constexpr (is_dec128) dict->getDecimal128(name, ids, dates, out); + } + + template + static void getOrDefault(const DictionaryType * dict, const std::string & name, const PaddedPODArray & ids, + const DefaultsType & def, DecimalPaddedPODArray & out) + { + if constexpr (is_dec32) dict->getDecimal32(name, ids, def, out); + if constexpr (is_dec64) dict->getDecimal64(name, ids, def, out); + if constexpr (is_dec128) dict->getDecimal128(name, ids, def, out); + } + + template + static void getOrDefault(const DictionaryType * dict, const std::string & name, const Columns & key_columns, + const DataTypes & key_types, const DefaultsType & def, DecimalPaddedPODArray & out) + { + if constexpr (is_dec32) dict->getDecimal32(name, key_columns, key_types, def, out); + if constexpr (is_dec64) dict->getDecimal64(name, key_columns, key_types, def, out); + if constexpr (is_dec128) dict->getDecimal128(name, key_columns, key_types, def, out); + } +}; + template class FunctionDictGet final : public IFunction { using Type = typename DataType::FieldType; + using ColVec = std::conditional_t, ColumnDecimal, ColumnVector>; public: static constexpr auto name = Name::name; - static FunctionPtr create(const Context & context) + static FunctionPtr create(const Context & context, UInt32 dec_scale = 0) { - return std::make_shared(context.getExternalDictionaries()); + return std::make_shared(context.getExternalDictionaries(), dec_scale); } - FunctionDictGet(const ExternalDictionaries & dictionaries) : dictionaries(dictionaries) {} + FunctionDictGet(const ExternalDictionaries & dictionaries, UInt32 dec_scale = 0) + : dictionaries(dictionaries) + , decimal_scale(dec_scale) + {} String getName() const override { return name; } @@ -719,7 +776,10 @@ private: ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT}; } - return std::make_shared(); + if constexpr (IsDataTypeDecimal) + return std::make_shared(DataType::maxPrecision(), decimal_scale); + else + return std::make_shared(); } bool isDeterministic() const override { return false; } @@ -771,7 +831,11 @@ private: const auto id_col_untyped = block.getByPosition(arguments[2]).column.get(); if (const auto id_col = checkAndGetColumn(id_col_untyped)) { - auto out = ColumnVector::create(id_col->size()); + typename ColVec::MutablePtr out; + if constexpr (IsDataTypeDecimal) + out = ColVec::create(id_col->size(), decimal_scale); + else + out = ColVec::create(id_col->size()); const auto & ids = id_col->getData(); auto & data = out->getData(); DictGetTraits::get(dict, attr_name, ids, data); @@ -780,9 +844,21 @@ private: else if (const auto id_col_const = checkAndGetColumnConst>(id_col_untyped)) { const PaddedPODArray ids(1, id_col_const->getValue()); - PaddedPODArray data(1); - DictGetTraits::get(dict, attr_name, ids, data); - block.getByPosition(result).column = DataTypeNumber().createColumnConst(id_col_const->size(), toField(data.front())); + + if constexpr (IsDataTypeDecimal) + { + DecimalPaddedPODArray data(1, decimal_scale); + DictGetTraits::get(dict, attr_name, ids, data); + block.getByPosition(result).column = + DataType(DataType::maxPrecision(), decimal_scale).createColumnConst( + id_col_const->size(), toField(data.front(), decimal_scale)); + } + else + { + PaddedPODArray data(1); + DictGetTraits::get(dict, attr_name, ids, data); + block.getByPosition(result).column = DataTypeNumber().createColumnConst(id_col_const->size(), toField(data.front())); + } } else throw Exception{"Third argument of function " + getName() + " must be UInt64", ErrorCodes::ILLEGAL_COLUMN}; @@ -818,7 +894,11 @@ private: const auto & key_columns = static_cast(*key_col).getColumnsCopy(); const auto & key_types = static_cast(*key_col_with_type.type).getElements(); - auto out = ColumnVector::create(key_columns.front()->size()); + typename ColVec::MutablePtr out; + if constexpr (IsDataTypeDecimal) + out = ColVec::create(key_columns.front()->size(), decimal_scale); + else + out = ColVec::create(key_columns.front()->size()); auto & data = out->getData(); DictGetTraits::get(dict, attr_name, key_columns, key_types, data); block.getByPosition(result).column = std::move(out); @@ -855,7 +935,11 @@ private: const auto & id_col_values = getColumnDataAsPaddedPODArray(*id_col_untyped, id_col_values_storage); const auto & range_col_values = getColumnDataAsPaddedPODArray(*range_col_untyped, range_col_values_storage); - auto out = ColumnVector::create(id_col_untyped->size()); + typename ColVec::MutablePtr out; + if constexpr (IsDataTypeDecimal) + out = ColVec::create(id_col_untyped->size(), decimal_scale); + else + out = ColVec::create(id_col_untyped->size()); auto & data = out->getData(); DictGetTraits::get(dict, attr_name, id_col_values, range_col_values, data); block.getByPosition(result).column = std::move(out); @@ -864,6 +948,7 @@ private: } const ExternalDictionaries & dictionaries; + UInt32 decimal_scale; }; struct NameDictGetUInt8 { static constexpr auto name = "dictGetUInt8"; }; @@ -879,6 +964,9 @@ struct NameDictGetFloat64 { static constexpr auto name = "dictGetFloat64"; }; struct NameDictGetDate { static constexpr auto name = "dictGetDate"; }; struct NameDictGetDateTime { static constexpr auto name = "dictGetDateTime"; }; struct NameDictGetUUID { static constexpr auto name = "dictGetUUID"; }; +struct NameDictGetDecimal32 { static constexpr auto name = "dictGetDecimal32"; }; +struct NameDictGetDecimal64 { static constexpr auto name = "dictGetDecimal64"; }; +struct NameDictGetDecimal128 { static constexpr auto name = "dictGetDecimal128"; }; using FunctionDictGetUInt8 = FunctionDictGet; using FunctionDictGetUInt16 = FunctionDictGet; @@ -893,22 +981,29 @@ using FunctionDictGetFloat64 = FunctionDictGet; using FunctionDictGetDateTime = FunctionDictGet; using FunctionDictGetUUID = FunctionDictGet; +using FunctionDictGetDecimal32 = FunctionDictGet, NameDictGetDecimal32>; +using FunctionDictGetDecimal64 = FunctionDictGet, NameDictGetDecimal64>; +using FunctionDictGetDecimal128 = FunctionDictGet, NameDictGetDecimal128>; template class FunctionDictGetOrDefault final : public IFunction { using Type = typename DataType::FieldType; + using ColVec = std::conditional_t, ColumnDecimal, ColumnVector>; public: static constexpr auto name = Name::name; - static FunctionPtr create(const Context & context) + static FunctionPtr create(const Context & context, UInt32 dec_scale = 0) { - return std::make_shared(context.getExternalDictionaries()); + return std::make_shared(context.getExternalDictionaries(), dec_scale); } - FunctionDictGetOrDefault(const ExternalDictionaries & dictionaries) : dictionaries(dictionaries) {} + FunctionDictGetOrDefault(const ExternalDictionaries & dictionaries, UInt32 dec_scale = 0) + : dictionaries(dictionaries) + , decimal_scale(dec_scale) + {} String getName() const override { return name; } @@ -935,9 +1030,12 @@ private: if (!checkAndGetDataType(arguments[3].get())) throw Exception{"Illegal type " + arguments[3]->getName() + " of fourth argument of function " + getName() - + ", must be " + String(DataType{}.getFamilyName()) + ".", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT}; + + ", must be " + TypeName::get() + ".", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT}; - return std::make_shared(); + if constexpr (IsDataTypeDecimal) + return std::make_shared(DataType::maxPrecision(), decimal_scale); + else + return std::make_shared(); } bool isDeterministic() const override { return false; } @@ -999,20 +1097,28 @@ private: { const auto default_col_untyped = block.getByPosition(arguments[3]).column.get(); - if (const auto default_col = checkAndGetColumn>(default_col_untyped)) + if (const auto default_col = checkAndGetColumn(default_col_untyped)) { /// vector ids, vector defaults - auto out = ColumnVector::create(id_col->size()); + typename ColVec::MutablePtr out; + if constexpr (IsDataTypeDecimal) + out = ColVec::create(id_col->size(), decimal_scale); + else + out = ColVec::create(id_col->size()); const auto & ids = id_col->getData(); auto & data = out->getData(); const auto & defs = default_col->getData(); DictGetTraits::getOrDefault(dictionary, attr_name, ids, defs, data); block.getByPosition(result).column = std::move(out); } - else if (const auto default_col_const = checkAndGetColumnConst>(default_col_untyped)) + else if (const auto default_col_const = checkAndGetColumnConst(default_col_untyped)) { /// vector ids, const defaults - auto out = ColumnVector::create(id_col->size()); + typename ColVec::MutablePtr out; + if constexpr (IsDataTypeDecimal) + out = ColVec::create(id_col->size(), decimal_scale); + else + out = ColVec::create(id_col->size()); const auto & ids = id_col->getData(); auto & data = out->getData(); const auto def = default_col_const->template getValue(); @@ -1020,7 +1126,7 @@ private: block.getByPosition(result).column = std::move(out); } else - throw Exception{"Fourth argument of function " + getName() + " must be " + String(DataType{}.getFamilyName()), ErrorCodes::ILLEGAL_COLUMN}; + throw Exception{"Fourth argument of function " + getName() + " must be " + TypeName::get(), ErrorCodes::ILLEGAL_COLUMN}; } template @@ -1030,7 +1136,7 @@ private: { const auto default_col_untyped = block.getByPosition(arguments[3]).column.get(); - if (const auto default_col = checkAndGetColumn>(default_col_untyped)) + if (const auto default_col = checkAndGetColumn(default_col_untyped)) { /// const ids, vector defaults const PaddedPODArray ids(1, id_col->getValue()); @@ -1038,24 +1144,48 @@ private: dictionary->has(ids, flags); if (flags.front()) { - PaddedPODArray data(1); - DictGetTraits::getOrDefault(dictionary, attr_name, ids, Type(), data); - block.getByPosition(result).column = DataTypeNumber().createColumnConst(id_col->size(), toField(data.front())); + if constexpr (IsDataTypeDecimal) + { + DecimalPaddedPODArray data(1, decimal_scale); + DictGetTraits::getOrDefault(dictionary, attr_name, ids, Type(), data); + block.getByPosition(result).column = + DataType(DataType::maxPrecision(), decimal_scale).createColumnConst( + id_col->size(), toField(data.front(), decimal_scale)); + } + else + { + PaddedPODArray data(1); + DictGetTraits::getOrDefault(dictionary, attr_name, ids, Type(), data); + block.getByPosition(result).column = DataType().createColumnConst(id_col->size(), toField(data.front())); + } } else block.getByPosition(result).column = block.getByPosition(arguments[3]).column; // reuse the default column } - else if (const auto default_col_const = checkAndGetColumnConst>(default_col_untyped)) + else if (const auto default_col_const = checkAndGetColumnConst(default_col_untyped)) { /// const ids, const defaults const PaddedPODArray ids(1, id_col->getValue()); - PaddedPODArray data(1); - const auto & def = default_col_const->template getValue(); - DictGetTraits::getOrDefault(dictionary, attr_name, ids, def, data); - block.getByPosition(result).column = DataTypeNumber().createColumnConst(id_col->size(), toField(data.front())); + + if constexpr (IsDataTypeDecimal) + { + DecimalPaddedPODArray data(1, decimal_scale); + const auto & def = default_col_const->template getValue(); + DictGetTraits::getOrDefault(dictionary, attr_name, ids, def, data); + block.getByPosition(result).column = + DataType(DataType::maxPrecision(), decimal_scale).createColumnConst( + id_col->size(), toField(data.front(), decimal_scale)); + } + else + { + PaddedPODArray data(1); + const auto & def = default_col_const->template getValue(); + DictGetTraits::getOrDefault(dictionary, attr_name, ids, def, data); + block.getByPosition(result).column = DataType().createColumnConst(id_col->size(), toField(data.front())); + } } else - throw Exception{"Fourth argument of function " + getName() + " must be " + String(DataType{}.getFamilyName()), ErrorCodes::ILLEGAL_COLUMN}; + throw Exception{"Fourth argument of function " + getName() + " must be " + TypeName::get(), ErrorCodes::ILLEGAL_COLUMN}; } template @@ -1082,31 +1212,36 @@ private: /// @todo detect when all key columns are constant const auto rows = key_col->size(); - auto out = ColumnVector::create(rows); + typename ColVec::MutablePtr out; + if constexpr (IsDataTypeDecimal) + out = ColVec::create(rows, decimal_scale); + else + out = ColVec::create(rows); auto & data = out->getData(); const auto default_col_untyped = block.getByPosition(arguments[3]).column.get(); - if (const auto default_col = checkAndGetColumn>(default_col_untyped)) + if (const auto default_col = checkAndGetColumn(default_col_untyped)) { /// const defaults const auto & defs = default_col->getData(); DictGetTraits::getOrDefault(dict, attr_name, key_columns, key_types, defs, data); } - else if (const auto default_col_const = checkAndGetColumnConst>(default_col_untyped)) + else if (const auto default_col_const = checkAndGetColumnConst(default_col_untyped)) { const auto def = default_col_const->template getValue(); DictGetTraits::getOrDefault(dict, attr_name, key_columns, key_types, def, data); } else - throw Exception{"Fourth argument of function " + getName() + " must be " + String(DataType{}.getFamilyName()), ErrorCodes::ILLEGAL_COLUMN}; + throw Exception{"Fourth argument of function " + getName() + " must be " + TypeName::get(), ErrorCodes::ILLEGAL_COLUMN}; block.getByPosition(result).column = std::move(out); return true; } const ExternalDictionaries & dictionaries; + UInt32 decimal_scale; }; struct NameDictGetUInt8OrDefault { static constexpr auto name = "dictGetUInt8OrDefault"; }; @@ -1122,6 +1257,9 @@ struct NameDictGetFloat64OrDefault { static constexpr auto name = "dictGetFloat6 struct NameDictGetDateOrDefault { static constexpr auto name = "dictGetDateOrDefault"; }; struct NameDictGetDateTimeOrDefault { static constexpr auto name = "dictGetDateTimeOrDefault"; }; struct NameDictGetUUIDOrDefault { static constexpr auto name = "dictGetUUIDOrDefault"; }; +struct NameDictGetDecimal32OrDefault { static constexpr auto name = "dictGetDecimal32OrDefault"; }; +struct NameDictGetDecimal64OrDefault { static constexpr auto name = "dictGetDecimal64OrDefault"; }; +struct NameDictGetDecimal128OrDefault { static constexpr auto name = "dictGetDecimal128OrDefault"; }; using FunctionDictGetUInt8OrDefault = FunctionDictGetOrDefault; using FunctionDictGetUInt16OrDefault = FunctionDictGetOrDefault; @@ -1136,21 +1274,10 @@ using FunctionDictGetFloat64OrDefault = FunctionDictGetOrDefault; using FunctionDictGetDateTimeOrDefault = FunctionDictGetOrDefault; using FunctionDictGetUUIDOrDefault = FunctionDictGetOrDefault; +using FunctionDictGetDecimal32OrDefault = FunctionDictGetOrDefault, NameDictGetDecimal32OrDefault>; +using FunctionDictGetDecimal64OrDefault = FunctionDictGetOrDefault, NameDictGetDecimal64OrDefault>; +using FunctionDictGetDecimal128OrDefault = FunctionDictGetOrDefault, NameDictGetDecimal128OrDefault>; -#define FOR_DICT_TYPES(M) \ - M(UInt8) \ - M(UInt16) \ - M(UInt32) \ - M(UInt64) \ - M(Int8) \ - M(Int16) \ - M(Int32) \ - M(Int64) \ - M(Float32) \ - M(Float64) \ - M(Date) \ - M(DateTime) \ - M(UUID) /// This variant of function derives the result type automatically. class FunctionDictGetNoType final : public IFunction @@ -1225,15 +1352,63 @@ private: if (attribute.name == attr_name) { WhichDataType dt = attribute.type; - if (dt.idx == TypeIndex::String) - impl = FunctionDictGetString::create(context); -#define DISPATCH(TYPE) \ - else if (dt.idx == TypeIndex::TYPE) \ - impl = FunctionDictGet::create(context); - FOR_DICT_TYPES(DISPATCH) -#undef DISPATCH - else - throw Exception("Unknown dictGet type", ErrorCodes::UNKNOWN_TYPE); + switch (dt.idx) + { + case TypeIndex::String: + case TypeIndex::FixedString: + impl = FunctionDictGetString::create(context); + break; + case TypeIndex::UInt8: + impl = FunctionDictGetUInt8::create(context); + break; + case TypeIndex::UInt16: + impl = FunctionDictGetUInt16::create(context); + break; + case TypeIndex::UInt32: + impl = FunctionDictGetUInt32::create(context); + break; + case TypeIndex::UInt64: + impl = FunctionDictGetUInt64::create(context); + break; + case TypeIndex::Int8: + impl = FunctionDictGetInt8::create(context); + break; + case TypeIndex::Int16: + impl = FunctionDictGetInt16::create(context); + break; + case TypeIndex::Int32: + impl = FunctionDictGetInt32::create(context); + break; + case TypeIndex::Int64: + impl = FunctionDictGetInt64::create(context); + break; + case TypeIndex::Float32: + impl = FunctionDictGetFloat32::create(context); + break; + case TypeIndex::Float64: + impl = FunctionDictGetFloat64::create(context); + break; + case TypeIndex::Date: + impl = FunctionDictGetDate::create(context); + break; + case TypeIndex::DateTime: + impl = FunctionDictGetDateTime::create(context); + break; + case TypeIndex::UUID: + impl = FunctionDictGetUUID::create(context); + break; + case TypeIndex::Decimal32: + impl = FunctionDictGetDecimal32::create(context, getDecimalScale(*attribute.type)); + break; + case TypeIndex::Decimal64: + impl = FunctionDictGetDecimal64::create(context, getDecimalScale(*attribute.type)); + break; + case TypeIndex::Decimal128: + impl = FunctionDictGetDecimal128::create(context, getDecimalScale(*attribute.type)); + break; + default: + throw Exception("Unknown dictGet type", ErrorCodes::UNKNOWN_TYPE); + } return attribute.type; } } @@ -1312,26 +1487,70 @@ private: const DictionaryAttribute & attribute = structure.attributes[idx]; if (attribute.name == attr_name) { + auto arg_type = arguments[3].type; WhichDataType dt = attribute.type; - if (dt.idx == TypeIndex::String) + + if ((arg_type->getTypeId() != dt.idx) || (dt.isStringOrFixedString() && !isString(arg_type))) + throw Exception{"Illegal type " + arg_type->getName() + " of fourth argument of function " + getName() + + ", must be " + getTypeName(dt.idx) + ".", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT}; + + switch (dt.idx) { - if (!isString(arguments[3].type)) - throw Exception{"Illegal type " + arguments[3].type->getName() + " of fourth argument of function " + getName() + - ", must be String.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT}; - impl = FunctionDictGetStringOrDefault::create(context); + case TypeIndex::String: + impl = FunctionDictGetStringOrDefault::create(context); + break; + case TypeIndex::UInt8: + impl = FunctionDictGetUInt8OrDefault::create(context); + break; + case TypeIndex::UInt16: + impl = FunctionDictGetUInt16OrDefault::create(context); + break; + case TypeIndex::UInt32: + impl = FunctionDictGetUInt32OrDefault::create(context); + break; + case TypeIndex::UInt64: + impl = FunctionDictGetUInt64OrDefault::create(context); + break; + case TypeIndex::Int8: + impl = FunctionDictGetInt8OrDefault::create(context); + break; + case TypeIndex::Int16: + impl = FunctionDictGetInt16OrDefault::create(context); + break; + case TypeIndex::Int32: + impl = FunctionDictGetInt32OrDefault::create(context); + break; + case TypeIndex::Int64: + impl = FunctionDictGetInt64OrDefault::create(context); + break; + case TypeIndex::Float32: + impl = FunctionDictGetFloat32OrDefault::create(context); + break; + case TypeIndex::Float64: + impl = FunctionDictGetFloat64OrDefault::create(context); + break; + case TypeIndex::Date: + impl = FunctionDictGetDateOrDefault::create(context); + break; + case TypeIndex::DateTime: + impl = FunctionDictGetDateTimeOrDefault::create(context); + break; + case TypeIndex::UUID: + impl = FunctionDictGetUUIDOrDefault::create(context); + break; + case TypeIndex::Decimal32: + impl = FunctionDictGetDecimal32OrDefault::create(context, getDecimalScale(*attribute.type)); + break; + case TypeIndex::Decimal64: + impl = FunctionDictGetDecimal64OrDefault::create(context, getDecimalScale(*attribute.type)); + break; + case TypeIndex::Decimal128: + impl = FunctionDictGetDecimal128OrDefault::create(context, getDecimalScale(*attribute.type)); + break; + default: + throw Exception("Unknown dictGetOrDefault type", ErrorCodes::UNKNOWN_TYPE); } -#define DISPATCH(TYPE) \ - else if (dt.idx == TypeIndex::TYPE) \ - { \ - if (!checkAndGetDataType(arguments[3].type.get())) \ - throw Exception{"Illegal type " + arguments[3].type->getName() + " of fourth argument of function " + getName() \ - + ", must be " + String(DataType##TYPE{}.getFamilyName()) + ".", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT}; \ - impl = FunctionDictGetOrDefault::create(context); \ - } - FOR_DICT_TYPES(DISPATCH) -#undef DISPATCH - else - throw Exception("Unknown dictGetOrDefault type", ErrorCodes::UNKNOWN_TYPE); + return attribute.type; } } diff --git a/dbms/tests/clickhouse-test-server b/dbms/tests/clickhouse-test-server index 256a2f157cb..799c070d0ff 100755 --- a/dbms/tests/clickhouse-test-server +++ b/dbms/tests/clickhouse-test-server @@ -57,6 +57,9 @@ if [ "$DATA_DIR_PATTERN" != "$DATA_DIR" ]; then export CLICKHOUSE_CONFIG=$DATA_DIR/etc/server-config.xml cp $CLICKHOUSE_CONFIG_USERS $DATA_DIR/etc cp -R -L $CLICKHOUSE_CONFIG_USERS_D $DATA_DIR/etc + cat ${CONFIG_SERVER_DIR}/ints_dictionary.xml | sed -e s!9000!$CLICKHOUSE_PORT_TCP! > $DATA_DIR/etc/ints_dictionary.xml + cat ${CONFIG_SERVER_DIR}/strings_dictionary.xml | sed -e s!9000!$CLICKHOUSE_PORT_TCP! > $DATA_DIR/etc/strings_dictionary.xml + cat ${CONFIG_SERVER_DIR}/decimals_dictionary.xml | sed -e s!9000!$CLICKHOUSE_PORT_TCP! > $DATA_DIR/etc/decimals_dictionary.xml fi CLICKHOUSE_EXTRACT_CONFIG=${CLICKHOUSE_EXTRACT_CONFIG:="${CLICKHOUSE_EXTRACT} --config=$CLICKHOUSE_CONFIG"} diff --git a/dbms/tests/decimals_dictionary.xml b/dbms/tests/decimals_dictionary.xml new file mode 120000 index 00000000000..a6e55eca649 --- /dev/null +++ b/dbms/tests/decimals_dictionary.xml @@ -0,0 +1 @@ +../../docker/test/stateless/decimals_dictionary.xml \ No newline at end of file diff --git a/dbms/tests/ints_dictionary.xml b/dbms/tests/ints_dictionary.xml new file mode 120000 index 00000000000..bd55a28b4c6 --- /dev/null +++ b/dbms/tests/ints_dictionary.xml @@ -0,0 +1 @@ +../../docker/test/stateless/ints_dictionary.xml \ No newline at end of file diff --git a/dbms/tests/queries/0_stateless/00080_show_tables_and_system_tables.sql b/dbms/tests/queries/0_stateless/00080_show_tables_and_system_tables.sql index a6261b69967..d3295f086e8 100644 --- a/dbms/tests/queries/0_stateless/00080_show_tables_and_system_tables.sql +++ b/dbms/tests/queries/0_stateless/00080_show_tables_and_system_tables.sql @@ -30,5 +30,5 @@ CREATE DATABASE test_DatabaseDictionary ENGINE = Dictionary; SELECT sum(ignore(*, metadata_modification_time, engine_full, create_table_query)) FROM system.tables; -DROP DATABASE test_DatabaseDictionary; +DROP DATABASE test_DatabaseDictionary; -- { serverError 48 } DROP DATABASE test_DatabaseMemory; diff --git a/dbms/tests/queries/0_stateless/00950_dict_get.reference b/dbms/tests/queries/0_stateless/00950_dict_get.reference new file mode 100644 index 00000000000..fabfda8425f --- /dev/null +++ b/dbms/tests/queries/0_stateless/00950_dict_get.reference @@ -0,0 +1,45 @@ +dictGet flat_ints 1 1 1 1 1 1 1 1 1 +dictGetOrDefault flat_ints 1 1 1 1 1 1 1 1 1 +dictGetOrDefault flat_ints 0 42 42 42 42 42 42 42 42 +dictGet hashed_ints 1 1 1 1 1 1 1 1 1 +dictGetOrDefault hashed_ints 1 1 1 1 1 1 1 1 1 +dictGetOrDefault hashed_ints 0 42 42 42 42 42 42 42 42 +dictGet cache_ints 1 1 1 1 1 1 1 1 1 +dictGetOrDefault cache_ints 1 1 1 1 1 1 1 1 1 +dictGetOrDefault cache_ints 0 42 42 42 42 42 42 42 42 +dictGet complex_hashed_ints (1) 1 1 1 1 1 1 1 1 +dictGetOrDefault complex_hashed_ints (1) 1 1 1 1 1 1 1 1 +dictGetOrDefault complex_hashed_ints (0) 42 42 42 42 42 42 42 42 +dictGet complex_cache_ints (1) 1 1 1 1 1 1 1 1 +dictGetOrDefault complex_cache_ints (1) 1 1 1 1 1 1 1 1 +dictGetOrDefault complex_cache_ints (0) 42 42 42 42 42 42 42 42 +dictGet flat_strings 1 1 +dictGetOrDefault flat_strings 1 1 +dictGetOrDefault flat_strings 0 * +dictGet hashed_strings 1 1 +dictGetOrDefault hashed_strings 1 1 +dictGetOrDefault hashed_strings 0 * +dictGet cache_strings 1 1 +dictGetOrDefault cache_strings 1 1 +dictGetOrDefault cache_strings 0 * +dictGet complex_hashed_strings 1 1 +dictGetOrDefault complex_hashed_strings 1 1 +dictGetOrDefault complex_hashed_strings 0 * +dictGet complex_cache_strings 1 1 +dictGetOrDefault complex_cache_strings 1 1 +dictGetOrDefault complex_cache_strings 0 * +dictGet flat_decimals 1 1.0000 1.000000 1.0 +dictGetOrDefault flat_decimals 1 1.0000 1.000000 1.0 +dictGetOrDefault flat_decimals 0 42.0000 42.000000 42.0 +dictGet hashed_decimals 1 1.0000 1.000000 1.0 +dictGetOrDefault hashed_decimals 1 1.0000 1.000000 1.0 +dictGetOrDefault hashed_decimals 0 42.0000 42.000000 42.0 +dictGet cache_decimals 1 1.0000 1.000000 1.0 +dictGetOrDefault cache_decimals 1 1.0000 1.000000 1.0 +dictGetOrDefault cache_decimals 0 42.0000 42.000000 42.0 +dictGet complex_hashed_decimals (1) 1.0000 1.000000 1.0 +dictGetOrDefault complex_hashed_decimals (1) 1.0000 1.000000 1.0 +dictGetOrDefault complex_hashed_decimals (0) 42.0000 42.000000 42.0 +dictGet complex_cache_decimals (1) 1.0000 1.000000 1.0 +dictGetOrDefault complex_cache_decimals (1) 1.0000 1.000000 1.0 +dictGetOrDefault complex_cache_decimals (0) 42.0000 42.000000 42.0 diff --git a/dbms/tests/queries/0_stateless/00950_dict_get.sql b/dbms/tests/queries/0_stateless/00950_dict_get.sql new file mode 100644 index 00000000000..b3b5e7c47f3 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00950_dict_get.sql @@ -0,0 +1,245 @@ +use default; +drop table if exists ints; +drop table if exists strings; +drop table if exists decimals; + +create table ints (key UInt64, i8 Int8, i16 Int16, i32 Int32, i64 Int64, u8 UInt8, u16 UInt16, u32 UInt32, u64 UInt64) Engine = Memory; +create table strings (key UInt64, str String) Engine = Memory; +create table decimals (key UInt64, d32 Decimal32(4), d64 Decimal64(6), d128 Decimal128(1)) Engine = Memory; + +insert into ints values (1, 1, 1, 1, 1, 1, 1, 1, 1); +insert into strings values (1, '1'); +insert into decimals values (1, 1, 1, 1); + +select 'dictGet', 'flat_ints' as dict_name, toUInt64(1) as k, + dictGet(dict_name, 'i8', k), + dictGet(dict_name, 'i16', k), + dictGet(dict_name, 'i32', k), + dictGet(dict_name, 'i64', k), + dictGet(dict_name, 'u8', k), + dictGet(dict_name, 'u16', k), + dictGet(dict_name, 'u32', k), + dictGet(dict_name, 'u64', k); +select 'dictGetOrDefault', 'flat_ints' as dict_name, toUInt64(1) as k, + dictGetOrDefault(dict_name, 'i8', k, toInt8(42)), + dictGetOrDefault(dict_name, 'i16', k, toInt16(42)), + dictGetOrDefault(dict_name, 'i32', k, toInt32(42)), + dictGetOrDefault(dict_name, 'i64', k, toInt64(42)), + dictGetOrDefault(dict_name, 'u8', k, toUInt8(42)), + dictGetOrDefault(dict_name, 'u16', k, toUInt16(42)), + dictGetOrDefault(dict_name, 'u32', k, toUInt32(42)), + dictGetOrDefault(dict_name, 'u64', k, toUInt64(42)); +select 'dictGetOrDefault', 'flat_ints' as dict_name, toUInt64(0) as k, + dictGetOrDefault(dict_name, 'i8', k, toInt8(42)), + dictGetOrDefault(dict_name, 'i16', k, toInt16(42)), + dictGetOrDefault(dict_name, 'i32', k, toInt32(42)), + dictGetOrDefault(dict_name, 'i64', k, toInt64(42)), + dictGetOrDefault(dict_name, 'u8', k, toUInt8(42)), + dictGetOrDefault(dict_name, 'u16', k, toUInt16(42)), + dictGetOrDefault(dict_name, 'u32', k, toUInt32(42)), + dictGetOrDefault(dict_name, 'u64', k, toUInt64(42)); + +select 'dictGet', 'hashed_ints' as dict_name, toUInt64(1) as k, + dictGet(dict_name, 'i8', k), + dictGet(dict_name, 'i16', k), + dictGet(dict_name, 'i32', k), + dictGet(dict_name, 'i64', k), + dictGet(dict_name, 'u8', k), + dictGet(dict_name, 'u16', k), + dictGet(dict_name, 'u32', k), + dictGet(dict_name, 'u64', k); +select 'dictGetOrDefault', 'hashed_ints' as dict_name, toUInt64(1) as k, + dictGetOrDefault(dict_name, 'i8', k, toInt8(42)), + dictGetOrDefault(dict_name, 'i16', k, toInt16(42)), + dictGetOrDefault(dict_name, 'i32', k, toInt32(42)), + dictGetOrDefault(dict_name, 'i64', k, toInt64(42)), + dictGetOrDefault(dict_name, 'u8', k, toUInt8(42)), + dictGetOrDefault(dict_name, 'u16', k, toUInt16(42)), + dictGetOrDefault(dict_name, 'u32', k, toUInt32(42)), + dictGetOrDefault(dict_name, 'u64', k, toUInt64(42)); +select 'dictGetOrDefault', 'hashed_ints' as dict_name, toUInt64(0) as k, + dictGetOrDefault(dict_name, 'i8', k, toInt8(42)), + dictGetOrDefault(dict_name, 'i16', k, toInt16(42)), + dictGetOrDefault(dict_name, 'i32', k, toInt32(42)), + dictGetOrDefault(dict_name, 'i64', k, toInt64(42)), + dictGetOrDefault(dict_name, 'u8', k, toUInt8(42)), + dictGetOrDefault(dict_name, 'u16', k, toUInt16(42)), + dictGetOrDefault(dict_name, 'u32', k, toUInt32(42)), + dictGetOrDefault(dict_name, 'u64', k, toUInt64(42)); + +select 'dictGet', 'cache_ints' as dict_name, toUInt64(1) as k, + dictGet(dict_name, 'i8', k), + dictGet(dict_name, 'i16', k), + dictGet(dict_name, 'i32', k), + dictGet(dict_name, 'i64', k), + dictGet(dict_name, 'u8', k), + dictGet(dict_name, 'u16', k), + dictGet(dict_name, 'u32', k), + dictGet(dict_name, 'u64', k); +select 'dictGetOrDefault', 'cache_ints' as dict_name, toUInt64(1) as k, + dictGetOrDefault(dict_name, 'i8', k, toInt8(42)), + dictGetOrDefault(dict_name, 'i16', k, toInt16(42)), + dictGetOrDefault(dict_name, 'i32', k, toInt32(42)), + dictGetOrDefault(dict_name, 'i64', k, toInt64(42)), + dictGetOrDefault(dict_name, 'u8', k, toUInt8(42)), + dictGetOrDefault(dict_name, 'u16', k, toUInt16(42)), + dictGetOrDefault(dict_name, 'u32', k, toUInt32(42)), + dictGetOrDefault(dict_name, 'u64', k, toUInt64(42)); +select 'dictGetOrDefault', 'cache_ints' as dict_name, toUInt64(0) as k, + dictGetOrDefault(dict_name, 'i8', k, toInt8(42)), + dictGetOrDefault(dict_name, 'i16', k, toInt16(42)), + dictGetOrDefault(dict_name, 'i32', k, toInt32(42)), + dictGetOrDefault(dict_name, 'i64', k, toInt64(42)), + dictGetOrDefault(dict_name, 'u8', k, toUInt8(42)), + dictGetOrDefault(dict_name, 'u16', k, toUInt16(42)), + dictGetOrDefault(dict_name, 'u32', k, toUInt32(42)), + dictGetOrDefault(dict_name, 'u64', k, toUInt64(42)); + +select 'dictGet', 'complex_hashed_ints' as dict_name, tuple(toUInt64(1)) as k, + dictGet(dict_name, 'i8', k), + dictGet(dict_name, 'i16', k), + dictGet(dict_name, 'i32', k), + dictGet(dict_name, 'i64', k), + dictGet(dict_name, 'u8', k), + dictGet(dict_name, 'u16', k), + dictGet(dict_name, 'u32', k), + dictGet(dict_name, 'u64', k); +select 'dictGetOrDefault', 'complex_hashed_ints' as dict_name, tuple(toUInt64(1)) as k, + dictGetOrDefault(dict_name, 'i8', k, toInt8(42)), + dictGetOrDefault(dict_name, 'i16', k, toInt16(42)), + dictGetOrDefault(dict_name, 'i32', k, toInt32(42)), + dictGetOrDefault(dict_name, 'i64', k, toInt64(42)), + dictGetOrDefault(dict_name, 'u8', k, toUInt8(42)), + dictGetOrDefault(dict_name, 'u16', k, toUInt16(42)), + dictGetOrDefault(dict_name, 'u32', k, toUInt32(42)), + dictGetOrDefault(dict_name, 'u64', k, toUInt64(42)); +select 'dictGetOrDefault', 'complex_hashed_ints' as dict_name, tuple(toUInt64(0)) as k, + dictGetOrDefault(dict_name, 'i8', k, toInt8(42)), + dictGetOrDefault(dict_name, 'i16', k, toInt16(42)), + dictGetOrDefault(dict_name, 'i32', k, toInt32(42)), + dictGetOrDefault(dict_name, 'i64', k, toInt64(42)), + dictGetOrDefault(dict_name, 'u8', k, toUInt8(42)), + dictGetOrDefault(dict_name, 'u16', k, toUInt16(42)), + dictGetOrDefault(dict_name, 'u32', k, toUInt32(42)), + dictGetOrDefault(dict_name, 'u64', k, toUInt64(42)); + +select 'dictGet', 'complex_cache_ints' as dict_name, tuple(toUInt64(1)) as k, + dictGet(dict_name, 'i8', k), + dictGet(dict_name, 'i16', k), + dictGet(dict_name, 'i32', k), + dictGet(dict_name, 'i64', k), + dictGet(dict_name, 'u8', k), + dictGet(dict_name, 'u16', k), + dictGet(dict_name, 'u32', k), + dictGet(dict_name, 'u64', k); +select 'dictGetOrDefault', 'complex_cache_ints' as dict_name, tuple(toUInt64(1)) as k, + dictGetOrDefault(dict_name, 'i8', k, toInt8(42)), + dictGetOrDefault(dict_name, 'i16', k, toInt16(42)), + dictGetOrDefault(dict_name, 'i32', k, toInt32(42)), + dictGetOrDefault(dict_name, 'i64', k, toInt64(42)), + dictGetOrDefault(dict_name, 'u8', k, toUInt8(42)), + dictGetOrDefault(dict_name, 'u16', k, toUInt16(42)), + dictGetOrDefault(dict_name, 'u32', k, toUInt32(42)), + dictGetOrDefault(dict_name, 'u64', k, toUInt64(42)); +select 'dictGetOrDefault', 'complex_cache_ints' as dict_name, tuple(toUInt64(0)) as k, + dictGetOrDefault(dict_name, 'i8', k, toInt8(42)), + dictGetOrDefault(dict_name, 'i16', k, toInt16(42)), + dictGetOrDefault(dict_name, 'i32', k, toInt32(42)), + dictGetOrDefault(dict_name, 'i64', k, toInt64(42)), + dictGetOrDefault(dict_name, 'u8', k, toUInt8(42)), + dictGetOrDefault(dict_name, 'u16', k, toUInt16(42)), + dictGetOrDefault(dict_name, 'u32', k, toUInt32(42)), + dictGetOrDefault(dict_name, 'u64', k, toUInt64(42)); + +-- + +select 'dictGet', 'flat_strings' as dict_name, toUInt64(1) as k, dictGet(dict_name, 'str', k); +select 'dictGetOrDefault', 'flat_strings' as dict_name, toUInt64(1) as k, dictGetOrDefault(dict_name, 'str', k, '*'); +select 'dictGetOrDefault', 'flat_strings' as dict_name, toUInt64(0) as k, dictGetOrDefault(dict_name, 'str', k, '*'); + +select 'dictGet', 'hashed_strings' as dict_name, toUInt64(1) as k, dictGet(dict_name, 'str', k); +select 'dictGetOrDefault', 'hashed_strings' as dict_name, toUInt64(1) as k, dictGetOrDefault(dict_name, 'str', k, '*'); +select 'dictGetOrDefault', 'hashed_strings' as dict_name, toUInt64(0) as k, dictGetOrDefault(dict_name, 'str', k, '*'); + +select 'dictGet', 'cache_strings' as dict_name, toUInt64(1) as k, dictGet(dict_name, 'str', k); +select 'dictGetOrDefault', 'cache_strings' as dict_name, toUInt64(1) as k, dictGetOrDefault(dict_name, 'str', k, '*'); +select 'dictGetOrDefault', 'cache_strings' as dict_name, toUInt64(0) as k, dictGetOrDefault(dict_name, 'str', k, '*'); + +select 'dictGet', 'complex_hashed_strings' as dict_name, toUInt64(1) as k, dictGet(dict_name, 'str', tuple(k)); +select 'dictGetOrDefault', 'complex_hashed_strings' as dict_name, toUInt64(1) as k, dictGetOrDefault(dict_name, 'str', tuple(k), '*'); +select 'dictGetOrDefault', 'complex_hashed_strings' as dict_name, toUInt64(0) as k, dictGetOrDefault(dict_name, 'str', tuple(k), '*'); + +select 'dictGet', 'complex_cache_strings' as dict_name, toUInt64(1) as k, dictGet(dict_name, 'str', tuple(k)); +select 'dictGetOrDefault', 'complex_cache_strings' as dict_name, toUInt64(1) as k, dictGetOrDefault(dict_name, 'str', tuple(k), '*'); +select 'dictGetOrDefault', 'complex_cache_strings' as dict_name, toUInt64(0) as k, dictGetOrDefault(dict_name, 'str', tuple(k), '*'); + +-- + +select 'dictGet', 'flat_decimals' as dict_name, toUInt64(1) as k, + dictGet(dict_name, 'd32', k), + dictGet(dict_name, 'd64', k), + dictGet(dict_name, 'd128', k); +select 'dictGetOrDefault', 'flat_decimals' as dict_name, toUInt64(1) as k, + dictGetOrDefault(dict_name, 'd32', k, toDecimal32(42, 4)), + dictGetOrDefault(dict_name, 'd64', k, toDecimal64(42, 6)), + dictGetOrDefault(dict_name, 'd128', k, toDecimal128(42, 1)); +select 'dictGetOrDefault', 'flat_decimals' as dict_name, toUInt64(0) as k, + dictGetOrDefault(dict_name, 'd32', k, toDecimal32(42, 4)), + dictGetOrDefault(dict_name, 'd64', k, toDecimal64(42, 6)), + dictGetOrDefault(dict_name, 'd128', k, toDecimal128(42, 1)); + +select 'dictGet', 'hashed_decimals' as dict_name, toUInt64(1) as k, + dictGet(dict_name, 'd32', k), + dictGet(dict_name, 'd64', k), + dictGet(dict_name, 'd128', k); +select 'dictGetOrDefault', 'hashed_decimals' as dict_name, toUInt64(1) as k, + dictGetOrDefault(dict_name, 'd32', k, toDecimal32(42, 4)), + dictGetOrDefault(dict_name, 'd64', k, toDecimal64(42, 6)), + dictGetOrDefault(dict_name, 'd128', k, toDecimal128(42, 1)); +select 'dictGetOrDefault', 'hashed_decimals' as dict_name, toUInt64(0) as k, + dictGetOrDefault(dict_name, 'd32', k, toDecimal32(42, 4)), + dictGetOrDefault(dict_name, 'd64', k, toDecimal64(42, 6)), + dictGetOrDefault(dict_name, 'd128', k, toDecimal128(42, 1)); + +select 'dictGet', 'cache_decimals' as dict_name, toUInt64(1) as k, + dictGet(dict_name, 'd32', k), + dictGet(dict_name, 'd64', k), + dictGet(dict_name, 'd128', k); +select 'dictGetOrDefault', 'cache_decimals' as dict_name, toUInt64(1) as k, + dictGetOrDefault(dict_name, 'd32', k, toDecimal32(42, 4)), + dictGetOrDefault(dict_name, 'd64', k, toDecimal64(42, 6)), + dictGetOrDefault(dict_name, 'd128', k, toDecimal128(42, 1)); +select 'dictGetOrDefault', 'cache_decimals' as dict_name, toUInt64(0) as k, + dictGetOrDefault(dict_name, 'd32', k, toDecimal32(42, 4)), + dictGetOrDefault(dict_name, 'd64', k, toDecimal64(42, 6)), + dictGetOrDefault(dict_name, 'd128', k, toDecimal128(42, 1)); + +select 'dictGet', 'complex_hashed_decimals' as dict_name, tuple(toUInt64(1)) as k, + dictGet(dict_name, 'd32', k), + dictGet(dict_name, 'd64', k), + dictGet(dict_name, 'd128', k); +select 'dictGetOrDefault', 'complex_hashed_decimals' as dict_name, tuple(toUInt64(1)) as k, + dictGetOrDefault(dict_name, 'd32', k, toDecimal32(42, 4)), + dictGetOrDefault(dict_name, 'd64', k, toDecimal64(42, 6)), + dictGetOrDefault(dict_name, 'd128', k, toDecimal128(42, 1)); +select 'dictGetOrDefault', 'complex_hashed_decimals' as dict_name, tuple(toUInt64(0)) as k, + dictGetOrDefault(dict_name, 'd32', k, toDecimal32(42, 4)), + dictGetOrDefault(dict_name, 'd64', k, toDecimal64(42, 6)), + dictGetOrDefault(dict_name, 'd128', k, toDecimal128(42, 1)); + +select 'dictGet', 'complex_cache_decimals' as dict_name, tuple(toUInt64(1)) as k, + dictGet(dict_name, 'd32', k), + dictGet(dict_name, 'd64', k), + dictGet(dict_name, 'd128', k); +select 'dictGetOrDefault', 'complex_cache_decimals' as dict_name, tuple(toUInt64(1)) as k, + dictGetOrDefault(dict_name, 'd32', k, toDecimal32(42, 4)), + dictGetOrDefault(dict_name, 'd64', k, toDecimal64(42, 6)), + dictGetOrDefault(dict_name, 'd128', k, toDecimal128(42, 1)); +select 'dictGetOrDefault', 'complex_cache_decimals' as dict_name, tuple(toUInt64(0)) as k, + dictGetOrDefault(dict_name, 'd32', k, toDecimal32(42, 4)), + dictGetOrDefault(dict_name, 'd64', k, toDecimal64(42, 6)), + dictGetOrDefault(dict_name, 'd128', k, toDecimal128(42, 1)); + +drop table ints; +drop table strings; +drop table decimals; diff --git a/dbms/tests/server-test.xml b/dbms/tests/server-test.xml index c936f15bf52..c20d34cce3f 100644 --- a/dbms/tests/server-test.xml +++ b/dbms/tests/server-test.xml @@ -110,7 +110,7 @@ query_log
7500 - dictionaries/dictionary_*.xml + *_dictionary.xml diff --git a/dbms/tests/strings_dictionary.xml b/dbms/tests/strings_dictionary.xml new file mode 120000 index 00000000000..b7650ec4e24 --- /dev/null +++ b/dbms/tests/strings_dictionary.xml @@ -0,0 +1 @@ +../../docker/test/stateless/strings_dictionary.xml \ No newline at end of file diff --git a/docker/test/stateless/Dockerfile b/docker/test/stateless/Dockerfile index 325745984d5..4685ece6dd9 100644 --- a/docker/test/stateless/Dockerfile +++ b/docker/test/stateless/Dockerfile @@ -34,6 +34,9 @@ COPY listen.xml /etc/clickhouse-server/config.d/listen.xml COPY part_log.xml /etc/clickhouse-server/config.d/part_log.xml COPY log_queries.xml /etc/clickhouse-server/users.d/log_queries.xml COPY readonly.xml /etc/clickhouse-server/users.d/readonly.xml +COPY ints_dictionary.xml /etc/clickhouse-server/ints_dictionary.xml +COPY strings_dictionary.xml /etc/clickhouse-server/strings_dictionary.xml +COPY decimals_dictionary.xml /etc/clickhouse-server/decimals_dictionary.xml CMD dpkg -i package_folder/clickhouse-common-static_*.deb; \ dpkg -i package_folder/clickhouse-common-static-dbg_*.deb; \ diff --git a/docker/test/stateless/decimals_dictionary.xml b/docker/test/stateless/decimals_dictionary.xml new file mode 100644 index 00000000000..0ef8f58ff12 --- /dev/null +++ b/docker/test/stateless/decimals_dictionary.xml @@ -0,0 +1,197 @@ + + + flat_decimals + + + localhost + 9000 + default + + + decimals
+
+ + 0 + + + + + + key + + + d32 + Decimal32(4) + 0 + + + d64 + Decimal64(6) + 0 + + + d128 + Decimal128(1) + 0 + + +
+ + + hashed_decimals + + + localhost + 9000 + default + + + decimals
+
+ + 0 + + + + + + key + + + d32 + Decimal32(4) + 0 + + + d64 + Decimal64(6) + 0 + + + d128 + Decimal128(1) + 0 + + +
+ + + cache_decimals + + + localhost + 9000 + default + + + decimals
+
+ + 0 + + 1000 + + + + key + + + d32 + Decimal32(4) + 0 + + + d64 + Decimal64(6) + 0 + + + d128 + Decimal128(1) + 0 + + +
+ + + complex_hashed_decimals + + + localhost + 9000 + default + + + decimals
+
+ + 0 + + + + + + + key + UInt64 + + + + d32 + Decimal32(4) + 0 + + + d64 + Decimal64(6) + 0 + + + d128 + Decimal128(1) + 0 + + +
+ + + complex_cache_decimals + + + localhost + 9000 + default + + + decimals
+
+ + 0 + + 1000 + + + + + key + UInt64 + + + + d32 + Decimal32(4) + 0 + + + d64 + Decimal64(6) + 0 + + + d128 + Decimal128(1) + 0 + + +
+
diff --git a/docker/test/stateless/ints_dictionary.xml b/docker/test/stateless/ints_dictionary.xml new file mode 100644 index 00000000000..6556c49ce99 --- /dev/null +++ b/docker/test/stateless/ints_dictionary.xml @@ -0,0 +1,322 @@ + + + flat_ints + + + localhost + 9000 + default + + + ints
+
+ + 0 + + + + + + key + + + i8 + Int8 + 0 + + + i16 + Int16 + 0 + + + i32 + Int32 + 0 + + + i64 + Int64 + 0 + + + u8 + UInt8 + 0 + + + u16 + UInt16 + 0 + + + u32 + UInt32 + 0 + + + u64 + UInt64 + 0 + + +
+ + + hashed_ints + + + localhost + 9000 + default + + + ints
+
+ + 0 + + + + + + key + + + i8 + Int8 + 0 + + + i16 + Int16 + 0 + + + i32 + Int32 + 0 + + + i64 + Int64 + 0 + + + u8 + UInt8 + 0 + + + u16 + UInt16 + 0 + + + u32 + UInt32 + 0 + + + u64 + UInt64 + 0 + + +
+ + + cache_ints + + + localhost + 9000 + default + + + ints
+
+ + 0 + + 1000 + + + + key + + + i8 + Int8 + 0 + + + i16 + Int16 + 0 + + + i32 + Int32 + 0 + + + i64 + Int64 + 0 + + + u8 + UInt8 + 0 + + + u16 + UInt16 + 0 + + + u32 + UInt32 + 0 + + + u64 + UInt64 + 0 + + +
+ + + complex_hashed_ints + + + localhost + 9000 + default + + + ints
+
+ + 0 + + + + + + + key + UInt64 + + + + i8 + Int8 + 0 + + + i16 + Int16 + 0 + + + i32 + Int32 + 0 + + + i64 + Int64 + 0 + + + u8 + UInt8 + 0 + + + u16 + UInt16 + 0 + + + u32 + UInt32 + 0 + + + u64 + UInt64 + 0 + + +
+ + + complex_cache_ints + + + localhost + 9000 + default + + + ints
+
+ + 0 + + 1000 + + + + + key + UInt64 + + + + i8 + Int8 + 0 + + + i16 + Int16 + 0 + + + i32 + Int32 + 0 + + + i64 + Int64 + 0 + + + u8 + UInt8 + 0 + + + u16 + UInt16 + 0 + + + u32 + UInt32 + 0 + + + u64 + UInt64 + 0 + + +
+
diff --git a/docker/test/stateless/strings_dictionary.xml b/docker/test/stateless/strings_dictionary.xml new file mode 100644 index 00000000000..1a01ebbbbe0 --- /dev/null +++ b/docker/test/stateless/strings_dictionary.xml @@ -0,0 +1,209 @@ + + + flat_strings + + + localhost + 9000 + default + + + strings
+
+ + 0 + + + + + + key + + + str + String + + + +
+ + + hashed_strings + + + localhost + 9000 + default + + + strings
+
+ + 0 + + + + + + key + + + str + String + + + +
+ + + cache_strings + + + localhost + 9000 + default + + + strings
+
+ + 0 + + 1000 + + + + key + + + str + String + + + +
+ + + complex_hashed_strings + + + localhost + 9000 + default + + + strings
+
+ + 0 + + + + + + + key + UInt64 + + + + str + String + + + +
+ + + complex_cache_strings + + + localhost + 9000 + default + + + strings
+
+ + 0 + + 1000 + + + + + key + UInt64 + + + + str + String + + + +
+ + + complex_hashed_strings_key + + + localhost + 9000 + default + + + strings
+
+ + 0 + + + + + + + str + String + + + + key + UInt64 + 0 + + +
+ + + complex_cache_strings_key + + + localhost + 9000 + default + + + strings
+
+ + 0 + + 1000 + + + + + str + String + + + + key + UInt64 + 0 + + +
+