-
Notifications
You must be signed in to change notification settings - Fork 301
Closed
Milestone
Description
In the module Database.Persist.Sql.Orphan.PersistUnique, upsert makes use of the backend-specific implementation (if any).
upsertBy does not appear in that module and therefore always uses the inefficient default implementation.
See output from the reproduction script below:
[Debug#SQL] INSERT INTO "person"("name","age") VALUES(?,?) RETURNING "id"; [PersistText "John Doe",PersistInt64 35]
--- Using `upsert` creates SQL a query that uses UPSERT syntax:
[Debug#SQL] INSERT INTO "person"("name","age") VALUES (?,?) ON CONFLICT ("name") DO UPDATE SET "age"=? WHERE "person"."name" =? RETURNING "person"."id", "person"."name", "person"."age"; [PersistText "John Doe",PersistNull,PersistInt64 36,PersistText "John Doe"]
--- Using `upsertBy` does not:
[Debug#SQL] SELECT "id","name","age" FROM "person" WHERE "name"=?; [PersistText "John Doe"]
[Debug#SQL] UPDATE "person" SET "age"=? WHERE "id"=? ; [PersistInt64 36,PersistInt64 24]
[Debug#SQL] SELECT "id", "name", "age" FROM "person" WHERE "id"=? ; [PersistInt64 24]
[Debug#SQL] DELETE FROM "person" WHERE "id"=? ; [PersistInt64 24]
Reproduction:
#!/usr/bin/env stack
-- stack --resolver lts-12.26 script
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
import Control.Monad.Logger (runStdoutLoggingT)
import Control.Monad.IO.Class (liftIO)
import Database.Persist
import Database.Persist.Postgresql
import Database.Persist.TH
import Control.Monad.Reader
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Person
name String
age Int Maybe
UniquePerson name
deriving Show Eq
BlogPost
title String
authorId PersonId
deriving Show Eq
|]
main :: IO ()
main = runStdoutLoggingT $ withPostgresqlPool "dbname=persistent" 1 $ liftSqlPersistMPool $ do
runMigration migrateAll
johnId <- insert $ Person "John Doe" $ Just 35
let newJohn = Person "John Doe" Nothing
liftIO $ putStrLn "--- Using `upsert` creates a SQL query that uses UPSERT syntax:"
upsert newJohn [PersonAge =. Just 36]
liftIO $ putStrLn "--- Using `upsertBy` does not:"
upsertBy (UniquePerson "John Doe") newJohn [PersonAge =. Just 36]
delete johnIdReactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels