Pavel Pereslegin created IGNITE-22056:
-----------------------------------------

             Summary: Jdbc. Incorrect value can be read for a column with 
Instant.
                 Key: IGNITE-22056
                 URL: https://issues.apache.org/jira/browse/IGNITE-22056
             Project: Ignite
          Issue Type: Bug
            Reporter: Pavel Pereslegin


For dates (before 1900), we can get the incorrect value using the 
ResultSet#getTimestamp method (for a column with Instant value (TIMESTAMP WITH 
TIME ZONE) ).

Reproducer
{code:java}
@Test
public void testTimestamps() throws SQLException {
    // Ignoring time zone.
    TimeZone.setDefault(TimeZone.getTimeZone(ZoneId.of("UTC")));

    try (Connection conn = DriverManager.getConnection(URL)) {
        try (Statement stmt = conn.createStatement()) {
            stmt.execute(
                    "CREATE TABLE t (tt_id INT PRIMARY KEY, dt timestamp, ts 
timestamp with local time zone);"
                            + "INSERT INTO t VALUES(0, '1581-12-31 00:00:00', 
'1581-12-31 00:00:00')"
            );
        }

        try (Statement stmt = conn.createStatement()) {
            try (ResultSet rs = stmt.executeQuery("select dt, ts from t")) {
                assertTrue(rs.next());

                LocalDateTime ldt = LocalDateTime.parse("1581-12-31T00:00:00");

                assertEquals(ldt, rs.getObject("dt"));
                assertEquals(ldt.atOffset(ZoneOffset.UTC).toInstant(), 
rs.getObject("ts"));

                Timestamp tsFromDateTime = rs.getTimestamp("dt");
                Timestamp tsFromTimestamp = rs.getTimestamp("ts");

                assertEquals(tsFromDateTime, tsFromTimestamp); // fails

                // Expected :1581-12-31 00:00:00.0
                // Actual   :1581-12-21 00:00:00.0
            }
        }
    }
}
{code}

The main problem is the poor implementation of java.sql.Timestamp.

To be specific, {{valueOf(LocalDateTime)}} and {{from(Instant)}} constructs 
different timestamps, even for the same dates.

{code:java}
    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

    Instant instant = Instant.parse("1581-12-31T00:00:00Z");
    LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, 
ZoneId.of("UTC"));

    Timestamp rightMillisTs = Timestamp.from(instant);
    Timestamp wrongMillisTs = Timestamp.valueOf(localDateTime);

    // This alidation fails.
    assertEquals(rightMillisTs.getTime(), wrongMillisTs.getTime());
    // Expected :-12244176000000
    // Actual   :-12243312000000
{code}






--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to