This is an automated email from the ASF dual-hosted git repository.
rubenql 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 d670812cc0 [CALCITE-7253] Add Default Programs Like DecorrelateProgram
to the Hep-Rule Test
d670812cc0 is described below
commit d670812cc002353dfa58867f4ee6903cc1cd746d
Author: Zhen Chen <[email protected]>
AuthorDate: Tue Oct 28 22:15:01 2025 +0800
[CALCITE-7253] Add Default Programs Like DecorrelateProgram to the Hep-Rule
Test
---
.../java/org/apache/calcite/tools/Programs.java | 8 ++++
core/src/test/resources/sql/hep.iq | 39 +++++++++++++++-
.../java/org/apache/calcite/test/QuidemTest.java | 53 +++++++++++++---------
3 files changed, 78 insertions(+), 22 deletions(-)
diff --git a/core/src/main/java/org/apache/calcite/tools/Programs.java
b/core/src/main/java/org/apache/calcite/tools/Programs.java
index cfcf68c664..af6d62a5cb 100644
--- a/core/src/main/java/org/apache/calcite/tools/Programs.java
+++ b/core/src/main/java/org/apache/calcite/tools/Programs.java
@@ -235,6 +235,14 @@ public static Program heuristicJoinOrder(
};
}
+ public static Program decorrelate() {
+ return new DecorrelateProgram();
+ }
+
+ public static Program trim() {
+ return new TrimFieldsProgram();
+ }
+
public static Program calc(RelMetadataProvider metadataProvider) {
return hep(RelOptRules.CALC_RULES, true, metadataProvider);
}
diff --git a/core/src/test/resources/sql/hep.iq
b/core/src/test/resources/sql/hep.iq
index 8c5b36fe90..baa57592fa 100644
--- a/core/src/test/resources/sql/hep.iq
+++ b/core/src/test/resources/sql/hep.iq
@@ -42,9 +42,12 @@
# Example: "+Rule1,+Rule1,-Rule1" results in rule being removed
# 3. Optimizer execution pipeline:
# The optimizer uses a multi-program architecture with the following
execution order:
+# - SubQuery program — executed to handle subqueries
+# - Decorrelate program — executed to remove correlated subqueries
+# - Trim program — executed to remove unused columns
# - HEP program — executed by HepPlanner; initial rules set by CoreRules.*
# - Volcano program — executed by VolcanoPlanner; initial rules set by
EnumerableRules.ENUMERABLE_RULES
-# and modified by configurable EnumerableRules.* rule sets.
+# and modified by configurable EnumerableRules.* rule sets
# - Calc program — executed by HepPlanner; initial rules set by
RelOptRules.CALC_RULES (non-configurable)
!use scott
@@ -114,4 +117,38 @@ Missing conversion is LogicalAggregate[convention: NONE ->
ENUMERABLE]
!error
!set hep-rules original
+# This hep-rules test query with correlated subquery can be executed.
+!set hep-rules "
++CoreRules.PROJECT_FILTER_TRANSPOSE"
+
+SELECT e1.mgr, e1.comm
+FROM emp e1
+WHERE e1.mgr > 12
+ AND EXISTS (
+ SELECT 1
+ FROM emp e2
+ WHERE e2.mgr = e1.mgr
+ AND e2.comm > 5);
++------+---------+
+| MGR | COMM |
++------+---------+
+| 7698 | 0.00 |
+| 7698 | 1400.00 |
+| 7698 | 300.00 |
+| 7698 | 500.00 |
+| 7698 | |
++------+---------+
+(5 rows)
+
+!ok
+EnumerableCalc(expr#0..3=[{inputs}], MGR=[$t1], COMM=[$t2])
+ EnumerableHashJoin(condition=[=($1, $3)], joinType=[inner])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[CAST($t3):INTEGER],
expr#9=[12], expr#10=[>($t8, $t9)], EMPNO=[$t0], MGR=[$t3], COMM=[$t6],
$condition=[$t10])
+ EnumerableTableScan(table=[[scott, EMP]])
+ EnumerableAggregate(group=[{0}])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[CAST($t6):DECIMAL(12, 2)],
expr#9=[5.00:DECIMAL(12, 2)], expr#10=[>($t8, $t9)], expr#11=[IS NOT
NULL($t3)], expr#12=[AND($t10, $t11)], MGR=[$t3], $condition=[$t12])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+!set hep-rules original
+
# End hep.iq
diff --git a/testkit/src/main/java/org/apache/calcite/test/QuidemTest.java
b/testkit/src/main/java/org/apache/calcite/test/QuidemTest.java
index f55b2c060f..d4ec9d2ba9 100644
--- a/testkit/src/main/java/org/apache/calcite/test/QuidemTest.java
+++ b/testkit/src/main/java/org/apache/calcite/test/QuidemTest.java
@@ -268,27 +268,38 @@ protected void checkRun(String path) throws Exception {
}
if (propertyName.equals("hep-rules")) {
- closer.add(
- Hook.PROGRAM.addThread((Consumer<Holder<Program>>)
- holder -> {
- List<RelOptRule> hepRules = new ArrayList<>();
- List<RelOptRule> volcanoRules =
- new ArrayList<>(EnumerableRules.ENUMERABLE_RULES);
-
- applyRulesInOrder((String) value, hepRules,
volcanoRules);
-
- Program hepProgram =
- Programs.hep(RuleSets.ofList(hepRules), false,
- DefaultRelMetadataProvider.INSTANCE);
- Program calcProgram =
- Programs.calc(DefaultRelMetadataProvider.INSTANCE);
- Program volcanoProgram =
- Programs.of(RuleSets.ofList(volcanoRules));
-
- Program combinedProgram =
- Programs.sequence(hepProgram, volcanoProgram,
calcProgram);
- holder.set(combinedProgram);
- }));
+ if (value.equals("original")) {
+ closer.add(
+ Hook.PROGRAM.addThread((Consumer<Holder<Program>>)
+ holder -> holder.set(null)));
+ } else {
+ closer.add(
+ Hook.PROGRAM.addThread((Consumer<Holder<Program>>)
+ holder -> {
+ List<RelOptRule> hepRules = new ArrayList<>();
+ List<RelOptRule> volcanoRules =
+ new
ArrayList<>(EnumerableRules.ENUMERABLE_RULES);
+
+ applyRulesInOrder((String) value, hepRules,
volcanoRules);
+
+ Program subQueryProgram =
+
Programs.subQuery(DefaultRelMetadataProvider.INSTANCE);
+ Program decorrelateProgram = Programs.decorrelate();
+ Program trimProgram = Programs.trim();
+ Program hepProgram =
+ Programs.hep(RuleSets.ofList(hepRules), false,
+ DefaultRelMetadataProvider.INSTANCE);
+ Program calcProgram =
+
Programs.calc(DefaultRelMetadataProvider.INSTANCE);
+ Program volcanoProgram =
+ Programs.of(RuleSets.ofList(volcanoRules));
+
+ Program combinedProgram =
+ Programs.sequence(subQueryProgram,
decorrelateProgram, trimProgram,
+ hepProgram, volcanoProgram, calcProgram);
+ holder.set(combinedProgram);
+ }));
+ }
}
})
.withEnv(QuidemTest::getEnv)