Java Code Examples for org.apache.hadoop.hbase.client.Scan#getStartRow()

The following examples show how to use org.apache.hadoop.hbase.client.Scan#getStartRow() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: StoreFileReader.java    From hbase with Apache License 2.0 6 votes vote down vote up
/**
 * A method for checking Bloom filters. Called directly from
 * StoreFileScanner in case of a multi-column query.
 *
 * @return True if passes
 */
private boolean passesGeneralRowPrefixBloomFilter(Scan scan) {
  BloomFilter bloomFilter = this.generalBloomFilter;
  if (bloomFilter == null) {
    return true;
  }

  byte[] row = scan.getStartRow();
  byte[] rowPrefix;
  if (scan.isGetScan()) {
    rowPrefix = Bytes.copy(row, 0, Math.min(prefixLength, row.length));
  } else {
    // For non-get scans
    // Find out the common prefix of startRow and stopRow.
    int commonLength = Bytes.findCommonPrefix(scan.getStartRow(), scan.getStopRow(),
        scan.getStartRow().length, scan.getStopRow().length, 0, 0);
    // startRow and stopRow don't have the common prefix.
    // Or the common prefix length is less than prefixLength
    if (commonLength <= 0 || commonLength < prefixLength) {
      return true;
    }
    rowPrefix = Bytes.copy(row, 0, prefixLength);
  }
  return checkGeneralBloomFilter(rowPrefix, null, bloomFilter);
}
 
Example 2
Source File: SMRecordReaderImplIT.java    From spliceengine with GNU Affero General Public License v3.0 6 votes vote down vote up
@Test
public void singleRegionScanWithOneStoreFileAndMemstore() throws Exception {
  List<String> names = new ArrayList<String>();
  names.add("COL1");
  names.add("COL2");
  config.set(MRConstants.SPLICE_SCAN_INFO, sqlUtil.getTableScannerBuilder(SMRecordReaderImplIT.class.getSimpleName() + ".B", names).base64Encode());
  SMRecordReaderImpl rr = new SMRecordReaderImpl(config);
  TableName tableName = TableName.valueOf(sqlUtil.getConglomID(SMRecordReaderImplIT.class.getSimpleName() + ".B"));
  try (Connection connection = ConnectionFactory.createConnection(config)) {
    Table table = connection.getTable(tableName);
    Scan scan = new Scan();
    rr.setHTable(table);
    rr.setScan(scan);
    SMSplit tableSplit = new SMSplit(new TableSplit(tableName, scan.getStartRow(), scan.getStopRow(), "sdfsdf"));
    rr.initialize(tableSplit, null);
    int i = 0;
    while (rr.nextKeyValue()) {
      i++;
      Assert.assertNotNull("Column 1 is null", rr.getCurrentValue().getColumn(1));
      Assert.assertNotNull("Column 2 is null", rr.getCurrentValue().getColumn(2));
      Assert.assertNotNull("Current Key is null", rr.getCurrentKey());
    }
    Assert.assertEquals("incorrect results returned", 1000, i);
  }
}
 
Example 3
Source File: SMRecordReaderImplIT.java    From spliceengine with GNU Affero General Public License v3.0 6 votes vote down vote up
@Test
public void twoRegionsWithMemstores() throws Exception {
  List<String> names = new ArrayList<String>();
  names.add("COL1");
  names.add("COL2");
  config.set(MRConstants.SPLICE_SCAN_INFO, sqlUtil.getTableScannerBuilder(SMRecordReaderImplIT.class.getSimpleName() + ".C", names).base64Encode());
  SMRecordReaderImpl rr = new SMRecordReaderImpl(config);
  TableName tableName = TableName.valueOf(sqlUtil.getConglomID(SMRecordReaderImplIT.class.getSimpleName() + ".C"));
  try (Connection connection = ConnectionFactory.createConnection(config)) {
    Table table = connection.getTable(tableName);
    Scan scan = new Scan();
    rr.setHTable(table);
    rr.setScan(scan);
    SMSplit tableSplit = new SMSplit(new TableSplit(tableName, scan.getStartRow(), scan.getStopRow(), "sdfsdf"));
    rr.initialize(tableSplit, null);
    int i = 0;
    while (rr.nextKeyValue()) {
      i++;
      Assert.assertNotNull("Column 1 is null", rr.getCurrentValue().getColumn(1));
      Assert.assertNotNull("Column 2 is null", rr.getCurrentValue().getColumn(2));
      Assert.assertNotNull("Current Key is null", rr.getCurrentKey());
    }
    Assert.assertEquals("incorrect results returned", 10000, i);
  }
}
 
