Skip to content

Commit 490b9ca

Browse files
robxphadej
authored andcommitted
Add pipeline mode API
https://www.postgresql.org/docs/current/libpq-pipeline-mode.html - Test pipelineStatus in smoke test - Test pipeline mode API
1 parent fee482e commit 490b9ca

File tree

13 files changed

+191
-41
lines changed

13 files changed

+191
-41
lines changed

Diff for: .github/workflows/haskell-ci.yml

+4-2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ jobs:
9494
chmod a+x "$HOME/.ghcup/bin/ghcup"
9595
"$HOME/.ghcup/bin/ghcup" install ghc "$HCVER" || (cat "$HOME"/.ghcup/logs/*.* && false)
9696
"$HOME/.ghcup/bin/ghcup" install cabal 3.12.1.0 || (cat "$HOME"/.ghcup/logs/*.* && false)
97+
apt-get update
98+
apt-get install -y libpq-dev
9799
env:
98100
HCKIND: ${{ matrix.compilerKind }}
99101
HCNAME: ${{ matrix.compiler }}
@@ -233,7 +235,7 @@ jobs:
233235
$CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --write-ghc-environment-files=always
234236
- name: tests
235237
run: |
236-
$CABAL v2-test $ARG_COMPILER $ARG_TESTS $ARG_BENCH all
238+
$CABAL v2-test $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --test-show-details=direct
237239
- name: cabal check
238240
run: |
239241
cd ${PKGDIR_postgresql_libpq} || false
@@ -244,7 +246,7 @@ jobs:
244246
${CABAL} -vnormal check
245247
- name: haddock
246248
run: |
247-
$CABAL v2-haddock --disable-documentation $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all
249+
$CABAL v2-haddock --disable-documentation --haddock-all $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all
248250
- name: unconstrained build
249251
run: |
250252
rm -f cabal.project.local

Diff for: .github/workflows/simple.yml

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ jobs:
3939
username: ci
4040
password: sw0rdfish
4141
database: test
42+
postgres-version: "14"
4243

4344
- name: Checkout
4445
uses: actions/checkout@v4

Diff for: cabal.haskell-ci

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
branches: master
22
postgresql: True
3-
4-
-- due build-type: Custom
5-
test-output-direct: False
6-
haddock-components: libs
3+
apt: libpq-dev
74

85
constraint-set pkg-config
96
constraints: postgresql-libpq +use-pkg-config

Diff for: postgresql-libpq-configure/configure

+8-8
Original file line numberDiff line numberDiff line change
@@ -3570,7 +3570,7 @@ then :
35703570
ac_cv_POSTGRESQL_LIBS="$POSTGRESQL_LIBS"
35713571
fi
35723572
3573-
postgresql_version_req=10.22
3573+
postgresql_version_req=14.12
35743574
found_postgresql="no"
35753575
35763576
POSTGRESQL_VERSION=""
@@ -3850,8 +3850,8 @@ do
38503850
for ac_exec_ext in '' $ac_executable_extensions; do
38513851
ac_path_PG_CONFIG="$as_dir$ac_prog$ac_exec_ext"
38523852
as_fn_executable_p "$ac_path_PG_CONFIG" || continue
3853-
ac_cv_path_PG_CONFIG="";$ac_path_PG_CONFIG --includedir > /dev/null \
3854-
&& ac_cv_path_PG_CONFIG=$ac_path_PG_CONFIG ac_path_PG_CONFIG_found=:
3853+
ac_cv_path_PG_CONFIG="";"$ac_path_PG_CONFIG" --includedir > /dev/null \
3854+
&& ac_cv_path_PG_CONFIG="$ac_path_PG_CONFIG" ac_path_PG_CONFIG_found=:
38553855
$ac_path_PG_CONFIG_found && break 3
38563856
done
38573857
done
@@ -3867,7 +3867,7 @@ fi
38673867
fi
38683868
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_PG_CONFIG" >&5
38693869
printf "%s\n" "$ac_cv_path_PG_CONFIG" >&6; }
3870-
PG_CONFIG=$ac_cv_path_PG_CONFIG
3870+
PG_CONFIG="$ac_cv_path_PG_CONFIG"
38713871
if test "X$PG_CONFIG" = "X"
38723872
then :
38733873
break
@@ -3879,7 +3879,7 @@ if test ${ac_cv_POSTGRESQL_CPPFLAGS+y}
38793879
then :
38803880
printf %s "(cached) " >&6
38813881
else $as_nop
3882-
ac_cv_POSTGRESQL_CPPFLAGS="-I`$PG_CONFIG --includedir`" || _AX_LIB_POSTGRESQL_OLD_fail=yes
3882+
ac_cv_POSTGRESQL_CPPFLAGS="-I`"$PG_CONFIG" --includedir`" || _AX_LIB_POSTGRESQL_OLD_fail=yes
38833883
fi
38843884
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_POSTGRESQL_CPPFLAGS" >&5
38853885
printf "%s\n" "$ac_cv_POSTGRESQL_CPPFLAGS" >&6; }
@@ -3895,7 +3895,7 @@ if test ${ac_cv_POSTGRESQL_LDFLAGS+y}
38953895
then :
38963896
printf %s "(cached) " >&6
38973897
else $as_nop
3898-
ac_cv_POSTGRESQL_LDFLAGS="-L`$PG_CONFIG --libdir`" || _AX_LIB_POSTGRESQL_OLD_fail=yes
3898+
ac_cv_POSTGRESQL_LDFLAGS="-L`"$PG_CONFIG" --libdir`" || _AX_LIB_POSTGRESQL_OLD_fail=yes
38993899
fi
39003900
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_POSTGRESQL_LDFLAGS" >&5
39013901
printf "%s\n" "$ac_cv_POSTGRESQL_LDFLAGS" >&6; }
@@ -3924,7 +3924,7 @@ then :
39243924
printf %s "(cached) " >&6
39253925
else $as_nop
39263926
3927-
ac_cv_POSTGRESQL_VERSION=`$PG_CONFIG --version | sed "s/^PostgreSQL[[:space:]][[:space:]]*\([0-9.][0-9.]*\).*/\1/"` \
3927+
ac_cv_POSTGRESQL_VERSION=`"$PG_CONFIG" --version | sed "s/^PostgreSQL[[:space:]][[:space:]]*\([0-9.][0-9.]*\).*/\1/"` \
39283928
|| _AX_LIB_POSTGRESQL_OLD_fail=yes
39293929
39303930
fi
@@ -3982,7 +3982,7 @@ x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version
39823982
printf "%s\n" "$found_postgresql_req_version" >&6; }
39833983
39843984
fi
3985-
if test "Xfound_postgresql_req_version" = "Xno"
3985+
if test "X$found_postgresql_req_version" = "Xno"
39863986
then :
39873987
break
39883988
fi

