1use itertools::Itertools;
16use risingwave_pb::expr::expr_node::{self, RexNode};
17use risingwave_pb::expr::{ExprNode, FunctionCall, UserDefinedFunction};
18use risingwave_pb::plan_common::PbColumnDesc;
19use risingwave_sqlparser::ast::{
20 Array, CdcTableInfo, CreateSink, CreateSinkStatement, CreateSourceStatement,
21 CreateSubscriptionStatement, Distinct, Expr, Function, FunctionArg, FunctionArgExpr,
22 FunctionArgList, Ident, ObjectName, Query, SelectItem, SetExpr, Statement, TableAlias,
23 TableFactor, TableWithJoins, Window,
24};
25use risingwave_sqlparser::parser::Parser;
26
27pub fn alter_relation_rename(definition: &str, new_name: &str) -> String {
32 if definition.is_empty() {
35 tracing::warn!("found empty definition when renaming relation, ignored.");
36 return definition.into();
37 }
38 let ast = Parser::parse_sql(definition).expect("failed to parse relation definition");
39 let mut stmt =
40 Itertools::exactly_one(ast.into_iter()).expect("should contains only one statement");
41
42 match &mut stmt {
43 Statement::CreateTable { name, .. }
44 | Statement::CreateView { name, .. }
45 | Statement::CreateIndex { name, .. }
46 | Statement::CreateSource {
47 stmt: CreateSourceStatement {
48 source_name: name, ..
49 },
50 }
51 | Statement::CreateSubscription {
52 stmt:
53 CreateSubscriptionStatement {
54 subscription_name: name,
55 ..
56 },
57 }
58 | Statement::CreateSink {
59 stmt: CreateSinkStatement {
60 sink_name: name, ..
61 },
62 } => replace_table_name(name, new_name),
63 _ => unreachable!(),
64 };
65
66 stmt.to_string()
67}
68
69pub fn alter_relation_rename_refs(definition: &str, from: &str, to: &str) -> String {
72 let ast = Parser::parse_sql(definition).expect("failed to parse relation definition");
73 let mut stmt =
74 Itertools::exactly_one(ast.into_iter()).expect("should contains only one statement");
75
76 match &mut stmt {
77 Statement::CreateTable {
78 query: Some(query), ..
79 }
80 | Statement::CreateView { query, .. }
81 | Statement::Query(query) | Statement::CreateSink {
83 stmt:
84 CreateSinkStatement {
85 sink_from: CreateSink::AsQuery(query),
86 into_table_name: None,
87 ..
88 },
89 } => {
90 QueryRewriter::rewrite_query(query, from, to);
91 }
92 Statement::CreateIndex { table_name, .. }
93 | Statement::CreateSink {
94 stmt:
95 CreateSinkStatement {
96 sink_from: CreateSink::From(table_name),
97 into_table_name: None,
98 ..
99 },
100 }| Statement::CreateSubscription {
101 stmt:
102 CreateSubscriptionStatement {
103 subscription_from: table_name,
104 ..
105 },
106 } | Statement::CreateTable {
107 cdc_table_info:
108 Some(CdcTableInfo {
109 source_name: table_name,
110 ..
111 }),
112 ..
113 } | Statement::CreateSource {
114 stmt: CreateSourceStatement {
115 cdc_table_info:
116 Some(CdcTableInfo {
117 source_name: table_name,
118 ..
119 }),
120 ..
121 },
122 } => replace_table_name(table_name, to),
123 Statement::CreateSink {
124 stmt: CreateSinkStatement {
125 sink_from,
126 into_table_name: Some(table_name),
127 ..
128 }
129 } => {
130 let idx = table_name.0.len() - 1;
131 if table_name.0[idx].real_value() == from {
132 table_name.0[idx] = Ident::from_real_value(to);
133 } else {
134 match sink_from {
135 CreateSink::From(table_name) => replace_table_name(table_name, to),
136 CreateSink::AsQuery(query) => QueryRewriter::rewrite_query(query, from, to),
137 }
138 }
139 }
140 _ => unreachable!(),
141 };
142 stmt.to_string()
143}
144
145fn replace_table_name(table_name: &mut ObjectName, to: &str) {
148 let idx = table_name.0.len() - 1;
149 table_name.0[idx] = Ident::from_real_value(to);
150}
151
152struct QueryRewriter<'a> {
155 from: &'a str,
156 to: &'a str,
157}
158
159impl QueryRewriter<'_> {
160 fn rewrite_query(query: &mut Query, from: &str, to: &str) {
161 let rewriter = QueryRewriter { from, to };
162 rewriter.visit_query(query)
163 }
164
165 fn visit_query(&self, query: &mut Query) {
167 if let Some(with) = &mut query.with {
168 for cte_table in &mut with.cte_tables {
169 match &mut cte_table.cte_inner {
170 risingwave_sqlparser::ast::CteInner::Query(query) => self.visit_query(query),
171 risingwave_sqlparser::ast::CteInner::ChangeLog {
172 from: name,
173 key: _key,
174 } => {
175 let idx = name.0.len() - 1;
176 if name.0[idx].real_value() == self.from {
177 replace_table_name(name, self.to);
178 }
179 }
180 }
181 }
182 }
183 self.visit_set_expr(&mut query.body);
184 for expr in &mut query.order_by {
185 self.visit_expr(&mut expr.expr);
186 }
187 }
188
189 fn visit_table_factor(&self, table_factor: &mut TableFactor) {
201 match table_factor {
202 TableFactor::Table { name, alias, .. } => {
203 let idx = name.0.len() - 1;
204 if name.0[idx].real_value() == self.from {
205 if alias.is_none() {
206 *alias = Some(TableAlias {
207 name: Ident::from_real_value(self.from),
208 columns: vec![],
209 });
210 }
211 name.0[idx] = Ident::from_real_value(self.to);
212 }
213 }
214 TableFactor::Derived { subquery, .. } => self.visit_query(subquery),
215 TableFactor::TableFunction { args, .. } => {
216 for arg in args {
217 self.visit_function_arg(arg);
218 }
219 }
220 TableFactor::NestedJoin(table_with_joins) => {
221 self.visit_table_with_joins(table_with_joins);
222 }
223 TableFactor::MatchRecognize { table, .. } => {
224 self.visit_table_factor(table);
228 }
229 }
230 }
231
232 fn visit_table_with_joins(&self, table_with_joins: &mut TableWithJoins) {
234 self.visit_table_factor(&mut table_with_joins.relation);
235 for join in &mut table_with_joins.joins {
236 self.visit_table_factor(&mut join.relation);
237 }
238 }
239
240 fn visit_set_expr(&self, set_expr: &mut SetExpr) {
242 match set_expr {
243 SetExpr::Select(select) => {
244 if let Distinct::DistinctOn(exprs) = &mut select.distinct {
245 for expr in exprs {
246 self.visit_expr(expr);
247 }
248 }
249 for select_item in &mut select.projection {
250 self.visit_select_item(select_item);
251 }
252 for from_item in &mut select.from {
253 self.visit_table_with_joins(from_item);
254 }
255 if let Some(where_clause) = &mut select.selection {
256 self.visit_expr(where_clause);
257 }
258 for expr in &mut select.group_by {
259 self.visit_expr(expr);
260 }
261 if let Some(having) = &mut select.having {
262 self.visit_expr(having);
263 }
264 for named_window in &mut select.window {
265 for expr in &mut named_window.window_spec.partition_by {
266 self.visit_expr(expr);
267 }
268 for expr in &mut named_window.window_spec.order_by {
269 self.visit_expr(&mut expr.expr);
270 }
271 }
272 }
273 SetExpr::Query(query) => self.visit_query(query),
274 SetExpr::SetOperation { left, right, .. } => {
275 self.visit_set_expr(left);
276 self.visit_set_expr(right);
277 }
278 SetExpr::Values(_) => {}
279 }
280 }
281
282 fn visit_function_arg(&self, function_arg: &mut FunctionArg) {
284 match function_arg {
285 FunctionArg::Unnamed(arg) | FunctionArg::Named { arg, .. } => match arg {
286 FunctionArgExpr::Expr(expr) | FunctionArgExpr::ExprQualifiedWildcard(expr, _) => {
287 self.visit_expr(expr)
288 }
289 FunctionArgExpr::QualifiedWildcard(_, None) | FunctionArgExpr::Wildcard(None) => {}
290 FunctionArgExpr::QualifiedWildcard(_, Some(exprs))
291 | FunctionArgExpr::Wildcard(Some(exprs)) => {
292 for expr in exprs {
293 self.visit_expr(expr);
294 }
295 }
296 FunctionArgExpr::SecretRef(_) => {}
297 },
298 }
299 }
300
301 fn visit_function_arg_list(&self, arg_list: &mut FunctionArgList) {
302 for arg in &mut arg_list.args {
303 self.visit_function_arg(arg);
304 }
305 for expr in &mut arg_list.order_by {
306 self.visit_expr(&mut expr.expr)
307 }
308 }
309
310 fn visit_function(&self, function: &mut Function) {
312 self.visit_function_arg_list(&mut function.arg_list);
313 if let Some(over) = &mut function.over {
314 match over {
315 Window::Spec(window) => {
316 for expr in &mut window.partition_by {
317 self.visit_expr(expr);
318 }
319 for expr in &mut window.order_by {
320 self.visit_expr(&mut expr.expr);
321 }
322 }
323 Window::Name(_) => {
324 }
326 }
327 }
328 }
329
330 fn visit_expr(&self, expr: &mut Expr) {
332 match expr {
333 Expr::FieldIdentifier(expr, ..)
334 | Expr::IsNull(expr)
335 | Expr::IsNotNull(expr)
336 | Expr::IsTrue(expr)
337 | Expr::IsNotTrue(expr)
338 | Expr::IsFalse(expr)
339 | Expr::IsNotFalse(expr)
340 | Expr::IsUnknown(expr)
341 | Expr::IsNotUnknown(expr)
342 | Expr::IsJson { expr, .. }
343 | Expr::InList { expr, .. }
344 | Expr::SomeOp(expr)
345 | Expr::AllOp(expr)
346 | Expr::UnaryOp { expr, .. }
347 | Expr::Cast { expr, .. }
348 | Expr::TryCast { expr, .. }
349 | Expr::AtTimeZone {
350 timestamp: expr, ..
351 }
352 | Expr::Extract { expr, .. }
353 | Expr::Substring { expr, .. }
354 | Expr::Overlay { expr, .. }
355 | Expr::Trim { expr, .. }
356 | Expr::Nested(expr)
357 | Expr::Index { obj: expr, .. }
358 | Expr::ArrayRangeIndex { obj: expr, .. } => self.visit_expr(expr),
359
360 Expr::Position { substring, string } => {
361 self.visit_expr(substring);
362 self.visit_expr(string);
363 }
364
365 Expr::InSubquery { expr, subquery, .. } => {
366 self.visit_expr(expr);
367 self.visit_query(subquery);
368 }
369 Expr::Between {
370 expr, low, high, ..
371 } => {
372 self.visit_expr(expr);
373 self.visit_expr(low);
374 self.visit_expr(high);
375 }
376 Expr::Like {
377 expr, pattern: pat, ..
378 } => {
379 self.visit_expr(expr);
380 self.visit_expr(pat);
381 }
382 Expr::ILike {
383 expr, pattern: pat, ..
384 } => {
385 self.visit_expr(expr);
386 self.visit_expr(pat);
387 }
388 Expr::SimilarTo {
389 expr, pattern: pat, ..
390 } => {
391 self.visit_expr(expr);
392 self.visit_expr(pat);
393 }
394
395 Expr::IsDistinctFrom(expr1, expr2)
396 | Expr::IsNotDistinctFrom(expr1, expr2)
397 | Expr::BinaryOp {
398 left: expr1,
399 right: expr2,
400 ..
401 } => {
402 self.visit_expr(expr1);
403 self.visit_expr(expr2);
404 }
405 Expr::Function(function) => self.visit_function(function),
406 Expr::Exists(query) | Expr::Subquery(query) | Expr::ArraySubquery(query) => {
407 self.visit_query(query)
408 }
409
410 Expr::GroupingSets(exprs_vec) | Expr::Cube(exprs_vec) | Expr::Rollup(exprs_vec) => {
411 for exprs in exprs_vec {
412 for expr in exprs {
413 self.visit_expr(expr);
414 }
415 }
416 }
417
418 Expr::Row(exprs) | Expr::Array(Array { elem: exprs, .. }) => {
419 for expr in exprs {
420 self.visit_expr(expr);
421 }
422 }
423 Expr::Map { entries } => {
424 for (key, value) in entries {
425 self.visit_expr(key);
426 self.visit_expr(value);
427 }
428 }
429
430 Expr::LambdaFunction { body, args: _ } => self.visit_expr(body),
431
432 Expr::Identifier(_)
434 | Expr::CompoundIdentifier(_)
435 | Expr::Collate { .. }
436 | Expr::Value(_)
437 | Expr::Parameter { .. }
438 | Expr::TypedString { .. }
439 | Expr::Case { .. } => {}
440 }
441 }
442
443 fn visit_select_item(&self, select_item: &mut SelectItem) {
445 match select_item {
446 SelectItem::UnnamedExpr(expr)
447 | SelectItem::ExprQualifiedWildcard(expr, _)
448 | SelectItem::ExprWithAlias { expr, .. } => self.visit_expr(expr),
449 SelectItem::QualifiedWildcard(_, None) | SelectItem::Wildcard(None) => {}
450 SelectItem::QualifiedWildcard(_, Some(exprs)) | SelectItem::Wildcard(Some(exprs)) => {
451 for expr in exprs {
452 self.visit_expr(expr);
453 }
454 }
455 }
456 }
457}
458
459pub struct IndexItemRewriter {
462 pub original_columns: Vec<PbColumnDesc>,
463 pub new_columns: Vec<PbColumnDesc>,
464}
465
466impl IndexItemRewriter {
467 pub fn rewrite_expr(&self, expr: &mut ExprNode) {
468 let rex_node = expr.rex_node.as_mut().unwrap();
469 match rex_node {
470 RexNode::InputRef(idx) => {
471 let old_idx = *idx as usize;
472 let original_column = &self.original_columns[old_idx];
473 let (new_idx, new_column) = self
474 .new_columns
475 .iter()
476 .find_position(|c| c.column_id == original_column.column_id)
477 .expect("should already checked index referencing column still exists");
478 *idx = new_idx as u32;
479
480 if new_column.column_type != original_column.column_type {
484 let old_type = original_column.column_type.clone().unwrap();
485 let new_type = new_column.column_type.clone().unwrap();
486
487 assert_eq!(&old_type, expr.return_type.as_ref().unwrap());
488 expr.return_type = Some(new_type); let new_expr_node = ExprNode {
491 function_type: expr_node::Type::CompositeCast as _,
492 return_type: Some(old_type),
493 rex_node: RexNode::FuncCall(FunctionCall {
494 children: vec![expr.clone()],
495 })
496 .into(),
497 };
498
499 *expr = new_expr_node;
500 }
501 }
502 RexNode::Constant(_) => {}
503 RexNode::Udf(udf) => self.rewrite_udf(udf),
504 RexNode::FuncCall(function_call) => self.rewrite_function_call(function_call),
505 RexNode::Now(_) | RexNode::SecretRef(_) => {}
506 }
507 }
508
509 fn rewrite_udf(&self, udf: &mut UserDefinedFunction) {
510 udf.children
511 .iter_mut()
512 .for_each(|expr| self.rewrite_expr(expr));
513 }
514
515 fn rewrite_function_call(&self, function_call: &mut FunctionCall) {
516 function_call
517 .children
518 .iter_mut()
519 .for_each(|expr| self.rewrite_expr(expr));
520 }
521}
522
523#[cfg(test)]
524mod tests {
525 use super::*;
526
527 #[test]
528 fn test_alter_table_rename() {
529 let definition = "CREATE TABLE foo (a int, b int)";
530 let new_name = "bar";
531 let expected = "CREATE TABLE bar (a INT, b INT)";
532 let actual = alter_relation_rename(definition, new_name);
533 assert_eq!(expected, actual);
534 }
535
536 #[test]
537 fn test_rename_index_refs() {
538 let definition = "CREATE INDEX idx1 ON foo(v1 DESC, v2)";
539 let from = "foo";
540 let to = "bar";
541 let expected = "CREATE INDEX idx1 ON bar(v1 DESC, v2)";
542 let actual = alter_relation_rename_refs(definition, from, to);
543 assert_eq!(expected, actual);
544 }
545
546 #[test]
547 fn test_rename_sink_refs() {
548 let definition =
549 "CREATE SINK sink_t FROM foo WITH (connector = 'kafka', format = 'append_only')";
550 let from = "foo";
551 let to = "bar";
552 let expected =
553 "CREATE SINK sink_t FROM bar WITH (connector = 'kafka', format = 'append_only')";
554 let actual = alter_relation_rename_refs(definition, from, to);
555 assert_eq!(expected, actual);
556 }
557
558 #[test]
559 fn test_rename_with_alias_refs() {
560 let definition =
561 "CREATE MATERIALIZED VIEW mv1 AS SELECT foo.v1 AS m1v, foo.v2 AS m2v FROM foo";
562 let from = "foo";
563 let to = "bar";
564 let expected =
565 "CREATE MATERIALIZED VIEW mv1 AS SELECT foo.v1 AS m1v, foo.v2 AS m2v FROM bar AS foo";
566 let actual = alter_relation_rename_refs(definition, from, to);
567 assert_eq!(expected, actual);
568
569 let definition = "CREATE MATERIALIZED VIEW mv1 AS SELECT foo.v1 AS m1v, (foo.v2).v3 AS m2v FROM foo WHERE foo.v1 = 1 AND (foo.v2).v3 IS TRUE";
570 let expected = "CREATE MATERIALIZED VIEW mv1 AS SELECT foo.v1 AS m1v, (foo.v2).v3 AS m2v FROM bar AS foo WHERE foo.v1 = 1 AND (foo.v2).v3 IS TRUE";
571 let actual = alter_relation_rename_refs(definition, from, to);
572 assert_eq!(expected, actual);
573
574 let definition = "CREATE MATERIALIZED VIEW mv1 AS SELECT bar.v1 AS m1v, (bar.v2).v3 AS m2v FROM foo AS bar WHERE bar.v1 = 1";
575 let expected = "CREATE MATERIALIZED VIEW mv1 AS SELECT bar.v1 AS m1v, (bar.v2).v3 AS m2v FROM bar AS bar WHERE bar.v1 = 1";
576 let actual = alter_relation_rename_refs(definition, from, to);
577 assert_eq!(expected, actual);
578 }
579
580 #[test]
581 fn test_rename_with_complex_funcs() {
582 let definition = "CREATE MATERIALIZED VIEW mv1 AS SELECT \
583 agg1(\
584 foo.v1, func2(foo.v2) \
585 ORDER BY \
586 (SELECT foo.v3 FROM foo), \
587 (SELECT first_value(foo.v4) OVER (PARTITION BY (SELECT foo.v5 FROM foo) ORDER BY (SELECT foo.v6 FROM foo)) FROM foo)\
588 ) \
589 FROM foo";
590 let from = "foo";
591 let to = "bar";
592 let expected = "CREATE MATERIALIZED VIEW mv1 AS SELECT \
593 agg1(\
594 foo.v1, func2(foo.v2) \
595 ORDER BY \
596 (SELECT foo.v3 FROM bar AS foo), \
597 (SELECT first_value(foo.v4) OVER (PARTITION BY (SELECT foo.v5 FROM bar AS foo) ORDER BY (SELECT foo.v6 FROM bar AS foo)) FROM bar AS foo)\
598 ) \
599 FROM bar AS foo";
600 let actual = alter_relation_rename_refs(definition, from, to);
601 assert_eq!(expected, actual);
602 }
603}