Example 4
Source File: SMRecordReaderImplIT.java    From spliceengine with GNU Affero General Public License v3.0 6 votes vote down vote up
@Test
public void emptyMemstoreScan() throws Exception {
  List<String> names = new ArrayList<String>();
  names.add("COL1");
  names.add("COL2");
  config.set(MRConstants.SPLICE_SCAN_INFO, sqlUtil.getTableScannerBuilder(SMRecordReaderImplIT.class.getSimpleName() + ".D", names).base64Encode());
  SMRecordReaderImpl rr = new SMRecordReaderImpl(config);
  TableName tableName = TableName.valueOf(sqlUtil.getConglomID(SMRecordReaderImplIT.class.getSimpleName() + ".D"));
  try (Connection connection = ConnectionFactory.createConnection(config)) {
    Table table = connection.getTable(tableName);
    Scan scan = new Scan();
    rr.setHTable(table);
    rr.setScan(scan);
    SMSplit tableSplit = new SMSplit(new TableSplit(tableName, scan.getStartRow(), scan.getStopRow(), "sdfsdf"));
    rr.initialize(tableSplit, null);
    int i = 0;
    while (rr.nextKeyValue()) {
      i++;
      Assert.assertNotNull("Column 1 is null", rr.getCurrentValue().getColumn(1));
      Assert.assertNotNull("Column 2 is null", rr.getCurrentValue().getColumn(2));
      Assert.assertNotNull("Current Key is null", rr.getCurrentKey());
    }
    Assert.assertEquals("incorrect results returned", 1000, i);
  }
}
 
Example 5
Source File: WhereCompilerTest.java    From phoenix with Apache License 2.0 6 votes vote down vote up
@Test
public void testSingleVariableFullPkSalted() throws SQLException {
    PhoenixConnection pconn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TEST_PROPERTIES)).unwrap(PhoenixConnection.class);
    pconn.createStatement().execute("CREATE TABLE t (k varchar(10) primary key, v varchar) SALT_BUCKETS=20");
    String query = "select * from t where k='a'";
    PhoenixPreparedStatement pstmt = newPreparedStatement(pconn, query);
    QueryPlan plan = pstmt.optimizeQuery();
    Scan scan = plan.getContext().getScan();
    Filter filter = scan.getFilter();
    assertNull(filter);
    byte[] key = new byte[2];
    PVarchar.INSTANCE.toBytes("a", key, 1);
    key[0] = SaltingUtil.getSaltingByte(key, 1, 1, 20);
    byte[] expectedStartKey = key;
    //lexicographically this is the next PK
    byte[] expectedEndKey = ByteUtil.concat(key,new byte[]{0});
    byte[] startKey = scan.getStartRow();
    byte[] stopKey = scan.getStopRow();
    assertTrue(Bytes.compareTo(expectedStartKey, startKey) == 0);
    assertTrue(Bytes.compareTo(expectedEndKey, stopKey) == 0);
}
 
Example 6
Source File: HBaseTableInputFormat.java    From spork with Apache License 2.0 6 votes vote down vote up
@Override
public void setScan(Scan scan) {
    super.setScan(scan);

    startRow_ = scan.getStartRow();
    endRow_ = scan.getStopRow();
    byte[] startPadded;
    byte[] endPadded;
    if (startRow_.length < endRow_.length) {
        startPadded = Bytes.padTail(startRow_, endRow_.length - startRow_.length);
        endPadded = endRow_;
    } else if (endRow_.length < startRow_.length) {
        startPadded = startRow_;
        endPadded = Bytes.padTail(endRow_, startRow_.length - endRow_.length);
    } else {
        startPadded = startRow_;
        endPadded = endRow_;
    }
    currRow_ = startRow_;
    byte [] prependHeader = {1, 0};
    bigStart_ = new BigInteger(Bytes.add(prependHeader, startPadded));
    bigEnd_ = new BigInteger(Bytes.add(prependHeader, endPadded));
    bigRange_ = new BigDecimal(bigEnd_.subtract(bigStart_));
    LOG.info("setScan with ranges: " + bigStart_ + " - " + bigEnd_ + " ( " + bigRange_ + ")");
}
 
