packages feed

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 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)