PHOENIX-1753 Query with RVC that doesn't lead with the row key can return incorrect results
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/e06ceaf4 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/e06ceaf4 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/e06ceaf4 Branch: refs/heads/4.x-HBase-1.x Commit: e06ceaf455642d92b500d0e4edc343a3342a0d93 Parents: 4bc162d Author: James Taylor <jtay...@salesforce.com> Authored: Thu Mar 19 18:54:57 2015 -0700 Committer: James Taylor <jtay...@salesforce.com> Committed: Sat Mar 21 11:13:24 2015 -0700 ---------------------------------------------------------------------- .../phoenix/end2end/RowValueConstructorIT.java | 33 +++++++++++++++++++- .../apache/phoenix/compile/WhereOptimizer.java | 4 +++ .../phoenix/compile/WhereOptimizerTest.java | 16 ++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/e06ceaf4/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorIT.java index 8d67fa4..3859785 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorIT.java @@ -1362,6 +1362,37 @@ public class RowValueConstructorIT extends BaseClientManagedTimeIT { conn.close(); } - + @Test + public void testRVCWithRowKeyNotLeading() throws Exception { + String ddl = "CREATE TABLE sorttest4 (rownum BIGINT primary key, name varchar(16), age integer)"; + Connection conn = nextConnection(getUrl()); + conn.createStatement().execute(ddl); + conn.close(); + conn = nextConnection(getUrl()); + String dml = "UPSERT INTO sorttest4 (rownum, name, age) values (?, ?, ?)"; + PreparedStatement stmt = conn.prepareStatement(dml); + stmt.setInt(1, 1); + stmt.setString(2, "A"); + stmt.setInt(3, 1); + stmt.executeUpdate(); + stmt.setInt(1, 2); + stmt.setString(2, "B"); + stmt.setInt(3, 2); + stmt.executeUpdate(); + conn.commit(); + conn.close(); + // the below query should only return one record -> (1, "A", 1) + String query = "SELECT rownum, name, age FROM sorttest4 where (age, rownum) < (2, 2)"; + conn = nextConnection(getUrl()); + ResultSet rs = conn.createStatement().executeQuery(query); + int numRecords = 0; + while (rs.next()) { + assertEquals(1, rs.getInt(1)); + assertEquals("A", rs.getString(2)); + assertEquals(1, rs.getInt(3)); + numRecords++; + } + assertEquals(1, numRecords); + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/e06ceaf4/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java index 713076e..b03793d 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java @@ -542,6 +542,10 @@ public class WhereOptimizer { int span = position - initialPosition; return new SingleKeySlot(new RowValueConstructorKeyPart(table.getPKColumns().get(initialPosition), rvc, span, childSlots), initialPosition, span, EVERYTHING_RANGES); } + // If we don't clear the child list, we end up passing some of + // the child expressions of previous matches up the tree, causing + // those expressions to form the scan start/stop key. PHOENIX-1753 + childSlots.clear(); return null; } http://git-wip-us.apache.org/repos/asf/phoenix/blob/e06ceaf4/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereOptimizerTest.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereOptimizerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereOptimizerTest.java index 0ec6b45..94b25d0 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereOptimizerTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereOptimizerTest.java @@ -1275,6 +1275,22 @@ public class WhereOptimizerTest extends BaseConnectionlessQueryTest { } @Test + public void testRVCExpressionWithNonFirstLeadingColOfRowKey() throws SQLException { + String old_value = "value"; + String orgId = getOrganizationId(); + + String query = "select * from entity_history where (old_value, organization_id) >= (?,?)"; + List<Object> binds = Arrays.<Object>asList(old_value, orgId); + StatementContext context = compileStatement(query, binds); + Scan scan = context.getScan(); + Filter filter = scan.getFilter(); + assertNotNull(filter); + assertTrue(filter instanceof SingleKeyValueComparisonFilter); + assertArrayEquals(HConstants.EMPTY_START_ROW, scan.getStartRow()); + assertArrayEquals(HConstants.EMPTY_END_ROW, scan.getStopRow()); + } + + @Test public void testMultiRVCExpressionsCombinedWithAnd() throws SQLException { String lowerTenantId = "000000000000001"; String lowerParentId = "000000000000002";