1#![cfg_attr(
38 not(any(feature = "ast-tools", feature = "generate", feature = "semantic")),
39 allow(dead_code)
40)]
41
42use crate::expressions::{Expression, TableRef};
43use std::collections::{HashMap, VecDeque};
44
45pub type NodeId = usize;
47
48#[derive(Debug, Clone)]
50pub struct ParentInfo {
51 pub parent_id: Option<NodeId>,
53 pub arg_key: String,
55 pub index: Option<usize>,
57}
58
59#[derive(Debug, Default)]
73pub struct TreeContext {
74 nodes: HashMap<NodeId, ParentInfo>,
76 next_id: NodeId,
78 path: Vec<(NodeId, String, Option<usize>)>,
80}
81
82impl TreeContext {
83 pub fn new() -> Self {
85 Self::default()
86 }
87
88 pub fn build(root: &Expression) -> Self {
90 let mut ctx = Self::new();
91 ctx.visit_expr(root);
92 ctx
93 }
94
95 fn visit_expr(&mut self, expr: &Expression) -> NodeId {
97 let id = self.next_id;
98 self.next_id += 1;
99
100 let parent_info = if let Some((parent_id, arg_key, index)) = self.path.last() {
102 ParentInfo {
103 parent_id: Some(*parent_id),
104 arg_key: arg_key.clone(),
105 index: *index,
106 }
107 } else {
108 ParentInfo {
109 parent_id: None,
110 arg_key: String::new(),
111 index: None,
112 }
113 };
114 self.nodes.insert(id, parent_info);
115
116 for (key, child) in iter_children(expr) {
118 self.path.push((id, key.to_string(), None));
119 self.visit_expr(child);
120 self.path.pop();
121 }
122
123 for (key, children) in iter_children_lists(expr) {
125 for (idx, child) in children.iter().enumerate() {
126 self.path.push((id, key.to_string(), Some(idx)));
127 self.visit_expr(child);
128 self.path.pop();
129 }
130 }
131
132 id
133 }
134
135 pub fn get(&self, id: NodeId) -> Option<&ParentInfo> {
137 self.nodes.get(&id)
138 }
139
140 pub fn depth_of(&self, id: NodeId) -> usize {
142 let mut depth = 0;
143 let mut current = id;
144 while let Some(info) = self.nodes.get(¤t) {
145 if let Some(parent_id) = info.parent_id {
146 depth += 1;
147 current = parent_id;
148 } else {
149 break;
150 }
151 }
152 depth
153 }
154
155 pub fn ancestors_of(&self, id: NodeId) -> Vec<NodeId> {
157 let mut ancestors = Vec::new();
158 let mut current = id;
159 while let Some(info) = self.nodes.get(¤t) {
160 if let Some(parent_id) = info.parent_id {
161 ancestors.push(parent_id);
162 current = parent_id;
163 } else {
164 break;
165 }
166 }
167 ancestors
168 }
169}
170
171fn iter_children(expr: &Expression) -> Vec<(&'static str, &Expression)> {
175 let mut children = Vec::new();
176
177 match expr {
178 Expression::Select(s) => {
179 if let Some(from) = &s.from {
180 for source in &from.expressions {
181 children.push(("from", source));
182 }
183 }
184 for join in &s.joins {
185 children.push(("join_this", &join.this));
186 if let Some(on) = &join.on {
187 children.push(("join_on", on));
188 }
189 if let Some(match_condition) = &join.match_condition {
190 children.push(("join_match_condition", match_condition));
191 }
192 for pivot in &join.pivots {
193 children.push(("join_pivot", pivot));
194 }
195 }
196 for lateral_view in &s.lateral_views {
197 children.push(("lateral_view", &lateral_view.this));
198 }
199 if let Some(prewhere) = &s.prewhere {
200 children.push(("prewhere", prewhere));
201 }
202 if let Some(where_clause) = &s.where_clause {
203 children.push(("where", &where_clause.this));
204 }
205 if let Some(group_by) = &s.group_by {
206 for e in &group_by.expressions {
207 children.push(("group_by", e));
208 }
209 }
210 if let Some(having) = &s.having {
211 children.push(("having", &having.this));
212 }
213 if let Some(qualify) = &s.qualify {
214 children.push(("qualify", &qualify.this));
215 }
216 if let Some(order_by) = &s.order_by {
217 for ordered in &order_by.expressions {
218 children.push(("order_by", &ordered.this));
219 }
220 }
221 if let Some(distribute_by) = &s.distribute_by {
222 for e in &distribute_by.expressions {
223 children.push(("distribute_by", e));
224 }
225 }
226 if let Some(cluster_by) = &s.cluster_by {
227 for ordered in &cluster_by.expressions {
228 children.push(("cluster_by", &ordered.this));
229 }
230 }
231 if let Some(sort_by) = &s.sort_by {
232 for ordered in &sort_by.expressions {
233 children.push(("sort_by", &ordered.this));
234 }
235 }
236 if let Some(limit) = &s.limit {
237 children.push(("limit", &limit.this));
238 }
239 if let Some(offset) = &s.offset {
240 children.push(("offset", &offset.this));
241 }
242 if let Some(limit_by) = &s.limit_by {
243 for e in limit_by {
244 children.push(("limit_by", e));
245 }
246 }
247 if let Some(fetch) = &s.fetch {
248 if let Some(count) = &fetch.count {
249 children.push(("fetch", count));
250 }
251 }
252 if let Some(top) = &s.top {
253 children.push(("top", &top.this));
254 }
255 if let Some(with) = &s.with {
256 for cte in &with.ctes {
257 children.push(("with_cte", &cte.this));
258 }
259 if let Some(search) = &with.search {
260 children.push(("with_search", search));
261 }
262 }
263 if let Some(sample) = &s.sample {
264 children.push(("sample_size", &sample.size));
265 if let Some(seed) = &sample.seed {
266 children.push(("sample_seed", seed));
267 }
268 if let Some(offset) = &sample.offset {
269 children.push(("sample_offset", offset));
270 }
271 if let Some(bucket_numerator) = &sample.bucket_numerator {
272 children.push(("sample_bucket_numerator", bucket_numerator));
273 }
274 if let Some(bucket_denominator) = &sample.bucket_denominator {
275 children.push(("sample_bucket_denominator", bucket_denominator));
276 }
277 if let Some(bucket_field) = &sample.bucket_field {
278 children.push(("sample_bucket_field", bucket_field));
279 }
280 }
281 if let Some(connect) = &s.connect {
282 if let Some(start) = &connect.start {
283 children.push(("connect_start", start));
284 }
285 children.push(("connect", &connect.connect));
286 }
287 if let Some(into) = &s.into {
288 children.push(("into", &into.this));
289 }
290 for lock in &s.locks {
291 for e in &lock.expressions {
292 children.push(("lock_expression", e));
293 }
294 if let Some(wait) = &lock.wait {
295 children.push(("lock_wait", wait));
296 }
297 if let Some(key) = &lock.key {
298 children.push(("lock_key", key));
299 }
300 if let Some(update) = &lock.update {
301 children.push(("lock_update", update));
302 }
303 }
304 for e in &s.for_xml {
305 children.push(("for_xml", e));
306 }
307 }
308 Expression::With(with) => {
309 for cte in &with.ctes {
310 children.push(("cte", &cte.this));
311 }
312 if let Some(search) = &with.search {
313 children.push(("search", search));
314 }
315 }
316 Expression::Cte(cte) => {
317 children.push(("this", &cte.this));
318 }
319 Expression::Insert(insert) => {
320 if let Some(query) = &insert.query {
321 children.push(("query", query));
322 }
323 if let Some(with) = &insert.with {
324 for cte in &with.ctes {
325 children.push(("with_cte", &cte.this));
326 }
327 if let Some(search) = &with.search {
328 children.push(("with_search", search));
329 }
330 }
331 if let Some(on_conflict) = &insert.on_conflict {
332 children.push(("on_conflict", on_conflict));
333 }
334 if let Some(replace_where) = &insert.replace_where {
335 children.push(("replace_where", replace_where));
336 }
337 if let Some(source) = &insert.source {
338 children.push(("source", source));
339 }
340 if let Some(function_target) = &insert.function_target {
341 children.push(("function_target", function_target));
342 }
343 if let Some(partition_by) = &insert.partition_by {
344 children.push(("partition_by", partition_by));
345 }
346 if let Some(output) = &insert.output {
347 for column in &output.columns {
348 children.push(("output_column", column));
349 }
350 if let Some(into_table) = &output.into_table {
351 children.push(("output_into_table", into_table));
352 }
353 }
354 for row in &insert.values {
355 for value in row {
356 children.push(("value", value));
357 }
358 }
359 for (_, value) in &insert.partition {
360 if let Some(value) = value {
361 children.push(("partition_value", value));
362 }
363 }
364 for returning in &insert.returning {
365 children.push(("returning", returning));
366 }
367 for setting in &insert.settings {
368 children.push(("setting", setting));
369 }
370 }
371 Expression::Update(update) => {
372 if let Some(from_clause) = &update.from_clause {
373 for source in &from_clause.expressions {
374 children.push(("from", source));
375 }
376 }
377 for join in &update.table_joins {
378 children.push(("table_join_this", &join.this));
379 if let Some(on) = &join.on {
380 children.push(("table_join_on", on));
381 }
382 }
383 for join in &update.from_joins {
384 children.push(("from_join_this", &join.this));
385 if let Some(on) = &join.on {
386 children.push(("from_join_on", on));
387 }
388 }
389 for (_, value) in &update.set {
390 children.push(("set_value", value));
391 }
392 if let Some(where_clause) = &update.where_clause {
393 children.push(("where", &where_clause.this));
394 }
395 if let Some(output) = &update.output {
396 for column in &output.columns {
397 children.push(("output_column", column));
398 }
399 if let Some(into_table) = &output.into_table {
400 children.push(("output_into_table", into_table));
401 }
402 }
403 if let Some(with) = &update.with {
404 for cte in &with.ctes {
405 children.push(("with_cte", &cte.this));
406 }
407 if let Some(search) = &with.search {
408 children.push(("with_search", search));
409 }
410 }
411 if let Some(limit) = &update.limit {
412 children.push(("limit", limit));
413 }
414 if let Some(order_by) = &update.order_by {
415 for ordered in &order_by.expressions {
416 children.push(("order_by", &ordered.this));
417 }
418 }
419 for returning in &update.returning {
420 children.push(("returning", returning));
421 }
422 }
423 Expression::Delete(delete) => {
424 if let Some(with) = &delete.with {
425 for cte in &with.ctes {
426 children.push(("with_cte", &cte.this));
427 }
428 if let Some(search) = &with.search {
429 children.push(("with_search", search));
430 }
431 }
432 if let Some(where_clause) = &delete.where_clause {
433 children.push(("where", &where_clause.this));
434 }
435 if let Some(output) = &delete.output {
436 for column in &output.columns {
437 children.push(("output_column", column));
438 }
439 if let Some(into_table) = &output.into_table {
440 children.push(("output_into_table", into_table));
441 }
442 }
443 if let Some(limit) = &delete.limit {
444 children.push(("limit", limit));
445 }
446 if let Some(order_by) = &delete.order_by {
447 for ordered in &order_by.expressions {
448 children.push(("order_by", &ordered.this));
449 }
450 }
451 for returning in &delete.returning {
452 children.push(("returning", returning));
453 }
454 for join in &delete.joins {
455 children.push(("join_this", &join.this));
456 if let Some(on) = &join.on {
457 children.push(("join_on", on));
458 }
459 }
460 }
461 Expression::Join(join) => {
462 children.push(("this", &join.this));
463 if let Some(on) = &join.on {
464 children.push(("on", on));
465 }
466 if let Some(match_condition) = &join.match_condition {
467 children.push(("match_condition", match_condition));
468 }
469 for pivot in &join.pivots {
470 children.push(("pivot", pivot));
471 }
472 }
473 Expression::Alias(a) => {
474 children.push(("this", &a.this));
475 }
476 Expression::Cast(c) => {
477 children.push(("this", &c.this));
478 }
479 Expression::Not(u) | Expression::Neg(u) | Expression::BitwiseNot(u) => {
480 children.push(("this", &u.this));
481 }
482 Expression::Paren(p) => {
483 children.push(("this", &p.this));
484 }
485 Expression::IsNull(i) => {
486 children.push(("this", &i.this));
487 }
488 Expression::Exists(e) => {
489 children.push(("this", &e.this));
490 }
491 Expression::Subquery(s) => {
492 children.push(("this", &s.this));
493 }
494 Expression::Where(w) => {
495 children.push(("this", &w.this));
496 }
497 Expression::Having(h) => {
498 children.push(("this", &h.this));
499 }
500 Expression::Qualify(q) => {
501 children.push(("this", &q.this));
502 }
503 Expression::And(op)
504 | Expression::Or(op)
505 | Expression::Add(op)
506 | Expression::Sub(op)
507 | Expression::Mul(op)
508 | Expression::Div(op)
509 | Expression::Mod(op)
510 | Expression::Eq(op)
511 | Expression::Neq(op)
512 | Expression::Lt(op)
513 | Expression::Lte(op)
514 | Expression::Gt(op)
515 | Expression::Gte(op)
516 | Expression::BitwiseAnd(op)
517 | Expression::BitwiseOr(op)
518 | Expression::BitwiseXor(op)
519 | Expression::Concat(op) => {
520 children.push(("left", &op.left));
521 children.push(("right", &op.right));
522 }
523 Expression::Like(op) | Expression::ILike(op) => {
524 children.push(("left", &op.left));
525 children.push(("right", &op.right));
526 }
527 Expression::Between(b) => {
528 children.push(("this", &b.this));
529 children.push(("low", &b.low));
530 children.push(("high", &b.high));
531 }
532 Expression::In(i) => {
533 children.push(("this", &i.this));
534 if let Some(ref query) = i.query {
535 children.push(("query", query));
536 }
537 if let Some(ref unnest) = i.unnest {
538 children.push(("unnest", unnest));
539 }
540 }
541 Expression::Case(c) => {
542 if let Some(ref operand) = &c.operand {
543 children.push(("operand", operand));
544 }
545 }
546 Expression::WindowFunction(wf) => {
547 children.push(("this", &wf.this));
548 }
549 Expression::Union(u) => {
550 children.push(("left", &u.left));
551 children.push(("right", &u.right));
552 if let Some(with) = &u.with {
553 for cte in &with.ctes {
554 children.push(("with_cte", &cte.this));
555 }
556 if let Some(search) = &with.search {
557 children.push(("with_search", search));
558 }
559 }
560 if let Some(order_by) = &u.order_by {
561 for ordered in &order_by.expressions {
562 children.push(("order_by", &ordered.this));
563 }
564 }
565 if let Some(limit) = &u.limit {
566 children.push(("limit", limit));
567 }
568 if let Some(offset) = &u.offset {
569 children.push(("offset", offset));
570 }
571 if let Some(distribute_by) = &u.distribute_by {
572 for e in &distribute_by.expressions {
573 children.push(("distribute_by", e));
574 }
575 }
576 if let Some(sort_by) = &u.sort_by {
577 for ordered in &sort_by.expressions {
578 children.push(("sort_by", &ordered.this));
579 }
580 }
581 if let Some(cluster_by) = &u.cluster_by {
582 for ordered in &cluster_by.expressions {
583 children.push(("cluster_by", &ordered.this));
584 }
585 }
586 for e in &u.on_columns {
587 children.push(("on_column", e));
588 }
589 }
590 Expression::Intersect(i) => {
591 children.push(("left", &i.left));
592 children.push(("right", &i.right));
593 if let Some(with) = &i.with {
594 for cte in &with.ctes {
595 children.push(("with_cte", &cte.this));
596 }
597 if let Some(search) = &with.search {
598 children.push(("with_search", search));
599 }
600 }
601 if let Some(order_by) = &i.order_by {
602 for ordered in &order_by.expressions {
603 children.push(("order_by", &ordered.this));
604 }
605 }
606 if let Some(limit) = &i.limit {
607 children.push(("limit", limit));
608 }
609 if let Some(offset) = &i.offset {
610 children.push(("offset", offset));
611 }
612 if let Some(distribute_by) = &i.distribute_by {
613 for e in &distribute_by.expressions {
614 children.push(("distribute_by", e));
615 }
616 }
617 if let Some(sort_by) = &i.sort_by {
618 for ordered in &sort_by.expressions {
619 children.push(("sort_by", &ordered.this));
620 }
621 }
622 if let Some(cluster_by) = &i.cluster_by {
623 for ordered in &cluster_by.expressions {
624 children.push(("cluster_by", &ordered.this));
625 }
626 }
627 for e in &i.on_columns {
628 children.push(("on_column", e));
629 }
630 }
631 Expression::Except(e) => {
632 children.push(("left", &e.left));
633 children.push(("right", &e.right));
634 if let Some(with) = &e.with {
635 for cte in &with.ctes {
636 children.push(("with_cte", &cte.this));
637 }
638 if let Some(search) = &with.search {
639 children.push(("with_search", search));
640 }
641 }
642 if let Some(order_by) = &e.order_by {
643 for ordered in &order_by.expressions {
644 children.push(("order_by", &ordered.this));
645 }
646 }
647 if let Some(limit) = &e.limit {
648 children.push(("limit", limit));
649 }
650 if let Some(offset) = &e.offset {
651 children.push(("offset", offset));
652 }
653 if let Some(distribute_by) = &e.distribute_by {
654 for expr in &distribute_by.expressions {
655 children.push(("distribute_by", expr));
656 }
657 }
658 if let Some(sort_by) = &e.sort_by {
659 for ordered in &sort_by.expressions {
660 children.push(("sort_by", &ordered.this));
661 }
662 }
663 if let Some(cluster_by) = &e.cluster_by {
664 for ordered in &cluster_by.expressions {
665 children.push(("cluster_by", &ordered.this));
666 }
667 }
668 for expr in &e.on_columns {
669 children.push(("on_column", expr));
670 }
671 }
672 Expression::Merge(merge) => {
673 children.push(("this", &merge.this));
674 children.push(("using", &merge.using));
675 if let Some(on) = &merge.on {
676 children.push(("on", on));
677 }
678 if let Some(using_cond) = &merge.using_cond {
679 children.push(("using_cond", using_cond));
680 }
681 if let Some(whens) = &merge.whens {
682 children.push(("whens", whens));
683 }
684 if let Some(with_) = &merge.with_ {
685 children.push(("with_", with_));
686 }
687 if let Some(returning) = &merge.returning {
688 children.push(("returning", returning));
689 }
690 }
691 Expression::Any(q) | Expression::All(q) => {
692 children.push(("this", &q.this));
693 children.push(("subquery", &q.subquery));
694 }
695 Expression::Ordered(o) => {
696 children.push(("this", &o.this));
697 }
698 Expression::Interval(i) => {
699 if let Some(ref this) = i.this {
700 children.push(("this", this));
701 }
702 }
703 Expression::Describe(d) => {
704 children.push(("target", &d.target));
705 }
706 Expression::CreateTask(ct) => {
707 children.push(("body", &ct.body));
708 }
709 Expression::Prepare(prepare) => {
710 children.push(("statement", &prepare.statement));
711 }
712 Expression::Execute(exec) => {
713 children.push(("this", &exec.this));
714 for argument in &exec.arguments {
715 children.push(("argument", argument));
716 }
717 for parameter in &exec.parameters {
718 children.push(("parameter", ¶meter.value));
719 }
720 }
721 Expression::Analyze(a) => {
722 if let Some(this) = &a.this {
723 children.push(("this", this));
724 }
725 if let Some(expr) = &a.expression {
726 children.push(("expression", expr));
727 }
728 }
729 _ => {}
730 }
731
732 children
733}
734
735fn iter_children_lists(expr: &Expression) -> Vec<(&'static str, &[Expression])> {
739 let mut lists = Vec::new();
740
741 match expr {
742 Expression::Select(s) => lists.push(("expressions", s.expressions.as_slice())),
743 Expression::Function(f) => {
744 lists.push(("args", f.args.as_slice()));
745 }
746 Expression::AggregateFunction(f) => {
747 lists.push(("args", f.args.as_slice()));
748 }
749 Expression::From(f) => {
750 lists.push(("expressions", f.expressions.as_slice()));
751 }
752 Expression::GroupBy(g) => {
753 lists.push(("expressions", g.expressions.as_slice()));
754 }
755 Expression::In(i) => {
758 lists.push(("expressions", i.expressions.as_slice()));
759 }
760 Expression::Array(a) => {
761 lists.push(("expressions", a.expressions.as_slice()));
762 }
763 Expression::Tuple(t) => {
764 lists.push(("expressions", t.expressions.as_slice()));
765 }
766 Expression::TryCatch(try_catch) => {
767 lists.push(("try_body", try_catch.try_body.as_slice()));
768 if let Some(catch_body) = &try_catch.catch_body {
769 lists.push(("catch_body", catch_body.as_slice()));
770 }
771 }
772 Expression::Coalesce(c) => {
774 lists.push(("expressions", c.expressions.as_slice()));
775 }
776 Expression::Greatest(g) | Expression::Least(g) => {
777 lists.push(("expressions", g.expressions.as_slice()));
778 }
779 _ => {}
780 }
781
782 lists
783}
784
785pub struct DfsIter<'a> {
794 stack: Vec<&'a Expression>,
795}
796
797impl<'a> DfsIter<'a> {
798 pub fn new(root: &'a Expression) -> Self {
800 Self { stack: vec![root] }
801 }
802}
803
804impl<'a> Iterator for DfsIter<'a> {
805 type Item = &'a Expression;
806
807 fn next(&mut self) -> Option<Self::Item> {
808 let expr = self.stack.pop()?;
809
810 let children: Vec<_> = iter_children(expr).into_iter().map(|(_, e)| e).collect();
812 for child in children.into_iter().rev() {
813 self.stack.push(child);
814 }
815
816 let lists: Vec<_> = iter_children_lists(expr)
817 .into_iter()
818 .flat_map(|(_, es)| es.iter())
819 .collect();
820 for child in lists.into_iter().rev() {
821 self.stack.push(child);
822 }
823
824 Some(expr)
825 }
826}
827
828pub struct BfsIter<'a> {
836 queue: VecDeque<&'a Expression>,
837}
838
839impl<'a> BfsIter<'a> {
840 pub fn new(root: &'a Expression) -> Self {
842 let mut queue = VecDeque::new();
843 queue.push_back(root);
844 Self { queue }
845 }
846}
847
848impl<'a> Iterator for BfsIter<'a> {
849 type Item = &'a Expression;
850
851 fn next(&mut self) -> Option<Self::Item> {
852 let expr = self.queue.pop_front()?;
853
854 for (_, child) in iter_children(expr) {
856 self.queue.push_back(child);
857 }
858
859 for (_, children) in iter_children_lists(expr) {
860 for child in children {
861 self.queue.push_back(child);
862 }
863 }
864
865 Some(expr)
866 }
867}
868
869pub trait ExpressionWalk {
875 fn dfs(&self) -> DfsIter<'_>;
880
881 fn bfs(&self) -> BfsIter<'_>;
885
886 fn find<F>(&self, predicate: F) -> Option<&Expression>
890 where
891 F: Fn(&Expression) -> bool;
892
893 fn find_all<F>(&self, predicate: F) -> Vec<&Expression>
897 where
898 F: Fn(&Expression) -> bool;
899
900 fn contains<F>(&self, predicate: F) -> bool
902 where
903 F: Fn(&Expression) -> bool;
904
905 fn count<F>(&self, predicate: F) -> usize
907 where
908 F: Fn(&Expression) -> bool;
909
910 fn children(&self) -> Vec<&Expression>;
915
916 fn tree_depth(&self) -> usize;
920
921 #[cfg(any(
927 feature = "transpile",
928 feature = "ast-tools",
929 feature = "generate",
930 feature = "semantic"
931 ))]
932 fn transform_owned<F>(self, fun: F) -> crate::Result<Expression>
933 where
934 F: Fn(Expression) -> crate::Result<Option<Expression>>,
935 Self: Sized;
936}
937
938impl ExpressionWalk for Expression {
939 fn dfs(&self) -> DfsIter<'_> {
940 DfsIter::new(self)
941 }
942
943 fn bfs(&self) -> BfsIter<'_> {
944 BfsIter::new(self)
945 }
946
947 fn find<F>(&self, predicate: F) -> Option<&Expression>
948 where
949 F: Fn(&Expression) -> bool,
950 {
951 self.dfs().find(|e| predicate(e))
952 }
953
954 fn find_all<F>(&self, predicate: F) -> Vec<&Expression>
955 where
956 F: Fn(&Expression) -> bool,
957 {
958 self.dfs().filter(|e| predicate(e)).collect()
959 }
960
961 fn contains<F>(&self, predicate: F) -> bool
962 where
963 F: Fn(&Expression) -> bool,
964 {
965 self.dfs().any(|e| predicate(e))
966 }
967
968 fn count<F>(&self, predicate: F) -> usize
969 where
970 F: Fn(&Expression) -> bool,
971 {
972 self.dfs().filter(|e| predicate(e)).count()
973 }
974
975 fn children(&self) -> Vec<&Expression> {
976 let mut result: Vec<&Expression> = Vec::new();
977 for (_, child) in iter_children(self) {
978 result.push(child);
979 }
980 for (_, children_list) in iter_children_lists(self) {
981 for child in children_list {
982 result.push(child);
983 }
984 }
985 result
986 }
987
988 fn tree_depth(&self) -> usize {
989 let mut max_depth = 0;
990
991 for (_, child) in iter_children(self) {
992 let child_depth = child.tree_depth();
993 if child_depth + 1 > max_depth {
994 max_depth = child_depth + 1;
995 }
996 }
997
998 for (_, children) in iter_children_lists(self) {
999 for child in children {
1000 let child_depth = child.tree_depth();
1001 if child_depth + 1 > max_depth {
1002 max_depth = child_depth + 1;
1003 }
1004 }
1005 }
1006
1007 max_depth
1008 }
1009
1010 #[cfg(any(
1011 feature = "transpile",
1012 feature = "ast-tools",
1013 feature = "generate",
1014 feature = "semantic"
1015 ))]
1016 fn transform_owned<F>(self, fun: F) -> crate::Result<Expression>
1017 where
1018 F: Fn(Expression) -> crate::Result<Option<Expression>>,
1019 {
1020 transform(self, &fun)
1021 }
1022}
1023
1024#[cfg(any(
1045 feature = "transpile",
1046 feature = "ast-tools",
1047 feature = "generate",
1048 feature = "semantic"
1049))]
1050pub fn transform<F>(expr: Expression, fun: &F) -> crate::Result<Expression>
1051where
1052 F: Fn(Expression) -> crate::Result<Option<Expression>>,
1053{
1054 crate::dialects::transform_recursive(expr, &|e| match fun(e)? {
1055 Some(transformed) => Ok(transformed),
1056 None => Ok(Expression::Null(crate::expressions::Null)),
1057 })
1058}
1059
1060#[cfg(any(
1081 feature = "transpile",
1082 feature = "ast-tools",
1083 feature = "generate",
1084 feature = "semantic"
1085))]
1086pub fn transform_map<F>(expr: Expression, fun: &F) -> crate::Result<Expression>
1087where
1088 F: Fn(Expression) -> crate::Result<Expression>,
1089{
1090 crate::dialects::transform_recursive(expr, fun)
1091}
1092
1093pub fn is_column(expr: &Expression) -> bool {
1101 matches!(expr, Expression::Column(_))
1102}
1103
1104pub fn is_literal(expr: &Expression) -> bool {
1106 matches!(
1107 expr,
1108 Expression::Literal(_) | Expression::Boolean(_) | Expression::Null(_)
1109 )
1110}
1111
1112pub fn is_function(expr: &Expression) -> bool {
1114 matches!(
1115 expr,
1116 Expression::Function(_) | Expression::AggregateFunction(_)
1117 )
1118}
1119
1120pub fn is_subquery(expr: &Expression) -> bool {
1122 matches!(expr, Expression::Subquery(_))
1123}
1124
1125pub fn is_select(expr: &Expression) -> bool {
1127 matches!(expr, Expression::Select(_))
1128}
1129
1130pub fn is_aggregate(expr: &Expression) -> bool {
1132 matches!(
1133 expr,
1134 Expression::AggregateFunction(_)
1135 | Expression::Count(_)
1136 | Expression::Sum(_)
1137 | Expression::Avg(_)
1138 | Expression::Min(_)
1139 | Expression::Max(_)
1140 | Expression::GroupConcat(_)
1141 | Expression::StringAgg(_)
1142 | Expression::ListAgg(_)
1143 | Expression::CountIf(_)
1144 | Expression::SumIf(_)
1145 )
1146}
1147
1148pub fn is_window_function(expr: &Expression) -> bool {
1150 matches!(expr, Expression::WindowFunction(_))
1151}
1152
1153pub fn get_columns(expr: &Expression) -> Vec<&Expression> {
1157 expr.find_all(is_column)
1158}
1159
1160pub fn get_tables(expr: &Expression) -> Vec<&Expression> {
1168 expr.find_all(|e| matches!(e, Expression::Table(_)))
1169}
1170
1171pub fn get_all_tables(expr: &Expression) -> Vec<Expression> {
1179 use std::collections::HashSet;
1180
1181 let mut seen = HashSet::new();
1182 let mut result = Vec::new();
1183
1184 for node in expr.dfs() {
1186 if let Expression::Table(t) = node {
1187 let qname = table_ref_qualified_name(t);
1188 if seen.insert(qname) {
1189 result.push(node.clone());
1190 }
1191 }
1192
1193 let refs: Vec<&TableRef> = match node {
1195 Expression::Insert(ins) => vec![&ins.table],
1196 Expression::Update(upd) => {
1197 let mut v = vec![&upd.table];
1198 v.extend(upd.extra_tables.iter());
1199 v
1200 }
1201 Expression::Delete(del) => {
1202 let mut v = vec![&del.table];
1203 v.extend(del.using.iter());
1204 v
1205 }
1206 _ => continue,
1207 };
1208 for tref in refs {
1209 if tref.name.name.is_empty() {
1210 continue;
1211 }
1212 let qname = table_ref_qualified_name(tref);
1213 if seen.insert(qname) {
1214 result.push(Expression::Table(Box::new(tref.clone())));
1215 }
1216 }
1217 }
1218
1219 result
1220}
1221
1222fn table_ref_qualified_name(t: &TableRef) -> String {
1224 let mut name = String::new();
1225 if let Some(ref cat) = t.catalog {
1226 name.push_str(&cat.name);
1227 name.push('.');
1228 }
1229 if let Some(ref schema) = t.schema {
1230 name.push_str(&schema.name);
1231 name.push('.');
1232 }
1233 name.push_str(&t.name.name);
1234 name
1235}
1236
1237fn unwrap_merge_table(expr: &Expression) -> Option<&Expression> {
1241 match expr {
1242 Expression::Table(_) => Some(expr),
1243 Expression::Alias(alias) => match &alias.this {
1244 Expression::Table(_) => Some(&alias.this),
1245 _ => None,
1246 },
1247 _ => None,
1248 }
1249}
1250
1251pub fn get_merge_target(expr: &Expression) -> Option<&Expression> {
1256 match expr {
1257 Expression::Merge(m) => unwrap_merge_table(&m.this),
1258 _ => None,
1259 }
1260}
1261
1262pub fn get_merge_source(expr: &Expression) -> Option<&Expression> {
1268 match expr {
1269 Expression::Merge(m) => unwrap_merge_table(&m.using),
1270 _ => None,
1271 }
1272}
1273
1274pub fn contains_aggregate(expr: &Expression) -> bool {
1276 expr.contains(is_aggregate)
1277}
1278
1279pub fn contains_window_function(expr: &Expression) -> bool {
1281 expr.contains(is_window_function)
1282}
1283
1284pub fn contains_subquery(expr: &Expression) -> bool {
1286 expr.contains(is_subquery)
1287}
1288
1289macro_rules! is_type {
1295 ($name:ident, $($variant:pat),+ $(,)?) => {
1296 pub fn $name(expr: &Expression) -> bool {
1298 matches!(expr, $($variant)|+)
1299 }
1300 };
1301}
1302
1303is_type!(is_insert, Expression::Insert(_));
1305is_type!(is_update, Expression::Update(_));
1306is_type!(is_delete, Expression::Delete(_));
1307is_type!(is_merge, Expression::Merge(_));
1308is_type!(is_union, Expression::Union(_));
1309is_type!(is_intersect, Expression::Intersect(_));
1310is_type!(is_except, Expression::Except(_));
1311
1312is_type!(is_boolean, Expression::Boolean(_));
1314is_type!(is_null_literal, Expression::Null(_));
1315is_type!(is_star, Expression::Star(_));
1316is_type!(is_identifier, Expression::Identifier(_));
1317is_type!(is_table, Expression::Table(_));
1318
1319is_type!(is_eq, Expression::Eq(_));
1321is_type!(is_neq, Expression::Neq(_));
1322is_type!(is_lt, Expression::Lt(_));
1323is_type!(is_lte, Expression::Lte(_));
1324is_type!(is_gt, Expression::Gt(_));
1325is_type!(is_gte, Expression::Gte(_));
1326is_type!(is_like, Expression::Like(_));
1327is_type!(is_ilike, Expression::ILike(_));
1328
1329is_type!(is_add, Expression::Add(_));
1331is_type!(is_sub, Expression::Sub(_));
1332is_type!(is_mul, Expression::Mul(_));
1333is_type!(is_div, Expression::Div(_));
1334is_type!(is_mod, Expression::Mod(_));
1335is_type!(is_concat, Expression::Concat(_));
1336
1337is_type!(is_and, Expression::And(_));
1339is_type!(is_or, Expression::Or(_));
1340is_type!(is_not, Expression::Not(_));
1341
1342is_type!(is_in, Expression::In(_));
1344is_type!(is_between, Expression::Between(_));
1345is_type!(is_is_null, Expression::IsNull(_));
1346is_type!(is_exists, Expression::Exists(_));
1347
1348is_type!(is_count, Expression::Count(_));
1350is_type!(is_sum, Expression::Sum(_));
1351is_type!(is_avg, Expression::Avg(_));
1352is_type!(is_min_func, Expression::Min(_));
1353is_type!(is_max_func, Expression::Max(_));
1354is_type!(is_coalesce, Expression::Coalesce(_));
1355is_type!(is_null_if, Expression::NullIf(_));
1356is_type!(is_cast, Expression::Cast(_));
1357is_type!(is_try_cast, Expression::TryCast(_));
1358is_type!(is_safe_cast, Expression::SafeCast(_));
1359is_type!(is_case, Expression::Case(_));
1360
1361is_type!(is_from, Expression::From(_));
1363is_type!(is_join, Expression::Join(_));
1364is_type!(is_where, Expression::Where(_));
1365is_type!(is_group_by, Expression::GroupBy(_));
1366is_type!(is_having, Expression::Having(_));
1367is_type!(is_order_by, Expression::OrderBy(_));
1368is_type!(is_limit, Expression::Limit(_));
1369is_type!(is_offset, Expression::Offset(_));
1370is_type!(is_with, Expression::With(_));
1371is_type!(is_cte, Expression::Cte(_));
1372is_type!(is_alias, Expression::Alias(_));
1373is_type!(is_paren, Expression::Paren(_));
1374is_type!(is_ordered, Expression::Ordered(_));
1375
1376is_type!(is_create_table, Expression::CreateTable(_));
1378is_type!(is_drop_table, Expression::DropTable(_));
1379is_type!(is_alter_table, Expression::AlterTable(_));
1380is_type!(is_create_index, Expression::CreateIndex(_));
1381is_type!(is_drop_index, Expression::DropIndex(_));
1382is_type!(is_create_view, Expression::CreateView(_));
1383is_type!(is_drop_view, Expression::DropView(_));
1384
1385pub fn is_query(expr: &Expression) -> bool {
1391 matches!(
1392 expr,
1393 Expression::Select(_)
1394 | Expression::Insert(_)
1395 | Expression::Update(_)
1396 | Expression::Delete(_)
1397 | Expression::Merge(_)
1398 )
1399}
1400
1401pub fn is_set_operation(expr: &Expression) -> bool {
1403 matches!(
1404 expr,
1405 Expression::Union(_) | Expression::Intersect(_) | Expression::Except(_)
1406 )
1407}
1408
1409pub fn is_comparison(expr: &Expression) -> bool {
1411 matches!(
1412 expr,
1413 Expression::Eq(_)
1414 | Expression::Neq(_)
1415 | Expression::Lt(_)
1416 | Expression::Lte(_)
1417 | Expression::Gt(_)
1418 | Expression::Gte(_)
1419 | Expression::Like(_)
1420 | Expression::ILike(_)
1421 )
1422}
1423
1424pub fn is_arithmetic(expr: &Expression) -> bool {
1426 matches!(
1427 expr,
1428 Expression::Add(_)
1429 | Expression::Sub(_)
1430 | Expression::Mul(_)
1431 | Expression::Div(_)
1432 | Expression::Mod(_)
1433 )
1434}
1435
1436pub fn is_logical(expr: &Expression) -> bool {
1438 matches!(
1439 expr,
1440 Expression::And(_) | Expression::Or(_) | Expression::Not(_)
1441 )
1442}
1443
1444pub fn is_ddl(expr: &Expression) -> bool {
1446 matches!(
1447 expr,
1448 Expression::CreateTable(_)
1449 | Expression::DropTable(_)
1450 | Expression::Undrop(_)
1451 | Expression::AlterTable(_)
1452 | Expression::CreateIndex(_)
1453 | Expression::DropIndex(_)
1454 | Expression::CreateView(_)
1455 | Expression::DropView(_)
1456 | Expression::AlterView(_)
1457 | Expression::CreateSchema(_)
1458 | Expression::DropSchema(_)
1459 | Expression::CreateDatabase(_)
1460 | Expression::DropDatabase(_)
1461 | Expression::CreateFunction(_)
1462 | Expression::DropFunction(_)
1463 | Expression::CreateProcedure(_)
1464 | Expression::DropProcedure(_)
1465 | Expression::CreateSequence(_)
1466 | Expression::CreateSynonym(_)
1467 | Expression::DropSequence(_)
1468 | Expression::AlterSequence(_)
1469 | Expression::CreateTrigger(_)
1470 | Expression::DropTrigger(_)
1471 | Expression::CreateType(_)
1472 | Expression::DropType(_)
1473 )
1474}
1475
1476pub fn find_parent<'a>(root: &'a Expression, target: &Expression) -> Option<&'a Expression> {
1483 fn search<'a>(node: &'a Expression, target: *const Expression) -> Option<&'a Expression> {
1484 for (_, child) in iter_children(node) {
1485 if std::ptr::eq(child, target) {
1486 return Some(node);
1487 }
1488 if let Some(found) = search(child, target) {
1489 return Some(found);
1490 }
1491 }
1492 for (_, children_list) in iter_children_lists(node) {
1493 for child in children_list {
1494 if std::ptr::eq(child, target) {
1495 return Some(node);
1496 }
1497 if let Some(found) = search(child, target) {
1498 return Some(found);
1499 }
1500 }
1501 }
1502 None
1503 }
1504
1505 search(root, target as *const Expression)
1506}
1507
1508pub fn find_ancestor<'a, F>(
1514 root: &'a Expression,
1515 target: &Expression,
1516 predicate: F,
1517) -> Option<&'a Expression>
1518where
1519 F: Fn(&Expression) -> bool,
1520{
1521 fn build_path<'a>(
1523 node: &'a Expression,
1524 target: *const Expression,
1525 path: &mut Vec<&'a Expression>,
1526 ) -> bool {
1527 if std::ptr::eq(node, target) {
1528 return true;
1529 }
1530 path.push(node);
1531 for (_, child) in iter_children(node) {
1532 if build_path(child, target, path) {
1533 return true;
1534 }
1535 }
1536 for (_, children_list) in iter_children_lists(node) {
1537 for child in children_list {
1538 if build_path(child, target, path) {
1539 return true;
1540 }
1541 }
1542 }
1543 path.pop();
1544 false
1545 }
1546
1547 let mut path = Vec::new();
1548 if !build_path(root, target as *const Expression, &mut path) {
1549 return None;
1550 }
1551
1552 for ancestor in path.iter().rev() {
1554 if predicate(ancestor) {
1555 return Some(ancestor);
1556 }
1557 }
1558 None
1559}
1560
1561#[cfg(test)]
1562mod tests {
1563 use super::*;
1564 use crate::expressions::{BinaryOp, Column, Identifier, Literal};
1565
1566 fn make_column(name: &str) -> Expression {
1567 Expression::boxed_column(Column {
1568 name: Identifier {
1569 name: name.to_string(),
1570 quoted: false,
1571 trailing_comments: vec![],
1572 span: None,
1573 },
1574 table: None,
1575 join_mark: false,
1576 trailing_comments: vec![],
1577 span: None,
1578 inferred_type: None,
1579 })
1580 }
1581
1582 fn make_literal(value: i64) -> Expression {
1583 Expression::Literal(Box::new(Literal::Number(value.to_string())))
1584 }
1585
1586 #[test]
1587 fn test_dfs_simple() {
1588 let left = make_column("a");
1589 let right = make_literal(1);
1590 let expr = Expression::Eq(Box::new(BinaryOp {
1591 left,
1592 right,
1593 left_comments: vec![],
1594 operator_comments: vec![],
1595 trailing_comments: vec![],
1596 inferred_type: None,
1597 }));
1598
1599 let nodes: Vec<_> = expr.dfs().collect();
1600 assert_eq!(nodes.len(), 3); assert!(matches!(nodes[0], Expression::Eq(_)));
1602 assert!(matches!(nodes[1], Expression::Column(_)));
1603 assert!(matches!(nodes[2], Expression::Literal(_)));
1604 }
1605
1606 #[test]
1607 fn test_find() {
1608 let left = make_column("a");
1609 let right = make_literal(1);
1610 let expr = Expression::Eq(Box::new(BinaryOp {
1611 left,
1612 right,
1613 left_comments: vec![],
1614 operator_comments: vec![],
1615 trailing_comments: vec![],
1616 inferred_type: None,
1617 }));
1618
1619 let column = expr.find(is_column);
1620 assert!(column.is_some());
1621 assert!(matches!(column.unwrap(), Expression::Column(_)));
1622
1623 let literal = expr.find(is_literal);
1624 assert!(literal.is_some());
1625 assert!(matches!(literal.unwrap(), Expression::Literal(_)));
1626 }
1627
1628 #[test]
1629 fn test_find_all() {
1630 let col1 = make_column("a");
1631 let col2 = make_column("b");
1632 let expr = Expression::And(Box::new(BinaryOp {
1633 left: col1,
1634 right: col2,
1635 left_comments: vec![],
1636 operator_comments: vec![],
1637 trailing_comments: vec![],
1638 inferred_type: None,
1639 }));
1640
1641 let columns = expr.find_all(is_column);
1642 assert_eq!(columns.len(), 2);
1643 }
1644
1645 #[test]
1646 fn test_contains() {
1647 let col = make_column("a");
1648 let lit = make_literal(1);
1649 let expr = Expression::Eq(Box::new(BinaryOp {
1650 left: col,
1651 right: lit,
1652 left_comments: vec![],
1653 operator_comments: vec![],
1654 trailing_comments: vec![],
1655 inferred_type: None,
1656 }));
1657
1658 assert!(expr.contains(is_column));
1659 assert!(expr.contains(is_literal));
1660 assert!(!expr.contains(is_subquery));
1661 }
1662
1663 #[test]
1664 fn test_count() {
1665 let col1 = make_column("a");
1666 let col2 = make_column("b");
1667 let lit = make_literal(1);
1668
1669 let inner = Expression::Add(Box::new(BinaryOp {
1670 left: col2,
1671 right: lit,
1672 left_comments: vec![],
1673 operator_comments: vec![],
1674 trailing_comments: vec![],
1675 inferred_type: None,
1676 }));
1677
1678 let expr = Expression::Eq(Box::new(BinaryOp {
1679 left: col1,
1680 right: inner,
1681 left_comments: vec![],
1682 operator_comments: vec![],
1683 trailing_comments: vec![],
1684 inferred_type: None,
1685 }));
1686
1687 assert_eq!(expr.count(is_column), 2);
1688 assert_eq!(expr.count(is_literal), 1);
1689 }
1690
1691 #[test]
1692 fn test_tree_depth() {
1693 let lit = make_literal(1);
1695 assert_eq!(lit.tree_depth(), 0);
1696
1697 let col = make_column("a");
1699 let expr = Expression::Eq(Box::new(BinaryOp {
1700 left: col,
1701 right: lit.clone(),
1702 left_comments: vec![],
1703 operator_comments: vec![],
1704 trailing_comments: vec![],
1705 inferred_type: None,
1706 }));
1707 assert_eq!(expr.tree_depth(), 1);
1708
1709 let inner = Expression::Add(Box::new(BinaryOp {
1711 left: make_column("b"),
1712 right: lit,
1713 left_comments: vec![],
1714 operator_comments: vec![],
1715 trailing_comments: vec![],
1716 inferred_type: None,
1717 }));
1718 let outer = Expression::Eq(Box::new(BinaryOp {
1719 left: make_column("a"),
1720 right: inner,
1721 left_comments: vec![],
1722 operator_comments: vec![],
1723 trailing_comments: vec![],
1724 inferred_type: None,
1725 }));
1726 assert_eq!(outer.tree_depth(), 2);
1727 }
1728
1729 #[test]
1730 fn test_tree_context() {
1731 let col = make_column("a");
1732 let lit = make_literal(1);
1733 let expr = Expression::Eq(Box::new(BinaryOp {
1734 left: col,
1735 right: lit,
1736 left_comments: vec![],
1737 operator_comments: vec![],
1738 trailing_comments: vec![],
1739 inferred_type: None,
1740 }));
1741
1742 let ctx = TreeContext::build(&expr);
1743
1744 let root_info = ctx.get(0).unwrap();
1746 assert!(root_info.parent_id.is_none());
1747
1748 let left_info = ctx.get(1).unwrap();
1750 assert_eq!(left_info.parent_id, Some(0));
1751 assert_eq!(left_info.arg_key, "left");
1752
1753 let right_info = ctx.get(2).unwrap();
1754 assert_eq!(right_info.parent_id, Some(0));
1755 assert_eq!(right_info.arg_key, "right");
1756 }
1757
1758 #[test]
1761 fn test_transform_rename_columns() {
1762 let ast = crate::parser::Parser::parse_sql("SELECT a, b FROM t").unwrap();
1763 let expr = ast[0].clone();
1764 let result = super::transform_map(expr, &|e| {
1765 if let Expression::Column(ref c) = e {
1766 if c.name.name == "a" {
1767 return Ok(Expression::boxed_column(Column {
1768 name: Identifier::new("alpha"),
1769 table: c.table.clone(),
1770 join_mark: false,
1771 trailing_comments: vec![],
1772 span: None,
1773 inferred_type: None,
1774 }));
1775 }
1776 }
1777 Ok(e)
1778 })
1779 .unwrap();
1780 let sql = crate::generator::Generator::sql(&result).unwrap();
1781 assert!(sql.contains("alpha"), "Expected 'alpha' in: {}", sql);
1782 assert!(sql.contains("b"), "Expected 'b' in: {}", sql);
1783 }
1784
1785 #[test]
1786 fn test_transform_noop() {
1787 let ast = crate::parser::Parser::parse_sql("SELECT 1 + 2").unwrap();
1788 let expr = ast[0].clone();
1789 let result = super::transform_map(expr.clone(), &|e| Ok(e)).unwrap();
1790 let sql1 = crate::generator::Generator::sql(&expr).unwrap();
1791 let sql2 = crate::generator::Generator::sql(&result).unwrap();
1792 assert_eq!(sql1, sql2);
1793 }
1794
1795 #[test]
1796 fn test_transform_nested() {
1797 let ast = crate::parser::Parser::parse_sql("SELECT a + b FROM t").unwrap();
1798 let expr = ast[0].clone();
1799 let result = super::transform_map(expr, &|e| {
1800 if let Expression::Column(ref c) = e {
1801 return Ok(Expression::Literal(Box::new(Literal::Number(
1802 if c.name.name == "a" { "1" } else { "2" }.to_string(),
1803 ))));
1804 }
1805 Ok(e)
1806 })
1807 .unwrap();
1808 let sql = crate::generator::Generator::sql(&result).unwrap();
1809 assert_eq!(sql, "SELECT 1 + 2 FROM t");
1810 }
1811
1812 #[test]
1813 fn test_transform_error() {
1814 let ast = crate::parser::Parser::parse_sql("SELECT a FROM t").unwrap();
1815 let expr = ast[0].clone();
1816 let result = super::transform_map(expr, &|e| {
1817 if let Expression::Column(ref c) = e {
1818 if c.name.name == "a" {
1819 return Err(crate::error::Error::parse("test error", 0, 0, 0, 0));
1820 }
1821 }
1822 Ok(e)
1823 });
1824 assert!(result.is_err());
1825 }
1826
1827 #[test]
1828 fn test_transform_owned_trait() {
1829 let ast = crate::parser::Parser::parse_sql("SELECT x FROM t").unwrap();
1830 let expr = ast[0].clone();
1831 let result = expr.transform_owned(|e| Ok(Some(e))).unwrap();
1832 let sql = crate::generator::Generator::sql(&result).unwrap();
1833 assert_eq!(sql, "SELECT x FROM t");
1834 }
1835
1836 #[test]
1839 fn test_children_leaf() {
1840 let lit = make_literal(1);
1841 assert_eq!(lit.children().len(), 0);
1842 }
1843
1844 #[test]
1845 fn test_children_binary_op() {
1846 let left = make_column("a");
1847 let right = make_literal(1);
1848 let expr = Expression::Eq(Box::new(BinaryOp {
1849 left,
1850 right,
1851 left_comments: vec![],
1852 operator_comments: vec![],
1853 trailing_comments: vec![],
1854 inferred_type: None,
1855 }));
1856 let children = expr.children();
1857 assert_eq!(children.len(), 2);
1858 assert!(matches!(children[0], Expression::Column(_)));
1859 assert!(matches!(children[1], Expression::Literal(_)));
1860 }
1861
1862 #[test]
1863 fn test_children_select() {
1864 let ast = crate::parser::Parser::parse_sql("SELECT a, b FROM t").unwrap();
1865 let expr = &ast[0];
1866 let children = expr.children();
1867 assert!(children.len() >= 2);
1869 }
1870
1871 #[test]
1872 fn test_children_select_includes_from_and_join_sources() {
1873 let ast = crate::parser::Parser::parse_sql(
1874 "SELECT u.id FROM users u JOIN orders o ON u.id = o.user_id",
1875 )
1876 .unwrap();
1877 let expr = &ast[0];
1878 let children = expr.children();
1879
1880 let table_names: Vec<&str> = children
1881 .iter()
1882 .filter_map(|e| match e {
1883 Expression::Table(t) => Some(t.name.name.as_str()),
1884 _ => None,
1885 })
1886 .collect();
1887
1888 assert!(table_names.contains(&"users"));
1889 assert!(table_names.contains(&"orders"));
1890 }
1891
1892 #[test]
1893 fn test_get_tables_includes_insert_query_sources() {
1894 let ast = crate::parser::Parser::parse_sql(
1895 "INSERT INTO dst (id) SELECT s.id FROM src s JOIN dim d ON s.id = d.id",
1896 )
1897 .unwrap();
1898 let expr = &ast[0];
1899 let tables = get_tables(expr);
1900 let names: Vec<&str> = tables
1901 .iter()
1902 .filter_map(|e| match e {
1903 Expression::Table(t) => Some(t.name.name.as_str()),
1904 _ => None,
1905 })
1906 .collect();
1907
1908 assert!(names.contains(&"src"));
1909 assert!(names.contains(&"dim"));
1910 }
1911
1912 #[test]
1915 fn test_find_parent_binary() {
1916 let left = make_column("a");
1917 let right = make_literal(1);
1918 let expr = Expression::Eq(Box::new(BinaryOp {
1919 left,
1920 right,
1921 left_comments: vec![],
1922 operator_comments: vec![],
1923 trailing_comments: vec![],
1924 inferred_type: None,
1925 }));
1926
1927 let col = expr.find(is_column).unwrap();
1929 let parent = super::find_parent(&expr, col);
1930 assert!(parent.is_some());
1931 assert!(matches!(parent.unwrap(), Expression::Eq(_)));
1932 }
1933
1934 #[test]
1935 fn test_find_parent_root_has_none() {
1936 let lit = make_literal(1);
1937 let parent = super::find_parent(&lit, &lit);
1938 assert!(parent.is_none());
1939 }
1940
1941 #[test]
1944 fn test_find_ancestor_select() {
1945 let ast = crate::parser::Parser::parse_sql("SELECT a FROM t WHERE a > 1").unwrap();
1946 let expr = &ast[0];
1947
1948 let where_col = expr.dfs().find(|e| {
1950 if let Expression::Column(c) = e {
1951 c.name.name == "a"
1952 } else {
1953 false
1954 }
1955 });
1956 assert!(where_col.is_some());
1957
1958 let ancestor = super::find_ancestor(expr, where_col.unwrap(), is_select);
1960 assert!(ancestor.is_some());
1961 assert!(matches!(ancestor.unwrap(), Expression::Select(_)));
1962 }
1963
1964 #[test]
1965 fn test_find_ancestor_no_match() {
1966 let left = make_column("a");
1967 let right = make_literal(1);
1968 let expr = Expression::Eq(Box::new(BinaryOp {
1969 left,
1970 right,
1971 left_comments: vec![],
1972 operator_comments: vec![],
1973 trailing_comments: vec![],
1974 inferred_type: None,
1975 }));
1976
1977 let col = expr.find(is_column).unwrap();
1978 let ancestor = super::find_ancestor(&expr, col, is_select);
1979 assert!(ancestor.is_none());
1980 }
1981
1982 #[test]
1983 fn test_ancestors() {
1984 let col = make_column("a");
1985 let lit = make_literal(1);
1986 let inner = Expression::Add(Box::new(BinaryOp {
1987 left: col,
1988 right: lit,
1989 left_comments: vec![],
1990 operator_comments: vec![],
1991 trailing_comments: vec![],
1992 inferred_type: None,
1993 }));
1994 let outer = Expression::Eq(Box::new(BinaryOp {
1995 left: make_column("b"),
1996 right: inner,
1997 left_comments: vec![],
1998 operator_comments: vec![],
1999 trailing_comments: vec![],
2000 inferred_type: None,
2001 }));
2002
2003 let ctx = TreeContext::build(&outer);
2004
2005 let ancestors = ctx.ancestors_of(3);
2013 assert_eq!(ancestors, vec![2, 0]); }
2015
2016 #[test]
2017 fn test_get_merge_target_and_source() {
2018 let dialect = crate::Dialect::get(crate::dialects::DialectType::Generic);
2019
2020 let sql = "MERGE INTO orders o USING customers c ON o.customer_id = c.id WHEN MATCHED THEN UPDATE SET amount = amount + 100";
2022 let exprs = dialect.parse(sql).unwrap();
2023 let expr = &exprs[0];
2024
2025 assert!(is_merge(expr));
2026 assert!(is_query(expr));
2027
2028 let target = get_merge_target(expr).expect("should find target table");
2029 assert!(matches!(target, Expression::Table(_)));
2030 if let Expression::Table(t) = target {
2031 assert_eq!(t.name.name, "orders");
2032 }
2033
2034 let source = get_merge_source(expr).expect("should find source table");
2035 assert!(matches!(source, Expression::Table(_)));
2036 if let Expression::Table(t) = source {
2037 assert_eq!(t.name.name, "customers");
2038 }
2039 }
2040
2041 #[test]
2042 fn test_get_merge_source_subquery_returns_none() {
2043 let dialect = crate::Dialect::get(crate::dialects::DialectType::Generic);
2044
2045 let sql = "MERGE INTO orders o USING (SELECT * FROM customers) c ON o.customer_id = c.id WHEN MATCHED THEN DELETE";
2047 let exprs = dialect.parse(sql).unwrap();
2048 let expr = &exprs[0];
2049
2050 assert!(get_merge_target(expr).is_some());
2051 assert!(get_merge_source(expr).is_none());
2052 }
2053
2054 #[test]
2055 fn test_get_merge_on_non_merge_returns_none() {
2056 let dialect = crate::Dialect::get(crate::dialects::DialectType::Generic);
2057 let exprs = dialect.parse("SELECT 1").unwrap();
2058 assert!(get_merge_target(&exprs[0]).is_none());
2059 assert!(get_merge_source(&exprs[0]).is_none());
2060 }
2061
2062 #[test]
2063 fn test_get_tables_finds_tables_inside_in_subquery() {
2064 let dialect = crate::Dialect::get(crate::dialects::DialectType::Generic);
2065 let sql = "SELECT id, name FROM customers WHERE id IN (SELECT customer_id FROM orders WHERE amount > 1000)";
2066 let exprs = dialect.parse(sql).unwrap();
2067 let tables = get_tables(&exprs[0]);
2068 let names: Vec<&str> = tables
2069 .iter()
2070 .filter_map(|e| {
2071 if let Expression::Table(t) = e {
2072 Some(t.name.name.as_str())
2073 } else {
2074 None
2075 }
2076 })
2077 .collect();
2078 assert!(names.contains(&"customers"), "should find outer table");
2079 assert!(names.contains(&"orders"), "should find subquery table");
2080 }
2081
2082 #[test]
2083 fn test_get_tables_finds_tables_inside_exists_subquery() {
2084 let dialect = crate::Dialect::get(crate::dialects::DialectType::Generic);
2085 let sql = "SELECT * FROM customers c WHERE EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.id)";
2086 let exprs = dialect.parse(sql).unwrap();
2087 let tables = get_tables(&exprs[0]);
2088 let names: Vec<&str> = tables
2089 .iter()
2090 .filter_map(|e| {
2091 if let Expression::Table(t) = e {
2092 Some(t.name.name.as_str())
2093 } else {
2094 None
2095 }
2096 })
2097 .collect();
2098 assert!(names.contains(&"customers"), "should find outer table");
2099 assert!(
2100 names.contains(&"orders"),
2101 "should find EXISTS subquery table"
2102 );
2103 }
2104
2105 #[test]
2106 fn test_get_tables_finds_tables_in_correlated_subquery() {
2107 let dialect = crate::Dialect::get(crate::dialects::DialectType::TSQL);
2108 let sql = "SELECT id, name FROM customers WHERE id IN (SELECT customer_id FROM orders WHERE amount > 1000)";
2109 let exprs = dialect.parse(sql).unwrap();
2110 let tables = get_tables(&exprs[0]);
2111 let names: Vec<&str> = tables
2112 .iter()
2113 .filter_map(|e| {
2114 if let Expression::Table(t) = e {
2115 Some(t.name.name.as_str())
2116 } else {
2117 None
2118 }
2119 })
2120 .collect();
2121 assert!(
2122 names.contains(&"customers"),
2123 "TSQL: should find outer table"
2124 );
2125 assert!(
2126 names.contains(&"orders"),
2127 "TSQL: should find subquery table"
2128 );
2129 }
2130}