Skip to content

Failures in persistent >= 2.13 with SafeToRemove columns #1273

@brandonchinn178

Description

@brandonchinn178

My library's tests starting failing when tested against persistent-2.13 using a persistent model with a column marked with SafeToRemove.

  • In persistent-sqlite-2.13, this only seems to break putMany.
  • In persistent-postgresql-2.13, this seems to break insert (and since I can't insert, I don't know whether any of the query functions like get work)
  • In persistent-postgresql-2.13, this also seems to break migrations. Previously, if the SafeToRemove column exists, running migrations should remove it, but now it seems to try to re-create the column.

CI failure: https://app.circleci.com/pipelines/github/brandonchinn178/persistent-mtl/125/workflows/eb5cdac0-040b-473c-ae93-23a68f88cf1e/jobs/1116

Repro

This repros the sqlite failure, which is easier to quickly repro than postgres (considering a postgres repro would require running a postgres db). Put the following into a file Repro.hs and run stack Repro.hs.

#!/usr/bin/env stack
{-
  stack script
    --resolver nightly-2021-05-20
    --package mtl
    --package monad-logger
    --package persistent
    --package persistent-sqlite
    --extra-dep persistent-2.13.0.1
    --extra-dep persistent-sqlite-2.13.0.0
-}

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}

import Control.Monad.Logger
import Control.Monad.Reader
import Database.Persist
import Database.Persist.Sql
import Database.Persist.Sqlite
import Database.Persist.TH

share [mkPersist sqlSettings, mkMigrate "migration"]
  [persistLowerCase|
Person
  name          String
  age           Int
  removedColumn String SafeToRemove
  UniqueName name
  deriving Show Eq
|]

main :: IO ()
main =
  runStdoutLoggingT $
    withSqliteConn "/tmp/db.sqlite" $ \conn ->
      (`runReaderT` conn) $ do
        _ <- runMigrationSilent migration
        putMany [Person "Alice" 30]

Output (with whitespace added by me)

[Debug#SQL] CREATE TABLE "person"("id" INTEGER PRIMARY KEY,"name" VARCHAR NOT NULL,"age" INTEGER NOT NULL,CONSTRAINT "unique_name" UNIQUE ("name")); []

[Debug#SQL] INSERT INTO "person"("name", "age", "removed_column") VALUES (?, ?, ?) ON CONFLICT ("name") DO UPDATE SET "name"=EXCLUDED."name", "age"=EXCLUDED."age", "removed_column"=EXCLUDED."removed_column"; [PersistText "Alice",PersistInt64 30]

Foo.hs: SQLite3 returned ErrorError while attempting to perform prepare "INSERT INTO \"person\"(\"name\", \"age\", \"removed_column\") VALUES (?, ?, ?) ON CONFLICT (\"name\") DO UPDATE SET \"name\"=EXCLUDED.\"name\", \"age\"=EXCLUDED.\"age\", \"removed_column\"=EXCLUDED.\"removed_column\"": table person has no column named removed_column

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions