Search in sources :

Example 16 with SkipScanFilter

use of org.apache.phoenix.filter.SkipScanFilter in project phoenix by apache.

the class WhereCompilerTest method testSecondPkColInListFilter.

@Test
public void testSecondPkColInListFilter() throws SQLException {
    String tenantId = "000000000000001";
    String entityId1 = "00000000000000X";
    String entityId2 = "00000000000000Y";
    String query = String.format("select * from %s where organization_id='%s' AND entity_id IN ('%s','%s')", ATABLE_NAME, tenantId, entityId1, entityId2);
    PhoenixConnection pconn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TEST_PROPERTIES)).unwrap(PhoenixConnection.class);
    PhoenixPreparedStatement pstmt = newPreparedStatement(pconn, query);
    QueryPlan plan = pstmt.optimizeQuery();
    Scan scan = plan.getContext().getScan();
    byte[] startRow = PVarchar.INSTANCE.toBytes(tenantId + entityId1);
    assertArrayEquals(startRow, scan.getStartRow());
    byte[] stopRow = PVarchar.INSTANCE.toBytes(tenantId + entityId2);
    assertArrayEquals(ByteUtil.concat(stopRow, QueryConstants.SEPARATOR_BYTE_ARRAY), scan.getStopRow());
    Filter filter = scan.getFilter();
    assertEquals(new SkipScanFilter(ImmutableList.of(Arrays.asList(pointRange(tenantId, entityId1), pointRange(tenantId, entityId2))), SchemaUtil.VAR_BINARY_SCHEMA), filter);
}
Also used : PhoenixConnection(org.apache.phoenix.jdbc.PhoenixConnection) RowKeyComparisonFilter(org.apache.phoenix.filter.RowKeyComparisonFilter) TestUtil.multiEncodedKVFilter(org.apache.phoenix.util.TestUtil.multiEncodedKVFilter) SkipScanFilter(org.apache.phoenix.filter.SkipScanFilter) Filter(org.apache.hadoop.hbase.filter.Filter) TestUtil.singleKVFilter(org.apache.phoenix.util.TestUtil.singleKVFilter) Scan(org.apache.hadoop.hbase.client.Scan) PhoenixPreparedStatement(org.apache.phoenix.jdbc.PhoenixPreparedStatement) SkipScanFilter(org.apache.phoenix.filter.SkipScanFilter) Test(org.junit.Test) BaseConnectionlessQueryTest(org.apache.phoenix.query.BaseConnectionlessQueryTest)

Example 17 with SkipScanFilter

use of org.apache.phoenix.filter.SkipScanFilter in project phoenix by apache.

the class WhereCompilerTest method testInListWithAnd2Filter.

@Test
public void testInListWithAnd2Filter() throws SQLException {
    String tenantId1 = "000000000000001";
    String tenantId2 = "000000000000002";
    String entityId1 = "00000000000000X";
    String entityId2 = "00000000000000Y";
    String query = String.format("select * from %s where organization_id IN ('%s','%s') AND entity_id IN ('%s', '%s')", ATABLE_NAME, tenantId1, tenantId2, entityId1, entityId2);
    PhoenixConnection pconn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TEST_PROPERTIES)).unwrap(PhoenixConnection.class);
    PhoenixPreparedStatement pstmt = newPreparedStatement(pconn, query);
    QueryPlan plan = pstmt.optimizeQuery();
    Scan scan = plan.getContext().getScan();
    Filter filter = scan.getFilter();
    assertEquals(new SkipScanFilter(ImmutableList.<List<KeyRange>>of(ImmutableList.of(pointRange(tenantId1, entityId1), pointRange(tenantId1, entityId2), pointRange(tenantId2, entityId1), pointRange(tenantId2, entityId2))), SchemaUtil.VAR_BINARY_SCHEMA), filter);
}
Also used : PhoenixConnection(org.apache.phoenix.jdbc.PhoenixConnection) RowKeyComparisonFilter(org.apache.phoenix.filter.RowKeyComparisonFilter) TestUtil.multiEncodedKVFilter(org.apache.phoenix.util.TestUtil.multiEncodedKVFilter) SkipScanFilter(org.apache.phoenix.filter.SkipScanFilter) Filter(org.apache.hadoop.hbase.filter.Filter) TestUtil.singleKVFilter(org.apache.phoenix.util.TestUtil.singleKVFilter) Scan(org.apache.hadoop.hbase.client.Scan) List(java.util.List) FilterList(org.apache.hadoop.hbase.filter.FilterList) ImmutableList(com.google.common.collect.ImmutableList) PhoenixPreparedStatement(org.apache.phoenix.jdbc.PhoenixPreparedStatement) SkipScanFilter(org.apache.phoenix.filter.SkipScanFilter) Test(org.junit.Test) BaseConnectionlessQueryTest(org.apache.phoenix.query.BaseConnectionlessQueryTest)

