Measured while implementing #7598. Filing unassigned — recording, not claiming.
The fact
comparand-shape.ts's TEXT_PATTERN_OPERATORS lists four operators:
$contains, $notContains, $startsWith, $endsWith
$icontains is not among them. It is in filter-normalizer.ts's
MONGO_TO_CUBE_OP (added by #6520), and read-scope-sql.ts's $icontains arm
does call assertRenderableText. So the analytics where door is the one face
that applies no comparand-shape gate at all to $icontains.
Measured on origin/main @ 5823d593d:
| filter | analytics where door | read-scope-sql |
|---|
{name: {$contains: {foo: 1}}} | REFUSED (INVALID_FILTER / 400) | REFUSED (READ_SCOPE_COMPILE_FAILED / 500) |
{name: {$icontains: {foo: 1}}} | compiles — leaf {operator: 'icontains', values: [{foo: 1}]} | REFUSED |
The leaf then reaches NativeSQLStrategy.buildFilterClause, whose
likeShape.icontains is 'contains', so likePattern renders it through
String(value) and the statement runs LIKE '%[object Object]%' — the exact
pattern #5234 exists to prevent, at the one operator that arrived after it.
Why it matters
This is #5234's defect, verbatim, at an operator the fence was never extended
to: a parameterised, syntactically perfect LIKE pattern nobody wrote. It is
also a split inside one package — the sibling door refuses the same
comparand — which is the shape #5234 / #5332 / #5567 each spent a round
removing.
Adjacent, already closed at a different consumer: #7158 (objectql having had
no $icontains comparand-shape gate either). Same class, third face.
Scope note
Left untouched by #7598's PR deliberately: that card is about a { $field }
comparand and fixing this would be a second defect riding it. The cell is pinned
as a RECORDED GAP in
packages/services/service-analytics/src/__tests__/cross-field-reference-refusal.test.ts
so it shows in test output rather than being re-discovered; that pin is what
should flip when this is fixed.
The likely fix is one entry in TEXT_PATTERN_OPERATORS plus the pins, but it
wants its own measurement of what else reads that set before it is called a
one-liner.
Refs
Generated by Claude Code
Measured while implementing #7598. Filing unassigned — recording, not claiming.
The fact
comparand-shape.ts'sTEXT_PATTERN_OPERATORSlists four operators:$icontainsis not among them. It is infilter-normalizer.ts'sMONGO_TO_CUBE_OP(added by #6520), andread-scope-sql.ts's$icontainsarmdoes call
assertRenderableText. So the analyticswheredoor is the one facethat applies no comparand-shape gate at all to
$icontains.Measured on
origin/main@5823d593d:wheredoorread-scope-sql{name: {$contains: {foo: 1}}}INVALID_FILTER/ 400)READ_SCOPE_COMPILE_FAILED/ 500){name: {$icontains: {foo: 1}}}{operator: 'icontains', values: [{foo: 1}]}The leaf then reaches
NativeSQLStrategy.buildFilterClause, whoselikeShape.icontainsis'contains', solikePatternrenders it throughString(value)and the statement runsLIKE '%[object Object]%'— the exactpattern #5234 exists to prevent, at the one operator that arrived after it.
Why it matters
This is #5234's defect, verbatim, at an operator the fence was never extended
to: a parameterised, syntactically perfect
LIKEpattern nobody wrote. It isalso a split inside one package — the sibling door refuses the same
comparand — which is the shape #5234 / #5332 / #5567 each spent a round
removing.
Adjacent, already closed at a different consumer: #7158 (objectql
havinghadno
$icontainscomparand-shape gate either). Same class, third face.Scope note
Left untouched by #7598's PR deliberately: that card is about a
{ $field }comparand and fixing this would be a second defect riding it. The cell is pinned
as a RECORDED GAP in
packages/services/service-analytics/src/__tests__/cross-field-reference-refusal.test.tsso it shows in test output rather than being re-discovered; that pin is what
should flip when this is fixed.
The likely fix is one entry in
TEXT_PATTERN_OPERATORSplus the pins, but itwants its own measurement of what else reads that set before it is called a
one-liner.
Refs
$in/$nin的非$field对象成员,与 LIKE 族的对象比较值(String 成[object Object]) #5234 (the fence, and the measured value table it was built from)$icontains(driver-memory 两面 / driver-mongodb / objectqlhaving/ formula)—— SQL 族已实现,同一 filter 在内存 double 上抛错 #6520 ($icontainson the analytics compilers)havinghas no$icontainscomparand-shape gate — an empty comparand matches EVERY row (2 of 5FILTER_TEXT_CASESrejection rows unenrollable) #7158 (the same gap at objectqlhaving)service-analytics' read-scope / Cube filter compilers still refuse$field, so a CEL field-to-field RLS rule 400s on those faces #7598 (where this was measured)Generated by Claude Code