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

larsh pushed a commit to branch 4.x-HBase-1.5
in repository https://gitbox.apache.org/repos/asf/phoenix.git


The following commit(s) were added to refs/heads/4.x-HBase-1.5 by this push:
     new 1620c7d  PHOENIX-5096 Local index region pruning is not working as 
expected.
1620c7d is described below

commit 1620c7d7f6b8ce8ccf38e27e6bff1182ec6f7985
Author: Lars Hofhansl <la...@apache.org>
AuthorDate: Tue Dec 24 06:26:39 2019 -0800

    PHOENIX-5096 Local index region pruning is not working as expected.
---
 .../phoenix/iterate/BaseResultIterators.java       |  9 ++++
 .../apache/phoenix/compile/QueryCompilerTest.java  | 60 ++++++++++++++++++++++
 2 files changed, 69 insertions(+)

diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
index 45b4d4d..2dcc88b 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
@@ -1023,6 +1023,15 @@ public abstract class BaseResultIterators extends 
ExplainTable implements Result
                     endKey = regionBoundaries.get(regionIndex);
                 }
                 if (isLocalIndex) {
+                    if (dataPlan != null && 
dataPlan.getTableRef().getTable().getType() != PTableType.INDEX) { // Sanity 
check
+                        ScanRanges dataScanRanges = 
dataPlan.getContext().getScanRanges();
+                        // we can skip a region completely for local indexes 
if the data plan does not intersect
+                        if 
(!dataScanRanges.intersectRegion(regionInfo.getStartKey(), 
regionInfo.getEndKey(), false)) {
+                            currentKeyBytes = endKey;
+                            regionIndex++;
+                            continue;
+                        }
+                    }
                     // Only attempt further pruning if the prefix range is 
using
                     // a skip scan since we've already pruned the range of 
regions
                     // based on the start/stop key.
diff --git 
a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java 
b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
index e6337fa..b49aaf8 100644
--- 
a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
+++ 
b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
@@ -4870,6 +4870,66 @@ public class QueryCompilerTest extends 
BaseConnectionlessQueryTest {
     }
 
     @Test
+    public void testLocalIndexRegionPruning() throws SQLException {
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
+            conn.createStatement().execute("CREATE TABLE T (\n" + 
+                    "    A CHAR(1) NOT NULL,\n" + 
+                    "    B CHAR(1) NOT NULL,\n" + 
+                    "    C CHAR(1) NOT NULL,\n" + 
+                    "    D CHAR(1),\n" + 
+                    "    CONSTRAINT PK PRIMARY KEY (\n" + 
+                    "        A,\n" + 
+                    "        B,\n" + 
+                    "        C\n" + 
+                    "    )\n" + 
+                    ") SPLIT ON ('A','C','E','G','I')");
+
+            conn.createStatement().execute("CREATE LOCAL INDEX IDX ON T(D)");
+
+            // un-pruned, need to scan all six regions
+            String query = "SELECT * FROM T WHERE D = 'C'";
+            PhoenixStatement statement = 
conn.createStatement().unwrap(PhoenixStatement.class);
+            QueryPlan plan = statement.optimizeQuery(query);
+            assertEquals("IDX", 
plan.getContext().getCurrentTable().getTable().getName().getString());
+            plan.iterator();
+            assertEquals(6, plan.getScans().size());
+
+            // fixing first part of the key, can limit scanning to two regions
+            query = "SELECT * FROM T WHERE A = 'A' AND D = 'C'";
+            statement = conn.createStatement().unwrap(PhoenixStatement.class);
+            plan = statement.optimizeQuery(query);
+            assertEquals("IDX", 
plan.getContext().getCurrentTable().getTable().getName().getString());
+            plan.iterator();
+            assertEquals(2, plan.getScans().size());
+
+            // same with skipscan filter
+            query = "SELECT * FROM T WHERE A IN ('A', 'C') AND D = 'C'";
+            statement = conn.createStatement().unwrap(PhoenixStatement.class);
+            plan = statement.optimizeQuery(query);
+            assertEquals("IDX", 
plan.getContext().getCurrentTable().getTable().getName().getString());
+            plan.iterator();
+            assertEquals(3, plan.getScans().size());
+
+            // two parts of key fixed, need to scan a single region only
+            query = "SELECT * FROM T WHERE A = 'A' AND B = 'A' AND D = 'C'";
+            statement = conn.createStatement().unwrap(PhoenixStatement.class);
+            plan = statement.optimizeQuery(query);
+            assertEquals("IDX", 
plan.getContext().getCurrentTable().getTable().getName().getString());
+            plan.iterator();
+            assertEquals(1, plan.getScans().size());
+
+            // same with skipscan filter
+            query = "SELECT * FROM T WHERE A IN ('A', 'C') AND B = 'A' AND D = 
'C'";
+            statement = conn.createStatement().unwrap(PhoenixStatement.class);
+            plan = statement.optimizeQuery(query);
+            assertEquals("IDX", 
plan.getContext().getCurrentTable().getTable().getName().getString());
+            plan.iterator();
+            assertEquals(2, plan.getScans().size());
+        }
+    }
+
+    @Test
     public void testSmallScanForPointLookups() throws SQLException {
         Properties props = PropertiesUtil.deepCopy(new Properties());
         createTestTable(getUrl(), "CREATE TABLE FOO(\n" +

Reply via email to