This is an automated email from the ASF dual-hosted git repository.

sophieyou pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new ae619b169c fix: the temporal x-axis results in a none time_range. 
(#25429)
ae619b169c is described below

commit ae619b169c2b02bbc2a72fd10fd23ad3322c45f6
Author: mapledan <[email protected]>
AuthorDate: Sat Nov 4 00:57:47 2023 +0800

    fix: the temporal x-axis results in a none time_range. (#25429)
    
    Co-authored-by: Elizabeth Thompson <[email protected]>
---
 superset/common/query_object_factory.py            | 45 ++++++++++++++++++--
 tests/unit_tests/common/test_process_time_range.py | 48 ++++++++++++++++++++++
 2 files changed, 90 insertions(+), 3 deletions(-)

diff --git a/superset/common/query_object_factory.py 
b/superset/common/query_object_factory.py
index a2732ae553..d993eca279 100644
--- a/superset/common/query_object_factory.py
+++ b/superset/common/query_object_factory.py
@@ -16,12 +16,21 @@
 # under the License.
 from __future__ import annotations
 
-from typing import Any, TYPE_CHECKING
+from typing import Any, cast, TYPE_CHECKING
 
 from superset.common.chart_data import ChartDataResultType
 from superset.common.query_object import QueryObject
 from superset.common.utils.time_range_utils import 
get_since_until_from_time_range
-from superset.utils.core import apply_max_row_limit, DatasourceDict, 
DatasourceType
+from superset.constants import NO_TIME_RANGE
+from superset.superset_typing import Column
+from superset.utils.core import (
+    apply_max_row_limit,
+    DatasourceDict,
+    DatasourceType,
+    FilterOperator,
+    get_xaxis_label,
+    QueryObjectFilterClause,
+)
 
 if TYPE_CHECKING:
     from sqlalchemy.orm import sessionmaker
@@ -61,8 +70,11 @@ class QueryObjectFactory:  # pylint: 
disable=too-few-public-methods
         processed_extras = self._process_extras(extras)
         result_type = kwargs.setdefault("result_type", parent_result_type)
         row_limit = self._process_row_limit(row_limit, result_type)
+        processed_time_range = self._process_time_range(
+            time_range, kwargs.get("filters"), kwargs.get("columns")
+        )
         from_dttm, to_dttm = get_since_until_from_time_range(
-            time_range, time_shift, processed_extras
+            processed_time_range, time_shift, processed_extras
         )
         kwargs["from_dttm"] = from_dttm
         kwargs["to_dttm"] = to_dttm
@@ -99,6 +111,33 @@ class QueryObjectFactory:  # pylint: 
disable=too-few-public-methods
         )
         return apply_max_row_limit(row_limit or default_row_limit)
 
+    @staticmethod
+    def _process_time_range(
+        time_range: str | None,
+        filters: list[QueryObjectFilterClause] | None = None,
+        columns: list[Column] | None = None,
+    ) -> str:
+        if time_range is None:
+            time_range = NO_TIME_RANGE
+            temporal_flt = [
+                flt
+                for flt in filters or []
+                if flt.get("op") == FilterOperator.TEMPORAL_RANGE
+            ]
+            if temporal_flt:
+                # Use the temporal filter as the time range.
+                # if the temporal filters uses x-axis as the temporal filter
+                # then use it or use the first temporal filter
+                xaxis_label = get_xaxis_label(columns or [])
+                match_flt = [
+                    flt for flt in temporal_flt if flt.get("col") == 
xaxis_label
+                ]
+                if match_flt:
+                    time_range = cast(str, match_flt[0].get("val"))
+                else:
+                    time_range = cast(str, temporal_flt[0].get("val"))
+        return time_range
+
     # light version of the view.utils.core
     # import view.utils require application context
     # Todo: move it and the view.utils.core to utils package
diff --git a/tests/unit_tests/common/test_process_time_range.py 
b/tests/unit_tests/common/test_process_time_range.py
new file mode 100644
index 0000000000..12ee6d21aa
--- /dev/null
+++ b/tests/unit_tests/common/test_process_time_range.py
@@ -0,0 +1,48 @@
+# 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.
+from superset.common.query_object_factory import QueryObjectFactory
+from superset.constants import NO_TIME_RANGE
+
+
+def test_process_time_range():
+    """
+    correct empty time range
+    """
+    assert QueryObjectFactory._process_time_range(None) == NO_TIME_RANGE
+
+    """
+    Use the first temporal filter as time range
+    """
+    filters = [
+        {"col": "dttm", "op": "TEMPORAL_RANGE", "val": "2001 : 2002"},
+        {"col": "dttm2", "op": "TEMPORAL_RANGE", "val": "2002 : 2003"},
+    ]
+    assert QueryObjectFactory._process_time_range(None, filters) == "2001 : 
2002"
+
+    """
+    Use the BASE_AXIS temporal filter as time range
+    """
+    columns = [
+        {
+            "columnType": "BASE_AXIS",
+            "label": "dttm2",
+            "sqlExpression": "dttm",
+        }
+    ]
+    assert (
+        QueryObjectFactory._process_time_range(None, filters, columns) == 
"2002 : 2003"
+    )

Reply via email to