public Signature getCoercion(Type fromType, Type toType) { return getCoercion(fromType.getTypeSignature(), toType.getTypeSignature()); }
public Signature getCoercion(Type fromType, Type toType) { return getCoercion(fromType.getTypeSignature(), toType.getTypeSignature()); }
static OptionalDouble toStatsRepresentation(FunctionRegistry functionRegistry, ConnectorSession session, Type type, Object value) { if (convertibleToDoubleWithCast(type)) { InterpretedFunctionInvoker functionInvoker = new InterpretedFunctionInvoker(functionRegistry); Signature castSignature = functionRegistry.getCoercion(type, DoubleType.DOUBLE); return OptionalDouble.of((double) functionInvoker.invoke(castSignature, session, singletonList(value))); } if (DateType.DATE.equals(type)) { return OptionalDouble.of(((Long) value).doubleValue()); } return OptionalDouble.empty(); }
static OptionalDouble toStatsRepresentation(FunctionRegistry functionRegistry, ConnectorSession session, Type type, Object value) { if (convertibleToDoubleWithCast(type)) { InterpretedFunctionInvoker functionInvoker = new InterpretedFunctionInvoker(functionRegistry); Signature castSignature = functionRegistry.getCoercion(type, DoubleType.DOUBLE); return OptionalDouble.of((double) functionInvoker.invoke(castSignature, session, singletonList(value))); } if (DateType.DATE.equals(type)) { return OptionalDouble.of(((Long) value).doubleValue()); } return OptionalDouble.empty(); }
@Override public BytecodeNode generateExpression(Signature signature, BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments) { RowExpression argument = arguments.get(0); Signature function = generatorContext .getRegistry() .getCoercion(argument.getType(), returnType); return generatorContext.generateCall(function.getName(), generatorContext.getRegistry().getScalarFunctionImplementation(function), ImmutableList.of(generatorContext.generate(argument))); } }
@Override public BytecodeNode generateExpression(Signature signature, BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments) { RowExpression argument = arguments.get(0); Signature function = generatorContext .getRegistry() .getCoercion(argument.getType(), returnType); return generatorContext.generateCall(function.getName(), generatorContext.getRegistry().getScalarFunctionImplementation(function), ImmutableList.of(generatorContext.generate(argument))); } }
private static String castToVarchar(Type type, Object value, FunctionRegistry functionRegistry, Session session) { if (value == null) { return "NULL"; } try { Signature coercion = functionRegistry.getCoercion(type, VARCHAR); Slice coerced = (Slice) new InterpretedFunctionInvoker(functionRegistry).invoke(coercion, session.toConnectorSession(), value); return coerced.toStringUtf8(); } catch (OperatorNotFoundException e) { return "<UNREPRESENTABLE VALUE>"; } } }
private static String castToVarchar(Type type, Object value, FunctionRegistry functionRegistry, Session session) { if (value == null) { return "NULL"; } try { Signature coercion = functionRegistry.getCoercion(type, VARCHAR); Slice coerced = (Slice) new InterpretedFunctionInvoker(functionRegistry).invoke(coercion, session.toConnectorSession(), value); return coerced.toStringUtf8(); } catch (OperatorNotFoundException e) { return "<UNREPRESENTABLE VALUE>"; } } }
private int compareOriginalValueToCoerced(Type originalValueType, Object originalValue, Type coercedValueType, Object coercedValue) { Signature castToOriginalTypeOperator = metadata.getFunctionRegistry().getCoercion(coercedValueType, originalValueType); Object coercedValueInOriginalType = functionInvoker.invoke(castToOriginalTypeOperator, session.toConnectorSession(), coercedValue); Block originalValueBlock = Utils.nativeValueToBlock(originalValueType, originalValue); Block coercedValueBlock = Utils.nativeValueToBlock(originalValueType, coercedValueInOriginalType); return originalValueType.compareTo(originalValueBlock, 0, coercedValueBlock, 0); }
private int compareOriginalValueToCoerced(Type originalValueType, Object originalValue, Type coercedValueType, Object coercedValue) { Signature castToOriginalTypeOperator = metadata.getFunctionRegistry().getCoercion(coercedValueType, originalValueType); Object coercedValueInOriginalType = functionInvoker.invoke(castToOriginalTypeOperator, session.toConnectorSession(), coercedValue); Block originalValueBlock = Utils.nativeValueToBlock(originalValueType, originalValue); Block coercedValueBlock = Utils.nativeValueToBlock(originalValueType, coercedValueInOriginalType); return originalValueType.compareTo(originalValueBlock, 0, coercedValueBlock, 0); }
private static BytecodeNode cast( BytecodeGeneratorContext generatorContext, BytecodeNode argument, Type actualType, TypeSignature requiredType) { if (actualType.getTypeSignature().equals(requiredType)) { return argument; } Signature function = generatorContext .getRegistry() .getCoercion(actualType.getTypeSignature(), requiredType); // TODO: do we need a full function call? (nullability checks, etc) return generatorContext.generateCall(function.getName(), generatorContext.getRegistry().getScalarFunctionImplementation(function), ImmutableList.of(argument)); } }
private static BytecodeNode cast( BytecodeGeneratorContext generatorContext, BytecodeNode argument, Type actualType, TypeSignature requiredType) { if (actualType.getTypeSignature().equals(requiredType)) { return argument; } Signature function = generatorContext .getRegistry() .getCoercion(actualType.getTypeSignature(), requiredType); // TODO: do we need a full function call? (nullability checks, etc) return generatorContext.generateCall(function.getName(), generatorContext.getRegistry().getScalarFunctionImplementation(function), ImmutableList.of(argument)); } }
@Test public void testIdentityCast() { TypeRegistry typeManager = new TypeRegistry(); FunctionRegistry registry = new FunctionRegistry(typeManager, new BlockEncodingManager(typeManager), new FeaturesConfig()); Signature exactOperator = registry.getCoercion(HYPER_LOG_LOG, HYPER_LOG_LOG); assertEquals(exactOperator.getName(), mangleOperatorName(OperatorType.CAST.name())); assertEquals(transform(exactOperator.getArgumentTypes(), Functions.toStringFunction()), ImmutableList.of(StandardTypes.HYPER_LOG_LOG)); assertEquals(exactOperator.getReturnType().getBase(), StandardTypes.HYPER_LOG_LOG); }
@Test public void testIdentityCast() { TypeRegistry typeManager = new TypeRegistry(); FunctionRegistry registry = new FunctionRegistry(typeManager, new BlockEncodingManager(typeManager), new FeaturesConfig()); Signature exactOperator = registry.getCoercion(HYPER_LOG_LOG, HYPER_LOG_LOG); assertEquals(exactOperator.getName(), mangleOperatorName(OperatorType.CAST.name())); assertEquals(transform(exactOperator.getArgumentTypes(), Functions.toStringFunction()), ImmutableList.of(StandardTypes.HYPER_LOG_LOG)); assertEquals(exactOperator.getReturnType().getBase(), StandardTypes.HYPER_LOG_LOG); }
@Override public ScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, TypeManager typeManager, FunctionRegistry functionRegistry) { Type fromType = boundVariables.getTypeVariable("F"); Type toType = boundVariables.getTypeVariable("T"); Class<?> returnType = Primitives.wrap(toType.getJavaType()); List<ArgumentProperty> argumentProperties; MethodHandle tryCastHandle; // the resulting method needs to return a boxed type Signature signature = functionRegistry.getCoercion(fromType, toType); ScalarFunctionImplementation implementation = functionRegistry.getScalarFunctionImplementation(signature); argumentProperties = ImmutableList.of(implementation.getArgumentProperty(0)); MethodHandle coercion = implementation.getMethodHandle(); coercion = coercion.asType(methodType(returnType, coercion.type())); MethodHandle exceptionHandler = dropArguments(constant(returnType, null), 0, RuntimeException.class); tryCastHandle = catchException(coercion, RuntimeException.class, exceptionHandler); return new ScalarFunctionImplementation(true, argumentProperties, tryCastHandle, isDeterministic()); } }
@Override public ScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, TypeManager typeManager, FunctionRegistry functionRegistry) { Type fromType = boundVariables.getTypeVariable("F"); Type toType = boundVariables.getTypeVariable("T"); Class<?> returnType = Primitives.wrap(toType.getJavaType()); List<ArgumentProperty> argumentProperties; MethodHandle tryCastHandle; // the resulting method needs to return a boxed type Signature signature = functionRegistry.getCoercion(fromType, toType); ScalarFunctionImplementation implementation = functionRegistry.getScalarFunctionImplementation(signature); argumentProperties = ImmutableList.of(implementation.getArgumentProperty(0)); MethodHandle coercion = implementation.getMethodHandle(); coercion = coercion.asType(methodType(returnType, coercion.type())); MethodHandle exceptionHandler = dropArguments(constant(returnType, null), 0, RuntimeException.class); tryCastHandle = catchException(coercion, RuntimeException.class, exceptionHandler); return new ScalarFunctionImplementation(true, argumentProperties, tryCastHandle, isDeterministic()); } }
@Override protected Type visitGenericLiteral(GenericLiteral node, StackableAstVisitorContext<Context> context) { Type type; try { type = typeManager.getType(parseTypeSignature(node.getType())); } catch (IllegalArgumentException e) { throw new SemanticException(TYPE_MISMATCH, node, "Unknown type: " + node.getType()); } if (!JSON.equals(type)) { try { functionRegistry.getCoercion(VARCHAR, type); } catch (IllegalArgumentException e) { throw new SemanticException(TYPE_MISMATCH, node, "No literal form for type %s", type); } } return setExpressionType(node, type); }
@Override protected Type visitGenericLiteral(GenericLiteral node, StackableAstVisitorContext<Context> context) { Type type; try { type = typeManager.getType(parseTypeSignature(node.getType())); } catch (IllegalArgumentException e) { throw new SemanticException(TYPE_MISMATCH, node, "Unknown type: " + node.getType()); } if (!JSON.equals(type)) { try { functionRegistry.getCoercion(VARCHAR, type); } catch (IllegalArgumentException e) { throw new SemanticException(TYPE_MISMATCH, node, "No literal form for type %s", type); } } return setExpressionType(node, type); }
@Override protected Object visitGenericLiteral(GenericLiteral node, ConnectorSession session) { Type type = metadata.getType(parseTypeSignature(node.getType())); if (type == null) { throw new SemanticException(TYPE_MISMATCH, node, "Unknown type: " + node.getType()); } if (JSON.equals(type)) { Signature operatorSignature = new Signature("json_parse", SCALAR, JSON.getTypeSignature(), VARCHAR.getTypeSignature()); return functionInvoker.invoke(operatorSignature, session, ImmutableList.of(utf8Slice(node.getValue()))); } try { Signature signature = metadata.getFunctionRegistry().getCoercion(VARCHAR, type); return functionInvoker.invoke(signature, session, ImmutableList.of(utf8Slice(node.getValue()))); } catch (IllegalArgumentException e) { throw new SemanticException(TYPE_MISMATCH, node, "No literal form for type %s", type); } }
@Override protected Object visitGenericLiteral(GenericLiteral node, ConnectorSession session) { Type type = metadata.getType(parseTypeSignature(node.getType())); if (type == null) { throw new SemanticException(TYPE_MISMATCH, node, "Unknown type: " + node.getType()); } if (JSON.equals(type)) { Signature operatorSignature = new Signature("json_parse", SCALAR, JSON.getTypeSignature(), VARCHAR.getTypeSignature()); return functionInvoker.invoke(operatorSignature, session, ImmutableList.of(utf8Slice(node.getValue()))); } try { Signature signature = metadata.getFunctionRegistry().getCoercion(VARCHAR, type); return functionInvoker.invoke(signature, session, ImmutableList.of(utf8Slice(node.getValue()))); } catch (IllegalArgumentException e) { throw new SemanticException(TYPE_MISMATCH, node, "No literal form for type %s", type); } }