Skip to content

fix: page respects paginator max size#37

Open
klaidliadon wants to merge 10 commits intomasterfrom
max-size
Open

fix: page respects paginator max size#37
klaidliadon wants to merge 10 commits intomasterfrom
max-size

Conversation

@klaidliadon
Copy link
Contributor

@klaidliadon klaidliadon commented Feb 2, 2026

Page size is limited by the constant in the codebase (50). This prevents higher page sizes, even when specified by a paginator. It also removes some generics that are not needed


This pull request refactors the paginator implementation to simplify configuration and improve clarity. The main change is replacing the functional options pattern with a PaginatorOptions struct, which centralizes configuration for default page size, max size, sort order, and column transformation. All paginator methods and tests are updated to use this new struct, resulting in more straightforward and maintainable code.

Paginator configuration refactor:

  • Replaced the functional options pattern (WithDefaultSize, WithMaxSize, etc.) with a single PaginatorOptions struct that holds all configuration, including DefaultSize, MaxSize, Sort, and ColumnFunc. The NewPaginator function now takes a pointer to PaginatorOptions instead of variadic option functions. (page.go)
  • Updated all paginator methods (Limit, Offset, etc.) to accept a *PaginatorOptions parameter, ensuring they use the correct configuration values from the struct. (page.go)

Paginator logic updates:

  • Modified paginator logic in methods like PrepareQuery, PrepareRaw, and PrepareResult to use the new options struct for determining limits, offsets, and sorting, ensuring consistent behavior. (page.go) [1] [2]

Test updates:

  • Refactored all tests to use the new PaginatorOptions struct instead of the old functional options, improving readability and alignment with the new API. (page_test.go) [1] [2] [3] [4] [5]

@klaidliadon klaidliadon requested a review from attente February 3, 2026 16:16
@attente
Copy link
Contributor

attente commented Feb 4, 2026

• The change introduces a regression in default pagination behavior: with nil or partial options, PrepareQuery now discards non‑zero page.Size values and applies an unintended default limit/offset. This will
produce incorrect pagination for callers who relied on the previous defaults.

Review comment:

  • [P2] Apply default sizes before clamping page.Size — /home/william/pgkit/page.go:200-205
    When NewPaginator(nil) is used (or when PaginatorOptions leaves DefaultSize/MaxSize as zero), p.DefaultSize and p.MaxSize are both 0 here. That causes any non‑zero page.Size to be clamped to 0 and then the
    query uses Limit()’s default (10), so a request like page.Size=20 is silently ignored and offsets are computed for 10‑row pages. This is a regression from the previous default behavior; consider applying
    getDefaults() here or initializing PaginatorOptions with default values in NewPaginator so user‑supplied sizes are respected.

@attente
Copy link
Contributor

attente commented Feb 4, 2026

Sorry, a new one now:

• The new defaulting logic in PrepareQuery can leave page.Size inconsistent with the actual LIMIT when
MaxSize is left unset, producing incorrect pagination metadata in a realistic construction pattern.

Review comment:

  • [P2] Clamp page.Size when MaxSize is left unset — /home/william/pgkit/page.go:212-216
    Because PrepareQuery only clamps when p.MaxSize != 0, constructing a paginator via struct literal
    (e.g., PaginatorOptions{DefaultSize: 100} with MaxSize left at zero) leaves page.Size at 100 while
    page.Limit(&p.PaginatorOptions) still caps the query to MaxPageSize (50) via getDefaults(). This
    makes the pagination metadata disagree with the actual LIMIT in this valid usage path. Consider
    deriving defaults with getDefaults() or treating MaxSize == 0 as the default max when updating
    page.Size.

@attente
Copy link
Contributor

attente commented Feb 5, 2026

• There is a behavioral inconsistency in the new pagination defaults: getDefaults can reduce the effective default page size when DefaultSize exceeds MaxSize unless options are normalized via NewPaginator, which
breaks the documented behavior and can lead to incorrect pagination.

Review comment:

  • [P2] Normalize MaxSize instead of shrinking DefaultSize — /home/william/pgkit/page.go:185-197
    The new PaginatorOptions.getDefaults swaps values using min/max, so if DefaultSize exceeds MaxSize (or DefaultSize is raised above the default MaxPageSize), Page.Limit/Offset will use the smaller MaxSize as
    the default (e.g., DefaultSize: 100 ends up limiting to 50). This only shows up when callers use Page.Limit/Offset directly or construct Paginator without NewPaginator, but it contradicts the documented
    behavior (“MaxSize is set to DefaultSize”) and yields smaller page sizes/offsets than requested; consider clamping MaxSize up to DefaultSize in getDefaults as well.

func (m *Mapper) TraversalsByName(t reflect.Type, names []string) [][]int {
r := make([][]int, 0, len(names))
m.TraversalsByNameFunc(t, names, func(_ int, i []int) error {
_ = m.TraversalsByNameFunc(t, names, func(_ int, i []int) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is redundant.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's to signal the linter you are explicitly ignoring the error

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.

2 participants