private static SqlScalarFunction decimalModulusOperator() { Signature signature = modulusSignatureBuilder() .operatorType(MODULUS) .build(); return modulusScalarFunction(signature); }
private static SqlScalarFunction decimalModulusOperator() { Signature signature = modulusSignatureBuilder() .operatorType(MODULUS) .build(); return modulusScalarFunction(signature); }
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(); }
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(); }
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); }
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(); }
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); }
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(); }
private static SqlScalarFunction decimalMultiplyOperator() { TypeSignature decimalLeftSignature = parseTypeSignature("decimal(a_precision, a_scale)", ImmutableSet.of("a_precision", "a_scale")); TypeSignature decimalRightSignature = parseTypeSignature("decimal(b_precision, b_scale)", ImmutableSet.of("b_precision", "b_scale")); TypeSignature decimalResultSignature = parseTypeSignature("decimal(r_precision, r_scale)", ImmutableSet.of("r_precision", "r_scale")); Signature signature = Signature.builder() .kind(SCALAR) .operatorType(MULTIPLY) .longVariableConstraints( longVariableExpression("r_precision", "min(38, a_precision + b_precision)"), longVariableExpression("r_scale", "a_scale + b_scale")) .argumentTypes(decimalLeftSignature, decimalRightSignature) .returnType(decimalResultSignature) .build(); return SqlScalarFunction.builder(DecimalOperators.class) .signature(signature) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup .methods("multiplyShortShortShort", "multiplyShortShortLong", "multiplyLongLongLong", "multiplyShortLongLong", "multiplyLongShortLong"))) .build(); }
private static SqlScalarFunction decimalMultiplyOperator() { TypeSignature decimalLeftSignature = parseTypeSignature("decimal(a_precision, a_scale)", ImmutableSet.of("a_precision", "a_scale")); TypeSignature decimalRightSignature = parseTypeSignature("decimal(b_precision, b_scale)", ImmutableSet.of("b_precision", "b_scale")); TypeSignature decimalResultSignature = parseTypeSignature("decimal(r_precision, r_scale)", ImmutableSet.of("r_precision", "r_scale")); Signature signature = Signature.builder() .kind(SCALAR) .operatorType(MULTIPLY) .longVariableConstraints( longVariableExpression("r_precision", "min(38, a_precision + b_precision)"), longVariableExpression("r_scale", "a_scale + b_scale")) .argumentTypes(decimalLeftSignature, decimalRightSignature) .returnType(decimalResultSignature) .build(); return SqlScalarFunction.builder(DecimalOperators.class) .signature(signature) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup .methods("multiplyShortShortShort", "multiplyShortShortLong", "multiplyLongLongLong", "multiplyShortLongLong", "multiplyLongShortLong"))) .build(); }
private static SqlScalarFunction decimalDivideOperator() { TypeSignature decimalLeftSignature = parseTypeSignature("decimal(a_precision, a_scale)", ImmutableSet.of("a_precision", "a_scale")); TypeSignature decimalRightSignature = parseTypeSignature("decimal(b_precision, b_scale)", ImmutableSet.of("b_precision", "b_scale")); TypeSignature decimalResultSignature = parseTypeSignature("decimal(r_precision, r_scale)", ImmutableSet.of("r_precision", "r_scale")); // we extend target precision by b_scale. This is upper bound on how much division result will grow. // pessimistic case is a / 0.0000001 // if scale of divisor is greater than scale of dividend we extend scale further as we // want result scale to be maximum of scales of divisor and dividend. Signature signature = Signature.builder() .kind(SCALAR) .operatorType(DIVIDE) .longVariableConstraints( longVariableExpression("r_precision", "min(38, a_precision + b_scale + max(b_scale - a_scale, 0))"), longVariableExpression("r_scale", "max(a_scale, b_scale)")) .argumentTypes(decimalLeftSignature, decimalRightSignature) .returnType(decimalResultSignature) .build(); return SqlScalarFunction.builder(DecimalOperators.class) .signature(signature) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup .methods("divideShortShortShort", "divideShortLongShort", "divideLongShortShort", "divideShortShortLong", "divideLongLongLong", "divideShortLongLong", "divideLongShortLong") .withExtraParameters(DecimalOperators::divideRescaleFactor))) .build(); }
private static SqlScalarFunction decimalAddOperator() { TypeSignature decimalLeftSignature = parseTypeSignature("decimal(a_precision, a_scale)", ImmutableSet.of("a_precision", "a_scale")); TypeSignature decimalRightSignature = parseTypeSignature("decimal(b_precision, b_scale)", ImmutableSet.of("b_precision", "b_scale")); TypeSignature decimalResultSignature = parseTypeSignature("decimal(r_precision, r_scale)", ImmutableSet.of("r_precision", "r_scale")); Signature signature = Signature.builder() .kind(SCALAR) .operatorType(ADD) .longVariableConstraints( longVariableExpression("r_precision", "min(38, max(a_precision - a_scale, b_precision - b_scale) + max(a_scale, b_scale) + 1)"), longVariableExpression("r_scale", "max(a_scale, b_scale)")) .argumentTypes(decimalLeftSignature, decimalRightSignature) .returnType(decimalResultSignature) .build(); return SqlScalarFunction.builder(DecimalOperators.class) .signature(signature) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup .methods("addShortShortShort") .withExtraParameters(DecimalOperators::calculateShortRescaleParameters)) .implementation(methodsGroup -> methodsGroup .methods("addShortShortLong", "addLongLongLong", "addShortLongLong", "addLongShortLong") .withExtraParameters(DecimalOperators::calculateLongRescaleParameters))) .build(); }
private static SqlScalarFunction decimalSubtractOperator() { TypeSignature decimalLeftSignature = parseTypeSignature("decimal(a_precision, a_scale)", ImmutableSet.of("a_precision", "a_scale")); TypeSignature decimalRightSignature = parseTypeSignature("decimal(b_precision, b_scale)", ImmutableSet.of("b_precision", "b_scale")); TypeSignature decimalResultSignature = parseTypeSignature("decimal(r_precision, r_scale)", ImmutableSet.of("r_precision", "r_scale")); Signature signature = Signature.builder() .kind(SCALAR) .operatorType(SUBTRACT) .longVariableConstraints( longVariableExpression("r_precision", "min(38, max(a_precision - a_scale, b_precision - b_scale) + max(a_scale, b_scale) + 1)"), longVariableExpression("r_scale", "max(a_scale, b_scale)")) .argumentTypes(decimalLeftSignature, decimalRightSignature) .returnType(decimalResultSignature) .build(); return SqlScalarFunction.builder(DecimalOperators.class) .signature(signature) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup .methods("subtractShortShortShort") .withExtraParameters(DecimalOperators::calculateShortRescaleParameters)) .implementation(methodsGroup -> methodsGroup .methods("subtractShortShortLong", "subtractLongLongLong", "subtractShortLongLong", "subtractLongShortLong") .withExtraParameters(DecimalOperators::calculateLongRescaleParameters))) .build(); }
private static SqlScalarFunction castFunctionFromDecimalTo(TypeSignature to, String... methodNames) { Signature signature = Signature.builder() .kind(SCALAR) .operatorType(CAST) .argumentTypes(parseTypeSignature("decimal(precision,scale)", ImmutableSet.of("precision", "scale"))) .returnType(to) .build(); return SqlScalarFunction.builder(DecimalCasts.class) .signature(signature) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup .methods(methodNames) .withExtraParameters((context) -> { long precision = context.getLiteral("precision"); long scale = context.getLiteral("scale"); Number tenToScale; if (isShortDecimal(context.getParameterTypes().get(0))) { tenToScale = longTenToNth(intScale(scale)); } else { tenToScale = bigIntegerTenToNth(intScale(scale)); } return ImmutableList.of(precision, scale, tenToScale); }))) .build(); }
private static SqlScalarFunction decimalSubtractOperator() { TypeSignature decimalLeftSignature = parseTypeSignature("decimal(a_precision, a_scale)", ImmutableSet.of("a_precision", "a_scale")); TypeSignature decimalRightSignature = parseTypeSignature("decimal(b_precision, b_scale)", ImmutableSet.of("b_precision", "b_scale")); TypeSignature decimalResultSignature = parseTypeSignature("decimal(r_precision, r_scale)", ImmutableSet.of("r_precision", "r_scale")); Signature signature = Signature.builder() .kind(SCALAR) .operatorType(SUBTRACT) .longVariableConstraints( longVariableExpression("r_precision", "min(38, max(a_precision - a_scale, b_precision - b_scale) + max(a_scale, b_scale) + 1)"), longVariableExpression("r_scale", "max(a_scale, b_scale)")) .argumentTypes(decimalLeftSignature, decimalRightSignature) .returnType(decimalResultSignature) .build(); return SqlScalarFunction.builder(DecimalOperators.class) .signature(signature) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup .methods("subtractShortShortShort") .withExtraParameters(DecimalOperators::calculateShortRescaleParameters)) .implementation(methodsGroup -> methodsGroup .methods("subtractShortShortLong", "subtractLongLongLong", "subtractShortLongLong", "subtractLongShortLong") .withExtraParameters(DecimalOperators::calculateLongRescaleParameters))) .build(); }
private static SqlScalarFunction betweenOperator() { Signature signature = Signature.builder() .kind(SCALAR) .operatorType(BETWEEN) .argumentTypes(DECIMAL_SIGNATURE, DECIMAL_SIGNATURE, DECIMAL_SIGNATURE) .returnType(parseTypeSignature(BOOLEAN)) .build(); return SqlScalarFunction.builder(DecimalInequalityOperators.class) .signature(signature) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup .methods("betweenShortShortShort", "betweenLongLongLong"))) .build(); }
private static SqlScalarFunction betweenOperator() { Signature signature = Signature.builder() .kind(SCALAR) .operatorType(BETWEEN) .argumentTypes(DECIMAL_SIGNATURE, DECIMAL_SIGNATURE, DECIMAL_SIGNATURE) .returnType(parseTypeSignature(BOOLEAN)) .build(); return SqlScalarFunction.builder(DecimalInequalityOperators.class) .signature(signature) .deterministic(true) .choice(choice -> choice .implementation(methodsGroup -> methodsGroup .methods("betweenShortShortShort", "betweenLongLongLong"))) .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); }
@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 castFunctionToDecimalFromBuilder(TypeSignature from, boolean nullableResult, String... methodNames) { Signature signature = Signature.builder() .kind(SCALAR) .operatorType(CAST) .argumentTypes(from) .returnType(parseTypeSignature("decimal(precision,scale)", ImmutableSet.of("precision", "scale"))) .build(); return SqlScalarFunction.builder(DecimalCasts.class) .signature(signature) .deterministic(true) .choice(choice -> choice .nullableResult(nullableResult) .implementation(methodsGroup -> methodsGroup .methods(methodNames) .withExtraParameters((context) -> { DecimalType resultType = (DecimalType) context.getReturnType(); Number tenToScale; if (isShortDecimal(resultType)) { tenToScale = longTenToNth(resultType.getScale()); } else { tenToScale = bigIntegerTenToNth(resultType.getScale()); } return ImmutableList.of(resultType.getPrecision(), resultType.getScale(), tenToScale); }))).build(); }