diff --git a/plugin/trino-memsql/src/test/java/io/trino/plugin/memsql/TestMemSqlTypeMapping.java b/plugin/trino-memsql/src/test/java/io/trino/plugin/memsql/TestMemSqlTypeMapping.java index 91c14d47292a..ee067eb47d0b 100644 --- a/plugin/trino-memsql/src/test/java/io/trino/plugin/memsql/TestMemSqlTypeMapping.java +++ b/plugin/trino-memsql/src/test/java/io/trino/plugin/memsql/TestMemSqlTypeMapping.java @@ -25,6 +25,7 @@ import io.trino.testing.datatype.DataSetup; import io.trino.testing.datatype.DataType; import io.trino.testing.datatype.DataTypeTest; +import io.trino.testing.datatype.SqlDataTypeTest; import io.trino.testing.sql.SqlExecutor; import io.trino.testing.sql.TestTable; import io.trino.testing.sql.TrinoSqlExecutor; @@ -33,12 +34,9 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; import java.time.ZoneId; -import java.util.Objects; -import java.util.function.Function; import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Verify.verify; @@ -52,6 +50,7 @@ import static io.trino.plugin.memsql.MemSqlClient.MEMSQL_VARCHAR_MAX_LENGTH; import static io.trino.plugin.memsql.MemSqlQueryRunner.createMemSqlQueryRunner; import static io.trino.spi.type.BigintType.BIGINT; +import static io.trino.spi.type.CharType.createCharType; import static io.trino.spi.type.DateType.DATE; import static io.trino.spi.type.DecimalType.createDecimalType; import static io.trino.spi.type.DoubleType.DOUBLE; @@ -59,21 +58,11 @@ import static io.trino.spi.type.RealType.REAL; import static io.trino.spi.type.SmallintType.SMALLINT; import static io.trino.spi.type.TimeZoneKey.UTC_KEY; +import static io.trino.spi.type.TinyintType.TINYINT; import static io.trino.spi.type.VarcharType.createUnboundedVarcharType; import static io.trino.spi.type.VarcharType.createVarcharType; -import static io.trino.testing.datatype.DataType.bigintDataType; -import static io.trino.testing.datatype.DataType.charDataType; import static io.trino.testing.datatype.DataType.dataType; -import static io.trino.testing.datatype.DataType.dateDataType; -import static io.trino.testing.datatype.DataType.decimalDataType; -import static io.trino.testing.datatype.DataType.doubleDataType; -import static io.trino.testing.datatype.DataType.formatStringLiteral; -import static io.trino.testing.datatype.DataType.integerDataType; import static io.trino.testing.datatype.DataType.realDataType; -import static io.trino.testing.datatype.DataType.smallintDataType; -import static io.trino.testing.datatype.DataType.stringDataType; -import static io.trino.testing.datatype.DataType.tinyintDataType; -import static io.trino.testing.datatype.DataType.varcharDataType; import static io.trino.type.JsonType.JSON; import static java.lang.String.format; import static java.math.RoundingMode.HALF_UP; @@ -104,67 +93,62 @@ public final void destroy() @Test public void testBasicTypes() { - DataTypeTest.create() - .addRoundTrip(bigintDataType(), 123_456_789_012L) - .addRoundTrip(integerDataType(), 1_234_567_890) - .addRoundTrip(smallintDataType(), (short) 32_456) - .addRoundTrip(tinyintDataType(), (byte) 125) - .addRoundTrip(doubleDataType(), 123.45d) - .addRoundTrip(realDataType(), 123.45f) + SqlDataTypeTest.create() + .addRoundTrip("bigint", "123456789012", BIGINT, "123456789012") + .addRoundTrip("integer", "1234567890", INTEGER, "1234567890") + .addRoundTrip("smallint", "32456", SMALLINT, "SMALLINT '32456'") + .addRoundTrip("tinyint", "125", TINYINT, "TINYINT '125'") + .addRoundTrip("double", "123.45", DOUBLE, "DOUBLE '123.45'") + // TODO: fails in SqlDataTypeTest#verifyPredicate + // .addRoundTrip("real", "123.45", REAL, "REAL '123.45'") .execute(getQueryRunner(), trinoCreateAsSelect("test_basic_types")); } @Test public void testFloat() { - singlePrecisionFloatingPointTests(realDataType()) - .execute(getQueryRunner(), trinoCreateAsSelect("trino_test_float")); - singlePrecisionFloatingPointTests(memSqlFloatDataType()) - .execute(getQueryRunner(), memSqlCreateAndInsert("tpch.memsql_test_float")); - } + // TODO: convert to SqlDataTypeTest (fails in SqlDataTypeTest#verifyPredicate) - private static DataTypeTest singlePrecisionFloatingPointTests(DataType floatType) - { // we are not testing Nan/-Infinity/+Infinity as those are not supported by MemSQL - return DataTypeTest.create() - .addRoundTrip(floatType, 3.14f) + DataTypeTest.create() + .addRoundTrip(realDataType(), 3.14f) + // TODO Overeagerly rounded by MemSQL to 3.14159 + // .addRoundTrip(realDataType(), 3.1415927f) + .addRoundTrip(realDataType(), null) + .execute(getQueryRunner(), trinoCreateAsSelect("trino_test_float")); + + DataTypeTest.create() + .addRoundTrip(memSqlFloatDataType(), 3.14f) // TODO Overeagerly rounded by MemSQL to 3.14159 // .addRoundTrip(floatType, 3.1415927f) - .addRoundTrip(floatType, null); + .addRoundTrip(memSqlFloatDataType(), null) + .execute(getQueryRunner(), memSqlCreateAndInsert("tpch.memsql_test_float")); } @Test public void testDouble() { - doublePrecisionFloatingPointTests(doubleDataType()) + // we are not testing Nan/-Infinity/+Infinity as those are not supported by MemSQL + SqlDataTypeTest.create() + .addRoundTrip("double", "1.0E100", DOUBLE, "DOUBLE '1.0E100'") + .addRoundTrip("double", "NULL", DOUBLE, "CAST(NULL AS double)") .execute(getQueryRunner(), trinoCreateAsSelect("trino_test_double")); - doublePrecisionFloatingPointTests(memSqlDoubleDataType()) - .execute(getQueryRunner(), memSqlCreateAndInsert("tpch.memsql_test_double")); - } - private static DataTypeTest doublePrecisionFloatingPointTests(DataType doubleType) - { - // we are not testing Nan/-Infinity/+Infinity as those are not supported by MemSQL - return DataTypeTest.create() - .addRoundTrip(doubleType, 1.0e100d) - .addRoundTrip(doubleType, null); + SqlDataTypeTest.create() + .addRoundTrip("double precision", "1.0E100", DOUBLE, "DOUBLE '1.0E100'") + .addRoundTrip("double precision", "NULL", DOUBLE, "CAST(NULL AS double)") + .execute(getQueryRunner(), memSqlCreateAndInsert("tpch.memsql_test_double")); } @Test public void testUnsignedTypes() { - DataType memSqlUnsignedTinyInt = DataType.dataType("TINYINT UNSIGNED", SMALLINT, Objects::toString); - DataType memSqlUnsignedSmallInt = DataType.dataType("SMALLINT UNSIGNED", INTEGER, Objects::toString); - DataType memSqlUnsignedInt = DataType.dataType("INT UNSIGNED", BIGINT, Objects::toString); - DataType memSqlUnsignedInteger = DataType.dataType("INTEGER UNSIGNED", BIGINT, Objects::toString); - DataType memSqlUnsignedBigint = DataType.dataType("BIGINT UNSIGNED", createDecimalType(20), Objects::toString); - - DataTypeTest.create() - .addRoundTrip(memSqlUnsignedTinyInt, (short) 255) - .addRoundTrip(memSqlUnsignedSmallInt, 65_535) - .addRoundTrip(memSqlUnsignedInt, 4_294_967_295L) - .addRoundTrip(memSqlUnsignedInteger, 4_294_967_295L) - .addRoundTrip(memSqlUnsignedBigint, new BigDecimal("18446744073709551615")) + SqlDataTypeTest.create() + .addRoundTrip("tinyint unsigned", "255", SMALLINT, "SMALLINT '255'") + .addRoundTrip("smallint unsigned", "65535", INTEGER) + .addRoundTrip("int unsigned", "4294967295", BIGINT) + .addRoundTrip("integer unsigned", "4294967295", BIGINT) + .addRoundTrip("bigint unsigned", "18446744073709551615", createDecimalType(20, 0), "CAST('18446744073709551615' AS decimal(20, 0))") .execute(getQueryRunner(), memSqlCreateAndInsert("tpch.memsql_test_unsigned")); } @@ -182,25 +166,27 @@ public void testTrinoCreatedDecimal() .execute(getQueryRunner(), trinoCreateAsSelect("test_decimal")); } - private DataTypeTest decimalTests() - { - return DataTypeTest.create() - .addRoundTrip(decimalDataType(3, 0), new BigDecimal("193")) - .addRoundTrip(decimalDataType(3, 0), new BigDecimal("19")) - .addRoundTrip(decimalDataType(3, 0), new BigDecimal("-193")) - .addRoundTrip(decimalDataType(3, 1), new BigDecimal("10.0")) - .addRoundTrip(decimalDataType(3, 1), new BigDecimal("10.1")) - .addRoundTrip(decimalDataType(3, 1), new BigDecimal("-10.1")) - .addRoundTrip(decimalDataType(4, 2), new BigDecimal("2")) - .addRoundTrip(decimalDataType(4, 2), new BigDecimal("2.3")) - .addRoundTrip(decimalDataType(24, 2), new BigDecimal("2")) - .addRoundTrip(decimalDataType(24, 2), new BigDecimal("2.3")) - .addRoundTrip(decimalDataType(24, 2), new BigDecimal("123456789.3")) - .addRoundTrip(decimalDataType(24, 4), new BigDecimal("12345678901234567890.31")) - .addRoundTrip(decimalDataType(30, 5), new BigDecimal("3141592653589793238462643.38327")) - .addRoundTrip(decimalDataType(30, 5), new BigDecimal("-3141592653589793238462643.38327")) - .addRoundTrip(decimalDataType(38, 0), new BigDecimal("27182818284590452353602874713526624977")) - .addRoundTrip(decimalDataType(38, 0), new BigDecimal("-27182818284590452353602874713526624977")); + private SqlDataTypeTest decimalTests() + { + return SqlDataTypeTest.create() + .addRoundTrip("decimal(3, 0)", "CAST(NULL AS decimal(3, 0))", createDecimalType(3, 0), "CAST(NULL AS decimal(3, 0))") + .addRoundTrip("decimal(3, 0)", "CAST('193' AS decimal(3, 0))", createDecimalType(3, 0), "CAST('193' AS decimal(3, 0))") + .addRoundTrip("decimal(3, 0)", "CAST('19' AS decimal(3, 0))", createDecimalType(3, 0), "CAST('19' AS decimal(3, 0))") + .addRoundTrip("decimal(3, 0)", "CAST('-193' AS decimal(3, 0))", createDecimalType(3, 0), "CAST('-193' AS decimal(3, 0))") + .addRoundTrip("decimal(3, 1)", "CAST('10.0' AS decimal(3, 1))", createDecimalType(3, 1), "CAST('10.0' AS decimal(3, 1))") + .addRoundTrip("decimal(3, 1)", "CAST('10.1' AS decimal(3, 1))", createDecimalType(3, 1), "CAST('10.1' AS decimal(3, 1))") + .addRoundTrip("decimal(3, 1)", "CAST('-10.1' AS decimal(3, 1))", createDecimalType(3, 1), "CAST('-10.1' AS decimal(3, 1))") + .addRoundTrip("decimal(4, 2)", "CAST('2' AS decimal(4, 2))", createDecimalType(4, 2), "CAST('2' AS decimal(4, 2))") + .addRoundTrip("decimal(4, 2)", "CAST('2.3' AS decimal(4, 2))", createDecimalType(4, 2), "CAST('2.3' AS decimal(4, 2))") + .addRoundTrip("decimal(24, 2)", "CAST('2' AS decimal(24, 2))", createDecimalType(24, 2), "CAST('2' AS decimal(24, 2))") + .addRoundTrip("decimal(24, 2)", "CAST('2.3' AS decimal(24, 2))", createDecimalType(24, 2), "CAST('2.3' AS decimal(24, 2))") + .addRoundTrip("decimal(24, 2)", "CAST('123456789.3' AS decimal(24, 2))", createDecimalType(24, 2), "CAST('123456789.3' AS decimal(24, 2))") + .addRoundTrip("decimal(24, 4)", "CAST('12345678901234567890.31' AS decimal(24, 4))", createDecimalType(24, 4), "CAST('12345678901234567890.31' AS decimal(24, 4))") + .addRoundTrip("decimal(30, 5)", "CAST('3141592653589793238462643.38327' AS decimal(30, 5))", createDecimalType(30, 5), "CAST('3141592653589793238462643.38327' AS decimal(30, 5))") + .addRoundTrip("decimal(30, 5)", "CAST('-3141592653589793238462643.38327' AS decimal(30, 5))", createDecimalType(30, 5), "CAST('-3141592653589793238462643.38327' AS decimal(30, 5))") + .addRoundTrip("decimal(38, 0)", "CAST(NULL AS decimal(38, 0))", createDecimalType(38, 0), "CAST(NULL AS decimal(38, 0))") + .addRoundTrip("decimal(38, 0)", "CAST('27182818284590452353602874713526624977' AS decimal(38, 0))", createDecimalType(38, 0), "CAST('27182818284590452353602874713526624977' AS decimal(38, 0))") + .addRoundTrip("decimal(38, 0)", "CAST('-27182818284590452353602874713526624977' AS decimal(38, 0))", createDecimalType(38, 0), "CAST('-27182818284590452353602874713526624977' AS decimal(38, 0))"); } @Test @@ -386,72 +372,71 @@ public void testMemSqlCreatedParameterizedChar() .execute(getQueryRunner(), memSqlCreateAndInsert("tpch.memsql_test_parameterized_char")); } - private DataTypeTest memSqlCharTypeTest() + private SqlDataTypeTest memSqlCharTypeTest() { - return DataTypeTest.create() - .addRoundTrip(charDataType("char", 1), "") - .addRoundTrip(charDataType("char", 1), "a") - .addRoundTrip(charDataType(1), "") - .addRoundTrip(charDataType(1), "a") - .addRoundTrip(charDataType(8), "abc") - .addRoundTrip(charDataType(8), "12345678") - .addRoundTrip(charDataType(255), "a".repeat(255)); + return SqlDataTypeTest.create() + .addRoundTrip("char(1)", "''", createCharType(1), "CAST('' AS char(1))") + .addRoundTrip("char(1)", "'a'", createCharType(1), "CAST('a' AS char(1))") + .addRoundTrip("char(8)", "'abc'", createCharType(8), "CAST('abc' AS char(8))") + .addRoundTrip("char(8)", "'12345678'", createCharType(8), "CAST('12345678' AS char(8))") + .addRoundTrip("char(255)", format("'%s'", "a".repeat(255)), createCharType(255), format("CAST('%s' AS char(255))", "a".repeat(255))); } @Test public void testMemSqlCreatedParameterizedCharUnicode() { - DataTypeTest.create() - .addRoundTrip(charDataType(1, CHARACTER_SET_UTF8), "\u653b") - .addRoundTrip(charDataType(5, CHARACTER_SET_UTF8), "\u653b\u6bbb") - .addRoundTrip(charDataType(5, CHARACTER_SET_UTF8), "\u653b\u6bbb\u6a5f\u52d5\u968a") + SqlDataTypeTest.create() + .addRoundTrip("char(1)", "'攻'", createCharType(1), "CAST('攻' AS char(1))") + .addRoundTrip("char(5)", "'攻殻'", createCharType(5), "CAST('攻殻' AS char(5))") + .addRoundTrip("char(5)", "'攻殻機動隊'", createCharType(5), "CAST('攻殻機動隊' AS char(5))") .execute(getQueryRunner(), memSqlCreateAndInsert("tpch.memsql_test_parameterized_varchar")); } @Test public void testTrinoCreatedParameterizedVarchar() { - DataTypeTest.create() - .addRoundTrip(stringDataType("varchar(10)", createVarcharType(10)), "text_a") - .addRoundTrip(stringDataType("varchar(255)", createVarcharType(255)), "text_b") - .addRoundTrip(stringDataType("varchar(256)", createVarcharType(256)), "text_c") - .addRoundTrip(stringDataType("varchar(" + MEMSQL_VARCHAR_MAX_LENGTH + ")", createVarcharType(MEMSQL_VARCHAR_MAX_LENGTH)), "text_memsql_max") + SqlDataTypeTest.create() + .addRoundTrip("varchar(10)", "'text_a'", createVarcharType(10), "CAST('text_a' AS varchar(10))") + .addRoundTrip("varchar(255)", "'text_b'", createVarcharType(255), "CAST('text_b' AS varchar(255))") + .addRoundTrip("varchar(256)", "'text_c'", createVarcharType(256), "CAST('text_c' AS varchar(256))") + .addRoundTrip("varchar(" + MEMSQL_VARCHAR_MAX_LENGTH + ")", "'text_memsql_max'", createVarcharType(MEMSQL_VARCHAR_MAX_LENGTH), "CAST('text_memsql_max' AS varchar(" + MEMSQL_VARCHAR_MAX_LENGTH + "))") // types larger than max VARCHAR(n) for MemSQL get mapped to one of TEXT/MEDIUMTEXT/LONGTEXT - .addRoundTrip(stringDataType("varchar(" + (MEMSQL_VARCHAR_MAX_LENGTH + 1) + ")", createVarcharType(65535)), "text_memsql_larger_than_max") - .addRoundTrip(stringDataType("varchar(65535)", createVarcharType(65535)), "text_d") - .addRoundTrip(stringDataType("varchar(65536)", createVarcharType(16777215)), "text_e") - .addRoundTrip(stringDataType("varchar(16777215)", createVarcharType(16777215)), "text_f") - .addRoundTrip(stringDataType("varchar(16777216)", createUnboundedVarcharType()), "text_g") - .addRoundTrip(stringDataType("varchar(" + VarcharType.MAX_LENGTH + ")", createUnboundedVarcharType()), "text_h") - .addRoundTrip(varcharDataType(), "unbounded") + .addRoundTrip("varchar(" + (MEMSQL_VARCHAR_MAX_LENGTH + 1) + ")", "'text_memsql_larger_than_max'", createVarcharType(65535), "CAST('text_memsql_larger_than_max' AS varchar(65535))") + .addRoundTrip("varchar(65535)", "'text_d'", createVarcharType(65535), "CAST('text_d' AS varchar(65535))") + .addRoundTrip("varchar(65536)", "'text_e'", createVarcharType(16777215), "CAST('text_e' AS varchar(16777215))") + .addRoundTrip("varchar(16777215)", "'text_f'", createVarcharType(16777215), "CAST('text_f' AS varchar(16777215))") + .addRoundTrip("varchar(16777216)", "'text_g'", createUnboundedVarcharType(), "CAST('text_g' AS varchar)") + .addRoundTrip("varchar(" + VarcharType.MAX_LENGTH + ")", "'text_h'", createUnboundedVarcharType(), "CAST('text_h' AS varchar)") + .addRoundTrip("varchar", "'unbounded'", createUnboundedVarcharType(), "CAST('unbounded' AS varchar)") .execute(getQueryRunner(), trinoCreateAsSelect("trino_test_parameterized_varchar")); } @Test public void testMemSqlCreatedParameterizedVarchar() { - DataTypeTest.create() - .addRoundTrip(stringDataType("tinytext", createVarcharType(255)), "a") - .addRoundTrip(stringDataType("text", createVarcharType(65535)), "b") - .addRoundTrip(stringDataType("mediumtext", createVarcharType(16777215)), "c") - .addRoundTrip(stringDataType("longtext", createUnboundedVarcharType()), "d") - .addRoundTrip(varcharDataType(32), "e") - .addRoundTrip(varcharDataType(15000), "f") + SqlDataTypeTest.create() + .addRoundTrip("tinytext", "'a'", createVarcharType(255), "CAST('a' AS varchar(255))") + .addRoundTrip("text", "'b'", createVarcharType(65535), "CAST('b' AS varchar(65535))") + .addRoundTrip("mediumtext", "'c'", createVarcharType(16777215), "CAST('c' AS varchar(16777215))") + .addRoundTrip("longtext", "'unbounded'", createUnboundedVarcharType(), "CAST('unbounded' AS varchar)") + .addRoundTrip("varchar(32)", "'e'", createVarcharType(32), "CAST('e' AS varchar(32))") + .addRoundTrip("varchar(15000)", "'f'", createVarcharType(15000), "CAST('f' AS varchar(15000))") .execute(getQueryRunner(), memSqlCreateAndInsert("tpch.memsql_test_parameterized_varchar")); } @Test public void testMemSqlCreatedParameterizedVarcharUnicode() { - String sampleUnicodeText = "\u653b\u6bbb\u6a5f\u52d5\u968a"; - DataTypeTest.create() - .addRoundTrip(stringDataType("tinytext " + CHARACTER_SET_UTF8, createVarcharType(255)), sampleUnicodeText) - .addRoundTrip(stringDataType("text " + CHARACTER_SET_UTF8, createVarcharType(65535)), sampleUnicodeText) - .addRoundTrip(stringDataType("mediumtext " + CHARACTER_SET_UTF8, createVarcharType(16777215)), sampleUnicodeText) - .addRoundTrip(stringDataType("longtext " + CHARACTER_SET_UTF8, createUnboundedVarcharType()), sampleUnicodeText) - .addRoundTrip(varcharDataType(sampleUnicodeText.length(), CHARACTER_SET_UTF8), sampleUnicodeText) - .addRoundTrip(varcharDataType(32, CHARACTER_SET_UTF8), sampleUnicodeText) - .addRoundTrip(varcharDataType(20000, CHARACTER_SET_UTF8), sampleUnicodeText) + String sampleUnicodeLiteral = "'\u653b\u6bbb\u6a5f\u52d5\u968a'"; + SqlDataTypeTest.create() + .addRoundTrip("tinytext " + CHARACTER_SET_UTF8, sampleUnicodeLiteral, createVarcharType(255), "CAST(" + sampleUnicodeLiteral + " AS varchar(255))") + .addRoundTrip("text " + CHARACTER_SET_UTF8, sampleUnicodeLiteral, createVarcharType(65535), "CAST(" + sampleUnicodeLiteral + " AS varchar(65535))") + .addRoundTrip("mediumtext " + CHARACTER_SET_UTF8, sampleUnicodeLiteral, createVarcharType(16777215), "CAST(" + sampleUnicodeLiteral + " AS varchar(16777215))") + .addRoundTrip("longtext " + CHARACTER_SET_UTF8, sampleUnicodeLiteral, createUnboundedVarcharType(), "CAST(" + sampleUnicodeLiteral + " AS varchar)") + .addRoundTrip("varchar(" + sampleUnicodeLiteral.length() + ") " + CHARACTER_SET_UTF8, sampleUnicodeLiteral, + createVarcharType(sampleUnicodeLiteral.length()), "CAST(" + sampleUnicodeLiteral + " AS varchar(" + sampleUnicodeLiteral.length() + "))") + .addRoundTrip("varchar(32) " + CHARACTER_SET_UTF8, sampleUnicodeLiteral, createVarcharType(32), "CAST(" + sampleUnicodeLiteral + " AS varchar(32))") + .addRoundTrip("varchar(20000) " + CHARACTER_SET_UTF8, sampleUnicodeLiteral, createVarcharType(20000), "CAST(" + sampleUnicodeLiteral + " AS varchar(20000))") .execute(getQueryRunner(), memSqlCreateAndInsert("tpch.memsql_test_parameterized_varchar_unicode")); } @@ -463,40 +448,35 @@ public void testDate() ZoneId someZone = ZoneId.of("Europe/Vilnius"); - for (String timeZoneId : ImmutableList.of(UTC_KEY.getId(), jvmZone.getId(), someZone.getId())) { - Session session = Session.builder(getSession()) - .setTimeZoneKey(TimeZoneKey.getTimeZoneKey(timeZoneId)) - .build(); - dateTestCases(memSqlDateDataType(value -> formatStringLiteral(value.toString())), jvmZone, someZone) - .execute(getQueryRunner(), session, memSqlCreateAndInsert("tpch.test_date")); - dateTestCases(dateDataType(), jvmZone, someZone) - .execute(getQueryRunner(), session, trinoCreateAsSelect(session, "test_date")); - dateTestCases(dateDataType(), jvmZone, someZone) - .execute(getQueryRunner(), session, trinoCreateAsSelect(getSession(), "test_date")); - dateTestCases(dateDataType(), jvmZone, someZone) - .execute(getQueryRunner(), session, trinoCreateAndInsert(session, "test_date")); - } - } - - private DataTypeTest dateTestCases(DataType dateDataType, ZoneId jvmZone, ZoneId someZone) - { LocalDate dateOfLocalTimeChangeForwardAtMidnightInJvmZone = LocalDate.of(1970, 1, 1); verify(jvmZone.getRules().getValidOffsets(dateOfLocalTimeChangeForwardAtMidnightInJvmZone.atStartOfDay()).isEmpty()); - LocalDate dateOfLocalTimeChangeForwardAtMidnightInSomeZone = LocalDate.of(1983, 4, 1); verify(someZone.getRules().getValidOffsets(dateOfLocalTimeChangeForwardAtMidnightInSomeZone.atStartOfDay()).isEmpty()); LocalDate dateOfLocalTimeChangeBackwardAtMidnightInSomeZone = LocalDate.of(1983, 10, 1); verify(someZone.getRules().getValidOffsets(dateOfLocalTimeChangeBackwardAtMidnightInSomeZone.atStartOfDay().minusMinutes(1)).size() == 2); - return DataTypeTest.create() - .addRoundTrip(dateDataType, LocalDate.of(1952, 4, 3)) // before epoch - .addRoundTrip(dateDataType, LocalDate.of(1970, 1, 1)) - .addRoundTrip(dateDataType, LocalDate.of(1970, 2, 3)) - .addRoundTrip(dateDataType, LocalDate.of(2017, 7, 1)) // summer on northern hemisphere (possible DST) - .addRoundTrip(dateDataType, LocalDate.of(2017, 1, 1)) // winter on northern hemisphere (possible DST on southern hemisphere) - .addRoundTrip(dateDataType, dateOfLocalTimeChangeForwardAtMidnightInJvmZone) - .addRoundTrip(dateDataType, dateOfLocalTimeChangeForwardAtMidnightInSomeZone) - .addRoundTrip(dateDataType, dateOfLocalTimeChangeBackwardAtMidnightInSomeZone); + for (String timeZoneId : ImmutableList.of(UTC_KEY.getId(), jvmZone.getId(), someZone.getId())) { + Session session = Session.builder(getSession()) + .setTimeZoneKey(TimeZoneKey.getTimeZoneKey(timeZoneId)) + .build(); + + SqlDataTypeTest.create() + .addRoundTrip("date", "CAST('1952-04-03' AS date)", DATE, "DATE '1952-04-03'") // before epoch + .addRoundTrip("date", "CAST('1970-01-01' AS date)", DATE, "DATE '1970-01-01'") + .addRoundTrip("date", "CAST('1970-02-03' AS date)", DATE, "DATE '1970-02-03'") + .addRoundTrip("date", "CAST('2017-07-01' AS date)", DATE, "DATE '2017-07-01'") // summer on northern hemisphere (possible DST) + .addRoundTrip("date", "CAST('2017-01-01' AS date)", DATE, "DATE '2017-01-01'") // winter on northern hemisphere (possible DST on southern hemisphere) + .addRoundTrip("date", "CAST('" + dateOfLocalTimeChangeForwardAtMidnightInJvmZone.toString() + "' AS date)", + DATE, "DATE '" + dateOfLocalTimeChangeForwardAtMidnightInJvmZone.toString() + "'") + .addRoundTrip("date", "CAST('" + dateOfLocalTimeChangeForwardAtMidnightInSomeZone.toString() + "' AS date)", + DATE, "DATE '" + dateOfLocalTimeChangeForwardAtMidnightInSomeZone.toString() + "'") + .addRoundTrip("date", "CAST('" + dateOfLocalTimeChangeBackwardAtMidnightInSomeZone.toString() + "' AS date)", + DATE, "DATE '" + dateOfLocalTimeChangeBackwardAtMidnightInSomeZone.toString() + "'") + .execute(getQueryRunner(), session, memSqlCreateAndInsert("tpch.test_date")) + .execute(getQueryRunner(), session, trinoCreateAsSelect(session, "test_date")) + .execute(getQueryRunner(), session, trinoCreateAsSelect(getSession(), "test_date")) + .execute(getQueryRunner(), session, trinoCreateAndInsert(session, "test_date")); + } } @Test @@ -516,28 +496,34 @@ public void testTimestamp() @Test public void testJson() { - jsonTestCases(memSqlJsonDataType(value -> "JSON " + formatStringLiteral(value))) + SqlDataTypeTest.create() + .addRoundTrip("json", "json_parse('{}')", JSON, "JSON '{}'") + .addRoundTrip("json", "null", JSON, "CAST(NULL AS json)") + .addRoundTrip("json", "json_parse('null')", JSON, "JSON 'null'") + .addRoundTrip("json", "123.4", JSON, "JSON '123.4'") + .addRoundTrip("json", "'abc'", JSON, "JSON '\"abc\"'") + .addRoundTrip("json", "'text with '' apostrophes'", JSON, "JSON '\"text with '' apostrophes\"'") + .addRoundTrip("json", "''", JSON, "JSON '\"\"'") + .addRoundTrip("json", "json_parse('{\"a\":1,\"b\":2}')", JSON, "JSON '{\"a\":1,\"b\":2}'") + .addRoundTrip("json", "json_parse('{\"a\":[1,2,3],\"b\":{\"aa\":11,\"bb\":[{\"a\":1,\"b\":2},{\"a\":0}]}}')", JSON, "JSON '{\"a\":[1,2,3],\"b\":{\"aa\":11,\"bb\":[{\"a\":1,\"b\":2},{\"a\":0}]}}'") + .addRoundTrip("json", "json_parse('[]')", JSON, "JSON '[]'") .execute(getQueryRunner(), trinoCreateAsSelect("trino_test_json")); + // MemSQL doesn't support CAST to JSON but accepts string literals as JSON values - jsonTestCases(memSqlJsonDataType(value -> format("%s", formatStringLiteral(value)))) + SqlDataTypeTest.create() + .addRoundTrip("json", "'{}'", JSON, "JSON '{}'") + .addRoundTrip("json", "null", JSON, "CAST(NULL AS json)") + .addRoundTrip("json", "'null'", JSON, "JSON 'null'") + .addRoundTrip("json", "'123.4'", JSON, "JSON '123.4'") + .addRoundTrip("json", "'\"abc\"'", JSON, "JSON '\"abc\"'") + .addRoundTrip("json", "'\"text with '' apostrophes\"'", JSON, "JSON '\"text with '' apostrophes\"'") + .addRoundTrip("json", "'\"\"'", JSON, "JSON '\"\"'") + .addRoundTrip("json", "'{\"a\":1,\"b\":2}'", JSON, "JSON '{\"a\":1,\"b\":2}'") + .addRoundTrip("json", "'{\"a\":[1,2,3],\"b\":{\"aa\":11,\"bb\":[{\"a\":1,\"b\":2},{\"a\":0}]}}'", JSON, "JSON '{\"a\":[1,2,3],\"b\":{\"aa\":11,\"bb\":[{\"a\":1,\"b\":2},{\"a\":0}]}}'") + .addRoundTrip("json", "'[]'", JSON, "JSON '[]'") .execute(getQueryRunner(), memSqlCreateAndInsert("tpch.mysql_test_json")); } - private DataTypeTest jsonTestCases(DataType jsonDataType) - { - return DataTypeTest.create() - .addRoundTrip(jsonDataType, "{}") - .addRoundTrip(jsonDataType, null) - .addRoundTrip(jsonDataType, "null") - .addRoundTrip(jsonDataType, "123.4") - .addRoundTrip(jsonDataType, "\"abc\"") - .addRoundTrip(jsonDataType, "\"text with ' apostrophes\"") - .addRoundTrip(jsonDataType, "\"\"") - .addRoundTrip(jsonDataType, "{\"a\":1,\"b\":2}") - .addRoundTrip(jsonDataType, "{\"a\":[1,2,3],\"b\":{\"aa\":11,\"bb\":[{\"a\":1,\"b\":2},{\"a\":0}]}}") - .addRoundTrip(jsonDataType, "[]"); - } - private void testUnsupportedDataType(String databaseDataType) { SqlExecutor jdbcSqlExecutor = memSqlServer::execute; @@ -572,23 +558,8 @@ private DataSetup memSqlCreateAndInsert(String tableNamePrefix) return new CreateAndInsertDataSetup(memSqlServer::execute, tableNamePrefix); } - private static DataType memSqlDateDataType(Function toLiteral) - { - return dataType("date", DATE, toLiteral); - } - - private static DataType memSqlJsonDataType(Function toLiteral) - { - return dataType("json", JSON, toLiteral); - } - private static DataType memSqlFloatDataType() { return dataType("float", REAL, Object::toString); } - - private static DataType memSqlDoubleDataType() - { - return dataType("double precision", DOUBLE, Object::toString); - } }