Java Code Examples for org.apache.phoenix.query.QueryConstants#SEPARATOR_BYTE

The following examples show how to use org.apache.phoenix.query.QueryConstants#SEPARATOR_BYTE . 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: StatisticsUtil.java    From phoenix with Apache License 2.0 6 votes vote down vote up
public static byte[] getRowKey(byte[] table, ImmutableBytesWritable fam, ImmutableBytesWritable guidePostStartKey) {
    // always starts with the source table
    int guidePostLength = guidePostStartKey.getLength();
    boolean hasGuidePost = guidePostLength > 0;
    byte[] rowKey = new byte[table.length + fam.getLength() + guidePostLength + (hasGuidePost ? 2 : 1)];
    int offset = 0;
    System.arraycopy(table, 0, rowKey, offset, table.length);
    offset += table.length;
    rowKey[offset++] = QueryConstants.SEPARATOR_BYTE; // assumes stats table columns not DESC
    System.arraycopy(fam.get(), fam.getOffset(), rowKey, offset, fam.getLength());
    if (hasGuidePost) {
        offset += fam.getLength();
        rowKey[offset++] = QueryConstants.SEPARATOR_BYTE; // assumes stats table columns not DESC
        System.arraycopy(guidePostStartKey.get(), 0, rowKey, offset, guidePostLength);
    }
    return rowKey;
}
 
Example 2
Source File: ScanUtil.java    From phoenix with Apache License 2.0 6 votes vote down vote up
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++;
    }
    if (!schema.getField(pos-1).getDataType().isFixedWidth()) {
        byte[] newLowerRange = new byte[key.length + 1];
        System.arraycopy(key, 0, newLowerRange, 0, key.length);
        newLowerRange[key.length] = QueryConstants.SEPARATOR_BYTE;
        key = newLowerRange;
    } else {
        key = Arrays.copyOf(key, key.length);
    }
    ByteUtil.nextKey(key, key.length);
    return key;
}
 
Example 3
Source File: SchemaUtil.java    From phoenix with Apache License 2.0 5 votes vote down vote up
public static int getVarCharLength(byte[] buf, int keyOffset, int maxLength, int skipCount) {
    int length = 0;
    for (int i=0; i<skipCount; i++) {
        while (length < maxLength && buf[keyOffset+length] != QueryConstants.SEPARATOR_BYTE) {
            length++;
        }
        if (i != skipCount-1) { // skip over the separator if it's not the last one.
            length++;
        }
    }
    return length;
}
 
Example 4
Source File: StatisticsUtil.java    From phoenix with Apache License 2.0 5 votes vote down vote up
private static byte[] getKey(byte[] table, ImmutableBytesWritable fam, boolean terminateWithSeparator) {
    // always starts with the source table and column family
    byte[] rowKey = new byte[table.length + fam.getLength() + 1 + (terminateWithSeparator ? 1 : 0)];
    int offset = 0;
    System.arraycopy(table, 0, rowKey, offset, table.length);
    offset += table.length;
    rowKey[offset++] = QueryConstants.SEPARATOR_BYTE; // assumes stats table columns not DESC
    System.arraycopy(fam.get(), fam.getOffset(), rowKey, offset, fam.getLength());
    offset += fam.getLength();
    if (terminateWithSeparator) {
        rowKey[offset] = QueryConstants.SEPARATOR_BYTE;
    }
    return rowKey;
}
 
