in velox/functions/prestosql/aggregates/ApproxPercentileAggregate.cpp [491:586]
bool registerApproxPercentile(const std::string& name) {
std::vector<std::shared_ptr<exec::AggregateFunctionSignature>> signatures;
for (const auto& inputType :
{"tinyint", "smallint", "integer", "bigint", "real", "double"}) {
signatures.push_back(exec::AggregateFunctionSignatureBuilder()
.returnType(inputType)
.intermediateType("varbinary")
.argumentType(inputType)
.argumentType("double")
.build());
signatures.push_back(exec::AggregateFunctionSignatureBuilder()
.returnType(inputType)
.intermediateType("varbinary")
.argumentType(inputType)
.argumentType("bigint")
.argumentType("double")
.build());
}
exec::registerAggregateFunction(
name,
std::move(signatures),
[name](
core::AggregationNode::Step step,
const std::vector<TypePtr>& argTypes,
const TypePtr& resultType) -> std::unique_ptr<exec::Aggregate> {
auto isRawInput = exec::isRawInput(step);
auto hasWeight = argTypes.size() == 3;
if (isRawInput) {
VELOX_USER_CHECK_GE(
argTypes.size(), 2, "{} takes 2 or 3 arguments", name);
VELOX_USER_CHECK_LE(
argTypes.size(), 3, "{} takes 2 or 3 arguments", name);
if (hasWeight) {
VELOX_USER_CHECK_EQ(
argTypes[1]->kind(),
TypeKind::BIGINT,
"The type of the weight argument of {} must be BIGINT",
name);
}
VELOX_USER_CHECK_EQ(
argTypes.back()->kind(),
TypeKind::DOUBLE,
"The type of the percentile argument of {} must be DOUBLE",
name);
} else {
VELOX_USER_CHECK_EQ(
argTypes.size(),
1,
"The type of partial result for {} must be VARBINARY",
name);
VELOX_USER_CHECK_GE(
argTypes[0]->kind(),
TypeKind::VARBINARY,
"The type of partial result for {} must be VARBINARY",
name);
}
if (!isRawInput && exec::isPartialOutput(step)) {
return std::make_unique<ApproxPercentileAggregate<double>>(
false, VARBINARY());
}
TypePtr type = isRawInput ? argTypes[0] : resultType;
switch (type->kind()) {
case TypeKind::TINYINT:
return std::make_unique<ApproxPercentileAggregate<int8_t>>(
hasWeight, resultType);
case TypeKind::SMALLINT:
return std::make_unique<ApproxPercentileAggregate<int16_t>>(
hasWeight, resultType);
case TypeKind::INTEGER:
return std::make_unique<ApproxPercentileAggregate<int32_t>>(
hasWeight, resultType);
case TypeKind::BIGINT:
return std::make_unique<ApproxPercentileAggregate<int64_t>>(
hasWeight, resultType);
case TypeKind::REAL:
return std::make_unique<ApproxPercentileAggregate<float>>(
hasWeight, resultType);
case TypeKind::DOUBLE:
return std::make_unique<ApproxPercentileAggregate<double>>(
hasWeight, resultType);
default:
VELOX_USER_FAIL(
"Unsupported input type for {} aggregation {}",
name,
type->toString());
}
});
return true;
}