Skip to content

Commit 19c60bc

Browse files
authored
Merge pull request #58 from haskellari/issue-54
Fix issue with empty binary values
2 parents 7998053 + 2b6d5ae commit 19c60bc

File tree

5 files changed

+58
-13
lines changed

5 files changed

+58
-13
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
0.10.1.0
2+
--------
3+
4+
- Fix issue with empty binary values (https://github.com/haskellari/postgresql-libpq/issues/54)
5+
16
0.10.0.0
27
--------
38

postgresql-libpq.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ library
7272
Database.PostgreSQL.LibPQ.Marshal
7373
Database.PostgreSQL.LibPQ.Notify
7474
Database.PostgreSQL.LibPQ.Oid
75+
Database.PostgreSQL.LibPQ.Ptr
7576

7677
build-depends:
7778
, base >=4.12.0.0 && <4.20

src/Database/PostgreSQL/LibPQ.hs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ import Database.PostgreSQL.LibPQ.Internal
238238
import Database.PostgreSQL.LibPQ.Marshal
239239
import Database.PostgreSQL.LibPQ.Notify
240240
import Database.PostgreSQL.LibPQ.Oid
241+
import Database.PostgreSQL.LibPQ.Ptr
241242

242243
-- $dbconn
243244
-- The following functions deal with making a connection to a
@@ -662,10 +663,13 @@ newtype Result = Result (ForeignPtr PGresult) deriving (Eq, Show)
662663
-- * 'ByteString' uses pinned memory
663664
-- * the reference to the 'CString' doesn't escape
664665
unsafeUseParamAsCString :: (B.ByteString, Format) -> (CString -> IO a) -> IO a
665-
unsafeUseParamAsCString (bs, format) =
666+
unsafeUseParamAsCString (bs, format) kont =
666667
case format of
667-
Binary -> B.unsafeUseAsCString bs
668-
Text -> B.useAsCString bs
668+
Binary -> B.unsafeUseAsCStringLen bs kont'
669+
Text -> B.useAsCString bs kont
670+
where
671+
kont' (ptr, 0) = if ptr == nullPtr then kont emptyPtr else kont ptr
672+
kont' (ptr, _) = kont ptr
669673

670674
-- | Convert a list of parameters to the format expected by libpq FFI calls.
671675
withParams :: [Maybe (Oid, B.ByteString, Format)]

src/Database/PostgreSQL/LibPQ/Ptr.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{-# LANGUAGE MagicHash #-}
2+
module Database.PostgreSQL.LibPQ.Ptr (emptyPtr) where
3+
4+
import GHC.Ptr (Ptr (..))
5+
6+
emptyPtr :: Ptr a
7+
emptyPtr = Ptr ""#

test/Smoke.hs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
1+
{-# LANGUAGE OverloadedStrings #-}
12
module Main (main) where
23

3-
import Control.Monad (unless)
4-
import Test.Tasty (defaultMain, testGroup)
5-
import Test.Tasty.HUnit (testCaseSteps, assertEqual)
4+
import Control.Monad (unless)
5+
import Data.Foldable (toList)
66
import Database.PostgreSQL.LibPQ
7-
import Data.Foldable (toList)
8-
import System.Environment (getEnvironment)
9-
import System.Exit (exitFailure)
7+
import System.Environment (getEnvironment)
8+
import System.Exit (exitFailure)
9+
import Test.Tasty (defaultMain, testGroup)
10+
import Test.Tasty.HUnit (assertEqual, testCaseSteps)
1011

12+
import qualified Data.ByteString as BS
1113
import qualified Data.ByteString.Char8 as BS8
1214

1315
main :: IO ()
1416
main = do
1517
libpqVersion >>= print
1618
withConnstring $ \connString -> defaultMain $ testGroup "postgresql-libpq"
17-
[ testCaseSteps "smoke" $ \info -> smoke info connString
19+
[ testCaseSteps "smoke" $ smoke connString
20+
, testCaseSteps "issue54" $ issue54 connString
1821
]
1922

2023
withConnstring :: (BS8.ByteString -> IO ()) -> IO ()
@@ -39,8 +42,8 @@ withConnstring kont = do
3942
, "port=5432"
4043
]
4144

42-
smoke :: (String -> IO ()) -> BS8.ByteString -> IO ()
43-
smoke info connstring = do
45+
smoke :: BS8.ByteString -> (String -> IO ()) -> IO ()
46+
smoke connstring info = do
4447
let infoShow x = info (show x)
4548

4649
conn <- connectdb connstring
@@ -56,6 +59,31 @@ smoke info connstring = do
5659
serverVersion conn >>= infoShow
5760

5861
s <- status conn
59-
assertEqual "connection not ok" s ConnectionOk
62+
assertEqual "connection not ok" ConnectionOk s
6063

6164
finish conn
65+
66+
issue54 :: BS8.ByteString -> (String -> IO ()) -> IO ()
67+
issue54 connString info = do
68+
conn <- connectdb connString
69+
70+
Just result <- execParams conn
71+
"SELECT ($1 :: bytea), ($2 :: bytea)"
72+
[Just (Oid 17,"",Binary), Just (Oid 17,BS.empty,Binary)]
73+
Binary
74+
s <- resultStatus result
75+
assertEqual "result status" TuplesOk s
76+
77+
-- ntuples result >>= info . show
78+
-- nfields result >>= info . show
79+
80+
null1 <- getisnull result 0 0
81+
null2 <- getisnull result 0 1
82+
assertEqual "fst not null" False null1
83+
assertEqual "snd not null" False null2
84+
85+
Just val1 <- getvalue result 0 0
86+
Just val2 <- getvalue result 0 1
87+
88+
assertEqual "fst not null" BS.empty val1
89+
assertEqual "snd not null" BS.empty val2

0 commit comments

Comments
 (0)