Skip to content

[WIP][SPARK-57811][SQL] Support string to nanosecond-precision timestamp coercion in comparisons and predicates#57223

Open
stevomitric wants to merge 2 commits into
apache:masterfrom
stevomitric:stevomitric/spark-57811-nanos
Open

[WIP][SPARK-57811][SQL] Support string to nanosecond-precision timestamp coercion in comparisons and predicates#57223
stevomitric wants to merge 2 commits into
apache:masterfrom
stevomitric:stevomitric/spark-57811-nanos

Conversation

@stevomitric

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Add non-ANSI type-coercion arms so that a string compared against a nanosecond-precision timestamp column (TIMESTAMP_NTZ(p)/TIMESTAMP_LTZ(p), p in [7, 9]) is cast to that nanos type, mirroring the existing microsecond TimestampType handling (StringPromotionTypeCoercion equality arms + TypeCoercion.findCommonTypeForBinaryComparison).

Why are the changes needed?

Without a nanos arm, a string compared to a nanos column loses sub-microsecond precision under legacy spark.sql.legacy.typeCoercion.datetimeToString.enabled=true instead of parsing at full precision like the microsecond types. ANSI mode is unchanged.

Does this PR introduce any user-facing change?

Yes. String vs nanosecond-timestamp comparisons now coerce the string to the nanos type with full precision (preview spark.sql.timestampNanosTypes.enabled).

How was this patch tested?

Extended existing suits and added golden file tests.

Was this patch authored or co-authored using generative AI tooling?

Generated-by: Claude Code

…oercion in comparisons and predicates

Type coercion previously handled only microsecond TimestampType when one
operand of a comparison or predicate is a string: the string was cast to
TimestampType so subsecond digits compared exactly. Nanosecond timestamp
types (Timestamp{LTZ,NTZ}NanosType) had no such arm, so a string compared
against a nanos column fell through to generic handling and lost the 7th-9th
fractional digits.

This adds the missing non-ANSI arms, mirroring the existing microsecond
handling: two Equality arms in StringPromotionTypeCoercion cast the string to
the concrete nanos operand type, and two findCommonTypeForBinaryComparison
cases in TypeCoercion return that nanos type for the range path. The concrete
family and precision of the timestamp operand are preserved, the arms are
ordered so equality fires before the range path, and legacy
castDatetimeToString is honored (range promotes both sides to string, equality
still casts the string to nanos). ANSI type coercion is intentionally left
unchanged.

Tests: TypeCoercionSuite "binary comparison with string promotion" gains
nanos assertions (all precisions, both families, plus a legacy-mode block that
exercises the new arms); TimestampNanosWideningSuiteBase adds an end-to-end
string-operand test; and the timestamp-{ltz,ntz}-nanos golden files add
equality/range/BETWEEN cases.

Co-authored-by: Isaac
…ion divergence

Add a comment at the new findCommonTypeForBinaryComparison nanos arms noting
that AnyTimestampNanoType covers both LTZ and NTZ, so the nanos types honor
castDatetimeToString like micros TimestampType (LTZ) -- deliberately more
precise than micros TimestampNTZType, which has no arm and falls through to
the config-blind canPromoteAsInBinaryComparison case.

Co-authored-by: Isaac
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.

1 participant