You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Make dynamic statistics drill-downs describe what they count
Three ways a count on the dynamic statistics page could link to a search
returning different records than the count, all of them in the generic
statistics framework rather than the p-adic tables:
Cells of a two-dimensional grid with no records were synthesized by
KeyedDefaultDict from the formatted row and column headers, so their urls were
built from displayed values (TeX, html, "not computed") rather than stored ones.
The totaler intersects the urls of a row to find the row's constraint, so a
sparse row lost it: the "not nilpotent" total on the abstract groups statistics
page linked to /Groups/Abstract/? and returned all 1.5 million groups instead of
the 455903 counted. display_data now indexes counts by the stored values and
builds every url, empty cells included, from those, so a formatter is free to
produce TeX or html. Values that display identically share a row, adding their
counts, rather than one silently replacing the other.
Drill-down urls were serialized from the parsed query, whose columns are often
not parameters the search page accepts: dynamic statistics constrained by Artin
slopes produced slopes_tmp=2A, which the p-adic parser ignores, so clicking a
count opened a broader search. dynamic_setup now passes the search boxes the
user filled in as link_constraint, which reproduce the same query by
construction, and a test asserts they re-parse to it.
Bucket endpoints for top_slope were compared as text against the fixed-width
decimal encoding the column is stored in, so a bucket of 1-2 counted the wrong
fields, and topslope_query sliced 12 characters off every endpoint, turning the
bucket 1-2 into topslope=-. Buckets are now encoded through a bucket_encoders
hook before they reach the backend and decoded for display and links, and an
endpoint that is not a rational is rejected with the usual message.
Along the way: the sentinel for unsearchable values moves into the framework, so
a null bucket is linkless in every table rather than only in p-adic ones; totals
that share no constraint are no longer linked; total urls list their parameters
in a fixed order rather than set order; invalid input to the dynamic statistics
page flashes an error instead of raising a 500; the default p and c buckets are
left open above so no field is omitted as the database grows; a not-computed
jump set is distinguished from an empty one; and nilp_qformatter maps the stored
-1 to nilpotent=no, since nilpotency_class=-1 matches nothing.
Every statistics page in LMFDB renders identically to before apart from those
fixes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
0 commit comments