nodedb_sql/planner/bitmap_emit/hashjoin.rs
1// SPDX-License-Identifier: Apache-2.0
2
3//! HashJoin bitmap-emission analysis.
4//!
5//! Given the two children of a `SqlPlan::Join`, this module determines which
6//! side(s) qualify for bitmap-producer pushdown and returns a `BitmapJoinHints`
7//! struct. The converter layer (`nodedb`'s `sql_plan_convert::scan`) uses these
8//! hints to populate `QueryOp::HashJoin::inline_left_bitmap` and
9//! `inline_right_bitmap` with the appropriate `PhysicalPlan` sub-plans.
10//!
11//! Selection policy (no cost model; no statistics required):
12//! - Left child qualifies → emit `inline_left_bitmap` hint.
13//! - Right child qualifies → emit `inline_right_bitmap` hint.
14//! - Both qualify → emit the side that is already a `DocumentIndexLookup`
15//! (already indexed), preferring left if both are the same shape.
16//! - Neither qualifies → both hints are `None`.
17
18use crate::types::SqlPlan;
19
20use super::predicate::{self, BitmapHint};
21
22/// Bitmap-pushdown hints for both sides of a join.
23#[derive(Debug, Default)]
24pub struct BitmapJoinHints {
25 /// Hint for the left join child. When `Some`, the converter should build an
26 /// `IndexedFetch` (or `Scan`) sub-plan and place it in `inline_left_bitmap`.
27 pub left: Option<BitmapHint>,
28 /// Hint for the right join child. Same semantics as `left`.
29 pub right: Option<BitmapHint>,
30}
31
32/// Analyze both join children and return bitmap-pushdown hints.
33///
34/// Neither side is penalized for being analyzed — if both qualify, both hints
35/// are emitted so the executor can inject prefilters on both probe scans.
36/// This is safe: the executor will only use the bitmap that matches the
37/// collection it is about to scan.
38pub fn analyze_join_sides(left: &SqlPlan, right: &SqlPlan) -> BitmapJoinHints {
39 BitmapJoinHints {
40 left: predicate::analyze(left),
41 right: predicate::analyze(right),
42 }
43}