-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support upsert with empty updates #301
Conversation
Ah, dang. In the event that we do an So the most proper type of At least, as a default. Playing around locally, the following form works: WITH inserted AS (
INSERT INTO "OneUnique" (name, value)
VALUES ("asdf", 0)
ON CONFLICT (value)
DO NOTHING
RETURNING id, name, value
)
SELECT id, name, value
FROM inserted
UNION
SELECT id, name, value
FROM "OneUnique"
WHERE value = 0 But I have no idea what sorts of performance this has. This StackOverflow question/answer has some details and it looks to be somewhat complicated. Maybe the type of coolUpsert entity updates =
case NonEmpty.nonEmpty updates of
Just nonEmptyUpdates ->
Just <$> upsert entity nonEmptyUpdates
Nothing ->
insertOnConflictDoNothing entity It might be tempting to write:
But this only means that the uniqueness key is the same, not the rest of the values. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dang, this is more complicated than I thought.
@@ -51,6 +51,34 @@ import Common.Test | |||
import Common.Test.Import hiding (from, on) | |||
import PostgreSQL.MigrateJSON | |||
|
|||
spec :: Spec |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is just moved up to the top
@@ -1038,18 +1066,20 @@ testInsertUniqueViolation = | |||
sqlErrorHint = ""} | |||
|
|||
testUpsert :: SpecDb | |||
testUpsert = | |||
describe "Upsert test" $ do | |||
testUpsert = describe "Upsert test" $ do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed formatting to be 4 space indent
test/PostgreSQL/Test.hs
Outdated
itDb "Works with no updates" $ do | ||
_ <- EP.upsert u1 [] | ||
pure () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New test case here
test/PostgreSQL/Test.hs
Outdated
itDb "Works with no updates" $ do | ||
_ <- EP.upsert u1 [] | ||
pure () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, this passes. Hooray.
test/PostgreSQL/Test.hs
Outdated
itDb "Works with no updates, twice" $ do | ||
Entity u1Key u1' <- EP.upsert u1 [] | ||
Entity u1Key_ u1'' <- EP.upsert u1 { oneUniqueName = "Something Else" } [] | ||
pure () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, this fails with ErrorCall "head: empty list"
.
The reason is that:
INSERT INTO "OneUnique" (name, value)
VALUES (?, ?)
ON CONFLICT DO NOTHING
RETURNING id, name, value
does not return anything if we don't perform an INSERT
- so the return is []
which he head
on and it goes boom.
DO UPDATE
always does something. But we really don't want to do something silly like DO UPDATE SET blah = EXCLUDED.blah
because this does unnecessary writes and triggers.
* Remove `Coercible` abiilty for `SqlExpr`. (#413) * Remove Coercible * Remove coercible * update docs and changelog * Support upsert with empty updates (#301) * Support upsert with empty updates * stylish, changelog link * clean * remove focus * oh no * update with new api * tests pass * Fix distinctOn (#287) * Fix distinctOn * lol * expose * Deprecation Cycles for 3.6 (#412) * Deprecate ilike outside of Postgres * lol * Deprecation Cycling * wow okay cool * oh woops * Add fixity on question-dot operator (#420) * Add fixity on question-dot operator * changelog link * Deprecate LockingKind constructors (#421) * Deprecate LockingKind constructors * changelog * `HasField` for `SqlExpr (Maybe (Entity a))` joins `Maybe` (#422) * HasField on SqlExpr (Maybe Entity) joins Maybe * hmmm that works kinda nicely * Incorporate changes from the work codebase * add another test case * changelog * wat * wat * wat * 3.6 fixups (#425) * Re-export Nullable from ToMaybe * Fixity on ilike * lolwhoops * changelog link * add toBaseIdMaybe and fromBaseIdMaybe * start sketching out the sqlcoerce class * no sqlcoerce yet * ok for convenience
Fixes #300
Before submitting your PR, check that you've:
@since
declarations to the Haddock.stylish-haskell
and otherwise adhered to the style guide.After submitting your PR: