我编写了一个用户定义的聚合函数,看到了以下行为。这样的查询可以正常工作,
SELECT
my_aggregate_function(column)
FROM table
位置:
SELECT
a,
my_aggregate_function(column)
FROM table
GROUP BY
1
抛出一个java.lang.reflect.InvocationTargetException
。我希望编写聚合函数时一定搞砸了。该函数是hyperloglog算法的实现,但经过修改后可以从另一系统记录的base64编码格式中提取数据:
@AggregationFunction("hll_merge")
public final class HyperLogLogAggregation
{
private HyperLogLogAggregation()
{
}
// This function tells us how to process rows into the accumulator state
@InputFunction
public static void input(@AggregationState HyperLogLogState state, @SqlType(StandardTypes.VARCHAR) Slice registers)
{
byte[] decodedBytes = Base64.getDecoder().decode(registers.getBytes());
DynamicSliceOutput bytesToDeserialize = new DynamicSliceOutput(decodedBytes.length)
.appendBytes(decodedBytes);
merge(state, HyperLogLog.newInstance(bytesToDeserialize.slice()));
}
// This function tells us how to combine accumulators
@CombineFunction
public static void combine(@AggregationState HyperLogLogState state, @AggregationState HyperLogLogState otherState)
{
merge(state, otherState.getHyperLogLog());
}
// This function takes our state and merges in a new HLL.
private static void merge(@AggregationState HyperLogLogState state, HyperLogLog input)
{
HyperLogLog previous = state.getHyperLogLog();
if (previous == null) {
state.setHyperLogLog(input);
state.addMemoryUsage(input.estimatedMemorySize());
}
else {
state.addMemoryUsage(-previous.estimatedMemorySize());
previous.mergeWith(input);
state.addMemoryUsage(previous.estimatedMemorySize());
}
}
@OutputFunction(StandardTypes.VARCHAR)
public static void output(@AggregationState HyperLogLogState state, BlockBuilder out)
{
HyperLogLog hll = state.getHyperLogLog();
if (hll == null) {
out.appendNull();
}
else {
Slice output = hll.serialize();
String encodedData = Base64.getEncoder().encodeToString(output.getBytes());
DynamicSliceOutput outSlice = new DynamicSliceOutput(encodedData.length());
outSlice.appendBytes(encodedData.getBytes());
VARCHAR.writeSlice(out, outSlice.slice());
}
}
}
我很想听到关于这个问题可能是什么的任何想法,因为我很困惑。