dhruv-techdev opened a new issue, #45436:
URL: https://github.com/apache/superset/issues/45436

   ### Bug description
   
   The `get_filters()` and `filter_values()` Jinja macros skip any filter whose 
value is falsy. A filter with the value `0` or `false` is silently left out, so 
templates in virtual datasets don't see it.
   
   The most common trigger is a dashboard **Range** native filter whose lower 
bound is `0`. Selecting 0–100 sends two filters, `col >= 0` and `col <= 100`, 
but `get_filters('col')` returns only the `<= 100` one.
   
   The cause is a truthiness check on the value in `superset/jinja_context.py`:
   
   ```python
   # ExtraCache.get_filters
   and (
       val
       # IS_NULL and IS_NOT_NULL operators do not have a value
       or op in (FilterOperator.IS_NULL, FilterOperator.IS_NOT_NULL)
   )
   
   # ExtraCache.filter_values
   elif val:
       return_val.append(val)
   ```
   
   The drill-to-detail fallback in the same class, 
`_get_filters_from_query_context`, already checks `val is None` and handles 
these values correctly.
   
   **How to reproduce**
   
   1. Create a virtual dataset with SQL like:
      ```sql
      SELECT * FROM my_table
      WHERE 1=1
      {% for f in get_filters('amount', remove_filter=True) %}
        AND amount {{ f.op }} {{ f.val }}
      {% endfor %}
      ```
   2. Add a chart on it to a dashboard, plus a **Range** native filter on 
`amount`.
   3. Set the range to 0–100 and apply it.
   4. View the chart's query (… → View query). Only `AND amount <= 100` is 
rendered; the `>= 0` bound is missing.
   
   It also reproduces in Explore with a simple adhoc filter such as `amount = 
0` or `is_active = false`: neither appears in `get_filters()`, and 
`filter_values('amount')` returns `[]`.
   
   Minimal unit-level reproduction:
   
   ```python
   with current_app.test_request_context(
       data={"form_data": json.dumps({"extra_form_data": {"filters": [
           {"col": "col", "op": ">=", "val": 0},
           {"col": "col", "op": "<=", "val": 100},
       ]}})}
   ):
       ExtraCache().get_filters("col")
       # actual:   [{'op': '<=', 'col': 'col', 'val': 100}]
       # expected: [{'op': '>=', 'col': 'col', 'val': 0}, {'op': '<=', 'col': 
'col', 'val': 100}]
   ```
   
   **Expected:** every applied filter is returned, including those with value 
`0` or `false`.
   **Actual:** those filters are dropped. With `remove_filter=True` the column 
also isn't marked as removed, so the template and the outer query disagree 
about which filters apply.
   
   
   ### Screenshots/recordings
   
   N/A
   
   ### Superset version
   
   master / latest-dev
   
   ### Python version
   
   3.12
   
   ### Node version
   
   Not applicable
   
   ### Browser
   
   Not applicable
   
   ### Additional context
   
   - Reproduced on master (4f49d24151) with a unit test against `ExtraCache`. A 
control filter with value 5 is returned correctly.
   - Suggested fix: compare against `None` (and empty values) instead of using 
truthiness, e.g. `val is not None and val != "" and val != []` in 
`get_filters`, and `elif val is not None:` in `filter_values`.
   
   
   ### Checklist
   
   - [ ] I have searched Superset docs and Slack and didn't find a solution to 
my problem.
   - [ ] I have searched the GitHub issue tracker and didn't find a similar bug 
report.
   - [ ] I have checked Superset's logs for errors and if I found a relevant 
Python stacktrace, I included it here as text in the "additional context" 
section.


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