fix: unknown lucene field falls through in search#2422
Conversation
🦋 Changeset detectedLatest commit: a6ed715 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🔵 Tier 2 — Low RiskSmall, isolated change with no API route or data model modifications. Why this tier:
Review process: AI review + quick human skim (target: 5–15 min). Reviewer validates AI assessment and checks for domain-specific concerns. Stats
|
09e5e96 to
a6ed715
Compare
E2E Test Results✅ All tests passed • 197 passed • 3 skipped • 1261s
Tests ran across 4 shards in parallel. |
a6ed715 to
bd9a8b6
Compare
Deep ReviewGating the unknown-field fall-through is the right call, and the implementation is sound: every ✅ No critical issues found. 🟡 P2 -- recommended
🔵 P3 nitpicks (4)
Reviewers (6): correctness, testing, maintainability, kieran-typescript, security, performance. Testing gaps:
|
Summary
Why
When a Lucene search field couldn't be resolved to a real column, the
CustomSchemaSQLSerializerV2fall-through emitted it verbatim as a raw SQL identifier (queryParser.ts, the old// It might be an alias, let's just try the columnbranch). That had two problems:WHERE myTypo = '...', which ClickHouse rejects with a confusingUnknown identifiererror instead of simply returning no rows.WHERE), but it couldn't tell an alias apart from a typo — both were emitted blindly.This change makes that distinction explicit: a field that matches a known SELECT alias is emitted as a bare identifier; anything genuinely unknown resolves to the no-match predicate
(1 = 0).What changed
queryParser.ts):CustomSchemaConfig/CustomSchemaSQLSerializerV2gain an optionalselectAliases: Set<string>. The resolver now returns the bare identifier only whenselectAliases.has(field); otherwise it returnsfound: false, which renders as(1 = 0).renderChartConfig.ts): newextractSelectAliases(...)helper gathers aliases from bothselectandgroupBy, for both list shapes — array form ({ valueExpression, alias }[]) readsaliasdirectly, and string form (raw SQL, e.g. a source'sdefaultTableSelectExpressionsuch as'Timestamp, ServiceName as service, Body') is parsed via the existingchSqlToAliasMap()helper to recover declared aliases. This matters because the default search/events view uses string-form selects, so without it the default view would lose alias resolution. The set is threaded throughrenderWhereExpressionStrinto the serializer.queryParser.ts): the exact-match branch now treats anull/undefinedmaterialized-columns lookup the same as the existing catch path (?? new Map()), so a missing lookup proceeds with no materialized columns instead of throwing on.entries().Behavior change
ServiceName:foo)Content:foowhereBody AS Content)myTypo:foo)(1 = 0)→ no rowsExample that now works end-to-end:
SELECT Body AS Content … WHERE Content = '…'How to test on Vercel preview
Preview routes:
/searchSteps:
References