Commit Graph
33 Commits
Author SHA1 Message Date
fa01396dfd Fix: selection_data re-derives the filtered document set 5 times over (#13229)
* Fix: selection_data re-derives the filtered document set 5 times over

_get_selection_data_for_queryset() (powers ?include_selection_data=true on
the document list and search endpoints) computed document_count for
Correspondent/DocumentType/StoragePath/Tag/CustomField by embedding the
caller's full filtered queryset -- filters plus the permission check -- as
a subquery inside 5 separate Count(filter=Q(documents__in=queryset), ...)
calls. Each one re-evaluates that whole queryset from scratch.

Resolve the document ids once into a concrete list and reuse it across all
five annotations instead. For Tag/CustomField specifically (M2M via a
through-model table), also route through annotate_document_count_by_ids()
-- extracted from the tag/custom-field document_count fix (#13203) -- to
avoid the same Count(filter=Q(id__in=...), distinct=True)-on-an-M2M-relation
anti-pattern diagnosed there.

On a 400k-document/1,000-tag corpus, the correspondents portion alone
previously didn't finish within several minutes (killed twice while
investigating, including one run that left a zombie query still consuming
a CPU 30+ minutes later). All five queries together now complete in
~30-35s. Root-caused from a real report (paperless-ngx#13201) via a
different, already-fixed query (#13205) -- this one hasn't been reported
in the wild yet, found by auditing the same call path.

Depends on #13203 for annotate_document_count_by_ids().

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>

* Address review feedback: drop unnecessary ordering before collecting ids

queryset passed into _get_selection_data_for_queryset() carries the
default/user-specified ordering, which is irrelevant once we're only
collecting a flat id list. Clearing it removes a pointless sort.

No measurable change in benchmarking at 400k documents -- the id-list
materialization/IN-clause cost still dominates -- but it's a free,
strictly-correct cleanup, not just noise-neutral in the other direction.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 19:21:20 +00:00
84a04301d1 Fix: tag/custom-field document_count scales badly with tag count (#13203)
* Fix (beta): tag/custom-field document_count scales badly with tag count

TagViewSet and CustomFieldViewSet's document_count annotation used a
per-row correlated subquery (annotate_document_count_for_related_queryset),
executed once per tag/custom-field row. Fine at a few dozen rows, but at
~1,000 tags it degrades to a full per-tag GroupAggregate over the tags M2M
table -- 6s+ in production reports, confirmed via EXPLAIN (loops=1000).

Replaced with a single, independent GROUP BY over the through table
(permission filter expressed as a plain WHERE, not an aggregate FILTER),
then injected via Case/When. Also tried a more "obvious" fix -- a plain
Count(filter=Q(id__in=permitted_ids), distinct=True) directly on the M2M
relation -- but that's worse: Postgres fails to plan the id__in check as a
semi-join once a large M2M bridge table is involved, and instead re-checks
subquery membership once per joined row.

Benchmarked against a synthetic corpus (400k documents, 1,000 tags @ ~5/doc,
matching real-world reports in discussion #13161): tag list wall-clock drops
from ~180s to ~8s for a permission-restricted user, ~21s to ~8s for a
superuser. No measurable change at typical home-instance scale (tens of
tags).

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>

* Address review feedback: restore validation, scope aggregation to queryset

- Restore the document_count_source_field validation helper dropped during
  the refactor -- misconfiguring a viewset (document_count_through set
  without document_count_source_field) now fails fast with a clear error
  again instead of an obscure runtime failure.
- Restrict annotate_document_count_for_related_queryset()'s through-table
  aggregation to rows whose related_object_field is one of the annotated
  queryset's pks. No-op for the main tag-list call site (queryset is all
  tags), but avoids unnecessary work for narrower callers like the tag
  descendants branch in TagViewSet.list().

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22 21:28:49 -07:00
Trenton HandGitHub 14fe520319 Chore: Update typing and baselines again (#12641)
a
2026-04-28 09:28:05 -07:00
0c25c2dac5 Feature: Allow monitoring access to tasks summary (#12624)
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2026-04-22 13:48:54 -07:00
shamoonandGitHub 4629bbf83e Enhancement: add view_global_statistics and view_system_status permissions (#12530) 2026-04-08 15:39:47 +00:00
shamoon 4884b67714 Fix more typing failures 2026-02-16 09:37:33 -08:00
shamoon be4e29a19c Merge branch 'main' into dev 2026-02-16 09:01:19 -08:00
shamoonandGitHub 5b45b89d35 Performance fix: use subqueries to improve object retrieval in large installs (#11950) 2026-02-05 08:46:32 -08:00
Sebastian SteinbeißerandGitHub 3b5ffbf9fa Chore(mypy): Annotate None returns for typing improvements (#11213) 2026-02-02 08:44:12 -08:00
shamoonandGitHub 4428354150 Feature: allow duplicates with warnings, UI for discovery (#11815) 2026-01-26 18:55:08 +00:00
shamoonandGitHub 128c3539d5 Chore: fix set_permissions_for_object type (#11564) 2025-12-10 00:12:40 +00:00
shamoon 8efc998687 Chore: refactor permission checks to use queryset.exists() 2025-12-08 15:53:10 -08:00
shamoonandGitHub b60fb8ed82 Fix: remove unnecessary permission requirements for new email endpoint (#11215) 2025-10-29 07:14:51 -07:00
shamoonandGitHub 13161ebb01 Fix: retrieve document_count for tag children (#11125) 2025-10-22 11:13:15 -07:00
shamoonandGitHub df86882e8e Fix: require only change permissions for task dismissal, add frontend error handling (#11023) 2025-10-07 00:56:16 -07:00
shamoonandGitHub 3b19a727b8 Change: better handle permissions in patch requests (#9393) 2025-03-14 08:53:00 -07:00
Sebastian SteinbeißerandGitHub e560fa3be0 Chore: Enable ruff FBT (#8645) 2025-02-07 09:12:03 -08:00
shamoonandGitHub f1559b7108 Fix: add permissions to OPTIONS requests for notes (#7661) 2024-09-09 08:34:21 -07:00
shamoonandGitHub d8c96b6e4a Enhancement: dont require document model permissions for notes (#6913) 2024-06-08 01:23:45 +00:00
Trenton HandGitHub 7be7185418 Handcrafts SQL queries a little more to reduce the query count and/or the amount of returned data (#6489) 2024-04-30 07:37:09 -07:00
shamoonandGitHub f812f2af4d Fix: remove admin.logentry perm, use admin (staff) status (#6380) 2024-04-14 00:35:34 +00:00
shamoonandGitHub 5881f05dbc Change workflow permissions assignment to merge (#5496) 2024-01-22 16:34:16 -08:00
Trenton H 6f163111ce Upgrades black to v23, upgrades ruff 2023-04-26 09:35:27 -07:00
shamoon 1fb03a755f Respect permissions on document view actions 2023-04-25 22:49:37 -07:00
shamoon 52e8a1aba3 Include permissions for suggestions 2023-04-16 00:09:41 -07:00
shamoon 5bd06494d5 Use exclude instead of difference for mariadb 2023-03-31 13:52:06 -07:00
shamoon ae0c585918 Fix inherited permissions should not display per user in permissions form 2023-03-19 23:41:36 -07:00
Michael Shamoon a5ab6f2558 Add ability to set owner per object 2022-12-09 15:54:30 -08:00
Michael Shamoon 6ece5240a5 Bulk edit permissions 2022-12-08 02:03:50 -08:00
Michael Shamoon 2973e4672a fix python tests for user object perms 2022-12-06 22:05:24 -08:00
Michael Shamoon fad13c148e Object-level permissions + filtering 2022-12-05 22:56:03 -08:00
Michael Shamoon 28d70438ec add api permissions test 2022-11-24 22:09:28 -08:00
Michael Shamoon 70eb22df42 Add Django model permissions to API endpoints 2022-11-15 00:44:32 -08:00