This is an automated email from the ASF dual-hosted git repository.
zhenchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new 09a149942f [CALCITE-7386] An error occurred while using
TopDownGeneralDecorrelator to process the aggregate(col) filter
09a149942f is described below
commit 09a149942f024477a853c727227be18bbfab8c8c
Author: Zhen Chen <[email protected]>
AuthorDate: Sat Mar 7 20:01:01 2026 +0800
[CALCITE-7386] An error occurred while using TopDownGeneralDecorrelator to
process the aggregate(col) filter
---
.../sql2rel/TopDownGeneralDecorrelator.java | 22 ++++++++++++++++++++--
core/src/test/resources/sql/measure.iq | 2 --
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git
a/core/src/main/java/org/apache/calcite/sql2rel/TopDownGeneralDecorrelator.java
b/core/src/main/java/org/apache/calcite/sql2rel/TopDownGeneralDecorrelator.java
index c1f8494ebd..c3d2bd9249 100644
---
a/core/src/main/java/org/apache/calcite/sql2rel/TopDownGeneralDecorrelator.java
+++
b/core/src/main/java/org/apache/calcite/sql2rel/TopDownGeneralDecorrelator.java
@@ -18,6 +18,7 @@
import org.apache.calcite.linq4j.function.Experimental;
import org.apache.calcite.plan.RelOptCostImpl;
+import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.plan.Strong;
import org.apache.calcite.plan.hep.HepPlanner;
@@ -35,6 +36,7 @@
import org.apache.calcite.rel.core.SetOp;
import org.apache.calcite.rel.core.Sort;
import org.apache.calcite.rel.rules.CoreRules;
+import org.apache.calcite.rel.rules.FilterProjectTransposeRule;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexCall;
import org.apache.calcite.rex.RexCorrelVariable;
@@ -196,10 +198,26 @@ private TopDownGeneralDecorrelator
createSubDecorrelator() {
* @return Equivalent node without correlation
*/
public static RelNode decorrelateQuery(RelNode rel, RelBuilder builder) {
+ // Use a custom FILTER_PROJECT_TRANSPOSE that does not push filters through
+ // projects containing V2M (measure) expressions. Pushing a filter past a
+ // V2M-carrying project changes the scope of the measure computation and
+ // produces incorrect aggregate results.
+ RelOptRule filterProjectTransposeNoV2m =
+ CoreRules.FILTER_PROJECT_TRANSPOSE.config
+ .as(FilterProjectTransposeRule.Config.class)
+ .withOperandSupplier(b0 ->
+ b0.operand(Filter.class)
+ .predicate(f ->
!RexUtil.containsCorrelation(f.getCondition()))
+ .oneInput(b1 ->
+ b1.operand(Project.class)
+ .predicate(p ->
!RexUtil.find(SqlKind.V2M).inProject(p))
+ .anyInputs()))
+ .as(FilterProjectTransposeRule.Config.class)
+ .toRule();
HepProgram preProgram = HepProgram.builder()
.addRuleCollection(
ImmutableList.of(
- CoreRules.FILTER_PROJECT_TRANSPOSE,
+ filterProjectTransposeNoV2m,
CoreRules.FILTER_INTO_JOIN,
CoreRules.FILTER_CORRELATE))
.build();
@@ -226,7 +244,7 @@ public static RelNode decorrelateQuery(RelNode rel,
RelBuilder builder) {
HepProgram postProgram = HepProgram.builder()
.addRuleCollection(
ImmutableList.of(
- CoreRules.FILTER_PROJECT_TRANSPOSE,
+ filterProjectTransposeNoV2m,
CoreRules.FILTER_INTO_JOIN,
CoreRules.MARK_TO_SEMI_OR_ANTI_JOIN_RULE,
CoreRules.PROJECT_MERGE,
diff --git a/core/src/test/resources/sql/measure.iq
b/core/src/test/resources/sql/measure.iq
index 624041d090..aa8ee999fd 100644
--- a/core/src/test/resources/sql/measure.iq
+++ b/core/src/test/resources/sql/measure.iq
@@ -667,7 +667,6 @@ group by deptno, deptno2;
!ok
-!if (use_old_decorr) {
# Measure with FILTER
select job,
c,
@@ -690,7 +689,6 @@ group by job;
(3 rows)
!ok
-!}
!if (false) {
# Null values in GROUP BY