@@ -237,7 +237,7 @@ public RelNode visitParse(Parse node, CalcitePlanContext context) {
237
237
String pattern = (String ) node .getPattern ().getValue ();
238
238
List <String > groupCandidates =
239
239
ParseUtils .getNamedGroupCandidates (parseMethod , pattern , arguments );
240
- List <RexNode > overrideFields = new ArrayList <>();
240
+ List <RexNode > overridingFields = new ArrayList <>();
241
241
List <RexNode > newFields =
242
242
groupCandidates .stream ()
243
243
.map (
@@ -248,14 +248,16 @@ public RelNode visitParse(Parse node, CalcitePlanContext context) {
248
248
sourceField ,
249
249
context .rexBuilder .makeLiteral (pattern ));
250
250
if (originalFieldNames .contains (group )) {
251
- overrideFields .add (context .relBuilder .field (group ));
251
+ overridingFields .add (context .relBuilder .field (group ));
252
252
}
253
253
return context .relBuilder .alias (regexp , group );
254
254
})
255
255
.toList ();
256
256
context .relBuilder .projectPlus (newFields );
257
- context .relBuilder .projectExcept (overrideFields );
258
- renameForOverriding (groupCandidates , context );
257
+
258
+ if (!overridingFields .isEmpty ()) {
259
+ renameForOverriding (overridingFields , groupCandidates , context );
260
+ }
259
261
return context .relBuilder .peek ();
260
262
}
261
263
@@ -283,16 +285,13 @@ public RelNode visitEval(Eval node, CalcitePlanContext context) {
283
285
ImmutableList .of (v .get ().id ));
284
286
context .popCorrelVar ();
285
287
} else {
286
- // Overriding the existing field if the alias has the same name with original field
287
- // name.
288
- RexNode overrideField = null ;
288
+ // Overriding the existing field if the alias has the same name with original field.
289
289
String alias =
290
290
((RexLiteral ) ((RexCall ) eval ).getOperands ().get (1 )).getValueAs (String .class );
291
291
if (originalFieldNames .contains (alias )) {
292
- overrideField = context .relBuilder .field (alias );
292
+ RexNode toOverride = context .relBuilder .field (alias );
293
293
context .relBuilder .projectPlus (eval );
294
- context .relBuilder .projectExcept (overrideField );
295
- renameForOverriding (List .of (alias ), context );
294
+ renameForOverriding (List .of (toOverride ), List .of (alias ), context );
296
295
} else {
297
296
context .relBuilder .projectPlus (eval );
298
297
}
@@ -301,12 +300,21 @@ public RelNode visitEval(Eval node, CalcitePlanContext context) {
301
300
return context .relBuilder .peek ();
302
301
}
303
302
304
- private static void renameForOverriding (List <String > newNames , CalcitePlanContext context ) {
305
- List <String > originalFieldNames = context .relBuilder .peek ().getRowType ().getFieldNames ();
306
- int length = originalFieldNames .size ();
303
+ private void renameForOverriding (
304
+ List <RexNode > toOverrideList ,
305
+ List <String > newNames ,
306
+ CalcitePlanContext context ) {
307
+ assert toOverrideList .size () == newNames .size () : "Overriding fields are not matched" ;
308
+ // 1. drop the overriding field list, it's duplicated now. For example "age, country"
309
+ context .relBuilder .projectExcept (toOverrideList );
310
+ // 2. get current fields list, the "age0, country0" should include in it.
311
+ List <String > currentFields = context .relBuilder .peek ().getRowType ().getFieldNames ();
312
+ int length = currentFields .size ();
313
+ // 3. add new names "age, country" to the end of rename list.
307
314
List <String > expectedRenameFields =
308
- new ArrayList <>(originalFieldNames .subList (0 , length - newNames .size ()));
315
+ new ArrayList <>(currentFields .subList (0 , length - newNames .size ()));
309
316
expectedRenameFields .addAll (newNames );
317
+ // 4. rename
310
318
context .relBuilder .rename (expectedRenameFields );
311
319
}
312
320
0 commit comments