PHOENIX-4967 Reverse scan along LOCAL index does not always return all data.


Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/9c27fcc6
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/9c27fcc6
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/9c27fcc6

Branch: refs/heads/4.14-cdh5.11
Commit: 9c27fcc66227bef7e40195842eed338ebcf88f0c
Parents: 70b85a6
Author: Lars Hofhansl <la...@apache.org>
Authored: Sat Oct 13 22:34:44 2018 +0100
Committer: Pedro Boado <pbo...@apache.org>
Committed: Fri Oct 26 23:05:21 2018 +0100

----------------------------------------------------------------------
 .../phoenix/end2end/index/LocalIndexIT.java     | 55 +++++++++++++++++++-
 .../phoenix/iterate/BaseResultIterators.java    |  3 +-
 2 files changed, 56 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/9c27fcc6/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
index 42cdab3..cc3a2a5 100644
--- 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
+++ 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
@@ -298,11 +298,15 @@ public class LocalIndexIT extends BaseLocalIndexIT {
 
             rs = conn1.createStatement().executeQuery(query);
             String v = "";
+            int i = 0;
             while(rs.next()) {
                 String next = rs.getString("v1");
                 assertTrue(v.compareTo(next) <= 0);
                 v = next;
+                i++;
             }
+            // see PHOENIX-4967
+            assertEquals(4, i);
             rs.close();
 
             query = "SELECT * FROM " + tableName +" ORDER BY V1 DESC NULLS 
LAST";
@@ -316,16 +320,65 @@ public class LocalIndexIT extends BaseLocalIndexIT {
 
             rs = conn1.createStatement().executeQuery(query);
             v = "zz";
+            i = 0;
             while(rs.next()) {
                 String next = rs.getString("v1");
                 assertTrue(v.compareTo(next) >= 0);
                 v = next;
+                i++;
             }
+            // see PHOENIX-4967
+            assertEquals(4, i);
             rs.close();
 
         }
     }
-    
+
+    @Test
+    public void testLocalIndexReverseScanShouldReturnAllRows() throws 
Exception {
+        String tableName = schemaName + "." + generateUniqueName();
+        String indexName = "IDX_" + generateUniqueName();
+        TableName physicalTableName = 
SchemaUtil.getPhysicalTableName(tableName.getBytes(), isNamespaceMapped);
+        String indexPhysicalTableName = physicalTableName.getNameAsString();
+
+        createBaseTable(tableName, null, "('e','i','o')");
+        try (Connection conn1 = getConnection()) {
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " 
values('b',1,2,4,'z')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " 
values('f',1,2,3,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " 
values('j',2,4,2,'b')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " 
values('q',3,1,1,'c')");
+            conn1.commit();
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName 
+ " ON " + tableName + "(v1)");
+
+            String query = "SELECT V1 FROM " + tableName +" ORDER BY V1 DESC 
NULLS LAST";
+            ResultSet rs = conn1.createStatement().executeQuery("EXPLAIN "+ 
query);
+
+            HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), 
TestUtil.TEST_PROPERTIES).getAdmin();
+            int numRegions = admin.getTableRegions(physicalTableName).size();
+
+            assertEquals(
+                "CLIENT PARALLEL " + numRegions + "-WAY REVERSE RANGE SCAN 
OVER "
+                        + indexPhysicalTableName + " [1]\n"
+                                + "    SERVER FILTER BY FIRST KEY ONLY\n"
+                                + "CLIENT MERGE SORT",
+                        QueryUtil.getExplainPlan(rs));
+
+            rs = conn1.createStatement().executeQuery(query);
+            String v = "zz";
+            int i = 0;
+            while(rs.next()) {
+                String next = rs.getString("v1");
+                assertTrue(v.compareTo(next) >= 0);
+                v = next;
+                i++;
+            }
+            // see PHOENIX-4967
+            assertEquals(4, i);
+            rs.close();
+
+        }
+    }
+
     @Test
     public void testLocalIndexScanJoinColumnsFromDataTable() throws Exception {
         String tableName = schemaName + "." + generateUniqueName();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/9c27fcc6/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
----------------------------------------------------------------------
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 d890383..6bc9a15 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
@@ -1278,10 +1278,11 @@ public abstract class BaseResultIterators extends 
ExplainTable implements Result
                         if (timeOutForScan < 0) {
                             throw new 
SQLExceptionInfo.Builder(SQLExceptionCode.OPERATION_TIMED_OUT).setMessage(". 
Query couldn't be completed in the alloted time: " + queryTimeOut + " 
ms").build().buildException(); 
                         }
+                        // make sure we apply the iterators in order
                         if (isLocalIndex && previousScan != null && 
previousScan.getScan() != null
                                 && (((!isReverse && 
Bytes.compareTo(scanPair.getFirst().getAttribute(SCAN_ACTUAL_START_ROW),
                                         previousScan.getScan().getStopRow()) < 
0)
-                                || (isReverse && 
Bytes.compareTo(scanPair.getFirst().getAttribute(SCAN_ACTUAL_START_ROW),
+                                || (isReverse && 
previousScan.getScan().getStopRow().length > 0 && 
Bytes.compareTo(scanPair.getFirst().getAttribute(SCAN_ACTUAL_START_ROW),
                                         previousScan.getScan().getStopRow()) > 
0)
                                 || 
(Bytes.compareTo(scanPair.getFirst().getStopRow(), 
previousScan.getScan().getStopRow()) == 0)) 
                                     && 
Bytes.compareTo(scanPair.getFirst().getAttribute(SCAN_START_ROW_SUFFIX), 
previousScan.getScan().getAttribute(SCAN_START_ROW_SUFFIX))==0)) {

Reply via email to