diff --git a/presto-tests/src/main/java/com/facebook/presto/tests/H2QueryRunner.java b/presto-tests/src/main/java/com/facebook/presto/tests/H2QueryRunner.java index 4cf85afcc317..94dbf5a26c03 100644 --- a/presto-tests/src/main/java/com/facebook/presto/tests/H2QueryRunner.java +++ b/presto-tests/src/main/java/com/facebook/presto/tests/H2QueryRunner.java @@ -51,6 +51,7 @@ import java.time.LocalTime; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.concurrent.TimeUnit; import static com.facebook.presto.spi.type.BigintType.BIGINT; @@ -287,7 +288,20 @@ else if (TIME_WITH_TIME_ZONE.equals(type)) { } else if (TIMESTAMP.equals(type)) { // resultSet.getTimestamp(i) doesn't work if JVM's zone had forward offset at the date/time being retrieved - LocalDateTime timestampValue = resultSet.getObject(i, LocalDateTime.class); + LocalDateTime timestampValue; + try { + timestampValue = resultSet.getObject(i, LocalDateTime.class); + } + catch (SQLException first) { + // H2 cannot convert DATE to LocalDateTime in their JDBC driver (even though it can convert to java.sql.Timestamp), we need to do this manually + try { + timestampValue = Optional.ofNullable(resultSet.getObject(i, LocalDate.class)).map(LocalDate::atStartOfDay).orElse(null); + } + catch (RuntimeException e) { + first.addSuppressed(e); + throw first; + } + } if (resultSet.wasNull()) { row.add(null); } diff --git a/presto-tests/src/test/java/com/facebook/presto/tests/TestH2QueryRunner.java b/presto-tests/src/test/java/com/facebook/presto/tests/TestH2QueryRunner.java new file mode 100644 index 000000000000..50cdec4d0942 --- /dev/null +++ b/presto-tests/src/test/java/com/facebook/presto/tests/TestH2QueryRunner.java @@ -0,0 +1,63 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.facebook.presto.tests; + +import com.facebook.presto.testing.MaterializedResult; +import com.google.common.collect.ImmutableList; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; + +import static com.facebook.presto.SessionTestUtils.TEST_SESSION; +import static com.facebook.presto.spi.type.TimestampType.TIMESTAMP; +import static com.google.common.base.Preconditions.checkState; +import static org.testng.Assert.assertEquals; + +public class TestH2QueryRunner +{ + private H2QueryRunner h2QueryRunner; + + @BeforeClass + public void init() + { + h2QueryRunner = new H2QueryRunner(); + } + + @AfterClass(alwaysRun = true) + public void close() + { + h2QueryRunner.close(); + h2QueryRunner = null; + } + + @Test + public void testDateToTimestampCoercion() + { + // allow running tests with a connector that supports TIMESTAMP but not DATE + + // ordinary date + MaterializedResult rows = h2QueryRunner.execute(TEST_SESSION, "SELECT DATE '2018-01-13'", ImmutableList.of(TIMESTAMP)); + assertEquals(rows.getOnlyValue(), LocalDate.of(2018, 1, 13).atStartOfDay()); + + // date, which midnight was skipped in JVM zone + LocalDate forwardOffsetChangeAtMidnightInJvmZone = LocalDate.of(1986, 1, 1); + checkState(ZoneId.systemDefault().getRules().getValidOffsets(forwardOffsetChangeAtMidnightInJvmZone.atStartOfDay()).size() == 0, "This test assumes certain JVM time zone"); + rows = h2QueryRunner.execute(TEST_SESSION, DateTimeFormatter.ofPattern("'SELECT DATE '''uuuu-MM-dd''").format(forwardOffsetChangeAtMidnightInJvmZone), ImmutableList.of(TIMESTAMP)); + assertEquals(rows.getOnlyValue(), forwardOffsetChangeAtMidnightInJvmZone.atStartOfDay()); + } +}