Skip to content

limit: Fix HeadQuery + SlowFieldSort applying limit before sort#6690

Open
Maxr1998 wants to merge 1 commit into
beetbox:masterfrom
Maxr1998:limit-fix
Open

limit: Fix HeadQuery + SlowFieldSort applying limit before sort#6690
Maxr1998 wants to merge 1 commit into
beetbox:masterfrom
Maxr1998:limit-fix

Conversation

@Maxr1998

Copy link
Copy Markdown
Contributor

Description

When Results.__iter__() has both a slow sort and a slow query active, the slow query was applied during row materialization (inside _get_objects()), before sort.sort() ran.
Because HeadQuery is order-sensitive (it counts items and stops at N), it was capping the result set to N unsorted rows, which were then sorted. The fix temporarily suppresses the slow query while fetching all rows, sorts them, and only then applies the query to the sorted sequence.

A regression test is added in test/plugins/test_limit.py.

Fixes #5076.

To Do

  • Documentation.
  • Changelog (will be added once reviewed & approved).
  • Tests.

Copilot AI review requested due to automatic review settings May 30, 2026 14:44
@Maxr1998 Maxr1998 requested a review from a team as a code owner May 30, 2026 14:44
@github-actions github-actions Bot added the limit limit plugin label May 30, 2026
@github-actions

Copy link
Copy Markdown

Thank you for the PR! The changelog has not been updated, so here is a friendly reminder to check if you need to add an entry.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a regression test and updates DBCore iteration so that “slow sort” results are sorted before applying order-sensitive limits (e.g., HeadQuery), fixing incorrect top-N behavior when sorting by flexible (non-DB) fields.

Changes:

  • Add a regression test covering limit prefix + slow (flexible-field) sorting behavior.
  • Adjust Results.__iter__ slow-sort path to apply HeadQuery after sorting.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
test/plugins/test_limit.py Adds regression test verifying correct top-N ordering when slow sort is used.
beets/dbcore/db.py Changes slow-sort iteration to sort first, then apply order-sensitive query filtering.

Comment thread beets/dbcore/db.py Outdated
Comment on lines +880 to +895
# When a slow query is also present (e.g. HeadQuery),
# apply it AFTER sorting:
# slow queries may be order-sensitive (HeadQuery counts items and stops at N),
# so limiting before sorting would produce wrong results.
# Temporarily suppress the slow query to materialize all rows, sort them, then filter.
if self.query:
slow_query = self.query
self.query = None
try:
all_objects = list(self._get_objects())
finally:
self.query = slow_query
sorted_objects = self.sort.sort(all_objects)
return iter(
obj for obj in sorted_objects if slow_query.match(obj)
)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point. Keeping a list of order-sensitive query types is error-prone, though, so I'm unsure what the best approach is here.

Comment thread beets/dbcore/db.py
Comment on lines +886 to +891
slow_query = self.query
self.query = None
try:
all_objects = list(self._get_objects())
finally:
self.query = slow_query

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I doubt thread-safety hazards really apply here, but adding the query as a parameter here should work. Let me know whether I should do that.

Comment thread test/plugins/test_limit.py Outdated
When `Results.__iter__()` has both a slow sort and a slow query active,
the slow query was applied during row materialization (inside `_get_objects()`),
before `sort.sort()` ran.
Because `HeadQuery` is order-sensitive (it counts items and stops at N),
it was capping the result set to N unsorted rows, which were then sorted.
The fix temporarily suppresses the slow query while fetching all rows, sorts them,
and only then applies the query to the sorted sequence.

A regression test is added in `test/plugins/test_limit.py`.
@codecov

codecov Bot commented May 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.58%. Comparing base (2efc80b) to head (3120b07).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #6690      +/-   ##
==========================================
+ Coverage   72.57%   72.58%   +0.01%     
==========================================
  Files         162      162              
  Lines       20810    20818       +8     
  Branches     3292     3293       +1     
==========================================
+ Hits        15103    15111       +8     
  Misses       4982     4982              
  Partials      725      725              
Files with missing lines Coverage Δ
beets/dbcore/db.py 94.01% <100.00%> (+0.07%) ⬆️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

limit limit plugin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Limit: issue with sorting by play_count (from lastimport)

2 participants