Skip to content

fix(mcp): carry semantic selection versions for new charts - #45828

Open
mikebridge wants to merge 4 commits into
apache:masterfrom
mikebridge:sc-130238-mcp-semantic-selection-version
Open

mikebridge wants to merge 4 commits into
apache:masterfrom
mikebridge:sc-130238-mcp-semantic-selection-version

Conversation

@mikebridge

Copy link
Copy Markdown
Contributor

SUMMARY

TL;DR: MCP chart tools can now save charts and build Explore links on versioned semantic views.

Background: Semantic views that version their member identifiers (for example, table-qualified Snowflake names such as O.TOTAL_REVENUE) expose a semantic_selection_version. Explore saves it with a chart's form data and sends it in each query's extras, and the query layer refuses selections whose version is missing or old, so a chart saved under an older naming scheme can't silently resolve to the wrong member.

Problem: generate_chart and generate_explore_link built semantic-view form data without the version, so every new MCP chart on a versioned view looked like an old chart and was refused ("Saved semantic selections use an older identity format…"). The MCP query builder also dropped a top-level version instead of forwarding it to query extras. Separately, an XY chart with a categorical semantic x-axis was first mapped as temporal, which ignored the requested sort and produced a false "x-axis is temporal" warning.

What this changes:

  • New selections from generate_chart and generate_explore_link are stamped with the view's current selection version.
  • The MCP query builder forwards that version to every query's extras, mirroring the frontend: selections that include unverified external filters or controls are still marked unverified, so they keep failing closed.
  • The XY mapping for semantic views is rebuilt with the view's real temporal columns before sort and warning decisions.
  • update_chart is unchanged: rename, add-columns and config updates on existing charts don't receive a new version, because they can retain selections from the saved chart. Safely re-stamping existing charts needs a separate full-reselection rule.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Not applicable: MCP request and payload changes only.

TESTING INSTRUCTIONS

  1. With a versioned semantic view, call generate_chart with view_id, current metric and dimension IDs and save_chart=true (for example a bar chart of a revenue metric by a segment dimension). It saves, and the saved params carry semantic_selection_version.
  2. Call generate_explore_link for the same view: the form data carries the version and the chart renders.
  3. Confirm a categorical x-axis keeps the requested sort with no temporal warning.

Automated: MCP chart and Explore tool tests, including generation, Explore links, query extras for every query, wrong/old/absent provenance, and existing-chart updates staying unstamped.

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration
  • Introduces new feature or API
  • Removes existing feature or API

No migration, provider-version or frontend change.

Stamp only newly generated chart and Explore selections, forward their identity through query extras without certifying external filters, and apply semantic temporal metadata before sorting. Keep existing-chart updates unstamped pending a complete-reselection contract.
@netlify

netlify Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit e28262a
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6aebc025df234beddadf47a1
😎 Deploy Preview https://deploy-preview-45828--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@codecov

codecov Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 8.47458% with 54 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.24%. Comparing base (c0b27ee) to head (8441c48).
⚠️ Report is 49 commits behind head on master.

Files with missing lines Patch % Lines
superset/mcp_service/chart/chart_helpers.py 5.88% 32 Missing ⚠️
superset/mcp_service/dashboard_scope.py 11.76% 15 Missing ⚠️
superset/mcp_service/chart/datasource_resolver.py 25.00% 3 Missing ⚠️
superset/mcp_service/chart/plugins/xy.py 0.00% 2 Missing ⚠️
superset/mcp_service/chart/tool/generate_chart.py 0.00% 1 Missing ⚠️
.../mcp_service/explore/tool/generate_explore_link.py 0.00% 1 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (c0b27ee) and HEAD (8441c48). Click for more details.

HEAD has 3 uploads less than BASE
Flag BASE (c0b27ee) HEAD (8441c48)
python 7 5
postgres 2 1
Additional details and impacted files
@@             Coverage Diff             @@
##           master   #45828       +/-   ##
===========================================
- Coverage   85.00%   65.24%   -19.76%     
===========================================
  Files        3080     3080               
  Lines      209252   210521     +1269     
  Branches    49292    49505      +213     
===========================================
- Hits       177881   137363    -40518     
- Misses      27990    69981    +41991     
+ Partials     3381     3177      -204     
Flag Coverage Δ
hive 34.08% <8.47%> (-0.12%) ⬇️
mysql 51.87% <8.47%> (-0.15%) ⬇️
postgres 51.90% <8.47%> (-0.14%) ⬇️
presto 35.73% <8.47%> (-0.13%) ⬇️
python 52.20% <8.47%> (-35.77%) ⬇️
sqlite 51.58% <8.47%> (-0.20%) ⬇️
unit ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mikebridge
mikebridge marked this pull request as ready for review October 30, 2026 17:22
@aminghadersohi
aminghadersohi self-requested a review October 30, 2026 20:10

@aminghadersohi aminghadersohi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The external-selection guard still has a fail-open merge path.

Keep each contributor's source status before dashboard and request filters lose their origin. Apply the same guard when appending filters to a saved query context so missing or stale provenance cannot borrow its version. Addresses review thread 4428377061.
@pull-request-size pull-request-size Bot added size/XL and removed size/L labels Nov 1, 2026
@codeant-ai-for-open-source

codeant-ai-for-open-source Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

CodeAnt  CodeAnt PR Risk

🟡  Medium Risk

  • The PR needs attention before merging.
  • A matching caller-supplied source record could let stale semantic filters carry the current version and resolve old IDs under the wrong identity scheme.

Assessed commit: 8441c4814fa3

@gabotorresruiz gabotorresruiz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mikebridge thanks for this! LGTM. New selections are only stamped after every metric, dimension, filter and sort reference has passed the view checks, so a stale ID is refused before anything is saved or queried, and the merge paths keep unproven inputs unverified. I left one non-blocking note on the cross viz update_chart path.

I ran the MCP, semantic layer and common unit suites on this branch plus a few stale ID probes through generate_chart and generate_explore_link. CI is green.

Comment on lines +103 to +105
# The existing config merge may drop the old marker; neither retaining
# nor dropping it certifies these selections as current.
assert form_data.get("semantic_selection_version") in (None, saved_version)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a blocker, more of a follow-up. The drop happens on cross viz updates: _merge_allowlisted_form_data only carries keys from FORM_DATA_UPDATE_PRESERVE_KEYS, and semantic_selection_version isn't one of them. So on this branch, a chart that generate_chart just stamped followed by update_chart changing kind from bar to line builds its compile query with no version and comes back with "Saved semantic selections use an older identity format", while bar to bar keeps the version and saves fine.

Keeping whatever marker the saved chart already has never upgrades an older one, so could it ride along with the envelope keys?

"envelope": frozenset(
    {
        ...
        "semantic_selection_version",
        ...
    }
),

A case here with a current saved_version and a viz change would pin it. Or am I missing a reason cross viz updates should drop it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, fixed here rather than in a follow-up: 8441c48 carries semantic_selection_version along with the envelope keys on cross-viz updates, keeping whatever marker the saved chart already has (an older one is never upgraded). A generate then bar-to-line update now keeps the version and saves.

Carry the saved selection version and its source evidence through the cross-visualization envelope merge. Dropping the version refuses newly generated charts, while retaining it without source evidence can lose external-selection validation.

Cover generated bar-to-line saves, preview/save marker preservation, and missing or older versions without upgrading them.
@github-actions github-actions Bot added the requires:rebase Requires rebasing on top of current master label Nov 10, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

requires:rebase Requires rebasing on top of current master size/XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants