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 3a38ebf40f [CALCITE-5286] Join with parameterized LIMIT throws AssertionError "not a literal" 3a38ebf40f is described below commit 3a38ebf40f6dfc1170ba3d3acc5d8e1f234ed45c Author: xiejiajun <jiajunbernou...@foxmail.com> AuthorDate: Mon Sep 19 11:12:41 2022 +0800 [CALCITE-5286] Join with parameterized LIMIT throws AssertionError "not a literal" --- .../calcite/rel/metadata/RelMdMaxRowCount.java | 2 +- .../calcite/rel/metadata/RelMdMinRowCount.java | 2 +- .../org/apache/calcite/test/RelMetadataTest.java | 37 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java index c8cec39f98..3fe8f4311a 100644 --- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java +++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java @@ -208,7 +208,7 @@ public class RelMdMaxRowCount for (RelNode node : rel.getRels()) { if (node instanceof Sort) { Sort sort = (Sort) node; - if (sort.fetch != null) { + if (sort.fetch instanceof RexLiteral) { return (double) RexLiteral.intValue(sort.fetch); } } diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMinRowCount.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMinRowCount.java index 1d392aad13..9fff399917 100644 --- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMinRowCount.java +++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMinRowCount.java @@ -168,7 +168,7 @@ public class RelMdMinRowCount for (RelNode node : rel.getRels()) { if (node instanceof Sort) { Sort sort = (Sort) node; - if (sort.fetch != null) { + if (sort.fetch instanceof RexLiteral) { return (double) RexLiteral.intValue(sort.fetch); } } diff --git a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java index ee73bcab6b..307c3a9ba9 100644 --- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java +++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java @@ -16,9 +16,12 @@ */ package org.apache.calcite.test; +import org.apache.calcite.adapter.enumerable.EnumerableConvention; import org.apache.calcite.adapter.enumerable.EnumerableMergeJoin; +import org.apache.calcite.adapter.enumerable.EnumerableRules; import org.apache.calcite.config.CalciteSystemProperty; import org.apache.calcite.linq4j.tree.Types; +import org.apache.calcite.plan.ConventionTraitDef; import org.apache.calcite.plan.RelOptCluster; import org.apache.calcite.plan.RelOptPlanner; import org.apache.calcite.plan.RelOptPredicateList; @@ -27,6 +30,7 @@ import org.apache.calcite.plan.RelTraitSet; import org.apache.calcite.plan.hep.HepPlanner; import org.apache.calcite.plan.hep.HepProgram; import org.apache.calcite.plan.hep.HepProgramBuilder; +import org.apache.calcite.plan.volcano.VolcanoPlanner; import org.apache.calcite.rel.RelCollation; import org.apache.calcite.rel.RelCollationTraitDef; import org.apache.calcite.rel.RelCollations; @@ -644,6 +648,39 @@ public class RelMetadataTest { fixture.assertThatRowCount(is(9D), is(0D), is(10d)); } + /** Test case for + * <a href="https://issues.apache.org/jira/browse/CALCITE-5286">[CALCITE-5286] + * Join with parameterized LIMIT throws AssertionError "not a literal". </a>. */ + @Test void testRowCountJoinWithDynamicParameters() { + final String sql = "select r.ename, s.sal from\n" + + "(select * from emp limit ?) r join bonus s\n" + + "on r.ename=s.ename where r.sal+1=s.sal"; + sql(sql) + .withCluster(cluster -> { + RelOptPlanner planner = new VolcanoPlanner(); + planner.addRule(EnumerableRules.ENUMERABLE_TABLE_SCAN_RULE); + planner.addRule(EnumerableRules.ENUMERABLE_PROJECT_RULE); + planner.addRule(EnumerableRules.ENUMERABLE_FILTER_RULE); + planner.addRule(EnumerableRules.ENUMERABLE_JOIN_RULE); + planner.addRule(EnumerableRules.ENUMERABLE_LIMIT_SORT_RULE); + planner.addRelTraitDef(ConventionTraitDef.INSTANCE); + return RelOptCluster.create(planner, cluster.getRexBuilder()); + }) + .withRelTransform(rel -> { + RelOptPlanner planner = rel.getCluster().getPlanner(); + planner.setRoot(rel); + RelTraitSet requiredOutputTraits = + rel.getCluster().traitSet().replace(EnumerableConvention.INSTANCE); + final RelNode rootRel2 = planner.changeTraits(rel, requiredOutputTraits); + + planner.setRoot(rootRel2); + final RelOptPlanner planner2 = planner.chooseDelegate(); + final RelNode rootRel3 = planner2.findBestExp(); + return rootRel3; + }) + .assertThatRowCount(is(1.0), is(0D), is(Double.POSITIVE_INFINITY)); + } + @Test void testRowCountSortLimitOffsetDynamic() { sql("select * from emp order by ename limit ? offset ?") .assertThatRowCount(is(EMP_SIZE), is(0D), is(Double.POSITIVE_INFINITY));