Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions plugin/trino-sqlserver/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mssqlserver</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ public void testReadFromView()

@Test
public void testColumnComment()
throws Exception
{
try (TestTable testTable = new TestTable(onRemoteDatabase(), "test_column_comment", "(col1 bigint, col2 bigint, col3 bigint)")) {
onRemoteDatabase().execute("" +
Expand All @@ -156,7 +155,6 @@ public void testColumnComment()

@Test
public void testPredicatePushdown()
throws Exception
{
// varchar equality
assertThat(query("SELECT regionkey, nationkey, name FROM nation WHERE name = 'ROMANIA'"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import io.trino.testing.sql.SqlExecutor;
import io.trino.testing.sql.TestTable;
import io.trino.testing.sql.TrinoSqlExecutor;
import org.intellij.lang.annotations.Language;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
Expand Down Expand Up @@ -55,6 +56,7 @@
import static io.trino.testing.sql.TestTable.randomTableSuffix;
import static java.lang.String.format;
import static java.time.ZoneOffset.UTC;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

public abstract class BaseSqlServerTypeMapping
extends AbstractTestQueryFramework
Expand Down Expand Up @@ -89,21 +91,114 @@ public void setUp()
}

@Test
public void testBasicTypes()
public void testTrinoBoolean()
{
SqlDataTypeTest.create()
.addRoundTrip("boolean", "null", BOOLEAN, "CAST(NULL AS BOOLEAN)")
.addRoundTrip("boolean", "true", BOOLEAN)
.addRoundTrip("boolean", "false", BOOLEAN)
.addRoundTrip("bigint", "null", BIGINT, "CAST(NULL AS BIGINT)")
.addRoundTrip("bigint", "123456789012", BIGINT)
.addRoundTrip("integer", "null", INTEGER, "CAST(NULL AS INTEGER)")
.addRoundTrip("integer", "123456789", INTEGER)
.addRoundTrip("smallint", "null", SMALLINT, "CAST(NULL AS SMALLINT)")
.addRoundTrip("smallint", "32456", SMALLINT, "SMALLINT '32456'")
.addRoundTrip("tinyint", "null", TINYINT, "CAST(NULL AS TINYINT)")
.execute(getQueryRunner(), trinoCreateAsSelect("test_boolean"))
.execute(getQueryRunner(), trinoCreateAndInsert("test_boolean"));
}

@Test
public void testSqlServerBit()
{
SqlDataTypeTest.create()
.addRoundTrip("bit", "null", BOOLEAN, "CAST(NULL AS BOOLEAN)")
.addRoundTrip("bit", "1", BOOLEAN, "true")
.addRoundTrip("bit", "0", BOOLEAN, "false")
.execute(getQueryRunner(), sqlServerCreateAndInsert("test_bit"));
}

@Test
public void testTinyint()
{
// TODO: Add min/max/min-1/max+1 tests (https://github.com/trinodb/trino/issues/11209)
SqlDataTypeTest.create()
.addRoundTrip("tinyint", "NULL", TINYINT, "CAST(NULL AS TINYINT)")
.addRoundTrip("tinyint", "5", TINYINT, "TINYINT '5'")
.execute(getQueryRunner(), trinoCreateAsSelect("test_basic_types"));
.execute(getQueryRunner(), sqlServerCreateAndInsert("test_tinyint"))
.execute(getQueryRunner(), trinoCreateAsSelect("test_tinyint"))
.execute(getQueryRunner(), trinoCreateAndInsert("test_tinyint"));
}

@Test
public void testSmallint()
{
SqlDataTypeTest.create()
.addRoundTrip("smallint", "NULL", SMALLINT, "CAST(NULL AS SMALLINT)")
.addRoundTrip("smallint", "-32768", SMALLINT, "SMALLINT '-32768'") // min value in SQL Server and Trino
.addRoundTrip("smallint", "32456", SMALLINT, "SMALLINT '32456'")
.addRoundTrip("smallint", "32767", SMALLINT, "SMALLINT '32767'") // max value in SQL Server and Trino
.execute(getQueryRunner(), sqlServerCreateAndInsert("test_smallint"))
.execute(getQueryRunner(), trinoCreateAsSelect("test_smallint"))
.execute(getQueryRunner(), trinoCreateAndInsert("test_smallint"));
}

@Test
public void testUnsupportedSmallint()
{
try (TestTable table = new TestTable(onRemoteDatabase(), "test_unsupported_smallint", "(data smallint)")) {
assertSqlServerQueryFails(
format("INSERT INTO %s VALUES (-32769)", table.getName()), // min - 1
"Arithmetic overflow error for data type smallint, value = -32769.");
assertSqlServerQueryFails(
format("INSERT INTO %s VALUES (32768)", table.getName()), // max + 1
"Arithmetic overflow error for data type smallint, value = 32768.");
}
}

@Test
public void testInteger()
{
SqlDataTypeTest.create()
.addRoundTrip("integer", "NULL", INTEGER, "CAST(NULL AS INTEGER)")
.addRoundTrip("integer", "-2147483648", INTEGER, "-2147483648") // min value in SQL Server and Trino
.addRoundTrip("integer", "1234567890", INTEGER, "1234567890")
.addRoundTrip("integer", "2147483647", INTEGER, "2147483647") // max value in SQL Server and Trino
.execute(getQueryRunner(), sqlServerCreateAndInsert("test_int"))
.execute(getQueryRunner(), trinoCreateAsSelect("test_int"))
.execute(getQueryRunner(), trinoCreateAndInsert("test_int"));
}

@Test
public void testUnsupportedInteger()
{
try (TestTable table = new TestTable(onRemoteDatabase(), "test_unsupported_integer", "(data integer)")) {
assertSqlServerQueryFails(
format("INSERT INTO %s VALUES (-2147483649)", table.getName()), // min - 1
"Arithmetic overflow error converting expression to data type int.");
assertSqlServerQueryFails(
format("INSERT INTO %s VALUES (2147483648)", table.getName()), // max + 1
"Arithmetic overflow error converting expression to data type int.");
}
}

@Test
public void testBigint()
{
SqlDataTypeTest.create()
.addRoundTrip("bigint", "NULL", BIGINT, "CAST(NULL AS BIGINT)")
.addRoundTrip("bigint", "-9223372036854775808", BIGINT, "-9223372036854775808") // min value in SQL Server and Trino
.addRoundTrip("bigint", "123456789012", BIGINT, "123456789012")
.addRoundTrip("bigint", "9223372036854775807", BIGINT, "9223372036854775807") // max value in SQL Server and Trino
.execute(getQueryRunner(), sqlServerCreateAndInsert("test_bigint"))
.execute(getQueryRunner(), trinoCreateAsSelect("test_bigint"))
.execute(getQueryRunner(), trinoCreateAndInsert("test_bigint"));
Comment thread
tangjiangling marked this conversation as resolved.
Outdated
}

@Test
public void testUnsupportedBigint()
{
try (TestTable table = new TestTable(onRemoteDatabase(), "test_unsupported_bigint", "(data bigint)")) {
assertSqlServerQueryFails(
format("INSERT INTO %s VALUES (-9223372036854775809)", table.getName()), // min - 1
"Arithmetic overflow error converting expression to data type bigint.");
assertSqlServerQueryFails(
format("INSERT INTO %s VALUES (9223372036854775808)", table.getName()), // max + 1
"Arithmetic overflow error converting expression to data type bigint.");
}
}

@Test
Expand All @@ -120,7 +215,8 @@ public void testReal()
.addRoundTrip("real", "NULL", REAL, "CAST(NULL AS real)")
.addRoundTrip("real", "3.14", REAL, "REAL '3.14'")
.addRoundTrip("real", "3.1415927", REAL, "REAL '3.1415927'")
.execute(getQueryRunner(), trinoCreateAsSelect("test_real"));
.execute(getQueryRunner(), trinoCreateAsSelect("test_real"))
.execute(getQueryRunner(), trinoCreateAndInsert("test_real"));
}

@Test
Expand Down Expand Up @@ -178,7 +274,8 @@ public void testDecimal()
.addRoundTrip("decimal(30, 5)", "3141592653589793238462643.38327", createDecimalType(30, 5), "CAST('3141592653589793238462643.38327' AS decimal(30, 5))")
.addRoundTrip("decimal(30, 5)", "-3141592653589793238462643.38327", createDecimalType(30, 5), "CAST('-3141592653589793238462643.38327' AS decimal(30, 5))")
.execute(getQueryRunner(), sqlServerCreateAndInsert("test_decimal"))
.execute(getQueryRunner(), trinoCreateAsSelect("test_decimal"));
.execute(getQueryRunner(), trinoCreateAsSelect("test_decimal"))
.execute(getQueryRunner(), trinoCreateAndInsert("test_decimal"));
}

@Test
Expand All @@ -199,7 +296,7 @@ public void testChar()
.addRoundTrip("char(32)", "CAST('攻殻機動隊' AS char(32))", createCharType(32), "CAST('攻殻機動隊' AS char(32))")
.addRoundTrip("char(20)", "CAST('😂' AS char(20))", createCharType(20), "CAST('😂' AS char(20))")
.addRoundTrip("char(77)", "CAST('Ну, погоди!' AS char(77))", createCharType(77), "CAST('Ну, погоди!' AS char(77))")
.execute(getQueryRunner(), trinoCreateAndInsert(getSession(), "test_char"))
.execute(getQueryRunner(), trinoCreateAndInsert("test_char"))
.execute(getQueryRunner(), trinoCreateAsSelect("test_char"));
}

Expand All @@ -219,7 +316,7 @@ public void testTrinoLongChar()
// testing mapping char > 4000 -> varchar(max)
SqlDataTypeTest.create()
.addRoundTrip("char(4001)", "'text_c'", createUnboundedVarcharType(), "VARCHAR 'text_c'")
.execute(getQueryRunner(), trinoCreateAndInsert(getSession(), "test_long_char"))
.execute(getQueryRunner(), trinoCreateAndInsert("test_long_char"))
.execute(getQueryRunner(), trinoCreateAsSelect("test_long_char"));
}

Expand All @@ -239,7 +336,7 @@ public void testVarchar()
.addRoundTrip("varchar(32)", "CAST('攻殻機動隊' AS varchar(32))", createVarcharType(32), "CAST('攻殻機動隊' AS varchar(32))")
.addRoundTrip("varchar(20)", "CAST('😂' AS varchar(20))", createVarcharType(20), "CAST('😂' AS varchar(20))")
.addRoundTrip("varchar(77)", "CAST('Ну, погоди!' AS varchar(77))", createVarcharType(77), "CAST('Ну, погоди!' AS varchar(77))")
.execute(getQueryRunner(), trinoCreateAndInsert(getSession(), "test_varchar"))
.execute(getQueryRunner(), trinoCreateAndInsert("test_varchar"))
.execute(getQueryRunner(), trinoCreateAsSelect("test_varchar"));
}