Example 7
Source File: StoreFileReader.java    From hbase with Apache License 2.0 6 votes vote down vote up
/**
 * Checks whether the given scan rowkey range overlaps with the current storefile's
 * @param scan the scan specification. Used to determine the rowkey range.
 * @return true if there is overlap, false otherwise
 */
public boolean passesKeyRangeFilter(Scan scan) {
  Optional<Cell> firstKeyKV = this.getFirstKey();
  Optional<Cell> lastKeyKV = this.getLastKey();
  if (!firstKeyKV.isPresent() || !lastKeyKV.isPresent()) {
    // the file is empty
    return false;
  }
  if (Bytes.equals(scan.getStartRow(), HConstants.EMPTY_START_ROW) &&
      Bytes.equals(scan.getStopRow(), HConstants.EMPTY_END_ROW)) {
    return true;
  }
  byte[] smallestScanRow = scan.isReversed() ? scan.getStopRow() : scan.getStartRow();
  byte[] largestScanRow = scan.isReversed() ? scan.getStartRow() : scan.getStopRow();
  boolean nonOverLapping = (getComparator()
      .compareRows(firstKeyKV.get(), largestScanRow, 0, largestScanRow.length) > 0 &&
      !Bytes.equals(scan.isReversed() ? scan.getStartRow() : scan.getStopRow(),
        HConstants.EMPTY_END_ROW)) ||
      getComparator().compareRows(lastKeyKV.get(), smallestScanRow, 0,
        smallestScanRow.length) < 0;
  return !nonOverLapping;
}
 
Example 8
Source File: Export.java    From hbase with Apache License 2.0 6 votes vote down vote up
private Scan validateKey(final RegionInfo region, final ExportProtos.ExportRequest request)
    throws IOException {
  Scan scan = ProtobufUtil.toScan(request.getScan());
  byte[] regionStartKey = region.getStartKey();
  byte[] originStartKey = scan.getStartRow();
  if (originStartKey == null
          || Bytes.compareTo(originStartKey, regionStartKey) < 0) {
    scan.withStartRow(regionStartKey);
  }
  byte[] regionEndKey = region.getEndKey();
  byte[] originEndKey = scan.getStopRow();
  if (originEndKey == null
          || Bytes.compareTo(originEndKey, regionEndKey) > 0) {
    scan.withStartRow(regionEndKey);
  }
  return scan;
}
 
Example 9
Source File: WhereCompilerTest.java    From phoenix with Apache License 2.0 6 votes vote down vote up
@Test
public void testSingleVariableFullPkSalted() throws SQLException {
    PhoenixConnection pconn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TEST_PROPERTIES)).unwrap(PhoenixConnection.class);
    pconn.createStatement().execute("CREATE TABLE t (k varchar primary key, v varchar) SALT_BUCKETS=20");
    String query = "select * from t where k='a'";
    PhoenixPreparedStatement pstmt = newPreparedStatement(pconn, query);
    QueryPlan plan = pstmt.optimizeQuery();
    Scan scan = plan.getContext().getScan();
    Filter filter = scan.getFilter();
    assertNull(filter);
    byte[] key = new byte[2];
    PVarchar.INSTANCE.toBytes("a", key, 1);
    key[0] = SaltingUtil.getSaltingByte(key, 1, 1, 20);
    byte[] expectedStartKey = key;
    byte[] expectedEndKey = ByteUtil.nextKey(ByteUtil.concat(key, QueryConstants.SEPARATOR_BYTE_ARRAY));
    byte[] startKey = scan.getStartRow();
    byte[] stopKey = scan.getStopRow();
    assertTrue(Bytes.compareTo(expectedStartKey, startKey) == 0);
    assertTrue(Bytes.compareTo(expectedEndKey, stopKey) == 0);
}
 
