(cte: Cte, ctx: &mut Context)
| 424 | } |
| 425 | |
| 426 | fn translate_cte(cte: Cte, ctx: &mut Context) -> Result<(sql_ast::Cte, bool)> { |
| 427 | let decl = ctx.anchor.lookup_table_decl(&cte.tid).unwrap(); |
| 428 | let cte_name = decl.name.clone().unwrap(); |
| 429 | |
| 430 | let cte_name = translate_ident(Some(cte_name), None, ctx).pop().unwrap(); |
| 431 | |
| 432 | let (query, recursive) = match cte.kind { |
| 433 | // base case |
| 434 | CteKind::Normal(rel) => (translate_relation(rel, ctx)?, false), |
| 435 | |
| 436 | // special: WITH RECURSIVE |
| 437 | CteKind::Loop { initial, step } => { |
| 438 | // compile initial |
| 439 | let initial = query_to_set_expr(translate_relation(initial, ctx)?, ctx); |
| 440 | |
| 441 | let step = query_to_set_expr(translate_relation(step, ctx)?, ctx); |
| 442 | |
| 443 | // build CTE and its SELECT |
| 444 | let inner_query = default_query(SetExpr::SetOperation { |
| 445 | op: sql_ast::SetOperator::Union, |
| 446 | set_quantifier: sql_ast::SetQuantifier::All, |
| 447 | left: initial, |
| 448 | right: step, |
| 449 | }); |
| 450 | |
| 451 | (inner_query, true) |
| 452 | |
| 453 | // RECURSIVE can only follow WITH directly. |
| 454 | // Initial implementation assumed that it applies only to the first CTE. |
| 455 | // This meant that it had to wrap any-non-first CTE into a *nested* WITH, so the inner |
| 456 | // WITH could be RECURSIVE. |
| 457 | // This is implementation of that, in case some dialect requires it. |
| 458 | // let inner_cte = sql_ast::Cte { |
| 459 | // alias: simple_table_alias(cte_name.clone()), |
| 460 | // query: Box::new(inner_query), |
| 461 | // from: None, |
| 462 | // }; |
| 463 | // let outer_query = sql_ast::Query { |
| 464 | // with: Some(sql_ast::With { |
| 465 | // recursive: true, |
| 466 | // cte_tables: vec![inner_cte], |
| 467 | // }), |
| 468 | // ..default_query(sql_ast::SetExpr::Select(Box::new(sql_ast::Select { |
| 469 | // projection: vec![SelectItem::Wildcard( |
| 470 | // sql_ast::WildcardAdditionalOptions::default(), |
| 471 | // )], |
| 472 | // from: vec![TableWithJoins { |
| 473 | // relation: TableFactor::Table { |
| 474 | // name: sql_ast::ObjectName(vec![cte_name.clone()]), |
| 475 | // alias: None, |
| 476 | // args: None, |
| 477 | // with_hints: Vec::new(), |
| 478 | // }, |
| 479 | // joins: vec![], |
| 480 | // }], |
| 481 | // ..default_select() |
| 482 | // }))) |
| 483 | // }; |
no test coverage detected