Skip to content

Commit d82d800

Browse files
committed
don't copy binary parameter data
1 parent e849c41 commit d82d800

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,12 +747,25 @@ 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
withParams :: [Maybe (Oid, B.ByteString, Format)]
751764
-> (CInt -> Ptr Oid -> Ptr CString -> Ptr CInt -> Ptr CInt -> IO a)
752765
-> IO a
753766
withParams params action =
754767
withArray oids $ \ts ->
755-
withMany (maybeWith B.useAsCString) values $ \c_values ->
768+
withMany (maybeWith unsafeUseParamAsCString) values $ \c_values ->
756769
withArray c_values $ \vs ->
757770
withArray c_lengths $ \ls ->
758771
withArrayLen formats $ \n fs ->
@@ -767,7 +780,7 @@ withParams params action =
767780
, 0:d
768781
)
769782
accum (!a,!b,!c,!d) (Just (t,v,f)) = ( t:a
770-
, (Just v):b
783+
, (Just (v,f)):b
771784
, (toEnum $ B.length v):c
772785
, (toEnum $ fromEnum f):d
773786
)
@@ -776,7 +789,7 @@ withParamsPrepared :: [Maybe (B.ByteString, Format)]
776789
-> (CInt -> Ptr CString -> Ptr CInt -> Ptr CInt -> IO a)
777790
-> IO a
778791
withParamsPrepared params action =
779-
withMany (maybeWith B.useAsCString) values $ \c_values ->
792+
withMany (maybeWith unsafeUseParamAsCString) values $ \c_values ->
780793
withArray c_values $ \vs ->
781794
withArray c_lengths $ \ls ->
782795
withArrayLen formats $ \n fs ->
@@ -788,7 +801,7 @@ withParamsPrepared params action =
788801
, 0:b
789802
, 0:c
790803
)
791-
accum (!a,!b,!c) (Just (v, f)) = ( (Just v):a
804+
accum (!a,!b,!c) (Just (v, f)) = ( (Just (v,f)):a
792805
, (toEnum $ B.length v):b
793806
, (toEnum $ fromEnum f):c
794807
)

0 commit comments

Comments
 (0)