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 rewrite_option(aggregate.filter.as_mut(), rewrite);
158 rewrite_order(&mut aggregate.order_by, rewrite);
159 }
160 for row in &mut select.values {
161 for value in row {
162 rewrite_expr(value, rewrite);
163 }
164 }
165 for (_, arm) in &mut select.compounds {
166 rewrite_select(arm, rewrite);
167 }
168 for window in &mut select.windows {
169 rewrite_window(window, rewrite);
170 }
171}
172
173fn rewrite_source(source: &mut ColumnSource, rewrite: Rewrite<'_>) {
178 match source {
179 ColumnSource::Row(_) => {}
180 ColumnSource::Expr(expr) | ColumnSource::Generated(expr) => rewrite_expr(expr, rewrite),
181 }
182}
183
184pub fn rewrite_insert(statement: &mut BoundInsert, rewrite: Rewrite<'_>) {
190 for column in &mut statement.columns {
191 rewrite_source(column, rewrite);
192 }
193 if let Some(rowid) = statement.rowid.as_mut() {
194 rewrite_source(rowid, rewrite);
195 }
196 match &mut statement.source {
197 BoundInsertSource::Values(rows) => {
198 for row in rows {
199 for value in row {
200 rewrite_expr(value, rewrite);
201 }
202 }
203 }
204 BoundInsertSource::Select(select) => rewrite_select(select, rewrite),
205 }
206 for check in &mut statement.checks {
207 rewrite_expr(&mut check.expr, rewrite);
208 }
209 for upsert in &mut statement.upsert {
210 for assignment in &mut upsert.assignments {
211 rewrite_expr(&mut assignment.value, rewrite);
212 }
213 rewrite_option(upsert.filter.as_mut(), rewrite);
214 }
215 rewrite_columns(&mut statement.returning, rewrite);
216}
217
218pub fn rewrite_update(statement: &mut BoundUpdate, rewrite: Rewrite<'_>) {
224 for assignment in &mut statement.assignments {
225 rewrite_expr(&mut assignment.value, rewrite);
226 }
227 for source in &mut statement.from {
233 rewrite_option(source.constraint.as_mut(), rewrite);
234 match &mut source.rows {
235 SourceRows::Table | SourceRows::RecursiveSelf { .. } => {}
236 SourceRows::Subquery(block) => rewrite_select(block, rewrite),
237 SourceRows::Recursive(body) => {
238 for (_, arm) in body.seeds.iter_mut().chain(body.steps.iter_mut()) {
239 rewrite_select(arm, rewrite);
240 }
241 }
242 }
243 }
244 rewrite_option(statement.filter.as_mut(), rewrite);
245 for check in &mut statement.checks {
246 rewrite_expr(&mut check.expr, rewrite);
247 }
248 rewrite_columns(&mut statement.returning, rewrite);
249 rewrite_order(&mut statement.order_by, rewrite);
250 rewrite_option(statement.limit.as_mut(), rewrite);
251 rewrite_option(statement.offset.as_mut(), rewrite);
252 if let Some(rows) = statement.view_rows.as_mut() {
253 rewrite_select(rows, rewrite);
254 }
255}
256
257pub fn rewrite_delete(statement: &mut BoundDelete, rewrite: Rewrite<'_>) {
263 rewrite_option(statement.filter.as_mut(), rewrite);
264 rewrite_columns(&mut statement.returning, rewrite);
265 rewrite_order(&mut statement.order_by, rewrite);
266 rewrite_option(statement.limit.as_mut(), rewrite);
267 rewrite_option(statement.offset.as_mut(), rewrite);
268 if let Some(rows) = statement.view_rows.as_mut() {
269 rewrite_select(rows, rewrite);
270 }
271}