Search in sources :

Example 6 with Field

use of org.apache.phoenix.schema.ValueSchema.Field in project phoenix by apache.

the class ScanUtil method setKey.

public static int setKey(RowKeySchema schema, List<List<KeyRange>> slots, int[] slotSpan, int[] position, Bound bound, byte[] key, int byteOffset, int slotStartIndex, int slotEndIndex, int schemaStartIndex) {
    int offset = byteOffset;
    boolean lastInclusiveUpperSingleKey = false;
    boolean anyInclusiveUpperRangeKey = false;
    boolean lastUnboundUpper = false;
    // The index used for slots should be incremented by 1,
    // but the index for the field it represents in the schema
    // should be incremented by 1 + value in the current slotSpan index
    // slotSpan stores the number of columns beyond one that the range spans
    Field field = null;
    int i = slotStartIndex, fieldIndex = ScanUtil.getRowKeyPosition(slotSpan, slotStartIndex);
    for (i = slotStartIndex; i < slotEndIndex; i++) {
        // Build up the key by appending the bound of each key range
        // from the current position of each slot. 
        KeyRange range = slots.get(i).get(position[i]);
        // Use last slot in a multi-span column to determine if fixed width
        field = schema.getField(fieldIndex + slotSpan[i]);
        boolean isFixedWidth = field.getDataType().isFixedWidth();
        /*
             * If the current slot is unbound then stop if:
             * 1) setting the upper bound. There's no value in
             *    continuing because nothing will be filtered.
             * 2) setting the lower bound when the type is fixed length
             *    for the same reason. However, if the type is variable width
             *    continue building the key because null values will be filtered
             *    since our separator byte will be appended and incremented.
             * 3) if the range includes everything as we cannot add any more useful
             *    information to the key after that.
             */
        lastUnboundUpper = false;
        if (range.isUnbound(bound) && (bound == Bound.UPPER || isFixedWidth || range == KeyRange.EVERYTHING_RANGE)) {
            lastUnboundUpper = (bound == Bound.UPPER);
            break;
        }
        byte[] bytes = range.getRange(bound);
        System.arraycopy(bytes, 0, key, offset, bytes.length);
        offset += bytes.length;
        /*
             * We must add a terminator to a variable length key even for the last PK column if
             * the lower key is non inclusive or the upper key is inclusive. Otherwise, we'd be
             * incrementing the key value itself, and thus bumping it up too much.
             */
        boolean inclusiveUpper = range.isUpperInclusive() && bound == Bound.UPPER;
        boolean exclusiveLower = !range.isLowerInclusive() && bound == Bound.LOWER && range != KeyRange.EVERYTHING_RANGE;
        boolean exclusiveUpper = !range.isUpperInclusive() && bound == Bound.UPPER;
        // If we are setting the upper bound of using inclusive single key, we remember 
        // to increment the key if we exit the loop after this iteration.
        // 
        // We remember to increment the last slot if we are setting the upper bound with an
        // inclusive range key.
        //
        // We cannot combine the two flags together in case for single-inclusive key followed
        // by the range-exclusive key. In that case, we do not need to increment the end at the
        // end. But if we combine the two flag, the single inclusive key in the middle of the
        // key slots would cause the flag to become true.
        lastInclusiveUpperSingleKey = range.isSingleKey() && inclusiveUpper;
        anyInclusiveUpperRangeKey |= !range.isSingleKey() && inclusiveUpper;
        // A null or empty byte array is always represented as a zero byte
        byte sepByte = SchemaUtil.getSeparatorByte(schema.rowKeyOrderOptimizable(), bytes.length == 0, field);
        if (!isFixedWidth && (sepByte == QueryConstants.DESC_SEPARATOR_BYTE || (!exclusiveUpper && (fieldIndex < schema.getMaxFields() || inclusiveUpper || exclusiveLower)))) {
            key[offset++] = sepByte;
            // Set lastInclusiveUpperSingleKey back to false if this is the last pk column
            // as we don't want to increment the null byte in this case
            lastInclusiveUpperSingleKey &= i < schema.getMaxFields() - 1;
        }
        if (exclusiveUpper) {
            // would match k1 = 2, k2 = 3 which is wrong.
            break;
        }
        // only after the last key part.
        if (exclusiveLower) {
            if (!ByteUtil.nextKey(key, offset)) {
                // have an end key specified.
                return -byteOffset;
            }
            // just added and incremented.
            if (!isFixedWidth && bytes.length == 0 && SchemaUtil.getSeparatorByte(schema.rowKeyOrderOptimizable(), false, field) == QueryConstants.DESC_SEPARATOR_BYTE) {
                key[offset++] = QueryConstants.DESC_SEPARATOR_BYTE;
            }
        }
        fieldIndex += slotSpan[i] + 1;
    }
    if (lastInclusiveUpperSingleKey || anyInclusiveUpperRangeKey || lastUnboundUpper) {
        if (!ByteUtil.nextKey(key, offset)) {
            // have an end key specified.
            return -byteOffset;
        }
    }
    // byte.
    if (bound == Bound.LOWER) {
        while (--i >= schemaStartIndex && offset > byteOffset && !(field = schema.getField(--fieldIndex)).getDataType().isFixedWidth() && field.getSortOrder() == SortOrder.ASC && key[offset - 1] == QueryConstants.SEPARATOR_BYTE) {
            offset--;
            fieldIndex -= slotSpan[i];
        }
    }
    return offset - byteOffset;
}
Also used : Field(org.apache.phoenix.schema.ValueSchema.Field) KeyRange(org.apache.phoenix.query.KeyRange)

