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 for (condition, result) in &c.whens {
546 children.push(("when", condition));
547 children.push(("then", result));
548 }
549 if let Some(ref else_) = c.else_ {
550 children.push(("else", else_));
551 }
552 }
553 Expression::WindowFunction(wf) => {
554 children.push(("this", &wf.this));
555 }
556 Expression::Union(u) => {
557 children.push(("left", &u.left));
558 children.push(("right", &u.right));
559 if let Some(with) = &u.with {
560 for cte in &with.ctes {
561 children.push(("with_cte", &cte.this));
562 }
563 if let Some(search) = &with.search {
564 children.push(("with_search", search));
565 }
566 }
567 if let Some(order_by) = &u.order_by {
568 for ordered in &order_by.expressions {
569 children.push(("order_by", &ordered.this));
570 }
571 }
572 if let Some(limit) = &u.limit {
573 children.push(("limit", limit));
574 }
575 if let Some(offset) = &u.offset {
576 children.push(("offset", offset));
577 }
578 if let Some(distribute_by) = &u.distribute_by {
579 for e in &distribute_by.expressions {
580 children.push(("distribute_by", e));
581 }
582 }
583 if let Some(sort_by) = &u.sort_by {
584 for ordered in &sort_by.expressions {
585 children.push(("sort_by", &ordered.this));
586 }
587 }
588 if let Some(cluster_by) = &u.cluster_by {
589 for ordered in &cluster_by.expressions {
590 children.push(("cluster_by", &ordered.this));
591 }
592 }
593 for e in &u.on_columns {
594 children.push(("on_column", e));
595 }
596 }
597 Expression::Intersect(i) => {
598 children.push(("left", &i.left));
599 children.push(("right", &i.right));
600 if let Some(with) = &i.with {
601 for cte in &with.ctes {
602 children.push(("with_cte", &cte.this));
603 }
604 if let Some(search) = &with.search {
605 children.push(("with_search", search));
606 }
607 }
608 if let Some(order_by) = &i.order_by {
609 for ordered in &order_by.expressions {
610 children.push(("order_by", &ordered.this));
611 }
612 }
613 if let Some(limit) = &i.limit {
614 children.push(("limit", limit));
615 }
616 if let Some(offset) = &i.offset {
617 children.push(("offset", offset));
618 }
619 if let Some(distribute_by) = &i.distribute_by {
620 for e in &distribute_by.expressions {
621 children.push(("distribute_by", e));
622 }
623 }
624 if let Some(sort_by) = &i.sort_by {
625 for ordered in &sort_by.expressions {
626 children.push(("sort_by", &ordered.this));
627 }
628 }
629 if let Some(cluster_by) = &i.cluster_by {
630 for ordered in &cluster_by.expressions {
631 children.push(("cluster_by", &ordered.this));
632 }
633 }
634 for e in &i.on_columns {
635 children.push(("on_column", e));
636 }
637 }
638 Expression::Except(e) => {
639 children.push(("left", &e.left));
640 children.push(("right", &e.right));
641 if let Some(with) = &e.with {
642 for cte in &with.ctes {
643 children.push(("with_cte", &cte.this));
644 }
645 if let Some(search) = &with.search {
646 children.push(("with_search", search));
647 }
648 }
649 if let Some(order_by) = &e.order_by {
650 for ordered in &order_by.expressions {
651 children.push(("order_by", &ordered.this));
652 }
653 }
654 if let Some(limit) = &e.limit {
655 children.push(("limit", limit));
656 }
657 if let Some(offset) = &e.offset {
658 children.push(("offset", offset));
659 }
660 if let Some(distribute_by) = &e.distribute_by {
661 for expr in &distribute_by.expressions {
662 children.push(("distribute_by", expr));
663 }
664 }
665 if let Some(sort_by) = &e.sort_by {
666 for ordered in &sort_by.expressions {
667 children.push(("sort_by", &ordered.this));
668 }
669 }
670 if let Some(cluster_by) = &e.cluster_by {
671 for ordered in &cluster_by.expressions {
672 children.push(("cluster_by", &ordered.this));
673 }
674 }
675 for expr in &e.on_columns {
676 children.push(("on_column", expr));
677 }
678 }
679 Expression::Merge(merge) => {
680 children.push(("this", &merge.this));
681 children.push(("using", &merge.using));
682 if let Some(on) = &merge.on {
683 children.push(("on", on));
684 }
685 if let Some(using_cond) = &merge.using_cond {
686 children.push(("using_cond", using_cond));
687 }
688 if let Some(whens) = &merge.whens {
689 children.push(("whens", whens));
690 }
691 if let Some(with_) = &merge.with_ {
692 children.push(("with_", with_));
693 }
694 if let Some(returning) = &merge.returning {
695 children.push(("returning", returning));
696 }
697 }
698 Expression::Any(q) | Expression::All(q) => {
699 children.push(("this", &q.this));
700 children.push(("subquery", &q.subquery));
701 }
702 Expression::Ordered(o) => {
703 children.push(("this", &o.this));
704 }
705 Expression::Interval(i) => {
706 if let Some(ref this) = i.this {
707 children.push(("this", this));
708 }
709 }
710 Expression::Describe(d) => {
711 children.push(("target", &d.target));
712 }
713 Expression::CreateTask(ct) => {
714 children.push(("body", &ct.body));
715 }
716 Expression::Prepare(prepare) => {
717 children.push(("statement", &prepare.statement));
718 }
719 Expression::Execute(exec) => {
720 children.push(("this", &exec.this));
721 for argument in &exec.arguments {
722 children.push(("argument", argument));
723 }
724 for parameter in &exec.parameters {
725 children.push(("parameter", ¶meter.value));
726 }
727 }
728 Expression::Analyze(a) => {
729 if let Some(this) = &a.this {
730 children.push(("this", this));
731 }
732 if let Some(expr) = &a.expression {
733 children.push(("expression", expr));
734 }
735 }
736 _ => {}
737 }
738
739 children
740}
741
742fn iter_children_lists(expr: &Expression) -> Vec<(&'static str, &[Expression])> {
746 let mut lists = Vec::new();
747
748 match expr {
749 Expression::Select(s) => lists.push(("expressions", s.expressions.as_slice())),
750 Expression::Function(f) => {
751 lists.push(("args", f.args.as_slice()));
752 }
753 Expression::AggregateFunction(f) => {
754 lists.push(("args", f.args.as_slice()));
755 }
756 Expression::From(f) => {
757 lists.push(("expressions", f.expressions.as_slice()));
758 }
759 Expression::GroupBy(g) => {
760 lists.push(("expressions", g.expressions.as_slice()));
761 }
762 Expression::In(i) => {
765 lists.push(("expressions", i.expressions.as_slice()));
766 }
767 Expression::Array(a) => {
768 lists.push(("expressions", a.expressions.as_slice()));
769 }
770 Expression::Tuple(t) => {
771 lists.push(("expressions", t.expressions.as_slice()));
772 }
773 Expression::TryCatch(try_catch) => {
774 lists.push(("try_body", try_catch.try_body.as_slice()));
775 if let Some(catch_body) = &try_catch.catch_body {
776 lists.push(("catch_body", catch_body.as_slice()));
777 }
778 }
779 Expression::Coalesce(c) => {
781 lists.push(("expressions", c.expressions.as_slice()));
782 }
783 Expression::Greatest(g) | Expression::Least(g) => {
784 lists.push(("expressions", g.expressions.as_slice()));
785 }
786 _ => {}
787 }
788
789 lists
790}
791
792pub struct DfsIter<'a> {
801 stack: Vec<&'a Expression>,
802}
803
804impl<'a> DfsIter<'a> {
805 pub fn new(root: &'a Expression) -> Self {
807 Self { stack: vec![root] }
808 }
809}
810
811impl<'a> Iterator for DfsIter<'a> {
812 type Item = &'a Expression;
813
814 fn next(&mut self) -> Option<Self::Item> {
815 let expr = self.stack.pop()?;
816
817 let children: Vec<_> = iter_children(expr).into_iter().map(|(_, e)| e).collect();
819 for child in children.into_iter().rev() {
820 self.stack.push(child);
821 }
822
823 let lists: Vec<_> = iter_children_lists(expr)
824 .into_iter()
825 .flat_map(|(_, es)| es.iter())
826 .collect();
827 for child in lists.into_iter().rev() {
828 self.stack.push(child);
829 }
830
831 Some(expr)
832 }
833}
834
835pub struct BfsIter<'a> {
843 queue: VecDeque<&'a Expression>,
844}
845
846impl<'a> BfsIter<'a> {
847 pub fn new(root: &'a Expression) -> Self {
849 let mut queue = VecDeque::new();
850 queue.push_back(root);
851 Self { queue }
852 }
853}
854
855impl<'a> Iterator for BfsIter<'a> {
856 type Item = &'a Expression;
857
858 fn next(&mut self) -> Option<Self::Item> {
859 let expr = self.queue.pop_front()?;
860
861 for (_, child) in iter_children(expr) {
863 self.queue.push_back(child);
864 }
865
866 for (_, children) in iter_children_lists(expr) {
867 for child in children {
868 self.queue.push_back(child);
869 }
870 }
871
872 Some(expr)
873 }
874}
875
876pub trait ExpressionWalk {
882 fn dfs(&self) -> DfsIter<'_>;
887
888 fn bfs(&self) -> BfsIter<'_>;
892
893 fn find<F>(&self, predicate: F) -> Option<&Expression>
897 where
898 F: Fn(&Expression) -> bool;
899
900 fn find_all<F>(&self, predicate: F) -> Vec<&Expression>
904 where
905 F: Fn(&Expression) -> bool;
906
907 fn contains<F>(&self, predicate: F) -> bool
909 where
910 F: Fn(&Expression) -> bool;
911
912 fn count<F>(&self, predicate: F) -> usize
914 where
915 F: Fn(&Expression) -> bool;
916
917 fn children(&self) -> Vec<&Expression>;
922
923 fn tree_depth(&self) -> usize;
927
928 #[cfg(any(
934 feature = "transpile",
935 feature = "ast-tools",
936 feature = "generate",
937 feature = "semantic"
938 ))]
939 fn transform_owned<F>(self, fun: F) -> crate::Result<Expression>
940 where
941 F: Fn(Expression) -> crate::Result<Option<Expression>>,
942 Self: Sized;
943}
944
945impl ExpressionWalk for Expression {
946 fn dfs(&self) -> DfsIter<'_> {
947 DfsIter::new(self)
948 }
949
950 fn bfs(&self) -> BfsIter<'_> {
951 BfsIter::new(self)
952 }
953
954 fn find<F>(&self, predicate: F) -> Option<&Expression>
955 where
956 F: Fn(&Expression) -> bool,
957 {
958 self.dfs().find(|e| predicate(e))
959 }
960
961 fn find_all<F>(&self, predicate: F) -> Vec<&Expression>
962 where
963 F: Fn(&Expression) -> bool,
964 {
965 self.dfs().filter(|e| predicate(e)).collect()
966 }
967
968 fn contains<F>(&self, predicate: F) -> bool
969 where
970 F: Fn(&Expression) -> bool,
971 {
972 self.dfs().any(|e| predicate(e))
973 }
974
975 fn count<F>(&self, predicate: F) -> usize
976 where
977 F: Fn(&Expression) -> bool,
978 {
979 self.dfs().filter(|e| predicate(e)).count()
980 }
981
982 fn children(&self) -> Vec<&Expression> {
983 let mut result: Vec<&Expression> = Vec::new();
984 for (_, child) in iter_children(self) {
985 result.push(child);
986 }
987 for (_, children_list) in iter_children_lists(self) {
988 for child in children_list {
989 result.push(child);
990 }
991 }
992 result
993 }
994
995 fn tree_depth(&self) -> usize {
996 let mut max_depth = 0;
997
998 for (_, child) in iter_children(self) {
999 let child_depth = child.tree_depth();
1000 if child_depth + 1 > max_depth {
1001 max_depth = child_depth + 1;
1002 }
1003 }
1004
1005 for (_, children) in iter_children_lists(self) {
1006 for child in children {
1007 let child_depth = child.tree_depth();
1008 if child_depth + 1 > max_depth {
1009 max_depth = child_depth + 1;
1010 }
1011 }
1012 }
1013
1014 max_depth
1015 }
1016
1017 #[cfg(any(
1018 feature = "transpile",
1019 feature = "ast-tools",
1020 feature = "generate",
1021 feature = "semantic"
1022 ))]
1023 fn transform_owned<F>(self, fun: F) -> crate::Result<Expression>
1024 where
1025 F: Fn(Expression) -> crate::Result<Option<Expression>>,
1026 {
1027 transform(self, &fun)
1028 }
1029}
1030
1031#[cfg(any(
1052 feature = "transpile",
1053 feature = "ast-tools",
1054 feature = "generate",
1055 feature = "semantic"
1056))]
1057pub fn transform<F>(expr: Expression, fun: &F) -> crate::Result<Expression>
1058where
1059 F: Fn(Expression) -> crate::Result<Option<Expression>>,
1060{
1061 crate::dialects::transform_recursive(expr, &|e| match fun(e)? {
1062 Some(transformed) => Ok(transformed),
1063 None => Ok(Expression::Null(crate::expressions::Null)),
1064 })
1065}
1066
1067#[cfg(any(
1088 feature = "transpile",
1089 feature = "ast-tools",
1090 feature = "generate",
1091 feature = "semantic"
1092))]
1093pub fn transform_map<F>(expr: Expression, fun: &F) -> crate::Result<Expression>
1094where
1095 F: Fn(Expression) -> crate::Result<Expression>,
1096{
1097 crate::dialects::transform_recursive(expr, fun)
1098}
1099
1100pub fn is_column(expr: &Expression) -> bool {
1108 matches!(expr, Expression::Column(_))
1109}
1110
1111pub fn is_literal(expr: &Expression) -> bool {
1113 matches!(
1114 expr,
1115 Expression::Literal(_) | Expression::Boolean(_) | Expression::Null(_)
1116 )
1117}
1118
1119pub fn is_function(expr: &Expression) -> bool {
1121 matches!(
1122 expr,
1123 Expression::Function(_) | Expression::AggregateFunction(_)
1124 )
1125}
1126
1127pub fn is_subquery(expr: &Expression) -> bool {
1129 matches!(expr, Expression::Subquery(_))
1130}
1131
1132pub fn is_select(expr: &Expression) -> bool {
1134 matches!(expr, Expression::Select(_))
1135}
1136
1137pub fn is_aggregate(expr: &Expression) -> bool {
1139 matches!(
1140 expr,
1141 Expression::AggregateFunction(_)
1142 | Expression::Count(_)
1143 | Expression::Sum(_)
1144 | Expression::Avg(_)
1145 | Expression::Min(_)
1146 | Expression::Max(_)
1147 | Expression::GroupConcat(_)
1148 | Expression::StringAgg(_)
1149 | Expression::ListAgg(_)
1150 | Expression::CountIf(_)
1151 | Expression::SumIf(_)
1152 )
1153}
1154
1155pub fn is_window_function(expr: &Expression) -> bool {
1157 matches!(expr, Expression::WindowFunction(_))
1158}
1159
1160pub fn get_columns(expr: &Expression) -> Vec<&Expression> {
1164 expr.find_all(is_column)
1165}
1166
1167pub fn get_tables(expr: &Expression) -> Vec<&Expression> {
1175 expr.find_all(|e| matches!(e, Expression::Table(_)))
1176}
1177
1178pub fn get_all_tables(expr: &Expression) -> Vec<Expression> {
1186 use std::collections::HashSet;
1187
1188 let mut seen = HashSet::new();
1189 let mut result = Vec::new();
1190
1191 for node in expr.dfs() {
1193 if let Expression::Table(t) = node {
1194 let qname = table_ref_qualified_name(t);
1195 if seen.insert(qname) {
1196 result.push(node.clone());
1197 }
1198 }
1199
1200 let refs: Vec<&TableRef> = match node {
1202 Expression::Insert(ins) => vec![&ins.table],
1203 Expression::Update(upd) => {
1204 let mut v = vec![&upd.table];
1205 v.extend(upd.extra_tables.iter());
1206 v
1207 }
1208 Expression::Delete(del) => {
1209 let mut v = vec![&del.table];
1210 v.extend(del.using.iter());
1211 v
1212 }
1213 _ => continue,
1214 };
1215 for tref in refs {
1216 if tref.name.name.is_empty() {
1217 continue;
1218 }
1219 let qname = table_ref_qualified_name(tref);
1220 if seen.insert(qname) {
1221 result.push(Expression::Table(Box::new(tref.clone())));
1222 }
1223 }
1224 }
1225
1226 result
1227}
1228
1229fn table_ref_qualified_name(t: &TableRef) -> String {
1231 let mut name = String::new();
1232 if let Some(ref cat) = t.catalog {
1233 name.push_str(&cat.name);
1234 name.push('.');
1235 }
1236 if let Some(ref schema) = t.schema {
1237 name.push_str(&schema.name);
1238 name.push('.');
1239 }
1240 name.push_str(&t.name.name);
1241 name
1242}
1243
1244fn unwrap_merge_table(expr: &Expression) -> Option<&Expression> {
1248 match expr {
1249 Expression::Table(_) => Some(expr),
1250 Expression::Alias(alias) => match &alias.this {
1251 Expression::Table(_) => Some(&alias.this),
1252 _ => None,
1253 },
1254 _ => None,
1255 }
1256}
1257
1258pub fn get_merge_target(expr: &Expression) -> Option<&Expression> {
1263 match expr {
1264 Expression::Merge(m) => unwrap_merge_table(&m.this),
1265 _ => None,
1266 }
1267}
1268
1269pub fn get_merge_source(expr: &Expression) -> Option<&Expression> {
1275 match expr {
1276 Expression::Merge(m) => unwrap_merge_table(&m.using),
1277 _ => None,
1278 }
1279}
1280
1281pub fn contains_aggregate(expr: &Expression) -> bool {
1283 expr.contains(is_aggregate)
1284}
1285
1286pub fn contains_window_function(expr: &Expression) -> bool {
1288 expr.contains(is_window_function)
1289}
1290
1291pub fn contains_subquery(expr: &Expression) -> bool {
1293 expr.contains(is_subquery)
1294}
1295
1296macro_rules! is_type {
1302 ($name:ident, $($variant:pat),+ $(,)?) => {
1303 pub fn $name(expr: &Expression) -> bool {
1305 matches!(expr, $($variant)|+)
1306 }
1307 };
1308}
1309
1310is_type!(is_insert, Expression::Insert(_));
1312is_type!(is_update, Expression::Update(_));
1313is_type!(is_delete, Expression::Delete(_));
1314is_type!(is_merge, Expression::Merge(_));
1315is_type!(is_union, Expression::Union(_));
1316is_type!(is_intersect, Expression::Intersect(_));
1317is_type!(is_except, Expression::Except(_));
1318
1319is_type!(is_boolean, Expression::Boolean(_));
1321is_type!(is_null_literal, Expression::Null(_));
1322is_type!(is_star, Expression::Star(_));
1323is_type!(is_identifier, Expression::Identifier(_));
1324is_type!(is_table, Expression::Table(_));
1325
1326is_type!(is_eq, Expression::Eq(_));
1328is_type!(is_neq, Expression::Neq(_));
1329is_type!(is_lt, Expression::Lt(_));
1330is_type!(is_lte, Expression::Lte(_));
1331is_type!(is_gt, Expression::Gt(_));
1332is_type!(is_gte, Expression::Gte(_));
1333is_type!(is_like, Expression::Like(_));
1334is_type!(is_ilike, Expression::ILike(_));
1335
1336is_type!(is_add, Expression::Add(_));
1338is_type!(is_sub, Expression::Sub(_));
1339is_type!(is_mul, Expression::Mul(_));
1340is_type!(is_div, Expression::Div(_));
1341is_type!(is_mod, Expression::Mod(_));
1342is_type!(is_concat, Expression::Concat(_));
1343
1344is_type!(is_and, Expression::And(_));
1346is_type!(is_or, Expression::Or(_));
1347is_type!(is_not, Expression::Not(_));
1348
1349is_type!(is_in, Expression::In(_));
1351is_type!(is_between, Expression::Between(_));
1352is_type!(is_is_null, Expression::IsNull(_));
1353is_type!(is_exists, Expression::Exists(_));
1354
1355is_type!(is_count, Expression::Count(_));
1357is_type!(is_sum, Expression::Sum(_));
1358is_type!(is_avg, Expression::Avg(_));
1359is_type!(is_min_func, Expression::Min(_));
1360is_type!(is_max_func, Expression::Max(_));
1361is_type!(is_coalesce, Expression::Coalesce(_));
1362is_type!(is_null_if, Expression::NullIf(_));
1363is_type!(is_cast, Expression::Cast(_));
1364is_type!(is_try_cast, Expression::TryCast(_));
1365is_type!(is_safe_cast, Expression::SafeCast(_));
1366is_type!(is_case, Expression::Case(_));
1367
1368is_type!(is_from, Expression::From(_));
1370is_type!(is_join, Expression::Join(_));
1371is_type!(is_where, Expression::Where(_));
1372is_type!(is_group_by, Expression::GroupBy(_));
1373is_type!(is_having, Expression::Having(_));
1374is_type!(is_order_by, Expression::OrderBy(_));
1375is_type!(is_limit, Expression::Limit(_));
1376is_type!(is_offset, Expression::Offset(_));
1377is_type!(is_with, Expression::With(_));
1378is_type!(is_cte, Expression::Cte(_));
1379is_type!(is_alias, Expression::Alias(_));
1380is_type!(is_paren, Expression::Paren(_));
1381is_type!(is_ordered, Expression::Ordered(_));
1382
1383is_type!(is_create_table, Expression::CreateTable(_));
1385is_type!(is_drop_table, Expression::DropTable(_));
1386is_type!(is_alter_table, Expression::AlterTable(_));
1387is_type!(is_create_index, Expression::CreateIndex(_));
1388is_type!(is_drop_index, Expression::DropIndex(_));
1389is_type!(is_create_view, Expression::CreateView(_));
1390is_type!(is_drop_view, Expression::DropView(_));
1391
1392pub fn is_query(expr: &Expression) -> bool {
1398 matches!(
1399 expr,
1400 Expression::Select(_)
1401 | Expression::Insert(_)
1402 | Expression::Update(_)
1403 | Expression::Delete(_)
1404 | Expression::Merge(_)
1405 )
1406}
1407
1408pub fn is_set_operation(expr: &Expression) -> bool {
1410 matches!(
1411 expr,
1412 Expression::Union(_) | Expression::Intersect(_) | Expression::Except(_)
1413 )
1414}
1415
1416pub fn is_comparison(expr: &Expression) -> bool {
1418 matches!(
1419 expr,
1420 Expression::Eq(_)
1421 | Expression::Neq(_)
1422 | Expression::Lt(_)
1423 | Expression::Lte(_)
1424 | Expression::Gt(_)
1425 | Expression::Gte(_)
1426 | Expression::Like(_)
1427 | Expression::ILike(_)
1428 )
1429}
1430
1431pub fn is_arithmetic(expr: &Expression) -> bool {
1433 matches!(
1434 expr,
1435 Expression::Add(_)
1436 | Expression::Sub(_)
1437 | Expression::Mul(_)
1438 | Expression::Div(_)
1439 | Expression::Mod(_)
1440 )
1441}
1442
1443pub fn is_logical(expr: &Expression) -> bool {
1445 matches!(
1446 expr,
1447 Expression::And(_) | Expression::Or(_) | Expression::Not(_)
1448 )
1449}
1450
1451pub fn is_ddl(expr: &Expression) -> bool {
1453 matches!(
1454 expr,
1455 Expression::CreateTable(_)
1456 | Expression::DropTable(_)
1457 | Expression::Undrop(_)
1458 | Expression::AlterTable(_)
1459 | Expression::CreateIndex(_)
1460 | Expression::DropIndex(_)
1461 | Expression::CreateView(_)
1462 | Expression::DropView(_)
1463 | Expression::AlterView(_)
1464 | Expression::CreateSchema(_)
1465 | Expression::DropSchema(_)
1466 | Expression::CreateDatabase(_)
1467 | Expression::DropDatabase(_)
1468 | Expression::CreateFunction(_)
1469 | Expression::DropFunction(_)
1470 | Expression::CreateProcedure(_)
1471 | Expression::DropProcedure(_)
1472 | Expression::CreateSequence(_)
1473 | Expression::CreateSynonym(_)
1474 | Expression::DropSequence(_)
1475 | Expression::AlterSequence(_)
1476 | Expression::CreateTrigger(_)
1477 | Expression::DropTrigger(_)
1478 | Expression::CreateType(_)
1479 | Expression::DropType(_)
1480 )
1481}
1482
1483pub fn find_parent<'a>(root: &'a Expression, target: &Expression) -> Option<&'a Expression> {
1490 fn search<'a>(node: &'a Expression, target: *const Expression) -> Option<&'a Expression> {
1491 for (_, child) in iter_children(node) {
1492 if std::ptr::eq(child, target) {
1493 return Some(node);
1494 }
1495 if let Some(found) = search(child, target) {
1496 return Some(found);
1497 }
1498 }
1499 for (_, children_list) in iter_children_lists(node) {
1500 for child in children_list {
1501 if std::ptr::eq(child, target) {
1502 return Some(node);
1503 }
1504 if let Some(found) = search(child, target) {
1505 return Some(found);
1506 }
1507 }
1508 }
1509 None
1510 }
1511
1512 search(root, target as *const Expression)
1513}
1514
1515pub fn find_ancestor<'a, F>(
1521 root: &'a Expression,
1522 target: &Expression,
1523 predicate: F,
1524) -> Option<&'a Expression>
1525where
1526 F: Fn(&Expression) -> bool,
1527{
1528 fn build_path<'a>(
1530 node: &'a Expression,
1531 target: *const Expression,
1532 path: &mut Vec<&'a Expression>,
1533 ) -> bool {
1534 if std::ptr::eq(node, target) {
1535 return true;
1536 }
1537 path.push(node);
1538 for (_, child) in iter_children(node) {
1539 if build_path(child, target, path) {
1540 return true;
1541 }
1542 }
1543 for (_, children_list) in iter_children_lists(node) {
1544 for child in children_list {
1545 if build_path(child, target, path) {
1546 return true;
1547 }
1548 }
1549 }
1550 path.pop();
1551 false
1552 }
1553
1554 let mut path = Vec::new();
1555 if !build_path(root, target as *const Expression, &mut path) {
1556 return None;
1557 }
1558
1559 for ancestor in path.iter().rev() {
1561 if predicate(ancestor) {
1562 return Some(ancestor);
1563 }
1564 }
1565 None
1566}
1567
1568#[cfg(test)]
1569mod tests {
1570 use super::*;
1571 use crate::expressions::{BinaryOp, Column, Identifier, Literal};
1572
1573 fn make_column(name: &str) -> Expression {
1574 Expression::boxed_column(Column {
1575 name: Identifier {
1576 name: name.to_string(),
1577 quoted: false,
1578 trailing_comments: vec![],
1579 span: None,
1580 },
1581 table: None,
1582 join_mark: false,
1583 trailing_comments: vec![],
1584 span: None,
1585 inferred_type: None,
1586 })
1587 }
1588
1589 fn make_literal(value: i64) -> Expression {
1590 Expression::Literal(Box::new(Literal::Number(value.to_string())))
1591 }
1592
1593 #[test]
1594 fn test_dfs_simple() {
1595 let left = make_column("a");
1596 let right = make_literal(1);
1597 let expr = Expression::Eq(Box::new(BinaryOp {
1598 left,
1599 right,
1600 left_comments: vec![],
1601 operator_comments: vec![],
1602 trailing_comments: vec![],
1603 inferred_type: None,
1604 }));
1605
1606 let nodes: Vec<_> = expr.dfs().collect();
1607 assert_eq!(nodes.len(), 3); assert!(matches!(nodes[0], Expression::Eq(_)));
1609 assert!(matches!(nodes[1], Expression::Column(_)));
1610 assert!(matches!(nodes[2], Expression::Literal(_)));
1611 }
1612
1613 #[test]
1614 fn test_find() {
1615 let left = make_column("a");
1616 let right = make_literal(1);
1617 let expr = Expression::Eq(Box::new(BinaryOp {
1618 left,
1619 right,
1620 left_comments: vec![],
1621 operator_comments: vec![],
1622 trailing_comments: vec![],
1623 inferred_type: None,
1624 }));
1625
1626 let column = expr.find(is_column);
1627 assert!(column.is_some());
1628 assert!(matches!(column.unwrap(), Expression::Column(_)));
1629
1630 let literal = expr.find(is_literal);
1631 assert!(literal.is_some());
1632 assert!(matches!(literal.unwrap(), Expression::Literal(_)));
1633 }
1634
1635 #[test]
1636 fn test_find_all() {
1637 let col1 = make_column("a");
1638 let col2 = make_column("b");
1639 let expr = Expression::And(Box::new(BinaryOp {
1640 left: col1,
1641 right: col2,
1642 left_comments: vec![],
1643 operator_comments: vec![],
1644 trailing_comments: vec![],
1645 inferred_type: None,
1646 }));
1647
1648 let columns = expr.find_all(is_column);
1649 assert_eq!(columns.len(), 2);
1650 }
1651
1652 #[test]
1653 fn test_contains() {
1654 let col = make_column("a");
1655 let lit = make_literal(1);
1656 let expr = Expression::Eq(Box::new(BinaryOp {
1657 left: col,
1658 right: lit,
1659 left_comments: vec![],
1660 operator_comments: vec![],
1661 trailing_comments: vec![],
1662 inferred_type: None,
1663 }));
1664
1665 assert!(expr.contains(is_column));
1666 assert!(expr.contains(is_literal));
1667 assert!(!expr.contains(is_subquery));
1668 }
1669
1670 #[test]
1671 fn test_count() {
1672 let col1 = make_column("a");
1673 let col2 = make_column("b");
1674 let lit = make_literal(1);
1675
1676 let inner = Expression::Add(Box::new(BinaryOp {
1677 left: col2,
1678 right: lit,
1679 left_comments: vec![],
1680 operator_comments: vec![],
1681 trailing_comments: vec![],
1682 inferred_type: None,
1683 }));
1684
1685 let expr = Expression::Eq(Box::new(BinaryOp {
1686 left: col1,
1687 right: inner,
1688 left_comments: vec![],
1689 operator_comments: vec![],
1690 trailing_comments: vec![],
1691 inferred_type: None,
1692 }));
1693
1694 assert_eq!(expr.count(is_column), 2);
1695 assert_eq!(expr.count(is_literal), 1);
1696 }
1697
1698 #[test]
1699 fn test_tree_depth() {
1700 let lit = make_literal(1);
1702 assert_eq!(lit.tree_depth(), 0);
1703
1704 let col = make_column("a");
1706 let expr = Expression::Eq(Box::new(BinaryOp {
1707 left: col,
1708 right: lit.clone(),
1709 left_comments: vec![],
1710 operator_comments: vec![],
1711 trailing_comments: vec![],
1712 inferred_type: None,
1713 }));
1714 assert_eq!(expr.tree_depth(), 1);
1715
1716 let inner = Expression::Add(Box::new(BinaryOp {
1718 left: make_column("b"),
1719 right: lit,
1720 left_comments: vec![],
1721 operator_comments: vec![],
1722 trailing_comments: vec![],
1723 inferred_type: None,
1724 }));
1725 let outer = Expression::Eq(Box::new(BinaryOp {
1726 left: make_column("a"),
1727 right: inner,
1728 left_comments: vec![],
1729 operator_comments: vec![],
1730 trailing_comments: vec![],
1731 inferred_type: None,
1732 }));
1733 assert_eq!(outer.tree_depth(), 2);
1734 }
1735
1736 #[test]
1737 fn test_tree_context() {
1738 let col = make_column("a");
1739 let lit = make_literal(1);
1740 let expr = Expression::Eq(Box::new(BinaryOp {
1741 left: col,
1742 right: lit,
1743 left_comments: vec![],
1744 operator_comments: vec![],
1745 trailing_comments: vec![],
1746 inferred_type: None,
1747 }));
1748
1749 let ctx = TreeContext::build(&expr);
1750
1751 let root_info = ctx.get(0).unwrap();
1753 assert!(root_info.parent_id.is_none());
1754
1755 let left_info = ctx.get(1).unwrap();
1757 assert_eq!(left_info.parent_id, Some(0));
1758 assert_eq!(left_info.arg_key, "left");
1759
1760 let right_info = ctx.get(2).unwrap();
1761 assert_eq!(right_info.parent_id, Some(0));
1762 assert_eq!(right_info.arg_key, "right");
1763 }
1764
1765 #[test]
1768 fn test_transform_rename_columns() {
1769 let ast = crate::parser::Parser::parse_sql("SELECT a, b FROM t").unwrap();
1770 let expr = ast[0].clone();
1771 let result = super::transform_map(expr, &|e| {
1772 if let Expression::Column(ref c) = e {
1773 if c.name.name == "a" {
1774 return Ok(Expression::boxed_column(Column {
1775 name: Identifier::new("alpha"),
1776 table: c.table.clone(),
1777 join_mark: false,
1778 trailing_comments: vec![],
1779 span: None,
1780 inferred_type: None,
1781 }));
1782 }
1783 }
1784 Ok(e)
1785 })
1786 .unwrap();
1787 let sql = crate::generator::Generator::sql(&result).unwrap();
1788 assert!(sql.contains("alpha"), "Expected 'alpha' in: {}", sql);
1789 assert!(sql.contains("b"), "Expected 'b' in: {}", sql);
1790 }
1791
1792 #[test]
1793 fn test_transform_noop() {
1794 let ast = crate::parser::Parser::parse_sql("SELECT 1 + 2").unwrap();
1795 let expr = ast[0].clone();
1796 let result = super::transform_map(expr.clone(), &|e| Ok(e)).unwrap();
1797 let sql1 = crate::generator::Generator::sql(&expr).unwrap();
1798 let sql2 = crate::generator::Generator::sql(&result).unwrap();
1799 assert_eq!(sql1, sql2);
1800 }
1801
1802 #[test]
1803 fn test_transform_nested() {
1804 let ast = crate::parser::Parser::parse_sql("SELECT a + b FROM t").unwrap();
1805 let expr = ast[0].clone();
1806 let result = super::transform_map(expr, &|e| {
1807 if let Expression::Column(ref c) = e {
1808 return Ok(Expression::Literal(Box::new(Literal::Number(
1809 if c.name.name == "a" { "1" } else { "2" }.to_string(),
1810 ))));
1811 }
1812 Ok(e)
1813 })
1814 .unwrap();
1815 let sql = crate::generator::Generator::sql(&result).unwrap();
1816 assert_eq!(sql, "SELECT 1 + 2 FROM t");
1817 }
1818
1819 #[test]
1820 fn test_transform_error() {
1821 let ast = crate::parser::Parser::parse_sql("SELECT a FROM t").unwrap();
1822 let expr = ast[0].clone();
1823 let result = super::transform_map(expr, &|e| {
1824 if let Expression::Column(ref c) = e {
1825 if c.name.name == "a" {
1826 return Err(crate::error::Error::parse("test error", 0, 0, 0, 0));
1827 }
1828 }
1829 Ok(e)
1830 });
1831 assert!(result.is_err());
1832 }
1833
1834 #[test]
1835 fn test_transform_owned_trait() {
1836 let ast = crate::parser::Parser::parse_sql("SELECT x FROM t").unwrap();
1837 let expr = ast[0].clone();
1838 let result = expr.transform_owned(|e| Ok(Some(e))).unwrap();
1839 let sql = crate::generator::Generator::sql(&result).unwrap();
1840 assert_eq!(sql, "SELECT x FROM t");
1841 }
1842
1843 #[test]
1846 fn test_children_leaf() {
1847 let lit = make_literal(1);
1848 assert_eq!(lit.children().len(), 0);
1849 }
1850
1851 #[test]
1852 fn test_children_binary_op() {
1853 let left = make_column("a");
1854 let right = make_literal(1);
1855 let expr = Expression::Eq(Box::new(BinaryOp {
1856 left,
1857 right,
1858 left_comments: vec![],
1859 operator_comments: vec![],
1860 trailing_comments: vec![],
1861 inferred_type: None,
1862 }));
1863 let children = expr.children();
1864 assert_eq!(children.len(), 2);
1865 assert!(matches!(children[0], Expression::Column(_)));
1866 assert!(matches!(children[1], Expression::Literal(_)));
1867 }
1868
1869 #[test]
1870 fn test_children_select() {
1871 let ast = crate::parser::Parser::parse_sql("SELECT a, b FROM t").unwrap();
1872 let expr = &ast[0];
1873 let children = expr.children();
1874 assert!(children.len() >= 2);
1876 }
1877
1878 #[test]
1879 fn test_children_select_includes_from_and_join_sources() {
1880 let ast = crate::parser::Parser::parse_sql(
1881 "SELECT u.id FROM users u JOIN orders o ON u.id = o.user_id",
1882 )
1883 .unwrap();
1884 let expr = &ast[0];
1885 let children = expr.children();
1886
1887 let table_names: Vec<&str> = children
1888 .iter()
1889 .filter_map(|e| match e {
1890 Expression::Table(t) => Some(t.name.name.as_str()),
1891 _ => None,
1892 })
1893 .collect();
1894
1895 assert!(table_names.contains(&"users"));
1896 assert!(table_names.contains(&"orders"));
1897 }
1898
1899 #[test]
1900 fn test_get_tables_includes_insert_query_sources() {
1901 let ast = crate::parser::Parser::parse_sql(
1902 "INSERT INTO dst (id) SELECT s.id FROM src s JOIN dim d ON s.id = d.id",
1903 )
1904 .unwrap();
1905 let expr = &ast[0];
1906 let tables = get_tables(expr);
1907 let names: Vec<&str> = tables
1908 .iter()
1909 .filter_map(|e| match e {
1910 Expression::Table(t) => Some(t.name.name.as_str()),
1911 _ => None,
1912 })
1913 .collect();
1914
1915 assert!(names.contains(&"src"));
1916 assert!(names.contains(&"dim"));
1917 }
1918
1919 #[test]
1922 fn test_find_parent_binary() {
1923 let left = make_column("a");
1924 let right = make_literal(1);
1925 let expr = Expression::Eq(Box::new(BinaryOp {
1926 left,
1927 right,
1928 left_comments: vec![],
1929 operator_comments: vec![],
1930 trailing_comments: vec![],
1931 inferred_type: None,
1932 }));
1933
1934 let col = expr.find(is_column).unwrap();
1936 let parent = super::find_parent(&expr, col);
1937 assert!(parent.is_some());
1938 assert!(matches!(parent.unwrap(), Expression::Eq(_)));
1939 }
1940
1941 #[test]
1942 fn test_find_parent_root_has_none() {
1943 let lit = make_literal(1);
1944 let parent = super::find_parent(&lit, &lit);
1945 assert!(parent.is_none());
1946 }
1947
1948 #[test]
1951 fn test_find_ancestor_select() {
1952 let ast = crate::parser::Parser::parse_sql("SELECT a FROM t WHERE a > 1").unwrap();
1953 let expr = &ast[0];
1954
1955 let where_col = expr.dfs().find(|e| {
1957 if let Expression::Column(c) = e {
1958 c.name.name == "a"
1959 } else {
1960 false
1961 }
1962 });
1963 assert!(where_col.is_some());
1964
1965 let ancestor = super::find_ancestor(expr, where_col.unwrap(), is_select);
1967 assert!(ancestor.is_some());
1968 assert!(matches!(ancestor.unwrap(), Expression::Select(_)));
1969 }
1970
1971 #[test]
1972 fn test_find_ancestor_no_match() {
1973 let left = make_column("a");
1974 let right = make_literal(1);
1975 let expr = Expression::Eq(Box::new(BinaryOp {
1976 left,
1977 right,
1978 left_comments: vec![],
1979 operator_comments: vec![],
1980 trailing_comments: vec![],
1981 inferred_type: None,
1982 }));
1983
1984 let col = expr.find(is_column).unwrap();
1985 let ancestor = super::find_ancestor(&expr, col, is_select);
1986 assert!(ancestor.is_none());
1987 }
1988
1989 #[test]
1990 fn test_ancestors() {
1991 let col = make_column("a");
1992 let lit = make_literal(1);
1993 let inner = Expression::Add(Box::new(BinaryOp {
1994 left: col,
1995 right: lit,
1996 left_comments: vec![],
1997 operator_comments: vec![],
1998 trailing_comments: vec![],
1999 inferred_type: None,
2000 }));
2001 let outer = Expression::Eq(Box::new(BinaryOp {
2002 left: make_column("b"),
2003 right: inner,
2004 left_comments: vec![],
2005 operator_comments: vec![],
2006 trailing_comments: vec![],
2007 inferred_type: None,
2008 }));
2009
2010 let ctx = TreeContext::build(&outer);
2011
2012 let ancestors = ctx.ancestors_of(3);
2020 assert_eq!(ancestors, vec![2, 0]); }
2022
2023 #[test]
2024 fn test_get_merge_target_and_source() {
2025 let dialect = crate::Dialect::get(crate::dialects::DialectType::Generic);
2026
2027 let sql = "MERGE INTO orders o USING customers c ON o.customer_id = c.id WHEN MATCHED THEN UPDATE SET amount = amount + 100";
2029 let exprs = dialect.parse(sql).unwrap();
2030 let expr = &exprs[0];
2031
2032 assert!(is_merge(expr));
2033 assert!(is_query(expr));
2034
2035 let target = get_merge_target(expr).expect("should find target table");
2036 assert!(matches!(target, Expression::Table(_)));
2037 if let Expression::Table(t) = target {
2038 assert_eq!(t.name.name, "orders");
2039 }
2040
2041 let source = get_merge_source(expr).expect("should find source table");
2042 assert!(matches!(source, Expression::Table(_)));
2043 if let Expression::Table(t) = source {
2044 assert_eq!(t.name.name, "customers");
2045 }
2046 }
2047
2048 #[test]
2049 fn test_get_merge_source_subquery_returns_none() {
2050 let dialect = crate::Dialect::get(crate::dialects::DialectType::Generic);
2051
2052 let sql = "MERGE INTO orders o USING (SELECT * FROM customers) c ON o.customer_id = c.id WHEN MATCHED THEN DELETE";
2054 let exprs = dialect.parse(sql).unwrap();
2055 let expr = &exprs[0];
2056
2057 assert!(get_merge_target(expr).is_some());
2058 assert!(get_merge_source(expr).is_none());
2059 }
2060
2061 #[test]
2062 fn test_get_merge_on_non_merge_returns_none() {
2063 let dialect = crate::Dialect::get(crate::dialects::DialectType::Generic);
2064 let exprs = dialect.parse("SELECT 1").unwrap();
2065 assert!(get_merge_target(&exprs[0]).is_none());
2066 assert!(get_merge_source(&exprs[0]).is_none());
2067 }
2068
2069 #[test]
2070 fn test_get_tables_finds_tables_inside_in_subquery() {
2071 let dialect = crate::Dialect::get(crate::dialects::DialectType::Generic);
2072 let sql = "SELECT id, name FROM customers WHERE id IN (SELECT customer_id FROM orders WHERE amount > 1000)";
2073 let exprs = dialect.parse(sql).unwrap();
2074 let tables = get_tables(&exprs[0]);
2075 let names: Vec<&str> = tables
2076 .iter()
2077 .filter_map(|e| {
2078 if let Expression::Table(t) = e {
2079 Some(t.name.name.as_str())
2080 } else {
2081 None
2082 }
2083 })
2084 .collect();
2085 assert!(names.contains(&"customers"), "should find outer table");
2086 assert!(names.contains(&"orders"), "should find subquery table");
2087 }
2088
2089 #[test]
2090 fn test_get_tables_finds_tables_inside_exists_subquery() {
2091 let dialect = crate::Dialect::get(crate::dialects::DialectType::Generic);
2092 let sql = "SELECT * FROM customers c WHERE EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.id)";
2093 let exprs = dialect.parse(sql).unwrap();
2094 let tables = get_tables(&exprs[0]);
2095 let names: Vec<&str> = tables
2096 .iter()
2097 .filter_map(|e| {
2098 if let Expression::Table(t) = e {
2099 Some(t.name.name.as_str())
2100 } else {
2101 None
2102 }
2103 })
2104 .collect();
2105 assert!(names.contains(&"customers"), "should find outer table");
2106 assert!(
2107 names.contains(&"orders"),
2108 "should find EXISTS subquery table"
2109 );
2110 }
2111
2112 #[test]
2113 fn test_get_tables_finds_tables_in_correlated_subquery() {
2114 let dialect = crate::Dialect::get(crate::dialects::DialectType::TSQL);
2115 let sql = "SELECT id, name FROM customers WHERE id IN (SELECT customer_id FROM orders WHERE amount > 1000)";
2116 let exprs = dialect.parse(sql).unwrap();
2117 let tables = get_tables(&exprs[0]);
2118 let names: Vec<&str> = tables
2119 .iter()
2120 .filter_map(|e| {
2121 if let Expression::Table(t) = e {
2122 Some(t.name.name.as_str())
2123 } else {
2124 None
2125 }
2126 })
2127 .collect();
2128 assert!(
2129 names.contains(&"customers"),
2130 "TSQL: should find outer table"
2131 );
2132 assert!(
2133 names.contains(&"orders"),
2134 "TSQL: should find subquery table"
2135 );
2136 }
2137}