Expand All @@ -262,7 +359,7 @@ public void testTrinoLongVarchar()
// testing mapping varchar > 4000 -> varchar(max)
SqlDataTypeTest.create()
.addRoundTrip("varchar(4001)", "'text_c'", createUnboundedVarcharType(), "VARCHAR 'text_c'")
.execute(getQueryRunner(), trinoCreateAndInsert(getSession(), "test_long_varchar"))
.execute(getQueryRunner(), trinoCreateAndInsert("test_long_varchar"))
.execute(getQueryRunner(), trinoCreateAsSelect("test_long_varchar"));
}

Expand All @@ -288,7 +385,7 @@ public void testTrinoUnboundedVarchar()
.addRoundTrip("varchar", "VARCHAR '😂'", createUnboundedVarcharType(), "VARCHAR '😂'")
.addRoundTrip("varchar", "VARCHAR 'Ну, погоди!'", createUnboundedVarcharType(), "VARCHAR 'Ну, погоди!'")
.addRoundTrip("varchar", "'text_f'", createUnboundedVarcharType(), "VARCHAR 'text_f'")
.execute(getQueryRunner(), trinoCreateAndInsert(getSession(), "test_unbounded_varchar"))
.execute(getQueryRunner(), trinoCreateAndInsert("test_unbounded_varchar"))
.execute(getQueryRunner(), trinoCreateAsSelect("test_unbounded_varchar"));
}

