psixto-denodo opened a new issue, #838:
URL: https://github.com/apache/arrow-java/issues/838
### Describe the bug, including details regarding any error messages,
version, and platform.
The FlightSQL JDBC driver always treats timestamps as milliseconds when
sending them to the server, ignoring the connection setting timeStampPrecision
(for example microseconds). As a result, when the connection precision is set
to microseconds the driver truncates/offsets the timestamp and the value stored
on the server is incorrect.
Expected behavior When the JDBC connection option timeStampPrecision is set
(e.g. microseconds, milliseconds, nanoseconds), PreparedStatement#setTimestamp
(and setTimestamp with timestamptz) should send timestamps with the configured
precision so the server receives the correct epoch value.
Actual behavior The driver converts java.sql.Timestamp values to an epoch
value assuming milliseconds. If the connection is configured for microseconds
(or other precision) the conversion is incorrect and inserted timestamps are
wrong.
```
// Connection includes timeStampPrecision parameter (example: microseconds)
String jdbcUrlFlight =
"jdbc:arrow-flight-sql://localhost:9994?useEncryption=0&timeStampPrecision=microseconds";
try (Connection conn = DriverManager.getConnection(jdbcUrlFlight);
PreparedStatement stmt = conn.prepareStatement("INSERT INTO ... VALUES
(?, ?, ?, ?, ?)")) {
for (RowData row : generatedData) {
stmt.setDate(1, row.c_date());
stmt.setTime(2, row.c_time());
stmt.setTime(3, row.c_timetz());
stmt.setTimestamp(4, row.c_timestamp()); // incorrect
conversion happens here
stmt.setTimestamp(5, row.c_timestamptz()); // and here
stmt.addBatch();
}
stmt.executeBatch();
}
```
Example A — connection configured for microseconds (bug triggered)
- Value I want to insert:
- Timestamp object: "2024-11-03 12:45:09.869885001"
- nanos = 869885001
- fastTime = 1730634309000
- **DateTimeUtils#sqlTimestampToUnixTimestamp(Timestamp, TimeZone) returns:
1730637909869**:
- Interpreted as milliseconds, that is: **2024-11-03 12:45:09.869**
(GMT)
- Final value inserted into server: **1970-01-21 00:43:57.909869**
- Incorrect because the connection used microsecond precision but driver
treated the value as milliseconds.
Example B — connection set to milliseconds (works)
- Connection: ?timeStampPrecision=milliseconds
- Value I want to insert:
- "**2023-11-29 09:47:32.659534860**"
- nanos = 659534860
- fastTime = 1701247652000
- Driver sends: 1701251252659 (interpreted as milliseconds)
- Server receives: **2023-11-29 09:47:32.659** — correct when precision is
milliseconds.
Environment
- flight-sql-jdbc-driver-18.3.0.jar
- Java: 17
- Server FlightSQL implementation/version: 18.2
- OS: Windows
Relevant code & suspected area
DateTimeUtils#sqlTimestampToUnixTimestamp(Timestamp, TimeZone) appears to be
converting timestamps assuming millisecond precision.
```
public static long sqlTimestampToUnixTimestamp(Timestamp timestamp, TimeZone
timeZone) {
long time = timestamp.getTime();
LocalDateTime dateTime = timestamp.toLocalDateTime();
long unixTimestamp = dateTime.toEpochSecond(ZoneOffset.UTC) * 1000L
+ (long)dateTime.get(ChronoField.MILLI_OF_SECOND);
if (timeZone != null) {
unixTimestamp += (long)timeZone.getOffset(time);
}
unixTimestamp -= (long)DEFAULT_ZONE.getOffset(time);
return unixTimestamp;
}
```
The driver should respect the connection timeStampPrecision parameter, and
correctlyreturn the exact epoch value (as a long) at the configured timestamp
precision.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]