Skip to content

Commit 7a7c93f

Browse files
committed
rewrite table.col refs in trigger where,from,when...etc
fixes
1 parent 263cae5 commit 7a7c93f

File tree

2 files changed

+325
-5
lines changed

2 files changed

+325
-5
lines changed

core/translate/alter.rs

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2510,3 +2510,270 @@ fn rewrite_expr_column_ref(
25102510
None,
25112511
)
25122512
}
2513+
2514+
pub fn rewrite_expr_table_refs_for_rename(
2515+
expr: &mut Box<ast::Expr>,
2516+
old_table_norm: &str,
2517+
new_table_name: &str,
2518+
) -> bool {
2519+
let mut changed = false;
2520+
2521+
match expr.as_mut() {
2522+
2523+
ast::Expr::Qualified(ref mut tbl_name, _) => {
2524+
if normalize_ident(tbl_name.as_str()) == old_table_norm {
2525+
*tbl_name = ast::Name::from_string(format!("\"{}\"", new_table_name));
2526+
changed = true;
2527+
}
2528+
}
2529+
2530+
ast::Expr::DoublyQualified(_, ref mut tbl_name, _) => {
2531+
if normalize_ident(tbl_name.as_str()) == old_table_norm {
2532+
*tbl_name = ast::Name::from_string(format!("\"{}\"", new_table_name));
2533+
changed = true;
2534+
}
2535+
}
2536+
ast::Expr::Between { lhs, start, end, .. } => {
2537+
changed |= rewrite_expr_table_refs_for_rename(lhs, old_table_norm, new_table_name);
2538+
changed |= rewrite_expr_table_refs_for_rename(start, old_table_norm, new_table_name);
2539+
changed |= rewrite_expr_table_refs_for_rename(end, old_table_norm, new_table_name);
2540+
}
2541+
ast::Expr::Binary(lhs, _, rhs) => {
2542+
changed |= rewrite_expr_table_refs_for_rename(lhs, old_table_norm, new_table_name);
2543+
changed |= rewrite_expr_table_refs_for_rename(rhs, old_table_norm, new_table_name);
2544+
}
2545+
ast::Expr::Case { base, when_then_pairs, else_expr, .. } => {
2546+
if let Some(b) = base {
2547+
changed |= rewrite_expr_table_refs_for_rename(b, old_table_norm, new_table_name);
2548+
}
2549+
for (when_expr, then_expr) in when_then_pairs {
2550+
changed |= rewrite_expr_table_refs_for_rename(when_expr, old_table_norm, new_table_name);
2551+
changed |= rewrite_expr_table_refs_for_rename(then_expr, old_table_norm, new_table_name);
2552+
}
2553+
if let Some(else_e) = else_expr {
2554+
changed |= rewrite_expr_table_refs_for_rename(else_e, old_table_norm, new_table_name);
2555+
}
2556+
}
2557+
ast::Expr::Cast { expr: inner, .. } => {
2558+
changed |= rewrite_expr_table_refs_for_rename(inner, old_table_norm, new_table_name);
2559+
}
2560+
ast::Expr::Collate(inner, _) => {
2561+
changed |= rewrite_expr_table_refs_for_rename(inner, old_table_norm, new_table_name);
2562+
}
2563+
ast::Expr::FunctionCall { args, filter_over, .. } => {
2564+
for arg in args {
2565+
changed |= rewrite_expr_table_refs_for_rename(arg, old_table_norm, new_table_name);
2566+
}
2567+
if let Some(ref mut filter_expr) = filter_over.filter_clause {
2568+
changed |= rewrite_expr_table_refs_for_rename(filter_expr, old_table_norm, new_table_name);
2569+
}
2570+
}
2571+
ast::Expr::FunctionCallStar { filter_over, .. } => {
2572+
if let Some(ref mut filter_expr) = filter_over.filter_clause {
2573+
changed |= rewrite_expr_table_refs_for_rename(filter_expr, old_table_norm, new_table_name);
2574+
}
2575+
}
2576+
ast::Expr::InList { lhs, rhs, .. } => {
2577+
changed |= rewrite_expr_table_refs_for_rename(lhs, old_table_norm, new_table_name);
2578+
for item in rhs {
2579+
changed |= rewrite_expr_table_refs_for_rename(item, old_table_norm, new_table_name);
2580+
}
2581+
}
2582+
ast::Expr::InSelect { lhs, rhs, .. } => {
2583+
changed |= rewrite_expr_table_refs_for_rename(lhs, old_table_norm, new_table_name);
2584+
changed |= rewrite_select_table_refs_for_rename(rhs, old_table_norm, new_table_name);
2585+
}
2586+
ast::Expr::InTable { lhs, rhs, .. } => {
2587+
changed |= rewrite_expr_table_refs_for_rename(lhs, old_table_norm, new_table_name);
2588+
if normalize_ident(rhs.name.as_str()) == old_table_norm {
2589+
rhs.name = ast::Name::from_string(format!("\"{}\"", new_table_name));
2590+
changed = true;
2591+
}
2592+
}
2593+
ast::Expr::IsNull(inner) | ast::Expr::NotNull(inner) => {
2594+
changed |= rewrite_expr_table_refs_for_rename(inner, old_table_norm, new_table_name);
2595+
}
2596+
ast::Expr::Like { lhs, rhs, escape, .. } => {
2597+
changed |= rewrite_expr_table_refs_for_rename(lhs, old_table_norm, new_table_name);
2598+
changed |= rewrite_expr_table_refs_for_rename(rhs, old_table_norm, new_table_name);
2599+
if let Some(ref mut esc) = escape {
2600+
changed |= rewrite_expr_table_refs_for_rename(esc, old_table_norm, new_table_name);
2601+
}
2602+
}
2603+
ast::Expr::Parenthesized(inner) => {
2604+
for e in inner {
2605+
changed |= rewrite_expr_table_refs_for_rename(e, old_table_norm, new_table_name);
2606+
}
2607+
}
2608+
ast::Expr::Subquery(select) | ast::Expr::Exists(select) => {
2609+
changed |= rewrite_select_table_refs_for_rename(select, old_table_norm, new_table_name);
2610+
}
2611+
ast::Expr::Unary(_, inner) => {
2612+
changed |= rewrite_expr_table_refs_for_rename(inner, old_table_norm, new_table_name);
2613+
}
2614+
ast::Expr::Id(_)
2615+
| ast::Expr::Literal(_)
2616+
| ast::Expr::Name(_)
2617+
| ast::Expr::Variable(_)
2618+
| ast::Expr::Raise(_, _)
2619+
| ast::Expr::Register(_)
2620+
| ast::Expr::Column { .. }
2621+
| ast::Expr::RowId { .. }
2622+
| ast::Expr::SubqueryResult { .. } => {}
2623+
}
2624+
2625+
changed
2626+
}
2627+
2628+
fn rewrite_select_table_refs_for_rename(
2629+
select: &mut ast::Select,
2630+
old_table_norm: &str,
2631+
new_table_name: &str,
2632+
) -> bool {
2633+
let mut changed = false;
2634+
2635+
changed |= rewrite_select_body_table_refs_for_rename(&mut select.body, old_table_norm, new_table_name);
2636+
2637+
for sorted_col in &mut select.order_by {
2638+
changed |= rewrite_expr_table_refs_for_rename(&mut sorted_col.expr, old_table_norm, new_table_name);
2639+
}
2640+
2641+
if let Some(ref mut limit) = select.limit {
2642+
changed |= rewrite_expr_table_refs_for_rename(&mut limit.expr, old_table_norm, new_table_name);
2643+
if let Some(ref mut offset) = limit.offset {
2644+
changed |= rewrite_expr_table_refs_for_rename(offset, old_table_norm, new_table_name);
2645+
}
2646+
}
2647+
2648+
changed
2649+
}
2650+
2651+
fn rewrite_select_body_table_refs_for_rename(
2652+
body: &mut ast::SelectBody,
2653+
old_table_norm: &str,
2654+
new_table_name: &str,
2655+
) -> bool {
2656+
let mut changed = false;
2657+
2658+
changed |= rewrite_one_select_table_refs_for_rename(&mut body.select, old_table_norm, new_table_name);
2659+
2660+
for compound in &mut body.compounds {
2661+
changed |= rewrite_one_select_table_refs_for_rename(&mut compound.select, old_table_norm, new_table_name);
2662+
}
2663+
2664+
changed
2665+
}
2666+
2667+
fn rewrite_one_select_table_refs_for_rename(
2668+
one_select: &mut ast::OneSelect,
2669+
old_table_norm: &str,
2670+
new_table_name: &str,
2671+
) -> bool {
2672+
let mut changed = false;
2673+
2674+
match one_select {
2675+
ast::OneSelect::Select {
2676+
columns,
2677+
from,
2678+
where_clause,
2679+
group_by,
2680+
..
2681+
} => {
2682+
for col in columns {
2683+
match col {
2684+
ast::ResultColumn::Expr(expr, _) => {
2685+
changed |= rewrite_expr_table_refs_for_rename(expr, old_table_norm, new_table_name);
2686+
}
2687+
ast::ResultColumn::TableStar(ref mut name) => {
2688+
if normalize_ident(name.as_str()) == old_table_norm {
2689+
*name = ast::Name::from_string(format!("\"{}\"", new_table_name));
2690+
changed = true;
2691+
}
2692+
}
2693+
ast::ResultColumn::Star => {}
2694+
}
2695+
}
2696+
2697+
if let Some(ref mut from_clause) = from {
2698+
changed |= rewrite_from_clause_table_refs_for_rename(from_clause, old_table_norm, new_table_name);
2699+
}
2700+
2701+
if let Some(ref mut where_expr) = where_clause {
2702+
changed |= rewrite_expr_table_refs_for_rename(where_expr, old_table_norm, new_table_name);
2703+
}
2704+
2705+
if let Some(ref mut group) = group_by {
2706+
for expr in &mut group.exprs {
2707+
changed |= rewrite_expr_table_refs_for_rename(expr, old_table_norm, new_table_name);
2708+
}
2709+
if let Some(ref mut having) = group.having {
2710+
changed |= rewrite_expr_table_refs_for_rename(having, old_table_norm, new_table_name);
2711+
}
2712+
}
2713+
}
2714+
ast::OneSelect::Values(values) => {
2715+
for row in values {
2716+
for expr in row {
2717+
changed |= rewrite_expr_table_refs_for_rename(expr, old_table_norm, new_table_name);
2718+
}
2719+
}
2720+
}
2721+
}
2722+
2723+
changed
2724+
}
2725+
2726+
fn rewrite_from_clause_table_refs_for_rename(
2727+
from: &mut ast::FromClause,
2728+
old_table_norm: &str,
2729+
new_table_name: &str,
2730+
) -> bool {
2731+
let mut changed = false;
2732+
2733+
changed |= rewrite_select_table_entry_refs_for_rename(&mut from.select, old_table_norm, new_table_name);
2734+
2735+
for join in &mut from.joins {
2736+
changed |= rewrite_select_table_entry_refs_for_rename(&mut join.table, old_table_norm, new_table_name);
2737+
if let Some(ref mut constraint) = join.constraint {
2738+
if let ast::JoinConstraint::On(expr) = constraint {
2739+
changed |= rewrite_expr_table_refs_for_rename(expr, old_table_norm, new_table_name);
2740+
}
2741+
}
2742+
}
2743+
2744+
changed
2745+
}
2746+
2747+
fn rewrite_select_table_entry_refs_for_rename(
2748+
select_table: &mut Box<ast::SelectTable>,
2749+
old_table_norm: &str,
2750+
new_table_name: &str,
2751+
) -> bool {
2752+
let mut changed = false;
2753+
2754+
match select_table.as_mut() {
2755+
ast::SelectTable::Table(ref mut qualified_name, _, _) => {
2756+
if normalize_ident(qualified_name.name.as_str()) == old_table_norm {
2757+
qualified_name.name = ast::Name::from_string(format!("\"{}\"", new_table_name));
2758+
changed = true;
2759+
}
2760+
}
2761+
ast::SelectTable::TableCall(ref mut qualified_name, args, _) => {
2762+
if normalize_ident(qualified_name.name.as_str()) == old_table_norm {
2763+
qualified_name.name = ast::Name::from_string(format!("\"{}\"", new_table_name));
2764+
changed = true;
2765+
}
2766+
for arg in args {
2767+
changed |= rewrite_expr_table_refs_for_rename(arg, old_table_norm, new_table_name);
2768+
}
2769+
}
2770+
ast::SelectTable::Select(select, _) => {
2771+
changed |= rewrite_select_table_refs_for_rename(select, old_table_norm, new_table_name);
2772+
}
2773+
ast::SelectTable::Sub(from, _) => {
2774+
changed |= rewrite_from_clause_table_refs_for_rename(from, old_table_norm, new_table_name);
2775+
}
2776+
}
2777+
2778+
changed
2779+
}

core/vdbe/execute.rs

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5885,7 +5885,7 @@ pub fn op_function(
58855885
event,
58865886
mut tbl_name,
58875887
for_each_row,
5888-
when_clause,
5888+
mut when_clause,
58895889
mut commands,
58905890
} => {
58915891
// when renaming a table,we need to update table names inside trigger too
@@ -5899,19 +5899,72 @@ pub fn op_function(
58995899
changed = true;
59005900
}
59015901

5902-
5902+
if let Some(ref mut when_expr) = when_clause {
5903+
changed |= crate::translate::alter::rewrite_expr_table_refs_for_rename(
5904+
when_expr, &rename_from, original_rename_to.as_str()
5905+
);
5906+
}
5907+
59035908
for cmd in &mut commands {
59045909
match cmd {
5905-
ast::TriggerCmd::Update { tbl_name, .. }
5906-
| ast::TriggerCmd::Insert { tbl_name, .. }
5907-
| ast::TriggerCmd::Delete { tbl_name, .. } => {
5910+
ast::TriggerCmd::Update { tbl_name, sets, from, where_clause, .. } => {
5911+
if normalize_ident(tbl_name.as_str()) == rename_from {
5912+
*tbl_name = Name::from_string(format!(
5913+
"\"{}\"",
5914+
original_rename_to
5915+
));
5916+
changed = true;
5917+
}
5918+
for set in sets {
5919+
changed |= crate::translate::alter::rewrite_expr_table_refs_for_rename(
5920+
&mut set.expr, &rename_from, original_rename_to.as_str()
5921+
);
5922+
}
5923+
5924+
if let Some(ref mut from_clause) = from {
5925+
for join in &mut from_clause.joins {
5926+
if let Some(ref mut constraint) = join.constraint {
5927+
if let ast::JoinConstraint::On(expr) = constraint {
5928+
changed |= crate::translate::alter::rewrite_expr_table_refs_for_rename(
5929+
expr, &rename_from, original_rename_to.as_str()
5930+
);
5931+
}
5932+
}
5933+
}
5934+
}
5935+
if let Some(ref mut where_expr) = where_clause {
5936+
changed |= crate::translate::alter::rewrite_expr_table_refs_for_rename(
5937+
where_expr, &rename_from, original_rename_to.as_str()
5938+
);
5939+
}
5940+
}
5941+
ast::TriggerCmd::Insert { tbl_name, select, .. } => {
59085942
if normalize_ident(tbl_name.as_str()) == rename_from {
59095943
*tbl_name = Name::from_string(format!(
59105944
"\"{}\"",
59115945
original_rename_to
59125946
));
59135947
changed = true;
59145948
}
5949+
for sorted in &mut select.order_by {
5950+
changed |= crate::translate::alter::rewrite_expr_table_refs_for_rename(
5951+
&mut sorted.expr, &rename_from, original_rename_to.as_str()
5952+
);
5953+
}
5954+
}
5955+
ast::TriggerCmd::Delete { tbl_name, where_clause } => {
5956+
if normalize_ident(tbl_name.as_str()) == rename_from {
5957+
*tbl_name = Name::from_string(format!(
5958+
"\"{}\"",
5959+
original_rename_to
5960+
));
5961+
changed = true;
5962+
}
5963+
if let Some(ref mut where_expr) = where_clause {
5964+
changed |= crate::translate::alter::rewrite_expr_table_refs_for_rename(
5965+
where_expr, &rename_from, original_rename_to.as_str()
5966+
);
5967+
}
59155968
}
59165969
ast::TriggerCmd::Select(_) => {}
59175970
}

0 commit comments

Comments
 (0)