diff --git a/presto-base-jdbc/src/main/java/com/facebook/presto/plugin/jdbc/JdbcRecordSink.java b/presto-base-jdbc/src/main/java/com/facebook/presto/plugin/jdbc/JdbcRecordSink.java index 28325444bb12b..e32a9dc23196a 100644 --- a/presto-base-jdbc/src/main/java/com/facebook/presto/plugin/jdbc/JdbcRecordSink.java +++ b/presto-base-jdbc/src/main/java/com/facebook/presto/plugin/jdbc/JdbcRecordSink.java @@ -26,6 +26,7 @@ import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.SQLNonTransientException; +import java.sql.Timestamp; import java.util.Collection; import java.util.List; import java.util.concurrent.TimeUnit; @@ -33,6 +34,7 @@ import static com.facebook.presto.plugin.jdbc.JdbcErrorCode.JDBC_ERROR; import static com.facebook.presto.plugin.jdbc.JdbcErrorCode.JDBC_NON_TRANSIENT_ERROR; import static com.facebook.presto.spi.type.DateType.DATE; +import static com.facebook.presto.spi.type.TimestampType.TIMESTAMP; import static com.google.common.base.Preconditions.checkState; import static java.nio.charset.StandardCharsets.UTF_8; @@ -130,6 +132,11 @@ public void appendLong(long value) long localMillis = ISOChronology.getInstanceUTC().getZone().getMillisKeepLocal(DateTimeZone.getDefault(), utcMillis); statement.setDate(next(), new Date(localMillis)); } + else if (TIMESTAMP.equals(columnTypes.get(field))) { + long utcMillis = TimeUnit.MILLISECONDS.toMillis(value); + long localMillis = ISOChronology.getInstanceUTC().getZone().getMillisKeepLocal(DateTimeZone.getDefault(), utcMillis); + statement.setTimestamp(next(), new Timestamp(localMillis)); + } else { statement.setLong(next(), value); } diff --git a/presto-mysql/src/test/java/com/facebook/presto/plugin/mysql/TestMySqlIntegrationSmokeTest.java b/presto-mysql/src/test/java/com/facebook/presto/plugin/mysql/TestMySqlIntegrationSmokeTest.java index d7a3784daa0d9..2aae2d90bee93 100644 --- a/presto-mysql/src/test/java/com/facebook/presto/plugin/mysql/TestMySqlIntegrationSmokeTest.java +++ b/presto-mysql/src/test/java/com/facebook/presto/plugin/mysql/TestMySqlIntegrationSmokeTest.java @@ -14,6 +14,7 @@ package com.facebook.presto.plugin.mysql; import com.facebook.presto.Session; +import com.facebook.presto.spi.type.VarcharType; import com.facebook.presto.testing.MaterializedResult; import com.facebook.presto.testing.MaterializedRow; import com.facebook.presto.tests.AbstractTestIntegrationSmokeTest; @@ -25,8 +26,11 @@ import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; +import java.sql.Timestamp; import static com.facebook.presto.plugin.mysql.MySqlQueryRunner.createMySqlQueryRunner; +import static com.facebook.presto.spi.type.BigintType.BIGINT; +import static com.facebook.presto.spi.type.TimestampType.TIMESTAMP; import static com.facebook.presto.spi.type.VarcharType.VARCHAR; import static com.facebook.presto.testing.TestingSession.testSessionBuilder; import static com.facebook.presto.testing.assertions.Assert.assertEquals; @@ -64,31 +68,45 @@ public final void destroy() public void testDescribeTable() throws Exception { - // we need specific implementation of this tests due to specific Presto<->Mysql varchar length mapping. - MaterializedResult actualColumns = computeActual("DESC ORDERS").toJdbcTypes(); - - // some connectors don't support dates, and some do not support parametrized varchars, so we check multiple options + execute("CREATE TABLE tpch.test_describe_table (c_bigint bigint, c_varchar_255 varchar(255), c_varchar_15 varchar(15), c_double double, c_date date, c_integer integer, c_timestamp timestamp)"); + MaterializedResult actualColumns = computeActual("DESC test_describe_table").toJdbcTypes(); MaterializedResult expectedColumns = MaterializedResult.resultBuilder(getQueryRunner().getDefaultSession(), VARCHAR, VARCHAR, VARCHAR, VARCHAR) - .row("orderkey", "bigint", "", "") - .row("custkey", "bigint", "", "") - .row("orderstatus", "varchar(255)", "", "") - .row("totalprice", "double", "", "") - .row("orderdate", "date", "", "") - .row("orderpriority", "varchar(255)", "", "") - .row("clerk", "varchar(255)", "", "") - .row("shippriority", "integer", "", "") - .row("comment", "varchar(255)", "", "") + .row("c_bigint", "bigint", "", "") + .row("c_varchar_255", "varchar(255)", "", "") + .row("c_varchar_15", "varchar(15)", "", "") + .row("c_double", "double", "", "") + .row("c_date", "date", "", "") + .row("c_integer", "integer", "", "") + .row("c_timestamp", "timestamp", "", "") .build(); assertEquals(actualColumns, expectedColumns); + assertUpdate("DROP TABLE test_describe_table"); + } + + @Test + public void testCreateTableFromSelect() + throws Exception + { + execute("CREATE TABLE tpch.temp_table_with_timestamp_column (c_timestamp timestamp)"); + assertUpdate(getQueryRunner().getDefaultSession(), "INSERT INTO temp_table_with_timestamp_column VALUES (date_parse('1970-12-01 00:00:01','%Y-%m-%d %H:%i:%s'))", 1); + assertUpdate(getQueryRunner().getDefaultSession(), "CREATE TABLE test_create_table_as_select AS SELECT * FROM temp_table_with_timestamp_column", 1); + assertUpdate("DROP TABLE temp_table_with_timestamp_column"); + assertUpdate("DROP TABLE test_create_table_as_select"); } @Test public void testInsert() throws Exception { - execute("CREATE TABLE tpch.test_insert (x bigint, y varchar(100))"); - assertUpdate("INSERT INTO test_insert VALUES (123, 'test')", 1); - assertQuery("SELECT * FROM test_insert", "SELECT 123 x, 'test' y"); + execute("CREATE TABLE tpch.test_insert (c_bigint bigint, c_varchar_100 varchar(100), c_timestamp timestamp)"); + assertUpdate(getQueryRunner().getDefaultSession(), "INSERT INTO test_insert VALUES (123, 'test', date_parse('1970-12-01 00:00:01','%Y-%m-%d %H:%i:%s'))", 1); + assertUpdate(getQueryRunner().getDefaultSession(), "INSERT INTO test_insert VALUES (123, 'test', date_parse('2030-01-01 23:59:59','%Y-%m-%d %H:%i:%s'))", 1); + MaterializedResult actual = computeActual("SELECT * FROM test_insert"); + MaterializedResult expected = MaterializedResult.resultBuilder(getSession(), BIGINT, VarcharType.createVarcharType(100), TIMESTAMP) + .row((long) 123, "test", Timestamp.valueOf("1970-12-01 00:00:01")) + .row((long) 123, "test", Timestamp.valueOf("2030-01-01 23:59:59")) + .build(); + assertEquals(actual, expected); assertUpdate("DROP TABLE test_insert"); } diff --git a/presto-postgresql/src/test/java/com/facebook/presto/plugin/postgresql/TestPostgreSqlIntegrationSmokeTest.java b/presto-postgresql/src/test/java/com/facebook/presto/plugin/postgresql/TestPostgreSqlIntegrationSmokeTest.java index b01848af7c91e..e8642d9ed32b0 100644 --- a/presto-postgresql/src/test/java/com/facebook/presto/plugin/postgresql/TestPostgreSqlIntegrationSmokeTest.java +++ b/presto-postgresql/src/test/java/com/facebook/presto/plugin/postgresql/TestPostgreSqlIntegrationSmokeTest.java @@ -13,6 +13,7 @@ */ package com.facebook.presto.plugin.postgresql; +import com.facebook.presto.testing.MaterializedResult; import com.facebook.presto.tests.AbstractTestIntegrationSmokeTest; import io.airlift.testing.postgresql.TestingPostgreSqlServer; import org.testng.annotations.AfterClass; @@ -23,7 +24,12 @@ import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; +import java.sql.Timestamp; +import static com.facebook.presto.spi.type.BigintType.BIGINT; +import static com.facebook.presto.spi.type.TimestampType.TIMESTAMP; +import static com.facebook.presto.spi.type.VarcharType.VARCHAR; +import static com.facebook.presto.testing.assertions.Assert.assertEquals; import static io.airlift.tpch.TpchTable.ORDERS; import static org.testng.Assert.assertTrue; @@ -53,13 +59,44 @@ public final void destroy() postgreSqlServer.close(); } + @Test + public void testDescribeTable() + throws Exception + { + execute("CREATE TABLE tpch.test_decribe_table (c_timestamp timestamp without time zone, c_timestamp_tz timestamp with time zone)"); + MaterializedResult actualColumns = computeActual(getQueryRunner().getDefaultSession(), "DESC test_decribe_table").toJdbcTypes(); + MaterializedResult expectedColumns = MaterializedResult.resultBuilder(getQueryRunner().getDefaultSession(), VARCHAR, VARCHAR, VARCHAR, VARCHAR) + .row("c_timestamp", "timestamp", "", "") + .row("c_timestamp_tz", "timestamp", "", "") + .build(); + assertEquals(actualColumns, expectedColumns); + assertUpdate("DROP TABLE test_decribe_table"); + } + + @Test + public void testCreateTableFromSelect() + throws Exception + { + execute("CREATE TABLE tpch.temp_table_with_timestamp_column (c_timestamp timestamp)"); + assertUpdate(getQueryRunner().getDefaultSession(), "INSERT INTO temp_table_with_timestamp_column VALUES (date_parse('1970-12-01 00:00:01','%Y-%m-%d %H:%i:%s'))", 1); + assertUpdate(getQueryRunner().getDefaultSession(), "CREATE TABLE test_create_table_as_select AS SELECT * FROM temp_table_with_timestamp_column", 1); + assertUpdate("DROP TABLE temp_table_with_timestamp_column"); + assertUpdate("DROP TABLE test_create_table_as_select"); + } + @Test public void testInsert() throws Exception { - execute("CREATE TABLE tpch.test_insert (x bigint, y varchar(100))"); - assertUpdate("INSERT INTO test_insert VALUES (123, 'test')", 1); - assertQuery("SELECT * FROM test_insert", "SELECT 123 x, 'test' y"); + execute("CREATE TABLE tpch.test_insert (c_bigint bigint, c_varchar varchar, c_timestamp timestamp)"); + assertUpdate("INSERT INTO test_insert VALUES (123, 'test', date_parse('1970-12-01 00:00:01','%Y-%m-%d %H:%i:%s'))", 1); + assertUpdate("INSERT INTO test_insert VALUES (123, 'test', date_parse('2030-01-01 23:59:59','%Y-%m-%d %H:%i:%s'))", 1); + MaterializedResult actual = computeActual("SELECT * FROM test_insert"); + MaterializedResult expected = MaterializedResult.resultBuilder(getSession(), BIGINT, VARCHAR, TIMESTAMP) + .row((long) 123, "test", Timestamp.valueOf("1970-12-01 00:00:01")) + .row((long) 123, "test", Timestamp.valueOf("2030-01-01 23:59:59")) + .build(); + assertEquals(actual, expected); assertUpdate("DROP TABLE test_insert"); }