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]

Reply via email to