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

(superset) branch fix/postgresql-interval-chart-rendering created (now 44c9cc95fe)

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

rusackas pushed a change to branch fix/postgresql-interval-chart-rendering
in repository https://gitbox.apache.org/repos/asf/superset.git


      at 44c9cc95fe fix(charts): handle PostgreSQL INTERVAL type in bar and pie charts

This branch includes the following new commits:

     new 44c9cc95fe fix(charts): handle PostgreSQL INTERVAL type in bar and pie charts

The 1 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.



(superset) 01/01: fix(charts): handle PostgreSQL INTERVAL type in bar and pie charts

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

rusackas pushed a commit to branch fix/postgresql-interval-chart-rendering
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 44c9cc95fe8b23f015fe536d980d79f45de2aac5
Author: Evan Rusackas <ev...@rusackas.com>
AuthorDate: Fri Aug 1 14:52:24 2025 -0700

    fix(charts): handle PostgreSQL INTERVAL type in bar and pie charts
    
    PostgreSQL INTERVAL types were causing bar and pie charts to fail rendering when used as metrics. This fix converts INTERVAL values (timedelta objects) to numeric seconds so they can be properly displayed in charts.
    
    🤖 Generated with [Claude Code](https://claude.ai/code)
    
    Co-Authored-By: Claude <no...@anthropic.com>
---
 superset/db_engine_specs/postgres.py              | 13 +++++++++++--
 tests/unit_tests/db_engine_specs/test_postgres.py | 19 +++++++++++++++++--
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/superset/db_engine_specs/postgres.py b/superset/db_engine_specs/postgres.py
index b86172cb3a..bb1628310d 100644
--- a/superset/db_engine_specs/postgres.py
+++ b/superset/db_engine_specs/postgres.py
@@ -21,10 +21,10 @@ import logging
 import re
 from datetime import datetime
 from re import Pattern
-from typing import Any, TYPE_CHECKING
+from typing import Any, Callable, TYPE_CHECKING
 
 from flask_babel import gettext as __
-from sqlalchemy.dialects.postgresql import DOUBLE_PRECISION, ENUM, JSON
+from sqlalchemy.dialects.postgresql import DOUBLE_PRECISION, ENUM, INTERVAL, JSON
 from sqlalchemy.dialects.postgresql.base import PGInspector
 from sqlalchemy.engine.reflection import Inspector
 from sqlalchemy.engine.url import URL
@@ -238,8 +238,17 @@ class PostgresEngineSpec(BasicParametersMixin, PostgresBaseEngineSpec):
             ENUM(),
             GenericDataType.STRING,
         ),
+        (
+            re.compile(r"^interval", re.IGNORECASE),
+            INTERVAL(),
+            GenericDataType.NUMERIC,
+        ),
     )
 
+    column_type_mutators: dict[Any, Callable[[Any], Any]] = {
+        INTERVAL: lambda v: v.total_seconds() if hasattr(v, "total_seconds") else v,
+    }
+
     @classmethod
     def get_schema_from_engine_params(
         cls,
diff --git a/tests/unit_tests/db_engine_specs/test_postgres.py b/tests/unit_tests/db_engine_specs/test_postgres.py
index 290aa3575c..3fb3e7f674 100644
--- a/tests/unit_tests/db_engine_specs/test_postgres.py
+++ b/tests/unit_tests/db_engine_specs/test_postgres.py
@@ -15,13 +15,13 @@
 # specific language governing permissions and limitations
 # under the License.
 
-from datetime import datetime
+from datetime import datetime, timedelta
 from typing import Any, Optional
 
 import pytest
 from pytest_mock import MockerFixture
 from sqlalchemy import column, types
-from sqlalchemy.dialects.postgresql import DOUBLE_PRECISION, ENUM, JSON
+from sqlalchemy.dialects.postgresql import DOUBLE_PRECISION, ENUM, INTERVAL, JSON
 from sqlalchemy.engine.interfaces import Dialect
 from sqlalchemy.engine.url import make_url
 
@@ -280,3 +280,18 @@ SELECT * \nFROM my_schema.my_table
  LIMIT :param_1
     """.strip()
     )
+
+
+def test_interval_type_mutator() -> None:
+    """
+    DB Eng Specs (postgres): Test INTERVAL type mutator
+    """
+    # Test timedelta conversion
+    td = timedelta(days=1, hours=2, minutes=30, seconds=45)
+    mutator = spec.column_type_mutators[INTERVAL]
+    assert mutator(td) == 95445.0  # Total seconds: 1*86400 + 2*3600 + 30*60 + 45
+
+    # Test that non-timedelta values pass through unchanged
+    assert mutator("not a timedelta") == "not a timedelta"
+    assert mutator(12345) == 12345
+    assert mutator(None) is None