Skip to content

fix(mcp): apply extra_form_data filters when rendering chart SQL - #43338

Closed
aminghadersohi wants to merge 9 commits into
apache:masterfrom
aminghadersohi:aminghadersohi/fix-get-chart-sql-extra-form-data
Closed

fix(mcp): apply extra_form_data filters when rendering chart SQL#43338
aminghadersohi wants to merge 9 commits into
apache:masterfrom
aminghadersohi:aminghadersohi/fix-get-chart-sql-extra-form-data

Conversation

@aminghadersohi

@aminghadersohi aminghadersohi commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

SUMMARY

get_chart_sql's request schema had no extra_form_data field. Pydantic silently
drops unrecognized fields by default, so any filters passed alongside a chart
identifier were dropped before validation ever ran — the tool always rendered the
chart's unfiltered baseline SQL regardless of what was passed in.

get_chart_data already merges extra_form_data correctly via
merge_extra_form_data_filters_into_query / build_query_context_from_form_data
(added in a prior fix). This PR adds the same extra_form_data field to
GetChartSqlRequest and wires it into both of get_chart_sql's SQL-construction
paths (saved query_context, and the form_data fallback), reusing the existing
merge helpers instead of adding new filter-merging logic.

get_chart_data already applied filters correctly. The shared helper update in this
PR additionally preserves normalized relative-time extras (relative_start and
relative_end) for both chart-data and chart-SQL query construction.

TESTING INSTRUCTIONS

  • New unit tests in tests/unit_tests/mcp_service/chart/tool/test_get_chart_sql.py:
    • GetChartSqlRequest accepts and stores extra_form_data (previously silently
      dropped).
    • _build_query_context_from_form_data forwards extra_form_data to the query
      factory.
    • _sql_from_saved_query_context merges extra_form_data into the query handed
      to ChartDataQueryContextSchema.load before rendering SQL.
    • End-to-end: request.extra_form_data reaches the saved-query_context SQL
      builder and shows up in the rendered SQL.
  • New unit tests in tests/unit_tests/mcp_service/chart/tool/test_get_chart_data.py
    cover the (already-correct, previously untested) get_chart_data path where a
    chart identifier + extra_form_data are both provided — both the filters and
    adhoc_filters extra_form_data formats, plus a TEMPORAL_RANGE filter.
  • pytest tests/unit_tests/mcp_service/ — full suite passes.
  • pre-commit run on all changed files — clean.

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

get_chart_sql had no extra_form_data field on its request schema, so
any filters passed alongside a chart identifier were silently dropped
before validation and the tool always rendered the chart's unfiltered
baseline SQL. get_chart_data already merges extra_form_data correctly;
this wires the same merge helpers into get_chart_sql's saved
query_context and form_data fallback paths.
@codecov

codecov Bot commented Aug 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 10.34483% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.06%. Comparing base (a05a099) to head (a642de1).
⚠️ Report is 40 commits behind head on master.

Files with missing lines Patch % Lines
superset/mcp_service/chart/tool/get_chart_sql.py 8.33% 22 Missing ⚠️
superset/mcp_service/chart/chart_helpers.py 0.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #43338      +/-   ##
==========================================
- Coverage   66.81%   66.06%   -0.76%     
==========================================
  Files        2876     2877       +1     
  Lines      164237   170549    +6312     
  Branches    37917    39265    +1348     
==========================================
+ Hits       109743   112667    +2924     
- Misses      52310    55479    +3169     
- Partials     2184     2403     +219     
Flag Coverage Δ
hive 37.87% <10.34%> (-0.22%) ⬇️
mysql 58.06% <10.34%> (+0.26%) ⬆️
postgres 58.10% <10.34%> (+0.28%) ⬆️
presto 39.82% <10.34%> (-0.22%) ⬇️
python 58.37% <10.34%> (-0.89%) ⬇️
sqlite 57.80% <10.34%> (+0.29%) ⬆️
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.

@aminghadersohi
aminghadersohi marked this pull request as ready for review August 19, 2026 16:56
@dosubot dosubot Bot added the api Related to the REST API label Aug 19, 2026
@aminghadersohi
aminghadersohi requested review from richardfogaca and a lite review from Copilot August 19, 2026 17:45

Copilot AI 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.

Pull request overview

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Fixes get_chart_sql so request-supplied extra_form_data (dashboard-style filters) is preserved by the request schema and merged into query construction, matching get_chart_data behavior.

Changes:

  • Add extra_form_data to GetChartSqlRequest (Pydantic schema) so the field is validated/stored instead of silently dropped.
  • Forward/merge extra_form_data through both SQL build paths: saved query_context and form_data fallback.
  • Add unit tests covering request schema acceptance + propagation/merging into rendered SQL (and add missing coverage for get_chart_data’s already-correct path).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
tests/unit_tests/mcp_service/chart/tool/test_get_chart_sql.py Adds regression/unit tests verifying extra_form_data is accepted and applied in both saved-query_context and form_data SQL paths.
tests/unit_tests/mcp_service/chart/tool/test_get_chart_data.py Adds regression tests validating get_chart_data applies extra_form_data when called with a saved chart identifier.
superset/mcp_service/chart/tool/get_chart_sql.py Wires extra_form_data into query context building and merges it into saved query_context before SQL rendering.
superset/mcp_service/chart/schemas.py Extends GetChartSqlRequest with extra_form_data to prevent silent dropping of filters.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tests/unit_tests/mcp_service/chart/tool/test_get_chart_sql.py Outdated
Comment thread superset/mcp_service/chart/tool/get_chart_sql.py Outdated
Adds coverage for the form_data_key-only path, closing a patch-coverage
gap flagged on the extra_form_data fix.
@github-actions github-actions Bot removed the api Related to the REST API label Aug 19, 2026
@netlify

netlify Bot commented Aug 19, 2026

Copy link
Copy Markdown

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 6a081ed
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a887f8ad3c85d00086c273b
😎 Deploy Preview https://deploy-preview-43338--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.

Comment thread superset/mcp_service/chart/tool/get_chart_sql.py
Comment thread tests/unit_tests/mcp_service/chart/tool/test_get_chart_data.py
Address PR review feedback: an extra_form_data filter entry missing a
required key (e.g. "op") raised an unhandled KeyError out of
get_chart_sql instead of a structured ChartError. Also use a keyword
argument for extra_form_data at the _sql_from_form_data call site for
clarity, and strengthen the saved-query_context regression tests to
actually exercise both the "filters" and "adhoc_filters" extra_form_data
formats (previously only "filters" was tested despite the docstring
claiming both).
@bito-code-review

bito-code-review Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #ad9fae

Actionable Suggestions - 0
Review Details
  • Files reviewed - 4 · Commit Range: 09e60b9..d03fafa
    • superset/mcp_service/chart/schemas.py
    • superset/mcp_service/chart/tool/get_chart_sql.py
    • tests/unit_tests/mcp_service/chart/tool/test_get_chart_data.py
    • tests/unit_tests/mcp_service/chart/tool/test_get_chart_sql.py
  • Files skipped - 0
  • Tools
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@richardfogaca richardfogaca 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.

Richard’s agent here:

I found three correctness issues and one smaller error-handling concern at d03fafa:

1. Temporal filters are not exposed to Jinja rendering.
get_chart_sql merges extra_form_data into the query but never calls set_query_context_form_data before ChartDataCommand; the fallback path has the same omission. Because Jinja’s get_time_filter() reads request-local form data, a TEMPORAL_RANGE is unavailable while rendering virtual-dataset SQL. With remove_filter=True, it also cannot be marked consumed. Could we mirror the bridge used by get_chart_data on both SQL paths?

2. relative_start and relative_end are silently dropped.
These are standard extra_form_data overrides used when calculating relative time bounds. Normalization places them in form_data["extras"], but neither the saved-query merge nor the fresh-query builder copies those extras into the query object. Valid requests can therefore render SQL using the configured default anchor rather than the requested one. Could we merge normalized extras into every saved and newly built query?

3. Unsupported nested filter values can escape the structured error contract.
extra_form_data remains an unconstrained dictionary. A filter containing all required keys but an unsupported operator reaches ChartDataQueryContextSchema.load, which raises marshmallow.ValidationError; neither handler catches it. Malformed client input can therefore still become a tool-execution failure instead of ChartError(error_type="ValidationError"). Could we validate the nested filter shapes and translate schema-validation failures at the normalization/load boundary?

4. Small suggestion: narrow the KeyError translation.
The top-level handler currently reports every KeyError from the complete request path as malformed extra_form_data, including failures originating elsewhere. Scoping this conversion to filter normalization would preserve accurate error reporting.

For regression coverage, could we exercise actual query objects or rendered SQL across saved, fallback, and unsaved paths—covering get_time_filter(remove_filter=True), relative-time anchors, unsupported operators, and invalid nested container types? The current tests largely stop at raw dictionaries or mocked SQL, so they do not prove these behaviors.

@aminghadersohi

Copy link
Copy Markdown
Contributor Author

Addressed all feedback from the latest review in 50bc58fb8f:

  • bridge both saved-query-context and form-data SQL paths through set_query_context_form_data, so Jinja get_time_filter() sees and can consume temporal filters;
  • propagate normalized query extras, including relative_start and relative_end, into saved and freshly built query objects;
  • translate malformed nested filter containers and Marshmallow schema failures into structured ChartError(error_type="ValidationError") responses at the normalization/load boundaries;
  • removed the broad top-level KeyError handler so unrelated key errors are not mislabeled as malformed extra_form_data;
  • added regression coverage for relative-time extras and the request-local form-data bridge.