Example 18 with SkipScanFilter

use of org.apache.phoenix.filter.SkipScanFilter in project phoenix by apache.

the class WhereCompilerTest method testInListWithAnd1GTEFilter.

@Test
public void testInListWithAnd1GTEFilter() throws SQLException {
    String tenantId1 = "000000000000001";
    String tenantId2 = "000000000000002";
    String tenantId3 = "000000000000003";
    String entityId1 = "00000000000000X";
    String entityId2 = "00000000000000Y";
    String query = String.format("select * from %s where organization_id IN ('%s','%s','%s') AND entity_id>='%s' AND entity_id<='%s'", ATABLE_NAME, tenantId1, tenantId3, tenantId2, entityId1, entityId2);
    PhoenixConnection pconn = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TEST_PROPERTIES)).unwrap(PhoenixConnection.class);
    PhoenixPreparedStatement pstmt = newPreparedStatement(pconn, query);
    QueryPlan plan = pstmt.optimizeQuery();
    Scan scan = plan.getContext().getScan();
    Filter filter = scan.getFilter();
    assertEquals(new SkipScanFilter(ImmutableList.of(Arrays.asList(pointRange(tenantId1), pointRange(tenantId2), pointRange(tenantId3)), Arrays.asList(PChar.INSTANCE.getKeyRange(Bytes.toBytes(entityId1), true, Bytes.toBytes(entityId2), true))), plan.getTableRef().getTable().getRowKeySchema()), filter);
}
Also used : PhoenixConnection(org.apache.phoenix.jdbc.PhoenixConnection) RowKeyComparisonFilter(org.apache.phoenix.filter.RowKeyComparisonFilter) TestUtil.multiEncodedKVFilter(org.apache.phoenix.util.TestUtil.multiEncodedKVFilter) SkipScanFilter(org.apache.phoenix.filter.SkipScanFilter) Filter(org.apache.hadoop.hbase.filter.Filter) TestUtil.singleKVFilter(org.apache.phoenix.util.TestUtil.singleKVFilter) Scan(org.apache.hadoop.hbase.client.Scan) PhoenixPreparedStatement(org.apache.phoenix.jdbc.PhoenixPreparedStatement) SkipScanFilter(org.apache.phoenix.filter.SkipScanFilter) Test(org.junit.Test) BaseConnectionlessQueryTest(org.apache.phoenix.query.BaseConnectionlessQueryTest)

Example 19 with SkipScanFilter

use of org.apache.phoenix.filter.SkipScanFilter in project phoenix by apache.

the class ParallelIteratorsSplitTest method foreach.

private static Collection<?> foreach(KeyRange[][] ranges, int[] widths, KeyRange[] expectedSplits) {
    RowKeySchema schema = buildSchema(widths);
    List<List<KeyRange>> slots = Lists.transform(Lists.newArrayList(ranges), ARRAY_TO_LIST);
    SkipScanFilter filter = new SkipScanFilter(slots, schema);
    // Always set start and stop key to max to verify we are using the information in skipscan
    // filter over the scan's KMIN and KMAX.
    Scan scan = new Scan().setFilter(filter);
    ScanRanges scanRanges = ScanRanges.createSingleSpan(schema, slots);
    List<Object> ret = Lists.newArrayList();
    ret.add(new Object[] { scan, scanRanges, Arrays.<KeyRange>asList(expectedSplits) });
    return ret;
}
Also used : RowKeySchema(org.apache.phoenix.schema.RowKeySchema) List(java.util.List) Scan(org.apache.hadoop.hbase.client.Scan) SkipScanFilter(org.apache.phoenix.filter.SkipScanFilter) ScanRanges(org.apache.phoenix.compile.ScanRanges)

Example 20 with SkipScanFilter

use of org.apache.phoenix.filter.SkipScanFilter in project phoenix by apache.

the class ScanRanges method intersectScan.

