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


##########
superset/daos/base.py:
##########
@@ -499,9 +499,24 @@ def apply_column_operators(
                 )
             column = getattr(cls.model_cls, col)
             try:
-                # Always use ColumnOperatorEnum's apply method
                 operator_enum = ColumnOperatorEnum(opr)
-                query = query.filter(operator_enum.apply(column, value))
+                # Relationship attributes (many-to-one or many-to-many)
+                # can't be compared directly with scalar operators —
+                # SQLAlchemy needs `.any(...)` or `.has(...)`. Detect the
+                # collection case and dispatch to the related model's id
+                # column. This lets callers use the natural shape
+                # `{col: "<relationship>", opr: "eq", value: <id>}` to
+                # find rows whose related collection contains the given id.
+                if (
+                    operator_enum == ColumnOperatorEnum.eq
+                    and hasattr(column, "property")
+                    and isinstance(column.property, RelationshipProperty)
+                    and column.property.uselist
+                ):
+                    related_pk = inspect(column.property.mapper).primary_key[0]
+                    query = query.filter(column.any(related_pk == value))
+                else:
+                    query = query.filter(operator_enum.apply(column, value))

Review Comment:
   **Suggestion:** Relationship filters only get special handling for `eq`; any 
other operator on a collection relationship still falls through to the scalar 
operator path and will raise SQLAlchemy runtime errors (for example when a 
client sends `opr="in"` or `opr="sw"` with `col="dashboards"`). Add explicit 
handling for allowed relationship operators (or raise a clear validation error 
before query execution) so relationship filters cannot hit the invalid scalar 
comparison path. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ❌ list_charts crashes when using non-eq dashboard filters.
   - ⚠️ MCP clients can trigger 500s with malformed relationship filters.
   - ⚠️ Any BaseDAO m2m filter misusing operators hits runtime errors.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. From an MCP client, call the `list_charts` tool defined in
   `superset/mcp_service/chart/tool/list_charts.py:14-46` with a request 
payload whose
   `filters` array contains an entry like `{"col": "dashboards", "opr": "in", 
"value": [42]}`
   (or any non-`eq` operator such as `"sw"`).
   
   2. Inside `list_charts`, the request is parsed into `ListChartsRequest` and 
`ChartFilter`
   objects (see `superset/mcp_service/chart/schemas.py:18-48`, where 
`ChartFilter.opr` is a
   `ColumnOperatorEnum` and `col` allows `"dashboards"`). The tool then 
constructs a
   `ModelListCore` with `dao_class=ChartDAO` and calls
   `tool.run_tool(filters=request.filters, ...)` (see
   `superset/mcp_service/chart/tool/list_charts.py:93-114`).
   
   3. `ModelListCore.run_tool` in `superset/mcp_service/mcp_core.py:260-38` 
forwards those
   `ChartFilter` objects to the DAO via 
`ChartDAO.list(column_operators=filters, ...)`.
   `ChartDAO` inherits `BaseDAO[Slice]` (`superset/daos/chart.py`) so
   `BaseDAO.apply_column_operators` is used to apply the filters.
   
   4. In `BaseDAO.apply_column_operators` (`superset/daos/base.py:18-64` and 
the new logic at
   lines 510-519), for the filter with `col="dashboards"` and `opr="in"`, 
`column` is the
   `Slice.dashboards` many-to-many relationship attribute, `operator_enum` is
   `ColumnOperatorEnum.in_`, the relationship-specific `eq` branch at lines 
510-56 is
   skipped, and execution falls into the `else` branch at line 519 calling
   `operator_enum.apply(column, value)`. `ColumnOperatorEnum.in_` is mapped in
   `superset/daos/base.py:29-37` to `lambda col, val: col.in_(...)`, which is 
invalid for a
   collection relationship attribute; when `query.filter(column.in_(...))` is 
evaluated,
   SQLAlchemy raises a runtime error (e.g. an AttributeError or StatementError 
about
   comparing a collection to a scalar), causing the `list_charts` MCP call to 
