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

posted on 2024-04-17 19:48  荣锋亮  阅读(11)  评论(0编辑  收藏  举报

导航