(&mut self, q: &Query)
| 84 | } |
| 85 | |
| 86 | fn pre_visit_query(&mut self, q: &Query) -> ControlFlow<Self::Break> { |
| 87 | if let Some(with) = &q.with { |
| 88 | for cte in &with.cte_tables { |
| 89 | // The non-recursive CTE name is not in scope when evaluating the CTE itself, so this is valid: |
| 90 | // `WITH t AS (SELECT * FROM t) SELECT * FROM t` |
| 91 | // Where the first `t` refers to a predefined table. So we are careful here |
| 92 | // to visit the CTE first, before putting it in scope. |
| 93 | if !with.recursive { |
| 94 | // This is a bit hackish as the CTE will be visited again as part of visiting `q`, |
| 95 | // but thankfully `insert_relation` is idempotent. |
| 96 | cte.visit(self)?; |
| 97 | } |
| 98 | let cte_name = ObjectName::from(vec![cte.alias.name.clone()]); |
| 99 | match object_name_to_table_reference( |
| 100 | cte_name, |
| 101 | self.enable_ident_normalization, |
| 102 | ) { |
| 103 | Ok(cte_ref) => self.ctes_in_scope.push(cte_ref), |
| 104 | Err(e) => return ControlFlow::Break(e), |
| 105 | } |
| 106 | } |
| 107 | } |
| 108 | ControlFlow::Continue(()) |
| 109 | } |
| 110 | |
| 111 | fn post_visit_query(&mut self, q: &Query) -> ControlFlow<Self::Break> { |
| 112 | if let Some(with) = &q.with { |
nothing calls this directly
no test coverage detected