fail with an
   internal error instead of returning results or a clear validation error.
   ```
   </details>
   
   [Fix in 
Cursor](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=e6f6b28fd1ca4f6bb024b8cfb8219af3&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 | [Fix in VSCode 
Claude](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=e6f6b28fd1ca4f6bb024b8cfb8219af3&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(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/daos/base.py
   **Line:** 510:519
   **Comment:**
        *Logic Error: Relationship filters only get special handling for `eq`; 
any other operator on a collection relationship still falls through to the 
scalar operator path and will raise SQLAlchemy runtime errors (for example when 
a client sends `opr="in"` or `opr="sw"` with `col="dashboards"`). Add explicit 
handling for allowed relationship operators (or raise a clear validation error 
before query execution) so relationship filters cannot hit the invalid scalar 
comparison path.
   
   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%2F40397&comment_hash=33247a3251c46da1a0f0c3ae4dc157e0647835c4d555223bd9fddbd615fe5795&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F40397&comment_hash=33247a3251c46da1a0f0c3ae4dc157e0647835c4d555223bd9fddbd615fe5795&reaction=dislike'>👎</a>



##########
superset/mcp_service/chart/schemas.py:
##########
@@ -538,12 +538,15 @@ class ChartFilter(ColumnOperator):
         "datasource_name",
         "created_by_fk",
         "changed_by_fk",
+        "dashboards",

Review Comment:
   **Suggestion:** The schema now accepts `dashboards`, but this addition is 
not reflected in DAO filter discovery metadata, so 
`get_schema(model_type='chart')` still does not advertise `dashboards` as a 
filter column. This creates an API contract mismatch where clients following 
schema discovery won't learn about the new filter. Update chart filter metadata 
exposure (or relationship filter discovery) so `dashboards` appears 
consistently in `get_schema`. [api mismatch]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ⚠️ get_schema omits dashboards, hiding a supported chart filter.
   - ⚠️ MCP agents relying on discovery cannot learn dashboards filter.
   - ⚠️ Documentation in ChartFilter contradicts actual schema metadata.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Call the MCP `get_schema` tool with `{"request": {"model_type": 
"chart"}}`, which is
   implemented in `superset/mcp_service/system/tool/get_schema.py:66-83`. For
   `model_type="chart"`, `_get_chart_schema_core` returns a 
`ModelGetSchemaCore` configured
   with `dao_class=ChartDAO`, `select_columns=get_chart_columns()`, and
   `exclude_filter_columns=set(SELF_REFERENCING_FILTER_COLUMNS)`.
   
   2. In `ModelGetSchemaCore.run_tool` 
(`superset/mcp_service/mcp_core.py:69-83`), the method
   `_get_filter_columns` at `superset/mcp_service/mcp_core.py:35-62` calls
   `ChartDAO.get_filterable_columns_and_operators()` to build 
`schema_info.filter_columns`.
   
   3. `ChartDAO.get_filterable_columns_and_operators` 
(`superset/daos/chart.py:92-16`) simply
   delegates to `BaseDAO.get_filterable_columns_and_operators` and then 
augments with
   `CHART_CUSTOM_FIELDS`. `BaseDAO.get_filterable_columns_and_operators` in
   `superset/daos/base.py:526-119` inspects `mapper.columns` (real table 
columns) and hybrid
   properties; it does not include relationship attributes like the many-to-many
   `Slice.dashboards` relationship, so `"dashboards"` never appears in the 
returned mapping.
   
   4. As a result, the `get_schema` response for charts contains 
`schema_info.filter_columns`
   with entries for fields like `"slice_name"` and `"viz_type"`, but no 
`"dashboards"` key,
   while the MCP request schema `ChartFilter` in
   `superset/mcp_service/chart/schemas.py:18-40` explicitly allows 
`col="dashboards"` and its
   description tells clients to "Use get_schema(model_type='chart') for 
available filter
   columns" and mentions filtering by `'dashboards'`. This creates a contract 
mismatch:
   clients following the documented discovery flow (call `get_schema` to learn 
valid filters,
   then call `list_charts`) cannot discover the new `dashboards` filter even 
though the list
   tool and DAO now support it.
   ```
   </details>
   
   [Fix in 
Cursor](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=a058c1b7a028453bb51605c967517650&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 | [Fix in VSCode 
Claude](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=a058c1b7a028453bb51605c967517650&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(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/schemas.py
   **Line:** 541:541
   **Comment:**
        *Api Mismatch: The schema now accepts `dashboards`, but this addition 
is not reflected in DAO filter discovery metadata, so 
`get_schema(model_type='chart')` still does not advertise `dashboards` as a 
filter column. This creates an API contract mismatch where clients following 
schema discovery won't learn about the new filter. Update chart filter metadata 
exposure (or relationship filter discovery) so `dashboards` appears 
consistently in `get_schema`.
   
   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%2F40397&comment_hash=b521233f6de47e872fa18f2b9fb3f3958477c2f533a7ed9c6aeef7d3a0d6b31c&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F40397&comment_hash=b521233f6de47e872fa18f2b9fb3f3958477c2f533a7ed9c6aeef7d3a0d6b31c&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