Skip to content

feat(lance): support TIME type - #478

Merged
lxy-9602 merged 1 commit into
apache:mainfrom
SteNicholas:PAIMON-477
Oct 28, 2026
Merged

lxy-9602 merged 1 commit into
apache:mainfrom
SteNicholas:PAIMON-477

Conversation

@SteNicholas

@SteNicholas SteNicholas commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

Purpose

Linked issue: close #477

Paimon Java accepts TIME columns in Lance data files
(LanceFileFormat.LanceRowTypeVisitor.visit(TimeType)) and writes them as Arrow TIMEMILLI
(time32[ms]) through ArrowFieldTypeConversion. Paimon C++ has represented TIME as
time32[ms] since #378, but rejected it for Lance:

  • SchemaValidation::ValidateLanceDataField() had no TIME32 case, so a TIME column, at top
    level or nested in ARRAY or ROW, failed with Lance file format does not support type time32[ms].
  • LanceStatsExtractor::CreateEmptyStats() had no TIME32 case either, so lifting only the
    validation would still fail to finalize an append data file with a TIME column, with
    cannot create empty Lance statistics for type time32[ms].

This change:

  • Accepts TIME32 in ValidateLanceDataField(). The existing recursion covers TIME nested in
    ARRAY and ROW, and TableSchema::Create() still rejects non-millisecond units.
  • Returns empty integer statistics for TIME32 in LanceStatsExtractor::CreateEmptyStats(),
    as VortexStatsExtractor does.
  • Needs no reader change: the declared precision comes from the paimon.time.precision field
    metadata of the table schema, and LanceFileBatchReader aligns each batch to the read type.

Tests

  • SchemaValidationTest.TestLanceDataTypes: millisecond TIME at top level and in
    ROW<ARRAY<TIME>> moves from the rejected to the accepted fields; second-unit TIME, top level
    and nested, is still rejected.
  • LanceFileFormatTest.WriteThenReadSupportedTypes: adds a top-level TIME column and
    ARRAY<TIME>, ROW<TIME> and ROW<ARRAY<TIME>> columns declared with precisions 0, 3, 6 and
    9. The data covers 0 and 86399999, null and empty arrays, null elements and null ROW children,
    and is read with batch sizes 1, 2 and 4. A batch imported directly from the reader checks that
    the returned Arrow type keeps the read schema's field metadata, including
    paimon.time.precision.
  • LanceFileFormatTest.ExtractStatistics: a TIME column yields an empty statistics entry.
  • TimeColumnWriteInteTest.TestAppendTimeColumnFinalize, generalized from
    VortexTimeColumnWriteInteTest: append write, finalize and read of a TIME column for both
    Lance and Vortex.
  • ScanAndReadInteTest.TestLanceJavaCompatibility and TestLancePythonCompatibility: the
    lance/append_java_compat and lance/append_python_compat fixtures are regenerated with
    Paimon Java and Paimon Python at the same commit as before (63ffd40), adding
    f_time_0 TIME(0) and f_time_3 TIME(3) columns with 00:00:00, 23:59:59.999, 12:34:56.789
    and NULL values. All other columns, values, options and commits are unchanged. Both writers
    store TIME in Lance as time32[ms] without precision metadata, so C++ reads the declared
    precision from the table schema. The fixture READMEs list the new columns and tie every
    writer-specific statement to the writer commit in their header.

API and Format

No API changes. No storage format changes: TIME is written to Lance as time32[ms], as in
Paimon Java.

Documentation

Yes. docs/source/user_guide/data_types.rst no longer lists TIME as not supported. It describes
the time32[ms] mapping, how the declared precision is kept in paimon.time.precision while
values keep millisecond precision, and which file formats read or write TIME. A note states its
limitations: only append-only tables support TIME, primary-key tables support it neither as a
primary key nor as a value column, a TIME column cannot be a partition or bucket key, and
predicates cannot reference TIME columns.

Generative AI tooling

Generated-by: Claude Code 2.1.311 (Claude Opus 5.5)

🤖 Generated with Claude Code

Comment thread docs/source/user_guide/data_types.rst Resolved
Paimon Java accepts TIME columns in Lance data files and writes them as
time32[ms], but Paimon C++ rejected TIME in Lance schema validation,
both at top level and nested in ARRAY or ROW. Accept TIME there, and
create empty integer statistics for a TIME column in LanceStatsExtractor
so that finalizing a Lance data file with one does not fail.

Document TIME in the data types guide, which still listed it as not
supported. Describe its time32[ms] mapping, how the declared precision
is kept and which file formats read or write it, and state that only
append-only tables support it and that it cannot be a partition or
bucket key or be referenced by predicates.

@lxy-9602 lxy-9602 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

@lxy-9602
lxy-9602 merged commit 1b3c690 into apache:main Oct 28, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Support TIME in Lance file format

2 participants