Query.matches/search: flags omitted from cache hash causes wrong results
Author: uadhranCreated Sep 15, 2026Updated Sep 16, 2026
Description
Query.matches and Query.search accept a flags argument and close over it in the test function, but the query cache hash does not include flags:
return self._generate_test(test, ('matches', self._path, regex))
# and
return self._generate_test(test, ('search', self._path, regex))(tinydb/queries.py)
QueryInstance equality / hashing is based on _hash, and Table.search caches results by query. Two queries that differ only by flags are treated as the same cache key, so a later search can return the other flags’ results.
Verified on current master (4aa5311, TinyDB 4.9.0).
Minimal reproduction
import re
from tinydb import TinyDB, Query
from tinydb.storages import MemoryStorage
db = TinyDB(storage=MemoryStorage)
db.insert({'name': 'John'})
db.insert({'name': 'johnny'})
# Baseline (fresh DB): case-sensitive matches('john') matches 'johnny' only
# (re.match prefix), not 'John'
db_base = TinyDB(storage=MemoryStorage)
db_base.insert({'name': 'John'})
db_base.insert({'name': 'johnny'})
print([d['name'] for d in db_base.search(Query().name.matches('john'))])
# ['johnny']
# Cache collision:
print([d['name'] for d in db.search(Query().name.matches('john', flags=re.IGNORECASE))])
# ['John', 'johnny']
print([d['name'] for d in db.search(Query().name.matches('john'))])
# ['John', 'johnny'] — wrongly includes 'John'
# Same hash:
print(Query().name.matches('john', flags=re.IGNORECASE)._hash)
print(Query().name.matches('john')._hash)
# both: ('matches', ('name',), 'john')The same hash omission exists for Query.search(..., flags=...).
Expected behavior
Queries that differ by flags should not share a cache entry (include flags in the hash tuple), so case-sensitive vs case-insensitive (etc.) results stay correct.
Suggested tests
- Populate docs like above;
search(matches(..., re.I))thensearch(matches(...))must not return the ignorecase hit set for the case-sensitive query - Assert
_hashdiffers when onlyflagsdiffers (for bothmatchesandsearch)
Happy to open a PR once this looks correct.
Environment
- TinyDB 4.9.0 /
master@4aa5311
Source: msiemens/tinydb