@Test public void testStackRepresentation() throws Exception { Block array = arrayBlockOf(BIGINT, 1L, 2L); Block actualBlock = mapBlockOf(DOUBLE, new ArrayType(BIGINT), ImmutableMap.of(1.0, array)); DynamicSliceOutput actualSliceOutput = new DynamicSliceOutput(100); writeBlock(actualSliceOutput, actualBlock); Block expectedBlock = new InterleavedBlockBuilder( ImmutableList.<Type>of(DOUBLE, new ArrayType(BIGINT)), new BlockBuilderStatus(), 3) .writeDouble(1.0) .closeEntry() .writeObject( BIGINT .createBlockBuilder(new BlockBuilderStatus(), 1) .writeLong(1L) .closeEntry() .writeLong(2L) .closeEntry() .build()) .closeEntry() .build(); DynamicSliceOutput expectedSliceOutput = new DynamicSliceOutput(100); writeBlock(expectedSliceOutput, expectedBlock); assertEquals(actualSliceOutput.slice(), expectedSliceOutput.slice()); }
public static Expression toExpression(Object object, Type type) { requireNonNull(type, "type is null"); if (object instanceof Expression) { return (Expression) object; } if (object == null) { if (type.equals(UNKNOWN)) { return new NullLiteral(); } return new Cast(new NullLiteral(), type.getTypeSignature().toString(), false, true); } checkArgument( Primitives.wrap(type.getJavaType()).isInstance(object), "object.getClass (%s) and type.getJavaType (%s) do not agree", object.getClass(), type.getJavaType()); if (type.equals(BIGINT)) { return new LongLiteral(object.toString()); } if (type.equals(DOUBLE)) { Double value = (Double) object; // WARNING: the ORC predicate code depends on NaN and infinity not appearing in a tuple // domain, so // if you remove this, you will need to update the TupleDomainOrcPredicate if (value.isNaN()) { return new FunctionCall(new QualifiedName("nan"), ImmutableList.<Expression>of()); } else if (value.equals(Double.NEGATIVE_INFINITY)) { return ArithmeticUnaryExpression.negative( new FunctionCall(new QualifiedName("infinity"), ImmutableList.<Expression>of())); } else if (value.equals(Double.POSITIVE_INFINITY)) { return new FunctionCall(new QualifiedName("infinity"), ImmutableList.<Expression>of()); } else { return new DoubleLiteral(object.toString()); } } if (type instanceof VarcharType) { if (object instanceof String) { object = Slices.utf8Slice((String) object); } if (object instanceof Slice) { Slice value = (Slice) object; int length = SliceUtf8.countCodePoints(value); if (length == ((VarcharType) type).getLength()) { return new StringLiteral(value.toStringUtf8()); } return new Cast( new StringLiteral(value.toStringUtf8()), type.getDisplayName(), false, true); } throw new IllegalArgumentException( "object must be instance of Slice or String when type is VARCHAR"); } if (type.equals(BOOLEAN)) { return new BooleanLiteral(object.toString()); } if (object instanceof Block) { SliceOutput output = new DynamicSliceOutput(((Block) object).getSizeInBytes()); BlockSerdeUtil.writeBlock(output, (Block) object); object = output.slice(); // This if condition will evaluate to true: object instanceof Slice && !type.equals(VARCHAR) } if (object instanceof Slice) { // HACK: we need to serialize VARBINARY in a format that can be embedded in an expression to // be // able to encode it in the plan that gets sent to workers. // We do this by transforming the in-memory varbinary into a call to // from_base64(<base64-encoded value>) FunctionCall fromBase64 = new FunctionCall( new QualifiedName("from_base64"), ImmutableList.of( new StringLiteral(VarbinaryFunctions.toBase64((Slice) object).toStringUtf8()))); Signature signature = FunctionRegistry.getMagicLiteralFunctionSignature(type); return new FunctionCall(new QualifiedName(signature.getName()), ImmutableList.of(fromBase64)); } Signature signature = FunctionRegistry.getMagicLiteralFunctionSignature(type); Expression rawLiteral = toExpression(object, FunctionRegistry.typeForMagicLiteral(type)); return new FunctionCall(new QualifiedName(signature.getName()), ImmutableList.of(rawLiteral)); }
private static Slice blockToSlice(Block block) { // This function is strictly for testing use only SliceOutput sliceOutput = new DynamicSliceOutput(1000); BlockSerdeUtil.writeBlock(sliceOutput, block.copyRegion(0, block.getPositionCount())); return sliceOutput.slice(); }