From cebdf286cb1b6ddd68f1a41b4cf09a14968d39ad Mon Sep 17 00:00:00 2001 From: Chris Parks Date: Thu, 8 Jul 2021 09:38:32 -0700 Subject: [PATCH 1/2] Avoid generating an empty list as the left operand to NOT IN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Postgres treats 'x in ()' and 'x not in ()' as syntax errors. Instead translate: x in () ⇒ FALSE x not in () ⇒ TRUE Older versions of esqueleto did this, but apparently the latter got lost. --- src/Database/Esqueleto/Internal/Internal.hs | 6 +++++- test/Common/Test.hs | 13 +++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Database/Esqueleto/Internal/Internal.hs b/src/Database/Esqueleto/Internal/Internal.hs index b946c44d8..87222865a 100644 --- a/src/Database/Esqueleto/Internal/Internal.hs +++ b/src/Database/Esqueleto/Internal/Internal.hs @@ -939,7 +939,11 @@ notIn :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (ValueList typ) -> S ERaw noMeta $ \_ info -> let (b1, vals1) = v Parens info (b2, vals2) = list Parens info - in (b1 <> " NOT IN " <> b2, vals1 <> vals2) + in + if b2 == "()" then + ("TRUE", []) + else + (b1 <> " NOT IN " <> b2, vals1 <> vals2) -- | @EXISTS@ operator. For example: -- diff --git a/test/Common/Test.hs b/test/Common/Test.hs index fe717dc45..a8c3d5c6f 100644 --- a/test/Common/Test.hs +++ b/test/Common/Test.hs @@ -1431,6 +1431,19 @@ testListOfValues = describe "lists of values" $ do return p asserting $ ret `shouldBe` [ Entity p2k p2 ] + itDb "NOT IN works for valList (null list)" $ do + p1k <- insert p1 + p2k <- insert p2 + p3k <- insert p3 + ret <- select $ + from $ \p -> do + where_ (p ^. PersonName `notIn` valList []) + return p + asserting $ ret `shouldMatchList` [ Entity p1k p1 + , Entity p2k p2 + , Entity p3k p3 + ] + itDb "EXISTS works for subList_select" $ do p1k <- insert p1 _p2k <- insert p2 From e9a1261c942775e9d050d34c59994a7c887ff968 Mon Sep 17 00:00:00 2001 From: Chris Parks Date: Thu, 8 Jul 2021 14:57:02 -0700 Subject: [PATCH 2/2] Bump version and update changelog --- changelog.md | 6 ++++++ esqueleto.cabal | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 49f32430d..7dc4b977d 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,9 @@ +3.5.2.1 +======= +- @cdparks + - [#273](https://github.com/bitemyapp/esqueleto/pull/273) + - Avoid generating an empty list as the left operand to `NOT IN`. + 3.5.2.0 ======= - @ivanbakel diff --git a/esqueleto.cabal b/esqueleto.cabal index f192cbf89..f87997ab9 100644 --- a/esqueleto.cabal +++ b/esqueleto.cabal @@ -1,7 +1,7 @@ cabal-version: 1.12 name: esqueleto -version: 3.5.2.0 +version: 3.5.2.1 synopsis: Type-safe EDSL for SQL queries on persistent backends. description: @esqueleto@ is a bare bones, type-safe EDSL for SQL queries that works with unmodified @persistent@ SQL backends. Its language closely resembles SQL, so you don't have to learn new concepts, just new syntax, and it's fairly easy to predict the generated SQL and optimize it for your backend. Most kinds of errors committed when writing SQL are caught as compile-time errors---although it is possible to write type-checked @esqueleto@ queries that fail at runtime. .