Example 5
Source File: PArrayDataType.java    From phoenix with Apache License 2.0 5 votes vote down vote up
private static void writeNewOffsets(byte[] arrayBytes, byte[] newArray, boolean useShortNew,
        boolean useShortPrevious, int newOffsetArrayPosition, int arrayLength, int offsetArrayPosition, int offset,
        int offsetShift, int length) {
    int currentPosition = newOffsetArrayPosition;
    int offsetArrayElementSize = useShortNew ? Bytes.SIZEOF_SHORT : Bytes.SIZEOF_INT;
    if (useShortNew) {
        Bytes.putShort(newArray, currentPosition, (short)(0 - Short.MAX_VALUE));
    } else {
        Bytes.putInt(newArray, currentPosition, 0);
    }

    currentPosition += offsetArrayElementSize;
    boolean nullsAtBeginning = true;
    byte serializationVersion = arrayBytes[offset + length - Bytes.SIZEOF_BYTE];
    for (int arrayIndex = 0; arrayIndex < arrayLength - 1; arrayIndex++) {
        int oldOffset = getOffset(arrayBytes, arrayIndex, useShortPrevious, offsetArrayPosition + offset, serializationVersion);
        if (arrayBytes[offset + oldOffset] == QueryConstants.SEPARATOR_BYTE && nullsAtBeginning) {
            if (useShortNew) {
                Bytes.putShort(newArray, currentPosition, (short)(oldOffset - Short.MAX_VALUE));
            } else {
                Bytes.putInt(newArray, currentPosition, oldOffset);
            }
        } else {
            if (useShortNew) {
                Bytes.putShort(newArray, currentPosition, (short)(oldOffset + offsetShift - Short.MAX_VALUE));
            } else {
                Bytes.putInt(newArray, currentPosition, oldOffset + offsetShift);
            }
            nullsAtBeginning = false;
        }
        currentPosition += offsetArrayElementSize;
    }

    Bytes.putInt(newArray, currentPosition, newOffsetArrayPosition);
    currentPosition += Bytes.SIZEOF_INT;
    Bytes.putInt(newArray, currentPosition, useShortNew ? arrayLength : -arrayLength);
    currentPosition += Bytes.SIZEOF_INT;
    Bytes.putByte(newArray, currentPosition, arrayBytes[offset + length - 1]);
}
 
Example 6
Source File: SchemaUtil.java    From phoenix with Apache License 2.0 5 votes vote down vote up
public static int getVarCharLength(byte[] buf, int keyOffset, int maxLength, int skipCount) {
    int length = 0;
    for (int i=0; i<skipCount; i++) {
        while (length < maxLength && buf[keyOffset+length] != QueryConstants.SEPARATOR_BYTE) {
            length++;
        }
        if (i != skipCount-1) { // skip over the separator if it's not the last one.
            length++;
        }
    }
    return length;
}
 
Example 7
Source File: PDataTypeForArraysTest.java    From phoenix with Apache License 2.0 5 votes vote down vote up
@Test
public void testIsRowKeyOrderOptimized3() {
    Object[] objects = new Object[]{"a", "b", "c"};
    PhoenixArray arr = new PhoenixArray(PVarchar.INSTANCE, objects);
    byte[] bytes = PVarcharArray.INSTANCE.toBytes(arr, SortOrder.DESC);
    for (int i = 0; i < bytes.length; i++) {
        if (bytes[i] == QueryConstants.DESC_SEPARATOR_BYTE) {
            bytes[i] = QueryConstants.SEPARATOR_BYTE;
        }
    }
    assertFalse(PArrayDataType.isRowKeyOrderOptimized(PVarcharArray.INSTANCE, SortOrder.DESC, bytes, 0, bytes.length));
}
 
Example 8
Source File: SkipScanFilter.java    From phoenix with Apache License 2.0 5 votes vote down vote up
private int setStartKey(ImmutableBytesWritable ptr, int offset, int i) {
    int length = ptr.getOffset() - offset;
    startKey = copyKey(startKey, length + this.maxKeyLength, ptr.get(), offset, length);
    startKeyLength = length;
    // Add separator byte if we're at the end of the buffer, since trailing separator bytes are stripped
    if (ptr.getOffset() + ptr.getLength() == offset + length && i-1 > 0 && !schema.getField(i-1).getDataType().isFixedWidth()) {
        startKey[startKeyLength++] = QueryConstants.SEPARATOR_BYTE;
    }
    startKeyLength += setKey(Bound.LOWER, startKey, startKeyLength, i);
    return length;
}
 
