(&mut self, q: Query<Raw>)
| 1642 | } |
| 1643 | |
| 1644 | fn fold_query(&mut self, q: Query<Raw>) -> Query<Aug> { |
| 1645 | // Retain the old values of various CTE names so that we can restore them after we're done |
| 1646 | // planning this SELECT. |
| 1647 | let mut shadowed_cte_ids = Vec::new(); |
| 1648 | |
| 1649 | // A reused identifier indicates a reused name. |
| 1650 | use itertools::Itertools; |
| 1651 | if let Some(ident) = q.ctes.bound_identifiers().duplicates().next() { |
| 1652 | self.status = Err(sql_err!( |
| 1653 | "WITH query name \"{}\" specified more than once", |
| 1654 | normalize::ident_ref(ident), |
| 1655 | )); |
| 1656 | } |
| 1657 | |
| 1658 | let ctes: CteBlock<Aug> = match q.ctes { |
| 1659 | CteBlock::Simple(ctes) => { |
| 1660 | let mut result_ctes = Vec::<Cte<Aug>>::new(); |
| 1661 | |
| 1662 | let initial_id = self.ctes.len(); |
| 1663 | |
| 1664 | for (offset, cte) in ctes.into_iter().enumerate() { |
| 1665 | let cte_name = normalize::ident(cte.alias.name.clone()); |
| 1666 | let local_id = LocalId::new(u64::cast_from(initial_id + offset)); |
| 1667 | |
| 1668 | result_ctes.push(Cte { |
| 1669 | alias: cte.alias, |
| 1670 | id: local_id, |
| 1671 | query: self.fold_query(cte.query), |
| 1672 | }); |
| 1673 | |
| 1674 | let shadowed_id = self.ctes.insert(cte_name.clone(), local_id); |
| 1675 | shadowed_cte_ids.push((cte_name, shadowed_id)); |
| 1676 | } |
| 1677 | CteBlock::Simple(result_ctes) |
| 1678 | } |
| 1679 | CteBlock::MutuallyRecursive(MutRecBlock { options, ctes }) => { |
| 1680 | let mut result_ctes = Vec::<CteMutRec<Aug>>::new(); |
| 1681 | |
| 1682 | let initial_id = self.ctes.len(); |
| 1683 | |
| 1684 | // The identifiers for each CTE will be `initial_id` plus their offset in `q.ctes`. |
| 1685 | for (offset, cte) in ctes.iter().enumerate() { |
| 1686 | let cte_name = normalize::ident(cte.name.clone()); |
| 1687 | let local_id = LocalId::new(u64::cast_from(initial_id + offset)); |
| 1688 | let shadowed_id = self.ctes.insert(cte_name.clone(), local_id); |
| 1689 | shadowed_cte_ids.push((cte_name, shadowed_id)); |
| 1690 | } |
| 1691 | |
| 1692 | for (offset, cte) in ctes.into_iter().enumerate() { |
| 1693 | let local_id = LocalId::new(u64::cast_from(initial_id + offset)); |
| 1694 | |
| 1695 | let columns = cte |
| 1696 | .columns |
| 1697 | .into_iter() |
| 1698 | .map(|column| self.fold_cte_mut_rec_column_def(column)) |
| 1699 | .collect(); |
| 1700 | let query = self.fold_query(cte.query); |
| 1701 | result_ctes.push(CteMutRec { |
no test coverage detected