MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / plan_lateral_join

Function plan_lateral_join

nodedb-sql/src/planner/lateral/plan.rs:33–127  ·  view source on GitHub ↗
(
    outer_plan: SqlPlan,
    outer_alias: Option<String>,
    subquery: &ast::Query,
    lateral_alias: &str,
    left_join: bool,
    outer_projection: Vec<Projection>,
    catalog: &dyn SqlCatalog

Source from the content-addressed store, hash-verified

31/// `outer_projection` — SELECT list projection to apply after the lateral.
32#[allow(clippy::too_many_arguments)]
33pub fn plan_lateral_join(
34 outer_plan: SqlPlan,
35 outer_alias: Option<String>,
36 subquery: &ast::Query,
37 lateral_alias: &str,
38 left_join: bool,
39 outer_projection: Vec<Projection>,
40 catalog: &dyn SqlCatalog,
41 functions: &FunctionRegistry,
42 temporal: TemporalScope,
43) -> Result<SqlPlan> {
44 let select = match subquery.body.as_ref() {
45 sqlparser::ast::SetExpr::Select(s) => s,
46 _ => {
47 return Err(SqlError::Unsupported {
48 detail: "LATERAL subquery body must be a SELECT".into(),
49 });
50 }
51 };
52
53 let outer_alias_str = outer_alias.as_deref().unwrap_or("").to_string();
54
55 let analysis = analyse_lateral_where(subquery, &outer_alias_str);
56
57 // Determine if this is the equi-correlated + TopK shape:
58 // - At least one equi-key correlation.
59 // - A LIMIT k on the subquery.
60 // - No non-equi correlations (those require LateralLoop).
61 let has_equi = !analysis.equi_keys.is_empty();
62 let inner_limit = limit_from_query(subquery);
63 let is_top_k = has_equi && inner_limit.is_some() && analysis.non_equi.is_empty();
64
65 if is_top_k {
66 plan_lateral_top_k(
67 outer_plan,
68 outer_alias,
69 select,
70 subquery,
71 analysis.equi_keys,
72 inner_limit.expect("checked above"),
73 lateral_alias,
74 left_join,
75 outer_projection,
76 )
77 } else if has_equi && analysis.non_equi.is_empty() {
78 // Equi-correlated, no LIMIT: rewrite as a regular hash join.
79 let inner_plan =
80 crate::planner::select::plan_query(subquery, catalog, functions, temporal)?;
81 let equi_on: Vec<(String, String)> = analysis
82 .equi_keys
83 .into_iter()
84 .map(|c| (c.outer_col, c.inner_col))
85 .collect();
86 Ok(SqlPlan::Join {
87 left: Box::new(outer_plan),
88 right: Box::new(inner_plan),
89 on: equi_on,
90 join_type: if left_join {

Callers 2

plan_join_from_selectFunction · 0.85
plan_selectFunction · 0.85

Calls 11

analyse_lateral_whereFunction · 0.85
limit_from_queryFunction · 0.85
plan_lateral_top_kFunction · 0.85
plan_queryFunction · 0.85
to_stringMethod · 0.80
collectMethod · 0.80
as_refMethod · 0.45
is_emptyMethod · 0.45
expectMethod · 0.45
iterMethod · 0.45
cloneMethod · 0.45

Tested by

no test coverage detected