[qt/qtqa/gerrit]: Summary of bulk changes made

KDE Git Services - Bulk Change <[email protected]> Tue, 4 Aug 2026 18:15:46 +0000 (UTC)
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git repository change summary for qt/qtqa/gerrit
Pushed by mirror-service into branch 'upstream/stable-3.11'.
Changed from 53c97c7e1c488d6fbebe5137cd33ba75dac21768 to f698053df831ac439130416148c8ef67c4fdd150
Acknowledgement was received that this change introduces only existing code that has been pushed to another public open source repository.

This change contains the following new commits:

Git commit 75dfc37d43e8e0582a508d0ce4a4e0b8026cad0b by Nasser Grainawi (on behalf of Prakash Aswal) on 03/08/2026 at 19:13..
Return a ChangeDataSource none() from AndPredicate short-circuit

Commit 177a526c6d added a short-circuit that returns
ChangeIndexPredicate.none() as soon as any child of an AndPredicate
rewrites to none() (false AND anything = false). The returned value was
a bare ChangeStatusPredicate, which is an IndexPredicate but not a
ChangeDataSource.

When such an AND is nested inside an OrPredicate (e.g.
OR(AND(...,status:new), AND(none(),status:new))), the enclosing
OrPredicate.copy() requires every child to be a ChangeDataSource to fold
into an OrSource. The bare none() is not one, so the OR collapsed to a
plain OrPredicate, the top-level rewrite() saw a non-ChangeDataSource
result and wrapped the whole query as and(or(open,closed), in) -- a
full-status index scan across all changes instead of a trivially empty
result.

Return the none() wrapped in an IndexedChangeQuery instead. It is a
ChangeDataSource with cardinality 0, reads the index once as
status:__invalid__ (empty immediately), and satisfies the
ChangeDataSource requirement so the parent OR folds into an OrSource and
the full-scan fallback never triggers. The intended short-circuit
optimization is preserved.

Release-Notes: Fixed a full index scan when a none() predicate was nested inside an AND within an OR, which could make such change queries extremely slow
Change-Id: Id3f667ec7e76940e649731252ae3546181ad0004
https://invent.kde.org/qt/qtqa/gerrit/-/commit/75dfc37d43e8e0582a508d0ce4a4e0b8026cad0b

Git commit f698053df831ac439130416148c8ef67c4fdd150 by Nasser Grainawi (on behalf of Prakash Aswal) on 03/08/2026 at 22:24..
Return a ChangeDataSource none() from empty-OrPredicate short-circuit

The empty-OrPredicate short-circuit (added in 5601530245) returns a bare
ChangeIndexPredicate.none(), which has the same latent defect just fixed
for the AndPredicate short-circuit: none() is a ChangeStatusPredicate,
an IndexPredicate but not a ChangeDataSource. When such a none() ends up
nested inside a rewritable parent (e.g. an empty OR inside an AND inside
an OR), the parent OrPredicate cannot fold into an OrSource, so the
top-level rewrite() wraps the query as and(or(open,closed), in) -- a
full-status index scan across all changes.

Wrap the empty-OR result in an IndexedChangeQuery too, so it satisfies
the ChangeDataSource requirement of the enclosing fold, mirroring the
AndPredicate short-circuit fix.

Because the AndPredicate short-circuit detects a none() child by
equality, extract an isNone() helper that recognizes none() both bare
and wrapped in an IndexedChangeQuery, so an empty OR nested in an AND
still collapses the AND to none() as before.

Assert the rewritten children in the emptyOrInAndInsideOr unit test, not
just the root type. Asserting only OrSource passes even with isNone()
reduced to bare equality, because the collapsed AND reaches an OrSource
by another route; pinning the children to the expected two index queries
makes the test fail without the helper.

Extend the AbstractQueryChangesTest none() case with the nested
or(and(none(), x), x) shape, in both the bare-none() and empty-OR forms,
so result semantics are covered against the Lucene and fake backends
rather than only the rewritten tree shape.

Those acceptance assertions cannot detect the defect itself, though: a
fallback scan returns correct results, just slowly. Add a fake-index
test that counts index reads instead, following queryRightNumberOfTimes.
With index.maxPageSize capped below the number of indexed changes, a
wrapped none() reads an empty status:__invalid__ page per short-circuit,
so counting empty reads distinguishes the rewritten tree from one where
either short-circuit leaked a bare none().

Release-Notes: Fixed a full index scan when an empty OR predicate was nested inside an AND within an OR, which could make such change queries extremely slow
Change-Id: I6eee218b259b863a4b16ae0cc369fb8fe6660467
https://invent.kde.org/qt/qtqa/gerrit/-/commit/f698053df831ac439130416148c8ef67c4fdd150