MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / joinBlock

Method joinBlock

src/Interpreters/DirectJoin.cpp:142–210  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

140}
141
142JoinResultPtr DirectKeyValueJoin::joinBlock(Block block)
143{
144 const String & key_name = table_join->getOnlyClause().key_names_left[0];
145 const ColumnWithTypeAndName & key_col = block.getByName(key_name);
146 if (!key_col.column)
147 return {};
148
149 Block original_right_block = originalRightBlock(right_sample_block, *table_join);
150 Block right_block_to_use = !right_sample_block_with_storage_column_names.empty() ? right_sample_block_with_storage_column_names : original_right_block;
151 const Names & attribute_names = right_block_to_use.getNames();
152
153 bool is_all_join = table_join->strictness() == JoinStrictness::All;
154 bool is_semi_join = table_join->strictness() == JoinStrictness::Semi;
155 bool is_anti_join = table_join->strictness() == JoinStrictness::Anti;
156
157 NullMap null_map;
158 IColumn::Offsets offsets;
159 Chunk joined_chunk = storage->getByKeys({key_col}, attribute_names, null_map, offsets);
160
161 /// Expected right block may differ from structure in storage, because of `join_use_nulls` or we just select not all joined attributes
162 Block sample_storage_block = storage->getSampleBlock(attribute_names);
163 MutableColumns result_columns = convertBlockStructure(sample_storage_block, right_block_to_use, joined_chunk.mutateColumns(), null_map);
164
165 if (!offsets.empty())
166 {
167 /// For ALL semantics with offsets, replicate left rows
168 if (is_all_join)
169 {
170 MutableColumns replicated_columns = block.mutateColumns();
171 for (auto && col : replicated_columns)
172 col = IColumn::mutate(col->replicate(offsets));
173 block.setColumns(std::move(replicated_columns));
174 }
175 else
176 {
177 /// For ANY/ANTI/SEMI semantics right columns are not replicated
178 /// We need to 'unreplicate' them by keeping only the first match
179 selectFirstMatchForEachKey(offsets, result_columns, null_map);
180 }
181 }
182
183 for (size_t i = 0; i < result_columns.size(); ++i)
184 {
185 ColumnWithTypeAndName col = right_sample_block.getByPosition(i);
186 col.column = std::move(result_columns[i]);
187 block.insert(std::move(col));
188 }
189
190 if (is_anti_join)
191 {
192 /// invert null_map
193 for (auto & val : null_map)
194 val = !val;
195 }
196
197 size_t non_null_rows = countBytesInFilter(null_map);
198 bool has_null_matches = non_null_rows < null_map.size();
199 bool need_filtering = (isInner(table_join->kind()) || (isLeft(table_join->kind()) && (is_semi_join || is_anti_join)));

Callers

nothing calls this directly

Calls 15

originalRightBlockFunction · 0.85
convertBlockStructureFunction · 0.85
countBytesInFilterFunction · 0.85
isInnerFunction · 0.85
isLeftFunction · 0.85
getByNameMethod · 0.80
strictnessMethod · 0.80
kindMethod · 0.80
mutateFunction · 0.50
emptyMethod · 0.45
getNamesMethod · 0.45

Tested by

no test coverage detected