Repository navigation
Rust #325: narrow visibility queries in the database - #897
Conversation
A structured list query read every queried attribute row in the namespace and scanned its runs 500 at a time until it had the page, so a selective query in a large namespace read the whole namespace. The list statement now adds a narrowing every matching run satisfies: status, run text columns, attribute presence, keyword equality and integer comparisons, with text under the column's own collation. The matcher still decides each candidate, with only that page's attribute rows, so the answers are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Security read-only review of exact head 36276aa: no additional tenant-boundary or SQL-injection finding. Every request-derived namespace, filter, search-attribute key, literal, page limit and offset is bound; the only dynamically selected columns and integer operators come from closed internal variants; candidate reads retain both run and workflow-instance namespace predicates; search attributes are reached through workflow_runs.id, which is a primary key in every backend schema; and the existing compiled matcher remains the final inclusion decision. This is a source-design review only, not a substitute for the owner’s differential fixtures or current CI, and it adds no separate Security hold. |
|



Part of #325.
Problem
A structured list
queryused to read too much. It read every queried attribute row in the namespace. It then scanned the namespace's runs in list order, 500 at a time, deciding each in native code until it had the page. A selective query in a large namespace therefore read the whole namespace. Published PHP 2.11.7 applies the query in SQL.Change
Compiled::narrowing. It gives, perORgroup, conditions every run matching that group satisfies:IN;IN;IN.The list statement adds them as one condition, with every value bound.
Text comparisons. These run under the column's own collation. On MySQL that is the schema's
utf8mb4_unicode_ci, the collation Rust #325: compare visibility query text as each backend does #890's comparison keys follow, so a pair the matcher treats as equal is equal in the database too.Presence only. Comparisons whose database form could differ narrow only to the attribute being present: times, floats, booleans, keyword lists, long text and text inequality. A run-time comparison doesn't narrow at all. A group with nothing to narrow leaves the query unnarrowed, as before.
Answers unchanged. The matcher still decides every candidate, so the database can only leave out runs the query does not select.
Attribute rows. These are now read per candidate page, for that page's runs only.
Checks
a_selective_query_reads_its_candidates_not_the_whole_namespaceuses 650 runs, more than one scan page. Keyword, keyword-and-integer and integerINqueries each read exactly their matches. A time-only query still reads one scan page.narrowing_holds_for_every_match_and_stays_open_when_a_group_cannot_narrowpins which checks narrow.search-attributes,start-search-attributesandvisibility-collationagainst published 2.11.7 and against native built from this branch.compareaccepts each pair. CI covers PostgreSQL, MySQL andvisibility-current-runs.PhpImageContextTest.Checkpoint.
🤖 Generated with Claude Code