sqldelight icon indicating copy to clipboard operation
sqldelight copied to clipboard

Escape SQLite Keyword

Open cleemansen opened this issue 1 year ago • 1 comments

SQLDelight Version

2.0.1

Application Operating System

Android, iOS

Describe the Bug

For some SQL statements the generated (kotlin) code misses the used SQL keyword escape char.

// shared/src/commonMain/sqldelight/[app-package-name]/db/Group.sq
CREATE TABLE `Group` (
    id TEXT NOT NULL PRIMARY KEY
);

findById:
SELECT * FROM `Group` WHERE id = ?;

save:
INSERT OR REPLACE INTO `Group` VALUES ?;

deleteById:
DELETE FROM `Group` WHERE id = ?;

The generated queries:

// shared/build/generated/sqldelight/code/[app-package-name]/GroupQueries.kt
package [app-package-name]

import app.cash.sqldelight.Query
import app.cash.sqldelight.TransacterImpl
import app.cash.sqldelight.db.QueryResult
import app.cash.sqldelight.db.SqlCursor
import app.cash.sqldelight.db.SqlDriver
import kotlin.Any
import kotlin.String

public class GroupQueries(
  driver: SqlDriver,
) : TransacterImpl(driver) {
  public fun findById(id: String): Query<String> = FindByIdQuery(id) { cursor ->
    cursor.getString(0)!!
  }

  public fun save(Group: Group) {
    driver.execute(1_999_270_872, """INSERT OR REPLACE INTO Group (id) VALUES (?)""", 1) {
          bindString(0, Group.id)
        }
    notifyQueries(1_999_270_872) { emit ->
      emit("Group")
    }
  }

  public fun deleteById(id: String) {
    driver.execute(-1_138_505_160, """DELETE FROM `Group` WHERE id = ?""", 1) {
          bindString(0, id)
        }
    notifyQueries(-1_138_505_160) { emit ->
      emit("Group")
    }
  }

  private inner class FindByIdQuery<out T : Any>(
    public val id: String,
    mapper: (SqlCursor) -> T,
  ) : Query<T>(mapper) {
    override fun addListener(listener: Query.Listener) {
      driver.addListener("Group", listener = listener)
    }

    override fun removeListener(listener: Query.Listener) {
      driver.removeListener("Group", listener = listener)
    }

    override fun <R> execute(mapper: (SqlCursor) -> QueryResult<R>): QueryResult<R> =
        driver.executeQuery(-2_050_339_322, """SELECT * FROM `Group` WHERE id = ?""", mapper, 1) {
      bindString(0, id)
    }

    override fun toString(): String = "Group.sq:findById"
  }
}

As you can see the table name is not escaped in """INSERT OR REPLACE INTO Group (id) VALUES (?)""",.

Notes:

  1. Other statements/queries are still escaped eg """DELETE FROM `Group` WHERE id = ?"""
  2. This does not occur in SQLDelight v2.0.0.
  3. It doesn't matter which of the 4 SQLite keyword escape characters is used.

Stacktrace

No response

cleemansen avatar Dec 04 '23 09:12 cleemansen

Since this isn't getting any attention, I wanted to say me too. This is preventing me from updating to 2.0.1.

sproctor avatar Dec 19 '23 10:12 sproctor