Example 10
Source File: WhereCompilerTest.java    From phoenix with Apache License 2.0 6 votes vote down vote up
@Test
public void testSingleFixedFullPkSalted() throws SQLException {
    PhoenixConnection pconn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TEST_PROPERTIES)).unwrap(PhoenixConnection.class);
    pconn.createStatement().execute("CREATE TABLE t (k bigint not null primary key, v varchar) SALT_BUCKETS=20");
    String query = "select * from t where k=" + 1;
    PhoenixPreparedStatement pstmt = newPreparedStatement(pconn, query);
    QueryPlan plan = pstmt.optimizeQuery();
    Scan scan = plan.getContext().getScan();
    Filter filter = scan.getFilter();
    assertNull(filter);
    byte[] key = new byte[PLong.INSTANCE.getByteSize() + 1];
    PLong.INSTANCE.toBytes(1L, key, 1);
    key[0] = SaltingUtil.getSaltingByte(key, 1, PLong.INSTANCE.getByteSize(), 20);
    byte[] expectedStartKey = key;
    byte[] expectedEndKey = ByteUtil.nextKey(key);
    byte[] startKey = scan.getStartRow();
    byte[] stopKey = scan.getStopRow();
    assertArrayEquals(expectedStartKey, startKey);
    assertArrayEquals(expectedEndKey, stopKey);
}
 
Example 11
Source File: BaseScannerRegionObserver.java    From phoenix with Apache License 2.0 6 votes vote down vote up
private static void throwIfScanOutOfRegion(Scan scan, HRegion region) throws DoNotRetryIOException {
    boolean isLocalIndex = ScanUtil.isLocalIndex(scan);
    byte[] lowerInclusiveScanKey = scan.getStartRow();
    byte[] upperExclusiveScanKey = scan.getStopRow();
    byte[] lowerInclusiveRegionKey = region.getStartKey();
    byte[] upperExclusiveRegionKey = region.getEndKey();
    boolean isStaleRegionBoundaries;
    if (isLocalIndex) {
        byte[] expectedUpperRegionKey = scan.getAttribute(EXPECTED_UPPER_REGION_KEY);
        isStaleRegionBoundaries = expectedUpperRegionKey != null &&
                Bytes.compareTo(upperExclusiveRegionKey, expectedUpperRegionKey) != 0;
    } else {
        isStaleRegionBoundaries = Bytes.compareTo(lowerInclusiveScanKey, lowerInclusiveRegionKey) < 0 ||
                ( Bytes.compareTo(upperExclusiveScanKey, upperExclusiveRegionKey) > 0 && upperExclusiveRegionKey.length != 0);
    }
    if (isStaleRegionBoundaries) {
        Exception cause = new StaleRegionBoundaryCacheException(region.getRegionInfo().getTable().getNameAsString());
        throw new DoNotRetryIOException(cause.getMessage(), cause);
    }
}
 
Example 12
Source File: HBaseUtils.java    From envelope with Apache License 2.0 6 votes vote down vote up
public static Scan mergeRangeScans(List<Scan> rangeScans) {
  List<RowRange> ranges = Lists.newArrayList();
  
  for (Scan rangeScan : rangeScans) {
    byte[] startRow = rangeScan.getStartRow();
    byte[] stopRow = rangeScan.getStopRow();
    
    ranges.add(new RowRange(startRow, true, stopRow, false));
  }
  
  Scan mergedScan = new Scan();
  try {
    mergedScan.setFilter(new MultiRowRangeFilter(ranges));
  } catch (IOException e) {
    throw new RuntimeException(e);
  }
  
  return mergedScan;
}
 
Example 13
Source File: StoreFileReader.java    From hbase with Apache License 2.0 5 votes vote down vote up
/**
 * Checks whether the given scan passes the Bloom filter (if present). Only
 * checks Bloom filters for single-row or single-row-column scans. Bloom
 * filter checking for multi-gets is implemented as part of the store
 * scanner system (see {@link StoreFileScanner#seek(Cell)} and uses
 * the lower-level API {@link #passesGeneralRowBloomFilter(byte[], int, int)}
 * and {@link #passesGeneralRowColBloomFilter(Cell)}.
 *
 * @param scan the scan specification. Used to determine the row, and to
 *          check whether this is a single-row ("get") scan.
 * @param columns the set of columns. Only used for row-column Bloom
 *          filters.
 * @return true if the scan with the given column set passes the Bloom
 *         filter, or if the Bloom filter is not applicable for the scan.
 *         False if the Bloom filter is applicable and the scan fails it.
 */
boolean passesBloomFilter(Scan scan, final SortedSet<byte[]> columns) {
  byte[] row = scan.getStartRow();
  switch (this.bloomFilterType) {
    case ROW:
      if (!scan.isGetScan()) {
        return true;
      }
      return passesGeneralRowBloomFilter(row, 0, row.length);

    case ROWCOL:
      if (!scan.isGetScan()) {
        return true;
      }
      if (columns != null && columns.size() == 1) {
        byte[] column = columns.first();
        // create the required fake key
        Cell kvKey = PrivateCellUtil.createFirstOnRow(row, HConstants.EMPTY_BYTE_ARRAY, column);
        return passesGeneralRowColBloomFilter(kvKey);
      }

      // For multi-column queries the Bloom filter is checked from the
      // seekExact operation.
      return true;
    case ROWPREFIX_FIXED_LENGTH:
      return passesGeneralRowPrefixBloomFilter(scan);
    default:
      return true;
  }
}
 
