| 81 | |
| 82 | template <DictionaryKeyType dictionary_key_type, bool sharded> |
| 83 | Columns HashedArrayDictionary<dictionary_key_type, sharded>::getColumns( |
| 84 | const Strings & attribute_names, |
| 85 | const DataTypes & attribute_types, |
| 86 | const Columns & key_columns, |
| 87 | const DataTypes & key_types, |
| 88 | DefaultsOrFilter defaults_or_filter) const |
| 89 | { |
| 90 | bool is_short_circuit = std::holds_alternative<RefFilter>(defaults_or_filter); |
| 91 | chassert(is_short_circuit || std::holds_alternative<RefDefaults>(defaults_or_filter)); |
| 92 | |
| 93 | if (dictionary_key_type == DictionaryKeyType::Complex) |
| 94 | dict_struct.validateKeyTypes(key_types); |
| 95 | |
| 96 | DictionaryKeysArenaHolder<dictionary_key_type> arena_holder; |
| 97 | DictionaryKeysExtractor<dictionary_key_type> extractor(key_columns, arena_holder.getComplexKeyArena()); |
| 98 | |
| 99 | const size_t keys_size = extractor.getKeysSize(); |
| 100 | |
| 101 | IColumn::Filter * default_mask = nullptr; |
| 102 | if (is_short_circuit) |
| 103 | { |
| 104 | default_mask = &std::get<RefFilter>(defaults_or_filter).get(); |
| 105 | default_mask->resize(keys_size); |
| 106 | } |
| 107 | |
| 108 | KeyIndexToElementIndex key_index_to_element_index; |
| 109 | |
| 110 | /** Optimization for multiple attributes. |
| 111 | * For each key save element index in key_index_to_element_index array. |
| 112 | * Later in type_call for attribute use getItemsImpl specialization with key_index_to_element_index array |
| 113 | * instead of DictionaryKeyExtractor. |
| 114 | */ |
| 115 | if (attribute_names.size() > 1) |
| 116 | { |
| 117 | size_t keys_found = 0; |
| 118 | |
| 119 | key_index_to_element_index.resize(keys_size); |
| 120 | |
| 121 | for (size_t key_index = 0; key_index < keys_size; ++key_index) |
| 122 | { |
| 123 | auto key = extractor.extractCurrentKey(); |
| 124 | auto shard = getShard(key); |
| 125 | const auto & key_attribute_container = key_attribute.containers[shard]; |
| 126 | |
| 127 | auto it = key_attribute_container.find(key); |
| 128 | if (it == key_attribute_container.end()) |
| 129 | { |
| 130 | if constexpr (sharded) |
| 131 | key_index_to_element_index[key_index] = std::make_pair(-1, shard); |
| 132 | else |
| 133 | key_index_to_element_index[key_index] = -1; |
| 134 | |
| 135 | if (default_mask) |
| 136 | (*default_mask)[key_index] = 1; |
| 137 | } |
| 138 | else |
| 139 | { |
| 140 | if constexpr (sharded) |
nothing calls this directly
no test coverage detected