cashapp / sqldelight

SQLDelight - Generates typesafe Kotlin APIs from SQL
https://cashapp.github.io/sqldelight/
Apache License 2.0
6.01k stars 501 forks source link

SQLite: return Long instead of data class in SUM #5271

Closed MJegorovas closed 1 month ago

MJegorovas commented 1 month ago

SQLDelight Version

2.0.1

SQLDelight Dialect

sqlite-3-38

Describe the Bug

Example sql:

CREATE TABLE item (
    id TEXT PRIMARY KEY,
    size INTEGER NOT NULL DEFAULT 0
);
getSize:
SELECT sum(size)
FROM item;

Generated code:

public data class GetSize(
  public val sum: Long?,
)
...
public fun <T : Any> getSize(mapper: (sum: Long?) -> T): Query<T> = Query(660_388_533,
    arrayOf("item"), driver, "Item.sq", "getSize", """
|SELECT sum(size)
|FROM item
""".trimMargin()) { cursor ->
  mapper(
    cursor.getLong(0)
  )
}

public fun getSize(): Query<GetSize> = getSize { sum ->
  GetSize(
    sum
  )
}

Why does it return wrapped data class and not Long? directly?

Stacktrace

No response

griffio commented 1 month ago

🤔 I think this is currently by design - a nullable result generates a table interface see https://github.com/cashapp/sqldelight/discussions/3945

Even though the column size is NOT NULL the result of SUM() is considered nullable https://github.com/cashapp/sqldelight/blob/5606c7ea71a0bb8162682a000582daacf2f577bf/sqldelight-compiler/src/main/kotlin/app/cash/sqldelight/core/lang/util/ExprUtil.kt#L106-L113 e.g for example, using ROUND() would return Long directly

MJegorovas commented 1 month ago

Bummer, but the reason makes sense. Thanks!