Example 14
Source File: TransactionState.java    From hbase-secondary-index with GNU General Public License v3.0 5 votes vote down vote up
void addScan(final Scan scan) {
	ScanRange scanRange = new ScanRange(scan.getStartRow(),
			scan.getStopRow());
	LOG.trace(String.format(
			"Adding scan for transcaction [%s], from [%s] to [%s]",
			transactionId,
			scanRange.startRow == null ? "null" : Bytes
					.toString(scanRange.startRow),
			scanRange.endRow == null ? "null" : Bytes
					.toString(scanRange.endRow)));
	scans.add(scanRange);
}
 
Example 15
Source File: SaltingUtil.java    From phoenix with Apache License 2.0 5 votes vote down vote up
public static void addRegionStartKeyToScanStartAndStopRows(byte[] startKey, byte[] endKey, Scan scan) {
    if (startKey.length == 0 && endKey.length == 0) return;
    byte[] prefixBytes = startKey.length != 0 ? startKey : new byte[endKey.length];
    byte[] newStartRow = new byte[scan.getStartRow().length + prefixBytes.length];
    System.arraycopy(prefixBytes, 0, newStartRow, 0, prefixBytes.length);
    System.arraycopy(scan.getStartRow(), 0, newStartRow, prefixBytes.length, scan.getStartRow().length);
    scan.setStartRow(newStartRow);
    if (scan.getStopRow().length != 0) {
        byte[] newStopRow = new byte[scan.getStopRow().length + prefixBytes.length];
        System.arraycopy(prefixBytes, 0, newStopRow, 0, prefixBytes.length);
        System.arraycopy(scan.getStopRow(), 0, newStopRow, prefixBytes.length, scan.getStopRow().length);
        scan.setStopRow(newStopRow);
    }
}
 
Example 16
Source File: ScanUtil.java    From phoenix with Apache License 2.0 5 votes vote down vote up
public static void setupReverseScan(Scan scan) {
    if (isReversed(scan)) {
        byte[] startRow = scan.getStartRow();
        byte[] stopRow = scan.getStopRow();
        byte[] newStartRow = startRow;
        byte[] newStopRow = stopRow;
        if (startRow.length != 0) {
            /*
             * Must get previous key because this is going from an inclusive start key to an exclusive stop key, and
             * we need the start key to be included. We get the previous key by decrementing the last byte by one.
             * However, with variable length data types, we need to fill with the max byte value, otherwise, if the
             * start key is 'ab', we lower it to 'aa' which would cause 'aab' to be included (which isn't correct).
             * So we fill with a 0xFF byte to prevent this. A single 0xFF would be enough for our primitive types (as
             * that byte wouldn't occur), but for an arbitrary VARBINARY key we can't know how many bytes to tack
             * on. It's lame of HBase to force us to do this.
             */
            newStartRow = Arrays.copyOf(startRow, startRow.length + MAX_FILL_LENGTH_FOR_PREVIOUS_KEY.length);
            if (ByteUtil.previousKey(newStartRow, startRow.length)) {
                System.arraycopy(MAX_FILL_LENGTH_FOR_PREVIOUS_KEY, 0, newStartRow, startRow.length, MAX_FILL_LENGTH_FOR_PREVIOUS_KEY.length);
            } else {
                newStartRow = HConstants.EMPTY_START_ROW;
            }
        }
        if (stopRow.length != 0) {
            // Must add null byte because we need the start to be exclusive while it was inclusive
            newStopRow = ByteUtil.concat(stopRow, QueryConstants.SEPARATOR_BYTE_ARRAY);
        }
        scan.setStartRow(newStopRow);
        scan.setStopRow(newStartRow);
        scan.setReversed(true);
    }
}
 
