public Object getSampleValue(PDataType baseType, Integer arrayLength, Integer elemLength) { Preconditions.checkArgument(arrayLength == null || arrayLength >= 0); if (arrayLength == null) { arrayLength = 1; } Object[] array = new Object[arrayLength]; for (int i = 0; i < arrayLength; i++) { array[i] = baseType.getSampleValue(elemLength, arrayLength); } return instantiatePhoenixArray(baseType, array); }
public byte[] toBytes(Object object, PDataType baseType, SortOrder sortOrder) { return toBytes(object, baseType, sortOrder, true); }
@Override public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) { Expression arrayExpr = children.get(0); if (!arrayExpr.evaluate(tuple, ptr)) { return false; } else if (ptr.getLength() == 0) { return true; } PDataType baseType = PDataType.fromTypeId(children.get(0).getDataType() .getSqlType() - PDataType.ARRAY_TYPE_BASE); int length = Math.abs(PArrayDataType.getArrayLength(ptr, baseType, arrayExpr.getMaxLength())); byte[] lengthBuf = new byte[PInteger.INSTANCE.getByteSize()]; PInteger.INSTANCE.getCodec().encodeInt(length, lengthBuf, 0); ptr.set(lengthBuf); return true; }
@Override public Object toObject(Object object, PDataType actualType) { return toPhoenixArray(object, arrayBaseType(actualType)); }
@Override protected boolean modifierFunction(ImmutableBytesWritable ptr, int len, int offset, byte[] array1Bytes, PDataType baseDataType, int actualLengthOfArray1, Integer maxLength, Expression array1Exp) { int actualLengthOfArray2 = Math.abs(PArrayDataType.getArrayLength(ptr, baseDataType, array1Exp.getMaxLength())); // FIXME: concatArrays will be fine if it's copying the separator bytes, including the terminating bytes. return PArrayDataType.concatArrays(ptr, len, offset, array1Bytes, baseDataType, actualLengthOfArray1, actualLengthOfArray2); }
arrayBytes = generateEmptyArrayBytes(baseType, sortOrder); offset = 0; length = arrayBytes.length; int endElementPosition = getOffset(arrayBytes, arrayLength - 1, !useInt, offsetArrayPosition + offset, serializationVersion) + elementLength + Bytes.SIZEOF_BYTE; int newOffsetArrayPosition; int currOffset = getOffset(arrayBytes, index, !useInt, offsetArrayPosition + offset, serializationVersion); if (arrayBytes[offset + currOffset] == QueryConstants.SEPARATOR_BYTE) { nulls++; endElementPosition = getOffset(arrayBytes, arrayLength - 1, !useInt, offsetArrayPosition + offset, serializationVersion) + lengthIncrease; if (!useInt) { if (PArrayDataType.useShortForOffsetArray(endElementPosition)) { newArray = new byte[length + Bytes.SIZEOF_SHORT + lengthIncrease]; } else { currentPosition = serializeNulls(newArray, currentPosition, nulls); } else { if (!useInt) { if (PArrayDataType.useShortForOffsetArray(endElementPosition)) { newArray = new byte[length + elementLength + Bytes.SIZEOF_SHORT + Bytes.SIZEOF_BYTE]; } else { newArray[elementLength] = getSeparatorByte(isRowKeyOrderOptimized(false, sortOrder, arrayBytes, offset, length), sortOrder); currentPosition += elementLength + Bytes.SIZEOF_BYTE;
arrayBytes = generateEmptyArrayBytes(baseType, sortOrder); offset = 0; length = arrayBytes.length; if (PArrayDataType.useShortForOffsetArray(newElementPosition)) { newArray = new byte[length + elementLength + Bytes.SIZEOF_SHORT + Bytes.SIZEOF_BYTE]; } else { byte sepByte = getSeparatorByte(isRowKeyOrderOptimized(false, sortOrder, arrayBytes, offset, length), sortOrder); newArray[newOffsetArrayPosition-3] = sepByte; // Separator for new value newArray[newOffsetArrayPosition-2] = sepByte; // Double byte separator Bytes.putInt(newArray, newOffsetArrayPosition + offsetArrayLength, newElementPosition); writeEndBytes(newArray, newOffsetArrayPosition, offsetArrayLength, arrayLength, arrayBytes[offset + length - 1], true); } else { (short)(newElementPosition - Short.MAX_VALUE)); writeEndBytes(newArray, newOffsetArrayPosition, offsetArrayLength, arrayLength, arrayBytes[offset + length - 1], false); } else { for (int arrayIndex = 0; arrayIndex < Math.abs(arrayLength) - 1; arrayIndex++) { Bytes.putInt(newArray, off, getOffset(arrayBytes, arrayIndex, true, offsetArrayPosition + offset, serializationVersion)); off += Bytes.SIZEOF_INT;
&& baseType.isFixedWidth() == desiredBaseType.isFixedWidth() && actualSortOrder == desiredSortOrder && (desiredSortOrder == SortOrder.ASC || desiredBaseType.isFixedWidth() || isRowKeyOrderOptimized(actualType, actualSortOrder, ptr) == expectedRowKeyOrderOptimizable)) { return; value = toObject(ptr.get(), ptr.getOffset(), ptr.getLength(), baseType, actualSortOrder, maxLength, desiredScale, desiredBaseType); pArr = (PhoenixArray)value; ptr.set(toBytes(pArr, baseType, desiredSortOrder, expectedRowKeyOrderOptimizable));
PArrayDataType.isRowKeyOrderOptimized(this, lhsSortOrder, lhs, lhsOffset, lhsLength) == PArrayDataType.isRowKeyOrderOptimized(rhsType, rhsSortOrder, rhs, rhsOffset, rhsLength)) { if ( this.isArrayType() && PArrayDataType.isRowKeyOrderOptimized(this, lhsSortOrder, lhs, lhsOffset, lhsLength) == PArrayDataType.isRowKeyOrderOptimized(rhsType, rhsSortOrder, rhs, rhsOffset, rhsLength)) { rhsConverted = ((PArrayDataType)this).toBytes(o, PArrayDataType.arrayBaseType(this), lhsSortOrder, PArrayDataType.isRowKeyOrderOptimized(this, lhsSortOrder, lhs, lhsOffset, lhsLength)); } else { rhsConverted = this.toBytes(o); if ( rhsType.isArrayType() && PArrayDataType.isRowKeyOrderOptimized(rhsType, rhsSortOrder, rhs, rhsOffset, rhsLength) == PArrayDataType.isRowKeyOrderOptimized(this, lhsSortOrder, lhs, lhsOffset, lhsLength)) { lhsConverted = ((PArrayDataType)rhsType).toBytes(o, PArrayDataType.arrayBaseType(rhsType), rhsSortOrder, PArrayDataType.isRowKeyOrderOptimized(rhsType, rhsSortOrder, rhs, rhsOffset, rhsLength)); } else { lhsConverted = rhsType.toBytes(o);
public byte[] toBytes(Object object, PDataType baseType, SortOrder sortOrder, boolean rowKeyOrderOptimizable) { if (object == null) { throw new ConstraintViolationException(this + " may not be null"); } PhoenixArray arr = toPhoenixArray(object, baseType); int noOfElements = arr.numElements; if (noOfElements == 0) { return ByteUtil.EMPTY_BYTE_ARRAY; } TrustedByteArrayOutputStream byteStream = null; if (!baseType.isFixedWidth()) { Pair<Integer, Integer> nullsVsNullRepeationCounter = new Pair<>(); int size = estimateByteSize(object, nullsVsNullRepeationCounter, PDataType.fromTypeId((baseType.getSqlType() + PDataType.ARRAY_TYPE_BASE))); size += ((2 * Bytes.SIZEOF_BYTE) + (noOfElements - nullsVsNullRepeationCounter.getFirst()) * Bytes.SIZEOF_BYTE) + (nullsVsNullRepeationCounter.getSecond() * 2 * Bytes.SIZEOF_BYTE); // Assume an offset array that fit into Short.MAX_VALUE. Also not considering nulls that could be > 255 // In both of these cases, finally an array copy would happen int capacity = noOfElements * Bytes.SIZEOF_SHORT; // Here the int for noofelements, byte for the version, int for the offsetarray position and 2 bytes for the // end seperator byteStream = new TrustedByteArrayOutputStream(size + capacity + Bytes.SIZEOF_INT + Bytes.SIZEOF_BYTE + Bytes.SIZEOF_INT); } else { int elemLength = (arr.getMaxLength() == null ? baseType.getByteSize() : arr.getMaxLength()); int size = elemLength * noOfElements; // Here the int for noofelements, byte for the version byteStream = new TrustedByteArrayOutputStream(size); } DataOutputStream oStream = new DataOutputStream(byteStream); // Handles bit inversion also return createArrayBytes(byteStream, oStream, arr, noOfElements, baseType, sortOrder, rowKeyOrderOptimizable); }
return false; boolean isLHSRowKeyOrderOptimized = PArrayDataType.isRowKeyOrderOptimized(getLHSExpr().getDataType(), getLHSExpr().getSortOrder(), ptr); int actualLengthOfArray1 = Math.abs(PArrayDataType.getArrayLength(ptr, getLHSBaseType(), getLHSExpr().getMaxLength())); int lengthArray1 = ptr.getLength(); int offsetArray1 = ptr.getOffset();
throw TypeMismatchException.newException(type, actualType, value.toString()); byte[] b = type.isArrayType() ? ((PArrayDataType)type).toBytes(value, PArrayDataType.arrayBaseType(type), sortOrder, rowKeyOrderOptimizable) : type.toBytes(value, sortOrder); if (type == PVarchar.INSTANCE || type == PChar.INSTANCE) {
public static boolean isRowKeyOrderOptimized(PDataType type, SortOrder sortOrder, byte[] buf, int offset, int length) { PDataType baseType = PDataType.fromTypeId(type.getSqlType() - PDataType.ARRAY_TYPE_BASE); return isRowKeyOrderOptimized(baseType.isFixedWidth(), sortOrder, buf, offset, length); }
@Test public void testGetArrayLengthForVariableLengthArray() { String[] strArr = new String[5]; strArr[0] = "abx"; strArr[1] = "ereref"; strArr[2] = "random"; strArr[3] = "random12"; strArr[4] = "ranzzz"; PhoenixArray arr = PArrayDataType.instantiatePhoenixArray( PVarchar.INSTANCE, strArr); byte[] bytes = PVarcharArray.INSTANCE.toBytes(arr); ImmutableBytesWritable ptr = new ImmutableBytesWritable(bytes); int result = PArrayDataType.getArrayLength(ptr, PVarchar.INSTANCE, null); assertEquals(5, result); }
private List<Tuple> toTuples(PArrayDataType arrayType, List<Object[]> arrays) { List<Tuple> tuples = Lists.newArrayListWithExpectedSize(arrays.size()); PDataType baseType = PDataType.fromTypeId(arrayType.getSqlType() - PDataType.ARRAY_TYPE_BASE); for (Object[] array : arrays) { PhoenixArray pArray = new PhoenixArray(baseType, array); byte[] bytes = arrayType.toBytes(pArray); tuples.add(new SingleKeyValueTuple(PhoenixKeyValueUtil.newKeyValue(bytes, 0, bytes.length, bytes, 0, 0, bytes, 0, 0, 0, bytes, 0, 0, Cell.Type.Put))); } return tuples; } }
@Override public final void coerceBytes(ImmutableBytesWritable ptr, Object object, PDataType actualType, Integer maxLength, Integer scale, SortOrder actualModifer, Integer desiredMaxLength, Integer desiredScale, SortOrder desiredModifier) { coerceBytes(ptr, object, actualType, maxLength, scale, desiredMaxLength, desiredScale, this, actualModifer, desiredModifier, true); }
@Override protected boolean modifierFunction(ImmutableBytesWritable ptr, int len, int offset, byte[] arrayBytes, PDataType baseDataType, int arrayLength, Integer maxLength, Expression arrayExp) { return PArrayDataType.appendItemToArray(ptr, len, offset, arrayBytes, baseDataType, arrayLength, getMaxLength(), arrayExp.getSortOrder()); }
@Override public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) { Expression delimiterExpr = children.get(1); if (!delimiterExpr.evaluate(tuple, ptr)) { return false; } else if (ptr.getLength() == 0) { return true; } String delimiter = (String) delimiterExpr.getDataType().toObject(ptr, delimiterExpr.getSortOrder(), delimiterExpr.getMaxLength(), delimiterExpr.getScale()); Expression arrayExpr = children.get(0); if (!arrayExpr.evaluate(tuple, ptr)) { return false; } else if (ptr.getLength() == 0) { return true; } PhoenixArray array = (PhoenixArray) arrayExpr.getDataType().toObject(ptr, arrayExpr.getSortOrder(), arrayExpr.getMaxLength(), arrayExpr.getScale()); Expression nullExpr = children.get(2); String nullString = null; if (nullExpr.evaluate(tuple, ptr) && ptr.getLength() != 0) { nullString = (String) nullExpr.getDataType().toObject(ptr, nullExpr.getSortOrder(), nullExpr.getMaxLength(), nullExpr.getScale()); } return PArrayDataType.arrayToString(ptr, array, delimiter, nullString, getSortOrder()); }
arrayBytes = generateEmptyArrayBytes(baseType, sortOrder); offset = 0; length = arrayBytes.length; if (PArrayDataType.useShortForOffsetArray(newElementPosition)) { newArray = new byte[length + elementLength + Bytes.SIZEOF_SHORT + Bytes.SIZEOF_BYTE]; } else { byte sepByte = getSeparatorByte(isRowKeyOrderOptimized(false, sortOrder, arrayBytes, offset, length), sortOrder); newArray[newOffsetArrayPosition-3] = sepByte; // Separator for new value newArray[newOffsetArrayPosition-2] = sepByte; // Double byte separator Bytes.putInt(newArray, newOffsetArrayPosition + offsetArrayLength, newElementPosition); writeEndBytes(newArray, newOffsetArrayPosition, offsetArrayLength, arrayLength, arrayBytes[offset + length - 1], true); } else { (short)(newElementPosition - Short.MAX_VALUE)); writeEndBytes(newArray, newOffsetArrayPosition, offsetArrayLength, arrayLength, arrayBytes[offset + length - 1], false); } else { for (int arrayIndex = 0; arrayIndex < Math.abs(arrayLength) - 1; arrayIndex++) { Bytes.putInt(newArray, off, getOffset(arrayBytes, arrayIndex, true, offsetArrayPosition + offset, serializationVersion)); off += Bytes.SIZEOF_INT;
arrayBytes = generateEmptyArrayBytes(baseType, sortOrder); offset = 0; length = arrayBytes.length; int endElementPosition = getOffset(arrayBytes, arrayLength - 1, !useInt, offsetArrayPosition + offset, serializationVersion) + elementLength + Bytes.SIZEOF_BYTE; int newOffsetArrayPosition; int currOffset = getOffset(arrayBytes, index, !useInt, offsetArrayPosition + offset, serializationVersion); if (arrayBytes[offset + currOffset] == QueryConstants.SEPARATOR_BYTE) { nulls++; endElementPosition = getOffset(arrayBytes, arrayLength - 1, !useInt, offsetArrayPosition + offset, serializationVersion) + lengthIncrease; if (!useInt) { if (PArrayDataType.useShortForOffsetArray(endElementPosition)) { newArray = new byte[length + Bytes.SIZEOF_SHORT + lengthIncrease]; } else { currentPosition = serializeNulls(newArray, currentPosition, nulls); } else { if (!useInt) { if (PArrayDataType.useShortForOffsetArray(endElementPosition)) { newArray = new byte[length + elementLength + Bytes.SIZEOF_SHORT + Bytes.SIZEOF_BYTE]; } else { newArray[elementLength] = getSeparatorByte(isRowKeyOrderOptimized(false, sortOrder, arrayBytes, offset, length), sortOrder); currentPosition += elementLength + Bytes.SIZEOF_BYTE;