@@ -28,10 +28,12 @@ use crate::binder::bind_mutation::bind::MutationStrategy;
28
28
use crate :: binder:: bind_mutation:: mutation_expression:: MutationExpression ;
29
29
use crate :: binder:: util:: TableIdentifier ;
30
30
use crate :: binder:: Binder ;
31
+ use crate :: optimizer:: ir:: Matcher ;
31
32
use crate :: optimizer:: ir:: SExpr ;
32
33
use crate :: plans:: AggregateFunction ;
33
34
use crate :: plans:: BoundColumnRef ;
34
35
use crate :: plans:: Plan ;
36
+ use crate :: plans:: RelOp ;
35
37
use crate :: plans:: RelOperator ;
36
38
use crate :: plans:: ScalarItem ;
37
39
use crate :: plans:: VisitorMut ;
@@ -118,17 +120,20 @@ impl Binder {
118
120
let Plan :: DataMutation { box s_expr, .. } = & plan else {
119
121
return Ok ( plan) ;
120
122
} ;
121
- let RelOperator :: Mutation ( mutation) = & * s_expr. plan else {
123
+ let RelOperator :: Mutation ( mutation) = s_expr. plan ( ) else {
122
124
return Ok ( plan) ;
123
125
} ;
124
- let filter_expr = & s_expr. children [ 0 ] ;
125
- let RelOperator :: Filter ( _) = & * filter_expr. plan else {
126
- return Ok ( plan) ;
126
+ let input_expr = s_expr. unary_child ( ) ;
127
+ let matcher = Matcher :: MatchOp {
128
+ op_type : RelOp :: Filter ,
129
+ children : vec ! [ Matcher :: MatchOp {
130
+ op_type: RelOp :: Join ,
131
+ children: vec![ Matcher :: Leaf , Matcher :: Leaf ] ,
132
+ } ] ,
127
133
} ;
128
- let input = & filter_expr. children [ 0 ] ;
129
- let RelOperator :: Join ( _) = & * input. plan else {
134
+ if !matcher. matches ( input_expr) {
130
135
return Ok ( plan) ;
131
- } ;
136
+ }
132
137
133
138
let mut mutation = mutation. clone ( ) ;
134
139
@@ -176,7 +181,6 @@ impl Binder {
176
181
. flat_map ( |expr| expr. used_columns ( ) . into_iter ( ) )
177
182
} )
178
183
} )
179
- . chain ( mutation. required_columns . iter ( ) . copied ( ) )
180
184
. collect :: < HashSet < _ > > ( ) ;
181
185
182
186
let used_columns = used_columns
@@ -201,7 +205,7 @@ impl Binder {
201
205
202
206
let display_name = format ! ( "any({})" , binding. index) ;
203
207
let old = binding. index ;
204
- let mut aggr_func = ScalarExpr :: AggregateFunction ( AggregateFunction {
208
+ let mut aggr_func: ScalarExpr = AggregateFunction {
205
209
span : None ,
206
210
func_name : "any" . to_string ( ) ,
207
211
distinct : false ,
@@ -213,7 +217,8 @@ impl Binder {
213
217
return_type : binding. data_type . clone ( ) ,
214
218
sort_descs : vec ! [ ] ,
215
219
display_name : display_name. clone ( ) ,
216
- } ) ;
220
+ }
221
+ . into ( ) ;
217
222
218
223
let mut rewriter =
219
224
AggregateRewriter :: new ( & mut mutation. bind_context , self . metadata . clone ( ) ) ;
@@ -242,14 +247,30 @@ impl Binder {
242
247
for eval in & mut mutation. matched_evaluators {
243
248
if let Some ( expr) = & mut eval. condition {
244
249
for ( _, old, new) in & aggr_columns {
245
- expr. replace_column ( * old, * new) ?
250
+ expr. replace_column_datatype_to_nullable ( * old, * new) ?
246
251
}
247
252
}
248
253
249
254
if let Some ( update) = & mut eval. update {
250
255
for ( _, expr) in update. iter_mut ( ) {
251
256
for ( _, old, new) in & aggr_columns {
252
- expr. replace_column ( * old, * new) ?
257
+ expr. replace_column_datatype_to_nullable ( * old, * new) ?
258
+ }
259
+ }
260
+
261
+ for ( field_index, expr) in update. iter_mut ( ) {
262
+ if let Some ( target_column) =
263
+ mutation. bind_context . columns . iter ( ) . find ( |binding| {
264
+ binding. table_index == Some ( mutation. target_table_index )
265
+ && binding. column_name == field_index. to_string ( )
266
+ } )
267
+ {
268
+ let columns_used = expr. used_columns ( ) ;
269
+ for col_idx in columns_used {
270
+ if col_idx != target_column. index {
271
+ expr. replace_column_datatype_to_nullable ( col_idx, col_idx) ?;
272
+ }
273
+ }
253
274
}
254
275
}
255
276
}
@@ -270,26 +291,23 @@ impl Binder {
270
291
. collect ( ) ,
271
292
) ;
272
293
273
- let aggr_expr = self . bind_aggregate ( & mut mutation. bind_context , ( * * filter_expr ) . clone ( ) ) ?;
294
+ let aggr_expr = self . bind_aggregate ( & mut mutation. bind_context , input_expr . clone ( ) ) ?;
274
295
275
- let s_expr = SExpr :: create_unary (
296
+ let s_expr = Box :: new ( SExpr :: create_unary (
276
297
Arc :: new ( RelOperator :: Mutation ( mutation) ) ,
277
298
Arc :: new ( aggr_expr) ,
278
- ) ;
299
+ ) ) ;
279
300
280
301
let Plan :: DataMutation {
281
302
schema, metadata, ..
282
303
} = plan
283
304
else {
284
305
unreachable ! ( )
285
306
} ;
286
-
287
- let plan = Plan :: DataMutation {
288
- s_expr : Box :: new ( s_expr) ,
307
+ Ok ( Plan :: DataMutation {
308
+ s_expr,
289
309
schema,
290
310
metadata,
291
- } ;
292
-
293
- Ok ( plan)
311
+ } )
294
312
}
295
313
}
0 commit comments