Skip to content

Commit ed00f57

Browse files
committed
don't copy binary parameter data
1 parent 325087f commit ed00f57

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

src/Database/PostgreSQL/LibPQ.hsc

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -747,13 +747,26 @@ invalidOid :: Oid
747747
invalidOid = Oid (#const InvalidOid)
748748

749749

750+
-- | Prepare the given parameter bytestring for passing on to libpq,
751+
-- without copying for binary parameters.
752+
--
753+
-- This safe to use to pass parameters to libpq considering:
754+
-- * libpq treats the parameter data as read-only
755+
-- * 'ByteString' uses pinned memory
756+
-- * the reference to the 'CString' doesn't escape
757+
unsafeUseParamAsCString :: (B.ByteString, Format) -> (CString -> IO a) -> IO a
758+
unsafeUseParamAsCString (bs, format) =
759+
case format of
760+
Binary -> B.unsafeUseAsCString bs
761+
Text -> B.useAsCString bs
762+
750763
-- | Convert a list of parameters to the format expected by libpq FFI calls.
751764
withParams :: [Maybe (Oid, B.ByteString, Format)]
752765
-> (CInt -> Ptr Oid -> Ptr CString -> Ptr CInt -> Ptr CInt -> IO a)
753766
-> IO a
754767
withParams params action =
755768
withArray oids $ \ts ->
756-
withMany (maybeWith B.useAsCString) values $ \c_values ->
769+
withMany (maybeWith unsafeUseParamAsCString) values $ \c_values ->
757770
withArray c_values $ \vs ->
758771
withArray c_lengths $ \ls ->
759772
withArrayLen formats $ \n fs ->
@@ -768,7 +781,7 @@ withParams params action =
768781
, 0:d
769782
)
770783
accum (!a,!b,!c,!d) (Just (t,v,f)) = ( t:a
771-
, (Just v):b
784+
, (Just (v,f)):b
772785
, (toEnum $ B.length v):c
773786
, (toEnum $ fromEnum f):d
774787
)
@@ -779,7 +792,7 @@ withParamsPrepared :: [Maybe (B.ByteString, Format)]
779792
-> (CInt -> Ptr CString -> Ptr CInt -> Ptr CInt -> IO a)
780793
-> IO a
781794
withParamsPrepared params action =
782-
withMany (maybeWith B.useAsCString) values $ \c_values ->
795+
withMany (maybeWith unsafeUseParamAsCString) values $ \c_values ->
783796
withArray c_values $ \vs ->
784797
withArray c_lengths $ \ls ->
785798
withArrayLen formats $ \n fs ->
@@ -791,7 +804,7 @@ withParamsPrepared params action =
791804
, 0:b
792805
, 0:c
793806
)
794-
accum (!a,!b,!c) (Just (v, f)) = ( (Just v):a
807+
accum (!a,!b,!c) (Just (v, f)) = ( (Just (v,f)):a
795808
, (toEnum $ B.length v):b
796809
, (toEnum $ fromEnum f):c
797810
)

0 commit comments

Comments
 (0)