Skip to content

Reject out-of-range sql date/time fields in DateTimeConverter.toDate - #436

Draft
rootvector2 wants to merge 2 commits into
apache:masterfrom
rootvector2:sql-datetime-field-range
Draft

Reject out-of-range sql date/time fields in DateTimeConverter.toDate#436
rootvector2 wants to merge 2 commits into
apache:masterfrom
rootvector2:sql-datetime-field-range

Conversation

@rootvector2

Copy link
Copy Markdown
Contributor

DateTimeConverter.toDate builds java.sql.Date/Time/Timestamp with valueOf, which silently rolls over out-of-range fields (2006-02-31 -> 2006-03-03, 25:70:90 -> 02:11:30, 2006-10-23 25:70:90 -> next day), so malformed input in the default useLocaleFormat=false path is accepted as a different value instead of rejected; found while auditing the sql converters against the strict setLenient(false)/ParsePosition check the same class already applies on its locale-format branch, and fixed by validating against strict JDBC-format DateTimeFormatters (ResolverStyle.STRICT) before valueOf, leaving valid padded and single-digit input unchanged.

  • Read the contribution guidelines for this project.
  • Read the ASF Generative Tooling Guidance if you use Artificial Intelligence (AI).
  • I used AI to create any part of, or all of, this pull request. Which AI tool was used to create this pull request, and to what extent did it contribute?
  • Run a successful build using the default Maven goal with mvn; that's mvn on the command line by itself.
  • Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. This may not always be possible, but it is a best practice.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Each commit in the pull request should have a meaningful subject line and body. Note that a maintainer may squash commits during the merge process.

@garydgregory

Copy link
Copy Markdown
Member

Hello @rootvector2

Thank you for the PR.

The Javadoc and exception messages should be updated, for example

String must be in JDBC format [yyyy-MM-dd] to create a ...

The behavioral contract has now become stricter: out-of-range fields are rejected instead of being rolled over. The error messages are unchanged. The Javadoc and messages are technically still true but it do not document the new
strictness. How about mention that "validation is strict, out-of-range fields are rejected”.

@garydgregory garydgregory changed the title reject out-of-range sql date/time fields in DateTimeConverter.toDate Reject out-of-range sql date/time fields in DateTimeConverter.toDate Aug 16, 2026
@rootvector2

Copy link
Copy Markdown
Contributor Author

Makes sense. Updated all three exception messages to append "validation is strict, out-of-range fields are rejected" and added the same note to the toDate javadoc. Full mvn build still green (1287 tests, 0 failures).

garydgregory added a commit that referenced this pull request Aug 23, 2026
in DateTimeConverter.toDate

The problematic bug I fixed is three instances of double parsing.

Instead of going round and round, I applied the diff locally, made the
following changes, and pushed to master.

Double parsing for the `java.sql.Date` case.
Validation parses with the strict formatter and valueOf parses again.
Functionally correct, but wasteful. For example:
LocalDate.parse(value, SQL_DATE_FORMAT);
return type.cast(java.sql.Date.valueOf(value));
The parsed LocalDate is discarded. A more efficient form would be
Date.valueOf(LocalDate.parse(...)). Same for Time / Timestamp.

Double parsing of for the `java.sql.Time` case. Same as above.

Double parsing of for the `java.sql.Timestamp` case. Same as above.

I added details to Javadocs to clarify intent.

I added the follow unit tests:

In SqlDateConverterTest

testDefaultStringToTypeConvertValidLeapYear
testDefaultStringToTypeConvertInvalidNonLeapYearFeb29
testDefaultStringToTypeConvertValidBoundaryDates
testDefaultStringToTypeConvertStrictValidationMessage

In SqlTimeConverterTest

testDefaultStringToTypeConvertValidBoundaryTimes
testDefaultStringToTypeConvertInvalidTimeHourMinuteSecond
testDefaultStringToTypeConvertStrictValidationMessage

In SqlTimestampConverterTest

testDefaultStringToTypeConvertValidTimestampWithFraction
testDefaultStringToTypeConvertInvalidTimestampOutOfRangeDate
testDefaultStringToTypeConvertInvalidTimestampOutOfRangeTime
testDefaultStringToTypeConvertStrictValidationMessage

These tests cover valid leap-year and boundary values, invalid
out-of-range values for all three SQL types, timestamp fraction handling
and verification that the new ConversionException messages mention
strict validation.
@garydgregory

garydgregory commented Aug 23, 2026

Copy link
Copy Markdown
Member

Hello @rootvector2

I pushed patched up version of this PR. I think this PR can be closed unless you see follow up work needed.

The problematic bug I fixed is three instances of double parsing.

Instead of going round and round, I applied the diff locally, made the following changes, and pushed to master.

Double parsing for the java.sql.Date case.

Validation parses with the strict formatter and valueOf parses again. Functionally correct, but wasteful. For example:

LocalDate.parse(value, SQL_DATE_FORMAT);
return type.cast(java.sql.Date.valueOf(value));

The parsed LocalDate is discarded. A more efficient form would be Date.valueOf(LocalDate.parse(...)).

Double parsing of for the java.sql.Time case. Same as above.

Double parsing of for the java.sql.Timestamp case. Same as above.

I added details to Javadocs to clarify intent.

I added the follow unit tests:

In SqlDateConverterTest

testDefaultStringToTypeConvertValidLeapYear
testDefaultStringToTypeConvertInvalidNonLeapYearFeb29
testDefaultStringToTypeConvertValidBoundaryDates
testDefaultStringToTypeConvertStrictValidationMessage

In SqlTimeConverterTest

testDefaultStringToTypeConvertValidBoundaryTimes
testDefaultStringToTypeConvertInvalidTimeHourMinuteSecond
testDefaultStringToTypeConvertStrictValidationMessage

In SqlTimestampConverterTest

testDefaultStringToTypeConvertValidTimestampWithFraction
testDefaultStringToTypeConvertInvalidTimestampOutOfRangeDate
testDefaultStringToTypeConvertInvalidTimestampOutOfRangeTime
testDefaultStringToTypeConvertStrictValidationMessage

These tests cover valid leap-year and boundary values, invalid out-of-range values for all three SQL types, timestamp fraction handling and verification that the new ConversionException messages mention strict validation.

You are credited in changes.xml.

@garydgregory
garydgregory marked this pull request as draft August 23, 2026 13:15
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.

2 participants