From 7a895e2a282848bd3ba7fd222daa932d13ee6ae3 Mon Sep 17 00:00:00 2001 From: Aleksei Zinovev Date: Tue, 19 Nov 2024 11:58:32 +0100 Subject: [PATCH] Added this test for other databases (#954) Refactor inferNullability test logic Extracted common inferNullability test logic to `commonTestScenarios.kt` for reusability. Removed redundant code from individual test files and added necessary imports to support the new structure. --- .../dataframe/io/commonTestScenarios.kt | 130 ++++++++++++++++++ .../kotlinx/dataframe/io/h2/h2Test.kt | 123 +---------------- .../kotlinx/dataframe/io/h2/mariadbH2Test.kt | 6 + .../kotlinx/dataframe/io/h2/mssqlH2Test.kt | 124 +---------------- .../kotlinx/dataframe/io/h2/mysqlH2Test.kt | 6 + .../kotlinx/dataframe/io/h2/postgresH2Test.kt | 6 + .../kotlinx/dataframe/io/local/mariadbTest.kt | 6 + .../kotlinx/dataframe/io/local/mssqlTest.kt | 127 +---------------- .../kotlinx/dataframe/io/local/mysqlTest.kt | 6 + .../dataframe/io/local/postgresTest.kt | 6 + 10 files changed, 172 insertions(+), 368 deletions(-) create mode 100644 dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/commonTestScenarios.kt diff --git a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/commonTestScenarios.kt b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/commonTestScenarios.kt new file mode 100644 index 0000000000..f6de7b3d5b --- /dev/null +++ b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/commonTestScenarios.kt @@ -0,0 +1,130 @@ +package org.jetbrains.kotlinx.dataframe.io + +import io.kotest.matchers.shouldBe +import org.intellij.lang.annotations.Language +import org.jetbrains.kotlinx.dataframe.DataFrame +import org.jetbrains.kotlinx.dataframe.api.schema +import org.jetbrains.kotlinx.dataframe.io.db.MsSql +import java.sql.Connection +import java.sql.ResultSet +import kotlin.reflect.typeOf + +internal fun inferNullability(connection: Connection) { + // prepare tables and data + @Language("SQL") + val createTestTable1Query = """ + CREATE TABLE TestTable1 ( + id INT PRIMARY KEY, + name VARCHAR(50), + surname VARCHAR(50), + age INT NOT NULL + ) + """ + + connection.createStatement().execute(createTestTable1Query) + + connection.createStatement() + .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (1, 'John', 'Crawford', 40)") + connection.createStatement() + .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (2, 'Alice', 'Smith', 25)") + connection.createStatement() + .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (3, 'Bob', 'Johnson', 47)") + connection.createStatement() + .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (4, 'Sam', NULL, 15)") + + // start testing `readSqlTable` method + + // with default inferNullability: Boolean = true + val tableName = "TestTable1" + val df = DataFrame.readSqlTable(connection, tableName) + df.schema().columns["id"]!!.type shouldBe typeOf() + df.schema().columns["name"]!!.type shouldBe typeOf() + df.schema().columns["surname"]!!.type shouldBe typeOf() + df.schema().columns["age"]!!.type shouldBe typeOf() + + val dataSchema = DataFrame.getSchemaForSqlTable(connection, tableName) + dataSchema.columns.size shouldBe 4 + dataSchema.columns["id"]!!.type shouldBe typeOf() + dataSchema.columns["name"]!!.type shouldBe typeOf() + dataSchema.columns["surname"]!!.type shouldBe typeOf() + dataSchema.columns["age"]!!.type shouldBe typeOf() + + // with inferNullability: Boolean = false + val df1 = DataFrame.readSqlTable(connection, tableName, inferNullability = false) + df1.schema().columns["id"]!!.type shouldBe typeOf() + + // this column changed a type because it doesn't contain nulls + df1.schema().columns["name"]!!.type shouldBe typeOf() + df1.schema().columns["surname"]!!.type shouldBe typeOf() + df1.schema().columns["age"]!!.type shouldBe typeOf() + + // end testing `readSqlTable` method + + // start testing `readSQLQuery` method + + // ith default inferNullability: Boolean = true + @Language("SQL") + val sqlQuery = + """ + SELECT name, surname, age FROM TestTable1 + """.trimIndent() + + val df2 = DataFrame.readSqlQuery(connection, sqlQuery) + df2.schema().columns["name"]!!.type shouldBe typeOf() + df2.schema().columns["surname"]!!.type shouldBe typeOf() + df2.schema().columns["age"]!!.type shouldBe typeOf() + + val dataSchema2 = DataFrame.getSchemaForSqlQuery(connection, sqlQuery) + dataSchema2.columns.size shouldBe 3 + dataSchema2.columns["name"]!!.type shouldBe typeOf() + dataSchema2.columns["surname"]!!.type shouldBe typeOf() + dataSchema2.columns["age"]!!.type shouldBe typeOf() + + // with inferNullability: Boolean = false + val df3 = DataFrame.readSqlQuery(connection, sqlQuery, inferNullability = false) + // this column changed a type because it doesn't contain nulls + df3.schema().columns["name"]!!.type shouldBe typeOf() + df3.schema().columns["surname"]!!.type shouldBe typeOf() + df3.schema().columns["age"]!!.type shouldBe typeOf() + + // end testing `readSQLQuery` method + + // start testing `readResultSet` method + + connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE).use { st -> + @Language("SQL") + val selectStatement = "SELECT * FROM TestTable1" + + st.executeQuery(selectStatement).use { rs -> + // ith default inferNullability: Boolean = true + val df4 = DataFrame.readResultSet(rs, MsSql) + df4.schema().columns["id"]!!.type shouldBe typeOf() + df4.schema().columns["name"]!!.type shouldBe typeOf() + df4.schema().columns["surname"]!!.type shouldBe typeOf() + df4.schema().columns["age"]!!.type shouldBe typeOf() + + rs.beforeFirst() + + val dataSchema3 = DataFrame.getSchemaForResultSet(rs, MsSql) + dataSchema3.columns.size shouldBe 4 + dataSchema3.columns["id"]!!.type shouldBe typeOf() + dataSchema3.columns["name"]!!.type shouldBe typeOf() + dataSchema3.columns["surname"]!!.type shouldBe typeOf() + dataSchema3.columns["age"]!!.type shouldBe typeOf() + + // with inferNullability: Boolean = false + rs.beforeFirst() + + val df5 = DataFrame.readResultSet(rs, MsSql, inferNullability = false) + df5.schema().columns["id"]!!.type shouldBe typeOf() + + // this column changed a type because it doesn't contain nulls + df5.schema().columns["name"]!!.type shouldBe typeOf() + df5.schema().columns["surname"]!!.type shouldBe typeOf() + df5.schema().columns["age"]!!.type shouldBe typeOf() + } + } + // end testing `readResultSet` method + + connection.createStatement().execute("DROP TABLE TestTable1") +} diff --git a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/h2Test.kt b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/h2Test.kt index f3c676ce74..b5d8a931dd 100644 --- a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/h2Test.kt +++ b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/h2Test.kt @@ -10,7 +10,6 @@ import org.jetbrains.kotlinx.dataframe.annotations.DataSchema import org.jetbrains.kotlinx.dataframe.api.add import org.jetbrains.kotlinx.dataframe.api.cast import org.jetbrains.kotlinx.dataframe.api.filter -import org.jetbrains.kotlinx.dataframe.api.schema import org.jetbrains.kotlinx.dataframe.api.select import org.jetbrains.kotlinx.dataframe.io.DbConnectionConfig import org.jetbrains.kotlinx.dataframe.io.db.H2 @@ -20,6 +19,7 @@ import org.jetbrains.kotlinx.dataframe.io.getSchemaForAllSqlTables import org.jetbrains.kotlinx.dataframe.io.getSchemaForResultSet import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlQuery import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlTable +import org.jetbrains.kotlinx.dataframe.io.inferNullability import org.jetbrains.kotlinx.dataframe.io.readAllSqlTables import org.jetbrains.kotlinx.dataframe.io.readDataFrame import org.jetbrains.kotlinx.dataframe.io.readResultSet @@ -841,128 +841,9 @@ class JdbcTest { saleDataSchema1.columns["amount"]!!.type shouldBe typeOf() } - // TODO: add the same test for each particular database and refactor the scenario to the common test case - // https://github.com/Kotlin/dataframe/issues/688 @Test fun `infer nullability`() { - // prepare tables and data - @Language("SQL") - val createTestTable1Query = """ - CREATE TABLE TestTable1 ( - id INT PRIMARY KEY, - name VARCHAR(50), - surname VARCHAR(50), - age INT NOT NULL - ) - """ - - connection.createStatement().execute(createTestTable1Query) - - connection.createStatement() - .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (1, 'John', 'Crawford', 40)") - connection.createStatement() - .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (2, 'Alice', 'Smith', 25)") - connection.createStatement() - .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (3, 'Bob', 'Johnson', 47)") - connection.createStatement() - .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (4, 'Sam', NULL, 15)") - - // start testing `readSqlTable` method - - // with default inferNullability: Boolean = true - val tableName = "TestTable1" - val df = DataFrame.readSqlTable(connection, tableName) - df.schema().columns["id"]!!.type shouldBe typeOf() - df.schema().columns["name"]!!.type shouldBe typeOf() - df.schema().columns["surname"]!!.type shouldBe typeOf() - df.schema().columns["age"]!!.type shouldBe typeOf() - - val dataSchema = DataFrame.getSchemaForSqlTable(connection, tableName) - dataSchema.columns.size shouldBe 4 - dataSchema.columns["id"]!!.type shouldBe typeOf() - dataSchema.columns["name"]!!.type shouldBe typeOf() - dataSchema.columns["surname"]!!.type shouldBe typeOf() - dataSchema.columns["age"]!!.type shouldBe typeOf() - - // with inferNullability: Boolean = false - val df1 = DataFrame.readSqlTable(connection, tableName, inferNullability = false) - df1.schema().columns["id"]!!.type shouldBe typeOf() - - // this column changed a type because it doesn't contain nulls - df1.schema().columns["name"]!!.type shouldBe typeOf() - df1.schema().columns["surname"]!!.type shouldBe typeOf() - df1.schema().columns["age"]!!.type shouldBe typeOf() - - // end testing `readSqlTable` method - - // start testing `readSQLQuery` method - - // ith default inferNullability: Boolean = true - @Language("SQL") - val sqlQuery = - """ - SELECT name, surname, age FROM TestTable1 - """.trimIndent() - - val df2 = DataFrame.readSqlQuery(connection, sqlQuery) - df2.schema().columns["name"]!!.type shouldBe typeOf() - df2.schema().columns["surname"]!!.type shouldBe typeOf() - df2.schema().columns["age"]!!.type shouldBe typeOf() - - val dataSchema2 = DataFrame.getSchemaForSqlQuery(connection, sqlQuery) - dataSchema2.columns.size shouldBe 3 - dataSchema2.columns["name"]!!.type shouldBe typeOf() - dataSchema2.columns["surname"]!!.type shouldBe typeOf() - dataSchema2.columns["age"]!!.type shouldBe typeOf() - - // with inferNullability: Boolean = false - val df3 = DataFrame.readSqlQuery(connection, sqlQuery, inferNullability = false) - - // this column changed a type because it doesn't contain nulls - df3.schema().columns["name"]!!.type shouldBe typeOf() - df3.schema().columns["surname"]!!.type shouldBe typeOf() - df3.schema().columns["age"]!!.type shouldBe typeOf() - - // end testing `readSQLQuery` method - - // start testing `readResultSet` method - - connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE).use { st -> - @Language("SQL") - val selectStatement = "SELECT * FROM TestTable1" - - st.executeQuery(selectStatement).use { rs -> - // ith default inferNullability: Boolean = true - val df4 = DataFrame.readResultSet(rs, H2(MySql)) - df4.schema().columns["id"]!!.type shouldBe typeOf() - df4.schema().columns["name"]!!.type shouldBe typeOf() - df4.schema().columns["surname"]!!.type shouldBe typeOf() - df4.schema().columns["age"]!!.type shouldBe typeOf() - - rs.beforeFirst() - - val dataSchema3 = DataFrame.getSchemaForResultSet(rs, H2(MySql)) - dataSchema3.columns.size shouldBe 4 - dataSchema3.columns["id"]!!.type shouldBe typeOf() - dataSchema3.columns["name"]!!.type shouldBe typeOf() - dataSchema3.columns["surname"]!!.type shouldBe typeOf() - dataSchema3.columns["age"]!!.type shouldBe typeOf() - - // with inferNullability: Boolean = false - rs.beforeFirst() - - val df5 = DataFrame.readResultSet(rs, H2(MySql), inferNullability = false) - df5.schema().columns["id"]!!.type shouldBe typeOf() - - // this column changed a type because it doesn't contain nulls - df5.schema().columns["name"]!!.type shouldBe typeOf() - df5.schema().columns["surname"]!!.type shouldBe typeOf() - df5.schema().columns["age"]!!.type shouldBe typeOf() - } - } - // end testing `readResultSet` method - - connection.createStatement().execute("DROP TABLE TestTable1") + inferNullability(connection) } @Test diff --git a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/mariadbH2Test.kt b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/mariadbH2Test.kt index c27a0bacf4..637e4307fc 100644 --- a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/mariadbH2Test.kt +++ b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/mariadbH2Test.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlinx.dataframe.api.filter import org.jetbrains.kotlinx.dataframe.api.select import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlQuery import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlTable +import org.jetbrains.kotlinx.dataframe.io.inferNullability import org.jetbrains.kotlinx.dataframe.io.readAllSqlTables import org.jetbrains.kotlinx.dataframe.io.readSqlQuery import org.jetbrains.kotlinx.dataframe.io.readSqlTable @@ -417,4 +418,9 @@ class MariadbH2Test { schema.columns["doublecol"]!!.type shouldBe typeOf() schema.columns["decimalcol"]!!.type shouldBe typeOf() } + + @Test + fun `infer nullability`() { + inferNullability(connection) + } } diff --git a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/mssqlH2Test.kt b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/mssqlH2Test.kt index 6482834180..62bc40f231 100644 --- a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/mssqlH2Test.kt +++ b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/mssqlH2Test.kt @@ -6,13 +6,10 @@ import org.jetbrains.kotlinx.dataframe.DataFrame import org.jetbrains.kotlinx.dataframe.annotations.DataSchema import org.jetbrains.kotlinx.dataframe.api.cast import org.jetbrains.kotlinx.dataframe.api.filter -import org.jetbrains.kotlinx.dataframe.api.schema -import org.jetbrains.kotlinx.dataframe.io.db.MsSql -import org.jetbrains.kotlinx.dataframe.io.getSchemaForResultSet import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlQuery import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlTable +import org.jetbrains.kotlinx.dataframe.io.inferNullability import org.jetbrains.kotlinx.dataframe.io.readAllSqlTables -import org.jetbrains.kotlinx.dataframe.io.readResultSet import org.jetbrains.kotlinx.dataframe.io.readSqlQuery import org.jetbrains.kotlinx.dataframe.io.readSqlTable import org.junit.AfterClass @@ -21,7 +18,6 @@ import org.junit.Test import java.math.BigDecimal import java.sql.Connection import java.sql.DriverManager -import java.sql.ResultSet import java.sql.SQLException import java.util.Date import java.util.UUID @@ -250,122 +246,6 @@ class MSSQLH2Test { @Test fun `infer nullability`() { - // prepare tables and data - @Language("SQL") - val createTestTable1Query = """ - CREATE TABLE TestTable1 ( - id INT PRIMARY KEY, - name VARCHAR(50), - surname VARCHAR(50), - age INT NOT NULL - ) - """ - - connection.createStatement().execute(createTestTable1Query) - - connection.createStatement() - .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (1, 'John', 'Crawford', 40)") - connection.createStatement() - .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (2, 'Alice', 'Smith', 25)") - connection.createStatement() - .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (3, 'Bob', 'Johnson', 47)") - connection.createStatement() - .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (4, 'Sam', NULL, 15)") - - // start testing `readSqlTable` method - - // with default inferNullability: Boolean = true - val tableName = "TestTable1" - val df = DataFrame.readSqlTable(connection, tableName) - df.schema().columns["id"]!!.type shouldBe typeOf() - df.schema().columns["name"]!!.type shouldBe typeOf() - df.schema().columns["surname"]!!.type shouldBe typeOf() - df.schema().columns["age"]!!.type shouldBe typeOf() - - val dataSchema = DataFrame.getSchemaForSqlTable(connection, tableName) - dataSchema.columns.size shouldBe 4 - dataSchema.columns["id"]!!.type shouldBe typeOf() - dataSchema.columns["name"]!!.type shouldBe typeOf() - dataSchema.columns["surname"]!!.type shouldBe typeOf() - dataSchema.columns["age"]!!.type shouldBe typeOf() - - // with inferNullability: Boolean = false - val df1 = DataFrame.readSqlTable(connection, tableName, inferNullability = false) - df1.schema().columns["id"]!!.type shouldBe typeOf() - - // this column changed a type because it doesn't contain nulls - df1.schema().columns["name"]!!.type shouldBe typeOf() - df1.schema().columns["surname"]!!.type shouldBe typeOf() - df1.schema().columns["age"]!!.type shouldBe typeOf() - - // end testing `readSqlTable` method - - // start testing `readSQLQuery` method - - // ith default inferNullability: Boolean = true - @Language("SQL") - val sqlQuery = - """ - SELECT name, surname, age FROM TestTable1 - """.trimIndent() - - val df2 = DataFrame.readSqlQuery(connection, sqlQuery) - df2.schema().columns["name"]!!.type shouldBe typeOf() - df2.schema().columns["surname"]!!.type shouldBe typeOf() - df2.schema().columns["age"]!!.type shouldBe typeOf() - - val dataSchema2 = DataFrame.getSchemaForSqlQuery(connection, sqlQuery) - dataSchema2.columns.size shouldBe 3 - dataSchema2.columns["name"]!!.type shouldBe typeOf() - dataSchema2.columns["surname"]!!.type shouldBe typeOf() - dataSchema2.columns["age"]!!.type shouldBe typeOf() - - // with inferNullability: Boolean = false - val df3 = DataFrame.readSqlQuery(connection, sqlQuery, inferNullability = false) - // this column changed a type because it doesn't contain nulls - df3.schema().columns["name"]!!.type shouldBe typeOf() - df3.schema().columns["surname"]!!.type shouldBe typeOf() - df3.schema().columns["age"]!!.type shouldBe typeOf() - - // end testing `readSQLQuery` method - - // start testing `readResultSet` method - - connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE).use { st -> - @Language("SQL") - val selectStatement = "SELECT * FROM TestTable1" - - st.executeQuery(selectStatement).use { rs -> - // ith default inferNullability: Boolean = true - val df4 = DataFrame.readResultSet(rs, MsSql) - df4.schema().columns["id"]!!.type shouldBe typeOf() - df4.schema().columns["name"]!!.type shouldBe typeOf() - df4.schema().columns["surname"]!!.type shouldBe typeOf() - df4.schema().columns["age"]!!.type shouldBe typeOf() - - rs.beforeFirst() - - val dataSchema3 = DataFrame.getSchemaForResultSet(rs, MsSql) - dataSchema3.columns.size shouldBe 4 - dataSchema3.columns["id"]!!.type shouldBe typeOf() - dataSchema3.columns["name"]!!.type shouldBe typeOf() - dataSchema3.columns["surname"]!!.type shouldBe typeOf() - dataSchema3.columns["age"]!!.type shouldBe typeOf() - - // with inferNullability: Boolean = false - rs.beforeFirst() - - val df5 = DataFrame.readResultSet(rs, MsSql, inferNullability = false) - df5.schema().columns["id"]!!.type shouldBe typeOf() - - // this column changed a type because it doesn't contain nulls - df5.schema().columns["name"]!!.type shouldBe typeOf() - df5.schema().columns["surname"]!!.type shouldBe typeOf() - df5.schema().columns["age"]!!.type shouldBe typeOf() - } - } - // end testing `readResultSet` method - - connection.createStatement().execute("DROP TABLE TestTable1") + inferNullability(connection) } } diff --git a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/mysqlH2Test.kt b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/mysqlH2Test.kt index 5ece05792f..921faae2ac 100644 --- a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/mysqlH2Test.kt +++ b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/mysqlH2Test.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlinx.dataframe.api.filter import org.jetbrains.kotlinx.dataframe.api.select import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlQuery import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlTable +import org.jetbrains.kotlinx.dataframe.io.inferNullability import org.jetbrains.kotlinx.dataframe.io.readAllSqlTables import org.jetbrains.kotlinx.dataframe.io.readSqlQuery import org.jetbrains.kotlinx.dataframe.io.readSqlTable @@ -417,4 +418,9 @@ class MySqlH2Test { schema.columns["doublecol"]!!.type shouldBe typeOf() schema.columns["decimalcol"]!!.type shouldBe typeOf() } + + @Test + fun `infer nullability`() { + inferNullability(connection) + } } diff --git a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/postgresH2Test.kt b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/postgresH2Test.kt index 4a2544838d..30df83e918 100644 --- a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/postgresH2Test.kt +++ b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/h2/postgresH2Test.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlinx.dataframe.api.filter import org.jetbrains.kotlinx.dataframe.api.select import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlQuery import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlTable +import org.jetbrains.kotlinx.dataframe.io.inferNullability import org.jetbrains.kotlinx.dataframe.io.readAllSqlTables import org.jetbrains.kotlinx.dataframe.io.readSqlQuery import org.jetbrains.kotlinx.dataframe.io.readSqlTable @@ -321,4 +322,9 @@ class PostgresH2Test { schema1.columns["realcol"]!!.type shouldBe typeOf() schema1.columns["serialcol"]!!.type shouldBe typeOf() } + + @Test + fun `infer nullability`() { + inferNullability(connection) + } } diff --git a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/local/mariadbTest.kt b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/local/mariadbTest.kt index 0fb5bf815a..c79c7f0be8 100644 --- a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/local/mariadbTest.kt +++ b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/local/mariadbTest.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlinx.dataframe.api.filter import org.jetbrains.kotlinx.dataframe.api.select import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlQuery import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlTable +import org.jetbrains.kotlinx.dataframe.io.inferNullability import org.jetbrains.kotlinx.dataframe.io.readAllSqlTables import org.jetbrains.kotlinx.dataframe.io.readSqlQuery import org.jetbrains.kotlinx.dataframe.io.readSqlTable @@ -468,4 +469,9 @@ class MariadbTest { schema.columns["doubleCol"]!!.type shouldBe typeOf() schema.columns["decimalCol"]!!.type shouldBe typeOf() } + + @Test + fun `infer nullability`() { + inferNullability(connection) + } } diff --git a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/local/mssqlTest.kt b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/local/mssqlTest.kt index c466255c27..a92ff9fd22 100644 --- a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/local/mssqlTest.kt +++ b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/local/mssqlTest.kt @@ -6,13 +6,10 @@ import org.jetbrains.kotlinx.dataframe.DataFrame import org.jetbrains.kotlinx.dataframe.annotations.DataSchema import org.jetbrains.kotlinx.dataframe.api.cast import org.jetbrains.kotlinx.dataframe.api.filter -import org.jetbrains.kotlinx.dataframe.api.schema -import org.jetbrains.kotlinx.dataframe.io.db.MsSql -import org.jetbrains.kotlinx.dataframe.io.getSchemaForResultSet import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlQuery import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlTable +import org.jetbrains.kotlinx.dataframe.io.inferNullability import org.jetbrains.kotlinx.dataframe.io.readAllSqlTables -import org.jetbrains.kotlinx.dataframe.io.readResultSet import org.jetbrains.kotlinx.dataframe.io.readSqlQuery import org.jetbrains.kotlinx.dataframe.io.readSqlTable import org.junit.AfterClass @@ -22,7 +19,6 @@ import org.junit.Test import java.math.BigDecimal import java.sql.Connection import java.sql.DriverManager -import java.sql.ResultSet import java.sql.SQLException import java.util.Date import java.util.UUID @@ -296,127 +292,8 @@ class MSSQLTest { table1Df[0][Table1MSSSQL::bigintColumn] shouldBe 123456789012345L } - // TODO: add the same test for each particular database and refactor the scenario to the common test case - // https://github.com/Kotlin/dataframe/issues/688 @Test fun `infer nullability`() { - // prepare tables and data - @Language("SQL") - val createTestTable1Query = """ - CREATE TABLE TestTable1 ( - id INT PRIMARY KEY, - name VARCHAR(50), - surname VARCHAR(50), - age INT NOT NULL - ) - """ - - connection.createStatement().execute(createTestTable1Query) - - connection.createStatement() - .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (1, 'John', 'Crawford', 40)") - connection.createStatement() - .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (2, 'Alice', 'Smith', 25)") - connection.createStatement() - .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (3, 'Bob', 'Johnson', 47)") - connection.createStatement() - .execute("INSERT INTO TestTable1 (id, name, surname, age) VALUES (4, 'Sam', NULL, 15)") - - // start testing `readSqlTable` method - - // with default inferNullability: Boolean = true - val tableName = "TestTable1" - val df = DataFrame.readSqlTable(connection, tableName) - df.schema().columns["id"]!!.type shouldBe typeOf() - df.schema().columns["name"]!!.type shouldBe typeOf() - df.schema().columns["surname"]!!.type shouldBe typeOf() - df.schema().columns["age"]!!.type shouldBe typeOf() - - val dataSchema = DataFrame.getSchemaForSqlTable(connection, tableName) - dataSchema.columns.size shouldBe 4 - dataSchema.columns["id"]!!.type shouldBe typeOf() - dataSchema.columns["name"]!!.type shouldBe typeOf() - dataSchema.columns["surname"]!!.type shouldBe typeOf() - dataSchema.columns["age"]!!.type shouldBe typeOf() - - // with inferNullability: Boolean = false - val df1 = DataFrame.readSqlTable(connection, tableName, inferNullability = false) - df1.schema().columns["id"]!!.type shouldBe typeOf() - - // this column changed a type because it doesn't contain nulls - df1.schema().columns["name"]!!.type shouldBe typeOf() - df1.schema().columns["surname"]!!.type shouldBe typeOf() - df1.schema().columns["age"]!!.type shouldBe typeOf() - - // end testing `readSqlTable` method - - // start testing `readSQLQuery` method - - // ith default inferNullability: Boolean = true - @Language("SQL") - val sqlQuery = - """ - SELECT name, surname, age FROM TestTable1 - """.trimIndent() - - val df2 = DataFrame.readSqlQuery(connection, sqlQuery) - df2.schema().columns["name"]!!.type shouldBe typeOf() - df2.schema().columns["surname"]!!.type shouldBe typeOf() - df2.schema().columns["age"]!!.type shouldBe typeOf() - - val dataSchema2 = DataFrame.getSchemaForSqlQuery(connection, sqlQuery) - dataSchema2.columns.size shouldBe 3 - dataSchema2.columns["name"]!!.type shouldBe typeOf() - dataSchema2.columns["surname"]!!.type shouldBe typeOf() - dataSchema2.columns["age"]!!.type shouldBe typeOf() - - // with inferNullability: Boolean = false - val df3 = DataFrame.readSqlQuery(connection, sqlQuery, inferNullability = false) - - // this column changed a type because it doesn't contain nulls - df3.schema().columns["name"]!!.type shouldBe typeOf() - df3.schema().columns["surname"]!!.type shouldBe typeOf() - df3.schema().columns["age"]!!.type shouldBe typeOf() - - // end testing `readSQLQuery` method - - // start testing `readResultSet` method - - connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE).use { st -> - @Language("SQL") - val selectStatement = "SELECT * FROM TestTable1" - - st.executeQuery(selectStatement).use { rs -> - // ith default inferNullability: Boolean = true - val df4 = DataFrame.readResultSet(rs, MsSql) - df4.schema().columns["id"]!!.type shouldBe typeOf() - df4.schema().columns["name"]!!.type shouldBe typeOf() - df4.schema().columns["surname"]!!.type shouldBe typeOf() - df4.schema().columns["age"]!!.type shouldBe typeOf() - - rs.beforeFirst() - - val dataSchema3 = DataFrame.getSchemaForResultSet(rs, MsSql) - dataSchema3.columns.size shouldBe 4 - dataSchema3.columns["id"]!!.type shouldBe typeOf() - dataSchema3.columns["name"]!!.type shouldBe typeOf() - dataSchema3.columns["surname"]!!.type shouldBe typeOf() - dataSchema3.columns["age"]!!.type shouldBe typeOf() - - // with inferNullability: Boolean = false - rs.beforeFirst() - - val df5 = DataFrame.readResultSet(rs, MsSql, inferNullability = false) - df5.schema().columns["id"]!!.type shouldBe typeOf() - - // this column changed a type because it doesn't contain nulls - df5.schema().columns["name"]!!.type shouldBe typeOf() - df5.schema().columns["surname"]!!.type shouldBe typeOf() - df5.schema().columns["age"]!!.type shouldBe typeOf() - } - } - // end testing `readResultSet` method - - connection.createStatement().execute("DROP TABLE TestTable1") + inferNullability(connection) } } diff --git a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/local/mysqlTest.kt b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/local/mysqlTest.kt index 3db3851786..868cfdd884 100644 --- a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/local/mysqlTest.kt +++ b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/local/mysqlTest.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlinx.dataframe.api.filter import org.jetbrains.kotlinx.dataframe.api.select import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlQuery import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlTable +import org.jetbrains.kotlinx.dataframe.io.inferNullability import org.jetbrains.kotlinx.dataframe.io.readAllSqlTables import org.jetbrains.kotlinx.dataframe.io.readSqlQuery import org.jetbrains.kotlinx.dataframe.io.readSqlTable @@ -471,4 +472,9 @@ class MySqlTest { // getObject(i+1, type) catch getObject catch getString // add direct mapping to getString and other methods } + + @Test + fun `infer nullability`() { + inferNullability(connection) + } } diff --git a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/local/postgresTest.kt b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/local/postgresTest.kt index 4c452d49e8..9dddd6521f 100644 --- a/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/local/postgresTest.kt +++ b/dataframe-jdbc/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/local/postgresTest.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlinx.dataframe.api.filter import org.jetbrains.kotlinx.dataframe.api.select import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlQuery import org.jetbrains.kotlinx.dataframe.io.getSchemaForSqlTable +import org.jetbrains.kotlinx.dataframe.io.inferNullability import org.jetbrains.kotlinx.dataframe.io.readAllSqlTables import org.jetbrains.kotlinx.dataframe.io.readSqlQuery import org.jetbrains.kotlinx.dataframe.io.readSqlTable @@ -413,4 +414,9 @@ class PostgresTest { schema1.columns["smallserialcol"]!!.type shouldBe typeOf() schema1.columns["serialcol"]!!.type shouldBe typeOf() } + + @Test + fun `infer nullability`() { + inferNullability(connection) + } }