@Test(expectedExceptions = {IllegalStateException.class}, expectedExceptionsMessageRegExp = "two matching methods \\(varcharToBigintReturnFirstExtraParameter and varcharToBigintReturnExtraParameter\\) for parameter types \\[varchar\\(10\\)\\]") public void testFailIfTwoMethodsWithSameArguments() { SqlScalarFunction function = SqlScalarFunction.builder(TestMethods.class) .signature(SIGNATURE) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup.methods("varcharToBigintReturnFirstExtraParameter")) .implementation(methodsGroup -> methodsGroup.methods("varcharToBigintReturnExtraParameter"))) .build(); function.specialize(BOUND_VARIABLES, 1, TYPE_REGISTRY, REGISTRY); }
@Test public void testMultiScalarParse() { Signature expectedSignature1 = new Signature( "static_method_scalar_1", FunctionKind.SCALAR, DOUBLE.getTypeSignature(), ImmutableList.of(DOUBLE.getTypeSignature())); Signature expectedSignature2 = new Signature( "static_method_scalar_2", FunctionKind.SCALAR, BIGINT.getTypeSignature(), ImmutableList.of(BIGINT.getTypeSignature())); List<SqlScalarFunction> functions = ScalarFromAnnotationsParser.parseFunctionDefinitions(MultiScalarFunction.class); assertEquals(functions.size(), 2); ParametricScalar scalar1 = (ParametricScalar) functions.stream().filter(signature -> signature.getSignature().equals(expectedSignature1)).collect(toImmutableList()).get(0); ParametricScalar scalar2 = (ParametricScalar) functions.stream().filter(signature -> signature.getSignature().equals(expectedSignature2)).collect(toImmutableList()).get(0); assertImplementationCount(scalar1, 1, 0, 0); assertImplementationCount(scalar2, 1, 0, 0); assertEquals(scalar1.getSignature(), expectedSignature1); assertTrue(scalar1.isDeterministic()); assertFalse(scalar1.isHidden()); assertEquals(scalar1.getDescription(), "Simple scalar with single implementation based on method 1"); assertEquals(scalar2.getSignature(), expectedSignature2); assertFalse(scalar2.isDeterministic()); assertTrue(scalar2.isHidden()); assertEquals(scalar2.getDescription(), "Simple scalar with single implementation based on method 2"); }
public static SqlScalarFunction modulusScalarFunction(Signature signature) { return SqlScalarFunction.builder(DecimalOperators.class) .signature(signature) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup .methods("modulusShortShortShort", "modulusLongLongLong", "modulusShortLongLong", "modulusShortLongShort", "modulusLongShortShort", "modulusLongShortLong") .withExtraParameters(DecimalOperators::modulusRescaleParameters))) .build(); }
.expireAfterWrite(1, HOURS) .build(CacheLoader.from(key -> ((SqlScalarFunction) key.getFunction()) .specialize(key.getBoundVariables(), key.getArity(), typeManager, this)));
public static SqlScalarFunction modulusScalarFunction(Signature signature) { return SqlScalarFunction.builder(DecimalOperators.class) .signature(signature) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup .methods("modulusShortShortShort", "modulusLongLongLong", "modulusShortLongLong", "modulusShortLongShort", "modulusLongShortShort", "modulusLongShortLong") .withExtraParameters(DecimalOperators::modulusRescaleParameters))) .build(); }
.expireAfterWrite(1, HOURS) .build(CacheLoader.from(key -> ((SqlScalarFunction) key.getFunction()) .specialize(key.getBoundVariables(), key.getArity(), typeManager, this)));
@Test(expectedExceptions = {IllegalStateException.class}, expectedExceptionsMessageRegExp = "two matching methods \\(varcharToBigintReturnFirstExtraParameter and varcharToBigintReturnExtraParameter\\) for parameter types \\[varchar\\(10\\)\\]") public void testFailIfTwoMethodsWithSameArguments() { SqlScalarFunction function = SqlScalarFunction.builder(TestMethods.class) .signature(SIGNATURE) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup.methods("varcharToBigintReturnFirstExtraParameter")) .implementation(methodsGroup -> methodsGroup.methods("varcharToBigintReturnExtraParameter"))) .build(); function.specialize(BOUND_VARIABLES, 1, TYPE_REGISTRY, REGISTRY); }
@Test(expectedExceptions = {IllegalStateException.class}, expectedExceptionsMessageRegExp = "methods must be selected first") public void testFailNoMethodsAreSelectedWhenExtraParametersFunctionIsSet() { SqlScalarFunction.builder(TestMethods.class) .signature(SIGNATURE) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup .withExtraParameters(context -> ImmutableList.of(42)))) .build(); }
@Test public void testMultiScalarParse() { Signature expectedSignature1 = new Signature( "static_method_scalar_1", FunctionKind.SCALAR, DOUBLE.getTypeSignature(), ImmutableList.of(DOUBLE.getTypeSignature())); Signature expectedSignature2 = new Signature( "static_method_scalar_2", FunctionKind.SCALAR, BIGINT.getTypeSignature(), ImmutableList.of(BIGINT.getTypeSignature())); List<SqlScalarFunction> functions = ScalarFromAnnotationsParser.parseFunctionDefinitions(MultiScalarFunction.class); assertEquals(functions.size(), 2); ParametricScalar scalar1 = (ParametricScalar) functions.stream().filter(signature -> signature.getSignature().equals(expectedSignature1)).collect(toImmutableList()).get(0); ParametricScalar scalar2 = (ParametricScalar) functions.stream().filter(signature -> signature.getSignature().equals(expectedSignature2)).collect(toImmutableList()).get(0); assertImplementationCount(scalar1, 1, 0, 0); assertImplementationCount(scalar2, 1, 0, 0); assertEquals(scalar1.getSignature(), expectedSignature1); assertTrue(scalar1.isDeterministic()); assertFalse(scalar1.isHidden()); assertEquals(scalar1.getDescription(), "Simple scalar with single implementation based on method 1"); assertEquals(scalar2.getSignature(), expectedSignature2); assertFalse(scalar2.isDeterministic()); assertTrue(scalar2.isHidden()); assertEquals(scalar2.getDescription(), "Simple scalar with single implementation based on method 2"); }
@Test public void testSelectsMethodBasedOnReturnType() throws Throwable { SqlScalarFunction function = SqlScalarFunction.builder(TestMethods.class) .signature(SIGNATURE) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup.methods("varcharToVarcharCreateSliceWithExtraParameterLength")) .implementation(methodsGroup -> methodsGroup .methods("varcharToBigintReturnExtraParameter") .withExtraParameters(context -> ImmutableList.of(42)))) .build(); ScalarFunctionImplementation functionImplementation = function.specialize(BOUND_VARIABLES, 1, TYPE_REGISTRY, REGISTRY); assertEquals(functionImplementation.getMethodHandle().invoke(INPUT_SLICE), VARCHAR_TO_BIGINT_RETURN_VALUE); }
private static SqlScalarFunction genericIntegerTypeToDecimalSaturatedFloorCast(Type integerType) { return SqlScalarFunction.builder(DecimalSaturatedFloorCasts.class) .signature(Signature.builder() .kind(SCALAR) .operatorType(SATURATED_FLOOR_CAST) .argumentTypes(integerType.getTypeSignature()) .returnType(parseTypeSignature("decimal(result_precision,result_scale)", ImmutableSet.of("result_precision", "result_scale"))) .build()) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup .methods("genericIntegerTypeToShortDecimal", "genericIntegerTypeToLongDecimal") .withExtraParameters((context) -> { int resultPrecision = toIntExact(context.getLiteral("result_precision")); int resultScale = toIntExact(context.getLiteral("result_scale")); return ImmutableList.of(resultPrecision, resultScale); }))) .build(); }
@Test public void testSelectsMethodBasedOnArgumentTypes() throws Throwable { SqlScalarFunction function = SqlScalarFunction.builder(TestMethods.class) .signature(SIGNATURE) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup.methods("bigintToBigintReturnExtraParameter")) .implementation(methodsGroup -> methodsGroup .methods("varcharToBigintReturnExtraParameter") .withExtraParameters(context -> ImmutableList.of(context.getLiteral("x"))))) .build(); ScalarFunctionImplementation functionImplementation = function.specialize(BOUND_VARIABLES, 1, TYPE_REGISTRY, REGISTRY); assertEquals(functionImplementation.getMethodHandle().invoke(INPUT_SLICE), INPUT_VARCHAR_LENGTH); }
@Test(expectedExceptions = {IllegalStateException.class}, expectedExceptionsMessageRegExp = "methods must be selected first") public void testFailNoMethodsAreSelectedWhenExtraParametersFunctionIsSet() { SqlScalarFunction.builder(TestMethods.class) .signature(SIGNATURE) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup .withExtraParameters(context -> ImmutableList.of(42)))) .build(); }
@Test public void testSelectsMethodBasedOnReturnType() throws Throwable { SqlScalarFunction function = SqlScalarFunction.builder(TestMethods.class) .signature(SIGNATURE) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup.methods("varcharToVarcharCreateSliceWithExtraParameterLength")) .implementation(methodsGroup -> methodsGroup .methods("varcharToBigintReturnExtraParameter") .withExtraParameters(context -> ImmutableList.of(42)))) .build(); ScalarFunctionImplementation functionImplementation = function.specialize(BOUND_VARIABLES, 1, TYPE_REGISTRY, REGISTRY); assertEquals(functionImplementation.getMethodHandle().invoke(INPUT_SLICE), VARCHAR_TO_BIGINT_RETURN_VALUE); }
private static SqlScalarFunction genericIntegerTypeToDecimalSaturatedFloorCast(Type integerType) { return SqlScalarFunction.builder(DecimalSaturatedFloorCasts.class) .signature(Signature.builder() .kind(SCALAR) .operatorType(SATURATED_FLOOR_CAST) .argumentTypes(integerType.getTypeSignature()) .returnType(parseTypeSignature("decimal(result_precision,result_scale)", ImmutableSet.of("result_precision", "result_scale"))) .build()) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup .methods("genericIntegerTypeToShortDecimal", "genericIntegerTypeToLongDecimal") .withExtraParameters((context) -> { int resultPrecision = toIntExact(context.getLiteral("result_precision")); int resultScale = toIntExact(context.getLiteral("result_scale")); return ImmutableList.of(resultPrecision, resultScale); }))) .build(); }
@Test public void testSelectsMethodBasedOnArgumentTypes() throws Throwable { SqlScalarFunction function = SqlScalarFunction.builder(TestMethods.class) .signature(SIGNATURE) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup.methods("bigintToBigintReturnExtraParameter")) .implementation(methodsGroup -> methodsGroup .methods("varcharToBigintReturnExtraParameter") .withExtraParameters(context -> ImmutableList.of(context.getLiteral("x"))))) .build(); ScalarFunctionImplementation functionImplementation = function.specialize(BOUND_VARIABLES, 1, TYPE_REGISTRY, REGISTRY); assertEquals(functionImplementation.getMethodHandle().invoke(INPUT_SLICE), INPUT_VARCHAR_LENGTH); }
private static PolymorphicScalarFunctionBuilder makeBinaryOperatorFunctionBuilder(OperatorType operatorType) { Signature signature = Signature.builder() .kind(SCALAR) .operatorType(operatorType) .argumentTypes(DECIMAL_SIGNATURE, DECIMAL_SIGNATURE) .returnType(parseTypeSignature(BOOLEAN)) .build(); return SqlScalarFunction.builder(DecimalInequalityOperators.class) .signature(signature) .deterministic(true); }
@Test public void testSetsHiddenToTrueForOperators() { Signature signature = Signature.builder() .operatorType(ADD) .kind(SCALAR) .returnType(parseTypeSignature("varchar(x)", ImmutableSet.of("x"))) .argumentTypes(parseTypeSignature("varchar(x)", ImmutableSet.of("x"))) .build(); SqlScalarFunction function = SqlScalarFunction.builder(TestMethods.class) .signature(signature) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup.methods("varcharToVarchar"))) .build(); ScalarFunctionImplementation functionImplementation = function.specialize(BOUND_VARIABLES, 1, TYPE_REGISTRY, REGISTRY); }
private static SqlScalarFunction decimalToGenericIntegerTypeSaturatedFloorCast(Type type, long minValue, long maxValue) { return SqlScalarFunction.builder(DecimalSaturatedFloorCasts.class) .signature(Signature.builder() .kind(SCALAR) .operatorType(SATURATED_FLOOR_CAST) .argumentTypes(parseTypeSignature("decimal(source_precision,source_scale)", ImmutableSet.of("source_precision", "source_scale"))) .returnType(type.getTypeSignature()) .build()) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup .methods("shortDecimalToGenericIntegerType", "longDecimalToGenericIntegerType") .withExtraParameters((context) -> { int sourceScale = toIntExact(context.getLiteral("source_scale")); return ImmutableList.of(sourceScale, minValue, maxValue); }))) .build(); }
@Test public void testSetsHiddenToTrueForOperators() { Signature signature = Signature.builder() .operatorType(ADD) .kind(SCALAR) .returnType(parseTypeSignature("varchar(x)", ImmutableSet.of("x"))) .argumentTypes(parseTypeSignature("varchar(x)", ImmutableSet.of("x"))) .build(); SqlScalarFunction function = SqlScalarFunction.builder(TestMethods.class) .signature(signature) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup.methods("varcharToVarchar"))) .build(); ScalarFunctionImplementation functionImplementation = function.specialize(BOUND_VARIABLES, 1, TYPE_REGISTRY, REGISTRY); }