git.iko.soy/typeable/postgresql-simple
on master help sign in
Document a SQL gotcha related to (In [])

Thanks to Simon Michael and Dan Haraj for bringing this issue to my attention, see #182.

commit38927bfa01c04e4afc957d049cee89ea46603c81 authorLeon P Smith <leon@melding-monads.com> dateSat 30 Apr 2016, 17:39 (10 years ago) parent0d78ba3
1 file changed+30
src/Database/PostgreSQL/Simple/Types.hs+30
src/Database/PostgreSQL/Simple/Types.hs+30
@@ -117,6 +117,36 @@ newtype Only a = Only {
117117-- Example:
118118--
119119-- > query c "select * from whatever where id in ?" (Only (In [3,4,5]))
120+--
121+-- Note that @IN []@ expands to @(null)@, which works as expected in
122+-- the query above, but evaluates to the logical null value on every
123+-- row instead of @TRUE@. This means that changing the query above
124+-- to @... id NOT in ?@ and supplying the empty list as the parameter
125+-- returns zero rows, instead of all of them as one would expect.
126+--
127+-- Since postgresql doesn't seem to provide a syntax for actually specifying
128+-- an empty list, which could solve this completely, there are two
129+-- workarounds worth mentioning, namely:
130+--
131+-- 1. Use postgresql-simple's 'Values' instead, which can handle the
132+-- empty case correctly. Note however that while specifying the
133+-- postgresql type @"int4"@ is mandatory in the empty case, specifying
134+-- the haskell type @[Int]@ would not normally be needed in realistic
135+-- use cases.
136+--
137+-- > query c "select * from whatever where id not in ?"
138+-- > (Only (Values "int4") ([] :: [Int]))
139+--
140+--
141+-- 2. Use sql's @COALESCE@ operator to turn a logical @null@ into the correct
142+-- boolean. Note however that the correct boolean depends on the use
143+-- case:
144+--
145+-- > query c "select * from whatever where coalesce(id NOT in ?, TRUE)"
146+-- > (Only (In ([] :: [Int])))
147+--
148+-- > query c "select * from whatever where coalesce(id IN ?, FALSE)"
149+-- > (Only (In ([] :: [Int])))
120150newtype In a = In a
121151 deriving (Eq, Ord, Read, Show, Typeable, Functor)
122152