starrocks读取paimon外表timestamp字段过滤漏扫数据

starrocks版本:3.3.21
spark版本:3.5.x

starrocks读取paimon表的时候,如果paimon表的timestamp类型是ltz类型(spark建表timestamp字段的默认类型,也即flink的timestamp_ltz类型),查询使用该字段作为条件,会出现漏扫数据的问题。
复现如下:

  1. spark建paimon表
    create table test_starrocks_paimon_ltz(ts_ltz timestamp) using paimon TBLPROPERTIES (‘primary-key’ = ‘ts_ltz’,‘bucket’=‘1’);

  2. spark独立写两条数据,分别生成两个parquet文件
    insert into test_starrocks_paimon_ltz values (‘2026-03-24 02:00:00’); – 2点的数据
    insert into test_starrocks_paimon_ltz values (‘2026-03-24 22:00:00’); – 22点的数据

  3. starrocks带条件查询(不带条件两条数据都可以检索到)
    select * from paimon_catalog.test.test_starrocks_paimon_ltz where ts_ltz >= ‘2026-03-24’;
    返回2026-03-24 22:00:00
    可以看到2点的数据没有检索出来

  4. parquet工具查看parquet文件的meta信息,ts_ltz字段信息如下:
    ts_ltz: INT64 ZSTD DO:0 FPO:120 SZ:40/31/0.78 VC:1 ENC:PLAIN,BIT_PACKED ST:[min: 2026-03-23T18:00:00.000000, max: 2026-03-23T18:00:00.000000, num_nulls: 0]
    可以看到2点的数据所在的parquet文件的ts_ltz字段的min max是和实际数据差8小时的,存储的是utc时间,时间范围落到了23号。

  5. parquet工具查看parquet文件的schema信息,ts_ltz字段的类型:
    {
    “Path”: “ts_ltz”,
    “Type”: “INT64”,
    “TypeLength”: null,
    “LogicalType”: {
    “Name”: “TIMESTAMP”,
    “IsAdjustedToUTC”: true,
    “Unit”: “MICROS”
    }

starrocks通过ts_ltz条件过滤数据的时候,可能参考了parquet文件的min max字段来跳过文件扫描优化查询性能,但是又没有正确处理timestamp字段的时区,导致错误的跳过了文件,最终数据漏了。

– Spark 建表时明确指定 NTZ

CREATE TABLE test_starrocks_paimon_ntz(

ts_ntz TIMESTAMP WITHOUT TIME ZONE

) USING paimon;

– 或 Flink 中使用 TIMESTAMP(3)