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/1c380865 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/1c380865 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/1c380865 Branch: refs/heads/4.x-cdh5.15 Commit: 1c3808654abbeb3e2f6042064a38439b6d20589c Parents: a694638 Author: Lars Hofhansl <la...@apache.org> Authored: Sat Oct 13 22:45:19 2018 +0100 Committer: Pedro Boado <pbo...@apache.org> Committed: Wed Oct 17 22:50:43 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/1c380865/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 5a59c81..d70a505 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/1c380865/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 2378175..c477afe 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)) {