Skip to content

Add support for timestamp (and duration) types in leaf data hashing #18

Description

@kurodo3

Summary

ArrowDigester.hash_table() raises NotImplementedError: Unsupported leaf type: timestamp[us, tz=UTC] when a table contains any timestamp column. This blocks using datetime.datetime values as data or tag values in projects that rely on starfix for content-addressable hashing.

Reproduction

import pyarrow as pa
from starfix import ArrowDigester
from datetime import datetime, timezone

dt = datetime(2024, 1, 15, 12, 0, 0, tzinfo=timezone.utc)
table = pa.table({"ts": pa.array([dt], type=pa.timestamp("us", tz="UTC"))})
ArrowDigester.hash_table(table)
# NotImplementedError: Unsupported leaf type: timestamp[us, tz=UTC]

Also fails for naive timestamps:

table = pa.table({"ts": pa.array([dt], type=pa.timestamp("us"))})
ArrowDigester.hash_table(table)
# NotImplementedError: Unsupported leaf type: timestamp[us]

Root cause

In arrow_digester.py, _element_size_for_type includes fixed-size types like date32 (4 bytes), date64 (8 bytes), time32 (4 bytes), and time64 (8 bytes), but is missing timestamp variants:

_sizes = {
    pa.int8(): 1, pa.uint8(): 1,
    pa.int16(): 2, pa.uint16(): 2, pa.float16(): 2,
    pa.int32(): 4, pa.uint32(): 4, pa.float32(): 4, pa.date32(): 4,
    pa.int64(): 8, pa.uint64(): 8, pa.float64(): 8, pa.date64(): 8,
}
# ← missing: timestamp (all units and timezones)
# ← missing: duration (all units)

Note that _data_type_to_value (used for schema hashing) already handles timestamp correctly — only the leaf data hashing step is missing.

Arrow storage layout

All timestamp variants and duration variants are stored as signed 64-bit integers in Arrow's physical layout (8 bytes per element). The unit (s, ms, us, ns) and timezone are schema-level metadata, not part of the data buffer. This means the fix is straightforward: treat timestamps and durations as fixed-size 8-byte values, just like int64.

Proposed fix

In _element_size_for_type, add handlers after the existing time32/time64 checks:

if pa.types.is_timestamp(dt):
    return 8  # int64 physical storage, unit/tz in schema metadata

if pa.types.is_duration(dt):
    return 8  # int64 physical storage, unit in schema metadata

Expected behavior

  • timestamp[us, tz=UTC] → hashed using 8-byte fixed-size data hashing (same as int64)
  • timestamp[us] → same
  • timestamp[s], timestamp[ms], timestamp[ns] → same
  • duration[us] etc. → same

Impact

Affects any use case where datetime (Python) values appear in Arrow tables — a very common pattern for tagging data with experiment dates, timestamps, dates of birth, etc. For example, orcapod (which depends on starfix) cannot hash tag values that are datetime.datetime objects as a result of this gap.

Version

starfix==0.3.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions