You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by va...@apache.org on 2025/03/26 20:24:01 UTC

(superset) branch fix/time-grain-macro-on-table-chart updated (84c9297397 -> 9e4c1d388d)

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

vavila pushed a change to branch fix/time-grain-macro-on-table-chart
in repository https://gitbox.apache.org/repos/asf/superset.git


 discard 84c9297397 fix(Jinja): Emit time grain to table charts even if they don't have a temporal column
     add 5222f940cc fix(echarts): Sort series by name using naturalCompare (#32850)
     add 68a81c3989 fix: update dataset/query catalog on DB changes (#32829)
     add 6c7f089ebb fix(translation): Dutch translations for Current datetime filter (#31869)
     add f0dc1e7527 fix(table-chart): Do not show comparison columns config if time_compare is set to [] (#32863)
     new 4e46ba8ca2 fix(Jinja): Emit time grain to table charts even if they don't have a temporal column
     new 9e4c1d388d fix(Jinja): Always emit time grain filter value to the table chart

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (84c9297397)
            \
             N -- N -- N   refs/heads/fix/time-grain-macro-on-table-chart (9e4c1d388d)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../plugins/plugin-chart-echarts/package.json      |   4 +-
 .../plugin-chart-echarts/src/utils/series.ts       |  12 ++-
 .../plugin-chart-echarts/test/utils/series.test.ts | 111 ++++++++++++++++++++
 .../plugin-chart-table/src/controlPanel.tsx        |   6 +-
 superset/commands/database/update.py               |  44 +++++++-
 superset/translations/nl/LC_MESSAGES/messages.po   |  21 ++--
 tests/integration_tests/charts/api_tests.py        |  58 -----------
 tests/integration_tests/charts/data/api_tests.py   | 112 +++++++++++++++------
 tests/unit_tests/commands/databases/update_test.py |  62 ++++++++++++
 9 files changed, 314 insertions(+), 116 deletions(-)


(superset) 02/02: fix(Jinja): Always emit time grain filter value to the table chart

Posted by va...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

vavila pushed a commit to branch fix/time-grain-macro-on-table-chart
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 9e4c1d388d5779c7e10fc51d6ad4b265cf49e4a3
Author: Vitor Avila <vi...@preset.io>
AuthorDate: Wed Mar 26 17:22:19 2025 -0300

    fix(Jinja): Always emit time grain filter value to the table chart
---
 .../plugin-chart-table/src/controlPanel.tsx        |   1 -
 tests/integration_tests/charts/api_tests.py        |  58 -----------
 tests/integration_tests/charts/data/api_tests.py   | 112 +++++++++++++++------
 3 files changed, 80 insertions(+), 91 deletions(-)

diff --git a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
index 4baf5f94a6..ef3a8e700c 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
+++ b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
@@ -233,7 +233,6 @@ const config: ControlPanelConfig = {
             name: 'time_grain_sqla',
             config: {
               ...sharedControls.time_grain_sqla,
-              default: null,
               visibility: ({ controls }) => {
                 const dttmLookup = Object.fromEntries(
                   ensureIsArray(controls?.groupby?.options).map(option => [
diff --git a/tests/integration_tests/charts/api_tests.py b/tests/integration_tests/charts/api_tests.py
index 5fd27bed0f..d4e8f01993 100644
--- a/tests/integration_tests/charts/api_tests.py
+++ b/tests/integration_tests/charts/api_tests.py
@@ -14,7 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-"""Unit tests for Superset"""
 
 from io import BytesIO
 from unittest import mock
@@ -24,7 +23,6 @@ from zipfile import is_zipfile, ZipFile
 import prison
 import pytest
 import yaml
-from flask import g
 from flask_babel import lazy_gettext as _
 from parameterized import parameterized
 from sqlalchemy import and_
@@ -63,7 +61,6 @@ from tests.integration_tests.fixtures.importexport import (
     dataset_config,
     dataset_metadata_config,
 )
-from tests.integration_tests.fixtures.query_context import get_query_context
 from tests.integration_tests.fixtures.tags import (
     create_custom_tags,  # noqa: F401
     get_filter_params,
@@ -80,7 +77,6 @@ from tests.integration_tests.insert_chart_mixin import InsertChartMixin
 from tests.integration_tests.test_app import app
 from tests.integration_tests.utils.get_dashboards import get_dashboards_ids
 
-CHART_DATA_URI = "api/v1/chart/data"
 CHARTS_FIXTURE_COUNT = 10
 
 
@@ -2330,57 +2326,3 @@ class TestChartApi(ApiOwnersTestCaseMixin, InsertChartMixin, SupersetTestCase):
 
         security_manager.add_permission_role(alpha_role, write_tags_perm)
         security_manager.add_permission_role(alpha_role, tag_charts_perm)
-
-    @patch("superset.security.manager.SupersetSecurityManager.has_guest_access")
-    @patch("superset.security.manager.SupersetSecurityManager.is_guest_user")
-    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
-    def test_get_chart_data_as_guest_user(
-        self, is_guest_user, has_guest_access
-    ):  # get_guest_rls_filters
-        """
-        Chart API: Test create simple chart
-        """
-        self.login(ADMIN_USERNAME)
-        g.user.rls = []
-        is_guest_user.return_value = True
-        has_guest_access.return_value = True
-
-        with mock.patch.object(Slice, "get_query_context") as mock_get_query_context:
-            mock_get_query_context.return_value = get_query_context("birth_names")
-            rv = self.client.post(
-                "api/v1/chart/data",  # noqa: F541
-                json={
-                    "datasource": {"id": 2, "type": "table"},
-                    "queries": [
-                        {
-                            "extras": {"where": "", "time_grain_sqla": "P1D"},
-                            "columns": ["name"],
-                            "metrics": [{"label": "sum__num"}],
-                            "orderby": [("sum__num", False)],
-                            "row_limit": 100,
-                            "granularity": "ds",
-                            "time_range": "100 years ago : now",
-                            "timeseries_limit": 0,
-                            "timeseries_limit_metric": None,
-                            "order_desc": True,
-                            "filters": [
-                                {"col": "gender", "op": "==", "val": "boy"},
-                                {"col": "num", "op": "IS NOT NULL"},
-                                {
-                                    "col": "name",
-                                    "op": "NOT IN",
-                                    "val": ["<NULL>", '"abc"'],
-                                },
-                            ],
-                            "having": "",
-                            "where": "",
-                        }
-                    ],
-                    "result_format": "json",
-                    "result_type": "full",
-                },
-            )
-            data = json.loads(rv.data.decode("utf-8"))
-            result = data["result"]
-            excluded_key = "query"
-            assert all([excluded_key not in query for query in result])  # noqa: C419
diff --git a/tests/integration_tests/charts/data/api_tests.py b/tests/integration_tests/charts/data/api_tests.py
index dd9480c124..253b169549 100644
--- a/tests/integration_tests/charts/data/api_tests.py
+++ b/tests/integration_tests/charts/data/api_tests.py
@@ -14,25 +14,45 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-# isort:skip_file
-"""Unit tests for Superset"""
 
-import unittest
 import copy
+import time
+import unittest
 from datetime import datetime
 from io import BytesIO
-import time
 from typing import Any, Optional
 from unittest import mock
 from zipfile import ZipFile
 
-from flask import Response
+import pytest
+from flask import g, Response
 from flask.ctx import AppContext
-from tests.integration_tests.conftest import with_feature_flags
+
 from superset.charts.data.api import ChartDataRestApi
+from superset.commands.chart.data.get_data_command import ChartDataCommand
+from superset.common.chart_data import ChartDataResultFormat, ChartDataResultType
+from superset.connectors.sqla.models import SqlaTable, TableColumn
+from superset.errors import SupersetErrorType
+from superset.extensions import async_query_manager_factory, db
+from superset.models.annotations import AnnotationLayer
+from superset.models.slice import Slice
 from superset.models.sql_lab import Query
+from superset.superset_typing import AdhocColumn
+from superset.utils import json
+from superset.utils.core import (
+    AdhocMetricExpressionType,
+    AnnotationType,
+    backend,
+    ExtraFiltersReasonType,
+    get_example_default_schema,
+)
+from superset.utils.database import get_example_database, get_main_database
+from tests.common.query_context_generator import ANNOTATION_LAYERS
+from tests.integration_tests.annotation_layers.fixtures import (
+    create_annotation_layers,  # noqa: F401
+)
 from tests.integration_tests.base_tests import SupersetTestCase, test_client
-from tests.integration_tests.annotation_layers.fixtures import create_annotation_layers  # noqa: F401
+from tests.integration_tests.conftest import with_feature_flags
 from tests.integration_tests.constants import (
     ADMIN_USERNAME,
     GAMMA_NO_CSV_USERNAME,
@@ -42,37 +62,13 @@ from tests.integration_tests.fixtures.birth_names_dashboard import (
     load_birth_names_dashboard_with_slices,  # noqa: F401
     load_birth_names_data,  # noqa: F401
 )
-from tests.integration_tests.test_app import app
 from tests.integration_tests.fixtures.energy_dashboard import (
-    load_energy_table_with_slice,  # noqa: F401
     load_energy_table_data,  # noqa: F401
+    load_energy_table_with_slice,  # noqa: F401
 )
-import pytest
-from superset.models.slice import Slice
-
-from superset.commands.chart.data.get_data_command import ChartDataCommand
-from superset.connectors.sqla.models import TableColumn, SqlaTable
-from superset.errors import SupersetErrorType
-from superset.extensions import async_query_manager_factory, db
-from superset.models.annotations import AnnotationLayer
-from superset.superset_typing import AdhocColumn
-from superset.utils.core import (
-    AnnotationType,
-    backend,
-    get_example_default_schema,
-    AdhocMetricExpressionType,
-    ExtraFiltersReasonType,
-)
-from superset.utils import json
-from superset.utils.database import get_example_database, get_main_database
-from superset.common.chart_data import ChartDataResultFormat, ChartDataResultType
-
-from tests.common.query_context_generator import ANNOTATION_LAYERS
 from tests.integration_tests.fixtures.query_context import get_query_context
-
 from tests.integration_tests.test_app import app  # noqa: F811
 
-
 CHART_DATA_URI = "api/v1/chart/data"
 CHARTS_FIXTURE_COUNT = 10
 ADHOC_COLUMN_FIXTURE: AdhocColumn = {
@@ -1286,6 +1282,58 @@ class TestGetChartDataApi(BaseTestChartDataApi):
             }
         ]
 
+    @mock.patch("superset.security.manager.SupersetSecurityManager.has_guest_access")
+    @mock.patch("superset.security.manager.SupersetSecurityManager.is_guest_user")
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
+    def test_chart_data_as_guest_user(self, is_guest_user, has_guest_access):
+        """
+        Chart data API: Test response does not inlcude the SQL query for embedded
+        users.
+        """
+        g.user.rls = []
+        is_guest_user.return_value = True
+        has_guest_access.return_value = True
+
+        rv = self.client.post(CHART_DATA_URI, json=self.query_context_payload)
+        data = json.loads(rv.data.decode("utf-8"))
+        result = data["result"]
+        excluded_key = "query"
+        assert all([excluded_key not in query for query in result])  # noqa: C419
+
+    def test_chart_data_table_chart_with_time_grain_filter(self):
+        """
+        Chart data API: Test that a table chart that's not using a temporal column can
+        still receive a time grain filter (for Jinja purposes).
+        """
+        metric_def = {
+            "aggregate": None,
+            "column": None,
+            "datasourceWarning": False,
+            "expressionType": "SQL",
+            "hasCustomLabel": True,
+            "label": "test",
+            "optionName": "metric_1eef4v0fryc_m7tm09g1hu",
+            "sqlExpression": "'{{ time_grain }}'",
+        }
+        self.query_context_payload["queries"][0]["columns"] = []
+        self.query_context_payload["queries"][0]["metrics"] = [metric_def]
+        self.query_context_payload["queries"][0]["row_limit"] = 1
+        self.query_context_payload["queries"][0]["extras"] = {
+            "where": "",
+            "having": "",
+            "time_grain_sqla": "PT5M",
+        }
+        self.query_context_payload["queries"][0]["orderby"] = [[metric_def, True]]
+        del self.query_context_payload["queries"][0]["granularity"]
+        del self.query_context_payload["queries"][0]["time_range"]
+        self.query_context_payload["queries"][0]["filters"] = []
+
+        rv = self.client.post(CHART_DATA_URI, json=self.query_context_payload)
+        data = json.loads(rv.data.decode("utf-8"))
+        result = data["result"][0]
+        assert "SELECT 'PT5M' AS test" in result["query"]
+        assert result["data"] == [{"test": "PT5M"}]
+
 
 @pytest.fixture
 def physical_query_context(physical_dataset) -> dict[str, Any]:


(superset) 01/02: fix(Jinja): Emit time grain to table charts even if they don't have a temporal column

Posted by va...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

vavila pushed a commit to branch fix/time-grain-macro-on-table-chart
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 4e46ba8ca248c6cee12112b0150890106a83ad43
Author: Vitor Avila <vi...@preset.io>
AuthorDate: Wed Mar 26 08:35:05 2025 -0300

    fix(Jinja): Emit time grain to table charts even if they don't have a temporal column
---
 superset-frontend/plugins/plugin-chart-table/src/buildQuery.ts    | 5 -----
 superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx | 1 +
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/superset-frontend/plugins/plugin-chart-table/src/buildQuery.ts b/superset-frontend/plugins/plugin-chart-table/src/buildQuery.ts
index 7068ab1193..5b9cb684ed 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/buildQuery.ts
+++ b/superset-frontend/plugins/plugin-chart-table/src/buildQuery.ts
@@ -198,11 +198,6 @@ const buildQuery: BuildQuery<TableChartFormData> = (
         (ownState.currentPage ?? 0) * (ownState.pageSize ?? 0);
     }
 
-    if (!temporalColumn) {
-      // This query is not using temporal column, so it doesn't need time grain
-      extras.time_grain_sqla = undefined;
-    }
-
     let queryObject = {
       ...baseQueryObject,
       columns,
diff --git a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
index ef3a8e700c..4baf5f94a6 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
+++ b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
@@ -233,6 +233,7 @@ const config: ControlPanelConfig = {
             name: 'time_grain_sqla',
             config: {
               ...sharedControls.time_grain_sqla,
+              default: null,
               visibility: ({ controls }) => {
                 const dttmLookup = Object.fromEntries(
                   ensureIsArray(controls?.groupby?.options).map(option => [