Skip to content

fix(postgrest): override limit and offset instead of appending duplicates#1512

Open
AndroidPoet wants to merge 1 commit into
supabase:mainfrom
AndroidPoet:fix/postgrest-limit-range-override
Open

fix(postgrest): override limit and offset instead of appending duplicates#1512
AndroidPoet wants to merge 1 commit into
supabase:mainfrom
AndroidPoet:fix/postgrest-limit-range-override

Conversation

@AndroidPoet

Copy link
Copy Markdown
Contributor

What

limit() and range() built their query params with appendSearchParams, which accumulates repeated keys. Because limit and offset are single-valued in PostgREST, chaining or re-applying them emitted duplicate, conflicting params:

from('t').select().limit(5).range(0, 9); // select=*&limit=5&limit=10&offset=0
from('t').select().limit(1).limit(2);     // limit=1&limit=2
from('t').select().range(0, 9).range(10, 19); // offset=0&offset=10&limit=10&limit=10

This overrides those keys so the last call wins.

Why

limit/range used appendSearchParams, but select (postgrest_transform_builder.dart:46) and order (:88) in the same file already use overrideSearchParams for exactly this reason. postgrest-js also uses searchParams.set(...) for limit and range. Emitting two limit/offset values is ambiguous and diverges from both.

Fix: give overrideSearchParams the same optional [Uri? url] parameter that appendSearchParams already has, then use it for limit (single key) and range (both offset and limit).

Not a breaking change

A single limit()/range() call produces the same query string as before — only the previously-duplicated case changes (the last value now wins, which is the documented intent). overrideSearchParams gains an optional parameter, so existing callers are unaffected.

Tests

Added packages/postgrest/test/limit_range_test.dart (URL-capturing mock): .limit(1).limit(2)limit=2; .limit(5).range(0,9) → single limit=10 + offset=0; .range(0,9).range(10,19) → single offset=10/limit=10; and the referencedTable variant stays scoped and single-valued. All fail on the current code (e.g. Actual: ['1', '2']) and pass with the fix. dart format and dart analyze --fatal-warnings are clean.

@AndroidPoet AndroidPoet requested a review from a team as a code owner July 2, 2026 10:24
@AndroidPoet AndroidPoet force-pushed the fix/postgrest-limit-range-override branch from 8ead7c7 to 9cbbe03 Compare July 2, 2026 11:24
…ates

limit() and range() built their query params with appendSearchParams, so
chaining or re-applying them on a shared builder emitted duplicate,
single-valued params, e.g. select().limit(5).range(0,9) produced
limit=5&limit=10&offset=0 and limit(1).limit(2) produced limit=1&limit=2.
PostgREST treats limit/offset as single-valued, so override them (last
call wins), matching postgrest-js and the select()/order() handling in
the same file.
@AndroidPoet AndroidPoet force-pushed the fix/postgrest-limit-range-override branch from 9cbbe03 to e4b5a19 Compare July 2, 2026 12:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant