codeant-ai-for-open-source[bot] commented on code in PR #37396:
URL: https://github.com/apache/superset/pull/37396#discussion_r3481281749


##########
superset-frontend/src/explore/components/DataTablesPane/components/useGridResultTable.tsx:
##########
@@ -17,61 +17,38 @@
  * under the License.
  */
 import { useMemo, useCallback, useRef, useState } from 'react';
-import {
-  getTimeFormatter,
-  safeHtmlSpan,
-  TimeFormats,
-  getMetricLabel,
-  QueryFormMetric,
-} from '@superset-ui/core';
-import { t } from '@apache-superset/core/translation';
+import { getTimeFormatter, safeHtmlSpan, TimeFormats } from 
'@superset-ui/core';
 import { Constants } from '@superset-ui/core/components';
 import { GenericDataType } from '@apache-superset/core/common';
 import type { IRowNode } from 'ag-grid-community';
 
 const timeFormatter = getTimeFormatter(TimeFormats.DATABASE_DATETIME);
-const CONTRIBUTION_SUFFIX = '__contribution';
 
+/**
+ * Builds Grid column definitions from query result metadata.
+ * Assumes {@link colnames}, {@link coltypes} and {@link collabels}
+ * have the same length and align. Only columns present in the first
+ * data row are included.
+ */
 export function useGridColumns(
   colnames: string[] | undefined,
   coltypes: GenericDataType[] | undefined,
+  collabels: string[] | undefined,
   data: Record<string, any>[] | undefined,
-  columnDisplayNames?: Record<string, string>,
 ) {
   return useMemo(
     () =>
       colnames && data?.length
         ? colnames
-            .filter((column: string) => Object.keys(data[0]).includes(column))
-            .map((key, index) => {
-              const colType = coltypes?.[index];
-
-              const rawHeader = columnDisplayNames?.[key] ?? key;
-              let cleaned = rawHeader;
-              let suffix = '';
-
-              if (rawHeader.endsWith(CONTRIBUTION_SUFFIX)) {
-                cleaned = rawHeader.slice(
-                  0,
-                  rawHeader.length - CONTRIBUTION_SUFFIX.length,
-                );
-                suffix = ` (${t('contribution')})`;
-              }
-
-              try {
-                const parsed = JSON.parse(cleaned);
-                if (parsed && typeof parsed === 'object') {
-                  cleaned = getMetricLabel(parsed as QueryFormMetric);
-                }
-              } catch {
-                /* not a JSON-encoded metric โ€“ keep original display name */
-              }
-
-              const cleanHeader = `${cleaned}${suffix}`;
+            .map((column, originalIndex) => [column, originalIndex] as const)
+            .filter(([column]) => Object.keys(data[0]).includes(column))

Review Comment:
   **Suggestion:** `Object.keys(data[0])` is recomputed for every column during 
filtering, creating avoidable O(nยฒ) work for wide result sets. Precompute the 
first-row key set once before filtering and check membership against that 
cached set to avoid repeated allocations and scans. [performance]
   
   <details>
   <summary><b>Severity Level:</b> Minor ๐Ÿงน</summary>
   
   ```mdx
   - โš ๏ธ Extra key scans during Explore results grid initialization.
   - โš ๏ธ Minor slowdown for wide tables with many columns.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction โœ… </b></summary>
   
   ```mdx
   1. In Explore's Samples or Results pane, a query is executed so `SamplesPane`
   
(`superset-frontend/src/explore/components/DataTablesPane/components/SamplesPane.tsx`,
   lines 89-120) or `useResultsPane`
   
(`superset-frontend/src/explore/components/DataTablesPane/components/useResultsPane.tsx`,
   lines 175-190) populates `colnames` and `data` and then calls 
`useGridColumns(colnames,
   coltypes, collabels, data)` (SamplesPane line 133, SingleQueryResultPane 
line 67).
   
   2. Inside `useGridColumns`
   
(`superset-frontend/src/explore/components/DataTablesPane/components/useGridResultTable.tsx`),
   the column names are processed starting at line 42: `colnames && 
data?.length ?
   colnames.map(...).filter(([column]) => 
Object.keys(data[0]).includes(column))...`.
   
   3. For each entry in `colnames`, the filter line 
`Object.keys(data[0]).includes(column)`
   at line 44 allocates a fresh array of keys from `data[0]` and scans it 
linearly with
   `.includes(column)`, repeating this work once per column.
   
   4. On every query rendering that uses `GridTable` with these columns (see 
`GridTable` at
   `superset-frontend/src/components/GridTable/index.tsx`, where `columns` are 
mapped into
   ag-grid `columnDefs` at lines 104-120), wide result sets with many columns 
incur repeated
   `Object.keys(data[0])` allocations and scans, introducing avoidable O(nยฒ) 
overhead in
   column construction before the grid is displayed.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=910d0c6cf7134022a03448109e68ff7a&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=910d0c6cf7134022a03448109e68ff7a&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent ๐Ÿค– </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** 
superset-frontend/src/explore/components/DataTablesPane/components/useGridResultTable.tsx
   **Line:** 44:44
   **Comment:**
        *Performance: `Object.keys(data[0])` is recomputed for every column 
during filtering, creating avoidable O(nยฒ) work for wide result sets. 
Precompute the first-row key set once before filtering and check membership 
against that cached set to avoid repeated allocations and scans.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F37396&comment_hash=97a888d16f2c93201bb3445dfbcbc4577b2e3581b7a06912ba098f9ccd42a09c&reaction=like'>๐Ÿ‘</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F37396&comment_hash=97a888d16f2c93201bb3445dfbcbc4577b2e3581b7a06912ba098f9ccd42a09c&reaction=dislike'>๐Ÿ‘Ž</a>



##########
superset-frontend/src/explore/components/DataTablesPane/components/useGridResultTable.tsx:
##########
@@ -17,61 +17,38 @@
  * under the License.
  */
 import { useMemo, useCallback, useRef, useState } from 'react';
-import {
-  getTimeFormatter,
-  safeHtmlSpan,
-  TimeFormats,
-  getMetricLabel,
-  QueryFormMetric,
-} from '@superset-ui/core';
-import { t } from '@apache-superset/core/translation';
+import { getTimeFormatter, safeHtmlSpan, TimeFormats } from 
'@superset-ui/core';
 import { Constants } from '@superset-ui/core/components';
 import { GenericDataType } from '@apache-superset/core/common';
 import type { IRowNode } from 'ag-grid-community';
 
 const timeFormatter = getTimeFormatter(TimeFormats.DATABASE_DATETIME);
-const CONTRIBUTION_SUFFIX = '__contribution';
 
+/**
+ * Builds Grid column definitions from query result metadata.
+ * Assumes {@link colnames}, {@link coltypes} and {@link collabels}
+ * have the same length and align. Only columns present in the first
+ * data row are included.
+ */
 export function useGridColumns(
   colnames: string[] | undefined,
   coltypes: GenericDataType[] | undefined,
+  collabels: string[] | undefined,
   data: Record<string, any>[] | undefined,
-  columnDisplayNames?: Record<string, string>,
 ) {
   return useMemo(
     () =>
       colnames && data?.length
         ? colnames
-            .filter((column: string) => Object.keys(data[0]).includes(column))
-            .map((key, index) => {
-              const colType = coltypes?.[index];
-
-              const rawHeader = columnDisplayNames?.[key] ?? key;
-              let cleaned = rawHeader;
-              let suffix = '';
-
-              if (rawHeader.endsWith(CONTRIBUTION_SUFFIX)) {
-                cleaned = rawHeader.slice(
-                  0,
-                  rawHeader.length - CONTRIBUTION_SUFFIX.length,
-                );
-                suffix = ` (${t('contribution')})`;
-              }
-
-              try {
-                const parsed = JSON.parse(cleaned);
-                if (parsed && typeof parsed === 'object') {
-                  cleaned = getMetricLabel(parsed as QueryFormMetric);
-                }
-              } catch {
-                /* not a JSON-encoded metric โ€“ keep original display name */
-              }
-
-              const cleanHeader = `${cleaned}${suffix}`;
+            .map((column, originalIndex) => [column, originalIndex] as const)
+            .filter(([column]) => Object.keys(data[0]).includes(column))
+            .map(([key, originalIndex]) => {
+              const colType = coltypes?.[originalIndex];
+              const headerLabel = collabels?.[originalIndex];
 
               return {
                 label: key,
-                headerName: cleanHeader,
+                headerName: headerLabel,

Review Comment:
   **Suggestion:** `headerName` is now assigned directly from `collabels`, 
which can be `undefined` when labels are missing or shorter than `colnames`. 
Other grid integrations (like the header menu's hidden-column list) read 
`headerName` directly, so those entries become blank. Set a deterministic 
fallback (`column` name) when no display label is present. [api mismatch]
   
   <details>
   <summary><b>Severity Level:</b> Major โš ๏ธ</summary>
   
   ```mdx
   - โŒ Hidden-column unhide list shows blank entries for unlabeled columns.
   - โš ๏ธ Grid table headers inconsistent when label arrays are incomplete.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction โœ… </b></summary>
   
   ```mdx
   1. Run any query in Explore that returns results so `useResultsPane` in
   
`superset-frontend/src/explore/components/DataTablesPane/components/useResultsPane.tsx`
   (lines 175-190) receives a `QueryResultInterface` with `colnames` populated 
but
   `collabels` either missing or shorter than `colnames` (no validation is 
performed before
   passing through).
   
   2. `useResultsPane` at lines 175-190 passes `result.colnames`, 
`result.collabels`, and
   `result.data` into `SingleQueryResultPane` (props `colnames`, `collabels`, 
`data`) in
   
`superset-frontend/src/explore/components/DataTablesPane/components/SingleQueryResultPane.tsx`
   (lines 49-63).
   
   3. Inside `SingleQueryResultPane`, `useGridColumns(colnames, coltypes, 
collabels, data)`
   is called at line 67, which reaches `useGridColumns` in
   
`superset-frontend/src/explore/components/DataTablesPane/components/useGridResultTable.tsx`
   (lines 33-51); here `const headerLabel = collabels?.[originalIndex];` (line 
47) can be
   `undefined` for columns without labels, and `headerName: headerLabel` (line 
51) sets the
   column definition's `headerName` to `undefined`.
   
   4. `GridTable` in `superset-frontend/src/components/GridTable/index.tsx` 
constructs
   ag-grid column definitions at lines 104-110 using `{ label, headerName, ... 
}`, and
   `HeaderMenu` in `superset-frontend/src/components/GridTable/HeaderMenu.tsx` 
builds the
   "Unhide" menu using `c.getColDef().headerName` at line 78; for columns where 
`headerName`
   was `undefined`, these menu entries render with blank labels, producing 
unnamed columns in
   the hidden-columns list and potentially in other header-driven UI.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=f2df40710d1d48918377da523b5ef2f0&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=f2df40710d1d48918377da523b5ef2f0&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent ๐Ÿค– </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** 
superset-frontend/src/explore/components/DataTablesPane/components/useGridResultTable.tsx
   **Line:** 47:51
   **Comment:**
        *Api Mismatch: `headerName` is now assigned directly from `collabels`, 
which can be `undefined` when labels are missing or shorter than `colnames`. 
Other grid integrations (like the header menu's hidden-column list) read 
`headerName` directly, so those entries become blank. Set a deterministic 
fallback (`column` name) when no display label is present.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F37396&comment_hash=8e534583a8c8c070c888a192023a72a0fcf6251d4007861b21a0b253c55fce99&reaction=like'>๐Ÿ‘</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F37396&comment_hash=8e534583a8c8c070c888a192023a72a0fcf6251d4007861b21a0b253c55fce99&reaction=dislike'>๐Ÿ‘Ž</a>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to