Example 17
Source File: BaseScannerRegionObserver.java    From phoenix with Apache License 2.0 5 votes vote down vote up
private static void throwIfScanOutOfRegion(Scan scan, Region region) throws DoNotRetryIOException {
    boolean isLocalIndex = ScanUtil.isLocalIndex(scan);
    byte[] lowerInclusiveScanKey = scan.getStartRow();
    byte[] upperExclusiveScanKey = scan.getStopRow();
    byte[] lowerInclusiveRegionKey = region.getRegionInfo().getStartKey();
    byte[] upperExclusiveRegionKey = region.getRegionInfo().getEndKey();
    boolean isStaleRegionBoundaries;
    if (isLocalIndex) {
        // For local indexes we have to abort any scan that was open during a split.
        // We detect that condition as follows:
        // 1. The scanner's stop row has to always match the region's end key.
        // 2. Phoenix sets the SCAN_ACTUAL_START_ROW attribute to the scan's original start row
        //    We cannot directly compare that with the region's start key, but can enforce that
        //    the original start row still falls within the new region.
        byte[] expectedUpperRegionKey =
                scan.getAttribute(EXPECTED_UPPER_REGION_KEY) == null ? scan.getStopRow() : scan
                        .getAttribute(EXPECTED_UPPER_REGION_KEY);

        byte[] actualStartRow = scan.getAttribute(SCAN_ACTUAL_START_ROW);
        isStaleRegionBoundaries = (expectedUpperRegionKey != null &&
                Bytes.compareTo(upperExclusiveRegionKey, expectedUpperRegionKey) != 0) || 
                (actualStartRow != null && Bytes.compareTo(actualStartRow, lowerInclusiveRegionKey) < 0);
    } else {
        isStaleRegionBoundaries = Bytes.compareTo(lowerInclusiveScanKey, lowerInclusiveRegionKey) < 0 ||
                ( Bytes.compareTo(upperExclusiveScanKey, upperExclusiveRegionKey) > 0 && upperExclusiveRegionKey.length != 0) ||
                (upperExclusiveRegionKey.length != 0 && upperExclusiveScanKey.length == 0);
    }
    if (isStaleRegionBoundaries) {
        Exception cause = new StaleRegionBoundaryCacheException(region.getRegionInfo().getTable().getNameAsString());
        throw new DoNotRetryIOException(cause.getMessage(), cause);
    }
    if(isLocalIndex) {
        ScanUtil.setupLocalIndexScan(scan);
    }
}
 
Example 18
Source File: ScanUtil.java    From phoenix with Apache License 2.0 5 votes vote down vote up
public static byte[] getActualStartRow(Scan localIndexScan, RegionInfo regionInfo) {
    return localIndexScan.getAttribute(SCAN_START_ROW_SUFFIX) == null ? localIndexScan
            .getStartRow() : ScanRanges.prefixKey(localIndexScan.getAttribute(SCAN_START_ROW_SUFFIX), 0 ,
        regionInfo.getStartKey().length == 0 ? new byte[regionInfo.getEndKey().length]
                : regionInfo.getStartKey(),
        regionInfo.getStartKey().length == 0 ? regionInfo.getEndKey().length : regionInfo
                .getStartKey().length);
}
 
