codeant-ai-for-open-source[bot] commented on code in PR #40099:
URL: https://github.com/apache/superset/pull/40099#discussion_r3238422367


##########
superset/mcp_service/chart/chart_helpers.py:
##########
@@ -69,6 +69,141 @@ def get_cached_form_data(form_data_key: str) -> str | None:
         return None
 
 
+def resolve_datasource_engine(datasource_id: Any, datasource_type: str) -> str:
+    """Return the datasource engine name, or ``"base"`` if it cannot be 
resolved."""
+    if not isinstance(datasource_id, (int, str)):
+        return "base"
+    try:
+        from superset.daos.datasource import DatasourceDAO
+        from superset.utils.core import DatasourceType
+
+        datasource = DatasourceDAO.get_datasource(
+            datasource_type=DatasourceType(datasource_type),
+            database_id_or_uuid=datasource_id,
+        )
+        return datasource.database.db_engine_spec.engine
+    except Exception:  # noqa: BLE001
+        logger.debug("Could not resolve engine for datasource %s", 
datasource_id)
+        return "base"
+
+
+def prepare_form_data_for_query(
+    form_data: dict[str, Any],
+    datasource_id: Any,
+    datasource_type: str,
+    extra_form_data: dict[str, Any] | None = None,
+    datasource_engine: str | None = None,
+) -> None:
+    """Normalize form_data filters before building a QueryObject payload.
+
+    Explore and legacy viz query construction merge dashboard/native filter 
payloads
+    and split adhoc filters into the concrete ``filters``/``where``/``having``
+    fields consumed by QueryObject. MCP tools that build query payloads 
directly
+    must perform the same normalization before calling QueryContextFactory.
+
+    Mutates ``form_data`` in place.
+    """
+    from superset.utils.core import (
+        convert_legacy_filters_into_adhoc,
+        form_data_to_adhoc,
+        merge_extra_filters,
+        simple_filter_to_adhoc,
+        split_adhoc_filters_into_base_filters,
+    )
+
+    if isinstance(form_data.get("adhoc_filters"), list):
+        adhoc_filters = [
+            *(
+                form_data_to_adhoc(form_data, clause)
+                for clause in ("having", "where")
+                if form_data.get(clause)
+            ),
+            *(
+                simple_filter_to_adhoc(filter_, "where")
+                for filter_ in form_data.get("filters") or []
+                if filter_ is not None
+            ),
+            *form_data["adhoc_filters"],
+        ]
+        form_data["adhoc_filters"] = adhoc_filters
+
+    if extra_form_data:
+        form_data["extra_form_data"] = extra_form_data

Review Comment:
   **Suggestion:** This overwrites any `extra_form_data` already present in 
cached `form_data` instead of merging it, so existing dashboard/native filter 
payload can be silently dropped whenever request-level `extra_form_data` is 
provided. Merge request extras into the existing `form_data["extra_form_data"]` 
additively so both cached and request filters are preserved before 
normalization. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ❌ MCP get_chart_data ignores cached dashboard/native filters with 
overrides.
   - ⚠️ LLM analyses see data inconsistent with Explore visualization filters.
   - ⚠️ Fallback query construction drops extra_form_data-based temporal 
restrictions.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. In the standard Explore flow, when a chart is rendered with 
dashboard/native filters,
   the view layer populates `form_data["extra_form_data"]` with those filters, 
as seen in
   `superset/viz.py:1638-1652` where `_apply_layer_filtering()` copies
   `self.form_data["extra_form_data"]` into the per-layer `form_data` dict.
   
   2. That Explore `form_data` (including `extra_form_data` from step 1) is 
cached under a
   `form_data_key` via the Explore caching mechanism used by 
`GetFormDataCommand`, which
   `get_cached_form_data()` in 
`superset/mcp_service/chart/chart_helpers.py:54-69` later
   reads back for MCP tools.
   
   3. An MCP client calls the `get_chart_data` tool at
   `superset/mcp_service/chart/tool/get_chart_data.py:99-120` with both
   `request.form_data_key` (pointing to cached `form_data` that already has
   `extra_form_data`) and a non-empty `request.extra_form_data` containing 
additional
   request-level filters; the unsaved-state branch at 
`get_chart_data.py:243-331` loads
   `cached_form_data_dict` and then invokes
   `prepare_form_data_for_query(cached_form_data_dict, datasource_id, 
datasource_type,
   request.extra_form_data)` at lines 326-331.
   
   4. Inside `prepare_form_data_for_query()` in
   `superset/mcp_service/chart/chart_helpers.py:90-137`, the check at line 130 
