Repository: phoenix Updated Branches: refs/heads/4.x-HBase-1.2 a97599cea -> 4f7013c73
PHOENIX-3968 Region boundary with key smaller than fixed width size causes skip scan filter to fail Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/4f7013c7 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/4f7013c7 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/4f7013c7 Branch: refs/heads/4.x-HBase-1.2 Commit: 4f7013c73320a0794501e42ea9d5ec797df24d78 Parents: a97599c Author: Samarth Jain <sama...@apache.org> Authored: Wed Jun 21 17:15:13 2017 -0700 Committer: Samarth Jain <sama...@apache.org> Committed: Wed Jun 21 17:15:13 2017 -0700 ---------------------------------------------------------------------- .../apache/phoenix/end2end/SkipScanQueryIT.java | 88 ++++++++++++++++++++ .../org/apache/phoenix/schema/RowKeySchema.java | 4 +- 2 files changed, 91 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f7013c7/phoenix-core/src/it/java/org/apache/phoenix/end2end/SkipScanQueryIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SkipScanQueryIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SkipScanQueryIT.java index c2de3b7..d98bbe2 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SkipScanQueryIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SkipScanQueryIT.java @@ -34,10 +34,12 @@ import java.util.Collections; import java.util.List; import java.util.Properties; +import org.apache.hadoop.hbase.client.HBaseAdmin; import org.apache.hadoop.hbase.util.Bytes; import org.apache.phoenix.util.TestUtil; import org.apache.phoenix.util.SchemaUtil; import org.apache.phoenix.util.PropertiesUtil; +import org.apache.phoenix.jdbc.PhoenixConnection; import org.apache.phoenix.util.PhoenixRuntime; import org.junit.Test; @@ -475,4 +477,90 @@ public class SkipScanQueryIT extends ParallelStatsDisabledIT { assertFalse(rs.next()); } } + + @Test + public void testSkipScanQueryWhenSplitKeyIsSmaller() throws Exception { + try (Connection conn = DriverManager.getConnection(getUrl())) { + String tableName = generateUniqueName(); + StringBuffer buf = + new StringBuffer("CREATE TABLE IF NOT EXISTS " + tableName + + "(ORGANIZATION_ID CHAR(15) NOT NULL," + + "FEED_ITEM_ID CHAR(15) NOT NULL," + "EXTENSION VARCHAR(128) NOT NULL," + + "CREATED_TIME TIMESTAMP," + "LAST_UPDATE TIMESTAMP," + + "LAST_ACCESSED TIMESTAMP," + "VERSION INTEGER," + + "DATA.PAYLOAD VARCHAR(512000)" + "CONSTRAINT PK PRIMARY KEY" + "(" + + " ORGANIZATION_ID," + " FEED_ITEM_ID," + + " EXTENSION" + ")" + ")"); + conn.createStatement().execute(buf.toString()); + String upsert = + "UPSERT INTO " + tableName + + " (ORGANIZATION_ID, FEED_ITEM_ID, EXTENSION) VALUES (?, ?, ?)"; + PreparedStatement stmt = conn.prepareStatement(upsert); + stmt.setString(1, "00Do0000000a8w1"); + stmt.setString(2, "0D5o000002MK5Uu"); + stmt.setString(3, "FI"); + stmt.executeUpdate(); + stmt.setString(1, "00Do0000000a8w1"); + stmt.setString(2, "0D5o000002MK5Uu"); + stmt.setString(3, "T0"); + stmt.executeUpdate(); + stmt.setString(1, "00Do0000000a8w1"); + stmt.setString(2, "0D5o000002QWbP0"); + stmt.setString(3, "FI"); + stmt.executeUpdate(); + stmt.setString(1, "00Do0000000a8w1"); + stmt.setString(2, "0D5o000002QWbP0"); + stmt.setString(3, "T0"); + stmt.executeUpdate(); + stmt.setString(1, "00Do0000000a8w1"); + stmt.setString(2, "0D5o000002QXXL2"); + stmt.setString(3, "FI"); + stmt.executeUpdate(); + stmt.setString(1, "00Do0000000a8w1"); + stmt.setString(2, "0D5o000002QXXL2"); + stmt.setString(3, "T0"); + stmt.executeUpdate(); + stmt.setString(1, "00Do0000000a8w1"); + stmt.setString(2, "0D5o000002RhvtQ"); + stmt.setString(3, "FI"); + stmt.executeUpdate(); + stmt.setString(1, "00Do0000000a8w1"); + stmt.setString(2, "0D5o000002RhvtQ"); + stmt.setString(3, "T0"); + stmt.executeUpdate(); + conn.commit(); + try (HBaseAdmin admin = + conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) { + /* + * The split key is 27 bytes instead of at least 30 bytes (CHAR(15) + CHAR(15)). + * Note that we cannot use the phoenix way of giving split points in the ddl because + * it ends up padding the split point bytes to 30. + */ + byte[] smallSplitKey = Bytes.toBytes("00Do0000000a8w10D5o000002Rhv"); + admin.split(Bytes.toBytes(tableName), smallSplitKey); + } + ResultSet rs = + conn.createStatement().executeQuery("SELECT EXTENSION FROM " + tableName + + " WHERE " + "ORGANIZATION_ID = '00Do0000000a8w1' AND " + + "FEED_ITEM_ID IN " + + "('0D5o000002MK5Uu','0D5o000002QWbP0','0D5o000002QXXL2','0D5o000002RhvtQ') ORDER BY ORGANIZATION_ID, FEED_ITEM_ID, EXTENSION"); + assertTrue(rs.next()); + assertEquals("FI", rs.getString(1)); + assertTrue(rs.next()); + assertEquals("T0", rs.getString(1)); + assertTrue(rs.next()); + assertEquals("FI", rs.getString(1)); + assertTrue(rs.next()); + assertEquals("T0", rs.getString(1)); + assertTrue(rs.next()); + assertEquals("FI", rs.getString(1)); + assertTrue(rs.next()); + assertEquals("T0", rs.getString(1)); + assertTrue(rs.next()); + assertEquals("FI", rs.getString(1)); + assertTrue(rs.next()); + assertEquals("T0", rs.getString(1)); + assertFalse(rs.next()); + } + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f7013c7/phoenix-core/src/main/java/org/apache/phoenix/schema/RowKeySchema.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/RowKeySchema.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/RowKeySchema.java index 3fa3a36..72ebddd 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/schema/RowKeySchema.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/RowKeySchema.java @@ -162,7 +162,9 @@ public class RowKeySchema extends ValueSchema { } Field field = this.getField(position); if (field.getDataType().isFixedWidth()) { - ptr.set(ptr.get(),ptr.getOffset(), field.getByteSize()); + // It is possible that the number of remaining row key bytes are less than the fixed + // width size. See PHOENIX-3968. + ptr.set(ptr.get(), ptr.getOffset(), Math.min(maxOffset - ptr.getOffset(), field.getByteSize())); } else { if (position+1 == getFieldCount() ) { // Last field has no terminator unless it's descending sort order