Expand All @@ -303,7 +400,8 @@ public void testVarbinary()
.addRoundTrip("varbinary", "X'4261672066756C6C206F6620F09F92B0'", VARBINARY, "to_utf8('Bag full of 💰')")
.addRoundTrip("varbinary", "X'0001020304050607080DF9367AA7000000'", VARBINARY, "X'0001020304050607080DF9367AA7000000'") // non-text
.addRoundTrip("varbinary", "X'000000000000'", VARBINARY, "X'000000000000'")
.execute(getQueryRunner(), trinoCreateAsSelect("test_varbinary"));
.execute(getQueryRunner(), trinoCreateAsSelect("test_varbinary"))
.execute(getQueryRunner(), trinoCreateAndInsert("test_varbinary"));

// Binary literals must be prefixed with 0x
// https://docs.microsoft.com/en-us/sql/analytics-platform-system/load-with-insert?view=aps-pdw-2016-au7#InsertingLiteralsBinary
Expand Down Expand Up @@ -447,8 +545,8 @@ public void testTime()
.addRoundTrip("TIME '23:59:59.999999'", "TIME '23:59:59.999999'")
.addRoundTrip("TIME '23:59:59.9999999'", "TIME '23:59:59.9999999'")

.execute(getQueryRunner(), trinoCreateAsSelect(getSession(), "test_time"))
.execute(getQueryRunner(), trinoCreateAndInsert(getSession(), "test_time"));
.execute(getQueryRunner(), trinoCreateAsSelect("test_time"))
.execute(getQueryRunner(), trinoCreateAndInsert("test_time"));

