pf_app/lib
Paul Trowbridge 766ccc52bb Scope an operation by a substring filter, case-insensitively
A view narrowed with `partd contains 'Keysto'` could be totalled but not
written: `SCOPE_OPS` carried the comparison and list operators and refused
everything else, so the panel showed a figure the operation answered 400 on.
Refusing is the right default -- a scope silently dropped is a write wider than
the panel that authorised it -- but `contains` is how a text dimension is
actually filtered, the alternative being an IN list of the 180 descriptions
that happen to match today.

ILIKE, not LIKE, because that is what the engine does: `t_tscalar::contains`
lowercases both sides before `std::string::find`, as do `begins_with` and
`ends_with`. On `fc_osm_skinny_34` the difference is 16,864 rows against 35, so
LIKE would have written a fortieth of what the grid displayed. Narrower is no
safer than wider here -- either way it is not the set the ledger counted.

The term is literal in the engine, so `%`, `_` and `\` are escaped out of it
before it becomes a pattern; `50%` means those three characters.

`matches` stays refused. It is RE2 in the engine and Postgres regexes are not
RE2 -- `\b` is a word boundary in one and a backspace in the other -- so a
pattern both accept could match a different set of rows, which is worse than a
400.

Every operator that takes a term now refuses an empty one. An unfinished filter
row in the pivot arrives as `[col, '==', null]`, which used to compile to
`= ''`; as a substring op it would have been `ILIKE '%%'`, which is every
non-null row and therefore no scope at all.

Runtime code, not template: nothing to regenerate, only a restart.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 11:53:18 -04:00
..
auth.js Scope what an account can see and change to its territory 2026-09-18 11:14:03 -04:00
sql_generator.js Scope an operation by a substring filter, case-insensitively 2026-09-22 11:53:18 -04:00
utils.js Read source columns from pg_catalog, not information_schema 2026-09-18 16:12:05 -04:00