This is an automated email from the ASF dual-hosted git repository.
vogievetsky pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new 338a35e69da Web console: workbench query should remain attached
(#18776)
338a35e69da is described below
commit 338a35e69da62c7970d4b1fadab914ac72ac6e2f
Author: Vadim Ogievetsky <[email protected]>
AuthorDate: Mon Dec 1 22:22:30 2025 +0000
Web console: workbench query should remain attached (#18776)
* workbench query should remain attached
* protective coding around future dates
* Filter segment timeline to for digit years only
* update deps to fix bugs
---
licenses.yaml | 4 ++--
web-console/package-lock.json | 28 +++++++++++-----------
web-console/package.json | 4 ++--
.../segment-timeline/segment-timeline.tsx | 13 ++++++----
.../workbench-query/workbench-query.ts | 10 +++++++-
.../src/views/workbench-view/workbench-view.tsx | 5 +++-
6 files changed, 40 insertions(+), 24 deletions(-)
diff --git a/licenses.yaml b/licenses.yaml
index 7a477f15e67..a3ecd134233 100644
--- a/licenses.yaml
+++ b/licenses.yaml
@@ -5550,7 +5550,7 @@ license_category: binary
module: web-console
license_name: Apache License version 2.0
copyright: Vadim Ogievetsky
-version: 1.2.1
+version: 1.2.3
---
@@ -5848,7 +5848,7 @@ license_category: binary
module: web-console
license_name: Apache License version 2.0
copyright: Imply Data
-version: 1.2.1
+version: 1.2.2
---
diff --git a/web-console/package-lock.json b/web-console/package-lock.json
index 07c2b194740..80e9d9b8307 100644
--- a/web-console/package-lock.json
+++ b/web-console/package-lock.json
@@ -19,7 +19,7 @@
"@internationalized/date": "^3.5.6",
"ace-builds": "~1.5.3",
"axios": "^1.12.0",
- "chronoshift": "^1.2.1",
+ "chronoshift": "^1.2.3",
"classnames": "^2.2.6",
"copy-to-clipboard": "^3.3.3",
"d3-array": "^3.2.4",
@@ -31,7 +31,7 @@
"d3-time-format": "^4.1.0",
"date-fns": "^2.28.0",
"dayjs": "^1.11.15",
- "druid-query-toolkit": "^1.2.1",
+ "druid-query-toolkit": "^1.2.2",
"echarts": "^5.5.1",
"file-saver": "^2.0.5",
"hjson": "^3.2.2",
@@ -6008,9 +6008,9 @@
}
},
"node_modules/chronoshift": {
- "version": "1.2.1",
- "resolved":
"https://registry.npmjs.org/chronoshift/-/chronoshift-1.2.1.tgz",
- "integrity":
"sha512-pfHPuUjGb9ECw8dcuRzY0pKO1ohO6MIDTlNvzKVPrng8RUkwT4R9v3hHnVPu4gPKTciMQEZxclYENZMLwLwF4Q==",
+ "version": "1.2.3",
+ "resolved":
"https://registry.npmjs.org/chronoshift/-/chronoshift-1.2.3.tgz",
+ "integrity":
"sha512-uCX2cz0n4Sqt5921L2jMGaSxBA9Dc9u8dBH2ZYhxvsfLbGsoKT+8cN/fqo/3/DRUnMiC72tCr/LHHXz7/wgKOw==",
"license": "Apache-2.0",
"dependencies": {
"@internationalized/date": "^3.5.6",
@@ -7290,9 +7290,9 @@
}
},
"node_modules/druid-query-toolkit": {
- "version": "1.2.1",
- "resolved":
"https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-1.2.1.tgz",
- "integrity":
"sha512-vg+r0J0cbK934QhqNaHs/Zs0nXYZSv//ZnLor71OCsP73ya60SBaN3nW3DuR+TxUGMIgZpSIgGQbG03eP7vfwA==",
+ "version": "1.2.2",
+ "resolved":
"https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-1.2.2.tgz",
+ "integrity":
"sha512-725nxfbbq/AXGvzzRi+8j5v5/jTkAMVmipGxt57ATApMs0lmTN01+BWI4TuOiyD7OrmHyoi7huEy0xfQ9QpPxg==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "^2.5.2"
@@ -22823,9 +22823,9 @@
"dev": true
},
"chronoshift": {
- "version": "1.2.1",
- "resolved":
"https://registry.npmjs.org/chronoshift/-/chronoshift-1.2.1.tgz",
- "integrity":
"sha512-pfHPuUjGb9ECw8dcuRzY0pKO1ohO6MIDTlNvzKVPrng8RUkwT4R9v3hHnVPu4gPKTciMQEZxclYENZMLwLwF4Q==",
+ "version": "1.2.3",
+ "resolved":
"https://registry.npmjs.org/chronoshift/-/chronoshift-1.2.3.tgz",
+ "integrity":
"sha512-uCX2cz0n4Sqt5921L2jMGaSxBA9Dc9u8dBH2ZYhxvsfLbGsoKT+8cN/fqo/3/DRUnMiC72tCr/LHHXz7/wgKOw==",
"requires": {
"@internationalized/date": "^3.5.6",
"tslib": "^2.8.1"
@@ -23711,9 +23711,9 @@
}
},
"druid-query-toolkit": {
- "version": "1.2.1",
- "resolved":
"https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-1.2.1.tgz",
- "integrity":
"sha512-vg+r0J0cbK934QhqNaHs/Zs0nXYZSv//ZnLor71OCsP73ya60SBaN3nW3DuR+TxUGMIgZpSIgGQbG03eP7vfwA==",
+ "version": "1.2.2",
+ "resolved":
"https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-1.2.2.tgz",
+ "integrity":
"sha512-725nxfbbq/AXGvzzRi+8j5v5/jTkAMVmipGxt57ATApMs0lmTN01+BWI4TuOiyD7OrmHyoi7huEy0xfQ9QpPxg==",
"requires": {
"tslib": "^2.5.2"
}
diff --git a/web-console/package.json b/web-console/package.json
index d8261ee0829..4db134f8caa 100644
--- a/web-console/package.json
+++ b/web-console/package.json
@@ -61,7 +61,7 @@
"@internationalized/date": "^3.5.6",
"ace-builds": "~1.5.3",
"axios": "^1.12.0",
- "chronoshift": "^1.2.1",
+ "chronoshift": "^1.2.3",
"classnames": "^2.2.6",
"copy-to-clipboard": "^3.3.3",
"d3-array": "^3.2.4",
@@ -73,7 +73,7 @@
"d3-time-format": "^4.1.0",
"date-fns": "^2.28.0",
"dayjs": "^1.11.15",
- "druid-query-toolkit": "^1.2.1",
+ "druid-query-toolkit": "^1.2.2",
"echarts": "^5.5.1",
"file-saver": "^2.0.5",
"hjson": "^3.2.2",
diff --git a/web-console/src/components/segment-timeline/segment-timeline.tsx
b/web-console/src/components/segment-timeline/segment-timeline.tsx
index d3b4721c196..b390dabcdca 100644
--- a/web-console/src/components/segment-timeline/segment-timeline.tsx
+++ b/web-console/src/components/segment-timeline/segment-timeline.tsx
@@ -34,7 +34,6 @@ import { day, Duration, Timezone } from 'chronoshift';
import { C, L, N, SqlExpression, SqlQuery } from 'druid-query-toolkit';
import { useEffect, useMemo, useState } from 'react';
-import { END_OF_TIME_DATE, START_OF_TIME_DATE } from '../../druid-models';
import type { Capabilities } from '../../helpers';
import { useQueryManager } from '../../hooks';
import {
@@ -56,6 +55,7 @@ import { SegmentBarChart } from './segment-bar-chart';
import './segment-timeline.scss';
+const FOUR_DIGIT_YEAR_LIKE = '____-%';
const DEFAULT_SHOWN_DURATION = new Duration('P1Y');
const SHOWN_DURATION_OPTIONS: Duration[] = ['P1D', 'P1W', 'P1M', 'P3M', 'P1Y',
'P5Y', 'P10Y'].map(
d => new Duration(d),
@@ -122,8 +122,8 @@ export const SegmentTimeline = function
SegmentTimeline(props: SegmentTimelinePr
const baseQuery = SqlQuery.from(N('sys').table('segments'))
.changeWhereExpression(
SqlExpression.and(
- C('start').unequal(START_OF_TIME_DATE),
- C('end').unequal(END_OF_TIME_DATE),
+ C('start').like(FOUR_DIGIT_YEAR_LIKE),
+ C('end').like(FOUR_DIGIT_YEAR_LIKE),
C('is_overshadowed').equal(0),
datasource ? C('datasource').equal(L(datasource)) : undefined,
),
@@ -141,7 +141,12 @@ export const SegmentTimeline = function
SegmentTimeline(props: SegmentTimelinePr
return getDateRange(DEFAULT_SHOWN_DURATION);
}
- queriedEnd = day.ceil(new Date(endRes[0].end), Timezone.UTC);
+ const endResDate = new Date(endRes[0].end); // Need to be protective
against a date in the far future
+ if (isNaN(endResDate.valueOf())) {
+ return getDateRange(DEFAULT_SHOWN_DURATION);
+ }
+
+ queriedEnd = day.ceil(endResDate, Timezone.UTC);
const startQuery = baseQuery
.addSelect(C('start'), { addToOrderBy: 'end', direction: 'ASC' })
diff --git a/web-console/src/druid-models/workbench-query/workbench-query.ts
b/web-console/src/druid-models/workbench-query/workbench-query.ts
index 26366f4885e..694c3b35a23 100644
--- a/web-console/src/druid-models/workbench-query/workbench-query.ts
+++ b/web-console/src/druid-models/workbench-query/workbench-query.ts
@@ -230,7 +230,7 @@ export class WorkbenchQuery {
public readonly unlimited?: boolean;
public readonly prefixLines?: number;
- public readonly parsedQuery?: SqlQuery;
+ public readonly parsedQuery?: SqlQuery; // Derived from query string
constructor(value: WorkbenchQueryValue) {
let queryString = value.queryString;
@@ -267,7 +267,9 @@ export class WorkbenchQuery {
queryContext: this.queryContext,
queryParameters: this.queryParameters,
engine: this.engine,
+ lastExecution: this.lastExecution,
unlimited: this.unlimited,
+ prefixLines: this.prefixLines,
};
}
@@ -281,6 +283,12 @@ export class WorkbenchQuery {
].join('\n\n');
}
+ public formatLastExecution(): string | undefined {
+ const { lastExecution } = this;
+ if (!lastExecution) return;
+ return `Attached to: ${lastExecution.id} (${lastExecution.engine})`;
+ }
+
public changeQueryString(queryString: string): WorkbenchQuery {
return new WorkbenchQuery({ ...this.valueOf(), queryString });
}
diff --git a/web-console/src/views/workbench-view/workbench-view.tsx
b/web-console/src/views/workbench-view/workbench-view.tsx
index fe7bf1c6a71..71ce8182885 100644
--- a/web-console/src/views/workbench-view/workbench-view.tsx
+++ b/web-console/src/views/workbench-view/workbench-view.tsx
@@ -57,6 +57,7 @@ import { ExecutionStateCache } from
'../../singletons/execution-state-cache';
import { WorkbenchRunningPromises } from
'../../singletons/workbench-running-promises';
import type { ColumnMetadata } from '../../utils';
import {
+ assemble,
deepSet,
generate8HexId,
localStorageGet,
@@ -552,7 +553,9 @@ export class WorkbenchView extends
React.PureComponent<WorkbenchViewProps, Workb
<div
key={i}
className={classNames('tab-button', { active })}
- data-tooltip={tabEntry.tabName}
+ data-tooltip={assemble(tabEntry.tabName,
tabEntry.query.formatLastExecution()).join(
+ '\n',
+ )}
>
{active ? (
<Popover
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]