|
13 | 13 | // limitations under the License. |
14 | 14 |
|
15 | 15 | use databend_common_column::bitmap::Bitmap; |
| 16 | +use databend_common_exception::ErrorCode; |
16 | 17 | use databend_common_exception::Result; |
17 | 18 | use databend_common_expression::arrow::and_validities; |
18 | 19 | use databend_common_expression::type_check::check_function; |
@@ -64,6 +65,7 @@ pub struct HashJoinDesc { |
64 | 65 | pub(crate) probe_projections: ColumnSet, |
65 | 66 | pub(crate) probe_to_build: Vec<(usize, (bool, bool))>, |
66 | 67 | pub(crate) build_schema: DataSchemaRef, |
| 68 | + pub(crate) probe_schema: DataSchemaRef, |
67 | 69 | } |
68 | 70 |
|
69 | 71 | #[derive(Debug, Clone)] |
@@ -139,6 +141,7 @@ impl HashJoinDesc { |
139 | 141 | build_projection: join.build_projections.clone(), |
140 | 142 | probe_projections: join.probe_projections.clone(), |
141 | 143 | build_schema: join.build.output_schema()?, |
| 144 | + probe_schema: join.probe.output_schema()?, |
142 | 145 | }) |
143 | 146 | } |
144 | 147 |
|
@@ -265,30 +268,50 @@ impl HashJoinDesc { |
265 | 268 | &self, |
266 | 269 | function_ctx: &FunctionContext, |
267 | 270 | block_size: usize, |
268 | | - ) -> Result<FilterExecutor> { |
269 | | - let offset = self.probe_projections.len(); |
| 271 | + ) -> Result<Option<FilterExecutor>> { |
| 272 | + let probe_len = self.probe_schema.num_fields(); |
270 | 273 |
|
271 | | - let predicate = self |
| 274 | + let projection = self |
| 275 | + .probe_projections |
| 276 | + .iter() |
| 277 | + .copied() |
| 278 | + .chain(self.build_projection.iter().map(|idx| probe_len + *idx)) |
| 279 | + .collect::<Vec<_>>(); |
| 280 | + |
| 281 | + let eq_predicates = self |
272 | 282 | .probe_keys |
273 | 283 | .iter() |
274 | 284 | .zip(&self.build_keys) |
275 | 285 | .map(|(probe, build)| { |
276 | | - let build = build.project_column_ref(|old| Ok(old + offset))?; |
| 286 | + let build = build.project_column_ref(|old| Ok(old + probe_len))?; |
277 | 287 | check_function(None, "eq", &[], &[probe.clone(), build], &BUILTIN_FUNCTIONS) |
| 288 | + }); |
| 289 | + |
| 290 | + let other_predicate = self.other_predicate.as_ref().map(|expr| { |
| 291 | + expr.project_column_ref(|index| { |
| 292 | + projection.get(*index).copied().ok_or_else(|| { |
| 293 | + ErrorCode::Internal(format!( |
| 294 | + "Invalid column index {} for nested loop predicate projection", |
| 295 | + index |
| 296 | + )) |
| 297 | + }) |
278 | 298 | }) |
279 | | - .chain(self.other_predicate.iter().map(|expr| Ok(expr.clone()))) |
| 299 | + }); |
| 300 | + |
| 301 | + let predicate = eq_predicates |
| 302 | + .chain(other_predicate) |
280 | 303 | .reduce(|lhs, rhs| { |
281 | 304 | check_function(None, "and_filters", &[], &[lhs?, rhs?], &BUILTIN_FUNCTIONS) |
282 | 305 | }) |
283 | 306 | .unwrap()?; |
284 | 307 |
|
285 | | - Ok(FilterExecutor::new( |
| 308 | + Ok(Some(FilterExecutor::new( |
286 | 309 | predicate, |
287 | 310 | function_ctx.clone(), |
288 | 311 | block_size, |
289 | | - None, |
| 312 | + Some(projection), |
290 | 313 | &BUILTIN_FUNCTIONS, |
291 | 314 | false, |
292 | | - )) |
| 315 | + ))) |
293 | 316 | } |
294 | 317 | } |
0 commit comments