pqi-conformance 1.0.4.0 → 1.0.5.0
raw patch · 3 files changed
+43/−2 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.md +6/−0
- pqi-conformance.cabal +1/−1
- src/library/Pqi/Conformance/Operation/SendQueryParams.hs +36/−1
CHANGELOG.md view
@@ -1,3 +1,9 @@+# v1.0.5.0++## Non-breaking++- Added `sendQueryParams` specs covering a parameter list longer than 65535: `libpq` rejects it locally, without writing anything to the socket, both standalone and in the middle of a pipeline where the commands surrounding it must still get dispatched and drained without desync. `pqi-native` 1.0.1.3 fails both, encoding the parameter count as a wrapping 16-bit field instead of validating it, which corrupted the `Bind` message and desynchronized the connection; 1.0.1.4 fixes it. Found via `hasql` issue #326.+ # v1.0.4.0 ## Non-breaking
pqi-conformance.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: pqi-conformance-version: 1.0.4.0+version: 1.0.5.0 category: Database, PostgreSQL, Testing synopsis: Differential conformance tests for pqi adapters description:
src/library/Pqi/Conformance/Operation/SendQueryParams.hs view
@@ -9,7 +9,7 @@ import qualified Pqi as Lq import Pqi.Conformance.Harness import Pqi.Conformance.Prelude-import Pqi.Conformance.Scenario (drainResults, int4Oid)+import Pqi.Conformance.Scenario (drainResults, execScenario, int4Oid, takeCommandResults, takeResult) import Test.Hspec spec :: Pqi.Adapter -> SpecWith ByteString@@ -54,3 +54,38 @@ results <- drainResults connection exited <- Lq.exitPipelineMode connection pure (entered, sentSelect, sentPrepare, sentQuery, synced, results, exited)++ -- @PQsendQueryParams@ rejects a parameter list longer than 65535 (the+ -- limit imposed by the wire protocol's 16-bit parameter count field)+ -- locally, without writing anything to the socket: it returns 'False'+ -- and leaves the connection exactly as usable as before the call.+ --+ -- <https://github.com/nikita-volkov/hasql/issues/326>+ it "rejects a parameter list longer than 65535 without sending anything, leaving the connection usable" \conninfo ->+ differential adapter conninfo \connection -> do+ let overflowingParams = replicate 65536 (Just (int4Oid, "1", Lq.Text))+ sent <- Lq.sendQueryParams connection "select 1 :: int4" overflowingParams Lq.Text+ followUp <- execScenario "select 2 :: int4" connection+ pure (sent, followUp)++ -- The same rejection placed in the middle of a pipeline: the commands+ -- before it must still get dispatched and the commands after it must+ -- still get queued, with no desync in the result stream and no lasting+ -- effect on the connection once the pipeline is torn down.+ it "in a pipeline, a rejected send is skipped without desyncing the surrounding commands" \conninfo ->+ differential adapter conninfo \connection -> do+ let overflowingParams = replicate 65536 (Just (int4Oid, "1", Lq.Text))+ entered <- Lq.enterPipelineMode connection+ sentBefore1 <- Lq.sendQueryParams connection "select 1 :: int4" [] Lq.Text+ sentBefore2 <- Lq.sendQueryParams connection "select 2 :: int4" [] Lq.Text+ sentBad <- Lq.sendQueryParams connection "select 3 :: int4" overflowingParams Lq.Text+ sentAfter <- Lq.sendQueryParams connection "select 4 :: int4" [] Lq.Text+ synced <- Lq.pipelineSync connection+ first <- takeCommandResults connection+ second <- takeCommandResults connection+ third <- takeCommandResults connection+ syncResult <- takeResult connection+ idle <- takeResult connection+ exited <- Lq.exitPipelineMode connection+ followUp <- execScenario "select 5 :: int4" connection+ pure (entered, sentBefore1, sentBefore2, sentBad, sentAfter, synced, first, second, third, syncResult, idle, exited, followUp)