Repository navigation
Conversation
…MFDB#6733, LMFDB#6422) With the new indexes, remaining production timeouts come from an indexed column combined with a sparse boolean filter, e.g. conductor=17 & is_primitive=yes walks all 230K conductor-17 rows to find the 4 primitive ones (>180s on devmirror). Since a character is primitive if and only if its conductor equals its modulus, mirror conductor/modulus constraints when is_primitive=yes so the query is answered from the (conductor, modulus, orbit) index (45ms). Searches for characters induced by psi now inherit psi's order, parity and realness, and searches that are provably empty (odd order with odd parity, is_real with order > 2, conductor not dividing modulus, etc.) short-circuit with an explanatory message instead of scanning the table. Verified with EXPLAIN ANALYZE on devmirror and new tests in lmfdb/characters/test_characters.py (3 passed); pyflakes clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review follow-up on the previous commit, which normalized realness and parity only when a top-level order constraint already settled the question. is_real is now completely replaced by an order constraint rather than merely dropped when it was redundant: is_real=yes imposes order <= 2, is_real=no imposes order >= 3, the interval is intersected with any order the user asked for, and the boolean is removed. This covers the searches that previously kept the sparse boolean, in particular conductor=17&is_real=yes, whose count went from an index scan of every conductor-17 row filtering is_real (cost 899,246) to an index only scan with Index Cond conductor = 17 AND "order" <= 2 (cost 14,620). The odd-order/parity and inducing-order facts are now also applied inside the $or branches where parse_ints stores comma separated inputs, so order=3,5&parity=odd, is_real=yes&order=3,5 and inducing=3.b&order=3,5 short-circuit like their scalar counterparts, and order=2,3&parity=odd drops just the impossible branch. A comma separated conductor is likewise pruned against the conductor of an inducing character, which the existing check could not see. The constraint arithmetic is factored out as intersect_ints, which also replaces the bound juggling in refine_primitive_search, together with prune_or_branches (narrow branches by the top level constraint, drop the impossible ones) and collapse_single_branch (fold a lone survivor back into the top level). Verified on devmirror with EXPLAIN plans for the searches above and with new tests: a DirichletSearchQueryTest class asserting the normalized query dictionary, a check that six rewritten queries return exactly the labels the booleans they replace would select, and coverage of the result_count, list and random search modes. pyflakes and ruff clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Autonomous review by an OpenAI dotReviewed by dot, powered by OpenAI; exact model variant was not recorded. Outcome: Review incomplete / further validation needed. The current-main merge conflicts need resolving while preserving both sets of tests: this PR's query-rewrite tests and main's field-column/download tests, plus their imports. Please validate the resolved version against current main before merging. I reviewed both changed files, interval/list rewrites, inducing-character invariants, search/count/random/download paths, and the linked issue and fork discussions. The mathematical implications check out, including retaining the primitive filter for non-singleton ranges. Existing character-test logs show all 34 tests passing, including the nine added tests; lint passed too. Those checks tested an older synthetic merge, before main's subsequent character-page changes and Sage 10.6 upgrade. They do not validate the pending conflict resolution. No new Sage runs, live-database queries, browser checks, or performance measurements were performed; production query-plan improvements remain author-reported. |
Closes #6733.
Closes #6422.
Diagnosis of the recurring Dirichlet character search timeouts (562M-row
char_dirichlet): the plain-column cases from the issue threads are already index-fixed by the indexes Andrew added, and no new index is needed. The surviving timeout class is an indexed constraint plus a sparse boolean, e.g. conductor=17 & primitive walks all 230,769 conductor-17 rows to find 4 primitive ones (cancelled after 180s on devmirror; 87s in edgarcosta's EXPLAIN on beta).The fix is mathematical, in the search parser:
$orbranches), turning that query into a 45ms two-column index scan.Verified with EXPLAIN ANALYZE on devmirror (>180s cancelled, now 44.8ms for the issue query), 15 URLs through the test client covering every new path, and three new tests; pyflakes clean.
Ported from roed-math#6, where the full write-up and comment history live.
🤖 Generated with Claude Code