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());

Reply via email to