dremio No enum constant com.dremio.common.types.TypeProtos.MinorType.TIMESTAMPMICRO 问题简单说明
现象
此问题一般出现了我们对于数据源的物理表进行了反射(源表包含时间戳类型的数据),但是我们希望直接使用反射里边的parquet 文件格式数据,此时使用预览默认是可以读取parquet 数据的,但是当我们实际查询的时候发现可能提示此问题
- 参考异常调用链
VALIDATION ERROR: No enum constant com.dremio.common.types.TypeProtos.MinorType.TIMESTAMPMICRO
SQL Query SELECT * FROM s3.datas."0_0_0_3.parquet"
(java.lang.IllegalArgumentException) No enum constant com.dremio.common.types.TypeProtos.MinorType.TIMESTAMPMICRO
java.lang.Enum.valueOf():240
com.dremio.common.types.TypeProtos$MinorType.valueOf():21
com.dremio.common.util.MajorTypeHelper.getMinorTypeFromArrowMinorType():162
com.dremio.common.expression.CompleteType.toMinorType():220
com.dremio.exec.planner.sql.CalciteArrowHelper$CompleteTypeWrapper.toCalciteType():285
com.dremio.exec.planner.sql.CalciteArrowHelper.toCalciteType():391
com.dremio.exec.planner.sql.CalciteArrowHelper$Schema.lambda$toCalciteRecordType$1():87
java.lang.Iterable.forEach():75
com.dremio.exec.planner.sql.CalciteArrowHelper$Schema.toCalciteRecordType():84
com.dremio.exec.store.NamespaceTable.getRowType():119
com.dremio.exec.catalog.DremioPrepareTable$1.get():69
com.dremio.exec.catalog.DremioPrepareTable$1.get():66
com.dremio.exec.catalog.DremioPrepareTable.getRowType():95
org.apache.calcite.sql.validate.TableNamespace.validateImpl():59
org.apache.calcite.sql.validate.AbstractNamespace.validate():84
org.apache.calcite.sql.validate.SqlValidatorImpl.validateNamespace():1042
org.apache.calcite.sql.validate.AbstractNamespace.getRowType():115
org.apache.calcite.sql.validate.IdentifierNamespace.validateImpl():227
org.apache.calcite.sql.validate.AbstractNamespace.validate():84
org.apache.calcite.sql.validate.SqlValidatorImpl.validateNamespace():1042
org.apache.calcite.sql.validate.SqlValidatorImpl.validateQuery():1002
org.apache.calcite.sql.validate.SqlValidatorImpl.validateFrom():3296
org.apache.calcite.sql.validate.SqlValidatorImpl.validateFrom():3278
org.apache.calcite.sql.validate.SqlValidatorImpl.validateSelect():3557
org.apache.calcite.sql.validate.SelectNamespace.validateImpl():60
org.apache.calcite.sql.validate.AbstractNamespace.validate():84
org.apache.calcite.sql.validate.SqlValidatorImpl.validateNamespace():1042
org.apache.calcite.sql.validate.SqlValidatorImpl.validateQuery():1002
org.apache.calcite.sql.SqlSelect.validate():247
org.apache.calcite.sql.validate.SqlValidatorImpl.validateScopedExpression():977
com.dremio.exec.planner.sql.SqlValidatorImpl.validate():127
com.dremio.exec.planner.sql.SqlValidatorAndToRelContext.validate():95
com.dremio.exec.planner.sql.handlers.SqlToRelTransformer.validateNode():218
com.dremio.exec.planner.sql.handlers.SqlToRelTransformer.validateThenSqlToRel():158
com.dremio.exec.planner.sql.handlers.SqlToRelTransformer.validateAndConvert():187
com.dremio.exec.planner.sql.handlers.SqlToRelTransformer.validateAndConvert():98
com.dremio.exec.planner.sql.handlers.query.NormalHandler.getPlan():77
com.dremio.exec.planner.sql.handlers.commands.HandlerToExec.plan():56
com.dremio.exec.work.foreman.AttemptManager.plan():638
com.dremio.exec.work.foreman.AttemptManager.lambda$run$4():519
com.dremio.service.commandpool.ReleasableBoundCommandPool.lambda$getWrappedCommand$3():156
com.dremio.service.commandpool.CommandWrapper.run():73
com.dremio.context.RequestContext.run():103
com.dremio.common.concurrent.ContextMigratingExecutorService.lambda$decorate$4():246
com.dremio.common.concurrent.ContextMigratingExecutorService$ComparableRunnable.run():222
java.util.concurrent.Executors$RunnableAdapter.call():515
java.util.concurrent.FutureTask.run():264
java.util.concurrent.ThreadPoolExecutor.runWorker():1128
java.util.concurrent.ThreadPoolExecutor$Worker.run():628
java.lang.Thread.run():829
原因
核心是时间戳数据格式的问题,可能使用了精度为6的,但是默认dremio 对于parquet的精度是3,造成查询提示数据类型不正常
但是对于iceberg dremio 的writer dremio 单独进行了类型映射处理,我们会发现实际反射是不影响的,但是如果希望查询paruqet 格式的就有问题,实际上通过一些parquet 查看工具也可以看出parquet 文件时间格式问题
iceberg 的处理(写入)
public void setup() throws IOException {
this.fs = plugin.createFS(location, queryUser, context);
this.batchSchema = incoming.getSchema();
if (this.isIcebergWriter) {
this.icebergBatchSchema = new BatchSchema(convertSchemaMilliToMicro(batchSchema.getFields()));
说明
以前我碰到过一个类似的时间戳精度问题,也说明过,可以参考,实际一个原则还是对于时间格式的精度必须统一,规避一些问题
参考资料
sabot/kernel/src/main/java/com/dremio/exec/store/parquet/ParquetRecordWriter.java
https://www.cnblogs.com/rongfengliang/p/17960740
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2022-04-17 使用openresty-lua-types+TypeScriptToLua+test-nginx 开发强类型的nginx lua 模块
2022-04-17 openresty-lua-types openresty typescript 类型定义
2022-04-17 TypeScriptToLua 使用typescript 开发lua 功能试用
2022-04-17 TypeScriptToLua npm 集成玩法
2021-04-17 streamsets http client 请求过大问题
2021-04-17 使用graalvm 运行cube.js
2021-04-17 使用presto-gateway 进行trino 扩展