Example 7 with Field

use of org.apache.phoenix.schema.ValueSchema.Field in project phoenix by apache.

the class IndexMaintainer method generateIndexRowKeySchema.

// We have enough information to generate the index row key schema
private RowKeySchema generateIndexRowKeySchema() {
    int nIndexedColumns = getIndexPkColumnCount() + (isMultiTenant ? 1 : 0) + (!isLocalIndex && nIndexSaltBuckets > 0 ? 1 : 0) + (viewIndexId != null ? 1 : 0) - getNumViewConstants();
    RowKeySchema.RowKeySchemaBuilder builder = new RowKeySchema.RowKeySchemaBuilder(nIndexedColumns);
    builder.rowKeyOrderOptimizable(rowKeyOrderOptimizable);
    if (!isLocalIndex && nIndexSaltBuckets > 0) {
        builder.addField(SaltingUtil.SALTING_COLUMN, false, SortOrder.ASC);
        nIndexedColumns--;
    }
    int dataPosOffset = isDataTableSalted ? 1 : 0;
    if (viewIndexId != null) {
        nIndexedColumns--;
        builder.addField(new PDatum() {

            @Override
            public boolean isNullable() {
                return false;
            }

            @Override
            public PDataType getDataType() {
                return MetaDataUtil.getViewIndexIdDataType();
            }

            @Override
            public Integer getMaxLength() {
                return null;
            }

            @Override
            public Integer getScale() {
                return null;
            }

            @Override
            public SortOrder getSortOrder() {
                return SortOrder.getDefault();
            }
        }, false, SortOrder.getDefault());
    }
    if (isMultiTenant) {
        Field field = dataRowKeySchema.getField(dataPosOffset++);
        builder.addField(field, field.isNullable(), field.getSortOrder());
        nIndexedColumns--;
    }
    Field[] indexFields = new Field[nIndexedColumns];
    BitSet viewConstantColumnBitSet = this.rowKeyMetaData.getViewConstantColumnBitSet();
    // Add Field for all data row pk columns
    for (int i = dataPosOffset; i < dataRowKeySchema.getFieldCount(); i++) {
        // same for all rows in this index)
        if (!viewConstantColumnBitSet.get(i)) {
            int pos = rowKeyMetaData.getIndexPkPosition(i - dataPosOffset);
            indexFields[pos] = dataRowKeySchema.getField(i);
        }
    }
    BitSet descIndexColumnBitSet = rowKeyMetaData.getDescIndexColumnBitSet();
    Iterator<Expression> expressionItr = indexedExpressions.iterator();
    for (int i = 0; i < indexFields.length; i++) {
        Field indexField = indexFields[i];
        PDataType dataTypeToBe;
        SortOrder sortOrderToBe;
        boolean isNullableToBe;
        Integer maxLengthToBe;
        Integer scaleToBe;
        if (indexField == null) {
            Expression e = expressionItr.next();
            isNullableToBe = e.isNullable();
            dataTypeToBe = IndexUtil.getIndexColumnDataType(isNullableToBe, e.getDataType());
            sortOrderToBe = descIndexColumnBitSet.get(i) ? SortOrder.DESC : SortOrder.ASC;
            maxLengthToBe = e.getMaxLength();
            scaleToBe = e.getScale();
        } else {
            isNullableToBe = indexField.isNullable();
            dataTypeToBe = IndexUtil.getIndexColumnDataType(isNullableToBe, indexField.getDataType());
            sortOrderToBe = descIndexColumnBitSet.get(i) ? SortOrder.DESC : SortOrder.ASC;
            maxLengthToBe = indexField.getMaxLength();
            scaleToBe = indexField.getScale();
        }
        final PDataType dataType = dataTypeToBe;
        final SortOrder sortOrder = sortOrderToBe;
        final boolean isNullable = isNullableToBe;
        final Integer maxLength = maxLengthToBe;
        final Integer scale = scaleToBe;
        builder.addField(new PDatum() {

            @Override
            public boolean isNullable() {
                return isNullable;
            }

            @Override
            public PDataType getDataType() {
                return dataType;
            }

            @Override
            public Integer getMaxLength() {
                return maxLength;
            }

            @Override
            public Integer getScale() {
                return scale;
            }

            @Override
            public SortOrder getSortOrder() {
                return sortOrder;
            }
        }, true, sortOrder);
    }
    return builder.build();
}
Also used : BitSet(org.apache.phoenix.util.BitSet) RowKeySchema(org.apache.phoenix.schema.RowKeySchema) SortOrder(org.apache.phoenix.schema.SortOrder) PDatum(org.apache.phoenix.schema.PDatum) Field(org.apache.phoenix.schema.ValueSchema.Field) PDataType(org.apache.phoenix.schema.types.PDataType) KeyValueColumnExpression(org.apache.phoenix.expression.KeyValueColumnExpression) SingleCellConstructorExpression(org.apache.phoenix.expression.SingleCellConstructorExpression) Expression(org.apache.phoenix.expression.Expression) SingleCellColumnExpression(org.apache.phoenix.expression.SingleCellColumnExpression) CoerceExpression(org.apache.phoenix.expression.CoerceExpression) LiteralExpression(org.apache.phoenix.expression.LiteralExpression)

