apache / apache/iotdb

[Bug] 在rc/1.3.3 版本中,UDAF函数中不支持2个时间序列。

Open
#16,777 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
6.4k
Forks
1.2k
Avg merge
1d 23h
Merged PRs (30d)
115

Description

### Search before asking

- [x] I searched in the [issues](https://github.com/apache/iotdb/issues) and found nothing similar.

### Version

1.3.3

### Describe the bug and provide the minimal reproduce step

基于example\udf\src\main\java\org\apache\iotdb\udf\UDAFExample.java,在validate 函数中修改为2个时间序列:

Image

执行sql:SELECT UDAFExample(Latitude, Longitude) as level FROM root.XXXX.D52010000_0001 where time =1472870568779 客户端提示错误:Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 301: Error occurred during executing UDAF#validate(UDFParameterValidator):
, please check whether the implementation of UDF is correct according to the udf-api description.java.lang.IndexOutOfBoundsException: Index: 1, Size: 1

datanode 提示错误:

2025-11-19 13:32:37,844 [pool-41-IoTDB-ClientRPC-Processor-12$20251119_053237_00066_1.1.0] WARN o.a.i.d.q.e.a.UDAFAccumulator:206 - Error occurred during executing UDAF, please check whether the implementation of UDF is correct according to the udf-api description.
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.ArrayList.rangeCheck(ArrayList.java:657)
at java.util.ArrayList.get(ArrayList.java:433)
at org.apache.iotdb.udf.api.customizer.parameter.UDFParameters.getDataType(UDFParameters.java:84)
at org.apache.iotdb.udf.api.customizer.parameter.UDFParameterValidator.validateInputSeriesDataType(UDFParameterValidator.java:99)
at org.apache.iotdb.udf.UDAFExample.validate(UDAFExample.java:81)
at org.apache.iotdb.db.queryengine.execution.aggregation.UDAFAccumulator.reflectAndValidateUDF(UDAFAccumulator.java:105)
at org.apache.iotdb.db.queryengine.execution.aggregation.UDAFAccumulator.beforeStart(UDAFAccumulator.java:84)
at org.apache.iotdb.db.queryengine.execution.aggregation.UDAFAccumulator.(UDAFAccumulator.java:72)
at org.apache.iotdb.db.queryengine.execution.aggregation.AccumulatorFactory.createAccumulator(AccumulatorFactory.java:49)
at org.apache.iotdb.db.queryengine.plan.planner.OperatorTreeGenerator.createRawDataAggregationOperator(OperatorTreeGenerator.java:1995)
at org.apache.iotdb.db.queryengine.plan.planner.OperatorTreeGenerator.visitRawDataAggregation(OperatorTreeGenerator.java:1977)
at org.apache.iotdb.db.queryengine.plan.planner.OperatorTreeGenerator.visitRawDataAggregation(OperatorTreeGenerator.java:316)
at org.apache.iotdb.db.queryengine.plan.planner.plan.node.process.RawDataAggregationNode.accept(RawDataAggregationNode.java:212)
at org.apache.iotdb.db.queryengine.plan.planner.OperatorTreeGenerator.dealWithConsumeChildrenOneByOneNode(OperatorTreeGenerator.java:3472)
at org.apache.iotdb.db.queryengine.plan.planner.OperatorTreeGenerator.visitIdentitySink(OperatorTreeGenerator.java:2665)
at org.apache.iotdb.db.queryengine.plan.planner.OperatorTreeGenerator.visitIdentitySink(OperatorTreeGenerator.java:316)
at org.apache.iotdb.db.queryengine.plan.planner.plan.node.sink.IdentitySinkNode.accept(IdentitySinkNode.java:75)
at org.apache.iotdb.db.queryengine.plan.planner.LocalExecutionPlanner.plan(LocalExecutionPlanner.java:92)
at org.apache.iotdb.db.queryengine.execution.fragment.FragmentInstanceManager.lambda$execDataQueryFragmentInstance$3(FragmentInstanceManager.java:163)
at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
at org.apache.iotdb.db.queryengine.execution.fragment.FragmentInstanceManager.execDataQueryFragmentInstance(FragmentInstanceManager.java:139)
at org.apache.iotdb.db.consensus.statemachine.dataregion.DataRegionStateMachine.read(DataRegionStateMachine.java:354)
at org.apache.iotdb.consensus.iot.IoTConsensusServerImpl.read(IoTConsensusServerImpl.java:276)
at org.apache.iotdb.consensus.iot.IoTConsensus.read(IoTConsensus.java:224)
at org.apache.iotdb.db.queryengine.execution.executor.RegionReadExecutor.execute(RegionReadExecutor.java:84)
at org.apache.iotdb.db.queryengine.plan.scheduler.FragmentInstanceDispatcherImpl.dispatchLocally(FragmentInstanceDispatcherImpl.java:455)
at org.apache.iotdb.db.queryengine.plan.scheduler.FragmentInstanceDispatcherImpl.dispatchOneInstance(FragmentInstanceDispatcherImpl.java:298)
at org.apache.iotdb.db.queryengine.plan.scheduler.FragmentInstanceDispatcherImpl.dispatchRead(FragmentInstanceDispatcherImpl.java:131)
at org.apache.iotdb.db.queryengine.plan.scheduler.FragmentInstanceDispatcherImpl.dispatch(FragmentInstanceDispatcherImpl.java:118)
at org.apache.iotdb.db.queryengine.plan.scheduler.ClusterScheduler.start(ClusterScheduler.java:117)
at org.apache.iotdb.db.queryengine.plan.planner.TreeModelPlanner.doSchedule(TreeModelPlanner.java:144)
at org.apache.iotdb.db.queryengine.plan.execution.QueryExecution.schedule(QueryExecution.java:267)
at org.apache.iotdb.db.queryengine.plan.execution.QueryExecution.start(QueryExecution.java:180)
at org.apache.iotdb.db.queryengine.plan.Coordinator.execution(Coordinator.java:134)
at org.apache.iotdb.db.queryengine.plan.Coordinator.executeForTreeModel(Coordinator.java:169)
at org.apache.iotdb.db.protocol.thrift.impl.ClientRPCServiceImpl.executeStatementInternal(ClientRPCServiceImpl.java:312)
at org.apache.iotdb.db.protocol.thrift.impl.ClientRPCServiceImpl.executeStatementV2(ClientRPCServiceImpl.java:778)
at org.apache.iotdb.service.rpc.thrift.IClientRPCService$Processor$executeStatementV2.getResult(IClientRPCService.java:4104)
at org.apache.iotdb.service.rpc.thrift.IClientRPCService$Processor$executeStatementV2.getResult(IClientRPCService.java:4084)
at org.apache.thrift.ProcessFunction.process(ProcessFunction.java:38)
at org.apache.iotdb.db.protocol.thrift.ProcessorWithMetrics.process(ProcessorWithMetrics.java:64)
at org.apache.thrift.server.TThreadPoolServer$WorkerProcess.run(TThreadPoolServer.java:248)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
2025-11-19 13:32:37,850 [pool-41-IoTDB-ClientRPC-Processor-12$20251119_053237_00066_1.1.0] WARN o.a.i.d.q.e.f.FragmentInstanceManager:202 - error when create FragmentInstanceExecution.
java.lang.RuntimeException: Error occurred during executing UDAF#validate(UDFParameterValidator):
, please check whether the implementation of UDF is correct according to the udf-api description.java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at org.apache.iotdb.db.queryengine.execution.aggregation.UDAFAccumulator.onError(UDAFAccumulator.java:210)
at org.apache.iotdb.db.queryengine.execution.aggregation.UDAFAccumulator.reflectAndValidateUDF(UDAFAccumulator.java:107)
at org.apache.iotdb.db.queryengine.execution.aggregation.UDAFAccumulator.beforeStart(UDAFAccumulator.java:84)
at org.apache.iotdb.db.queryengine.execution.aggregation.UDAFAccumulator.(UDAFAccumulator.java:72)
at org.apache.iotdb.db.queryengine.execution.aggregation.AccumulatorFactory.createAccumulator(AccumulatorFactory.java:49)
at org.apache.iotdb.db.queryengine.plan.planner.OperatorTreeGenerator.createRawDataAggregationOperator(OperatorTreeGenerator.java:1995)
at org.apache.iotdb.db.queryengine.plan.planner.OperatorTreeGenerator.visitRawDataAggregation(OperatorTreeGenerator.java:1977)
at org.apache.iotdb.db.queryengine.plan.planner.OperatorTreeGenerator.visitRawDataAggregation(OperatorTreeGenerator.java:316)
at org.apache.iotdb.db.queryengine.plan.planner.plan.node.process.RawDataAggregationNode.accept(RawDataAggregationNode.java:212)
at org.apache.iotdb.db.queryengine.plan.planner.OperatorTreeGenerator.dealWithConsumeChildrenOneByOneNode(OperatorTreeGenerator.java:3472)
at org.apache.iotdb.db.queryengine.plan.planner.OperatorTreeGenerator.visitIdentitySink(OperatorTreeGenerator.java:2665)
at org.apache.iotdb.db.queryengine.plan.planner.OperatorTreeGenerator.visitIdentitySink(OperatorTreeGenerator.java:316)
at org.apache.iotdb.db.queryengine.plan.planner.plan.node.sink.IdentitySinkNode.accept(IdentitySinkNode.java:75)
at org.apache.iotdb.db.queryengine.plan.planner.LocalExecutionPlanner.plan(LocalExecutionPlanner.java:92)
at org.apache.iotdb.db.queryengine.execution.fragment.FragmentInstanceManager.lambda$execDataQueryFragmentInstance$3(FragmentInstanceManager.java:163)
at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
at org.apache.iotdb.db.queryengine.execution.fragment.FragmentInstanceManager.execDataQueryFragmentInstance(FragmentInstanceManager.java:139)
at org.apache.iotdb.db.consensus.statemachine.dataregion.DataRegionStateMachine.read(DataRegionStateMachine.java:354)
at org.apache.iotdb.consensus.iot.IoTConsensusServerImpl.read(IoTConsensusServerImpl.java:276)
at org.apache.iotdb.consensus.iot.IoTConsensus.read(IoTConsensus.java:224)
at org.apache.iotdb.db.queryengine.execution.executor.RegionReadExecutor.execute(RegionReadExecutor.java:84)
at org.apache.iotdb.db.queryengine.plan.scheduler.FragmentInstanceDispatcherImpl.dispatchLocally(FragmentInstanceDispatcherImpl.java:455)
at org.apache.iotdb.db.queryengine.plan.scheduler.FragmentInstanceDispatcherImpl.dispatchOneInstance(FragmentInstanceDispatcherImpl.java:298)
at org.apache.iotdb.db.queryengine.plan.scheduler.FragmentInstanceDispatcherImpl.dispatchRead(FragmentInstanceDispatcherImpl.java:131)
at org.apache.iotdb.db.queryengine.plan.scheduler.FragmentInstanceDispatcherImpl.dispatch(FragmentInstanceDispatcherImpl.java:118)
at org.apache.iotdb.db.queryengine.plan.scheduler.ClusterScheduler.start(ClusterScheduler.java:117)
at org.apache.iotdb.db.queryengine.plan.planner.TreeModelPlanner.doSchedule(TreeModelPlanner.java:144)
at org.apache.iotdb.db.queryengine.plan.execution.QueryExecution.schedule(QueryExecution.java:267)
at org.apache.iotdb.db.queryengine.plan.execution.QueryExecution.start(QueryExecution.java:180)
at org.apache.iotdb.db.queryengine.plan.Coordinator.execution(Coordinator.java:134)
at org.apache.iotdb.db.queryengine.plan.Coordinator.executeForTreeModel(Coordinator.java:169)
at org.apache.iotdb.db.protocol.thrift.impl.ClientRPCServiceImpl.executeStatementInternal(ClientRPCServiceImpl.java:312)
at org.apache.iotdb.db.protocol.thrift.impl.ClientRPCServiceImpl.executeStatementV2(ClientRPCServiceImpl.java:778)
at org.apache.iotdb.service.rpc.thrift.IClientRPCService$Processor$executeStatementV2.getResult(IClientRPCService.java:4104)
at org.apache.iotdb.service.rpc.thrift.IClientRPCService$Processor$executeStatementV2.getResult(IClientRPCService.java:4084)
at org.apache.thrift.ProcessFunction.process(ProcessFunction.java:38)
at org.apache.iotdb.db.protocol.thrift.ProcessorWithMetrics.process(ProcessorWithMetrics.java:64)
at org.apache.thrift.server.TThreadPoolServer$WorkerProcess.run(TThreadPoolServer.java:248)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
2025-11-19 13:32:37,869 [pool-41-IoTDB-ClientRPC-Processor-12$20251119_053237_00066_1.1.0] WARN o.a.i.d.q.p.s.FragmentInstanceDispatcherImpl:457 - Error occurred during executing UDAF#validate(UDFParameterValidator):
, please check whether the implementation of UDF is correct according to the udf-api description.java.lang.IndexOutOfBoundsException: Index: 1, Size: 1

### What did you expect to see?

验证通过

### What did you see instead?

Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 301: Error occurred during executing UDAF#validate(UDFParameterValidator):
, please check whether the implementation of UDF is correct according to the udf-api description.java.lang.IndexOutOfBoundsException: Index: 1, Size: 1

### Anything else?

Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 301: Error occurred during executing UDAF#validate(UDFParameterValidator):
, please check whether the implementation of UDF is correct according to the udf-api description.java.lang.IndexOutOfBoundsException: Index: 1, Size: 1

### Are you willing to submit a PR?

- [ ] I'm willing to submit a PR!

Contributor guide

Open the contributing guide

Research direction

Start with example/udf/src/main/java/org/apache/iotdb/udf/UDAFExample.java and inspect how validate calls UDFParameterValidator.validateInputSeriesDataType for two input series. Reproduce the SELECT UDAFExample(Latitude, Longitude) query, then trace UDFParameters.getDataType in the reported stack. Done means the two-series UDAF validation no longer raises IndexOutOfBoundsException.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.