Skip to content

Commit 7c7140c

Browse files
Refactor parseTimestamp method to use standard Timestamp.valueOf() first
Address PR review feedback by simplifying timestamp parsing logic: - Try Timestamp.valueOf() on original text first - If that fails, try with T replaced by space - Only fall back to custom parser for complex formats - Extract custom parsing logic to separate method for clarity Also update NEXT_CHANGELOG.md to properly describe all changes in this PR. Signed-off-by: josecsotomorales <[email protected]>
1 parent 94d324b commit 7c7140c

File tree

2 files changed

+33
-20
lines changed

2 files changed

+33
-20
lines changed

NEXT_CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@
88

99
### Fixed
1010
- Fixed timestamp values returning only milliseconds instead of the full nanosecond precision.
11+
- Fixed complex data type conversion issues by improving StringConverter to handle Databricks complex objects (arrays/maps/structs), JDBC arrays/structs, and generic collections.
12+
- Fixed ComplexDataTypeParser to correctly parse ISO timestamps with T separators and timezone offsets, preventing Arrow ingestion failures.
1113
---
1214
*Note: When making changes, please add your change under the appropriate section with a brief description.*

src/main/java/com/databricks/jdbc/api/impl/ComplexDataTypeParser.java

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -223,36 +223,47 @@ private Timestamp parseTimestamp(String raw) {
223223
if (text == null || text.isEmpty()) {
224224
return null;
225225
}
226-
String normalized = text.replace('T', ' ');
226+
227+
// First, try standard Timestamp.valueOf() parsing
227228
try {
228-
return Timestamp.valueOf(normalized);
229+
return Timestamp.valueOf(text);
229230
} catch (IllegalArgumentException e) {
230-
// Try ISO offset date-time formats with timezone information
231+
// If that fails, try with T replaced by space
232+
String normalized = text.replace('T', ' ');
233+
try {
234+
return Timestamp.valueOf(normalized);
235+
} catch (IllegalArgumentException e2) {
236+
// If standard parsing fails, use custom parser for complex formats
237+
return parseTimestampWithCustomParser(text, normalized, raw);
238+
}
239+
}
240+
}
241+
242+
private Timestamp parseTimestampWithCustomParser(String text, String normalized, String raw) {
243+
// Try ISO offset date-time formats with timezone information
244+
try {
245+
OffsetDateTime offsetDateTime =
246+
OffsetDateTime.parse(text, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
247+
Instant instant = offsetDateTime.toInstant();
248+
return Timestamp.from(instant);
249+
} catch (DateTimeParseException e1) {
231250
try {
232251
OffsetDateTime offsetDateTime =
233-
OffsetDateTime.parse(text, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
252+
OffsetDateTime.parse(normalized, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
234253
Instant instant = offsetDateTime.toInstant();
235254
return Timestamp.from(instant);
236-
} catch (DateTimeParseException ignored) {
255+
} catch (DateTimeParseException e2) {
237256
try {
238-
OffsetDateTime offsetDateTime =
239-
OffsetDateTime.parse(normalized, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
240-
Instant instant = offsetDateTime.toInstant();
241-
return Timestamp.from(instant);
242-
} catch (DateTimeParseException ignoredAgain) {
257+
LocalDateTime localDateTime =
258+
LocalDateTime.parse(text, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
259+
return Timestamp.valueOf(localDateTime);
260+
} catch (DateTimeParseException e3) {
243261
try {
244262
LocalDateTime localDateTime =
245-
LocalDateTime.parse(text, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
263+
LocalDateTime.parse(normalized, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
246264
return Timestamp.valueOf(localDateTime);
247-
} catch (DateTimeParseException ignoredYetAgain) {
248-
try {
249-
LocalDateTime localDateTime =
250-
LocalDateTime.parse(normalized, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
251-
return Timestamp.valueOf(localDateTime);
252-
} catch (DateTimeParseException finalException) {
253-
throw new IllegalArgumentException(
254-
"Invalid timestamp format: " + raw, finalException);
255-
}
265+
} catch (DateTimeParseException e4) {
266+
throw new IllegalArgumentException("Invalid timestamp format: " + raw, e4);
256267
}
257268
}
258269
}

0 commit comments

Comments
 (0)