feat(semantic layers): derive Explore picker modes from declared semantic view features - #42540
Draft
mikebridge wants to merge 4 commits into
Draft
feat(semantic layers): derive Explore picker modes from declared semantic view features#42540mikebridge wants to merge 4 commits into
mikebridge wants to merge 4 commits into
Conversation
… capability contracts Serialize SemanticView.features as semantic_view_features in the explorable datasource payload (new opt-in SemanticViewFeature.ADHOC_COLUMN_EXPRESSIONS), translate it once through a provider-neutral ColumnPickerCapabilities adapter, and replace the overlapping compatibleMetrics/compatibleDimensions/ compatibilityLoading Redux fields with a discriminated CompatibilityResult (idle | loading | verified | failed) consumed through typed selectors. No provider identity crosses the wire; picker components consume capabilities only. Verified empty compatibility results are distinguishable from loading and failure; idle/loading/failed keep the existing no-filter fallback. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… modes for semantic views Semantic views that do not declare ADHOC_COLUMN_EXPRESSIONS open the column picker on Saved with every expression-less dimension listed as a Saved option (verbose-name searchable, metadata unmutated), disable the Simple and Custom SQL modes, and honor verified compatibility (absent dimensions disabled, a verified empty list distinct from loading/failure). A failed compatibility request shows an accessible non-blocking warning and falls back to unfiltered options. Incompatible or legacy adhoc edited values cannot be saved: Saved activates, the value stays inspectable, and accessible corrective feedback is associated with the disabled Save button until a compatible dimension is explicitly chosen. Default tab routing is disabled-aware, the Simple tab honors disabledTabs, and both DnD wrappers drop their duplicated semantic-view mode rules in favor of the shared picker-capability adapter. Filter subject and Sort by entry points are covered explicitly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…overage Keep Saved-mode metric selection reachable for saved-only semantic views now that Simple is disabled, and lock in unchanged behavior for tables and for semantic views that declare ADHOC_COLUMN_EXPRESSIONS (expression-based Simple/Saved classification, defaults, search, Save, no failure warning). Strengthen the apache#41456 backend assertions so temporal semantic dimensions keep expression=None alongside the new feature serialization. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…apability boundary Explain the opt-in SemanticViewFeature declaration, why the provider registry key is deliberately not published (the @semantic_layer decorator prefixes extension IDs), and the rule that generic picker components consume ColumnPickerCapabilities rather than provider metadata. Also address accessibility lint: the inline invalid-selection feedback uses an output element for its implicit status role, and the compatibility warning relies on Alert's native alert role. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
✅ Deploy Preview for superset-docs-preview ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #42540 +/- ##
==========================================
+ Coverage 65.27% 65.43% +0.16%
==========================================
Files 2795 2802 +7
Lines 157835 158614 +779
Branches 36080 36140 +60
==========================================
+ Hits 103027 103795 +768
- Misses 52816 52824 +8
- Partials 1992 1995 +3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SUMMARY
Semantic-view providers can now declare what their backend supports, and the Explore column picker adapts its modes and dimension classification to that declaration instead of guessing from column metadata.
A note on the originating report. The internal story behind this describes the "Columns and metrics" picker showing
0 item(s)for a Cube-backed semantic view, and that literal symptom no longer reproduces on master. Reproduced against a live Cube instance through the real model path: dimensions arrive withexpression=None, so the picker's expression-based split routes all four into Simple, not zero.The empty picker came from the pre-#41456 payload, which set
expression=dimension.definition. BecauseColumnSelectPopovertreats any column with a truthyexpressionas a Saved/calculated column, every dimension landed under Saved and Simple rendered0 item(s). #41456 (e28b259de0) flipped that field toNoneso temporal dimensions keep their time-grain affordance — and the dimensions moved into Simple.That fixed the emptiness but landed them in the wrong mode. The behavior agreed with design at the time was: dimensions and metrics presented under Saved, with Simple and Custom SQL disabled, because a semantic view whose backend cannot execute adhoc column expressions should not offer modes that compose them. The "disable Simple" half was never implemented, and #41456 additionally moved dimensions out of Saved. This PR implements that intent — generalized so it is driven by what a provider declares rather than by which provider it is:
1. Providers declare features; Explore consumes capabilities. A new opt-in
SemanticViewFeature.ADHOC_COLUMN_EXPRESSIONSmarks views whose backend accepts simple/custom-SQL column expressions. The declared set serializes to the datasource payload assemantic_view_features. A view that does not declare it gets a Saved-only picker: dimensions listed as Saved options, Simple and Custom SQL visible but disabled, so users cannot compose an expression the backend would reject.Polarity is opt-in to match the existing provider convention — Snowflake declares its features, Cube and MetricFlow deliberately ship
frozenset(). A companion one-line declaration onSnowflakeSemanticViewkeeps Snowflake's picker behavior unchanged and ships separately in the shell repo.Provider identity is deliberately not sent over the wire. The
@semantic_layerdecorator prefixes extension IDs (extensions.preset-io.cube-semantic-layer.cube), so there is no stable bare registry key to publish, and behavior keyed off provider identity would not survive that prefixing. Features are translated exactly once, inutils/pickerCapabilities.ts, into a provider-neutralColumnPickerCapabilities. Picker components consume capabilities and never read feature strings, registry keys, or display names. Two DnD wrappers that each carried their own copy of the "semantic views disable Custom SQL" rule now defer to that adapter.2. Compatibility request state was conflated (a real defect).
fetchCompatibilitydispatched an identical{compatibleMetrics: null, compatibleDimensions: null, compatibilityLoading: false}both when the datasource is non-semantic and when the request failed. A failed compatibility lookup was therefore indistinguishable from "no filtering applies", so no UI could ever surface it. That state is now a discriminatedCompatibilityResult(idle | loading | verified | failed) read through typed selectors, and every existing consumer — column picker, datasource-panel drag options, adhoc metric popover — was migrated in the same change so the replacement cannot strand an old reader. Idle, loading, and failed keep the existing no-filter fallback; averifiedempty result is a valid "nothing is compatible" answer, not a fallback;failedadditionally shows an accessible non-blocking warning where the capability enables it.Incompatible or legacy adhoc values can no longer be silently committed: Saved becomes the active mode, the legacy value stays inspectable under Custom SQL, and Save is disabled with accessible corrective feedback associated to it until the user explicitly picks a compatible dimension.
expression=Noneon semantic dimensions is preserved throughout — #41456's time-grain behavior is a protected invariant here, not a cleanup opportunity, and there is a regression assertion to that effect.BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
Not included: rendering a Cube-backed semantic view requires the proprietary provider extension, which is not installable in an OSS checkout. Behavior is covered by component tests that drive the real picker, and by a local reproduction against a Cube instance described below.
TESTING INSTRUCTIONS
Automated (no provider extension needed):
Manual, with a semantic-layer provider available:
ADHOC_COLUMN_EXPRESSIONS(and on a plain table dataset): modes, defaults, search, and Save are unchanged.The
0 item(s)claim above was verified against the Cube fixture indb-infra/databases/cube(REST API on:4000) using a throwaway provider stub overSemanticView.data; the stub is not part of this PR.ADDITIONAL INFORMATION
Backwards compatible:
semantic_view_featuresis additive and optional. Payloads without it, unknown feature strings, and non-semantic datasources all resolve to existing behavior, so noUPDATING.mdentry is needed.🤖 Generated with Claude Code