当使用非空GROUP BY设置进行调用时,Presto聚合函数UDF抛出java.lang.reflect.InvocationTargetException,但否则就可以

时间:2019-03-15 00:28:38

标签: presto

我编写了一个用户定义的聚合函数,看到了以下行为。这样的查询可以正常工作,

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());
        }
    }
}

我很想听到关于这个问题可能是什么的任何想法,因为我很困惑。

0 个答案:

没有答案