risingwave_sqlsmith/sqlreduce/passes/
replace.rs1use risingwave_sqlparser::ast::{Expr, SelectItem, SetExpr, Value};
16
17use crate::sqlreduce::passes::{Ast, Transform, extract_query, extract_query_mut};
18
19pub struct ScalarReplace;
41
42impl ScalarReplace {
43 fn replacement_for_value(v: &Value) -> Value {
44 match v {
45 Value::Number(_) => Value::Number("1".to_owned()),
46 Value::Boolean(_) => Value::Boolean(true),
47 Value::SingleQuotedString(_) => Value::SingleQuotedString("a".to_owned()),
48 Value::Null => Value::Null,
49 _ => Value::Null,
50 }
51 }
52}
53
54impl Transform for ScalarReplace {
55 fn name(&self) -> String {
56 "scalar_replace".to_owned()
57 }
58
59 fn get_reduction_points(&self, ast: Ast) -> Vec<usize> {
60 let mut reduction_points = Vec::new();
61 if let Some(query) = extract_query(&ast)
62 && let SetExpr::Select(select) = &query.body
63 {
64 for (i, item) in select.projection.iter().enumerate() {
65 if let SelectItem::UnnamedExpr(Expr::Value(_)) = item {
66 reduction_points.push(i);
67 }
68 }
69 }
70 reduction_points
71 }
72
73 fn apply_on(&self, ast: &mut Ast, reduction_points: Vec<usize>) -> Ast {
74 if let Some(query) = extract_query_mut(ast)
75 && let SetExpr::Select(select) = &mut query.body
76 {
77 for i in reduction_points {
78 if let SelectItem::UnnamedExpr(Expr::Value(ref mut v)) = select.projection[i] {
79 let new_v = Self::replacement_for_value(v);
80 *v = new_v;
81 }
82 }
83 }
84 ast.clone()
85 }
86}
87
88pub struct NullReplace;
106
107impl Transform for NullReplace {
108 fn name(&self) -> String {
109 "null_replace".to_owned()
110 }
111
112 fn get_reduction_points(&self, ast: Ast) -> Vec<usize> {
113 let mut reduction_points = Vec::new();
114 if let Some(query) = extract_query(&ast)
115 && let SetExpr::Select(select) = &query.body
116 {
117 for (i, _) in select.projection.iter().enumerate() {
118 reduction_points.push(i);
119 }
120 }
121 reduction_points
122 }
123
124 fn apply_on(&self, ast: &mut Ast, reduction_points: Vec<usize>) -> Ast {
125 if let Some(query) = extract_query_mut(ast)
126 && let SetExpr::Select(select) = &mut query.body
127 {
128 for i in reduction_points {
129 select.projection[i] = SelectItem::UnnamedExpr(Expr::Value(Value::Null));
130 }
131 }
132 ast.clone()
133 }
134}
135
136#[cfg(test)]
137mod tests {
138 use super::*;
139 use crate::parse_sql;
140
141 #[test]
142 fn test_scalar_replace() {
143 let sql = "SELECT 42, 'hello', false, null;";
144 let ast = parse_sql(sql);
145 let reduction_points = ScalarReplace.get_reduction_points(ast[0].clone());
146 assert_eq!(reduction_points, vec![0, 1, 2, 3]);
147
148 let new_ast = ScalarReplace.apply_on(&mut ast[0].clone(), reduction_points);
149 assert_eq!(new_ast, parse_sql("SELECT 1, 'a', true, null;")[0].clone());
150 }
151
152 #[test]
153 fn test_null_replace() {
154 let sql = "SELECT a, b, c;";
155 let ast = parse_sql(sql);
156 let reduction_points = NullReplace.get_reduction_points(ast[0].clone());
157 assert_eq!(reduction_points, vec![0, 1, 2]);
158
159 let new_ast = NullReplace.apply_on(&mut ast[0].clone(), reduction_points);
160 assert_eq!(new_ast, parse_sql("SELECT NULL, NULL, NULL;")[0].clone());
161 }
162}