Search in sources :

Example 1 with ColumnProjectionFilter

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

the class BaseResultIterators method optimizeProjection.

private static void optimizeProjection(StatementContext context, Scan scan, PTable table, FilterableStatement statement) {
    Map<byte[], NavigableSet<byte[]>> familyMap = scan.getFamilyMap();
    // columnsTracker contain cf -> qualifiers which should get returned.
    Map<ImmutableBytesPtr, NavigableSet<ImmutableBytesPtr>> columnsTracker = new TreeMap<ImmutableBytesPtr, NavigableSet<ImmutableBytesPtr>>();
    Set<byte[]> conditionOnlyCfs = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
    int referencedCfCount = familyMap.size();
    QualifierEncodingScheme encodingScheme = table.getEncodingScheme();
    ImmutableStorageScheme storageScheme = table.getImmutableStorageScheme();
    BitSet trackedColumnsBitset = isPossibleToUseEncodedCQFilter(encodingScheme, storageScheme) && !hasDynamicColumns(table) ? new BitSet(10) : null;
    boolean filteredColumnNotInProjection = false;
    for (Pair<byte[], byte[]> whereCol : context.getWhereConditionColumns()) {
        byte[] filteredFamily = whereCol.getFirst();
        if (!(familyMap.containsKey(filteredFamily))) {
            referencedCfCount++;
            filteredColumnNotInProjection = true;
        } else if (!filteredColumnNotInProjection) {
            NavigableSet<byte[]> projectedColumns = familyMap.get(filteredFamily);
            if (projectedColumns != null) {
                byte[] filteredColumn = whereCol.getSecond();
                if (filteredColumn == null) {
                    filteredColumnNotInProjection = true;
                } else {
                    filteredColumnNotInProjection = !projectedColumns.contains(filteredColumn);
                }
            }
        }
    }
    boolean preventSeekToColumn = false;
    if (statement.getHint().hasHint(Hint.SEEK_TO_COLUMN)) {
        // Allow seeking to column during filtering
        preventSeekToColumn = false;
    } else if (!EncodedColumnsUtil.useEncodedQualifierListOptimization(table)) {
        /*
             * preventSeekToColumn cannot be true, even if hinted, when encoded qualifier list
             * optimization is being used. When using the optimization, it is necessary that we
             * explicitly set the column qualifiers of the column family in the scan and not just
             * project the entire column family.
             */
        if (statement.getHint().hasHint(Hint.NO_SEEK_TO_COLUMN)) {
            // Prevent seeking to column during filtering
            preventSeekToColumn = true;
        } else {
            int hbaseServerVersion = context.getConnection().getQueryServices().getLowestClusterHBaseVersion();
            // When only a single column family is referenced, there are no hints, and HBase server version
            // is less than when the fix for HBASE-13109 went in (0.98.12), then we prevent seeking to a
            // column.
            preventSeekToColumn = referencedCfCount == 1 && hbaseServerVersion < MIN_SEEK_TO_COLUMN_VERSION;
        }
    }
    for (Entry<byte[], NavigableSet<byte[]>> entry : familyMap.entrySet()) {
        ImmutableBytesPtr cf = new ImmutableBytesPtr(entry.getKey());
        NavigableSet<byte[]> qs = entry.getValue();
        NavigableSet<ImmutableBytesPtr> cols = null;
        if (qs != null) {
            cols = new TreeSet<ImmutableBytesPtr>();
            for (byte[] q : qs) {
                cols.add(new ImmutableBytesPtr(q));
                if (trackedColumnsBitset != null) {
                    int qualifier = encodingScheme.decode(q);
                    trackedColumnsBitset.set(qualifier);
                }
            }
        }
        columnsTracker.put(cf, cols);
    }
    // Making sure that where condition CFs are getting scanned at HRS.
    for (Pair<byte[], byte[]> whereCol : context.getWhereConditionColumns()) {
        byte[] family = whereCol.getFirst();
        if (preventSeekToColumn) {
            if (!(familyMap.containsKey(family))) {
                conditionOnlyCfs.add(family);
            }
            scan.addFamily(family);
        } else {
            if (familyMap.containsKey(family)) {
                // where column's CF is present. If there are some specific columns added against this CF, we
                // need to ensure this where column also getting added in it.
                // If the select was like select cf1.*, then that itself will select the whole CF. So no need to
                // specifically add the where column. Adding that will remove the cf1.* stuff and only this
                // where condition column will get returned!
                NavigableSet<byte[]> cols = familyMap.get(family);
                // cols is null means the whole CF will get scanned.
                if (cols != null) {
                    if (whereCol.getSecond() == null) {
                        scan.addFamily(family);
                    } else {
                        scan.addColumn(family, whereCol.getSecond());
                    }
                }
            } else if (whereCol.getSecond() == null) {
                scan.addFamily(family);
            } else {
                // where column's CF itself is not present in family map. We need to add the column
                scan.addColumn(family, whereCol.getSecond());
            }
        }
    }
    if (!columnsTracker.isEmpty()) {
        if (preventSeekToColumn) {
            for (ImmutableBytesPtr f : columnsTracker.keySet()) {
                // This addFamily will remove explicit cols in scan familyMap and make it as entire row.
                // We don't want the ExplicitColumnTracker to be used. Instead we have the ColumnProjectionFilter
                scan.addFamily(f.get());
            }
        }
        // the ExplicitColumnTracker not to be used, though.
        if (!statement.isAggregate() && filteredColumnNotInProjection) {
            ScanUtil.andFilterAtEnd(scan, trackedColumnsBitset != null ? new EncodedQualifiersColumnProjectionFilter(SchemaUtil.getEmptyColumnFamily(table), trackedColumnsBitset, conditionOnlyCfs, table.getEncodingScheme()) : new ColumnProjectionFilter(SchemaUtil.getEmptyColumnFamily(table), columnsTracker, conditionOnlyCfs, EncodedColumnsUtil.usesEncodedColumnNames(table.getEncodingScheme())));
        }
    }
}
Also used : NavigableSet(java.util.NavigableSet) ImmutableBytesPtr(org.apache.phoenix.hbase.index.util.ImmutableBytesPtr) BitSet(java.util.BitSet) TreeMap(java.util.TreeMap) Hint(org.apache.phoenix.parse.HintNode.Hint) QualifierEncodingScheme(org.apache.phoenix.schema.PTable.QualifierEncodingScheme) TreeSet(java.util.TreeSet) ColumnProjectionFilter(org.apache.phoenix.filter.ColumnProjectionFilter) EncodedQualifiersColumnProjectionFilter(org.apache.phoenix.filter.EncodedQualifiersColumnProjectionFilter) EncodedQualifiersColumnProjectionFilter(org.apache.phoenix.filter.EncodedQualifiersColumnProjectionFilter) ImmutableStorageScheme(org.apache.phoenix.schema.PTable.ImmutableStorageScheme)

Aggregations

BitSet (java.util.BitSet)1 NavigableSet (java.util.NavigableSet)1 TreeMap (java.util.TreeMap)1 TreeSet (java.util.TreeSet)1 ColumnProjectionFilter (org.apache.phoenix.filter.ColumnProjectionFilter)1 EncodedQualifiersColumnProjectionFilter (org.apache.phoenix.filter.EncodedQualifiersColumnProjectionFilter)1 ImmutableBytesPtr (org.apache.phoenix.hbase.index.util.ImmutableBytesPtr)1 Hint (org.apache.phoenix.parse.HintNode.Hint)1 ImmutableStorageScheme (org.apache.phoenix.schema.PTable.ImmutableStorageScheme)1 QualifierEncodingScheme (org.apache.phoenix.schema.PTable.QualifierEncodingScheme)1