From 84adb9255e9c9ddce6f87f8086fc7a251f2b3e64 Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Mon, 8 Jan 2024 12:05:12 -0800 Subject: [PATCH] Web console: Fix spec conversion, expose failOnEmptyInsert (#15627) * Spec converter should dedupe the columns * Add "Fail on empty insert" setting to QueryContext toggles --- .../druid-models/query-context/query-context.tsx | 16 ++++++++++++++++ .../__snapshots__/spec-conversion.spec.ts.snap | 1 + web-console/src/helpers/spec-conversion.spec.ts | 5 +++++ web-console/src/helpers/spec-conversion.ts | 7 +++++-- .../views/workbench-view/run-panel/run-panel.tsx | 12 ++++++++++++ 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/web-console/src/druid-models/query-context/query-context.tsx b/web-console/src/druid-models/query-context/query-context.tsx index c0445038a60..50036f63fbd 100644 --- a/web-console/src/druid-models/query-context/query-context.tsx +++ b/web-console/src/druid-models/query-context/query-context.tsx @@ -146,6 +146,22 @@ export function changeTaskAssigment( : deepDelete(context, 'taskAssignment'); } +// failOnEmptyInsert + +export function getFailOnEmptyInsert(context: QueryContext): boolean | undefined { + const { failOnEmptyInsert } = context; + return typeof failOnEmptyInsert === 'boolean' ? failOnEmptyInsert : undefined; +} + +export function changeFailOnEmptyInsert( + context: QueryContext, + failOnEmptyInsert: boolean | undefined, +): QueryContext { + return typeof failOnEmptyInsert === 'boolean' + ? deepSet(context, 'failOnEmptyInsert', failOnEmptyInsert) + : deepDelete(context, 'failOnEmptyInsert'); +} + // finalizeAggregations export function getFinalizeAggregations(context: QueryContext): boolean | undefined { diff --git a/web-console/src/helpers/__snapshots__/spec-conversion.spec.ts.snap b/web-console/src/helpers/__snapshots__/spec-conversion.spec.ts.snap index a70842ee1c5..b6dceb034a6 100644 --- a/web-console/src/helpers/__snapshots__/spec-conversion.spec.ts.snap +++ b/web-console/src/helpers/__snapshots__/spec-conversion.spec.ts.snap @@ -58,6 +58,7 @@ SELECT COUNT(*) AS "count", SUM("added") AS "sum_added", SUM("commentLength") AS "sum_commentLength", + MAX("commentLength") AS "max_commentLength", SUM("delta") AS "sum_delta", SUM("deltaBucket") AS "sum_deltaBucket", SUM("deleted") AS "sum_deleted", diff --git a/web-console/src/helpers/spec-conversion.spec.ts b/web-console/src/helpers/spec-conversion.spec.ts index fa72378b155..154bfacbb1b 100644 --- a/web-console/src/helpers/spec-conversion.spec.ts +++ b/web-console/src/helpers/spec-conversion.spec.ts @@ -192,6 +192,11 @@ describe('spec conversion', () => { type: 'longSum', fieldName: 'commentLength', }, + { + name: 'max_commentLength', + type: 'longMax', + fieldName: 'commentLength', + }, { name: 'sum_delta', type: 'longSum', diff --git a/web-console/src/helpers/spec-conversion.ts b/web-console/src/helpers/spec-conversion.ts index c277ec430fc..9b67dac4cf6 100644 --- a/web-console/src/helpers/spec-conversion.ts +++ b/web-console/src/helpers/spec-conversion.ts @@ -18,6 +18,7 @@ import { C, + dedupe, L, RefName, SqlColumnDeclaration, @@ -120,6 +121,8 @@ export function convertSpecToSql(spec: any): QueryWithContext { ); } + columnDeclarations = dedupe(columnDeclarations, d => d.getColumnName()); + const transforms: Transform[] = deepGet(spec, 'spec.dataSchema.transformSpec.transforms') || []; if (!Array.isArray(transforms)) { throw new Error(`spec.dataSchema.transformSpec.transforms is not an array`); @@ -346,14 +349,14 @@ export function convertSpecToSql(spec: any): QueryWithContext { function convertQueryGranularity( timeExpression: string, - queryGranularity: { type: string } | string | undefined, + queryGranularity: { type: unknown } | string | undefined, ) { if (!queryGranularity) return timeExpression; const effectiveQueryGranularity = typeof queryGranularity === 'string' ? queryGranularity - : typeof queryGranularity.type === 'string' + : typeof queryGranularity?.type === 'string' ? queryGranularity.type : undefined; diff --git a/web-console/src/views/workbench-view/run-panel/run-panel.tsx b/web-console/src/views/workbench-view/run-panel/run-panel.tsx index 0bcd0a3d898..51e18ad4136 100644 --- a/web-console/src/views/workbench-view/run-panel/run-panel.tsx +++ b/web-console/src/views/workbench-view/run-panel/run-panel.tsx @@ -38,6 +38,7 @@ import { IndexSpecDialog } from '../../../dialogs/index-spec-dialog/index-spec-d import type { DruidEngine, IndexSpec, QueryContext, WorkbenchQuery } from '../../../druid-models'; import { changeDurableShuffleStorage, + changeFailOnEmptyInsert, changeFinalizeAggregations, changeGroupByEnableMultiValueUnnesting, changeMaxParseExceptions, @@ -47,6 +48,7 @@ import { changeUseCache, changeWaitUntilSegmentsLoad, getDurableShuffleStorage, + getFailOnEmptyInsert, getFinalizeAggregations, getGroupByEnableMultiValueUnnesting, getMaxParseExceptions, @@ -111,6 +113,7 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) { const queryParameters = query.queryParameters; const maxParseExceptions = getMaxParseExceptions(queryContext); + const failOnEmptyInsert = getFailOnEmptyInsert(queryContext); const finalizeAggregations = getFinalizeAggregations(queryContext); const waitUntilSegmentsLoad = getWaitUntilSegmentsLoad(queryContext); const groupByEnableMultiValueUnnesting = getGroupByEnableMultiValueUnnesting(queryContext); @@ -305,6 +308,15 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) { /> ))} + + changeQueryContext(changeFailOnEmptyInsert(queryContext, v)) + } + />