This is an automated email from the ASF dual-hosted git repository.
capistrant pushed a commit to branch 34.0.0
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/34.0.0 by this push:
new 065ac55d140 Web console: fix maxTask selector with SET statements
(#18221) (#18268)
065ac55d140 is described below
commit 065ac55d14004cbe0d9f51dbe99e9af20262a500
Author: Lucas Capistrant <[email protected]>
AuthorDate: Thu Jul 17 09:11:53 2025 -0500
Web console: fix maxTask selector with SET statements (#18221) (#18268)
* fix maxTask selector with SET statements
* add tests
* cleanup
Co-authored-by: Vadim Ogievetsky <[email protected]>
---
licenses.yaml | 2 +-
web-console/package-lock.json | 14 +--
web-console/package.json | 2 +-
.../workbench-query/workbench-query.spec.ts | 125 +++++++++++++++++++++
.../workbench-query/workbench-query.ts | 10 +-
.../views/workbench-view/query-tab/query-tab.tsx | 2 +-
6 files changed, 141 insertions(+), 14 deletions(-)
diff --git a/licenses.yaml b/licenses.yaml
index d43dc184f57..40c6b0f0027 100644
--- a/licenses.yaml
+++ b/licenses.yaml
@@ -5787,7 +5787,7 @@ license_category: binary
module: web-console
license_name: Apache License version 2.0
copyright: Imply Data
-version: 1.1.4
+version: 1.1.5
---
diff --git a/web-console/package-lock.json b/web-console/package-lock.json
index 77bf3e7d9d6..d0ed8d1be80 100644
--- a/web-console/package-lock.json
+++ b/web-console/package-lock.json
@@ -30,7 +30,7 @@
"d3-shape": "^3.2.0",
"d3-time-format": "^4.1.0",
"date-fns": "^2.28.0",
- "druid-query-toolkit": "^1.1.4",
+ "druid-query-toolkit": "^1.1.5",
"echarts": "^5.5.1",
"file-saver": "^2.0.5",
"hjson": "^3.2.2",
@@ -7151,9 +7151,9 @@
}
},
"node_modules/druid-query-toolkit": {
- "version": "1.1.4",
- "resolved":
"https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-1.1.4.tgz",
- "integrity":
"sha512-yppL7d/5PRUojDtOviU/0gK+wI5OP43FptRIFbZ6Trm8ngGEkLeqnLLT5rqGPkcPB23OvppcU9jKtdicWg2KhQ==",
+ "version": "1.1.5",
+ "resolved":
"https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-1.1.5.tgz",
+ "integrity":
"sha512-ZI9DG4C44jUZcfN3M/1YRF46q9Wkq8QkYvuWV/d+kQKLr6wVPDU16WtzGhsKbEZZaqWKmKuALag5fWqjApMXAQ==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "^2.5.2"
@@ -23502,9 +23502,9 @@
}
},
"druid-query-toolkit": {
- "version": "1.1.4",
- "resolved":
"https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-1.1.4.tgz",
- "integrity":
"sha512-yppL7d/5PRUojDtOviU/0gK+wI5OP43FptRIFbZ6Trm8ngGEkLeqnLLT5rqGPkcPB23OvppcU9jKtdicWg2KhQ==",
+ "version": "1.1.5",
+ "resolved":
"https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-1.1.5.tgz",
+ "integrity":
"sha512-ZI9DG4C44jUZcfN3M/1YRF46q9Wkq8QkYvuWV/d+kQKLr6wVPDU16WtzGhsKbEZZaqWKmKuALag5fWqjApMXAQ==",
"requires": {
"tslib": "^2.5.2"
}
diff --git a/web-console/package.json b/web-console/package.json
index f4542a4eca7..c332197da19 100644
--- a/web-console/package.json
+++ b/web-console/package.json
@@ -72,7 +72,7 @@
"d3-shape": "^3.2.0",
"d3-time-format": "^4.1.0",
"date-fns": "^2.28.0",
- "druid-query-toolkit": "^1.1.4",
+ "druid-query-toolkit": "^1.1.5",
"echarts": "^5.5.1",
"file-saver": "^2.0.5",
"hjson": "^3.2.2",
diff --git
a/web-console/src/druid-models/workbench-query/workbench-query.spec.ts
b/web-console/src/druid-models/workbench-query/workbench-query.spec.ts
index ec224cf29aa..9c732e7a15a 100644
--- a/web-console/src/druid-models/workbench-query/workbench-query.spec.ts
+++ b/web-console/src/druid-models/workbench-query/workbench-query.spec.ts
@@ -686,4 +686,129 @@ describe('WorkbenchQuery', () => {
expect(extractedContext).toEqual(complexContext);
});
});
+
+ describe('#getMaxNumTasks', () => {
+ it('returns maxNumTasks from query string context for SQL queries with SET
statements', () => {
+ const queryWithSet = sane`
+ SET maxNumTasks = 5;
+ SELECT * FROM wikipedia
+ `;
+
+ const workbenchQuery =
WorkbenchQuery.blank().changeQueryString(queryWithSet);
+
+ expect(workbenchQuery.getMaxNumTasks()).toBe(5);
+ });
+
+ it('returns maxNumTasks from queryContext when no SET statements exist',
() => {
+ const workbenchQuery = WorkbenchQuery.blank()
+ .changeQueryString('SELECT * FROM wikipedia')
+ .changeQueryContext({ maxNumTasks: 3 });
+
+ expect(workbenchQuery.getMaxNumTasks()).toBe(3);
+ });
+
+ it('prioritizes query string context over queryContext', () => {
+ const queryWithSet = sane`
+ SET maxNumTasks = 8;
+ SELECT * FROM wikipedia
+ `;
+
+ const workbenchQuery = WorkbenchQuery.blank()
+ .changeQueryString(queryWithSet)
+ .changeQueryContext({ maxNumTasks: 3 });
+
+ expect(workbenchQuery.getMaxNumTasks()).toBe(8);
+ });
+
+ it('returns undefined when maxNumTasks is not set anywhere', () => {
+ const workbenchQuery = WorkbenchQuery.blank().changeQueryString('SELECT
* FROM wikipedia');
+
+ expect(workbenchQuery.getMaxNumTasks()).toBeUndefined();
+ });
+
+ it('returns maxNumTasks from queryContext for JSON queries', () => {
+ const jsonQuery = '{"queryType": "topN", "dataSource": "test"}';
+ const workbenchQuery = WorkbenchQuery.blank()
+ .changeQueryString(jsonQuery)
+ .changeQueryContext({ maxNumTasks: 10 });
+
+ expect(workbenchQuery.getMaxNumTasks()).toBe(10);
+ });
+ });
+
+ describe('#setMaxNumTasksIfUnset', () => {
+ it('sets maxNumTasks when it is not already set', () => {
+ const workbenchQuery = WorkbenchQuery.blank().changeQueryString('SELECT
* FROM wikipedia');
+
+ const updatedQuery = workbenchQuery.setMaxNumTasksIfUnset(5);
+
+ expect(updatedQuery.getMaxNumTasks()).toBe(5);
+ expect(updatedQuery.queryContext.maxNumTasks).toBe(5);
+ });
+
+ it('does not override existing maxNumTasks in queryContext', () => {
+ const workbenchQuery = WorkbenchQuery.blank()
+ .changeQueryString('SELECT * FROM wikipedia')
+ .changeQueryContext({ maxNumTasks: 3 });
+
+ const updatedQuery = workbenchQuery.setMaxNumTasksIfUnset(10);
+
+ expect(updatedQuery).toBe(workbenchQuery); // Should return same instance
+ expect(updatedQuery.getMaxNumTasks()).toBe(3);
+ });
+
+ it('does not override maxNumTasks from SET statements', () => {
+ const queryWithSet = sane`
+ SET maxNumTasks = 7;
+ SELECT * FROM wikipedia
+ `;
+
+ const workbenchQuery =
WorkbenchQuery.blank().changeQueryString(queryWithSet);
+
+ const updatedQuery = workbenchQuery.setMaxNumTasksIfUnset(10);
+
+ expect(updatedQuery).toBe(workbenchQuery); // Should return same instance
+ expect(updatedQuery.getMaxNumTasks()).toBe(7);
+ });
+
+ it('enforces minimum value of 2', () => {
+ const workbenchQuery = WorkbenchQuery.blank().changeQueryString('SELECT
* FROM wikipedia');
+
+ const updatedQuery = workbenchQuery.setMaxNumTasksIfUnset(1);
+
+ expect(updatedQuery.getMaxNumTasks()).toBe(2);
+ });
+
+ it('returns same instance when passed undefined', () => {
+ const workbenchQuery = WorkbenchQuery.blank().changeQueryString('SELECT
* FROM wikipedia');
+
+ const updatedQuery = workbenchQuery.setMaxNumTasksIfUnset(undefined);
+
+ expect(updatedQuery).toBe(workbenchQuery);
+ expect(updatedQuery.getMaxNumTasks()).toBeUndefined();
+ });
+
+ it('returns same instance when passed 0', () => {
+ const workbenchQuery = WorkbenchQuery.blank().changeQueryString('SELECT
* FROM wikipedia');
+
+ const updatedQuery = workbenchQuery.setMaxNumTasksIfUnset(0);
+
+ expect(updatedQuery).toBe(workbenchQuery);
+ expect(updatedQuery.getMaxNumTasks()).toBeUndefined();
+ });
+
+ it('preserves other queryContext properties when setting maxNumTasks', ()
=> {
+ const workbenchQuery = WorkbenchQuery.blank()
+ .changeQueryString('SELECT * FROM wikipedia')
+ .changeQueryContext({ useCache: false, timeout: 30000 });
+
+ const updatedQuery = workbenchQuery.setMaxNumTasksIfUnset(5);
+
+ expect(updatedQuery.queryContext).toEqual({
+ useCache: false,
+ timeout: 30000,
+ maxNumTasks: 5,
+ });
+ });
+ });
});
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 c71d95d9074..26366f4885e 100644
--- a/web-console/src/druid-models/workbench-query/workbench-query.ts
+++ b/web-console/src/druid-models/workbench-query/workbench-query.ts
@@ -454,11 +454,13 @@ export class WorkbenchQuery {
return ret.changeQueryString(newQueryString);
}
- public setMaxNumTasksIfUnset(maxNumTasks: number | undefined):
WorkbenchQuery {
- const { queryContext } = this;
- if (typeof queryContext.maxNumTasks === 'number' || !maxNumTasks) return
this;
+ public getMaxNumTasks(): number | undefined {
+ return this.getQueryStringContext().maxNumTasks ??
this.queryContext.maxNumTasks;
+ }
- return this.changeQueryContext({ ...queryContext, maxNumTasks:
Math.max(maxNumTasks, 2) });
+ public setMaxNumTasksIfUnset(maxNumTasks: number | undefined):
WorkbenchQuery {
+ if (!maxNumTasks || typeof this.getMaxNumTasks() === 'number') return this;
+ return this.changeQueryContext({ ...this.queryContext, maxNumTasks:
Math.max(maxNumTasks, 2) });
}
public getApiQuery(makeQueryId: () => string = uuidv4): {
diff --git a/web-console/src/views/workbench-view/query-tab/query-tab.tsx
b/web-console/src/views/workbench-view/query-tab/query-tab.tsx
index bd3a13e671e..ee15ec0ceae 100644
--- a/web-console/src/views/workbench-view/query-tab/query-tab.tsx
+++ b/web-console/src/views/workbench-view/query-tab/query-tab.tsx
@@ -436,7 +436,7 @@ export const QueryTab = React.memo(function QueryTab(props:
QueryTabProps) {
const capacityInfo = await getClusterCapacity?.();
- const effectiveMaxNumTasks = effectiveQuery.queryContext.maxNumTasks ??
2;
+ const effectiveMaxNumTasks = effectiveQuery.getMaxNumTasks() ?? 2;
if (capacityInfo && capacityInfo.availableTaskSlots <
effectiveMaxNumTasks) {
setAlertElement(
<CapacityAlert
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]