in superset/utils/core.py [0:0]
def merge_extra_filters(form_data: dict[str, Any]) -> None: # noqa: C901
# extra_filters are temporary/contextual filters (using the legacy constructs)
# that are external to the slice definition. We use those for dynamic
# interactive filters.
# Note extra_filters only support simple filters.
form_data.setdefault("applied_time_extras", {})
adhoc_filters = form_data.get("adhoc_filters", [])
form_data["adhoc_filters"] = adhoc_filters
merge_extra_form_data(form_data)
if "extra_filters" in form_data:
# __form and __to are special extra_filters that target time
# boundaries. The rest of extra_filters are simple
# [column_name in list_of_values]. `__` prefix is there to avoid
# potential conflicts with column that would be named `from` or `to`
date_options = {
"__time_range": "time_range",
"__time_col": "granularity_sqla",
"__time_grain": "time_grain_sqla",
}
# Grab list of existing filters 'keyed' on the column and operator
def get_filter_key(f: dict[str, Any]) -> str:
if "expressionType" in f:
return f"{f['subject']}__{f['operator']}"
return f"{f['col']}__{f['op']}"
existing_filters = {}
for existing in adhoc_filters:
if (
existing["expressionType"] == "SIMPLE"
and existing.get("comparator") is not None
and existing.get("subject") is not None
):
existing_filters[get_filter_key(existing)] = existing["comparator"]
for filtr in form_data[ # pylint: disable=too-many-nested-blocks
"extra_filters"
]:
filtr["isExtra"] = True
# Pull out time filters/options and merge into form data
filter_column = filtr["col"]
if time_extra := date_options.get(filter_column):
time_extra_value = filtr.get("val")
if time_extra_value and time_extra_value != NO_TIME_RANGE:
form_data[time_extra] = time_extra_value
form_data["applied_time_extras"][filter_column] = time_extra_value
elif filtr["val"]:
# Merge column filters
if (filter_key := get_filter_key(filtr)) in existing_filters:
# Check if the filter already exists
if isinstance(filtr["val"], list):
if isinstance(existing_filters[filter_key], list):
# Add filters for unequal lists
# order doesn't matter
if set(existing_filters[filter_key]) != set(filtr["val"]):
adhoc_filters.append(simple_filter_to_adhoc(filtr))
else:
adhoc_filters.append(simple_filter_to_adhoc(filtr))
else:
# Do not add filter if same value already exists
if filtr["val"] != existing_filters[filter_key]:
adhoc_filters.append(simple_filter_to_adhoc(filtr))
else:
# Filter not found, add it
adhoc_filters.append(simple_filter_to_adhoc(filtr))
# Remove extra filters from the form data since no longer needed
del form_data["extra_filters"]