This is an automated email from the ASF dual-hosted git repository.

alexpl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new e8e6919ee28 IGNITE-17890 SQL Calcite: Support index scan on boolean 
fields - Fixes #10332.
e8e6919ee28 is described below

commit e8e6919ee2833bcdf51588e06134ee90d16fbc7d
Author: Aleksey Plekhanov <[email protected]>
AuthorDate: Thu Oct 20 11:32:15 2022 +0300

    IGNITE-17890 SQL Calcite: Support index scan on boolean fields - Fixes 
#10332.
    
    Signed-off-by: Aleksey Plekhanov <[email protected]>
---
 .../processors/query/calcite/util/RexUtils.java    | 16 +++++++
 .../integration/IndexScanlIntegrationTest.java     | 53 ++++++++++++++++++++++
 2 files changed, 69 insertions(+)

diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/RexUtils.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/RexUtils.java
index d32b89e254f..396be25e579 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/RexUtils.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/RexUtils.java
@@ -82,6 +82,7 @@ import static org.apache.calcite.sql.SqlKind.IS_NOT_NULL;
 import static org.apache.calcite.sql.SqlKind.IS_NULL;
 import static org.apache.calcite.sql.SqlKind.LESS_THAN;
 import static org.apache.calcite.sql.SqlKind.LESS_THAN_OR_EQUAL;
+import static org.apache.calcite.sql.SqlKind.NOT;
 import static org.apache.calcite.sql.SqlKind.SEARCH;
 
 /** */
@@ -562,6 +563,8 @@ public class RexUtils {
         Map<Integer, List<RexCall>> res = new HashMap<>(conjunctions.size());
 
         for (RexNode rexNode : conjunctions) {
+            rexNode = expandBooleanFieldComparison(rexNode, builder(cluster));
+
             if (!isSupportedTreeComparison(rexNode))
                 continue;
 
@@ -592,6 +595,19 @@ public class RexUtils {
         return res;
     }
 
+    /** */
+    private static RexNode expandBooleanFieldComparison(RexNode rexNode, 
RexBuilder builder) {
+        if (rexNode instanceof RexSlot)
+            return builder.makeCall(SqlStdOperatorTable.EQUALS, rexNode, 
builder.makeLiteral(true));
+        else if (rexNode instanceof RexCall && rexNode.getKind() == NOT &&
+            ((RexCall)rexNode).getOperands().get(0) instanceof RexSlot) {
+            return builder.makeCall(SqlStdOperatorTable.EQUALS, 
((RexCall)rexNode).getOperands().get(0),
+                builder.makeLiteral(false));
+        }
+
+        return rexNode;
+    }
+
     /** */
     private static RexNode extractRefFromBinary(RexCall call, RelOptCluster 
cluster) {
         assert isBinaryComparison(call);
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/IndexScanlIntegrationTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/IndexScanlIntegrationTest.java
index 53457074fd5..799a0fc6663 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/IndexScanlIntegrationTest.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/IndexScanlIntegrationTest.java
@@ -129,4 +129,57 @@ public class IndexScanlIntegrationTest extends 
AbstractBasicIntegrationTest {
             .returns("emp60")
             .check();
     }
+
+    /** */
+    @Test
+    public void testScanBooleanField() {
+        executeSql("CREATE TABLE t(i INTEGER, b BOOLEAN)");
+        executeSql("INSERT INTO t VALUES (0, TRUE), (1, TRUE), (2, FALSE), (3, 
FALSE), (4, null)");
+        executeSql("CREATE INDEX t_idx ON t(b)");
+
+        assertQuery("SELECT i FROM t WHERE b = TRUE")
+            .matches(QueryChecker.containsIndexScan("PUBLIC", "T", "T_IDX"))
+            .returns(0)
+            .returns(1)
+            .check();
+
+        assertQuery("SELECT i FROM t WHERE b = FALSE")
+            .matches(QueryChecker.containsIndexScan("PUBLIC", "T", "T_IDX"))
+            .returns(2)
+            .returns(3)
+            .check();
+
+        assertQuery("SELECT i FROM t WHERE b IS TRUE")
+            .matches(QueryChecker.containsIndexScan("PUBLIC", "T", "T_IDX"))
+            .returns(0)
+            .returns(1)
+            .check();
+
+        assertQuery("SELECT i FROM t WHERE b IS FALSE")
+            .matches(QueryChecker.containsIndexScan("PUBLIC", "T", "T_IDX"))
+            .returns(2)
+            .returns(3)
+            .check();
+
+        // Support index scans for IS TRUE, IS FALSE but not for IS NOT TRUE, 
IS NOT FALSE, since it requeres multi
+        // bounds scan and may not be effective.
+        assertQuery("SELECT i FROM t WHERE b IS NOT TRUE")
+            .matches(QueryChecker.containsTableScan("PUBLIC", "T"))
+            .returns(2)
+            .returns(3)
+            .returns(4)
+            .check();
+
+        assertQuery("SELECT i FROM t WHERE b IS NOT FALSE")
+            .matches(QueryChecker.containsTableScan("PUBLIC", "T"))
+            .returns(0)
+            .returns(1)
+            .returns(4)
+            .check();
+
+        assertQuery("SELECT i FROM t WHERE b IS NULL")
+            .matches(QueryChecker.containsIndexScan("PUBLIC", "T", "T_IDX"))
+            .returns(4)
+            .check();
+    }
 }

Reply via email to