SqlDataTypeTest.create()
// round down
Expand Down Expand Up @@ -479,8 +577,8 @@ public void testTime()
// round down
.addRoundTrip("TIME '23:59:59.999999949999'", "TIME '23:59:59.9999999'")

.execute(getQueryRunner(), trinoCreateAndInsert(getSession(), "test_time"))
.execute(getQueryRunner(), trinoCreateAsSelect(getSession(), "test_time"));
.execute(getQueryRunner(), trinoCreateAndInsert("test_time"))
.execute(getQueryRunner(), trinoCreateAsSelect("test_time"));
}

@Test(dataProvider = "sessionZonesDataProvider")
Expand Down Expand Up @@ -583,7 +681,7 @@ public void testTimestamp(ZoneId sessionZone)
.build();

tests.execute(getQueryRunner(), session, trinoCreateAsSelect(session, "test_timestamp"));
tests.execute(getQueryRunner(), session, trinoCreateAsSelect(getSession(), "test_timestamp"));
tests.execute(getQueryRunner(), session, trinoCreateAsSelect("test_timestamp"));
tests.execute(getQueryRunner(), session, trinoCreateAndInsert(session, "test_timestamp"));
}

Expand Down Expand Up @@ -733,6 +831,11 @@ protected DataSetup trinoCreateAsSelect(Session session, String tableNamePrefix)
return new CreateAsSelectDataSetup(new TrinoSqlExecutor(getQueryRunner(), session), tableNamePrefix);
}

protected DataSetup trinoCreateAndInsert(String tableNamePrefix)
{
return new CreateAndInsertDataSetup(new TrinoSqlExecutor(getQueryRunner(), getSession()), tableNamePrefix);
}

protected DataSetup trinoCreateAndInsert(Session session, String tableNamePrefix)
{
return new CreateAndInsertDataSetup(new TrinoSqlExecutor(getQueryRunner(), session), tableNamePrefix);
Expand All @@ -758,6 +861,13 @@ private static void checkIsGap(ZoneId zone, LocalDateTime dateTime)
verify(isGap(zone, dateTime), "Expected %s to be a gap in %s", dateTime, zone);
}

private void assertSqlServerQueryFails(@Language("SQL") String sql, String expectedMessage)
{
assertThatThrownBy(() -> onRemoteDatabase().execute(sql))
.getCause()
.hasMessageContaining(expectedMessage);
}

protected SqlExecutor onRemoteDatabase()
{
return sqlServer::execute;
Expand Down