You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by mi...@apache.org on 2026/09/18 00:45:39 UTC

(superset) branch master updated: fix(table): preserve semantic temporal column references (#44369)

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

aminghadersohi 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 20d7a3e9aea fix(table): preserve semantic temporal column references (#44369)
20d7a3e9aea is described below

commit 20d7a3e9aeade64893e18d79d4ea1b33ed539727
Author: Mike Bridge <mi...@preset.io>
AuthorDate: Thu Sep 17 18:45:33 2026 -0600

    fix(table): preserve semantic temporal column references (#44369)
    
    Co-authored-by: Mike Bridge <mi...@ext.preset.io>
---
 .../plugins/plugin-chart-table/src/buildQuery.ts   |   6 ++
 .../plugin-chart-table/test/buildQuery.test.ts     | 109 ++++++++++++++++++++-
 2 files changed, 114 insertions(+), 1 deletion(-)

diff --git a/superset-frontend/plugins/plugin-chart-table/src/buildQuery.ts b/superset-frontend/plugins/plugin-chart-table/src/buildQuery.ts
index a066f5f4e87..7e9d80b653b 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/buildQuery.ts
+++ b/superset-frontend/plugins/plugin-chart-table/src/buildQuery.ts
@@ -19,6 +19,7 @@
 import {
   AdhocColumn,
   BuildQuery,
+  DatasourceType,
   PostProcessingRule,
   QueryFormOrderBy,
   QueryMode,
@@ -196,6 +197,11 @@ export const buildQuery: BuildQuery<TableChartFormData> = (
             sqlExpression: col,
             label: col,
             expressionType: 'SQL',
+            ...(formData.datasource?.endsWith(
+              `__${DatasourceType.SemanticView}`,
+            )
+              ? { isColumnReference: true }
+              : {}),
           } as AdhocColumn;
           temporalColumnAdded = true;
           return false; // Do not include this in the output; it's added separately
diff --git a/superset-frontend/plugins/plugin-chart-table/test/buildQuery.test.ts b/superset-frontend/plugins/plugin-chart-table/test/buildQuery.test.ts
index 5cb6c2ec092..8f9e0481451 100644
--- a/superset-frontend/plugins/plugin-chart-table/test/buildQuery.test.ts
+++ b/superset-frontend/plugins/plugin-chart-table/test/buildQuery.test.ts
@@ -16,7 +16,12 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { QueryMode, TimeGranularity, VizType } from '@superset-ui/core';
+import {
+  AdhocColumn,
+  QueryMode,
+  TimeGranularity,
+  VizType,
+} from '@superset-ui/core';
 import buildQueryCached, {
   buildQuery as buildQueryUncached,
 } from '../src/buildQuery';
@@ -49,6 +54,108 @@ const extraQueryFormData: TableChartFormData = {
     } as any,
   ],
 };
+test.each([TimeGranularity.DAY, TimeGranularity.MONTH])(
+  'preserves semantic temporal references with grain %s',
+  grain => {
+    const query = buildQueryUncached({
+      ...basicFormData,
+      datasource: '2__semantic_view',
+      metrics: ['average_order_value'],
+      groupby: ['metric_time'],
+      time_grain_sqla: grain,
+      temporal_columns_lookup: { metric_time: true },
+    }).queries[0];
+
+    expect(query.columns).toEqual([
+      {
+        timeGrain: grain,
+        columnType: 'BASE_AXIS',
+        sqlExpression: 'metric_time',
+        label: 'metric_time',
+        expressionType: 'SQL',
+        isColumnReference: true,
+      },
+    ]);
+    expect(query.metrics).toEqual(['average_order_value']);
+  },
+);
+
+test('preserves semantic reference when a filter overrides the chart grain', () => {
+  const query = buildQueryUncached({
+    ...basicFormData,
+    datasource: '2__semantic_view',
+    groupby: ['metric_time'],
+    time_grain_sqla: TimeGranularity.DAY,
+    extra_form_data: { time_grain_sqla: TimeGranularity.MONTH },
+    temporal_columns_lookup: { metric_time: true },
+  }).queries[0];
+
+  expect(query.columns).toEqual([
+    {
+      timeGrain: TimeGranularity.MONTH,
+      columnType: 'BASE_AXIS',
+      sqlExpression: 'metric_time',
+      label: 'metric_time',
+      expressionType: 'SQL',
+      isColumnReference: true,
+    },
+  ]);
+});
+
+test.each(['2__semantic_view', '11__table'])(
+  'retains raw temporal columns without a grain for %s',
+  datasource => {
+    const query = buildQueryUncached({
+      ...basicFormData,
+      datasource,
+      groupby: ['metric_time'],
+      temporal_columns_lookup: { metric_time: true },
+    }).queries[0];
+
+    expect(query.columns).toEqual(['metric_time']);
+  },
+);
+
+test.each([TimeGranularity.DAY, TimeGranularity.MONTH])(
+  'preserves ordinary dataset temporal SQL with grain %s',
+  grain => {
+    const query = buildQueryUncached({
+      ...basicFormData,
+      groupby: ['metric_time'],
+      time_grain_sqla: grain,
+      temporal_columns_lookup: { metric_time: true },
+    }).queries[0];
+
+    expect(query.columns).toEqual([
+      {
+        timeGrain: grain,
+        columnType: 'BASE_AXIS',
+        sqlExpression: 'metric_time',
+        label: 'metric_time',
+        expressionType: 'SQL',
+      },
+    ]);
+  },
+);
+
+test('does not mark a semantic SQL expression as a declared column reference', () => {
+  const expression: AdhocColumn = {
+    expressionType: 'SQL',
+    sqlExpression: 'metric_time + 1',
+    label: 'shifted_time',
+  };
+  const query = buildQueryUncached({
+    ...basicFormData,
+    datasource: '2__semantic_view',
+    groupby: [expression],
+    time_grain_sqla: TimeGranularity.DAY,
+    temporal_columns_lookup: { shifted_time: true, metric_time: true },
+  }).queries[0];
+
+  expect(query.columns).toEqual([expression]);
+  expect(query.columns?.[0]).not.toHaveProperty('isColumnReference');
+});
+
 describe('plugin-chart-table', () => {
   describe('buildQuery', () => {
     test('should add post-processing and ignore duplicate metrics', () => {