public Scan intersectScan(Scan scan, final byte[] originalStartKey, final byte[] originalStopKey, final int keyOffset, boolean crossesRegionBoundary) {
    byte[] startKey = originalStartKey;
    byte[] stopKey = originalStopKey;
    if (stopKey.length > 0 && Bytes.compareTo(startKey, stopKey) >= 0) {
        return null;
    }
    // Keep the keys as they are if we have a point lookup, as we've already resolved the
    // salt bytes in that case.
    final int scanKeyOffset = this.isSalted && !this.isPointLookup ? SaltingUtil.NUM_SALTING_BYTES : 0;
    assert (scanKeyOffset == 0 || keyOffset == 0);
    // Total offset for startKey/stopKey. Either 1 for salted tables or the prefix length
    // of the current region for local indexes. We'll never have a case where a table is
    // both salted and local.
    final int totalKeyOffset = scanKeyOffset + keyOffset;
    byte[] prefixBytes = ByteUtil.EMPTY_BYTE_ARRAY;
    if (totalKeyOffset > 0) {
        prefixBytes = ScanUtil.getPrefix(startKey, totalKeyOffset);
        /*
             * If our startKey to stopKey crosses a region boundary consider everything after the startKey as our scan
             * is always done within a single region. This prevents us from having to prefix the key prior to knowing
             * whether or not there may be an intersection. We can't calculate whether or not we've crossed a region
             * boundary for local indexes, because we don't know the key offset of the next region, but only for the
             * current one (which is the one passed in). If the next prefix happened to be a subset of the previous
             * prefix, then this wouldn't detect that we crossed a region boundary.
             */
        if (crossesRegionBoundary) {
            stopKey = ByteUtil.EMPTY_BYTE_ARRAY;
        }
    }
    int scanStartKeyOffset = scanKeyOffset;
    byte[] scanStartKey = scan == null ? this.scanRange.getLowerRange() : scan.getStartRow();
    // Compare ignoring key prefix and salt byte
    if (scanStartKey.length - scanKeyOffset > 0) {
        if (startKey.length - totalKeyOffset > 0) {
            if (Bytes.compareTo(scanStartKey, scanKeyOffset, scanStartKey.length - scanKeyOffset, startKey, totalKeyOffset, startKey.length - totalKeyOffset) < 0) {
                scanStartKey = startKey;
                scanStartKeyOffset = totalKeyOffset;
            }
        }
    } else {
        scanStartKey = startKey;
        scanStartKeyOffset = totalKeyOffset;
    }
    int scanStopKeyOffset = scanKeyOffset;
    byte[] scanStopKey = scan == null ? this.scanRange.getUpperRange() : scan.getStopRow();
    if (scanStopKey.length - scanKeyOffset > 0) {
        if (stopKey.length - totalKeyOffset > 0) {
            if (Bytes.compareTo(scanStopKey, scanKeyOffset, scanStopKey.length - scanKeyOffset, stopKey, totalKeyOffset, stopKey.length - totalKeyOffset) > 0) {
                scanStopKey = stopKey;
                scanStopKeyOffset = totalKeyOffset;
            }
        }
    } else {
        scanStopKey = stopKey;
        scanStopKeyOffset = totalKeyOffset;
    }
    // If not scanning anything, return null
    if (scanStopKey.length - scanStopKeyOffset > 0 && Bytes.compareTo(scanStartKey, scanStartKeyOffset, scanStartKey.length - scanStartKeyOffset, scanStopKey, scanStopKeyOffset, scanStopKey.length - scanStopKeyOffset) >= 0) {
        return null;
    }
    if (originalStopKey.length != 0 && scanStopKey.length == 0) {
        scanStopKey = originalStopKey;
    }
    Filter newFilter = null;
    // start/stop or the scanRanges start/stop.
    if (this.useSkipScanFilter()) {
        byte[] skipScanStartKey = scanStartKey;
        byte[] skipScanStopKey = scanStopKey;
        // we need to remove the prefix before running our intersect method.
        if (scanKeyOffset > 0) {
            if (skipScanStartKey != originalStartKey) {
                // original already has correct salt byte
                skipScanStartKey = replaceSaltByte(skipScanStartKey, prefixBytes);
            }
            if (skipScanStopKey != originalStopKey) {
                skipScanStopKey = replaceSaltByte(skipScanStopKey, prefixBytes);
            }
        } else if (keyOffset > 0) {
            if (skipScanStartKey == originalStartKey) {
                skipScanStartKey = stripPrefix(skipScanStartKey, keyOffset);
            }
            if (skipScanStopKey == originalStopKey) {
                skipScanStopKey = stripPrefix(skipScanStopKey, keyOffset);
            }
        }
        if (scan == null) {
            return filter.hasIntersect(skipScanStartKey, skipScanStopKey) ? HAS_INTERSECTION : null;
        }
        Filter filter = scan.getFilter();
        SkipScanFilter newSkipScanFilter = null;
        if (filter instanceof SkipScanFilter) {
            SkipScanFilter oldSkipScanFilter = (SkipScanFilter) filter;
            newFilter = newSkipScanFilter = oldSkipScanFilter.intersect(skipScanStartKey, skipScanStopKey);
            if (newFilter == null) {
                return null;
            }
        } else if (filter instanceof FilterList) {
            FilterList oldList = (FilterList) filter;
            FilterList newList = new FilterList(FilterList.Operator.MUST_PASS_ALL);
            newFilter = newList;
            for (Filter f : oldList.getFilters()) {
                if (f instanceof SkipScanFilter) {
                    newSkipScanFilter = ((SkipScanFilter) f).intersect(skipScanStartKey, skipScanStopKey);
                    if (newSkipScanFilter == null) {
                        return null;
                    }
                    newList.addFilter(newSkipScanFilter);
                } else {
                    newList.addFilter(f);
                }
            }
        }
        // have an enclosing range when we do a point lookup.
        if (isPointLookup) {
            scanStartKey = ScanUtil.getMinKey(schema, newSkipScanFilter.getSlots(), slotSpan);
            scanStopKey = ScanUtil.getMaxKey(schema, newSkipScanFilter.getSlots(), slotSpan);
        }
    }
    // If we've got this far, we know we have an intersection
    if (scan == null) {
        return HAS_INTERSECTION;
    }
    if (newFilter == null) {
        newFilter = scan.getFilter();
    }
    Scan newScan = ScanUtil.newScan(scan);
    newScan.setFilter(newFilter);
    // for it.
    if (totalKeyOffset > 0) {
        if (scanStartKey != originalStartKey) {
            scanStartKey = prefixKey(scanStartKey, scanKeyOffset, prefixBytes, keyOffset);
        }
        if (scanStopKey != originalStopKey) {
            scanStopKey = prefixKey(scanStopKey, scanKeyOffset, prefixBytes, keyOffset);
        }
    }
    // Don't let the stopRow of the scan go beyond the originalStopKey
    if (originalStopKey.length > 0 && Bytes.compareTo(scanStopKey, originalStopKey) > 0) {
        scanStopKey = originalStopKey;
    }
    if (scanStopKey.length > 0 && Bytes.compareTo(scanStartKey, scanStopKey) >= 0) {
        return null;
    }
    newScan.setAttribute(SCAN_ACTUAL_START_ROW, scanStartKey);
    newScan.setStartRow(scanStartKey);
    newScan.setStopRow(scanStopKey);
    return newScan;
}
Also used : SkipScanFilter(org.apache.phoenix.filter.SkipScanFilter) Filter(org.apache.hadoop.hbase.filter.Filter) FilterList(org.apache.hadoop.hbase.filter.FilterList) Scan(org.apache.hadoop.hbase.client.Scan) SkipScanFilter(org.apache.phoenix.filter.SkipScanFilter)

