(expr: &SetExpr, cte_name: &str)
| 365 | type RecursiveInfo = (Vec<Filter>, Option<(String, String)>); |
| 366 | |
| 367 | fn extract_recursive_info(expr: &SetExpr, cte_name: &str) -> Result<RecursiveInfo> { |
| 368 | let select = match expr { |
| 369 | SetExpr::Select(s) => s, |
| 370 | _ => { |
| 371 | return Err(SqlError::Unsupported { |
| 372 | detail: "recursive CTE branch must be SELECT".into(), |
| 373 | }); |
| 374 | } |
| 375 | }; |
| 376 | |
| 377 | let mut real_table_alias = None; |
| 378 | let mut cte_alias = None; |
| 379 | let mut join_on_expr = None; |
| 380 | |
| 381 | for from in &select.from { |
| 382 | let table_name = extract_table_name(&from.relation); |
| 383 | let table_alias = extract_table_alias(&from.relation); |
| 384 | |
| 385 | if let Some(name) = &table_name { |
| 386 | if name.eq_ignore_ascii_case(cte_name) { |
| 387 | cte_alias = table_alias.or_else(|| Some(name.clone())); |
| 388 | } else { |
| 389 | real_table_alias = table_alias.or_else(|| Some(name.clone())); |
| 390 | } |
| 391 | } |
| 392 | |
| 393 | for join in &from.joins { |
| 394 | let join_table = extract_table_name(&join.relation); |
| 395 | let join_alias = extract_table_alias(&join.relation); |
| 396 | if let Some(jt) = &join_table { |
| 397 | if jt.eq_ignore_ascii_case(cte_name) { |
| 398 | cte_alias = join_alias.or_else(|| Some(jt.clone())); |
| 399 | if let Some(cond) = extract_join_on_condition(&join.join_operator) { |
| 400 | join_on_expr = Some(cond.clone()); |
| 401 | } |
| 402 | } else { |
| 403 | real_table_alias = join_alias.or_else(|| Some(jt.clone())); |
| 404 | if join_on_expr.is_none() |
| 405 | && let Some(cond) = extract_join_on_condition(&join.join_operator) |
| 406 | { |
| 407 | join_on_expr = Some(cond.clone()); |
| 408 | } |
| 409 | } |
| 410 | } |
| 411 | } |
| 412 | } |
| 413 | |
| 414 | // Extract the join link from the ON condition. |
| 415 | let join_link = if let (Some(real_alias), Some(cte_al), Some(on_expr)) = |
| 416 | (&real_table_alias, &cte_alias, &join_on_expr) |
| 417 | { |
| 418 | extract_equi_link(on_expr, real_alias, cte_al) |
| 419 | } else { |
| 420 | None |
| 421 | }; |
| 422 | |
| 423 | let mut filters = Vec::new(); |
| 424 | if let Some(where_expr) = &select.selection { |
no test coverage detected