aminghadersohi commented on code in PR #43771:
URL: https://github.com/apache/superset/pull/43771#discussion_r4206809018
##########
superset/mcp_service/chart/chart_helpers.py:
##########
@@ -450,12 +582,200 @@ def _resolve_deck_gl_metrics(
if value:
metrics.append(value)
elif isinstance(prf, str) and _is_metric_ref(prf):
- # Legacy deck_scatter: point_radius_fixed as a bare non-numeric metric
key
- logger.debug("Legacy point_radius_fixed string metric encountered:
%s", prf)
metrics.append(prf)
return metrics
+def _deck_query_adapter( # noqa: C901
+ form_data: dict[str, Any], query: dict[str, Any], viz_type: str
+) -> dict[str, Any]:
+ """Apply the native frontend builder for a single Deck.gl layer."""
+ base_columns = list(query.get("columns") or [])
+ base_metrics = list(query.get("metrics") or [])
+ filters = list(query.get("filters") or [])
+ tooltips = _deck_tooltip_columns(form_data.get("tooltip_contents"))
+
+ def add_null(column: str, *, value: Any = ...) -> None:
+ clause: dict[str, Any] = {"col": column, "op": "IS NOT NULL"}
+ if value is not ...:
+ clause["val"] = value
+ filters.append(clause)
+
+ if viz_type == "deck_geojson":
+ geometry = form_data.get("geojson")
+ if not isinstance(geometry, str) or not geometry:
+ raise ValueError("GeoJSON column is required for GeoJSON charts")
+ columns = _add_deck_columns(base_columns, [geometry] if geometry else
[])
+ cross_filter = form_data.get("cross_filter_column")
+ if cross_filter:
+ columns = _add_deck_columns(columns, [cross_filter])
+ columns = _add_deck_columns(columns, tooltips)
+ if form_data.get("filter_nulls", True) and isinstance(geometry, str):
+ add_null(geometry)
+ query.update(
+ columns=columns,
+ metrics=[],
+ groupby=[],
+ filters=filters,
+ is_timeseries=False,
+ )
+ return query
+
+ if viz_type == "deck_polygon":
+ line_column = form_data.get("line_column")
+ if not isinstance(line_column, str) or not line_column:
+ raise ValueError("Polygon column is required for Polygon charts")
+ columns = _add_deck_columns(base_columns, [line_column] if line_column
else [])
+ cross_filter = form_data.get("cross_filter_column")
+ if cross_filter:
+ columns = _add_deck_columns(columns, [cross_filter])
+ columns = _add_deck_columns(columns, tooltips)
+ metrics: list[Any] = []
+ if metric := form_data.get("metric"):
+ metrics.append(metric)
+ radius = form_data.get("point_radius_fixed")
+ if (
+ isinstance(radius, dict)
+ and radius.get("type") == "metric"
+ and radius.get("value") is not None
+ ):
+ metrics.append(radius["value"])
+ if form_data.get("filter_nulls", True) and isinstance(line_column,
str):
+ add_null(line_column)
+ if metric:
+ add_null(_deck_metric_label(metric))
+ query.update(
+ columns=columns,
+ metrics=metrics,
+ filters=filters,
+ is_timeseries=False,
+ )
+ return query
+
+ if viz_type == "deck_path":
+ line_column = form_data.get("line_column")
+ if not isinstance(line_column, str) or not line_column:
+ raise ValueError("Line column is required for Path charts")
+ columns = list(base_columns)
+ metrics = [metric for metric in base_metrics if
_is_deck_metric_value(metric)]
+ groupby = list(query.get("groupby") or [])
+ metric = form_data.get("metric")
+ if metrics or metric:
+ if metric and metric not in metrics:
+ metrics.append(metric)
+ if line_column and line_column not in groupby:
+ groupby.append(line_column)
+ elif line_column:
+ columns = _add_deck_columns(columns, [line_column])
+ if dimension := form_data.get("dimension"):
+ columns = _add_deck_columns(columns, [dimension])
+
+ line_width = form_data.get("line_width")
+ raw_width = (
+ line_width
+ if isinstance(line_width, str)
+ else line_width.get("value")
+ if isinstance(line_width, dict)
+ else None
+ )
+ width_metric = (
+ raw_width
+ if _is_deck_metric_value(line_width)
+ and raw_width is not None
+ and not isinstance(raw_width, (int, float))
+ else None
+ )
+ for extra_metric in (width_metric, form_data.get("breakpoint_metric")):
+ if extra_metric is None:
+ continue
+ labels = {_deck_metric_label(item) for item in metrics}
+ if _deck_metric_label(extra_metric) not in labels:
+ metrics.append(extra_metric)
+ if line_column and line_column not in groupby:
+ groupby.append(line_column)
+ columns = _add_deck_columns(columns, tooltips)
+ groupby = _add_deck_columns(groupby, tooltips)
+ if not any(
+ filter_.get("col") == line_column and filter_.get("op") == "IS NOT
NULL"
+ for filter_ in filters
+ if isinstance(filter_, dict)
+ ):
+ add_null(line_column)
+ query.update(
+ columns=columns,
+ metrics=metrics,
+ groupby=groupby,
Review Comment:
Fixed in 31bff3652ae76ff7db15a230ad8eeeb9563d2fdd.
The Path fallback now places line_column in canonical columns alongside
dimensions/tooltips and removes the deprecated groupby key.
test_deck_path_metric_keeps_canonical_path_grouping exercises the real
QueryObjectFactory and SQL generation, asserting path selection and GROUP BY
path with count/width/breakpoint metric controls. All three cases failed before
the fix and pass after; the existing spatial query-contract expectation was
updated.
Validation: MCP/common unit suites: 9,198 passed, 4 skipped; touched
modules: 343 passed plus 351 Sunburst tests passed. Pre-commit passed on all 83
branch-changed files, including mypy.
--
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]