yesodweb / yesodweb/persistent

What can we do when during tests, wipeDB (SQLite) throws: "uncaught exception: SqliteException (SQLite3 returned ErrorConstraint while attempting to perform step.)"?

Open
#675 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug Sqlite
Dominant language
Haskell
Stars
486
Forks
306
PR merge metrics
No merged PRs in 30d

Description

Some more info on StackOverflow:

https://stackoverflow.com/questions/43169704/what-may-cause-an-errorconstraint-sqliteexception-error-with-yesod-sqlite3

wipeDB implementation that I'm using as generated by stack's yesod-sqlite template:

wipeDB :: App -> IO ()
wipeDB app = do
    -- In order to wipe the database, we need to temporarily disable foreign key checks.
    -- Unfortunately, disabling FK checks in a transaction is a noop in SQLite.
    -- Normal Persistent functions will wrap your SQL in a transaction,
    -- so we create a raw SQLite connection to disable foreign keys.
    -- Foreign key checks are per-connection, so this won't effect queries outside this function.

    -- Aside: SQLite by default *does not enable foreign key checks*
    -- (disabling foreign keys is only necessary for those who specifically enable them).
    let settings = appSettings app
    sqliteConn <- rawConnection (sqlDatabase $ appDBSqliteConf settings)
    disableForeignKeys sqliteConn

    let logFunc = messageLoggerSource app (appLogger app)
    pool <- runLoggingT (createSqlPool (wrapConnection sqliteConn) 1) logFunc

    flip runSqlPersistMPool pool $ do
        tables <- getTables
        sqlBackend <- ask
        let queries = map (\t -> "DELETE FROM " ++ (connEscapeName sqlBackend $ DBName t)) tables
        forM_ queries (\q -> rawExecute q [])

Is this a bug in SQLite? Or perhaps, but I suspect less likely, a bug in persistent-sqlite? Or just a change in SQLite that would need to be adapted to by persistent-sqlite?

In the meantime -- since the above StackOverflow link mentions that SQLite 3.9 may be unaffected -- I am trying to downgrade to persistent-sqlite-2.2, which seems to be the last version to use 3.9 or below, namely 3.8.4.3.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the wipeDB implementation in the issue and compare the persistent-sqlite-2.2 sqlite3.c version with the version currently used. Review the linked StackOverflow report for reproduction details and determine whether the failure is in SQLite or persistent-sqlite. Done means documenting the cause and identifying the required compatibility change.

Written by the indexing model from the issue text.

Assessment

Tech stack
haskell, sqlite
Domain
databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.