diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ae39301..7b6c3df4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## New features - Added an option to override the credentials for a particular `query`/`command`/`exec`/`insert` request via the `BaseQueryParams.auth` setting; when set, the credentials will be taken from there instead of the username/password provided during the client instantiation. +- Allow overriding `session_id` per query ([@holi0317](https://github.com/Holi0317), [#271](https://github.com/ClickHouse/clickhouse-js/issues/271)). # 1.0.2 (Common, Node.js, Web) diff --git a/packages/client-common/__tests__/integration/exec.test.ts b/packages/client-common/__tests__/integration/exec.test.ts index e32848ea..5052b498 100644 --- a/packages/client-common/__tests__/integration/exec.test.ts +++ b/packages/client-common/__tests__/integration/exec.test.ts @@ -51,6 +51,19 @@ describe('exec', () => { }) }) + it('should use session_id override', async () => { + const session_id = guid() + + // Temporary tables cannot be used without a session + const tableName = `temp_table_${guid()}` + await expectAsync( + runExec({ + query: `CREATE TEMPORARY TABLE ${tableName} (val Int32)`, + session_id, + }), + ).toBeResolved() + }) + it('does not swallow ClickHouse error', async () => { const { ddl, tableName } = getDDL() const commands = async () => { @@ -92,6 +105,25 @@ describe('exec', () => { }), ).toBeResolved() }) + + it('should use override session_id', async () => { + const session_id = `test-session-override-${guid()}` + + const tableName = `temp_table_${guid()}` + await expectAsync( + sessionClient.exec({ + query: `CREATE TEMPORARY TABLE ${tableName} (val Int32)`, + }), + ).toBeResolved() + + // This should fail with table already exist if override logic is not working + await expectAsync( + sessionClient.exec({ + query: `CREATE TEMPORARY TABLE ${tableName} (val Int32)`, + session_id, + }), + ).toBeResolved() + }) }) it('can specify a parameterized query', async () => { diff --git a/packages/client-common/src/client.ts b/packages/client-common/src/client.ts index 8cb7aaff..f2305980 100644 --- a/packages/client-common/src/client.ts +++ b/packages/client-common/src/client.ts @@ -26,6 +26,8 @@ export interface BaseQueryParams { /** A specific `query_id` that will be sent with this request. * If it is not set, a random identifier will be generated automatically by the client. */ query_id?: string + /** A specific `session_id` for this query + * If it is not set, the client's session_id will be used. */ session_id?: string /** When defined, overrides the credentials from the {@link BaseClickHouseClientConfigOptions.username} * and {@link BaseClickHouseClientConfigOptions.password} settings for this particular request. @@ -163,9 +165,10 @@ export class ClickHouseClient { ): Promise> { const format = params.format ?? 'JSON' const query = formatQuery(params.query, format) + const queryParams = this.withClientQueryParams(params) const { stream, query_id } = await this.connection.query({ query, - ...this.withClientQueryParams(params), + ...queryParams, }) return this.makeResultSet(stream, format, query_id, (err) => { this.logWriter.error({ @@ -173,7 +176,7 @@ export class ClickHouseClient { module: 'Client', message: 'Error while processing the ResultSet.', args: { - session_id: this.sessionId, + session_id: queryParams.session_id, query, query_id, }, @@ -260,6 +263,7 @@ export class ClickHouseClient { query_params: params.query_params, abort_signal: params.abort_signal, query_id: params.query_id, + session_id: params.session_id ?? this.sessionId, auth: params.auth, } }