Diff for: postgresql-libpq-configure/configure.ac

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ AC_CONFIG_MACRO_DIRS([m4])
55
AC_PROG_CC
66
AC_PROG_SED
77

8-
AX_LIB_POSTGRESQL([10.22])
8+
AX_LIB_POSTGRESQL([14.12])
99

1010
POSTGRESQL_EXTRA_LIBS="pq"
1111
POSTGRESQL_LIBDIR=$(echo "$POSTGRESQL_LDFLAGS"|$SED 's/-L//')

Diff for: postgresql-libpq-configure/m4/ax_lib_postgresql.m4

+7-7
Original file line numberDiff line numberDiff line change
@@ -58,19 +58,19 @@ AC_DEFUN([_AX_LIB_POSTGRESQL_OLD],[
5858
while true; do
5959
AC_CACHE_CHECK([for the pg_config program], [ac_cv_path_PG_CONFIG],
6060
[AC_PATH_PROGS_FEATURE_CHECK([PG_CONFIG], [pg_config],
61-
[[ac_cv_path_PG_CONFIG="";$ac_path_PG_CONFIG --includedir > /dev/null \
62-
&& ac_cv_path_PG_CONFIG=$ac_path_PG_CONFIG ac_path_PG_CONFIG_found=:]],
61+
[[ac_cv_path_PG_CONFIG="";"$ac_path_PG_CONFIG" --includedir > /dev/null \
62+
&& ac_cv_path_PG_CONFIG="$ac_path_PG_CONFIG" ac_path_PG_CONFIG_found=:]],
6363
[ac_cv_path_PG_CONFIG=""])])
64-
PG_CONFIG=$ac_cv_path_PG_CONFIG
64+
PG_CONFIG="$ac_cv_path_PG_CONFIG"
6565
AS_IF([test "X$PG_CONFIG" = "X"],[break])
6666
6767
AC_CACHE_CHECK([for the PostgreSQL libraries CPPFLAGS],[ac_cv_POSTGRESQL_CPPFLAGS],
68-
[ac_cv_POSTGRESQL_CPPFLAGS="-I`$PG_CONFIG --includedir`" || _AX_LIB_POSTGRESQL_OLD_fail=yes])
68+
[ac_cv_POSTGRESQL_CPPFLAGS="-I`"$PG_CONFIG" --includedir`" || _AX_LIB_POSTGRESQL_OLD_fail=yes])
6969
AS_IF([test "X$_AX_LIB_POSTGRESQL_OLD_fail" = "Xyes"],[break])
7070
POSTGRESQL_CPPFLAGS="$ac_cv_POSTGRESQL_CPPFLAGS"
7171
7272
AC_CACHE_CHECK([for the PostgreSQL libraries LDFLAGS],[ac_cv_POSTGRESQL_LDFLAGS],
73-
[ac_cv_POSTGRESQL_LDFLAGS="-L`$PG_CONFIG --libdir`" || _AX_LIB_POSTGRESQL_OLD_fail=yes])
73+
[ac_cv_POSTGRESQL_LDFLAGS="-L`"$PG_CONFIG" --libdir`" || _AX_LIB_POSTGRESQL_OLD_fail=yes])
7474
AS_IF([test "X$_AX_LIB_POSTGRESQL_OLD_fail" = "Xyes"],[break])
7575
POSTGRESQL_LDFLAGS="$ac_cv_POSTGRESQL_LDFLAGS"
7676
@@ -80,7 +80,7 @@ AC_DEFUN([_AX_LIB_POSTGRESQL_OLD],[
8080
8181
AC_CACHE_CHECK([for the PostgreSQL version],[ac_cv_POSTGRESQL_VERSION],
8282
[
83-
ac_cv_POSTGRESQL_VERSION=`$PG_CONFIG --version | sed "s/^PostgreSQL[[[:space:]]][[[:space:]]]*\([[0-9.]][[0-9.]]*\).*/\1/"` \
83+
ac_cv_POSTGRESQL_VERSION=`"$PG_CONFIG" --version | sed "s/^PostgreSQL[[[:space:]]][[[:space:]]]*\([[0-9.]][[0-9.]]*\).*/\1/"` \
8484
|| _AX_LIB_POSTGRESQL_OLD_fail=yes
8585
])
8686
AS_IF([test "X$_AX_LIB_POSTGRESQL_OLD_fail" = "Xyes"],[break])
@@ -96,7 +96,7 @@ AC_DEFUN([_AX_LIB_POSTGRESQL_OLD],[
9696
[found_postgresql_req_version=yes],[found_postgresql_req_version=no])
9797
AC_MSG_RESULT([$found_postgresql_req_version])
9898
])
99-
AS_IF([test "Xfound_postgresql_req_version" = "Xno"],[break])
99+
AS_IF([test "X$found_postgresql_req_version" = "Xno"],[break])
100100
101101
found_postgresql="yes"
102102
break

Diff for: postgresql-libpq-configure/postgresql-libpq-configure.cabal

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 2.4
22
name: postgresql-libpq-configure
3-
version: 0.10
3+
version: 0.11
44
synopsis: low-level binding to libpq: configure based provider
55
description:
66
This is a binding to libpq: the C application

Diff for: postgresql-libpq-pkgconfig/postgresql-libpq-pkgconfig.cabal

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 2.4
22
name: postgresql-libpq-pkgconfig
3-
version: 0.10
3+
version: 0.11
44
synopsis: low-level binding to libpq: pkg-config based provider
55
description:
66
This is a binding to libpq: the C application
@@ -35,7 +35,7 @@ extra-source-files: CHANGELOG.md
3535
library
3636
default-language: Haskell2010
3737
build-depends: base <5
38-
pkgconfig-depends: libpq >=10.22
38+
pkgconfig-depends: libpq >=14.12
3939

4040
source-repository head
4141
type: git

Diff for: postgresql-libpq.cabal

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 2.4
22
name: postgresql-libpq
3-
version: 0.10.2.0
3+
version: 0.11.0.0
44
synopsis: low-level binding to libpq
55
description:
66
This is a binding to libpq: the C application
@@ -81,10 +81,10 @@ library
8181
build-depends: Win32 >=2.2.0.2 && <2.15
8282

8383
if flag(use-pkg-config)
84-
build-depends: postgresql-libpq-pkgconfig ^>=0.10
84+
build-depends: postgresql-libpq-pkgconfig ^>=0.11
8585

8686
else
87-
build-depends: postgresql-libpq-configure ^>=0.10
87+
build-depends: postgresql-libpq-configure ^>=0.11
8888

8989
build-tool-depends: hsc2hs:hsc2hs >=0.68.5
9090

Diff for: src/Database/PostgreSQL/LibPQ.hs

+63
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,15 @@ module Database.PostgreSQL.LibPQ
171171
, FlushStatus(..)
172172
, flush
173173

174+
-- * Pipeline Mode
175+
-- $pipelinemode
176+
, PipelineStatus(..)
177+
, pipelineStatus
178+
, enterPipelineMode
179+
, exitPipelineMode
180+
, pipelineSync
181+
, sendFlushRequest
182+
174183
-- * Cancelling Queries in Progress
175184
-- $cancel
176185
, Cancel
@@ -1640,6 +1649,60 @@ flush connection =
16401649
1 -> return FlushWriting
16411650
_ -> return FlushFailed
16421651

1652+
-- $pipelinemode
1653+
-- These functions control behaviour in pipeline mode.
1654+
--
1655+
-- Pipeline mode allows applications to send a query
1656+
-- without having to read the result of the previously
1657+
-- sent query. Taking advantage of the pipeline mode,
1658+
-- a client will wait less for the server, since multiple
1659+
-- queries/results can be sent/received in
1660+
-- a single network transaction.
1661+
1662+
-- | Returns the current pipeline mode status of the libpq connection.
1663+
--
1664+
-- @since 0.11.0.0
1665+
pipelineStatus :: Connection
1666+
-> IO PipelineStatus
1667+
pipelineStatus connection = do
1668+
stat <- withConn connection c_PQpipelineStatus
1669+
maybe
1670+
(fail $ "Unknown pipeline status " ++ show stat)
1671+
return
1672+
(fromCInt stat)
1673+
1674+
-- | Causes a connection to enter pipeline mode if it is currently idle or already in pipeline mode.
1675+
--
1676+
-- @since 0.11.0.0
1677+
enterPipelineMode :: Connection
1678+
-> IO Bool
1679+
enterPipelineMode connection =
1680+
enumFromConn connection c_PQenterPipelineMode
1681+
1682+
-- | Causes a connection to exit pipeline mode if it is currently in pipeline mode with an empty queue and no pending results.
1683+
--
1684+
-- @since 0.11.0.0
1685+
exitPipelineMode :: Connection
1686+
-> IO Bool
1687+
exitPipelineMode connection =
1688+
enumFromConn connection c_PQexitPipelineMode
1689+
1690+
-- | Marks a synchronization point in a pipeline by sending a sync message and flushing the send buffer. This serves as the delimiter of an implicit transaction and an error recovery point>
1691+
--
1692+
-- @since 0.11.0.0
1693+
pipelineSync :: Connection
1694+
-> IO Bool
1695+
pipelineSync connection =
1696+
enumFromConn connection c_PQpipelineSync
1697+
1698+
-- | Sends a request for the server to flush its output buffer.
1699+
--
1700+
-- @since 0.11.0.0
1701+
sendFlushRequest :: Connection
1702+
-> IO Bool
1703+
sendFlushRequest connection =
1704+
enumFromConn connection c_PQsendFlushRequest
1705+
16431706

16441707
-- $cancel
16451708
-- A client application can request cancellation of a command that is

Diff for: src/Database/PostgreSQL/LibPQ/Enums.hsc

+52-12
Original file line numberDiff line numberDiff line change
@@ -37,23 +37,42 @@ data ExecStatus
3737
| NonfatalError -- ^ A nonfatal error (a notice or
3838
-- warning) occurred.
3939
| FatalError -- ^ A fatal error occurred.
40-
| SingleTuple -- ^ The PGresult contains a single result tuple
40+
| SingleTuple -- ^ The 'Result' contains a single result tuple
4141
-- from the current command. This status occurs
4242
-- only when single-row mode has been selected
4343
-- for the query.
44+
45+
| PipelineSync -- ^ The 'Result' represents a synchronization
46+
-- point in pipeline mode, requested by
47+
-- 'pipelineSync'. This status occurs only
48+
-- when pipeline mode has been selected.
49+
--
50+
-- @since 0.11.0.0
51+
52+
| PipelineAbort -- ^ The 'Result' represents a pipeline that
53+
-- has received an error from the server.
54+
-- 'getResult' must be called repeatedly,
55+
-- and each time it will return this status
56+
-- code until the end of the current pipeline,
57+
-- at which point it will return 'PipelineSync'
58+
-- and normal processing can resume.
59+
--
60+
-- @since 0.11.0.0
4461
deriving (Eq, Show)
4562

4663
instance FromCInt ExecStatus where
47-
fromCInt (#const PGRES_EMPTY_QUERY) = Just EmptyQuery
48-
fromCInt (#const PGRES_COMMAND_OK) = Just CommandOk
49-
fromCInt (#const PGRES_TUPLES_OK) = Just TuplesOk
50-
fromCInt (#const PGRES_COPY_OUT) = Just CopyOut
51-
fromCInt (#const PGRES_COPY_IN) = Just CopyIn
52-
fromCInt (#const PGRES_COPY_BOTH) = Just CopyBoth
53-
fromCInt (#const PGRES_BAD_RESPONSE) = Just BadResponse
54-
fromCInt (#const PGRES_NONFATAL_ERROR) = Just NonfatalError
55-
fromCInt (#const PGRES_FATAL_ERROR) = Just FatalError
56-
fromCInt (#const PGRES_SINGLE_TUPLE) = Just SingleTuple
64+
fromCInt (#const PGRES_EMPTY_QUERY) = Just EmptyQuery
65+
fromCInt (#const PGRES_COMMAND_OK) = Just CommandOk
66+
fromCInt (#const PGRES_TUPLES_OK) = Just TuplesOk
67+
fromCInt (#const PGRES_COPY_OUT) = Just CopyOut
68+
fromCInt (#const PGRES_COPY_IN) = Just CopyIn
69+
fromCInt (#const PGRES_COPY_BOTH) = Just CopyBoth
70+
fromCInt (#const PGRES_BAD_RESPONSE) = Just BadResponse
71+
fromCInt (#const PGRES_NONFATAL_ERROR) = Just NonfatalError
72+
fromCInt (#const PGRES_FATAL_ERROR) = Just FatalError
73+
fromCInt (#const PGRES_SINGLE_TUPLE) = Just SingleTuple
74+
fromCInt (#const PGRES_PIPELINE_SYNC) = Just PipelineSync
75+
fromCInt (#const PGRES_PIPELINE_ABORTED) = Just PipelineAbort
5776
fromCInt _ = Nothing
5877

5978
instance ToCInt ExecStatus where
@@ -67,6 +86,8 @@ instance ToCInt ExecStatus where
6786
toCInt NonfatalError = (#const PGRES_NONFATAL_ERROR)
6887
toCInt FatalError = (#const PGRES_FATAL_ERROR)
6988
toCInt SingleTuple = (#const PGRES_SINGLE_TUPLE)
89+
toCInt PipelineSync = (#const PGRES_PIPELINE_SYNC)
90+
toCInt PipelineAbort = (#const PGRES_PIPELINE_ABORTED)
7091

7192

7293
data FieldCode
@@ -230,7 +251,7 @@ instance FromCInt ConnStatus where
230251
fromCInt (#const CONNECTION_SSL_STARTUP) = return ConnectionSSLStartup
231252
-- fromCInt (#const CONNECTION_NEEDED) = return ConnectionNeeded
232253
fromCInt _ = Nothing
233-
254+
234255

235256
data TransactionStatus
236257
= TransIdle -- ^ currently idle
@@ -263,6 +284,25 @@ instance FromCInt Format where
263284
fromCInt 1 = Just Binary
264285
fromCInt _ = Nothing
265286

287+
288+
-- |
289+
--
290+
-- @since 0.11.0.0
291+
data PipelineStatus
292+
= PipelineOn -- ^ The 'Connection' is in pipeline mode.
293+
| PipelineOff -- ^ The 'Connection' is /not/ in pipeline mode.
294+
| PipelineAborted -- ^ The 'Connection' is in pipeline mode and an error
295+
-- occurred while processing the current pipeline. The
296+
-- aborted flag is cleared when 'getResult' returns a
297+
-- result with status 'PipelineSync'.
298+
deriving (Eq, Show)
299+
300+
instance FromCInt PipelineStatus where
301+
fromCInt (#const PQ_PIPELINE_ON) = return PipelineOn
302+
fromCInt (#const PQ_PIPELINE_OFF) = return PipelineOff
303+
fromCInt (#const PQ_PIPELINE_ABORTED) = return PipelineAborted
304+
fromCInt _ = Nothing
305+
266306
-------------------------------------------------------------------------------
267307
-- System.IO enumerations
268308
-------------------------------------------------------------------------------

0 commit comments

Comments
 (0)