This is an automated email from the ASF dual-hosted git repository.
asolimando 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 cbf857e319 [CALCITE-5861] ReduceExpressionsRule rules should
constant-fold expressions in window bounds
cbf857e319 is described below
commit cbf857e319a695fe96b1f3f5f38a779821c92cb3
Author: Mihai Budiu <[email protected]>
AuthorDate: Tue Aug 1 14:48:08 2023 -0700
[CALCITE-5861] ReduceExpressionsRule rules should constant-fold expressions
in window bounds
Signed-off-by: Mihai Budiu <[email protected]>
---
.../calcite/rel/rules/ProjectToWindowRule.java | 2 +-
.../calcite/rel/rules/ReduceExpressionsRule.java | 20 +++++++++++++++++++-
.../org/apache/calcite/test/RelOptRulesTest.java | 20 ++++++++++++++++++++
.../org/apache/calcite/test/RelOptRulesTest.xml | 16 ++++++++++++++++
4 files changed, 56 insertions(+), 2 deletions(-)
diff --git
a/core/src/main/java/org/apache/calcite/rel/rules/ProjectToWindowRule.java
b/core/src/main/java/org/apache/calcite/rel/rules/ProjectToWindowRule.java
index c70ab6b03c..f97584b364 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ProjectToWindowRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ProjectToWindowRule.java
@@ -283,7 +283,7 @@ public abstract class ProjectToWindowRule
if (expr instanceof RexOver) {
final RexOver over = (RexOver) expr;
- // If we can found an existing cohort which satisfies the two
conditions,
+ // If we can find an existing cohort which satisfies the two
conditions,
// we will add this RexOver into that cohort
boolean isFound = false;
for (Pair<RexWindow, Set<Integer>> pair : windowToIndices) {
diff --git
a/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
b/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
index 44f978e5a3..9b19c97dc1 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
@@ -57,6 +57,8 @@ import org.apache.calcite.rex.RexSubQuery;
import org.apache.calcite.rex.RexUnknownAs;
import org.apache.calcite.rex.RexUtil;
import org.apache.calcite.rex.RexVisitorImpl;
+import org.apache.calcite.rex.RexWindow;
+import org.apache.calcite.rex.RexWindowBound;
import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlOperator;
@@ -666,7 +668,7 @@ public abstract class ReduceExpressionsRule<C extends
ReduceExpressionsRule.Conf
/**
* Reduces a list of expressions.
*
- * <p>The {@code matchNullability} flag comes into play when reducing a
+ * <p>The {@code matchNullability} flag comes into play when reducing an
* expression whose type is nullable. Suppose we are reducing an expression
* {@code CASE WHEN 'a' = 'a' THEN 1 ELSE NULL END}. Before reduction the
* type is {@code INTEGER} (nullable), but after reduction the literal 1 has
@@ -1072,9 +1074,25 @@ public abstract class ReduceExpressionsRule<C extends
ReduceExpressionsRule.Conf
return null;
}
+ void processWindowBound(RexWindowBound bound) {
+ RexNode offset = bound.getOffset();
+ if (offset == null) {
+ return;
+ }
+ bound.accept(this);
+ Constancy constancy = Util.last(stack);
+ if (constancy == Constancy.REDUCIBLE_CONSTANT) {
+ addResult(offset);
+ }
+ Util.last(stack, 1).clear();
+ }
+
@Override public Void visitOver(RexOver over) {
// assume non-constant (running SUM(1) looks constant but isn't)
analyzeCall(over, Constancy.NON_CONSTANT);
+ final RexWindow window = over.getWindow();
+ this.processWindowBound(window.getLowerBound());
+ this.processWindowBound(window.getUpperBound());
return null;
}
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
index c296ab7ca2..0bb72d07f4 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -4970,6 +4970,26 @@ class RelOptRulesTest extends RelOptTestBase {
.check();
}
+ /**
+ * Test case for <a
href="https://issues.apache.org/jira/browse/CALCITE-5861">
+ * [CALCITE-5861] ReduceExpressionsRule rules should constant-fold
+ * expressions in window bounds</a>.
+ */
+ @Test void testExpressionPreceding() {
+ HepProgramBuilder preBuilder = new HepProgramBuilder();
+ preBuilder.addRuleInstance(CoreRules.PROJECT_REDUCE_EXPRESSIONS);
+
preBuilder.addRuleInstance(CoreRules.PROJECT_TO_LOGICAL_PROJECT_AND_WINDOW);
+
+ final String sql =
+ "select COUNT(*) over (\n"
+ + "ORDER BY empno\n"
+ + "ROWS BETWEEN 5 + 5 PRECEDING AND 1 PRECEDING) AS w_count from
emp\n";
+ sql(sql)
+ .withPre(preBuilder.build())
+ .withRule(CoreRules.PROJECT_REDUCE_EXPRESSIONS)
+ .checkUnchanged();
+ }
+
/** Test case for
* <a href="https://issues.apache.org/jira/browse/CALCITE-750">[CALCITE-750]
* Allow windowed aggregate on top of regular aggregate</a>. */
diff --git
a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
index bdef8ae751..f2ae0acdbe 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -4203,6 +4203,22 @@ LogicalProject($0=[$3], $1=[$4])
<![CDATA[
LogicalProject(SUM1=[SUM($7) OVER (PARTITION BY $7 ORDER BY $5)],
SUM2=[SUM(+($7, $5)) OVER (PARTITION BY $7 ORDER BY $5)])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ </TestCase>
+ <TestCase name="testExpressionPreceding">
+ <Resource name="sql">
+ <![CDATA[select COUNT(*) over (
+ORDER BY empno
+ROWS BETWEEN 5 + 5 PRECEDING AND 1 PRECEDING) AS w_count from emp
+]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalProject($0=[$1])
+ LogicalWindow(window#0=[window(order by [0] rows between $1 PRECEDING and $2
PRECEDING aggs [COUNT()])])
+ LogicalProject(EMPNO=[$0])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
</TestCase>