From b6e5c794fb80f3ade89a3d47f4c08c66445698be Mon Sep 17 00:00:00 2001 From: Sam Bove Date: Mon, 24 Nov 2025 13:17:21 -0600 Subject: [PATCH] add abortSignal support to query() --- src/index.ts | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/index.ts b/src/index.ts index 1928aaf3..a334903f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -260,7 +260,7 @@ class Client { * @param {Query | string} query - The query to execute. * @returns A promise that resolves to a QueryResult object. */ - async query(query: Query | string): Promise> { + async query(query: Query | string, signal?: AbortSignal): Promise> { const req = typeof query === 'string' ? {query} : query; const headers: RawAxiosRequestHeaders = { [TRINO_USER_HEADER]: req.user, @@ -277,10 +277,15 @@ class Client { url: '/v1/statement', data: req.query, headers: cleanHeaders(headers), + // Intentionally not passing the AbortSignal on this initial request to avoid a race condition where + // trino starts running the query and we never send a cancel for it }; - return this.request(requestConfig).then( - result => new Iterator(new QueryIterator(this, result)) - ); + const createQueryRes = await this.request(requestConfig); + signal?.addEventListener('abort', () => { + this.cancel(createQueryRes.id); + }); + + return new Iterator(new QueryIterator(this, createQueryRes, signal)); } /** @@ -363,7 +368,8 @@ export class Iterator implements AsyncIterableIterator { export class QueryIterator implements AsyncIterableIterator { constructor( private readonly client: Client, - private queryResult: QueryResult + private queryResult: QueryResult, + private readonly signal?: AbortSignal, ) {} [Symbol.asyncIterator](): AsyncIterableIterator { @@ -390,6 +396,7 @@ export class QueryIterator implements AsyncIterableIterator { this.queryResult = await this.client.request({ url: this.queryResult.nextUri, + signal: this.signal, }); const data = this.queryResult.data ?? []; @@ -418,8 +425,8 @@ export class Trino { * @param query - The query to execute. * @returns A QueryIterator object. */ - async query(query: Query | string): Promise> { - return this.client.query(query); + async query(query: Query | string, signal?: AbortSignal): Promise> { + return this.client.query(query, signal); } /**