Aggregations

SkipScanFilter (org.apache.phoenix.filter.SkipScanFilter)28 Scan (org.apache.hadoop.hbase.client.Scan)24 Filter (org.apache.hadoop.hbase.filter.Filter)19 BaseConnectionlessQueryTest (org.apache.phoenix.query.BaseConnectionlessQueryTest)19 Test (org.junit.Test)19 RowKeyComparisonFilter (org.apache.phoenix.filter.RowKeyComparisonFilter)18 PhoenixConnection (org.apache.phoenix.jdbc.PhoenixConnection)15 FilterList (org.apache.hadoop.hbase.filter.FilterList)12 List (java.util.List)10 SingleCQKeyValueComparisonFilter (org.apache.phoenix.filter.SingleCQKeyValueComparisonFilter)10 PhoenixPreparedStatement (org.apache.phoenix.jdbc.PhoenixPreparedStatement)10 SingleKeyValueComparisonFilter (org.apache.phoenix.filter.SingleKeyValueComparisonFilter)9 TestUtil.rowKeyFilter (org.apache.phoenix.util.TestUtil.rowKeyFilter)9 TestUtil.multiEncodedKVFilter (org.apache.phoenix.util.TestUtil.multiEncodedKVFilter)8 TestUtil.singleKVFilter (org.apache.phoenix.util.TestUtil.singleKVFilter)8 Connection (java.sql.Connection)6 KeyRange (org.apache.phoenix.query.KeyRange)4 ArrayList (java.util.ArrayList)3 ScanRanges (org.apache.phoenix.compile.ScanRanges)3 ImmutableList (com.google.common.collect.ImmutableList)2