Repository navigation
feat: Add click-to-adhoc-filter to table charts - #3389
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: eb7e999 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
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 |
[Medium impact] The PR appears safe to merge within its stated SQL-parsing limitations. SummaryAdds include and exclude actions to grouped table cells for builder, raw SQL, and PromQL tables.
|
Duplicate code analysisNo new duplicate code introduced by this PR. jscpd compared this branch against |
E2E Test Results✅ All tests passed • 443 passed • 1 skipped • 1656s
Tests ran across 4 shards in parallel. |
8a3de77 to
4457c2e
Compare
4457c2e to
ed0cf25
Compare
ed0cf25 to
1f0ac52
Compare
1f0ac52 to
2aa0cdf
Compare
2aa0cdf to
b3785e7
Compare
b3785e7 to
fafa277
Compare
fafa277 to
6a8b409
Compare
🔴 Tier 4 — CriticalTouches authentication, tenancy data models, the public API or shipped database config — or substantially changes the query rendering engine, background tasks, the OTel pipeline, image build, or release CI. Why this tier:
Review process: Deep review from a domain expert. Synchronous walkthrough may be required. Stats
|
PR Review
3 finding(s): 🔴 0 critical · 🟠 0 major · 🔵 3 minor None could be anchored to changed lines; they are listed below. Findings outside the changed lines3 minor
Severity is the reviewer's own estimate and is used for ordering, not filtering. No finding blocks merge automatically; a maintainer decides. |
Deep Review✅ No critical issues found. No P0/P1 defects: no data loss, auth bypass, injection, or guaranteed crash is introduced. Cell filter values flow through 🟡 P2 — recommended
🔵 P3 nitpicks (6)
Reviewers (11): correctness, adversarial, kieran-typescript, julik-frontend-races, testing, maintainability, previous-comments, performance, project-standards, agent-native, learnings-researcher. The correctness and adversarial passes did not return structured findings before synthesis; those lenses were covered directly — value-escaping/injection, parser position/alias/name/expression matching, the Testing gaps:
No finding blocks merge automatically. A maintainer will expect P0/P1 findings in code this PR changes to be fixed; P2/P3 are your call -- fix or reply. Never fix findings about surrounding code here; reply instead. Do not widen the PR. How to respond |
| * SETTINGS clause, backtick-quoted identifiers, JSON paths) for parseable | ||
| * tokens. `restore` puts the originals back into text sliced from `sql`. | ||
| */ | ||
| function prepareChSqlForParser(chSql: ChSql) { |
There was a problem hiding this comment.
Extracted from chSqlToAliasMap
6a8b409 to
12d2407
Compare
12d2407 to
eb7e999
Compare
Summary
This PR adds click-to-adhoc-filter functionality to tables, across builder, raw SQL, and PromQL tables.
Most of the complexity comes from determining (a) which columns should be filterable and (b) what expression to filter on when a column / cell is clicked. In general, (a) group-by columns should be filterable while aggregate columns should not be (since other visualizations are unlikely to have the same aggregations) and (b) we try to filter on the underlying expression instead of the alias, since other visualizations may not have the same alias.
This determination is made as follows:
renderSelect). They're matched by position, not by name, because ClickHouse canonicalizes unaliased expressions.chSqlToSelectColumnsin common-utils). Each outer SELECT item lines up with a result column by position. An item is filterable if the GROUP BY lists it by alias, by name, by normalized expression, or by position (GROUP BY 2). If the query can't be read that way (no GROUP BY,GROUP BY ALL,SELECT *, a parse failure, or a column count that doesn't match the result), we fall back to type-based determination (any String type column is filterable).For all table types, DateTime columns aren't filterable, because cells hold ISO UTC timestamps that never equal
toString()of the column. Map and Array cells aren't filterable either, because they render as JSON that wouldn't match the value in a filter condition.Known Limitations
Parser incompatibility
This feature requires parsing arbitrary raw SQL queries to identify group-by columns. We currently do this with node-sql-parser, which doesn't support the full ClickHouse dialect. This means that the parser will fail on some SQL inputs (parametric functions, array join, join qualifiers, etc) and fallback to type-based group-by inference (eg. "All String type result columns are assumed to be group by columns).
This just means that the set of columns that can be clicked-to-filter is approximate and best effort, likely to be wrong sometimes, in particular for more complex SQL expressions. The impact is low - the user just can't click to filter a particular column, or clicking a column adds an undesirable filter key, which can then just as easily be removed from the filter.
This is an area that could be significantly improved with a full ClickHouse SQL parser, something we want to add in the future.
CTEs
When a query selects columns created in its CTE, it is likely that the same column doesn't exist in other charts without the same CTE, so adding an adhoc filter on the column will likely cause other tiles to fail.
This could be overcome only by either fully analyzing the query, following CTE reference chains. This is deemed too complicated to be worth it at the moment, particularly without a reliable ClickHouse SQL parser.
Again, the impact is low because the user can remove the filter they added easily.
Screenshots or video
Screen.Recording.2026-10-19.at.9.57.08.AM.mov
How to test on Vercel preview
Create a dashboard, add some tables and an adhoc filter, try click-to-filter. Note the limitations mentioned above.
References