无法预知udaf返回数据的字节大小,如何处理serializeLength?

看了udaf的文档 https://docs.starrocks.io/zh-cn/latest/sql-reference/sql-functions/JAVA_UDF#开发-udaf
我想开发一个udaf,但是返回数据的字节大小无法预知,应该如何处理serializeLength?
比如想实现一个类似 array_agg的Java udf 。应该如何定义State ? State中的 serializeLength() 应该怎么处理?

1赞

这个因为跟我们没有打通 只能您那边在udaf里面加个检查限制 返回出来length大小再进行定义

这样可以, 大佬帮忙看下有没有性能更好的方法

public static class State {
        ArrayList<EventEntity> events = new ArrayList<>();
        public int serializeLength() { return 4 + objToByteArray(events).length; }
    }

    public State create() {
        return new State();
    }

    public void destroy(State state) {
    }

    public final void update(State state, String json) {
        if(json != null && json.length()>0) {
            EventEntity eventEntity = JSON.parseObject(json, EventEntity.class);
            state.events.add(eventEntity);
        }
    }

    public void serialize(State state, java.nio.ByteBuffer buff) {
        byte[] bytes = objToByteArray(state.events);
        int len = bytes.length;
        buff.putInt(len);
        buff.put(bytes);

    }

    public void merge(State state, java.nio.ByteBuffer buffer) {
        int len = buffer.getInt();
        byte[] val = new byte[len];
        buffer.get(val);

        try {
            final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(val));
            ArrayList<EventEntity> o = (ArrayList<EventEntity>) in.readObject();
            if(!o.isEmpty()) {
                state.events.addAll(o);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public String finalize(State state) {
        return JSON.toJSONString(state.events);
    }

    public static byte[] objToByteArray(Object obj) {
        try {
            ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteOutputStream);

            objectOutputStream.writeObject(obj);
            objectOutputStream.flush();
            objectOutputStream.close();

            return byteOutputStream.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

这种写法性能太差了, 远远比不上array_agg。
udf可以支持传数组参数不? 我先用array_agg聚合数据,再用udf处理我的逻辑。
我看Doris的文档,udf支持传数组参数了,而且udaf不用处理 serializeLength。
https://doris.apache.org/zh-CN/docs/dev/ecosystem/udf/java-user-defined-function#类型对应关系

解决了 update中收到数据直接转为byte[]。 serialize和merge中就不需要序列化和反序列化了。
整型都是定长字节数。对于字符串类型会麻烦一点,简单处理截取成定长字节,复杂处理再用一个字节存字符串长度。

2赞