From d56d31b252dc5e648f6fcd7b042298df6d18d1ae Mon Sep 17 00:00:00 2001 From: Brian Donovan Date: Thu, 2 Apr 2026 13:19:57 -0700 Subject: [PATCH] fix(chart): word cloud secondary sort prevents Druid TopN optimization when sort_by_metric enabled When sort_by_metric is true, buildQuery unconditionally appended a secondary ORDER BY series ASC alongside the metric sort. On Druid, any multi-column ORDER BY prevents the native TopN query optimization, forcing a full GroupBy scan that can cause dramatic slowdowns and timeouts on high-cardinality dimensions. Make the series sort mutually exclusive with sort_by_metric, and add test coverage for both sort behaviors. Fixes #39072 --- .../src/plugin/buildQuery.ts | 3 +- .../test/buildQuery.test.ts | 57 +++++++++++++++---- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/superset-frontend/plugins/plugin-chart-word-cloud/src/plugin/buildQuery.ts b/superset-frontend/plugins/plugin-chart-word-cloud/src/plugin/buildQuery.ts index faf816d5eca..8179bec91c8 100644 --- a/superset-frontend/plugins/plugin-chart-word-cloud/src/plugin/buildQuery.ts +++ b/superset-frontend/plugins/plugin-chart-word-cloud/src/plugin/buildQuery.ts @@ -28,8 +28,7 @@ export default function buildQuery(formData: WordCloudFormData) { if (sort_by_metric && metric) { orderby.push([metric, false]); - } - if (series) { + } else if (series) { orderby.push([series, true]); } diff --git a/superset-frontend/plugins/plugin-chart-word-cloud/test/buildQuery.test.ts b/superset-frontend/plugins/plugin-chart-word-cloud/test/buildQuery.test.ts index c83f8993e81..c99d87fb12e 100644 --- a/superset-frontend/plugins/plugin-chart-word-cloud/test/buildQuery.test.ts +++ b/superset-frontend/plugins/plugin-chart-word-cloud/test/buildQuery.test.ts @@ -21,17 +21,52 @@ import { VizType } from '@superset-ui/core'; import { WordCloudFormData } from '../src'; import buildQuery from '../src/plugin/buildQuery'; -describe('WordCloud buildQuery', () => { - const formData: WordCloudFormData = { - datasource: '5__table', - granularity_sqla: 'ds', - series: 'foo', - viz_type: VizType.WordCloud, - }; +const basicFormData: WordCloudFormData = { + datasource: '5__table', + granularity_sqla: 'ds', + series: 'foo', + viz_type: VizType.WordCloud, +}; - test('should build columns from series in form data', () => { - const queryContext = buildQuery(formData); - const [query] = queryContext.queries; - expect(query.columns).toEqual(['foo']); +describe('plugin-chart-word-cloud', () => { + describe('buildQuery', () => { + test('should build columns from series in form data', () => { + const queryContext = buildQuery(basicFormData); + const [query] = queryContext.queries; + expect(query.columns).toEqual(['foo']); + }); + + test('should order by series ASC when sort_by_metric is false', () => { + const queryContext = buildQuery({ + ...basicFormData, + metric: 'count', + sort_by_metric: false, + row_limit: 100, + }); + const [query] = queryContext.queries; + expect(query.orderby).toEqual([['foo', true]]); + }); + + test('should order by metric DESC only when sort_by_metric is true', () => { + const queryContext = buildQuery({ + ...basicFormData, + metric: 'count', + sort_by_metric: true, + row_limit: 100, + }); + const [query] = queryContext.queries; + expect(query.orderby).toEqual([['count', false]]); + }); + + test('should not include secondary series sort when sort_by_metric is true', () => { + const queryContext = buildQuery({ + ...basicFormData, + metric: 'count', + sort_by_metric: true, + row_limit: 100, + }); + const [query] = queryContext.queries; + expect(query.orderby).toHaveLength(1); + }); }); });