1414import javax .annotation .processing .Generated ;
1515
1616public class CalciteGenerator implements CodeGenerator <CalciteGenerator .Env > {
17-
17+
1818 @ Override
1919 public Env preMatch (String rulename ) {
2020 return Env .empty (rulename );
@@ -229,22 +229,6 @@ public Env transformScan(Env env, RelRN.Scan scan) {
229229 return env .focus (env .current () + ".push(" + env .symbols ().get (scan .name ()) + ")" );
230230 }
231231
232- // @Override
233- // public Env onMatchCustom(Env env, RexRN custom) {
234- // return switch (custom) {
235- // case RRule.JoinConditionPush.JoinPred joinPred -> {
236- // var pred = env.expressions().first();
237- // var breakdown_env = assignVariable(env, STR."customSplitFilter(\{pred})");
238- // var breakdown = breakdown_env.expressions().first();
239- // yield breakdown_env
240- // .symbol(joinPred.bothPred(), STR."\{breakdown}.getBoth()")
241- // .symbol(joinPred.leftPred(), STR."\{breakdown}.getLeft()")
242- // .symbol(joinPred.rightPred(), STR."\{breakdown}.getRight()");
243- // }
244- // default -> CodeGenerator.super.onMatchCustom(env, custom);
245- // };
246- // }
247-
248232 @ Override
249233 public Env transformFilter (Env env , RelRN .Filter filter ) {
250234 var source_transform = transform (env , filter .source ());
@@ -274,7 +258,7 @@ public Env transformPred(Env env, RexRN.Pred pred) {
274258 return currentEnv .focus (env .current () + ".call(" + operatorCall + ", " + argsString + ")" );
275259 }
276260 else if (env .rulename .equals ("ProjectFilterTranspose" )) {
277- return env .focus ("org.qed.HelperFunction .mapFilterToProjectedColumns(call)" );
261+ return env .focus ("org.qed.Backends.Calcite.HelperFunctions .mapFilterToProjectedColumns(call)" );
278262 }
279263 else if (env .rulename .equals ("FilterProjectTranspose" )) {
280264 return env .focus (
@@ -283,10 +267,10 @@ else if (env.rulename.equals("FilterProjectTranspose")) {
283267 );
284268 }
285269 else if (env .rulename .equals ("AggregateFilterTranspose" )) {
286- return env .focus ("org.qed.HelperFunction .mapFilterToAggregatedColumns(call)" );
270+ return env .focus ("org.qed.Backends.Calcite.HelperFunctions .mapFilterToAggregatedColumns(call)" );
287271 }
288272 else if (env .rulename .equals ("FilterAggregateTranspose" )) {
289- return env .focus ("org.qed.HelperFunction .pushFilterPastAggregate(call)" );
273+ return env .focus ("org.qed.Backends.Calcite.HelperFunctions .pushFilterPastAggregate(call)" );
290274 }
291275 else {
292276 return env .focus (env .symbols ().get (pred .operator ().getName ()));
@@ -324,22 +308,22 @@ public Env transformJoinWithPushedConds(Env env, RelRN.JoinWithPushedConds join)
324308 var envWithBuilder = builderDecl .getValue ();
325309
326310 var leftCondDecl = envWithBuilder .declare (
327- "org.qed.HelperFunction .ConditionDecomposer.extractLeftOnlyConditions(" +
311+ "org.qed.Backends.Calcite.HelperFunctions .ConditionDecomposer.extractLeftOnlyConditions(" +
328312 "((LogicalJoin) call.rel(0)).getCondition(), " +
329313 "call.rel(1).getRowType().getFieldCount(), call)"
330314 );
331315 var envWithLeftCond = leftCondDecl .getValue ();
332316
333317 var rightCondDecl = envWithLeftCond .declare (
334- "org.qed.HelperFunction .ConditionDecomposer.extractRightOnlyConditions(" +
318+ "org.qed.Backends.Calcite.HelperFunctions .ConditionDecomposer.extractRightOnlyConditions(" +
335319 "((LogicalJoin) call.rel(0)).getCondition(), " +
336320 "call.rel(1).getRowType().getFieldCount(), " +
337321 "call.rel(1).getRowType().getFieldCount() + call.rel(2).getRowType().getFieldCount(), call)"
338322 );
339323 var envWithRightCond = rightCondDecl .getValue ();
340324
341325 var joinCondDecl = envWithRightCond .declare (
342- "org.qed.HelperFunction .ConditionDecomposer.extractJoinConditions(" +
326+ "org.qed.Backends.Calcite.HelperFunctions .ConditionDecomposer.extractJoinConditions(" +
343327 "((LogicalJoin) call.rel(0)).getCondition(), " +
344328 "call.rel(1).getRowType().getFieldCount(), " +
345329 "call.rel(1).getRowType().getFieldCount() + call.rel(2).getRowType().getFieldCount(), call)"
@@ -398,6 +382,15 @@ public Env transformUnion(Env env, RelRN.Union union) {
398382
399383 @ Override
400384 public Env transformIntersect (Env env , RelRN .Intersect intersect ) {
385+ if (env .rulename .equals ("PruneEmptyIntersect" )) {
386+ // 特殊处理:直接生成正确的代码
387+ String builderVar = env .statements ().get (0 ).split (" " )[1 ];
388+ return env .focus (
389+ builderVar + ".push(call.rel(1)).empty()" +
390+ ".push(call.rel(2))" +
391+ ".intersect(false, 2)"
392+ );
393+ }
401394 boolean all = intersect .all ();
402395 int sourceCount = intersect .sources ().size ();
403396 var current_env = env ;
@@ -436,7 +429,7 @@ public Env transformProj(Env env, RexRN.Proj proj) {
436429 @ Override
437430 public Env transformProject (Env env , RelRN .Project project ) {
438431 if (env .rulename .equals ("ProjectMerge" )) {
439- return env .focus ("org.qed.HelperFunction .mergeProjections(call)" );
432+ return env .focus ("org.qed.Backends.Calcite.HelperFunctions .mergeProjections(call)" );
440433 }
441434
442435 var source_transform = transform (env , project .source ());
@@ -460,9 +453,114 @@ public Env transformEmpty(Env env, RelRN.Empty empty) {
460453 return env .focus (env .current () + ".empty()" );
461454 }
462455
456+ // @Override
457+ // public Env onMatchCustom(Env env, RexRN custom) {
458+ // return switch (custom) {
459+ // case RRule.JoinConditionPush.JoinPred joinPred -> {
460+ // var pred = env.expressions().first();
461+ // var breakdown_env = assignVariable(env, STR."customSplitFilter(\{pred})");
462+ // var breakdown = breakdown_env.expressions().first();
463+ // yield breakdown_env
464+ // .symbol(joinPred.bothPred(), STR."\{breakdown}.getBoth()")
465+ // .symbol(joinPred.leftPred(), STR."\{breakdown}.getLeft()")
466+ // .symbol(joinPred.rightPred(), STR."\{breakdown}.getRight()");
467+ // }
468+ // default -> CodeGenerator.super.onMatchCustom(env, custom);
469+ // };
470+ // }
471+
472+ @ Override
473+ public Env onMatchCustom (Env env , RelRN custom ) {
474+ if (env .rulename .equals ("AggregateProjectConstantToDummyJoin" )) {
475+ return switch (custom ) {
476+ case org .qed .RRuleInstances .AggregateProjectConstantToDummyJoin .SourceTable st ->
477+ env .next ().grow ("operand(RelNode.class).anyInputs()" );
478+ case org .qed .RRuleInstances .AggregateProjectConstantToDummyJoin .ProjectWithConstantLiterals p -> {
479+ var sourceMatch = onMatch (env , p .input ());
480+ yield sourceMatch .grow ("operand(LogicalProject.class).oneInput(" + sourceMatch .skeleton () + ")" );
481+ }
482+ case org .qed .RRuleInstances .AggregateProjectConstantToDummyJoin .AggregateGroupingByConstants agg -> {
483+ var sourceMatch = onMatch (env , agg .input ());
484+ yield sourceMatch .grow ("operand(LogicalAggregate.class).oneInput(" + sourceMatch .skeleton () + ")" );
485+ }
486+ default -> env ;
487+ };
488+ }
489+
490+ if (env .rulename .equals ("UnionToDistinct" )) {
491+ return switch (custom ) {
492+ case org .qed .RRuleInstances .UnionToDistinct .DistinctUnion u -> {
493+ var leftMatch = onMatch (env .next (), u .left ());
494+ var rightMatch = onMatch (leftMatch .next (), u .right ());
495+ // Match Union DISTINCT (all=false)
496+ yield rightMatch .grow (
497+ "operand(LogicalUnion.class)" +
498+ ".predicate(union -> !union.all)" +
499+ ".anyInputs()"
500+ );
501+ }
502+ default -> env ;
503+ };
504+ }
505+
506+ if (env .rulename .equals ("UnionPullUpConstants" )) {
507+ return switch (custom ) {
508+ case org .qed .RRuleInstances .UnionPullUpConstants .UnionWithConstantColumns u -> {
509+ var leftMatch = onMatch (env .next (), u .left ());
510+ var rightMatch = onMatch (leftMatch .next (), u .right ());
511+ // Match Union ALL with field count > 1
512+ yield rightMatch .grow (
513+ "operand(LogicalUnion.class)" +
514+ ".predicate(union -> union.getRowType().getFieldCount() > 1)" +
515+ ".anyInputs()"
516+ );
517+ }
518+ case org .qed .RRuleInstances .UnionPullUpConstants .LeftProjectionWithConstants left -> {
519+ var sourceMatch = onMatch (env , left .input ());
520+ yield sourceMatch .grow ("operand(LogicalProject.class).oneInput(" + sourceMatch .skeleton () + ")" );
521+ }
522+ case org .qed .RRuleInstances .UnionPullUpConstants .RightProjectionWithConstants right -> {
523+ var sourceMatch = onMatch (env , right .input ());
524+ yield sourceMatch .grow ("operand(LogicalProject.class).oneInput(" + sourceMatch .skeleton () + ")" );
525+ }
526+ default -> env ;
527+ };
528+ }
529+
530+ if (env .rulename .equals ("ProjectAggregateMerge" )) {
531+ return switch (custom ) {
532+ case org .qed .RRuleInstances .ProjectAggregateMerge .ProjectUsingSubsetOfAggregates p -> {
533+ var sourceMatch = onMatch (env , p .input ());
534+ yield sourceMatch .grow ("operand(LogicalProject.class).oneInput(" + sourceMatch .skeleton () + ")" );
535+ }
536+ case org .qed .RRuleInstances .ProjectAggregateMerge .AggregateWithMultipleCalls a -> {
537+ var sourceMatch = onMatch (env , a .input ());
538+ yield sourceMatch .grow ("operand(LogicalAggregate.class).oneInput(" + sourceMatch .skeleton () + ")" );
539+ }
540+ case org .qed .RRuleInstances .ProjectAggregateMerge .SourceTable st -> {
541+ yield env .next ().grow ("operand(RelNode.class).anyInputs()" );
542+ }
543+ default -> env ;
544+ };
545+ }
546+
547+ return CodeGenerator .super .onMatchCustom (env , custom );
548+ }
463549
464550 @ Override
465551 public Env transformCustom (Env env , RelRN custom ) {
552+ if (env .rulename .equals ("AggregateProjectConstantToDummyJoin" )) {
553+ return env .focus ("org.qed.Backends.Calcite.HelperFunctions.aggregateProjectConstantToDummyJoin(call)" );
554+ }
555+ if (env .rulename .equals ("UnionToDistinct" )) {
556+ return env .focus ("org.qed.Backends.Calcite.HelperFunctions.unionToDistinct(call)" );
557+ }
558+ if (env .rulename .equals ("UnionPullUpConstants" )) {
559+ return env .focus ("org.qed.Backends.Calcite.HelperFunctions.unionPullUpConstants(call)" );
560+ }
561+ if (env .rulename .equals ("ProjectAggregateMerge" )) {
562+ return env .focus ("org.qed.Backends.Calcite.HelperFunctions.projectAggregateMerge(call)" );
563+ }
466564 return switch (custom ) {
467565 case org .qed .RRuleInstances .JoinCommute .ProjectionRelRN projection -> {
468566 var sourceEnv = transform (env , projection .source ());
@@ -536,10 +634,29 @@ public Env onMatchAggregate(Env env, RelRN.Aggregate aggregate) {
536634 @ Override
537635 public Env transformAggregate (Env env , RelRN .Aggregate aggregate ) {
538636 if (env .rulename .equals ("AggregateProjectMerge" )) {
539- return env .focus ("org.qed.HelperFunction .createMergedAggregateProject(call)" );
637+ return env .focus ("org.qed.Backends.Calcite.HelperFunctions .createMergedAggregateProject(call)" );
540638 }
541639 else if (env .rulename .equals ("AggregateExtractProject" )) {
542- return env .focus ("org.qed.HelperFunction.extractProjectForAggregate(call)" );
640+ return env .focus ("org.qed.Backends.Calcite.HelperFunctions.extractProjectForAggregate(call)" );
641+ }
642+ else if (env .rulename .equals ("AggregateJoinRemove" )) {
643+ // 直接手动构建,不用递归transform
644+ var groupSetDecl = env .declare ("((LogicalAggregate) call.rel(0)).getGroupSet()" );
645+ var envWithGroupSet = groupSetDecl .getValue ();
646+ var aggCallsDecl = envWithGroupSet .declare ("((LogicalAggregate) call.rel(0)).getAggCallList()" );
647+ var envWithAggCalls = aggCallsDecl .getValue ();
648+
649+ // 从statements里提取builder变量名 (第一个statement就是 "var var_X = call.builder();")
650+ String builderVar = env .statements ().get (0 ).split (" " )[1 ];
651+
652+ return envWithAggCalls .focus (
653+ builderVar + ".push(call.rel(3)).push(call.rel(4))" +
654+ ".join(JoinRelType.INNER, " + builderVar + ".literal(true))" +
655+ ".aggregate(" + builderVar + ".groupKey(" + groupSetDecl .getKey () + "), " + aggCallsDecl .getKey () + ")"
656+ );
657+ }
658+ else if (env .rulename .equals ("AggregateJoinJoinRemove" )) {
659+ return env .focus ("org.qed.Backends.Calcite.HelperFunctions.aggregateJoinJoinRemove(call)" );
543660 }
544661
545662 // Default aggregate transformation for other rules
0 commit comments