Example 8 with Field

use of org.apache.phoenix.schema.ValueSchema.Field in project phoenix by apache.

the class IndexMaintainer method initCachedState.

/**
     * Init calculated state reading/creating
     */
private void initCachedState() {
    byte[] emptyKvQualifier = EncodedColumnsUtil.getEmptyKeyValueInfo(encodingScheme).getFirst();
    dataEmptyKeyValueRef = new ColumnReference(emptyKeyValueCFPtr.copyBytesIfNecessary(), emptyKvQualifier);
    this.allColumns = Sets.newLinkedHashSetWithExpectedSize(indexedExpressions.size() + coveredColumnsMap.size());
    // columns that are required to evaluate all expressions in indexedExpressions (not including columns in data row key)
    this.indexedColumns = Sets.newLinkedHashSetWithExpectedSize(indexedExpressions.size());
    for (Expression expression : indexedExpressions) {
        KeyValueExpressionVisitor visitor = new KeyValueExpressionVisitor() {

            @Override
            public Void visit(KeyValueColumnExpression expression) {
                if (indexedColumns.add(new ColumnReference(expression.getColumnFamily(), expression.getColumnQualifier()))) {
                    indexedColumnTypes.add(expression.getDataType());
                }
                return null;
            }
        };
        expression.accept(visitor);
    }
    allColumns.addAll(indexedColumns);
    for (ColumnReference colRef : coveredColumnsMap.keySet()) {
        if (immutableStorageScheme == ImmutableStorageScheme.ONE_CELL_PER_COLUMN) {
            allColumns.add(colRef);
        } else {
            allColumns.add(new ColumnReference(colRef.getFamily(), QueryConstants.SINGLE_KEYVALUE_COLUMN_QUALIFIER_BYTES));
        }
    }
    int dataPkOffset = (isDataTableSalted ? 1 : 0) + (isMultiTenant ? 1 : 0);
    int nIndexPkColumns = getIndexPkColumnCount();
    dataPkPosition = new int[nIndexPkColumns];
    Arrays.fill(dataPkPosition, EXPRESSION_NOT_PRESENT);
    int numViewConstantColumns = 0;
    BitSet viewConstantColumnBitSet = rowKeyMetaData.getViewConstantColumnBitSet();
    for (int i = dataPkOffset; i < dataRowKeySchema.getFieldCount(); i++) {
        if (!viewConstantColumnBitSet.get(i)) {
            int indexPkPosition = rowKeyMetaData.getIndexPkPosition(i - dataPkOffset);
            this.dataPkPosition[indexPkPosition] = i;
        } else {
            numViewConstantColumns++;
        }
    }
    // Calculate the max number of trailing nulls that we should get rid of after building the index row key.
    // We only get rid of nulls for variable length types, so we have to be careful to consider the type of the
    // index table, not the data type of the data table
    int expressionsPos = indexedExpressions.size();
    int indexPkPos = nIndexPkColumns - numViewConstantColumns - 1;
    while (indexPkPos >= 0) {
        int dataPkPos = dataPkPosition[indexPkPos];
        boolean isDataNullable;
        PDataType dataType;
        if (dataPkPos == EXPRESSION_NOT_PRESENT) {
            isDataNullable = true;
            dataType = indexedExpressions.get(--expressionsPos).getDataType();
        } else {
            Field dataField = dataRowKeySchema.getField(dataPkPos);
            dataType = dataField.getDataType();
            isDataNullable = dataField.isNullable();
        }
        PDataType indexDataType = IndexUtil.getIndexColumnDataType(isDataNullable, dataType);
        if (indexDataType.isFixedWidth()) {
            break;
        }
        indexPkPos--;
    }
    maxTrailingNulls = nIndexPkColumns - indexPkPos - 1;
}
Also used : Field(org.apache.phoenix.schema.ValueSchema.Field) PDataType(org.apache.phoenix.schema.types.PDataType) KeyValueColumnExpression(org.apache.phoenix.expression.KeyValueColumnExpression) SingleCellConstructorExpression(org.apache.phoenix.expression.SingleCellConstructorExpression) Expression(org.apache.phoenix.expression.Expression) SingleCellColumnExpression(org.apache.phoenix.expression.SingleCellColumnExpression) CoerceExpression(org.apache.phoenix.expression.CoerceExpression) LiteralExpression(org.apache.phoenix.expression.LiteralExpression) BitSet(org.apache.phoenix.util.BitSet) KeyValueColumnExpression(org.apache.phoenix.expression.KeyValueColumnExpression) KeyValueExpressionVisitor(org.apache.phoenix.expression.visitor.KeyValueExpressionVisitor) ColumnReference(org.apache.phoenix.hbase.index.covered.update.ColumnReference)

