Rewrite a statement to use decimal functions
(&mut self, stmt: &mut Statement)
| 139 | |
| 140 | /// Rewrite a statement to use decimal functions |
| 141 | pub fn rewrite_statement(&mut self, stmt: &mut Statement) -> Result<(), String> { |
| 142 | match stmt { |
| 143 | Statement::Query(query) => { |
| 144 | // Always rewrite queries - the optimization is applied at the expression level |
| 145 | self.rewrite_query(query) |
| 146 | } |
| 147 | Statement::Insert(insert) => { |
| 148 | if let Some(source) = &mut insert.source { |
| 149 | // Check if the target table has decimal columns |
| 150 | let table_name = match &insert.table { |
| 151 | sqlparser::ast::TableObject::TableName(name) => name.to_string(), |
| 152 | _ => return Ok(()), |
| 153 | }; |
| 154 | let tables = self.extract_table_names_from_query(source); |
| 155 | let mut all_tables = vec![table_name]; |
| 156 | all_tables.extend(tables); |
| 157 | |
| 158 | if !self.any_table_has_decimal_columns(&all_tables) { |
| 159 | return Ok(()); // Skip rewriting |
| 160 | } |
| 161 | self.rewrite_query(source) |
| 162 | } else { |
| 163 | Ok(()) |
| 164 | } |
| 165 | } |
| 166 | Statement::Update { table, selection, assignments, .. } => { |
| 167 | // Check if the table has decimal columns |
| 168 | if let sqlparser::ast::TableFactor::Table { name, .. } = &table.relation { |
| 169 | let table_name = name.to_string(); |
| 170 | let has_decimal_columns = self.any_table_has_decimal_columns(std::slice::from_ref(&table_name)); |
| 171 | |
| 172 | // Create context with table name |
| 173 | let context = QueryContext { |
| 174 | default_table: Some(table_name), |
| 175 | ..Default::default() |
| 176 | }; |
| 177 | |
| 178 | // Always rewrite WHERE clause to check for implicit casts |
| 179 | if let Some(expr) = selection { |
| 180 | self.rewrite_expression_for_implicit_casts(expr, &context)?; |
| 181 | } |
| 182 | |
| 183 | // Rewrite assignment expressions only if table has decimal columns |
| 184 | if has_decimal_columns { |
| 185 | // For UPDATE assignments, we don't want to wrap simple numeric literals |
| 186 | // because rust_decimal can't handle very large numbers (>28 digits) |
| 187 | for assignment in assignments { |
| 188 | self.rewrite_update_assignment(&mut assignment.value, &context)?; |
| 189 | } |
| 190 | } |
| 191 | } |
| 192 | Ok(()) |
| 193 | } |
| 194 | Statement::Delete(delete) => { |
| 195 | // Extract all tables |
| 196 | let mut tables = Vec::new(); |
| 197 | |
| 198 | // Add tables from FROM clause if present |