inillucent_sql/
rewrite.rs1use crate::bind::{
36 BoundExpr, BoundFrameBound, BoundOrderTerm, BoundResultColumn, BoundSelect, BoundWindow,
37 SourceRows,
38};
39use crate::dml::{BoundDelete, BoundInsert, BoundInsertSource, BoundUpdate, ColumnSource};
40
41pub type Rewrite<'a> = &'a mut dyn FnMut(&mut BoundExpr);
43
44pub fn rewrite_expr(expr: &mut BoundExpr, rewrite: Rewrite<'_>) {
53 rewrite(expr);
54 for child in expr.children_mut() {
55 rewrite_expr(child, rewrite);
56 }
57 if let Some(block) = expr.block_mut() {
58 rewrite_select(block, rewrite);
59 }
60}
61
62fn rewrite_option(expr: Option<&mut BoundExpr>, rewrite: Rewrite<'_>) {
67 if let Some(expr) = expr {
68 rewrite_expr(expr, rewrite);
69 }
70}
71
72fn rewrite_columns(columns: &mut [BoundResultColumn], rewrite: Rewrite<'_>) {
77 for column in columns {
78 rewrite_expr(&mut column.expr, rewrite);
79 }
80}
81
82fn rewrite_order(terms: &mut [BoundOrderTerm], rewrite: Rewrite<'_>) {
87 for term in terms {
88 rewrite_expr(&mut term.expr, rewrite);
89 }
90}
91
92fn rewrite_bound(bound: &mut BoundFrameBound, rewrite: Rewrite<'_>) {
97 match bound {
98 BoundFrameBound::Preceding(expr) | BoundFrameBound::Following(expr) => {
99 rewrite_expr(expr, rewrite)
100 }
101 BoundFrameBound::UnboundedPreceding
102 | BoundFrameBound::CurrentRow
103 | BoundFrameBound::UnboundedFollowing => {}
104 }
105}
106
107fn rewrite_window(window: &mut BoundWindow, rewrite: Rewrite<'_>) {
112 for argument in &mut window.arguments {
113 rewrite_expr(argument, rewrite);
114 }
115 rewrite_option(window.filter.as_mut(), rewrite);
116 for term in &mut window.partition_by {
117 rewrite_expr(term, rewrite);
118 }
119 rewrite_order(&mut window.order_by, rewrite);
120 rewrite_bound(&mut window.start, rewrite);
121 rewrite_bound(&mut window.end, rewrite);
122}
123
124pub fn rewrite_select(select: &mut BoundSelect, rewrite: Rewrite<'_>) {
129 for source in &mut select.sources {
130 rewrite_option(source.constraint.as_mut(), rewrite);
131 match &mut source.rows {
132 SourceRows::Table | SourceRows::RecursiveSelf { .. } => {}
133 SourceRows::Subquery(block) => rewrite_select(block, rewrite),
134 SourceRows::Recursive(body) => {
135 for (_, arm) in body.seeds.iter_mut().chain(body.steps.iter_mut()) {
136 rewrite_select(arm, rewrite);
137 }
138 }
139 }
140 }
141 rewrite_option(select.filter.as_mut(), rewrite);
142 for term in &mut select.group_by {
143 rewrite_expr(term, rewrite);
144 }
145 rewrite_option(select.having.as_mut(), rewrite);
146 rewrite_columns(&mut select.columns, rewrite);
147 rewrite_order(&mut select.order_by, rewrite);
148 rewrite_option(select.limit.as_mut(), rewrite);
149 rewrite_option(select.offset.as_mut(), rewrite);
150 for aggregate in &mut select.aggregates {
151 for argument in &mut aggregate.arguments {
152 rewrite_expr(argument, rewrite);
153 }
154 }
155 for row in &mut select.values {
156 for value in row {
157 rewrite_expr(value, rewrite);
158 }
159 }
160 for (_, arm) in &mut select.compounds {
161 rewrite_select(arm, rewrite);
162 }
163 for window in &mut select.windows {
164 rewrite_window(window, rewrite);
165 }
166}
167
168fn rewrite_source(source: &mut ColumnSource, rewrite: Rewrite<'_>) {
173 match source {
174 ColumnSource::Row(_) => {}
175 ColumnSource::Expr(expr) | ColumnSource::Generated(expr) => rewrite_expr(expr, rewrite),
176 }
177}
178
179pub fn rewrite_insert(statement: &mut BoundInsert, rewrite: Rewrite<'_>) {
185 for column in &mut statement.columns {
186 rewrite_source(column, rewrite);
187 }
188 if let Some(rowid) = statement.rowid.as_mut() {
189 rewrite_source(rowid, rewrite);
190 }
191 match &mut statement.source {
192 BoundInsertSource::Values(rows) => {
193 for row in rows {
194 for value in row {
195 rewrite_expr(value, rewrite);
196 }
197 }
198 }
199 BoundInsertSource::Select(select) => rewrite_select(select, rewrite),
200 }
201 for check in &mut statement.checks {
202 rewrite_expr(&mut check.expr, rewrite);
203 }
204 for upsert in &mut statement.upsert {
205 for assignment in &mut upsert.assignments {
206 rewrite_expr(&mut assignment.value, rewrite);
207 }
208 rewrite_option(upsert.filter.as_mut(), rewrite);
209 }
210 rewrite_columns(&mut statement.returning, rewrite);
211}
212
213pub fn rewrite_update(statement: &mut BoundUpdate, rewrite: Rewrite<'_>) {
219 for assignment in &mut statement.assignments {
220 rewrite_expr(&mut assignment.value, rewrite);
221 }
222 for source in &mut statement.from {
228 rewrite_option(source.constraint.as_mut(), rewrite);
229 match &mut source.rows {
230 SourceRows::Table | SourceRows::RecursiveSelf { .. } => {}
231 SourceRows::Subquery(block) => rewrite_select(block, rewrite),
232 SourceRows::Recursive(body) => {
233 for (_, arm) in body.seeds.iter_mut().chain(body.steps.iter_mut()) {
234 rewrite_select(arm, rewrite);
235 }
236 }
237 }
238 }
239 rewrite_option(statement.filter.as_mut(), rewrite);
240 for check in &mut statement.checks {
241 rewrite_expr(&mut check.expr, rewrite);
242 }
243 rewrite_columns(&mut statement.returning, rewrite);
244 rewrite_order(&mut statement.order_by, rewrite);
245 rewrite_option(statement.limit.as_mut(), rewrite);
246 rewrite_option(statement.offset.as_mut(), rewrite);
247 if let Some(rows) = statement.view_rows.as_mut() {
248 rewrite_select(rows, rewrite);
249 }
250}
251
252pub fn rewrite_delete(statement: &mut BoundDelete, rewrite: Rewrite<'_>) {
258 rewrite_option(statement.filter.as_mut(), rewrite);
259 rewrite_columns(&mut statement.returning, rewrite);
260 rewrite_order(&mut statement.order_by, rewrite);
261 rewrite_option(statement.limit.as_mut(), rewrite);
262 rewrite_option(statement.offset.as_mut(), rewrite);
263 if let Some(rows) = statement.view_rows.as_mut() {
264 rewrite_select(rows, rewrite);
265 }
266}