Extract a correlated equality predicate from a WHERE clause. Looks for patterns like `o.user_id = u.id` and returns (outer_col, inner_col). The "inner" column is the one qualified with the subquery's table alias; the "outer" column is the one referencing the outer query's table.
(expr: &Expr)
| 290 | /// The "inner" column is the one qualified with the subquery's table alias; |
| 291 | /// the "outer" column is the one referencing the outer query's table. |
| 292 | fn extract_correlated_eq(expr: &Expr) -> Option<(String, String)> { |
| 293 | match expr { |
| 294 | Expr::BinaryOp { |
| 295 | left, |
| 296 | op: ast::BinaryOperator::Eq, |
| 297 | right, |
| 298 | } => { |
| 299 | let left_parts = extract_qualified_column(left); |
| 300 | let right_parts = extract_qualified_column(right); |
| 301 | match (left_parts, right_parts) { |
| 302 | (Some((_lt, lc)), Some((_rt, rc))) => { |
| 303 | // Convention: left is inner (subquery table), right is outer. |
| 304 | // But we can't distinguish without schema, so just return both. |
| 305 | Some((rc, lc)) |
| 306 | } |
| 307 | _ => None, |
| 308 | } |
| 309 | } |
| 310 | // For AND, try to find a correlated eq in either side. |
| 311 | Expr::BinaryOp { |
| 312 | left, |
| 313 | op: ast::BinaryOperator::And, |
| 314 | right, |
| 315 | } => extract_correlated_eq(left).or_else(|| extract_correlated_eq(right)), |
| 316 | Expr::Nested(inner) => extract_correlated_eq(inner), |
| 317 | _ => None, |
| 318 | } |
| 319 | } |
| 320 | |
| 321 | /// Extract table.column from a qualified identifier. |
| 322 | /// |
no test coverage detected