in velox/experimental/codegen/udf_manager/UDFManager.cpp [21:215]
void registerVeloxArithmeticUDFs(UDFManager& udfManager) {
const std::vector<std::string> arithmeticHeaders = {
"\"velox/functions/prestosql/CheckedArithmeticImpl.h\"",
"\"velox/functions/prestosql/ArithmeticImpl.h\""};
auto getDefaultArithmeticUDF = [&]() {
return UDFInformation()
.withHeaderFiles(arithmeticHeaders)
.withNullMode(ExpressionNullMode::NullInNullOut)
.withIsOptionalArguments(false)
.withIsOptionalOutput(false)
.withOutputForm(OutputForm::Return)
.withCodegenNullInNullOutChecks(true);
};
// Helper function to register arithmetic UDF.
auto registerUDF = [&](const std::unordered_set<std::string>& veloxNames,
const std::string& calledFunctionName,
const std::vector<velox::TypeKind>& argumentsTypes) {
udfManager.registerUDF(getDefaultArithmeticUDF()
.withVeloxFunctionNames(veloxNames)
.withCalledFunctionName(fmt::format(
"functions::{}", calledFunctionName))
.withArgumentsLookupTypes(argumentsTypes));
};
// Matches registerBinaryIntegral in Velox.
auto registerBinaryIntegralUDF = [&](const std::unordered_set<std::string>&
veloxNames,
const std::string& calledFunctionName) {
registerUDF(
veloxNames, calledFunctionName, {TypeKind::BIGINT, TypeKind::BIGINT});
registerUDF(
veloxNames, calledFunctionName, {TypeKind::INTEGER, TypeKind::INTEGER});
};
// Matches registerUnaryIntegral in Velox.
auto registerUnaryIntegralUDF =
[&](const std::unordered_set<std::string>& veloxNames,
const std::string& calledFunctionName) {
registerUDF(veloxNames, calledFunctionName, {TypeKind::BIGINT});
registerUDF(veloxNames, calledFunctionName, {TypeKind::INTEGER});
registerUDF(veloxNames, calledFunctionName, {TypeKind::SMALLINT});
registerUDF(veloxNames, calledFunctionName, {TypeKind::TINYINT});
};
// Matches registerBinaryFloatingPoint in Velox.
auto registerBinaryFloatingPointUDF =
[&](const std::unordered_set<std::string>& veloxNames,
const std::string& calledFunctionName) {
registerUDF(
veloxNames, calledFunctionName, {TypeKind::REAL, TypeKind::REAL});
registerUDF(
veloxNames,
calledFunctionName,
{TypeKind::DOUBLE, TypeKind::DOUBLE});
};
// Matches registerUnaryFloatingPointUDF in Velox.
auto registerUnaryFloatingPointUDF =
[&](const std::unordered_set<std::string>& veloxNames,
const std::string& calledFunctionName) {
registerUDF(veloxNames, calledFunctionName, {TypeKind::REAL});
registerUDF(veloxNames, calledFunctionName, {TypeKind::DOUBLE});
};
// Matches registerUnaryNumeric in Velox.
auto registerUnaryNumeric =
[&](const std::unordered_set<std::string>& veloxNames,
const std::string& calledFunctionName) {
registerUnaryFloatingPointUDF(veloxNames, calledFunctionName);
registerUnaryIntegralUDF(veloxNames, calledFunctionName);
};
registerBinaryIntegralUDF({"plus"}, "checkedPlus");
registerBinaryFloatingPointUDF({"plus"}, "plus");
registerBinaryIntegralUDF({"minus"}, "checkedMinus");
registerBinaryFloatingPointUDF({"minus"}, "minus");
registerBinaryIntegralUDF({"multiply"}, "checkedMultiply");
registerBinaryFloatingPointUDF({"multiply"}, "multiply");
registerBinaryIntegralUDF({"divide"}, "checkedDivide");
registerBinaryFloatingPointUDF({"divide"}, "divide");
registerUnaryIntegralUDF({"negate"}, "checkedNegate");
registerUnaryFloatingPointUDF({"negate"}, "negate");
registerBinaryIntegralUDF({"modulus"}, "checkedModulus");
registerUnaryNumeric({"abs"}, "abs");
registerUnaryNumeric({"floor"}, "floor");
registerUnaryNumeric({"ceil", "ceiling"}, "ceil");
// Round function
UDFInformation roundUDF = getDefaultArithmeticUDF()
.withVeloxFunctionNames({"round"})
.withCalledFunctionName("functions::round");
udfManager.registerUDF(roundUDF.withArgumentsLookupTypes(
{TypeKind::INTEGER, TypeKind::INTEGER}));
udfManager.registerUDF(
roundUDF.withArgumentsLookupTypes({TypeKind::BIGINT, TypeKind::INTEGER}));
udfManager.registerUDF(roundUDF.withArgumentsLookupTypes(
{TypeKind::SMALLINT, TypeKind::INTEGER}));
udfManager.registerUDF(roundUDF.withArgumentsLookupTypes(
{TypeKind::TINYINT, TypeKind::INTEGER}));
udfManager.registerUDF(roundUDF.withArgumentsLookupTypes(
{TypeKind::TINYINT, TypeKind::INTEGER}));
udfManager.registerUDF(
roundUDF.withArgumentsLookupTypes({TypeKind::DOUBLE, TypeKind::INTEGER}));
udfManager.registerUDF(
roundUDF.withArgumentsLookupTypes({TypeKind::REAL, TypeKind::INTEGER}));
// Second argument is optional
udfManager.registerUDF(
roundUDF.withArgumentsLookupTypes({TypeKind::INTEGER}));
udfManager.registerUDF(roundUDF.withArgumentsLookupTypes({TypeKind::BIGINT}));
udfManager.registerUDF(
roundUDF.withArgumentsLookupTypes({TypeKind::SMALLINT}));
udfManager.registerUDF(
roundUDF.withArgumentsLookupTypes({TypeKind::TINYINT}));
udfManager.registerUDF(
roundUDF.withArgumentsLookupTypes({TypeKind::TINYINT}));
udfManager.registerUDF(roundUDF.withArgumentsLookupTypes({TypeKind::DOUBLE}));
udfManager.registerUDF(roundUDF.withArgumentsLookupTypes({TypeKind::REAL}));
// Register hash function
UDFInformation hashBaseUDF =
getDefaultArithmeticUDF()
.withHeaderFiles(
{"\"velox/experimental/codegen/functions/HashFunctionStub.h\""})
.withVeloxFunctionNames({"hash"})
.withCalledFunctionName("codegen::computeHashStub");
udfManager.registerUDF(
hashBaseUDF.withArgumentsLookupTypes({TypeKind::INTEGER}));
udfManager.registerUDF(
hashBaseUDF.withArgumentsLookupTypes({TypeKind::BIGINT}));
udfManager.registerUDF(
hashBaseUDF.withArgumentsLookupTypes({TypeKind::SMALLINT}));
udfManager.registerUDF(
hashBaseUDF.withArgumentsLookupTypes({TypeKind::TINYINT}));
udfManager.registerUDF(
hashBaseUDF.withArgumentsLookupTypes({TypeKind::DOUBLE}));
udfManager.registerUDF(
hashBaseUDF.withArgumentsLookupTypes({TypeKind::REAL}));
udfManager.registerUDF(
hashBaseUDF.withArgumentsLookupTypes({TypeKind::VARCHAR}));
// Between is added with arithmetic for now since its the only non-built in
// logical
UDFInformation betweenBaseUDF =
getDefaultArithmeticUDF()
.withHeaderFiles({"\"velox/functions_core/ComparisonsImpl.h\""})
.withVeloxFunctionNames({"between"})
.withCalledFunctionName("functions::between");
udfManager.registerUDF(betweenBaseUDF.withArgumentsLookupTypes(
{TypeKind::INTEGER, TypeKind::INTEGER, TypeKind::INTEGER}));
udfManager.registerUDF(betweenBaseUDF.withArgumentsLookupTypes(
{TypeKind::BIGINT, TypeKind::BIGINT, TypeKind::BIGINT}));
udfManager.registerUDF(betweenBaseUDF.withArgumentsLookupTypes(
{TypeKind::SMALLINT, TypeKind::SMALLINT, TypeKind::SMALLINT}));
udfManager.registerUDF(betweenBaseUDF.withArgumentsLookupTypes(
{TypeKind::TINYINT, TypeKind::TINYINT, TypeKind::TINYINT}));
udfManager.registerUDF(betweenBaseUDF.withArgumentsLookupTypes(
{TypeKind::DOUBLE, TypeKind::DOUBLE, TypeKind::DOUBLE}));
udfManager.registerUDF(betweenBaseUDF.withArgumentsLookupTypes(
{TypeKind::REAL, TypeKind::REAL, TypeKind::REAL}));
// Add rand udf
UDFInformation randUDF =
getDefaultArithmeticUDF()
.withCalledFunctionName(" folly::Random::randDouble01")
.withVeloxFunctionNames({"rand"})
.withHeaderFiles({"\"folly/Random.h\""});
udfManager.registerUDF(randUDF.withArgumentsLookupTypes({}));
}