Example 19
Source File: WhereCompilerTest.java    From phoenix with Apache License 2.0 4 votes vote down vote up
@Test
public void testMultiFixedFullPkSalted() throws SQLException {
    PhoenixConnection pconn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TEST_PROPERTIES)).unwrap(PhoenixConnection.class);
    pconn.createStatement().execute("CREATE TABLE t (k bigint not null primary key, v varchar) SALT_BUCKETS=20");
    String query = "select * from t where k in (1,3)";
    PhoenixPreparedStatement pstmt = newPreparedStatement(pconn, query);
    QueryPlan plan = pstmt.optimizeQuery();
    Scan scan = plan.getContext().getScan();
    Filter filter = scan.getFilter();
    byte[] key = new byte[PLong.INSTANCE.getByteSize() + 1];
    PLong.INSTANCE.toBytes(1L, key, 1);
    key[0] = SaltingUtil.getSaltingByte(key, 1, PLong.INSTANCE.getByteSize(), 20);
    byte[] startKey1 = key;
    
    key = new byte[PLong.INSTANCE.getByteSize() + 1];
    PLong.INSTANCE.toBytes(3L, key, 1);
    key[0] = SaltingUtil.getSaltingByte(key, 1, PLong.INSTANCE.getByteSize(), 20);
    byte[] startKey2 = key;
    
    byte[] startKey = scan.getStartRow();
    byte[] stopKey = scan.getStopRow();
    
    // Due to salting byte, the 1 key may be after the 3 key
    byte[] expectedStartKey;
    byte[] expectedEndKey;
    List<List<KeyRange>> expectedRanges = Collections.singletonList(
            Arrays.asList(KeyRange.getKeyRange(startKey1),
                          KeyRange.getKeyRange(startKey2)));
    if (Bytes.compareTo(startKey1, startKey2) > 0) {
        expectedStartKey = startKey2;
        expectedEndKey = startKey1;
        Collections.reverse(expectedRanges.get(0));
    } else {
        expectedStartKey = startKey1;
        expectedEndKey = startKey2;
    }
    assertEquals(0,startKey.length);
    assertEquals(0,stopKey.length);

    assertNotNull(filter);
    assertTrue(filter instanceof SkipScanFilter);
    SkipScanFilter skipScanFilter = (SkipScanFilter)filter;
    assertEquals(1,skipScanFilter.getSlots().size());
    assertEquals(2,skipScanFilter.getSlots().get(0).size());
    assertArrayEquals(expectedStartKey, skipScanFilter.getSlots().get(0).get(0).getLowerRange());
    assertArrayEquals(expectedEndKey, skipScanFilter.getSlots().get(0).get(1).getLowerRange());
    StatementContext context = plan.getContext();
    ScanRanges scanRanges = context.getScanRanges();
    List<List<KeyRange>> ranges = scanRanges.getRanges();
    assertEquals(expectedRanges, ranges);
}
 
Example 20
Source File: WhereCompilerTest.java    From phoenix with Apache License 2.0 4 votes vote down vote up
@Test
public void testMultiFixedFullPkSalted() throws SQLException {
    PhoenixConnection pconn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TEST_PROPERTIES)).unwrap(PhoenixConnection.class);
    pconn.createStatement().execute("CREATE TABLE t (k bigint not null primary key, v varchar) SALT_BUCKETS=20");
    String query = "select * from t where k in (1,3)";
    PhoenixPreparedStatement pstmt = newPreparedStatement(pconn, query);
    QueryPlan plan = pstmt.optimizeQuery();
    Scan scan = plan.getContext().getScan();
    Filter filter = scan.getFilter();
    byte[] key = new byte[PLong.INSTANCE.getByteSize() + 1];
    PLong.INSTANCE.toBytes(1L, key, 1);
    key[0] = SaltingUtil.getSaltingByte(key, 1, PLong.INSTANCE.getByteSize(), 20);
    byte[] startKey1 = key;

    key = new byte[PLong.INSTANCE.getByteSize() + 1];
    PLong.INSTANCE.toBytes(3L, key, 1);
    key[0] = SaltingUtil.getSaltingByte(key, 1, PLong.INSTANCE.getByteSize(), 20);
    byte[] startKey2 = key;

    byte[] startKey = scan.getStartRow();
    byte[] stopKey = scan.getStopRow();

    // Due to salting byte, the 1 key may be after the 3 key
    byte[] expectedStartKey;
    byte[] expectedEndKey;
    List<List<KeyRange>> expectedRanges = Collections.singletonList(
            Arrays.asList(KeyRange.getKeyRange(startKey1),
                          KeyRange.getKeyRange(startKey2)));
    if (Bytes.compareTo(startKey1, startKey2) > 0) {
        expectedStartKey = startKey2;
        expectedEndKey = startKey1;
        Collections.reverse(expectedRanges.get(0));
    } else {
        expectedStartKey = startKey1;
        expectedEndKey = startKey2;
    }
    assertEquals(0,startKey.length);
    assertEquals(0,stopKey.length);

    assertNotNull(filter);
    assertTrue(filter instanceof SkipScanFilter);
    SkipScanFilter skipScanFilter = (SkipScanFilter)filter;
    assertEquals(1,skipScanFilter.getSlots().size());
    assertEquals(2,skipScanFilter.getSlots().get(0).size());
    assertArrayEquals(expectedStartKey, skipScanFilter.getSlots().get(0).get(0).getLowerRange());
    assertArrayEquals(expectedEndKey, skipScanFilter.getSlots().get(0).get(1).getLowerRange());
    StatementContext context = plan.getContext();
    ScanRanges scanRanges = context.getScanRanges();
    List<List<KeyRange>> ranges = scanRanges.getRanges();
    assertEquals(expectedRanges, ranges);
}