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


##########
superset/mcp_service/chart/schemas.py:
##########
@@ -1517,25 +1555,29 @@ def reject_sql_expression_in_raw_mode(self) -> 
"TableChartConfig":
     @model_validator(mode="after")
     def validate_unique_column_labels(self) -> "TableChartConfig":
         """Ensure all column labels are unique."""
-        labels_seen = set()
+        # Key is (saved_metric, label) so a saved metric and a regular column
+        # with the same input name are not flagged as duplicates — saved 
metrics
+        # resolve to their actual casing from the dataset during normalization.
+        labels_seen: dict[tuple[bool, str], str] = {}
         duplicates = []
 
         for i, col in enumerate(self.columns):
             # Generate the label that will be used (same logic as 
create_metric_object)
             if col.sql_expression:
                 # SQL metrics carry a required label; use it verbatim.
-                label = col.label
+                label = col.label or ""
             elif col.saved_metric:
-                label = col.label or col.name
+                label = col.label or col.name or ""
             elif col.aggregate:
                 label = col.label or f"{col.aggregate}({col.name})"
             else:
-                label = col.label or col.name
+                label = col.label or col.name or ""
 
-            if label in labels_seen:
+            key = (col.saved_metric, label)
+            if key in labels_seen:
                 duplicates.append(f"columns[{i}]: '{label}'")
             else:
-                labels_seen.add(label)
+                labels_seen[key] = f"columns[{i}]"

Review Comment:
   **Suggestion:** The duplicate-label check now keys by `(saved_metric, 
label)`, which allows the same rendered label to pass validation when one entry 
is a saved metric and the other is not. Superset still treats duplicate display 
labels as conflicts, so these requests can pass schema validation and fail 
later during query compilation. Deduplicate by final rendered label alone 
(after normalization), not by metric source type. [incorrect condition logic]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ❌ Table configs with mixed metrics can hit duplicate-label errors.
   - ⚠️ generate_explore_link may return URLs that fail in Explore.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Construct a `TableChartConfig` (model defined in
   `superset/mcp_service/chart/schemas.py:1494-1589`) with `chart_type="table"` 
and `columns`
   containing two entries that share the same display label but differ in 
`saved_metric`,
   e.g. `[ColumnRef(name="revenue", saved_metric=True), 
ColumnRef(name="revenue",
   aggregate="SUM", label="revenue")]`.
   
   2. When this config is parsed (e.g. as part of 
`GenerateExploreLinkRequest.config` in
   `superset/mcp_service/chart/schemas.py:1979-1988` or 
`GenerateChartRequest.config` in
   `schemas.py:1878-1904`), the 
`TableChartConfig.validate_unique_column_labels()` model
   validator at `schemas.py:1555-1589` runs. It computes `label` for each 
column and uses
   `key = (col.saved_metric, label)` (`schemas.py:1576`), so the two columns 
produce distinct
   keys `(True, "revenue")` and `(False, "revenue")` and no duplicate is 
recorded.
   
   3. In `generate_explore_link`
   (`superset/mcp_service/explore/tool/generate_explore_link.py:180-28`), the 
accepted
   `TableChartConfig` is mapped to Superset `form_data` via `map_table_config()`
   (`chart_utils.py:403-499`), where the saved metric becomes a metric named 
`"revenue"` and
   the ad‑hoc metric uses the explicit label `"revenue"`, yielding two identical
   metric/column labels in the query definition.
   
   4. When the resulting `form_data` is later executed through Superset's query 
layer (e.g.
   via `_compile_chart()` in `superset/mcp_service/chart/compile.py:143-200` or 
by visiting
   the generated Explore URL), 
`QueryObject._validate_no_have_duplicate_labels()` in
   `superset/common/query_object.py:15-25` builds `all_labels = 
self.metric_names +
   self.column_names` and raises `QueryObjectValidationError("Duplicate 
column/metric labels:
   ...")` because `"revenue"` appears twice, even though the schema-level 
validator allowed
   this configuration.
   ```
   </details>
   
   [Fix in 
Cursor](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=d5537f139ee84c369f017c9659663dcb&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=d5537f139ee84c369f017c9659663dcb&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:** 1576:1580
   **Comment:**
        *Incorrect Condition Logic: The duplicate-label check now keys by 
`(saved_metric, label)`, which allows the same rendered label to pass 
validation when one entry is a saved metric and the other is not. Superset 
still treats duplicate display labels as conflicts, so these requests can pass 
schema validation and fail later during query compilation. Deduplicate by final 
rendered label alone (after normalization), not by metric source type.
   
   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%2F39922&comment_hash=e9d91ae1fe82d0fa2e483d179e47a3aa9343a8e238d5d57845cc35bcb996e5e2&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39922&comment_hash=e9d91ae1fe82d0fa2e483d179e47a3aa9343a8e238d5d57845cc35bcb996e5e2&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