calcite icon indicating copy to clipboard operation
calcite copied to clipboard

[CALCITE-2743] Remove MySQL-specific Date & Time shifting

Open marcprux opened this issue 7 years ago • 7 comments

A workaround for a legacy MySQL bug where Date/Time/Timestamp fields are being shifted against the UTC offset is being applied regardless of the backend store. This PR removes that code, since the can better be worked around using the MySQL "useLegacyDatetimeCode" connection parameter.

Fixes: https://issues.apache.org/jira/browse/CALCITE-2743

marcprux avatar Dec 20 '18 13:12 marcprux

I didn't see any tests in place that tested this specific (mis)behavior. I won't be able to add any tests for this, but I agree they would be nice to have.

marcprux avatar Dec 21 '18 20:12 marcprux

Maybe you can create a very simple unit test, create and instance of such class and call the method, you know.

It will be very useful for the future in order to prevent that someone else reverts your change

eolivelli avatar Dec 22 '18 09:12 eolivelli

Here's a test case that demonstrates the failure using nothing but the ReflectiveSchema (i.e., there are no DB-specific timezone shenanigans getting in the way):

public class TimeZoneOffsetTest extends TestCase {
    public void testTimeZoneOffsets() throws Exception {
        testTimestampWithTimeZone("GMT"); // works: 1999-12-31 23:00:00.0
        testTimestampWithTimeZone("America/Chicago"); // fails: 1999-12-31 23:00:00.0 != 2000-01-01 05:00:00.0
    }

    public void testTimestampWithTimeZone(String tz) throws Exception {
        TimeZone curtz = TimeZone.getDefault();
        try {
            TimeZone.setDefault(TimeZone.getTimeZone(tz));
            try (var c = createReflectiveConnection(new TSSchema(), "adhoc")) {
                try (var rs = c.createStatement().executeQuery("SELECT TSTAMP FROM \"TABLE\"")) {
                    assertTrue(rs.next());
                    assertEquals("TimeZone comparison in " + tz, STAMP, rs.getObject(1));
                }
            }
        } finally {
            // restore previous TZ
            TimeZone.setDefault(curtz);
        }
    }

    static java.sql.Timestamp STAMP = new java.sql.Timestamp(946702800000l);
    public static class TSSchema {
        public static TSTable[] TABLE = new TSTable[] { new TSTable() };
        public static class TSTable { public java.sql.Timestamp TSTAMP = STAMP; }
    }

    Connection createReflectiveConnection(Object ob, String schemaName) throws ClassNotFoundException, SQLException {
        var info = new Properties();
        info.put("lex", "MYSQL_ANSI");
        var conn = DriverManager.getConnection("jdbc:calcite:", info);
        conn.unwrap(CalciteConnection.class).getRootSchema().add(schemaName, new ReflectiveSchema((ob)));
        conn.setSchema(schemaName); // use this schema name for queries
        return conn;
    }

}

marcprux avatar Dec 24 '18 21:12 marcprux

Great. Can you add it to the PR?

eolivelli avatar Dec 24 '18 22:12 eolivelli

@marcprux Can you also update the commit message to: [CALCITE-2743] Remove MySQL-specific Date & Time shifting (Marc Prud'hommeaux) ?

F21 avatar Jan 03 '19 02:01 F21

Hi,

can someone from the core Calcite team please comment what is needed to have this PR merged?

I'm happy to help. From my pov this bug hinders the adoption of Calcite quite significantly and it just feels bad to receive incorrect timestamps from Calcite.

dgloeckner avatar Jan 05 '21 09:01 dgloeckner

@dgloeckner apart from resolving the conflicts, a unit test should be provided in the PR: a test that fails with the current Calcite master (i.e. it shows the issue) and gets fixed with the patch.

rubenada avatar Jan 05 '21 11:01 rubenada