Skip to content

Fix raw_values mutation that broke repeated raw= searches#56

Open
roed-math wants to merge 1 commit into
roed314:masterfrom
roed-math:fix-raw-values-mutation
Open

Fix raw_values mutation that broke repeated raw= searches#56
roed-math wants to merge 1 commit into
roed314:masterfrom
roed-math:fix-raw-values-mutation

Conversation

@roed-math

Copy link
Copy Markdown

The bug

search() and lucky() declare a mutable default raw_values=[], and _build_query aliases that list before appending the limit/offset:

qstr, values = SQL(raw), raw_values   # values IS the caller's (default) list
...
if limit is not None:
    values.append(limit)              # mutates it
    if offset != 0:
        values.append(offset)

So the first raw= search in a process works, but every subsequent one inherits the accumulated limit/offset from the shared default list. The generated SQL then has fewer %s placeholders than values, and the query dies with:

TypeError: not all arguments converted during string formatting

A caller that passes its own raw_values list is also affected — the list is mutated as a side effect of the search.

Reproduce

from lmfdb import db
nf = db.nf_fields
list(nf.search({}, projection=["label"], limit=3, raw="degree = 2"))  # ok
list(nf.search({}, projection=["label"], limit=3, raw="degree = 2"))  # TypeError

The fix

  • Copy raw_values in _build_query (values = list(raw_values)) so the caller's list is never mutated.
  • Change the mutable defaults in search() and lucky() from [] to None (_build_query already coalesces None to []).

After the fix, repeated raw= searches succeed and a caller-supplied raw_values list is left untouched. Added a doctest in _build_query demonstrating both.

(Found while adding a command-line raw-SQL search to the LMFDB.)

🤖 Generated with Claude Code

search() and lucky() had a mutable default raw_values=[], and _build_query
aliased that list (values = raw_values) before appending the limit and
offset.  As a result the first raw= search in a process worked, but every
subsequent one inherited the accumulated limit/offset values and failed with
"TypeError: not all arguments converted during string formatting" (the query
had fewer %s placeholders than values).  A caller-supplied raw_values list
was likewise mutated as a side effect.

Copy raw_values in _build_query so the caller's list is never mutated, and
change the mutable defaults in search()/lucky() to None.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants