Skip to content

fix: keyset pagination rejects NULL and duplicate keys at every batch size - #2671

Merged
norberttech merged 2 commits into
1.xfrom
bug-2670
Oct 7, 2026
Merged

norberttech merged 2 commits into
1.xfrom
bug-2670

Conversation

@norberttech

Copy link
Copy Markdown
Member

Resolves: #2670

Change Log


Added

  • flow-php/etl-adapter-postgresql - keyset reads run a NULL key check query before the first page
  • flow-php/etl-adapter-doctrine - keyset reads run a NULL key check query before the first page

Fixed

  • flow-php/etl-adapter-postgresql - keyset reads no longer drop NULL or duplicate key rows depending on batch size
  • flow-php/etl-adapter-doctrine - keyset reads no longer drop NULL or duplicate key rows depending on batch size
  • flow-php/etl-adapter-postgresql - quoted keyset keys read their unquoted result columns
  • flow-php/postgresql - keyset pagination no longer silently replaces a query's own LIMIT
  • flow-php/postgresql - keyset pagination rejects a NULL cursor value

Changed

  • flow-php/etl-adapter-postgresql - a short keyset page ends the read without an extra query
  • flow-php/etl-adapter-doctrine - a short keyset page ends the read without an extra query
  • flow-php/etl-adapter-doctrine - keyset extractor rejects setMaxResults() / setFirstResult()
  • flow-php/etl-adapter-doctrine - pagination_key_set() requires at least one key
  • flow-php/postgresql - keyset query ORDER BY must equal the keys
  • flow-php/postgresql - same-direction composite keyset keys use a row comparison

Removed

Deprecated

Security

… size

- NULL check query before the first page, in both keyset extractors
- duplicate and collation-equal keys detected via a one-row page lookahead
- a short page ends the read without an extra query
- lib keyset rejects query LIMIT/OFFSET, a mismatched ORDER BY and NULL cursor values
- same-direction composite keys use a row comparison
- DBAL KeySet requires at least one key
@codecov

codecov Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.36%. Comparing base (ff96759) to head (9295550).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff              @@
##                1.x    #2671      +/-   ##
============================================
+ Coverage     89.31%   89.36%   +0.04%     
- Complexity    27705    27763      +58     
============================================
  Files          2105     2110       +5     
  Lines         81696    81901     +205     
============================================
+ Hits          72963    73187     +224     
+ Misses         8733     8714      -19     
Components Coverage Δ
etl 95.70% <ø> (ø)
cli 87.62% <ø> (ø)
lib-array-dot 96.52% <ø> (ø)
lib-azure-sdk 64.44% <ø> (ø)
lib-doctrine-dbal-bulk 94.24% <ø> (ø)
lib-filesystem 87.55% <ø> (ø)
lib-types 94.74% <ø> (ø)
lib-parquet 73.73% <ø> (-0.06%) ⬇️
lib-parquet-viewer 82.07% <ø> (ø)
lib-snappy 89.86% <ø> (ø)
lib-dremel 0.00% <ø> (ø)
lib-postgresql 89.38% <100.00%> (+0.05%) ⬆️
lib-telemetry 86.64% <ø> (ø)
bridge-filesystem-async-aws 92.76% <ø> (ø)
bridge-filesystem-azure 90.34% <ø> (ø)
bridge-filesystem-sftp 91.02% <ø> (ø)
bridge-monolog-http 96.84% <ø> (ø)
bridge-monolog-telemetry 94.79% <ø> (ø)
bridge-openapi-specification 91.45% <ø> (ø)
symfony-http-foundation 75.81% <ø> (ø)
bridge-psr18-telemetry 100.00% <ø> (ø)
bridge-psr3-telemetry 98.95% <ø> (ø)
bridge-psr7-telemetry 100.00% <ø> (ø)
bridge-telemetry-otlp 90.11% <ø> (ø)
bridge-symfony-http-foundation-telemetry 92.85% <ø> (ø)
bridge-symfony-filesystem-bundle 91.85% <ø> (ø)
bridge-symfony-filesystem-cache 98.18% <ø> (ø)
bridge-symfony-postgresql-bundle 93.62% <ø> (ø)
bridge-symfony-postgresql-cache 94.41% <ø> (ø)
bridge-symfony-postgresql-messenger 98.80% <ø> (ø)
bridge-symfony-postgresql-session 93.65% <ø> (ø)
bridge-symfony-telemetry-bundle 90.72% <ø> (ø)
adapter-chartjs 79.14% <ø> (ø)
adapter-csv 96.64% <ø> (ø)
adapter-doctrine 94.86% <100.00%> (+1.29%) ⬆️
adapter-google-sheet 99.18% <ø> (ø)
adapter-http 88.29% <ø> (ø)
adapter-json 89.91% <ø> (ø)
adapter-logger 44.44% <ø> (ø)
adapter-parquet 93.71% <ø> (ø)
adapter-text 96.92% <ø> (ø)
adapter-xml 94.18% <ø> (ø)
adapter-avro 7.14% <ø> (ø)
adapter-excel 97.27% <ø> (ø)
adapter-postgresql 97.48% <100.00%> (+1.58%) ⬆️
adapter-seal 90.86% <ø> (ø)
bridge-phpunit-postgresql 75.30% <ø> (ø)
bridge-phpunit-telemetry 87.36% <ø> (ø)
bridge-phpstan-types 0.00% <ø> (ø)
bridge-postgresql-valinor 100.00% <ø> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

- nix extension dev versions bumped to 0.46.0-dev
- keyset upgrading entries moved to 0.45.x → 0.46.x
@norberttech
norberttech merged commit 9642e80 into 1.x Oct 7, 2026
50 checks passed
@norberttech
norberttech deleted the bug-2670 branch October 7, 2026 20:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Bug]: Keyset extractor silently drops rows whose key is NULL, or throws, depending on batch size

1 participant