Example 9
Source File: StatisticsUtil.java    From phoenix with Apache License 2.0 5 votes vote down vote up
public static byte[] getRowKey(byte[] table, ImmutableBytesPtr fam, byte[] region) {
    // always starts with the source table
    byte[] rowKey = new byte[table.length + fam.getLength() + region.length + 2];
    int offset = 0;
    System.arraycopy(table, 0, rowKey, offset, table.length);
    offset += table.length;
    rowKey[offset++] = QueryConstants.SEPARATOR_BYTE;
    System.arraycopy(fam.get(), fam.getOffset(), rowKey, offset, fam.getLength());
    offset += fam.getLength();
    rowKey[offset++] = QueryConstants.SEPARATOR_BYTE;
    System.arraycopy(region, 0, rowKey, offset, region.length);
    return rowKey;
}
 
Example 10
Source File: RowKeySchema.java    From phoenix with Apache License 2.0 4 votes vote down vote up
@edu.umd.cs.findbugs.annotations.SuppressWarnings(
        value="NP_BOOLEAN_RETURN_NULL", 
        justification="Designed to return null.")
public Boolean previous(ImmutableBytesWritable ptr, int position, int minOffset) {
    if (position < 0) {
        return null;
    }
    Field field = this.getField(position);
    if (field.getDataType().isFixedWidth()) {
        ptr.set(ptr.get(), ptr.getOffset()-field.getByteSize(), field.getByteSize());
        return true;
    }
    // If ptr has length of zero, it is assumed that we're at the end of the row key
    int offsetAdjustment = position + 1 == this.getFieldCount() || ptr.getLength() == 0 ? 0 : 1;
    if (position == 0) {
        ptr.set(ptr.get(), minOffset, ptr.getOffset() - minOffset - offsetAdjustment);
        return true;
    }
    field = this.getField(position-1);
    // Field before the one we want to position at is variable length
    // In this case, we can search backwards for our separator byte
    // to determine the length
    if (!field.getDataType().isFixedWidth()) {
        byte[] buf = ptr.get();
        int offset = ptr.getOffset()-1-offsetAdjustment;
        // Separator always zero byte if zero length
        if (offset > minOffset && buf[offset] != QueryConstants.SEPARATOR_BYTE) {
            byte sepByte = SchemaUtil.getSeparatorByte(rowKeyOrderOptimizable, false, field);
            do {
                offset--;
            } while (offset > minOffset && buf[offset] != sepByte);
        }
        if (offset == minOffset) { // shouldn't happen
            ptr.set(buf, minOffset, ptr.getOffset()-minOffset-1);
        } else {
            ptr.set(buf,offset+1,ptr.getOffset()-1-offsetAdjustment-offset); // Don't include null terminator in length
        }
        return true;
    }
    int i,fixedOffset = field.getByteSize();
    for (i = position-2; i >= 0 && this.getField(i).getDataType().isFixedWidth(); i--) {
        fixedOffset += this.getField(i).getByteSize();
    }
    // All of the previous fields are fixed width, so we can calculate the offset
    // based on the total fixed offset
    if (i < 0) {
        int length = ptr.getOffset() - fixedOffset - minOffset - offsetAdjustment;
        ptr.set(ptr.get(),minOffset+fixedOffset, length);
        return true;
    }
    // Otherwise we're stuck with starting from the minOffset and working all the way forward,
    // because we can't infer the length of the previous position.
    return iterator(ptr.get(), minOffset, ptr.getOffset() - minOffset - offsetAdjustment, ptr, position+1);
}
 
Example 11
Source File: SystemCatalogWALEntryFilter.java    From phoenix with Apache License 2.0 4 votes vote down vote up
private boolean isTenantRowCell(Cell cell) {
  ImmutableBytesWritable key =
      new ImmutableBytesWritable(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
  //rows in system.catalog that aren't tenant-owned will have a leading separator byte
  return key.get()[key.getOffset()] != QueryConstants.SEPARATOR_BYTE;
}
 
Example 12
Source File: WhereOptimizer.java    From phoenix with Apache License 2.0 4 votes vote down vote up
@Override
public KeySlots visitLeave(LikeExpression node, List<KeySlots> childParts) {
    // TODO: optimize ILIKE by creating two ranges for the literal prefix: one with lower case, one with upper case
    if (childParts.isEmpty()) {
        return null;
    }
    // for SUBSTR(<column>,1,3) LIKE 'foo%'
    KeySlots childSlots = childParts.get(0);
    KeySlot childSlot = childSlots.getSlots().get(0);
    final String startsWith = node.getLiteralPrefix();
    SortOrder sortOrder = node.getChildren().get(0).getSortOrder();
    byte[] key = PVarchar.INSTANCE.toBytes(startsWith, sortOrder);
    // If the expression is an equality expression against a fixed length column
    // and the key length doesn't match the column length, the expression can
    // never be true.
    // An zero length byte literal is null which can never be compared against as true
    Expression firstChild = node.getChildren().get(0);
    Integer childNodeFixedLength = firstChild.getDataType().isFixedWidth() ? firstChild.getMaxLength() : null;
    if (childNodeFixedLength != null && key.length > childNodeFixedLength) {
        return EMPTY_KEY_SLOTS;
    }
    // TODO: is there a case where we'd need to go through the childPart to calculate the key range?
    PColumn column = childSlot.getKeyPart().getColumn();
    PDataType type = column.getDataType();
    byte[] lowerRange = key;
    byte[] upperRange = ByteUtil.nextKey(key);
    Integer columnFixedLength = column.getMaxLength();
    if (type.isFixedWidth()) {
        if (columnFixedLength != null) { // Sanity check - should always be non null
            // Always use minimum byte to fill as otherwise our key is bigger
            // that it should be when the sort order is descending.
            lowerRange = type.pad(lowerRange, columnFixedLength, SortOrder.ASC);
            upperRange = type.pad(upperRange, columnFixedLength, SortOrder.ASC);
        }
    } else if (column.getSortOrder() == SortOrder.DESC && table.rowKeyOrderOptimizable()) {
        // Append a zero byte if descending since a \xFF byte will be appended to the lowerRange
        // causing rows to be skipped that should be included. For example, with rows 'ab', 'a',
        // a lowerRange of 'a\xFF' would skip 'ab', while 'a\x00\xFF' would not.
        lowerRange = Arrays.copyOf(lowerRange, lowerRange.length+1);
        lowerRange[lowerRange.length-1] = QueryConstants.SEPARATOR_BYTE;
    }
    KeyRange range = type.getKeyRange(lowerRange, true, upperRange, false);
    if (column.getSortOrder() == SortOrder.DESC) {
        range = range.invert();
    }
    // Only extract LIKE expression if pattern ends with a wildcard and everything else was extracted
    return newKeyParts(childSlot, node.endsWithOnlyWildcard() ? node : null, range);
}
 
Example 13
Source File: PrefixFunction.java    From phoenix with Apache License 2.0 4 votes vote down vote up
@Override
public KeyRange getKeyRange(CompareOp op, Expression rhs) {
    byte[] lowerRange = KeyRange.UNBOUND;
    byte[] upperRange = KeyRange.UNBOUND;
    boolean lowerInclusive = true;
    PDataType type = getColumn().getDataType();
    switch (op) {
        case EQUAL:
            lowerRange = evaluateExpression(rhs);
            upperRange = ByteUtil.nextKey(lowerRange);
            break;
        case GREATER:
            lowerRange = ByteUtil.nextKey(evaluateExpression(rhs));
            break;
        case LESS_OR_EQUAL:
            upperRange = ByteUtil.nextKey(evaluateExpression(rhs));
            lowerInclusive = false;
            break;
        default:
            return childPart.getKeyRange(op, rhs);
    }
    PColumn column = getColumn();
    Integer length = column.getMaxLength();
    if (type.isFixedWidth()) {
        if (length != null) { // Sanity check - shouldn't be necessary
            // Don't pad based on current sort order, but instead use our
            // minimum byte as otherwise we'll end up skipping rows in
            // the case of descending, since rows with more padding appear
            // *after* rows with no padding.
            if (lowerRange != KeyRange.UNBOUND) {
                lowerRange = type.pad(lowerRange, length, SortOrder.ASC);
            }
            if (upperRange != KeyRange.UNBOUND) {
                upperRange = type.pad(upperRange, length, SortOrder.ASC);
            }
        }
    } else if (column.getSortOrder() == SortOrder.DESC && getTable().rowKeyOrderOptimizable()) {
        // Append a zero byte if descending since a \xFF byte will be appended to the lowerRange
        // causing rows to be skipped that should be included. For example, with rows 'ab', 'a',
        // a lowerRange of 'a\xFF' would skip 'ab', while 'a\x00\xFF' would not.
        if (lowerRange != KeyRange.UNBOUND) {
            lowerRange = Arrays.copyOf(lowerRange, lowerRange.length+1);
            lowerRange[lowerRange.length-1] = QueryConstants.SEPARATOR_BYTE;
        }
    }
    KeyRange range = KeyRange.getKeyRange(lowerRange, lowerInclusive, upperRange, false);
    if (column.getSortOrder() == SortOrder.DESC) {
        range = range.invert();
    }
    return range;
}
 
Example 14
Source File: PArrayDataType.java    From phoenix with Apache License 2.0 4 votes vote down vote up
public static void positionAtArrayElement(ImmutableBytesWritable ptr, int arrayIndex, PDataType baseDataType,
    Integer byteSize, int offset, int length, int noOfElements, boolean first) {
    byte[] bytes = ptr.get();
    if (!baseDataType.isFixedWidth()) {
        int indexOffset = Bytes.toInt(bytes, (offset + length - (Bytes.SIZEOF_BYTE + 2 * Bytes.SIZEOF_INT)))
                + offset;
        boolean useShort = true;
        if (first) {
            int count = Bytes.toInt(bytes,
                    (ptr.getOffset() + ptr.getLength() - (Bytes.SIZEOF_BYTE + Bytes.SIZEOF_INT)), Bytes.SIZEOF_INT);
            if (count < 0) {
                count = -count;
                useShort = false;
            }
        }
        if (arrayIndex >= noOfElements) {
            return;
        } else {
            // Skip those many offsets as given in the arrayIndex
            // If suppose there are 5 elements in the array and the arrayIndex = 3
            // This means we need to read the 4th element of the array
            // So inorder to know the length of the 4th element we will read the offset of 4th element and the
            // offset of 5th element.
            // Subtracting the offset of 5th element and 4th element will give the length of 4th element
            // So we could just skip reading the other elements.
            int currOffset = getOffset(bytes, arrayIndex, useShort, indexOffset);
            int elementLength = 0;
            if (arrayIndex == (noOfElements - 1)) {
                elementLength = bytes[currOffset + offset] == QueryConstants.SEPARATOR_BYTE ? 0 : indexOffset
                        - (currOffset + offset) - 3;
            } else {
                elementLength = bytes[currOffset + offset] == QueryConstants.SEPARATOR_BYTE ? 0 : getOffset(bytes,
                        arrayIndex + 1, useShort, indexOffset) - currOffset - 1;
            }
            ptr.set(bytes, currOffset + offset, elementLength);
        }
    } else {
        int elemByteSize = (byteSize == null ? baseDataType.getByteSize() : byteSize);
        offset += arrayIndex * elemByteSize;
        if (offset >= offset + length) {
            return;
        } else {
            ptr.set(bytes, offset, elemByteSize);
        }
    }
}
 
Example 15
Source File: RowKeyValueAccessor.java    From phoenix with Apache License 2.0 4 votes vote down vote up
private static boolean isSeparatorByte(byte b) {
    return b == QueryConstants.SEPARATOR_BYTE || b == QueryConstants.DESC_SEPARATOR_BYTE;
}
 
Example 16
Source File: PArrayDataType.java    From phoenix with Apache License 2.0 4 votes vote down vote up
public static void positionAtArrayElement(ImmutableBytesWritable ptr, int arrayIndex, PDataType baseDataType,
    Integer byteSize) {
    byte[] bytes = ptr.get();
    int initPos = ptr.getOffset();
    if (!baseDataType.isFixedWidth()) {
        int noOfElements = Bytes.toInt(bytes, (ptr.getOffset() + ptr.getLength() - (Bytes.SIZEOF_BYTE + Bytes.SIZEOF_INT)),
                Bytes.SIZEOF_INT);
        boolean useShort = true;
        if (noOfElements < 0) {
            noOfElements = -noOfElements;
            useShort = false;
        }
        if (arrayIndex >= noOfElements) {
            ptr.set(ByteUtil.EMPTY_BYTE_ARRAY);
            return;
        }

        int indexOffset = Bytes.toInt(bytes,
                (ptr.getOffset() + ptr.getLength() - (Bytes.SIZEOF_BYTE + 2 * Bytes.SIZEOF_INT))) + ptr.getOffset();
        if(arrayIndex >= noOfElements) {
            ptr.set(ByteUtil.EMPTY_BYTE_ARRAY);
        } else {
            // Skip those many offsets as given in the arrayIndex
            // If suppose there are 5 elements in the array and the arrayIndex = 3
            // This means we need to read the 4th element of the array
            // So inorder to know the length of the 4th element we will read the offset of 4th element and the
            // offset of 5th element.
            // Subtracting the offset of 5th element and 4th element will give the length of 4th element
            // So we could just skip reading the other elements.
            int currOffset = getOffset(bytes, arrayIndex, useShort, indexOffset);
            int elementLength = 0;
            if (arrayIndex == (noOfElements - 1)) {
                elementLength = bytes[currOffset + initPos] == QueryConstants.SEPARATOR_BYTE ? 0 : indexOffset
                        - (currOffset + initPos) - 3;
            } else {
                elementLength = bytes[currOffset + initPos] == QueryConstants.SEPARATOR_BYTE ? 0 : getOffset(bytes,
                        arrayIndex + 1, useShort, indexOffset) - currOffset - 1;
            }
            ptr.set(bytes, currOffset + initPos, elementLength);
        }
    } else {
        int elemByteSize = (byteSize == null ? baseDataType.getByteSize() : byteSize);
        int offset = arrayIndex * elemByteSize;
        if (offset >= ptr.getLength()) {
            ptr.set(ByteUtil.EMPTY_BYTE_ARRAY);
        } else {
            ptr.set(bytes, ptr.getOffset() + offset, elemByteSize);
        }
    }
}
 
Example 17
Source File: PArrayDataTypeDecoder.java    From phoenix with Apache License 2.0 4 votes vote down vote up
private static boolean isSeparatorByte(byte[] bytes, int initPos, int currOffset) {
    return bytes[currOffset + initPos] == QueryConstants.SEPARATOR_BYTE || bytes[currOffset + initPos] == QueryConstants.DESC_SEPARATOR_BYTE;
}
 
Example 18
Source File: ScanUtil.java    From phoenix with Apache License 2.0 4 votes vote down vote up
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;
    // 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
    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
        boolean isFixedWidth = schema.getField(fieldIndex + slotSpan[i]).getDataType().isFixedWidth();
        fieldIndex += slotSpan[i] + 1;
        /*
         * 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.
         */
        if (  range.isUnbound(bound) &&
            ( bound == Bound.UPPER || isFixedWidth) ){
            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.isInclusive(bound) && bound == Bound.UPPER;
        boolean exclusiveLower = !range.isInclusive(bound) && bound == Bound.LOWER;
        // 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;
        
        if (!isFixedWidth && ( fieldIndex < schema.getMaxFields() || inclusiveUpper || exclusiveLower)) {
            key[offset++] = QueryConstants.SEPARATOR_BYTE;
            // 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 we are setting the lower bound with an exclusive range key, we need to bump the
        // slot up for each key part. For an upper bound, we bump up an inclusive key, but
        // only after the last key part.
        if (!range.isSingleKey() && exclusiveLower) {
            if (!ByteUtil.nextKey(key, offset)) {
                // Special case for not being able to increment.
                // In this case we return a negative byteOffset to
                // remove this part from the key being formed. Since the
                // key has overflowed, this means that we should not
                // have an end key specified.
                return -byteOffset;
            }
        }
    }
    if (lastInclusiveUpperSingleKey || anyInclusiveUpperRangeKey) {
        if (!ByteUtil.nextKey(key, offset)) {
            // Special case for not being able to increment.
            // In this case we return a negative byteOffset to
            // remove this part from the key being formed. Since the
            // key has overflowed, this means that we should not
            // have an end key specified.
            return -byteOffset;
        }
    }
    // Remove trailing separator bytes, since the columns may have been added
    // after the table has data, in which case there won't be a separator
    // byte.
    if (bound == Bound.LOWER) {
        while (--i >= schemaStartIndex && offset > byteOffset && 
                !schema.getField(--fieldIndex).getDataType().isFixedWidth() && 
                key[offset-1] == QueryConstants.SEPARATOR_BYTE) {
            offset--;
            fieldIndex -= slotSpan[i];
        }
    }
    return offset - byteOffset;
}
 
Example 19
Source File: RowValueConstructorExpression.java    From phoenix with Apache License 2.0 4 votes vote down vote up
@Override
public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
    if(literalExprPtr != null) {
        // if determined during construction that the row value constructor is just comprised of literal expressions, 
        // let's just return the ptr we have already computed and be done with evaluation.
        ptr.set(literalExprPtr.get(), literalExprPtr.getOffset(), literalExprPtr.getLength());
        return true;
    }
    try {
        int j;
        int expressionCount = counter;
        for(j = counter; j < ptrs.length; j++) {
            final Expression expression = children.get(j);
            // TODO: handle overflow and underflow
            if (expression.evaluate(tuple, ptr)) {
                if (ptr.getLength() == 0) {
                    estimatedByteSize += getExpressionByteCount(expression);
                } else {
                    expressionCount = j+1;
                    ptrs[j] = new ImmutableBytesWritable();
                    ptrs[j].set(ptr.get(), ptr.getOffset(), ptr.getLength());
                    estimatedByteSize += ptr.getLength() + (expression.getDataType().isFixedWidth() ? 0 : 1); // 1 extra for the separator byte.
                }
                counter++;
            } else if (tuple == null || tuple.isImmutable()) {
                estimatedByteSize += getExpressionByteCount(expression);
                counter++;
            } else {
                return false;
            }
        }
        
        if (j == ptrs.length) {
            if (expressionCount == 0) {
                ptr.set(ByteUtil.EMPTY_BYTE_ARRAY);
                return true;
            }
            if (expressionCount == 1) {
                ptr.set(ptrs[0].get(), ptrs[0].getOffset(), ptrs[0].getLength());
                return true;
            }
            TrustedByteArrayOutputStream output = new TrustedByteArrayOutputStream(estimatedByteSize);
            try {
                boolean previousCarryOver = false;
                for (int i = 0; i< expressionCount; i++) {
                    Expression child = getChildren().get(i);
                    PDataType childType = child.getDataType();
                    ImmutableBytesWritable tempPtr = ptrs[i];
                    if (tempPtr == null) {
                        // Since we have a null and have no representation for null,
                        // we must decrement the value of the current. Otherwise,
                        // we'd have an ambiguity if this value happened to be the
                        // min possible value.
                        previousCarryOver = childType == null || childType.isFixedWidth();
                        int bytesToWrite = getExpressionByteCount(child);
                        for (int m = 0; m < bytesToWrite; m++) {
                            output.write(QueryConstants.SEPARATOR_BYTE);
                        }
                    } else {
                        output.write(tempPtr.get(), tempPtr.getOffset(), tempPtr.getLength());
                        if (!childType.isFixedWidth()) {
                            output.write(QueryConstants.SEPARATOR_BYTE);
                        }
                        if (previousCarryOver) {
                            previousCarryOver = !ByteUtil.previousKey(output.getBuffer(), output.size());
                        }
                    }
                }
                int outputSize = output.size();
                byte[] outputBytes = output.getBuffer();
                for (int k = expressionCount -1 ; 
                        k >=0 &&  getChildren().get(k).getDataType() != null && !getChildren().get(k).getDataType().isFixedWidth() && outputBytes[outputSize-1] == QueryConstants.SEPARATOR_BYTE ; k--) {
                    outputSize--;
                }
                ptr.set(outputBytes, 0, outputSize);
                return true;
            } finally {
                output.close();
            }
        }  
        return false;
    } catch (IOException e) {
        throw new RuntimeException(e); //Impossible.
    }
}
 