Validation: staged-file pre-commit passed mypy, ruff-format, ruff, and all other available hooks. The pylint hook could not run because pylint is not installed in this environment. Targeted pytest collection is also blocked by the environment's incompatible/missing sqlglot.dialects.singlestore module.

@aminghadersohi
aminghadersohi requested review from richardfogaca and a lite review from Copilot August 20, 2026 20:48

Copilot AI 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.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Suppressed comments (1)

superset/mcp_service/chart/tool/get_chart_sql.py:210

  • _sql_from_saved_query_context returns a ChartError on ChartDataQueryContextSchema.load() ValidationError, which prevents the caller from falling back to the (more resilient) form_data-based SQL builder. This can turn a stale/invalid saved query_context into a hard failure even though the fallback path could still produce SQL (and apply extra_form_data). Consider treating schema validation failures the same as other parse failures here by returning None so _handle_chart_sql_request can fall back.
        try:
            query_context = ChartDataQueryContextSchema().load(qc_json)
        except MarshmallowValidationError as ex:
            return ChartError(error=str(ex), error_type="ValidationError")

@aminghadersohi

Copy link
Copy Markdown
Contributor Author

Addressed Copilot’s follow-up suggestion in the latest commit: saved query_context Marshmallow validation failures now return None, allowing the existing form-data fallback to rebuild the query. Invalid request filters still return a structured ValidationError when the fallback validates them. Added a regression test for stale saved contexts.

@bito-code-review

bito-code-review Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #0e2ddf

Actionable Suggestions - 0
Additional Suggestions - 1
  • superset/mcp_service/chart/tool/get_chart_sql.py - 1
    • Silent validation failure loses diagnostics · Line 209-213
      Returning `None` silently discards the validation error details that were previously captured. MCP tool users lose all diagnostic information (which fields failed, what the schema expects) when a saved query_context is stale. Either preserve the error in a `ChartError` response or emit a structured log entry before returning `None`.
Review Details
  • Files reviewed - 4 · Commit Range: d03fafa..e811e91
    • superset/mcp_service/chart/chart_helpers.py
    • superset/mcp_service/chart/tool/get_chart_sql.py
    • tests/unit_tests/mcp_service/chart/test_chart_helpers.py
    • tests/unit_tests/mcp_service/chart/tool/test_get_chart_sql.py
  • Files skipped - 0
  • Tools
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@richardfogaca richardfogaca 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.

Richard's agent here:

I rechecked the PR diff at 6a081ed after the latest master merge. The provider diff is unchanged from the reviewed version, and the earlier Jinja form-data bridge, relative-time propagation, nested validation, and broad KeyError issues are addressed. I don't see a blocking correctness issue, so I'm approving.

Non-blocking suggestions:

  • Small suggestion: could we narrow the exception translation in _sql_from_form_data so unrelated datasource-resolution or query-construction failures are not reported as invalid extra_form_data?
  • Small suggestion: could we update the PR summary's “No behavior change for get_chart_data” statement? The shared helper change now propagates relative-time extras there as well.

The remaining coverage gap is behavioral: the current tests mostly assert mocked query dictionaries or bridge invocation rather than rendered SQL for Jinja get_time_filter(remove_filter=True) and relative-time anchors. That would be worth adding, but I don't think it needs to block this merge.

@aminghadersohi

Copy link
Copy Markdown
Contributor Author

Addressed the approver's final suggestions:

  • saved-query-context validation failures retain diagnostics via a warning log before falling back to form data;
  • fallback validation errors no longer blame extra_form_data specifically and instead report generic invalid chart query data, avoiding misclassification of unrelated form-data/query-construction problems;
  • added an assertion covering the preserved stale-context diagnostic;
  • updated the PR summary to document that the shared helper also propagates relative-time extras for get_chart_data.

All staged-file pre-commit hooks pass, including mypy, ruff-format, ruff, and pylint.

@bito-code-review

bito-code-review Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #875cd6

Actionable Suggestions - 0
Review Details
  • Files reviewed - 2 · Commit Range: e811e91..a642de1
    • superset/mcp_service/chart/tool/get_chart_sql.py
    • tests/unit_tests/mcp_service/chart/tool/test_get_chart_sql.py
  • Files skipped - 0
  • Tools
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers an incremental AI Review.

  • /review full - Manually triggers a full AI Review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@aminghadersohi aminghadersohi closed this by deleting the head repository Aug 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants