From aeace28ccbde8e3e65ddfc28650d981bf340666e Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Mon, 5 Aug 2024 13:21:51 -0700 Subject: [PATCH] Web console: Add columnMapping information to the Explain dialog (#16598) * Add columnMapping information in the Explain dialog * use arrow char --- web-console/src/utils/druid-query.ts | 22 +++++++++++++++---- .../explain-dialog.spec.tsx.snap | 6 ++--- .../explain-dialog/explain-dialog.spec.tsx | 22 +++++++++++++++++++ .../explain-dialog/explain-dialog.tsx | 4 ++-- 4 files changed, 45 insertions(+), 9 deletions(-) diff --git a/web-console/src/utils/druid-query.ts b/web-console/src/utils/druid-query.ts index 154103297044..fba63b946000 100644 --- a/web-console/src/utils/druid-query.ts +++ b/web-console/src/utils/druid-query.ts @@ -23,7 +23,7 @@ import axios from 'axios'; import { Api } from '../singletons'; import type { RowColumn } from './general'; -import { assemble } from './general'; +import { assemble, lookupBy } from './general'; const CANCELED_MESSAGE = 'Query canceled by user.'; @@ -345,10 +345,24 @@ export async function queryDruidSql( export interface QueryExplanation { query: any; signature: { name: string; type: string }[]; + columnMappings: { + queryColumn: string; + outputColumn: string; + }[]; } -export function formatSignature(queryExplanation: QueryExplanation): string { - return queryExplanation.signature - .map(({ name, type }) => `${C.optionalQuotes(name)}::${type}`) +export function formatColumnMappingsAndSignature(queryExplanation: QueryExplanation): string { + const columnNameToType = lookupBy( + queryExplanation.signature, + c => c.name, + c => c.type, + ); + return queryExplanation.columnMappings + .map(({ queryColumn, outputColumn }) => { + const type = columnNameToType[queryColumn]; + return `${C.optionalQuotes(queryColumn)}${type ? `::${type}` : ''}→${C.optionalQuotes( + outputColumn, + )}`; + }) .join(', '); } diff --git a/web-console/src/views/workbench-view/explain-dialog/__snapshots__/explain-dialog.spec.tsx.snap b/web-console/src/views/workbench-view/explain-dialog/__snapshots__/explain-dialog.spec.tsx.snap index e2a5a6c3ded5..806f209ef638 100644 --- a/web-console/src/views/workbench-view/explain-dialog/__snapshots__/explain-dialog.spec.tsx.snap +++ b/web-console/src/views/workbench-view/explain-dialog/__snapshots__/explain-dialog.spec.tsx.snap @@ -185,7 +185,7 @@ exports[`ExplainDialog matches snapshot on some data (many queries) 1`] = ` label="Signature" > @@ -287,7 +287,7 @@ exports[`ExplainDialog matches snapshot on some data (many queries) 1`] = ` label="Signature" > @@ -473,7 +473,7 @@ exports[`ExplainDialog matches snapshot on some data (one query) 1`] = ` label="Signature" > diff --git a/web-console/src/views/workbench-view/explain-dialog/explain-dialog.spec.tsx b/web-console/src/views/workbench-view/explain-dialog/explain-dialog.spec.tsx index 0d6a878d424c..bf3b1ece6ed8 100644 --- a/web-console/src/views/workbench-view/explain-dialog/explain-dialog.spec.tsx +++ b/web-console/src/views/workbench-view/explain-dialog/explain-dialog.spec.tsx @@ -160,6 +160,16 @@ describe('ExplainDialog', () => { type: 'LONG', }, ], + columnMappings: [ + { + queryColumn: 'd0', + outputColumn: 'channel', + }, + { + queryColumn: 'a0', + outputColumn: 'Count', + }, + ], }, ], }); @@ -199,6 +209,12 @@ describe('ExplainDialog', () => { type: 'STRING', }, ], + columnMappings: [ + { + queryColumn: 'channel', + outputColumn: 'channel', + }, + ], }, { query: { @@ -234,6 +250,12 @@ describe('ExplainDialog', () => { type: 'STRING', }, ], + columnMappings: [ + { + queryColumn: 'channel', + outputColumn: 'channel', + }, + ], }, ], }); diff --git a/web-console/src/views/workbench-view/explain-dialog/explain-dialog.tsx b/web-console/src/views/workbench-view/explain-dialog/explain-dialog.tsx index 4bab7e7bfb05..7f01436babbd 100644 --- a/web-console/src/views/workbench-view/explain-dialog/explain-dialog.tsx +++ b/web-console/src/views/workbench-view/explain-dialog/explain-dialog.tsx @@ -40,7 +40,7 @@ import { Api } from '../../../singletons'; import type { QueryExplanation } from '../../../utils'; import { deepGet, - formatSignature, + formatColumnMappingsAndSignature, getDruidErrorMessage, nonEmptyArray, queryDruidSql, @@ -141,7 +141,7 @@ export const ExplainDialog = React.memo(function ExplainDialog(props: ExplainDia /> - + {openQueryLabel && (