diff --git a/dialects/hsql/src/main/kotlin/app/cash/sqldelight/dialects/hsql/HsqlTypeResolver.kt b/dialects/hsql/src/main/kotlin/app/cash/sqldelight/dialects/hsql/HsqlTypeResolver.kt index c4c497ed3db..336d8799bb0 100644 --- a/dialects/hsql/src/main/kotlin/app/cash/sqldelight/dialects/hsql/HsqlTypeResolver.kt +++ b/dialects/hsql/src/main/kotlin/app/cash/sqldelight/dialects/hsql/HsqlTypeResolver.kt @@ -45,6 +45,7 @@ class HsqlTypeResolver(private val parentResolver: TypeResolver) : TypeResolver "coalesce", "ifnull" -> encapsulatingType(exprList, TINY_INT, SMALL_INT, HsqlType.INTEGER, INTEGER, BIG_INT, REAL, TEXT, BLOB) "max" -> encapsulatingType(exprList, TINY_INT, SMALL_INT, HsqlType.INTEGER, INTEGER, BIG_INT, REAL, TEXT, BLOB).asNullable() "min" -> encapsulatingType(exprList, BLOB, TEXT, TINY_INT, SMALL_INT, INTEGER, HsqlType.INTEGER, BIG_INT, REAL).asNullable() + "length", "char_length", "character_length" -> IntermediateType(BIG_INT).nullableIf(resolvedType(exprList[0]).javaType.isNullable) else -> null } } diff --git a/dialects/mysql/src/main/kotlin/app/cash/sqldelight/dialects/mysql/MySqlTypeResolver.kt b/dialects/mysql/src/main/kotlin/app/cash/sqldelight/dialects/mysql/MySqlTypeResolver.kt index 3015c70f353..36df03e9e00 100644 --- a/dialects/mysql/src/main/kotlin/app/cash/sqldelight/dialects/mysql/MySqlTypeResolver.kt +++ b/dialects/mysql/src/main/kotlin/app/cash/sqldelight/dialects/mysql/MySqlTypeResolver.kt @@ -69,6 +69,7 @@ class MySqlTypeResolver( "to_seconds" -> IntermediateType(INTEGER) "json_arrayagg" -> IntermediateType(TEXT) "date_add", "date_sub" -> IntermediateType(TEXT) + "char_length", "character_length" -> IntermediateType(INTEGER).nullableIf(resolvedType(exprList[0]).javaType.isNullable) else -> null } diff --git a/dialects/mysql/src/test/fixtures_mysql/alter-table-add-constraint-check/1.s b/dialects/mysql/src/test/fixtures_mysql/alter-table-add-constraint-check/1.s index 718ee43128b..941a14bbe47 100644 --- a/dialects/mysql/src/test/fixtures_mysql/alter-table-add-constraint-check/1.s +++ b/dialects/mysql/src/test/fixtures_mysql/alter-table-add-constraint-check/1.s @@ -1,6 +1,12 @@ CREATE TABLE t1 ( - c1 int(11) + c1 int(11), + t1 TEXT, + t2 VARCHAR(255), + t3 CHAR(10) ); ALTER TABLE t1 - ADD CONSTRAINT chk_c1 CHECK (c1 > 0); + ADD CONSTRAINT chk_c1 CHECK (c1 > 0), + ADD CONSTRAINT chk_t1 CHECK (LENGTH(t1) > 0), + ADD CONSTRAINT chk_t2 CHECK (CHAR_LENGTH(t2) > 0), + ADD CONSTRAINT chk_t3 CHECK (CHARACTER_LENGTH(t3) > 0); diff --git a/sqldelight-gradle-plugin/src/test/integration-hsql/src/main/sqldelight/app/cash/sqldelight/hsql/integration/Characters.sq b/sqldelight-gradle-plugin/src/test/integration-hsql/src/main/sqldelight/app/cash/sqldelight/hsql/integration/Characters.sq new file mode 100644 index 00000000000..037365cf461 --- /dev/null +++ b/sqldelight-gradle-plugin/src/test/integration-hsql/src/main/sqldelight/app/cash/sqldelight/hsql/integration/Characters.sq @@ -0,0 +1,13 @@ +CREATE TABLE characters ( + name VARCHAR(255) NOT NULL, + description VARCHAR(255) +); + +insertCharacter: + INSERT INTO characters (name, description) VALUES (:name, :description); + +selectNameCharLength: + SELECT char_length(name) FROM characters; + +selectDescriptionCharLength: + SELECT char_length(description) FROM characters; diff --git a/sqldelight-gradle-plugin/src/test/integration-hsql/src/test/kotlin/app/cash/sqldelight/hsql/integration/HsqlTest.kt b/sqldelight-gradle-plugin/src/test/integration-hsql/src/test/kotlin/app/cash/sqldelight/hsql/integration/HsqlTest.kt index 3068d964ad3..347fbff3e81 100644 --- a/sqldelight-gradle-plugin/src/test/integration-hsql/src/test/kotlin/app/cash/sqldelight/hsql/integration/HsqlTest.kt +++ b/sqldelight-gradle-plugin/src/test/integration-hsql/src/test/kotlin/app/cash/sqldelight/hsql/integration/HsqlTest.kt @@ -10,7 +10,7 @@ import java.sql.Connection import java.sql.DriverManager class HsqlTest { - val conn = DriverManager.getConnection("jdbc:hsqldb:mem:mymemdb") + val conn = DriverManager.getConnection("jdbc:hsqldb:mem:mymemdb;shutdown=true") val driver = object : JdbcDriver() { override fun getConnection() = conn override fun closeConnection(connection: Connection) = Unit @@ -41,4 +41,12 @@ class HsqlTest { ), ) } + + @Test fun charLengthFunctionReturnsCharacterCount() { + database.charactersQueries.insertCharacter("abcdef", null) + val length = database.charactersQueries.selectNameCharLength().executeAsOne() + assertThat(length).isEqualTo(6) + val nullLength = database.charactersQueries.selectDescriptionCharLength().executeAsOne() + assertThat(nullLength.char_length).isNull() + } } diff --git a/sqldelight-gradle-plugin/src/test/integration-mysql/src/main/sqldelight/app/cash/sqldelight/mysql/integration/Characters.sq b/sqldelight-gradle-plugin/src/test/integration-mysql/src/main/sqldelight/app/cash/sqldelight/mysql/integration/Characters.sq new file mode 100644 index 00000000000..3074f69350b --- /dev/null +++ b/sqldelight-gradle-plugin/src/test/integration-mysql/src/main/sqldelight/app/cash/sqldelight/mysql/integration/Characters.sq @@ -0,0 +1,19 @@ +CREATE TABLE characters( + name VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL, + description TEXT CHARACTER SET utf8mb4 +); + +insertCharacter: + INSERT INTO characters (name, description) VALUES (:name, :description); + +selectNameLength: + SELECT length(name) FROM characters; + +selectDescriptionLength: + SELECT length(description) FROM characters; + +selectNameCharLength: + SELECT char_length(name) FROM characters; + +selectDescriptionCharLength: + SELECT char_length(description) FROM characters; diff --git a/sqldelight-gradle-plugin/src/test/integration-mysql/src/test/kotlin/app/cash/sqldelight/mysql/integration/MySqlTest.kt b/sqldelight-gradle-plugin/src/test/integration-mysql/src/test/kotlin/app/cash/sqldelight/mysql/integration/MySqlTest.kt index f6963f4f1dd..9e5744f6a26 100644 --- a/sqldelight-gradle-plugin/src/test/integration-mysql/src/test/kotlin/app/cash/sqldelight/mysql/integration/MySqlTest.kt +++ b/sqldelight-gradle-plugin/src/test/integration-mysql/src/test/kotlin/app/cash/sqldelight/mysql/integration/MySqlTest.kt @@ -22,6 +22,7 @@ class MySqlTest { lateinit var connection: Connection lateinit var dogQueries: DogQueries lateinit var datesQueries: DatesQueries + lateinit var charactersQueries: CharactersQueries lateinit var driver: JdbcDriver @Before @@ -39,6 +40,7 @@ class MySqlTest { MyDatabase.Schema.create(driver) dogQueries = database.dogQueries datesQueries = database.datesQueries + charactersQueries = database.charactersQueries } @After @@ -123,6 +125,22 @@ class MySqlTest { } } + @Test fun lengthFunctionReturnsByteCount() { + charactersQueries.insertCharacter("海豚", null) + val length = charactersQueries.selectNameLength().executeAsOne() + assertThat(length).isEqualTo(6) + val nullLength = charactersQueries.selectDescriptionLength().executeAsOne() + assertThat(nullLength.length).isNull() + } + + @Test fun charLengthFunctionReturnsCharacterCount() { + charactersQueries.insertCharacter("海豚", null) + val length = charactersQueries.selectNameCharLength().executeAsOne() + assertThat(length).isEqualTo(2) + val nullLength = charactersQueries.selectDescriptionCharLength().executeAsOne() + assertThat(nullLength.char_length).isNull() + } + private class ExpectedException : Exception() private class SqlDriverTransacter(driver: SqlDriver) : TransacterImpl(driver) }