|
| 1 | +use crate::translate::expr::{walk_expr_mut, WalkControl}; |
1 | 2 | use std::sync::Arc; |
2 | 3 | use turso_parser::{ |
3 | 4 | ast::{self, TableInternalId}, |
@@ -2571,133 +2572,55 @@ pub fn walk_upsert_for_table_rename( |
2571 | 2572 | /// |
2572 | 2573 | /// `old_table_norm`: Normalized (lowercase) name of the table being renamed. |
2573 | 2574 | /// `new_table_name`: New name for the table (will be double-quoted in output). |
| 2575 | +/// |
| 2576 | +/// This function uses `walk_expr_mut` from `expr.rs` to traverse all expression |
| 2577 | +/// variants automatically, including WINDOW clauses and frame bounds. Only the |
| 2578 | +/// special cases (table-qualified names) are handled in the callback. |
2574 | 2579 | pub fn rewrite_expr_table_refs_for_rename( |
2575 | 2580 | expr: &mut Box<ast::Expr>, |
2576 | 2581 | old_table_norm: &str, |
2577 | 2582 | new_table_name: &str, |
2578 | 2583 | ) -> bool { |
2579 | 2584 | let mut changed = false; |
2580 | 2585 |
|
2581 | | - match expr.as_mut() { |
2582 | | - ast::Expr::Qualified(ref mut tbl_name, _) => { |
2583 | | - if normalize_ident(tbl_name.as_str()) == old_table_norm { |
2584 | | - // Wrap new name in double quotes to handle special characters/keywords |
2585 | | - *tbl_name = ast::Name::from_string(format!("\"{new_table_name}\"")); |
2586 | | - changed = true; |
2587 | | - } |
2588 | | - } |
2589 | | - |
2590 | | - ast::Expr::DoublyQualified(_, ref mut tbl_name, _) => { |
2591 | | - if normalize_ident(tbl_name.as_str()) == old_table_norm { |
2592 | | - *tbl_name = ast::Name::from_string(format!("\"{new_table_name}\"")); |
2593 | | - changed = true; |
2594 | | - } |
2595 | | - } |
2596 | | - ast::Expr::Between { |
2597 | | - lhs, start, end, .. |
2598 | | - } => { |
2599 | | - changed |= rewrite_expr_table_refs_for_rename(lhs, old_table_norm, new_table_name); |
2600 | | - changed |= rewrite_expr_table_refs_for_rename(start, old_table_norm, new_table_name); |
2601 | | - changed |= rewrite_expr_table_refs_for_rename(end, old_table_norm, new_table_name); |
2602 | | - } |
2603 | | - ast::Expr::Binary(lhs, _, rhs) => { |
2604 | | - changed |= rewrite_expr_table_refs_for_rename(lhs, old_table_norm, new_table_name); |
2605 | | - changed |= rewrite_expr_table_refs_for_rename(rhs, old_table_norm, new_table_name); |
2606 | | - } |
2607 | | - ast::Expr::Case { |
2608 | | - base, |
2609 | | - when_then_pairs, |
2610 | | - else_expr, |
2611 | | - .. |
2612 | | - } => { |
2613 | | - if let Some(b) = base { |
2614 | | - changed |= rewrite_expr_table_refs_for_rename(b, old_table_norm, new_table_name); |
2615 | | - } |
2616 | | - for (when_expr, then_expr) in when_then_pairs { |
2617 | | - changed |= |
2618 | | - rewrite_expr_table_refs_for_rename(when_expr, old_table_norm, new_table_name); |
2619 | | - changed |= |
2620 | | - rewrite_expr_table_refs_for_rename(then_expr, old_table_norm, new_table_name); |
| 2586 | + // Use walk_expr_mut to traverse ALL expression types automatically. |
| 2587 | + // This handles WINDOW clauses, frame bounds, and all other nested expressions. |
| 2588 | + let _ = walk_expr_mut(expr, &mut |e: &mut ast::Expr| -> Result<WalkControl> { |
| 2589 | + match e { |
| 2590 | + // Handle table-qualified column references: tbl.col -> "new_tbl".col |
| 2591 | + ast::Expr::Qualified(ref mut tbl_name, _) => { |
| 2592 | + if normalize_ident(tbl_name.as_str()) == old_table_norm { |
| 2593 | + *tbl_name = ast::Name::from_string(format!("\"{new_table_name}\"")); |
| 2594 | + changed = true; |
| 2595 | + } |
2621 | 2596 | } |
2622 | | - if let Some(else_e) = else_expr { |
2623 | | - changed |= |
2624 | | - rewrite_expr_table_refs_for_rename(else_e, old_table_norm, new_table_name); |
| 2597 | + // Handle doubly-qualified references: db.tbl.col -> db."new_tbl".col |
| 2598 | + ast::Expr::DoublyQualified(_, ref mut tbl_name, _) => { |
| 2599 | + if normalize_ident(tbl_name.as_str()) == old_table_norm { |
| 2600 | + *tbl_name = ast::Name::from_string(format!("\"{new_table_name}\"")); |
| 2601 | + changed = true; |
| 2602 | + } |
2625 | 2603 | } |
2626 | | - } |
2627 | | - ast::Expr::Cast { expr: inner, .. } => { |
2628 | | - changed |= rewrite_expr_table_refs_for_rename(inner, old_table_norm, new_table_name); |
2629 | | - } |
2630 | | - ast::Expr::Collate(inner, _) => { |
2631 | | - changed |= rewrite_expr_table_refs_for_rename(inner, old_table_norm, new_table_name); |
2632 | | - } |
2633 | | - ast::Expr::FunctionCall { |
2634 | | - args, filter_over, .. |
2635 | | - } => { |
2636 | | - for arg in args { |
2637 | | - changed |= rewrite_expr_table_refs_for_rename(arg, old_table_norm, new_table_name); |
| 2604 | + // Handle `x IN tbl` - the table reference is not a sub-expression |
| 2605 | + ast::Expr::InTable { rhs, .. } => { |
| 2606 | + if normalize_ident(rhs.name.as_str()) == old_table_norm { |
| 2607 | + rhs.name = ast::Name::from_string(format!("\"{new_table_name}\"")); |
| 2608 | + changed = true; |
| 2609 | + } |
2638 | 2610 | } |
2639 | | - if let Some(ref mut filter_expr) = filter_over.filter_clause { |
| 2611 | + // Handle subqueries - walk_expr_mut doesn't descend into SELECT statements |
| 2612 | + ast::Expr::InSelect { rhs, .. } => { |
2640 | 2613 | changed |= |
2641 | | - rewrite_expr_table_refs_for_rename(filter_expr, old_table_norm, new_table_name); |
| 2614 | + rewrite_select_table_refs_for_rename(rhs, old_table_norm, new_table_name); |
2642 | 2615 | } |
2643 | | - } |
2644 | | - ast::Expr::FunctionCallStar { filter_over, .. } => { |
2645 | | - if let Some(ref mut filter_expr) = filter_over.filter_clause { |
| 2616 | + ast::Expr::Subquery(select) | ast::Expr::Exists(select) => { |
2646 | 2617 | changed |= |
2647 | | - rewrite_expr_table_refs_for_rename(filter_expr, old_table_norm, new_table_name); |
2648 | | - } |
2649 | | - } |
2650 | | - ast::Expr::InList { lhs, rhs, .. } => { |
2651 | | - changed |= rewrite_expr_table_refs_for_rename(lhs, old_table_norm, new_table_name); |
2652 | | - for item in rhs { |
2653 | | - changed |= rewrite_expr_table_refs_for_rename(item, old_table_norm, new_table_name); |
| 2618 | + rewrite_select_table_refs_for_rename(select, old_table_norm, new_table_name); |
2654 | 2619 | } |
| 2620 | + _ => {} |
2655 | 2621 | } |
2656 | | - ast::Expr::InSelect { lhs, rhs, .. } => { |
2657 | | - changed |= rewrite_expr_table_refs_for_rename(lhs, old_table_norm, new_table_name); |
2658 | | - changed |= rewrite_select_table_refs_for_rename(rhs, old_table_norm, new_table_name); |
2659 | | - } |
2660 | | - ast::Expr::InTable { lhs, rhs, .. } => { |
2661 | | - changed |= rewrite_expr_table_refs_for_rename(lhs, old_table_norm, new_table_name); |
2662 | | - // `x IN tbl` - the table reference is not qualified, rewrite directly |
2663 | | - if normalize_ident(rhs.name.as_str()) == old_table_norm { |
2664 | | - rhs.name = ast::Name::from_string(format!("\"{new_table_name}\"")); |
2665 | | - changed = true; |
2666 | | - } |
2667 | | - } |
2668 | | - ast::Expr::IsNull(inner) | ast::Expr::NotNull(inner) => { |
2669 | | - changed |= rewrite_expr_table_refs_for_rename(inner, old_table_norm, new_table_name); |
2670 | | - } |
2671 | | - ast::Expr::Like { |
2672 | | - lhs, rhs, escape, .. |
2673 | | - } => { |
2674 | | - changed |= rewrite_expr_table_refs_for_rename(lhs, old_table_norm, new_table_name); |
2675 | | - changed |= rewrite_expr_table_refs_for_rename(rhs, old_table_norm, new_table_name); |
2676 | | - if let Some(ref mut esc) = escape { |
2677 | | - changed |= rewrite_expr_table_refs_for_rename(esc, old_table_norm, new_table_name); |
2678 | | - } |
2679 | | - } |
2680 | | - ast::Expr::Parenthesized(inner) => { |
2681 | | - for e in inner { |
2682 | | - changed |= rewrite_expr_table_refs_for_rename(e, old_table_norm, new_table_name); |
2683 | | - } |
2684 | | - } |
2685 | | - ast::Expr::Subquery(select) | ast::Expr::Exists(select) => { |
2686 | | - changed |= rewrite_select_table_refs_for_rename(select, old_table_norm, new_table_name); |
2687 | | - } |
2688 | | - ast::Expr::Unary(_, inner) => { |
2689 | | - changed |= rewrite_expr_table_refs_for_rename(inner, old_table_norm, new_table_name); |
2690 | | - } |
2691 | | - ast::Expr::Id(_) |
2692 | | - | ast::Expr::Literal(_) |
2693 | | - | ast::Expr::Name(_) |
2694 | | - | ast::Expr::Variable(_) |
2695 | | - | ast::Expr::Raise(_, _) |
2696 | | - | ast::Expr::Register(_) |
2697 | | - | ast::Expr::Column { .. } |
2698 | | - | ast::Expr::RowId { .. } |
2699 | | - | ast::Expr::SubqueryResult { .. } => {} |
2700 | | - } |
| 2622 | + Ok(WalkControl::Continue) |
| 2623 | + }); |
2701 | 2624 |
|
2702 | 2625 | changed |
2703 | 2626 | } |
|
0 commit comments