Calcite Planner状态转换异常:无法从STATE_5_CONVERTED切换至STATE_2_READY
Calcite Planner调用reset()后仍出现状态转换异常的解决思路
问题描述
每次调用reset()方法重置Calcite Planner后,依然抛出非法状态转换异常,具体异常信息如下:
java.lang.IllegalArgumentException: cannot move to STATE_2_READY from STATE_5_CONVERTED
异常堆栈:
at org.apache.calcite.prepare.PlannerImpl.ensure(PlannerImpl.java:148) at org.apache.calcite.prepare.PlannerImpl.parse(PlannerImpl.java:212) at org.apache.calcite.tools.Planner.parse(Planner.java:50) at com.sql.calcite.hbase.driver.SqlHepTest.doParse(SqlHepTest.java:102) at com.sql.calcite.hbase.driver.SqlHepTest.parseDataLineage(SqlHepTest.java:90) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
核心原因
Calcite的PlannerImpl是有状态的,reset()方法并非总能完全重置所有内部状态(尤其是在执行到STATE_5_CONVERTED阶段后),导致后续调用parse()时状态校验失败。
解决方法
- 放弃复用Planner实例:每次处理SQL时直接创建新的Planner实例,而非复用旧实例调用
reset()。示例代码:
// 每次处理SQL都创建新的Planner Planner planner = Frameworks.getPlanner(config); try { // 执行parse、validate、convert等流程 } finally { planner.close(); }
- 严格控制reset()调用时机:确保
reset()在Planner处于可重置状态时调用(比如未执行到convert阶段,或完成所有流程后立即调用)。若已进入STATE_5_CONVERTED,reset()无法正确回退到初始状态。 - 升级Calcite版本:部分旧版本Calcite存在
reset()状态重置不彻底的bug,升级到1.30.0及以上的稳定版本大概率能解决该问题。
内容的提问来源于stack exchange,提问作者A little yy
相关产品推荐
相关产品推荐

