diff --git a/src/Dictionaries/SSDComplexKeyCacheDictionary.cpp b/src/Dictionaries/SSDComplexKeyCacheDictionary.cpp index b23529eac7d..452065c20ad 100644 --- a/src/Dictionaries/SSDComplexKeyCacheDictionary.cpp +++ b/src/Dictionaries/SSDComplexKeyCacheDictionary.cpp @@ -24,6 +24,7 @@ #include #include +#include namespace ProfileEvents { @@ -1376,90 +1377,152 @@ SSDComplexKeyCacheDictionary::SSDComplexKeyCacheDictionary( createAttributes(); } -#define DECLARE(TYPE) \ - void SSDComplexKeyCacheDictionary::get##TYPE( \ - const std::string & attribute_name, \ - const Columns & key_columns, \ - const DataTypes & key_types, \ - ResultArrayType & out) const \ - { \ - const auto index = getAttributeIndex(attribute_name); \ - checkAttributeType(this, attribute_name, dict_struct.attributes[index].underlying_type, AttributeUnderlyingType::ut##TYPE); \ - const auto null_value = std::get(null_values[index]); /* NOLINT */ \ - getItemsNumberImpl(index, key_columns, key_types, out, [&](const size_t) { return null_value; }); /* NOLINT */ \ - } +ColumnPtr SSDComplexKeyCacheDictionary::getColumn( + const std::string & attribute_name, + const DataTypePtr &, + const Columns & key_columns, + const DataTypes & key_types, + const ColumnPtr default_untyped) const +{ + dict_struct.validateKeyTypes(key_types); - DECLARE(UInt8) - DECLARE(UInt16) - DECLARE(UInt32) - DECLARE(UInt64) - DECLARE(UInt128) - DECLARE(Int8) - DECLARE(Int16) - DECLARE(Int32) - DECLARE(Int64) - DECLARE(Float32) - DECLARE(Float64) - DECLARE(Decimal32) - DECLARE(Decimal64) - DECLARE(Decimal128) -#undef DECLARE + const auto index = getAttributeIndex(attribute_name); -#define DECLARE(TYPE) \ - void SSDComplexKeyCacheDictionary::get##TYPE( \ - const std::string & attribute_name, \ - const Columns & key_columns, \ - const DataTypes & key_types, \ - const PaddedPODArray & def, \ - ResultArrayType & out) const \ - { \ - const auto index = getAttributeIndex(attribute_name); \ - checkAttributeType(this, attribute_name, dict_struct.attributes[index].underlying_type, AttributeUnderlyingType::ut##TYPE); \ - getItemsNumberImpl(index, key_columns, key_types, out, [&](const size_t row) { return def[row]; }); /* NOLINT */ \ - } - DECLARE(UInt8) - DECLARE(UInt16) - DECLARE(UInt32) - DECLARE(UInt64) - DECLARE(UInt128) - DECLARE(Int8) - DECLARE(Int16) - DECLARE(Int32) - DECLARE(Int64) - DECLARE(Float32) - DECLARE(Float64) - DECLARE(Decimal32) - DECLARE(Decimal64) - DECLARE(Decimal128) -#undef DECLARE + ColumnPtr result; -#define DECLARE(TYPE) \ - void SSDComplexKeyCacheDictionary::get##TYPE( \ - const std::string & attribute_name, \ - const Columns & key_columns, \ - const DataTypes & key_types, \ - const TYPE def, \ - ResultArrayType & out) const \ - { \ - const auto index = getAttributeIndex(attribute_name); \ - checkAttributeType(this, attribute_name, dict_struct.attributes[index].underlying_type, AttributeUnderlyingType::ut##TYPE); \ - getItemsNumberImpl(index, key_columns, key_types, out, [&](const size_t) { return def; }); /* NOLINT */ \ - } - DECLARE(UInt8) - DECLARE(UInt16) - DECLARE(UInt32) - DECLARE(UInt64) - DECLARE(UInt128) - DECLARE(Int8) - DECLARE(Int16) - DECLARE(Int32) - DECLARE(Int64) - DECLARE(Float32) - DECLARE(Float64) - DECLARE(Decimal32) - DECLARE(Decimal64) - DECLARE(Decimal128) -#undef DECLARE + /// TODO: Check that attribute type is same as result type + /// TODO: Check if const will work as expected + + auto keys_size = key_columns.front()->size(); + + auto type_call = [&](const auto &dictionary_attribute_type) + { + using Type = std::decay_t; + using AttributeType = typename Type::AttributeType; + + if constexpr (std::is_same_v) + { + auto column_string = ColumnString::create(); + auto out = column_string.get(); + + if (default_untyped != nullptr) + { + if (const auto default_col = checkAndGetColumn(*default_untyped)) + { + getItemsStringImpl(index, key_columns, key_types, out, [&](const size_t row) { return default_col->getDataAt(row); }); + } + else if (const auto default_col_const = checkAndGetColumnConst(default_untyped.get())) + { + const auto & def = default_col_const->template getValue(); + + getItemsStringImpl(index, key_columns, key_types, out, [&](const size_t) { return StringRef{def}; }); + } + } + else + { + const auto null_value = StringRef{std::get(null_values[index])}; + + getItemsStringImpl(index, key_columns, key_types, out, [&](const size_t) { return null_value; }); + } + + result = std::move(column_string); + } + else if constexpr (IsNumber) + { + auto column = ColumnVector::create(keys_size); + auto& out = column->getData(); + + if (default_untyped != nullptr) + { + if (const auto default_col = checkAndGetColumn>(*default_untyped)) + { + getItemsNumberImpl( + index, + key_columns, + key_types, + out, + [&](const size_t row) { return default_col->getData()[row]; } + ); + } + else if (const auto default_col_const = checkAndGetColumnConst>(default_untyped.get())) + { + const auto & def = default_col_const->template getValue(); + + getItemsNumberImpl( + index, + key_columns, + key_types, + out, + [&](const size_t) { return def; } + ); + } + } + else + { + const auto null_value = std::get(null_values[index]); /* NOLINT */ + + getItemsNumberImpl( + index, + key_columns, + key_types, + out, + [&](const size_t) { return null_value; }); + } + + result = std::move(column); + } + else if constexpr (IsDecimalNumber) + { + // auto scale = getDecimalScale(*attribute.type); + auto column = ColumnDecimal::create(keys_size, 0); + auto& out = column->getData(); + + if (default_untyped != nullptr) + { + if (const auto default_col = checkAndGetColumn>(*default_untyped)) + { + getItemsNumberImpl( + index, + key_columns, + key_types, + out, + [&](const size_t row) { return default_col->getData()[row]; } + ); + } + else if (const auto default_col_const = checkAndGetColumnConst>(default_untyped.get())) + { + const auto & def = default_col_const->template getValue(); + + getItemsNumberImpl( + index, + key_columns, + key_types, + out, + [&](const size_t) { return def; } + ); + } + } + else + { + const auto null_value = std::get(null_values[index]); /* NOLINT */ + + getItemsNumberImpl( + index, + key_columns, + key_types, + out, + [&](const size_t) { return null_value; } + ); + } + + result = std::move(column); + } + }; + + callOnDictionaryAttributeType(dict_struct.attributes[index].underlying_type, type_call); + + return result; +} template void SSDComplexKeyCacheDictionary::getItemsNumberImpl( @@ -1508,42 +1571,6 @@ void SSDComplexKeyCacheDictionary::getItemsNumberImpl( getLifetime()); } -void SSDComplexKeyCacheDictionary::getString( - const std::string & attribute_name, - const Columns & key_columns, const DataTypes & key_types, ColumnString * out) const -{ - const auto index = getAttributeIndex(attribute_name); - checkAttributeType(this, attribute_name, dict_struct.attributes[index].underlying_type, AttributeUnderlyingType::utString); - - const auto null_value = StringRef{std::get(null_values[index])}; - - getItemsStringImpl(index, key_columns, key_types, out, [&](const size_t) { return null_value; }); -} - -void SSDComplexKeyCacheDictionary::getString( - const std::string & attribute_name, - const Columns & key_columns, const DataTypes & key_types, - const ColumnString * const def, ColumnString * const out) const -{ - const auto index = getAttributeIndex(attribute_name); - checkAttributeType(this, attribute_name, dict_struct.attributes[index].underlying_type, AttributeUnderlyingType::utString); - - getItemsStringImpl(index, key_columns, key_types, out, [&](const size_t row) { return def->getDataAt(row); }); -} - -void SSDComplexKeyCacheDictionary::getString( - const std::string & attribute_name, - const Columns & key_columns, - const DataTypes & key_types, - const String & def, - ColumnString * const out) const -{ - const auto index = getAttributeIndex(attribute_name); - checkAttributeType(this, attribute_name, dict_struct.attributes[index].underlying_type, AttributeUnderlyingType::utString); - - getItemsStringImpl(index, key_columns, key_types, out, [&](const size_t) { return StringRef{def}; }); -} - template void SSDComplexKeyCacheDictionary::getItemsStringImpl( const size_t attribute_index, @@ -1639,20 +1666,27 @@ void SSDComplexKeyCacheDictionary::getItemsStringImpl( } } -void SSDComplexKeyCacheDictionary::has( - const Columns & key_columns, - const DataTypes & key_types, - PaddedPODArray & out) const +ColumnUInt8::Ptr SSDComplexKeyCacheDictionary::has(const Columns & key_columns, const DataTypes & key_types) const { dict_struct.validateKeyTypes(key_types); + PaddedPODArray backup_storage; + const auto& ids = getColumnDataAsPaddedPODArray(this, key_columns.front(), backup_storage); + + auto result = ColumnUInt8::create(ext::size(ids)); + auto& out = result->getData(); + + const auto rows = ext::size(ids); + for (const auto row : ext::range(0, rows)) + out[row] = false; + const auto now = std::chrono::system_clock::now(); std::unordered_map> not_found_keys; TemporalComplexKeysPool not_found_pool; storage.has(key_columns, key_types, out, not_found_keys, not_found_pool, now); if (not_found_keys.empty()) - return; + return result; std::vector required_keys(not_found_keys.size()); std::transform(std::begin(not_found_keys), std::end(not_found_keys), std::begin(required_keys), [](const auto & pair) { return pair.first; }); @@ -1681,6 +1715,8 @@ void SSDComplexKeyCacheDictionary::has( out[row] = false; }, getLifetime()); + + return result; } BlockInputStreamPtr SSDComplexKeyCacheDictionary::getBlockInputStream( diff --git a/src/Dictionaries/SSDComplexKeyCacheDictionary.h b/src/Dictionaries/SSDComplexKeyCacheDictionary.h index 4758d62f1df..47c8f54a77d 100644 --- a/src/Dictionaries/SSDComplexKeyCacheDictionary.h +++ b/src/Dictionaries/SSDComplexKeyCacheDictionary.h @@ -569,88 +569,20 @@ public: std::exception_ptr getLastException() const override { return storage.getLastException(); } + DictionaryIdentifierType getIdentifierType() const override { return DictionaryIdentifierType::complex; } + + ColumnPtr getColumn( + const std::string& attribute_name, + const DataTypePtr & result_type, + const Columns & key_columns, + const DataTypes & key_types, + const ColumnPtr default_untyped) const override; + + ColumnUInt8::Ptr has(const Columns & key_columns, const DataTypes & key_types) const override; + template using ResultArrayType = SSDComplexKeyCacheStorage::ResultArrayType; -#define DECLARE(TYPE) \ - void get##TYPE( \ - const std::string & attribute_name, \ - const Columns & key_columns, \ - const DataTypes & key_types, \ - ResultArrayType & out) const; - DECLARE(UInt8) - DECLARE(UInt16) - DECLARE(UInt32) - DECLARE(UInt64) - DECLARE(UInt128) - DECLARE(Int8) - DECLARE(Int16) - DECLARE(Int32) - DECLARE(Int64) - DECLARE(Float32) - DECLARE(Float64) - DECLARE(Decimal32) - DECLARE(Decimal64) - DECLARE(Decimal128) -#undef DECLARE - - void getString(const std::string & attribute_name, const Columns & key_columns, - const DataTypes & key_types, ColumnString * out) const; - -#define DECLARE(TYPE) \ - void get##TYPE( \ - const std::string & attribute_name, \ - const Columns & key_columns, \ - const DataTypes & key_types, \ - const PaddedPODArray & def, \ - ResultArrayType & out) const; - DECLARE(UInt8) - DECLARE(UInt16) - DECLARE(UInt32) - DECLARE(UInt64) - DECLARE(UInt128) - DECLARE(Int8) - DECLARE(Int16) - DECLARE(Int32) - DECLARE(Int64) - DECLARE(Float32) - DECLARE(Float64) - DECLARE(Decimal32) - DECLARE(Decimal64) - DECLARE(Decimal128) -#undef DECLARE - - void getString(const std::string & attribute_name, const Columns & key_columns, - const DataTypes & key_types, const ColumnString * const def, ColumnString * const out) const; - -#define DECLARE(TYPE) \ - void get##TYPE( \ - const std::string & attribute_name, \ - const Columns & key_columns, \ - const DataTypes & key_types, \ - const TYPE def, \ - ResultArrayType & out) const; - DECLARE(UInt8) - DECLARE(UInt16) - DECLARE(UInt32) - DECLARE(UInt64) - DECLARE(UInt128) - DECLARE(Int8) - DECLARE(Int16) - DECLARE(Int32) - DECLARE(Int64) - DECLARE(Float32) - DECLARE(Float64) - DECLARE(Decimal32) - DECLARE(Decimal64) - DECLARE(Decimal128) -#undef DECLARE - - void getString(const std::string & attribute_name, const Columns & key_columns, - const DataTypes & key_types, const String & def, ColumnString * const out) const; - - void has(const Columns & key_columns, const DataTypes & key_types, PaddedPODArray & out) const; - BlockInputStreamPtr getBlockInputStream(const Names & column_names, size_t max_block_size) const override; private: