#637·tinydb

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:

python
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

python
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)) then search(matches(...)) must not return the ignorecase hit set for the case-sensitive query
  • Assert _hash differs when only flags differs (for both matches and search)

Happy to open a PR once this looks correct.

Environment

  • TinyDB 4.9.0 / master @ 4aa5311