tispark执行sql,where条件中筛选日期报错

tidb版本:6.1.2
spark版本:3.1.2
tispark版本:3.0.1

执行sql:
select create_time from call_log
where create_time > ‘2023-01-01’
limit 100

报错:Error operating EXECUTE_STATEMENT: com.pingcap.tikv.exception.TypeException: Error parsing string 2020-06-01 to datetime
at com.pingcap.tikv.types.Converter.convertToDateTime(Converter.java:248)
at com.pingcap.tikv.types.AbstractDateTimeType.encodeKey(AbstractDateTimeType.java:103)
at com.pingcap.tikv.types.DataType.encodeKey(DataType.java:424)
at com.pingcap.tikv.key.TypedKey.encodeKey(TypedKey.java:68)
at com.pingcap.tikv.key.TypedKey.(TypedKey.java:36)
at com.pingcap.tikv.key.TypedKey.toTypedKey(TypedKey.java:59)
at com.pingcap.tikv.expression.ComparisonBinaryExpression$NormalizedPredicate.getTypedLiteral(ComparisonBinaryExpression.java:203)
at com.pingcap.tikv.expression.visitor.PrunedPartitionBuilder.visit(PrunedPartitionBuilder.java:71)
at com.pingcap.tikv.expression.visitor.PrunedPartitionBuilder.visit(PrunedPartitionBuilder.java:35)
at com.pingcap.tikv.expression.ComparisonBinaryExpression.accept(ComparisonBinaryExpression.java:81)
at com.pingcap.tikv.expression.visitor.RangeSetBuilder.buildRange(RangeSetBuilder.java:137)

不带where条件执行select create_time from call_log limit 100 结果正常

隐式转换报错,这个日志挺明显的吧?

create_time是什么数据类型?


看看类型吧

在tidb中是datetime类型,但是我使用
select create_time from ods_esb.ob_call_log call_log
where create_time > to_date(‘20230101’,‘yyyyMMdd’)
limit 100
也是同样的错误

在tidb中是datetime类型,试过了to_date和to_timestamp,都查不出数据

我执行show create table 报org.apache.spark.sql.AnalysisException: SHOW CREATE TABLE is not supported for v2 tables.

建表语句,样例数据SQL来一些,我找个环境跑跑试一下

sql.txt (1.1 MB)

用你的例子没啥问题:

我也跑了跑,其他表都没问题,不知道是不是数据的原因,怪了

感觉可能是,你这个地方查的是 2023 年,报错是 2020 年,感觉是你查询内容解析有问题。

刚才测的是测试环境的数据,我先拿正式环境的部分数据试试


你看我的执行计划,就是 index scan,tikv 这边索引过滤出相关数据。没感觉需要数据转换。直接参数转换为2021-07-07 00:00:00.0 做的比较。

你可以先看看执行计划
是否一致呗

哦,我复现了,这个表如果加上表分区,就会报这个错

在tidb里面,这个表分区是不是没什么用?如果我删除表分区会删除数据吗?
image

你好,TiSpark 目前对读取 RANGE COLUMNS 表支持还不够完善
你可以在这里 https://github.com/pingcap/tispark/issues 提一个你使用 RANGE COLUMNS 时遇到的问题。后续解决我们可以在这个 issue 讨论。
另外针对你的问题,在修复之前,你可以暂时使用 RANGE 分区。如下

CREATE TABLE `test`.`range` ( `id` INT ( 11 ) NOT NULL, `ct` datetime NULL DEFAULT NULL ) PARTITION BY RANGE (to_days(ct)) (
	PARTITION `p0`
	VALUES
	LESS THAN (to_days('2020-01-01'))
	)

我查了一下原因,目前 string 转换为 datetime 时,需要为 yyyy-MM-dd HH:mm:ss 的格式。
你可以这样定义:partition p202005 values less than (“2020-06-01 00:00:00”)

参考
https://docs.pingcap.com/zh/tidb/dev/partitioned-table#range-columns-分区

在 TiSpark 3.0 中这样定义仍有问题(bug),在 TiSpark >= 3.1 之后这样定义不再有问题