This is an automated email from the ASF dual-hosted git repository. rusackas pushed a commit to branch fix/issue-39587-followup in repository https://gitbox.apache.org/repos/asf/superset.git
commit 5cb1752e65e2cbf76743f18931752ec62f728cc4 Author: rusackas <[email protected]> AuthorDate: Sat Jul 25 17:26:37 2026 -0700 fix(table): pick totals query positionally so all_records percent metrics don't shift it `buildQuery` inserts an extra query ahead of the totals query in `queriesData` when `percent_metric_calculation` is set to "all_records", so the fixed-index destructuring in `transformProps` grabbed that query instead of the actual totals query, leaving the summary row with the wrong (and unformatted) values. Fixes #39587 --- .../plugin-chart-table/src/transformProps.ts | 19 +++++++- .../plugin-chart-table/test/TableChart.test.tsx | 55 ++++++++++++++++++++++ 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts b/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts index ee3ee09bab7..e8a15d4a67d 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts +++ b/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts @@ -712,12 +712,27 @@ const transformProps = ( let totalQuery; let rowCount; if (serverPagination) { - [baseQuery, countQuery, totalQuery] = queriesData; + [baseQuery, countQuery] = queriesData; rowCount = (countQuery?.data?.[0]?.rowcount as number) ?? 0; } else { - [baseQuery, totalQuery] = queriesData; + [baseQuery] = queriesData; rowCount = baseQuery?.rowcount ?? 0; } + // `buildQuery` may prepend an extra query (used to compute percent metrics + // against the entire result set when `percent_metric_calculation` is set to + // `all_records`) before the totals query. Since the totals query, when + // present, is always the last entry in `queriesData`, look it up positionally + // from the end rather than assuming a fixed index. The minimum number of + // queries expected without a totals query is 1 (base query), or 2 when + // server pagination is enabled (base query + row count query). + const minQueriesWithoutTotals = serverPagination ? 2 : 1; + if ( + showTotals && + queryMode === QueryMode.Aggregate && + queriesData.length > minQueriesWithoutTotals + ) { + totalQuery = queriesData[queriesData.length - 1]; + } const data = processDataRecords(baseQuery?.data, columns); const comparisonData = processComparisonDataRecords( baseQuery?.data, diff --git a/superset-frontend/plugins/plugin-chart-table/test/TableChart.test.tsx b/superset-frontend/plugins/plugin-chart-table/test/TableChart.test.tsx index 8d1c6a62c13..b8a2dda2fa2 100644 --- a/superset-frontend/plugins/plugin-chart-table/test/TableChart.test.tsx +++ b/superset-frontend/plugins/plugin-chart-table/test/TableChart.test.tsx @@ -436,6 +436,61 @@ describe('plugin-chart-table', () => { expect(timestampColumn).toBeDefined(); }); + test( + 'should read the totals row from the correct query when percent metrics ' + + 'use the "all records" calculation mode', + () => { + // When `percent_metric_calculation` is `all_records`, buildQuery adds an + // extra query (used to compute percentages against the entire result set) + // *before* the totals query in `queriesData`. Verify totals are still + // sourced from the actual totals query and not this preceding query. + const props = { + ...testData.basic, + rawFormData: { + ...testData.basic.rawFormData, + query_mode: QueryMode.Aggregate, + metrics: ['sum__num'], + percent_metrics: ['count'], + percent_metric_calculation: 'all_records', + show_totals: true, + column_config: { + sum__num: { d3NumberFormat: '.0%' }, + }, + }, + queriesData: [ + { + ...testData.basic.queriesData[0], + colnames: ['name', 'sum__num', '%count'], + coltypes: [ + GenericDataType.String, + GenericDataType.Numeric, + GenericDataType.Numeric, + ], + data: [{ name: 'Michael', sum__num: 0.1, '%count': 0.05 }], + }, + // extra "all records" query used only to compute percent metrics + { + ...testData.basic.queriesData[0], + colnames: ['count'], + coltypes: [GenericDataType.Numeric], + data: [{ count: 999 }], + }, + // actual totals query + { + ...testData.basic.queriesData[0], + colnames: ['sum__num'], + coltypes: [GenericDataType.Numeric], + data: [{ sum__num: 0.27 }], + }, + ], + }; + + const transformedProps = transformProps(props); + + expect(transformedProps.totals).toEqual({ sum__num: 0.27 }); + }, + ); + describe('TableChart', () => { test('render basic data', () => { render(
