@@ -607,6 +607,94 @@ func TestConn_executeStatement_QueryTags(t *testing.T) {
607607 assert .NoError (t , err )
608608 assert .Equal (t , "flag" , capturedReq .ConfOverlay ["query_tags" ])
609609 })
610+
611+ t .Run ("session-level and statement-level query tags coexist" , func (t * testing.T ) {
612+ // Session-level tags are sent via TOpenSessionReq.Configuration at connect time.
613+ // Statement-level tags are sent via TExecuteStatementReq.ConfOverlay at query time.
614+ // They are independent fields on different requests, so both should work together.
615+
616+ var capturedOpenReq * cli_service.TOpenSessionReq
617+ var capturedExecReq * cli_service.TExecuteStatementReq
618+
619+ testClient := & client.TestClient {
620+ FnOpenSession : func (ctx context.Context , req * cli_service.TOpenSessionReq ) (* cli_service.TOpenSessionResp , error ) {
621+ capturedOpenReq = req
622+ return & cli_service.TOpenSessionResp {
623+ Status : & cli_service.TStatus {
624+ StatusCode : cli_service .TStatusCode_SUCCESS_STATUS ,
625+ },
626+ SessionHandle : & cli_service.TSessionHandle {
627+ SessionId : & cli_service.THandleIdentifier {
628+ GUID : []byte {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 },
629+ },
630+ },
631+ }, nil
632+ },
633+ FnExecuteStatement : func (ctx context.Context , req * cli_service.TExecuteStatementReq ) (* cli_service.TExecuteStatementResp , error ) {
634+ capturedExecReq = req
635+ return & cli_service.TExecuteStatementResp {
636+ Status : & cli_service.TStatus {
637+ StatusCode : cli_service .TStatusCode_SUCCESS_STATUS ,
638+ },
639+ OperationHandle : & cli_service.TOperationHandle {
640+ OperationId : & cli_service.THandleIdentifier {
641+ GUID : []byte {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 },
642+ Secret : []byte ("secret" ),
643+ },
644+ },
645+ DirectResults : & cli_service.TSparkDirectResults {
646+ OperationStatus : & cli_service.TGetOperationStatusResp {
647+ Status : & cli_service.TStatus {
648+ StatusCode : cli_service .TStatusCode_SUCCESS_STATUS ,
649+ },
650+ OperationState : cli_service .TOperationStatePtr (cli_service .TOperationState_FINISHED_STATE ),
651+ },
652+ },
653+ }, nil
654+ },
655+ }
656+
657+ // Simulate what connector.Connect() does: pass session params to OpenSession
658+ sessionParams := map [string ]string {
659+ "QUERY_TAGS" : "team:platform,env:prod" ,
660+ "ansi_mode" : "false" ,
661+ }
662+ protocolVersion := int64 (cli_service .TProtocolVersion_SPARK_CLI_SERVICE_PROTOCOL_V8 )
663+ session , err := testClient .OpenSession (context .Background (), & cli_service.TOpenSessionReq {
664+ ClientProtocolI64 : & protocolVersion ,
665+ Configuration : sessionParams ,
666+ })
667+ assert .NoError (t , err )
668+
669+ // Verify session-level tags were sent in OpenSession
670+ assert .Equal (t , "team:platform,env:prod" , capturedOpenReq .Configuration ["QUERY_TAGS" ])
671+ assert .Equal (t , "false" , capturedOpenReq .Configuration ["ansi_mode" ])
672+
673+ // Create conn with session that has session-level tags
674+ cfg := config .WithDefaults ()
675+ cfg .SessionParams = sessionParams
676+ testConn := & conn {
677+ session : session ,
678+ client : testClient ,
679+ cfg : cfg ,
680+ }
681+
682+ // Execute with statement-level tags
683+ ctx := driverctx .NewContextWithQueryTags (context .Background (), map [string ]string {
684+ "job" : "nightly-etl" ,
685+ })
686+ _ , err = testConn .executeStatement (ctx , "SELECT 1" , nil )
687+ assert .NoError (t , err )
688+
689+ // Statement-level tags should be in ConfOverlay
690+ assert .Equal (t , "job:nightly-etl" , capturedExecReq .ConfOverlay ["query_tags" ])
691+
692+ // ConfOverlay should ONLY have query_tags, not session params
693+ _ , hasAnsiMode := capturedExecReq .ConfOverlay ["ansi_mode" ]
694+ assert .False (t , hasAnsiMode , "session params should not leak into ConfOverlay" )
695+ _ , hasSessionQueryTags := capturedExecReq .ConfOverlay ["QUERY_TAGS" ]
696+ assert .False (t , hasSessionQueryTags , "session-level QUERY_TAGS should not be in ConfOverlay" )
697+ })
610698}
611699
612700func TestConn_pollOperation (t * testing.T ) {
0 commit comments