aminghadersohi commented on code in PR #45486:
URL: https://github.com/apache/superset/pull/45486#discussion_r4394894470


##########
superset/mcp_service/dashboard_scope.py:
##########
@@ -1032,23 +1015,7 @@ def scoped_dataset_query(
         time_range = intersect_time_ranges(constraints.time_range, time_range)
         time_column = scope_column
 
-    granularity = (time_column or main_dttm_col) if time_range else time_column
-    final = [*filters, *scope_filters]
-    if time_range and granularity:
-        final_with_time = [
-            *final,
-            {"col": granularity, "op": TEMPORAL_RANGE, "val": time_range},
-        ]
-    else:
-        final_with_time = final
-    removed = removed_granularity_column(final_with_time, granularity)
-    if removed is not None and removed in constraints.columns:
-        raise MCPDashboardScopeError(
-            f"the dashboard filter on {removed!r} would be dropped because 
that "
-            "column is also the query's time column.",
-            "Query without a time range on that column, or use the dashboard's 
charts.",
-        )
-    return final, time_range, time_column
+    return [*filters, *scope_filters], time_range, time_column

Review Comment:
   You're right; I reproduced that exact `get_table` shape at 
`19cf733704088dbddeec2c96899cba4a6d9d8386`. After scope rewriting both 
`order_date` filters are present, but `_apply_granularity` leaves an empty 
filter list and SQL with no WHERE:
   
   ```sql
   SELECT client AS client, COUNT(*) AS count
   FROM orders GROUP BY client
   LIMIT 1000 OFFSET 0
   ```
   
   Fixed in `a72613f8422e8b31d3073cf3bc61e8028409a4bb` with the narrowed guard. 
It examines the combined model/dashboard clauses and skips the refusal when an 
explicit `time_range` appends a matching binding. Same-column dashboard 
comparisons and ranges remain allowed.
   
   Regression test: 
`test_dataset_query_refuses_a_clause_on_a_non_time_temporal_column` 
(`tests/unit_tests/mcp_service/test_dashboard_scope.py`), parametrized over 
both dataset tools. Restoring the reviewed head's `dashboard_scope.py` gives 
**2 failed** (`DID NOT RAISE`); the new head gives **2 passed**. 
`test_dataset_query_keeps_scope_clauses_with_safe_temporal_bindings` adds **8 
passing controls** for the allowed shapes, including a dashboard range on the 
query's time column. I ran the four touched test files at the fixing SHA: **480 
passed**, with `manual`/`llm_compliance` deselected; changed-file pre-commit 
also passed. The PR description includes the command and the refreshed base 
comparison: **149 passed, 1 failed** without the production diff, **150 
passed** at this head for the original regression selection.
   
   Siblings checked:
   - superset/mcp_service/dashboard_scope.py:1018 — fixed in 
a72613f8422e8b31d3073cf3bc61e8028409a4bb
   - superset/mcp_service/semantic_layer/tool/get_table.py:137 — fixed in 
a72613f8422e8b31d3073cf3bc61e8028409a4bb via the shared dataset-scope rewrite; 
semantic-view requests remain refused while scoped.
   - superset/mcp_service/dataset/tool/query_dataset.py:244 — not affected: 
without a request range it does not set granularity; with a range it appends a 
matching temporal binding. The regression also pins the conservative 
shared-scope refusal for this tool.
   - superset/mcp_service/dashboard_scope.py:931 — not affected: chart 
data/preview and dashboard-data paths compose chart extra-form-data and retain 
their existing temporal-clause refusal, rather than using the dataset builder.
   - superset/mcp_service/dashboard_scope_sql.py:485 — not affected: SQL scope 
injects SQL predicates directly, without QueryContextFactory granularity 
rewriting.
   - superset/common/tabular_query.py:326 — not affected: the builder 
intentionally sets explicit granularity; its scoped dataset callers run through 
the shared guard before reaching it.
   - superset/common/query_context_factory.py:287 — not affected: cross-column 
removal remains intentional for overrides; this change refuses the unsafe 
scoped dataset request before that removal.
   - superset/common/form_data_query_context.py:1017 — not affected: chart-axis 
normalization, not a separate scoped dataset entry point.
   - superset/common/query_object.py:690 — not affected: temporal-bound 
cache-key handling does not perform the cross-column removal.
   - superset/common/query_actions.py:92 — not affected: filter-status 
reporting does not construct or replace predicates.
   - superset/mcp_service/chart/chart_helpers.py:1266 — not affected: shared 
chart normalization; scoped chart calls use chart extra-form-data composition.
   - superset/mcp_service/chart/chart_utils.py:3007 — not affected: chart 
generation/update builders, not the dataset-scope entry point; scoped data 
previews and saved-definition updates are refused by their existing gates.
   - superset/mcp_service/chart/plugins/big_number.py:221 — not affected: chart 
configuration/time-binding inheritance, not the dataset rewrite; existing scope 
gates refuse data previews and saved-definition updates.
   - superset/mcp_service/chart/plugins/gantt.py:152 — not affected: a 
temporal-column validation error, not a query rewrite.
   - superset/mcp_service/chart/plugins/geographic.py:146 — not affected: chart 
granularity binding; scoped chart reads use existing extra-form-data checks, 
not the dataset builder.
   - superset/mcp_service/chart/plugins/waterfall.py:213 — not affected: chart 
normalization, not a separate scoped dataset entry point.
   - superset/mcp_service/chart/schemas.py:3491 — not affected: inherited chart 
time-column metadata only.
   - superset/mcp_service/dataset/schemas.py:1259 — not affected: request-field 
declaration only.
   - superset/mcp_service/semantic_layer/schemas.py:252 — not affected: 
request-field declarations only.
   
   Search: `grep -rn --include='*.py' 'time_column\|_apply_granularity' 
superset/mcp_service superset/common`; entries above group repeated references 
within each path.
   



##########
superset/common/tabular_query.py:
##########
@@ -287,10 +287,8 @@ def _time_range_filters(
     """Express *time_range* as query filters.
 
     Semantic views need a one-sided range rewritten as an explicit comparison:
-    ``_apply_granularity`` removes the granularity column's ``TEMPORAL_RANGE``
-    filter (retaining non-range predicates on that column), and the mapper's
-    ``_get_time_filter`` emits nothing unless both bounds resolve, so the range
-    would vanish and the query would scan the whole view.
+    The mapper's ``_get_time_filter`` emits nothing unless both bounds resolve,

Review Comment:
   I agree. The docstring at `a72613f8422e8b31d3073cf3bc61e8028409a4bb` again 
explains both steps: `_apply_granularity` removes the granularity column's 
`TEMPORAL_RANGE`, while non-range predicates survive when the time column is 
unchanged; the semantic mapper then requires both bounds.
   
   This nit changes documentation only, so there is no fail-before runtime 
behavior to claim for it. A docstring-content check finds both 
`_apply_granularity` and `_get_time_filter` at this head, but not at 
`19cf733704088dbddeec2c96899cba4a6d9d8386`. 
`test_apply_granularity_keeps_simple_filters` covers the described range 
removal/predicate retention; the one-sided-range selection in 
`tests/unit_tests/common/test_tabular_query.py` passes **3 tests** at the new 
head. The separate behavioral regression in the same commit, 
`test_dataset_query_refuses_a_clause_on_a_non_time_temporal_column`, fails both 
cases before the guard and passes both afterward, as detailed in the other 
thread.
   
   Siblings checked:
   - superset/common/tabular_query.py:285 — fixed in 
a72613f8422e8b31d3073cf3bc61e8028409a4bb
   - superset/common/query_context_factory.py:435 — not affected: its existing 
removal behavior is the first step described by this comment; no runtime change 
here.
   - superset/semantic_layers/mapper.py:777 — not affected: its existing 
requirement for both bounds is the second step described by the comment; no 
runtime change here.
   



-- 
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