This is an automated email from the ASF dual-hosted git repository. jhyde pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/calcite.git
commit 2acf3426e5a9df85192d0dfb047a7c0cd7c335dd Author: Julian Hyde <jh...@apache.org> AuthorDate: Mon Sep 21 15:05:06 2020 -0700 [CALCITE-4271] RelBuilder.in should allow duplicate values --- .../java/org/apache/calcite/rex/RexBuilder.java | 9 ++++-- .../org/apache/calcite/test/RelBuilderTest.java | 36 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java index 7479ad2..09f7e55 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java +++ b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java @@ -56,6 +56,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableRangeSet; import com.google.common.collect.Lists; import com.google.common.collect.Range; +import com.google.common.collect.RangeSet; +import com.google.common.collect.TreeRangeSet; import java.math.BigDecimal; import java.math.MathContext; @@ -1358,6 +1360,7 @@ public class RexBuilder { /** Converts a list of expressions to a search argument, or returns null if * not possible. */ + @SuppressWarnings("UnstableApiUsage") private static <C extends Comparable<C>> Sarg<C> toSarg(Class<C> clazz, List<? extends RexNode> ranges, boolean containsNull) { if (ranges.isEmpty()) { @@ -1365,15 +1368,15 @@ public class RexBuilder { // because we use the type of the first element. return null; } - final ImmutableRangeSet.Builder<C> b = ImmutableRangeSet.builder(); + final RangeSet<C> rangeSet = TreeRangeSet.create(); for (RexNode range : ranges) { final C value = toComparable(clazz, range); if (value == null) { return null; } - b.add(Range.singleton(value)); + rangeSet.add(Range.singleton(value)); } - return Sarg.of(containsNull, b.build()); + return Sarg.of(containsNull, rangeSet); } private static <C extends Comparable<C>> C toComparable(Class<C> clazz, diff --git a/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java b/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java index 103b6df..53bd8af 100644 --- a/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java +++ b/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java @@ -3221,6 +3221,42 @@ public class RelBuilderTest { assertThat(root, hasTree(expected)); } + /** Tests {@link RelBuilder#in} with duplicate values. */ + @Test void testFilterIn() { + final Function<RelBuilder, RelNode> f = b -> + b.scan("EMP") + .filter( + b.in(b.field("DEPTNO"), b.literal(10), b.literal(20), + b.literal(10))) + .build(); + final String expected = "" + + "LogicalFilter(condition=[SEARCH($7, Sarg[10, 20])])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(f.apply(createBuilder()), hasTree(expected)); + assertThat(f.apply(createBuilder(c -> c.withSimplify(false))), + hasTree(expected)); + } + + @Test void testFilterOrIn() { + final Function<RelBuilder, RelNode> f = b -> + b.scan("EMP") + .filter( + b.or( + b.call(SqlStdOperatorTable.GREATER_THAN, b.field("DEPTNO"), + b.literal(15)), + b.in(b.field("JOB"), b.literal("CLERK")), + b.in(b.field("DEPTNO"), b.literal(10), b.literal(20), + b.literal(11), b.literal(10)))) + .build(); + final String expected = "" + + "LogicalFilter(condition=[OR(SEARCH($7, Sarg[10, 11, (15‥+∞)]), " + + "SEARCH($2, Sarg['CLERK']:CHAR(5)))])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(f.apply(createBuilder()), hasTree(expected)); + assertThat(f.apply(createBuilder(c -> c.withSimplify(false))), + hasTree(expected)); + } + /** Tests filter builder with correlation variables. */ @Test void testFilterWithCorrelationVariables() { final RelBuilder builder = RelBuilder.create(config().build());