Example 9 with Field

use of org.apache.phoenix.schema.ValueSchema.Field in project phoenix by apache.

the class ScanUtil method nextKey.

private static byte[] nextKey(byte[] key, RowKeySchema schema, ImmutableBytesWritable ptr) {
    int pos = 0;
    int maxOffset = schema.iterator(key, ptr);
    while (schema.next(ptr, pos, maxOffset) != null) {
        pos++;
    }
    Field field = schema.getField(pos - 1);
    if (!field.getDataType().isFixedWidth()) {
        byte[] newLowerRange = new byte[key.length + 1];
        System.arraycopy(key, 0, newLowerRange, 0, key.length);
        newLowerRange[key.length] = SchemaUtil.getSeparatorByte(schema.rowKeyOrderOptimizable(), key.length == 0, field);
        key = newLowerRange;
    } else {
        key = Arrays.copyOf(key, key.length);
    }
    ByteUtil.nextKey(key, key.length);
    return key;
}
Also used : Field(org.apache.phoenix.schema.ValueSchema.Field)

Example 10 with Field

use of org.apache.phoenix.schema.ValueSchema.Field in project phoenix by apache.

the class ScanUtil method getKey.

private static byte[] getKey(RowKeySchema schema, List<List<KeyRange>> slots, int[] slotSpan, Bound bound) {
    if (slots.isEmpty()) {
        return KeyRange.UNBOUND;
    }
    int[] position = new int[slots.size()];
    int maxLength = 0;
    for (int i = 0; i < position.length; i++) {
        position[i] = bound == Bound.LOWER ? 0 : slots.get(i).size() - 1;
        KeyRange range = slots.get(i).get(position[i]);
        Field field = schema.getField(i + slotSpan[i]);
        int keyLength = range.getRange(bound).length;
        if (!field.getDataType().isFixedWidth()) {
            keyLength++;
            if (range.isUnbound(bound) && !range.isInclusive(bound) && field.getSortOrder() == SortOrder.DESC) {
                keyLength++;
            }
        }
        maxLength += keyLength;
    }
    byte[] key = new byte[maxLength];
    int length = setKey(schema, slots, slotSpan, position, bound, key, 0, 0, position.length);
    if (length == 0) {
        return KeyRange.UNBOUND;
    }
    if (length == maxLength) {
        return key;
    }
    byte[] keyCopy = new byte[length];
    System.arraycopy(key, 0, keyCopy, 0, length);
    return keyCopy;
}
Also used : Field(org.apache.phoenix.schema.ValueSchema.Field) KeyRange(org.apache.phoenix.query.KeyRange)

Aggregations

Field (org.apache.phoenix.schema.ValueSchema.Field)14 Expression (org.apache.phoenix.expression.Expression)6 RowKeySchema (org.apache.phoenix.schema.RowKeySchema)5 PDataType (org.apache.phoenix.schema.types.PDataType)5 ImmutableBytesWritable (org.apache.hadoop.hbase.io.ImmutableBytesWritable)4 CoerceExpression (org.apache.phoenix.expression.CoerceExpression)4 KeyValueColumnExpression (org.apache.phoenix.expression.KeyValueColumnExpression)4 LiteralExpression (org.apache.phoenix.expression.LiteralExpression)4 SingleCellColumnExpression (org.apache.phoenix.expression.SingleCellColumnExpression)4 KeyRange (org.apache.phoenix.query.KeyRange)4 SortOrder (org.apache.phoenix.schema.SortOrder)4 BitSet (org.apache.phoenix.util.BitSet)4 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 SingleCellConstructorExpression (org.apache.phoenix.expression.SingleCellConstructorExpression)3 DataOutput (java.io.DataOutput)2 DataOutputStream (java.io.DataOutputStream)2 List (java.util.List)2 TupleProjector (org.apache.phoenix.execute.TupleProjector)2 RowKeyColumnExpression (org.apache.phoenix.expression.RowKeyColumnExpression)2