Skip to content

Commit 9f98112

Browse files
committed
Support setting session level tags as dict
1 parent 57b4450 commit 9f98112

4 files changed

Lines changed: 67 additions & 2 deletions

File tree

examples/session_params.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@ client
1010
.connect({ host, path, token })
1111
.then(async (client) => {
1212
const session = await client.openSession({
13+
queryTags: {
14+
team: 'engineering',
15+
test: 'session-params',
16+
driver: 'node',
17+
},
1318
configuration: {
14-
QUERY_TAGS: 'team:engineering,test:session-params,driver:node',
1519
ansi_mode: 'false',
1620
},
1721
});

lib/DBSQLClient.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import HttpConnection from './connection/connections/HttpConnection';
1616
import IConnectionOptions from './connection/contracts/IConnectionOptions';
1717
import Status from './dto/Status';
1818
import HiveDriverError from './errors/HiveDriverError';
19-
import { buildUserAgentString, definedOrError } from './utils';
19+
import { buildUserAgentString, definedOrError, serializeQueryTags } from './utils';
2020
import PlainHttpAuthentication from './connection/auth/PlainHttpAuthentication';
2121
import DatabricksOAuth, { OAuthFlow } from './connection/auth/DatabricksOAuth';
2222
import {
@@ -292,6 +292,16 @@ export default class DBSQLClient extends EventEmitter implements IDBSQLClient, I
292292
configuration['spark.sql.thriftserver.metadata.metricview.enabled'] = 'true';
293293
}
294294

295+
// Serialize queryTags dict and set in configuration; takes precedence over configuration.QUERY_TAGS
296+
if (request.queryTags !== undefined) {
297+
const serialized = serializeQueryTags(request.queryTags);
298+
if (serialized) {
299+
configuration['QUERY_TAGS'] = serialized;
300+
} else {
301+
delete configuration['QUERY_TAGS'];
302+
}
303+
}
304+
295305
const response = await this.driver.openSession({
296306
client_protocol_i64: new Int64(TProtocolVersion.SPARK_CLI_SERVICE_PROTOCOL_V8),
297307
...getInitialNamespaceOptions(request.initialCatalog, request.initialSchema),

lib/contracts/IDBSQLClient.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ export interface OpenSessionRequest {
6060
initialCatalog?: string;
6161
initialSchema?: string;
6262
configuration?: { [key: string]: string };
63+
/**
64+
* Session-level query tags as key-value pairs. Serialized and passed via session configuration
65+
* as "QUERY_TAGS". Values may be null/undefined to include a key without a value.
66+
* If both queryTags and configuration.QUERY_TAGS are specified, queryTags takes precedence.
67+
*/
68+
queryTags?: Record<string, string | null | undefined>;
6369
}
6470

6571
export default interface IDBSQLClient {

tests/unit/DBSQLClient.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,4 +636,49 @@ describe('DBSQLClient.enableMetricViewMetadata', () => {
636636
'spark.sql.thriftserver.metadata.metricview.enabled': 'true',
637637
});
638638
});
639+
640+
it('should serialize queryTags dict and set in session configuration', async () => {
641+
const client = new DBSQLClient();
642+
const thriftClient = new ThriftClientStub();
643+
sinon.stub(client, 'getClient').returns(Promise.resolve(thriftClient));
644+
645+
await client.openSession({
646+
queryTags: { team: 'data-eng', project: 'etl' },
647+
});
648+
649+
expect(thriftClient.openSessionReq?.configuration).to.deep.equal({
650+
QUERY_TAGS: 'team:data-eng,project:etl',
651+
});
652+
});
653+
654+
it('should let queryTags take precedence over configuration.QUERY_TAGS', async () => {
655+
const client = new DBSQLClient();
656+
const thriftClient = new ThriftClientStub();
657+
sinon.stub(client, 'getClient').returns(Promise.resolve(thriftClient));
658+
659+
await client.openSession({
660+
queryTags: { team: 'new-team' },
661+
configuration: { QUERY_TAGS: 'team:old-team,other:value', ansi_mode: 'true' },
662+
});
663+
664+
expect(thriftClient.openSessionReq?.configuration).to.deep.equal({
665+
QUERY_TAGS: 'team:new-team',
666+
ansi_mode: 'true',
667+
});
668+
});
669+
670+
it('should remove QUERY_TAGS from configuration when queryTags is empty', async () => {
671+
const client = new DBSQLClient();
672+
const thriftClient = new ThriftClientStub();
673+
sinon.stub(client, 'getClient').returns(Promise.resolve(thriftClient));
674+
675+
await client.openSession({
676+
queryTags: {},
677+
configuration: { QUERY_TAGS: 'team:old-team', ansi_mode: 'true' },
678+
});
679+
680+
expect(thriftClient.openSessionReq?.configuration).to.deep.equal({
681+
ansi_mode: 'true',
682+
});
683+
});
639684
});

0 commit comments

Comments
 (0)