(`if
   extra_form_data:`) and assignment at line 131 (`form_data["extra_form_data"] 
=
   extra_form_data`) overwrite any existing `form_data["extra_form_data"]` from 
the cached
   Explore state before `merge_extra_filters(form_data)` is called, so when the 
query context
   is built in `get_chart_data.py:333-351` the dashboard/native filters encoded 
in the
   original `extra_form_data` are silently dropped and only the request-level
   `extra_form_data` predicates are applied.
   ```
   </details>
   
   [Fix in 
Cursor](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt=This%20is%20a%20comment%20left%20during%20a%20code%20review.%0A%0A%2A%2APath%3A%2A%2A%20superset%2Fmcp_service%2Fchart%2Fchart_helpers.py%0A%2A%2ALine%3A%2A%2A%20130%3A131%0A%2A%2AComment%3A%2A%2A%0A%09%2ALogic%20Error%3A%20This%20overwrites%20any%20%60extra_form_data%60%20already%20present%20in%20cached%20%60form_data%60%20instead%20of%20merging%20it%2C%20so%20existing%20dashboard%2Fnative%20filter%20payload%20can%20be%20silently%20dropped%20whenever%20request-level%20%60extra_form_data%60%20is%20provided.%20Merge%20request%20extras%20into%20the%20existing%20%60form_data%5B%22extra_form_data%22%5D%60%20additively%20so%20both%20cached%20and%20request%20filters%20are%20preserved%20before%20normalization.%0A%0AValidate%20the%20correctness%20of%20the%20flagged%20issue.%20If%20correct%2C%20How%20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20concise.%0AOnce
 
%20fix%20is%20implemented%2C%20also%20check%20other%20comments%20on%20the%20same%20PR%2C%20and%20ask%20user%20if%20the%20user%20wants%20to%20fix%20the%20rest%20of%20the%20comments%20as%20well.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20comments%20validate%20the%20correctness%20and%20implement%20a%20minimal%20fix%0A)
 | [Fix in VSCode 
Claude](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt=This%20is%20a%20comment%20left%20during%20a%20code%20review.%0A%0A%2A%2APath%3A%2A%2A%20superset%2Fmcp_service%2Fchart%2Fchart_helpers.py%0A%2A%2ALine%3A%2A%2A%20130%3A131%0A%2A%2AComment%3A%2A%2A%0A%09%2ALogic%20Error%3A%20This%20overwrites%20any%20%60extra_form_data%60%20already%20present%20in%20cached%20%60form_data%60%20instead%20of%20merging%20it%2C%20so%20existing%20dashboard%2Fnative%20filter%20payload%20can%20be%20silently%20dropped%20whenever%20request-level%20%60extra_form_data%60%20is%20provided.%20Merge%20request%20extras%20into%20the%20existing%20%60form_data%5B%22ext
 
ra_form_data%22%5D%60%20additively%20so%20both%20cached%20and%20request%20filters%20are%20preserved%20before%20normalization.%0A%0AValidate%20the%20correctness%20of%20the%20flagged%20issue.%20If%20correct%2C%20How%20can%20I%20resolve%20this%3F%20If%20you%20propose%20a%20fix%2C%20implement%20it%20and%20please%20make%20it%20concise.%0AOnce%20fix%20is%20implemented%2C%20also%20check%20other%20comments%20on%20the%20same%20PR%2C%20and%20ask%20user%20if%20the%20user%20wants%20to%20fix%20the%20rest%20of%20the%20comments%20as%20well.%20if%20said%20yes%2C%20then%20fetch%20all%20the%20comments%20validate%20the%20correctness%20and%20implement%20a%20minimal%20fix%0A)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset/mcp_service/chart/chart_helpers.py
   **Line:** 130:131
   **Comment:**
        *Logic Error: This overwrites any `extra_form_data` already present in 
cached `form_data` instead of merging it, so existing dashboard/native filter 
payload can be silently dropped whenever request-level `extra_form_data` is 
provided. Merge request extras into the existing `form_data["extra_form_data"]` 
additively so both cached and request filters are preserved before 
normalization.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F40099&comment_hash=084f0813a0c53474695c029e998d1d1e7181a4ef9624ca46e9869cea64cbb4c0&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F40099&comment_hash=084f0813a0c53474695c029e998d1d1e7181a4ef9624ca46e9869cea64cbb4c0&reaction=dislike'>👎</a>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to