Example 20
Source File: RowKeySchema.java    From phoenix with Apache License 2.0 4 votes vote down vote up
@edu.umd.cs.findbugs.annotations.SuppressWarnings(
        value="NP_BOOLEAN_RETURN_NULL", 
        justification="Designed to return null.")
private Boolean next(ImmutableBytesWritable ptr, int position, int maxOffset, boolean isFirst) {
    if (ptr.getOffset() + ptr.getLength() >= maxOffset) {
        ptr.set(ptr.get(), maxOffset, 0);
        return null;
    }
    if (position >= getFieldCount()) {
        return null;
    }
    // Move the pointer past the current value and set length
    // to 0 to ensure you never set the ptr past the end of the
    // backing byte array.
    ptr.set(ptr.get(), ptr.getOffset() + ptr.getLength(), 0);
    // If positioned at SEPARATOR_BYTE, skip it.
    // Don't look back at previous fields if this is our first next call, as
    // we may have a partial key for RVCs that doesn't include the leading field.
    if (position > 0 && !isFirst && !getField(position-1).getDataType().isFixedWidth()) {
        ptr.set(ptr.get(), ptr.getOffset()+ptr.getLength()+1, 0);
    }
    Field field = this.getField(position);
    if (field.getDataType().isFixedWidth()) {
        // 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
            int len = maxOffset - ptr.getOffset();
            ptr.set(ptr.get(), ptr.getOffset(), maxOffset - ptr.getOffset() - (SchemaUtil.getSeparatorByte(rowKeyOrderOptimizable, len == 0, field) == QueryConstants.DESC_SEPARATOR_BYTE ? 1 : 0));
        } else {
            byte[] buf = ptr.get();
            int offset = ptr.getOffset();
            // First byte 
            if (offset < maxOffset && buf[offset] != QueryConstants.SEPARATOR_BYTE) {
                byte sepByte = SchemaUtil.getSeparatorByte(rowKeyOrderOptimizable, false, field);
                do {
                    offset++;
                } while (offset < maxOffset && buf[offset] != sepByte);
            }
            ptr.set(buf, ptr.getOffset(), offset - ptr.getOffset());
        }
    }
    return ptr.getLength() > 0;
}