This is an automated email from the ASF dual-hosted git repository. johnbodley pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
The following commit(s) were added to refs/heads/master by this push: new 237ac59 [fix] Fixing issue with Jinja filter_value (#9582) 237ac59 is described below commit 237ac59474ba39b3c812cca92d189673f758bb8c Author: John Bodley <4567245+john-bod...@users.noreply.github.com> AuthorDate: Mon Apr 20 09:44:45 2020 -0700 [fix] Fixing issue with Jinja filter_value (#9582) Co-authored-by: John Bodley <john.bod...@airbnb.com> --- superset/jinja_context.py | 34 ++++++++++------- tests/jinja_context_tests.py | 90 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 14 deletions(-) diff --git a/superset/jinja_context.py b/superset/jinja_context.py index 7863809..b4f9159 100644 --- a/superset/jinja_context.py +++ b/superset/jinja_context.py @@ -24,6 +24,7 @@ from jinja2.sandbox import SandboxedEnvironment from superset import jinja_base_context from superset.extensions import jinja_context_manager +from superset.utils.core import convert_legacy_filters_into_adhoc, merge_extra_filters def url_param(param: str, default: Optional[str] = None) -> Optional[Any]: @@ -80,8 +81,6 @@ def filter_values(column: str, default: Optional[str] = None) -> List[str]: - you want to have the ability for filter inside the main query for speed purposes - This searches for "filters" and "extra_filters" in ``form_data`` for a match - Usage example:: SELECT action, count(*) as times @@ -93,19 +92,26 @@ def filter_values(column: str, default: Optional[str] = None) -> List[str]: :param default: default value to return if there's no matching columns :return: returns a list of filter values """ + form_data = json.loads(request.form.get("form_data", "{}")) - return_val = [] - for filter_type in ["filters", "extra_filters"]: - if filter_type not in form_data: - continue - - for f in form_data[filter_type]: - if f["col"] == column: - if isinstance(f["val"], list): - for v in f["val"]: - return_val.append(v) - else: - return_val.append(f["val"]) + convert_legacy_filters_into_adhoc(form_data) + merge_extra_filters(form_data) + + return_val = [ + comparator + for filter in form_data.get("adhoc_filters", []) + for comparator in ( + filter["comparator"] + if isinstance(filter["comparator"], list) + else [filter["comparator"]] + ) + if ( + filter.get("expressionType") == "SIMPLE" + and filter.get("clause") == "WHERE" + and filter.get("subject") == column + and filter.get("comparator") + ) + ] if return_val: return return_val diff --git a/tests/jinja_context_tests.py b/tests/jinja_context_tests.py new file mode 100644 index 0000000..91cb5e4 --- /dev/null +++ b/tests/jinja_context_tests.py @@ -0,0 +1,90 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +import json +from unittest import mock + +from superset.jinja_context import filter_values +from tests.base_tests import SupersetTestCase + + +class Jinja2ContextTests(SupersetTestCase): + def test_filter_values_default(self) -> None: + request = mock.MagicMock() + request.form = {} + + with mock.patch("superset.jinja_context.request", request): + self.assertEquals(filter_values("name", "foo"), ["foo"]) + + def test_filter_values_no_default(self) -> None: + request = mock.MagicMock() + request.form = {} + + with mock.patch("superset.jinja_context.request", request): + self.assertEquals(filter_values("name"), []) + + def test_filter_values_adhoc_filters(self) -> None: + request = mock.MagicMock() + + request.form = { + "form_data": json.dumps( + { + "adhoc_filters": [ + { + "clause": "WHERE", + "comparator": "foo", + "expressionType": "SIMPLE", + "operator": "in", + "subject": "name", + } + ], + } + ) + } + + with mock.patch("superset.jinja_context.request", request): + self.assertEquals(filter_values("name"), ["foo"]) + + request.form = { + "form_data": json.dumps( + { + "adhoc_filters": [ + { + "clause": "WHERE", + "comparator": ["foo", "bar"], + "expressionType": "SIMPLE", + "operator": "in", + "subject": "name", + } + ], + } + ) + } + + with mock.patch("superset.jinja_context.request", request): + self.assertEquals(filter_values("name"), ["foo", "bar"]) + + def test_filter_values_extra_filters(self) -> None: + request = mock.MagicMock() + + request.form = { + "form_data": json.dumps( + {"extra_filters": [{"col": "name", "op": "in", "val": "foo"}]} + ) + } + + with mock.patch("superset.jinja_context.request", request): + self.assertEquals(filter_values("name"), ["foo"])