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

Function extract_join_predicate

nodedb-sql/src/planner/dml_update_delete.rs:183–220  ·  view source on GitHub ↗

Extract a single equi-join predicate of the form `target_table.col = source_table.col` (or the reverse) from a WHERE expression, returning `(target_col, source_col, remaining_filters)`. Also accepts `col = other_table.col` where `col` without a table qualifier is assumed to belong to the target (PostgreSQL behavior).

(
    expr: &ast::Expr,
    target_ref: &str,
    source_ref: &str,
)

Source from the content-addressed store, hash-verified

181/// Also accepts `col = other_table.col` where `col` without a table qualifier is
182/// assumed to belong to the target (PostgreSQL behavior).
183fn extract_join_predicate(
184 expr: &ast::Expr,
185 target_ref: &str,
186 source_ref: &str,
187) -> Result<(String, String, Vec<Filter>)> {
188 // Flatten the top-level AND chain.
189 let mut conjuncts: Vec<ast::Expr> = Vec::new();
190 flatten_and_expr(expr, &mut conjuncts);
191
192 // Find the first conjunct that is an equi-join between target and source.
193 let mut join_idx: Option<usize> = None;
194 let mut target_col = String::new();
195 let mut source_col = String::new();
196
197 for (i, conjunct) in conjuncts.iter().enumerate() {
198 if let Some((tc, sc)) = try_equijoin_pair(conjunct, target_ref, source_ref) {
199 target_col = tc;
200 source_col = sc;
201 join_idx = Some(i);
202 break;
203 }
204 }
205
206 let join_idx = join_idx.ok_or_else(|| SqlError::Parse {
207 detail: format!(
208 "UPDATE ... FROM requires a WHERE clause equi-join predicate of the form \
209 `{target_ref}.col = {source_ref}.col`; none found"
210 ),
211 })?;
212
213 conjuncts.remove(join_idx);
214
215 // Remaining conjuncts become target_filters. Strip table qualifier so
216 // `uf_target.score` becomes `score` — documents store bare field names.
217 let target_filters = strip_and_convert_filters(conjuncts, target_ref)?;
218
219 Ok((target_col, source_col, target_filters))
220}
221
222/// Try to extract `(target_col, source_col)` from an equality expression
223/// where one side is `target_ref.col` and the other is `source_ref.col`.

Callers 1

plan_update_fromFunction · 0.85

Calls 5

flatten_and_exprFunction · 0.85
try_equijoin_pairFunction · 0.85
iterMethod · 0.45
removeMethod · 0.45

Tested by

no test coverage detected