Skip to content

Commit 14cf8a5

Browse files
SNOW-834812 Adding connection parameter QUERY_TAG. (#916)
### Description Adding connection parameter QUERY_TAG. ### Checklist - [x] Code compiles correctly - [x] Code is formatted according to [Coding Conventions](../blob/master/CodingConventions.md) - [x] Created tests which fail without the change (if possible) - [x] All tests passing (`dotnet test`) - [x] Extended the README / documentation, if necessary - [x] Provide JIRA issue id (if possible) or GitHub issue id in PR name
1 parent 47235fb commit 14cf8a5

File tree

6 files changed

+77
-6
lines changed

6 files changed

+77
-6
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ The following table lists all valid connection properties:
135135
<br />
136136

137137
| Connection Property | Required | Comment |
138-
| ------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
138+
|--------------------------------| -------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
139139
| ACCOUNT | Yes | Your full account name might include additional segments that identify the region and cloud platform where your account is hosted |
140140
| APPLICATION | No | **_Snowflake partner use only_**: Specifies the name of a partner application to connect through .NET. The name must match the following pattern: ^\[A-Za-z](\[A-Za-z0-9.-]){1,50}$ (one letter followed by 1 to 50 letter, digit, .,- or, \_ characters). |
141141
| DB | No | |
@@ -163,10 +163,11 @@ The following table lists all valid connection properties:
163163
| PROXYPORT | Depends | The port number of the proxy server. <br/> <br/> If USEPROXY is set to `true`, you must set this parameter. <br/> <br/> This parameter was introduced in v2.0.4. |
164164
| PROXYUSER | No | The username for authenticating to the proxy server. <br/> <br/> This parameter was introduced in v2.0.4. |
165165
| PROXYPASSWORD | Depends | The password for authenticating to the proxy server. <br/> <br/> If USEPROXY is `true` and PROXYUSER is set, you must set this parameter. <br/> <br/> This parameter was introduced in v2.0.4. |
166-
| NONPROXYHOSTS | No | The list of hosts that the driver should connect to directly, bypassing the proxy server. Separate the hostnames with a pipe symbol (\|). You can also use an asterisk (`*`) as a wildcard. <br/> The host target value should fully match with any item from the proxy host list to bypass the proxy server. <br/> <br/> This parameter was introduced in v2.0.4. |
166+
| NONPROXYHOSTS | No | The list of hosts that the driver should connect to directly, bypassing the proxy server. Separate the hostnames with a pipe symbol (\|). You can also use an asterisk (`*`) as a wildcard. <br/> The host target value should fully match with any item from the proxy host list to bypass the proxy server. <br/> <br/> This parameter was introduced in v2.0.4. |
167167
| FILE_TRANSFER_MEMORY_THRESHOLD | No | The maximum number of bytes to store in memory used in order to provide a file encryption. If encrypting/decrypting file size exceeds provided value a temporary file will be created and the work will be continued in the temporary file instead of memory. <br/> If no value provided 1MB will be used as a default value (that is 1048576 bytes). <br/> It is possible to configure any integer value bigger than zero representing maximal number of bytes to reside in memory. |
168168
| CLIENT_CONFIG_FILE | No | The location of the client configuration json file. In this file you can configure easy logging feature. |
169169
| ALLOWUNDERSCORESINHOST | No | Specifies whether to allow underscores in account names. This impacts PrivateLink customers whose account names contain underscores. In this situation, you must override the default value by setting allowUnderscoresInHost to true. |
170+
| QUERY_TAG | No | Optional string that can be used to tag queries and other SQL statements executed within a connection. The tags are displayed in the output of the QUERY_HISTORY , QUERY_HISTORY_BY_* functions. |
170171

171172
<br />
172173

Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2224,6 +2224,24 @@ public void TestNativeOktaSuccess()
22242224
}
22252225
}
22262226

2227+
[Test]
2228+
public void TestConnectStringWithQueryTag()
2229+
{
2230+
using (var conn = new SnowflakeDbConnection())
2231+
{
2232+
string expectedQueryTag = "Test QUERY_TAG 12345";
2233+
conn.ConnectionString = ConnectionString + $";query_tag={expectedQueryTag}";
2234+
2235+
conn.Open();
2236+
var command = conn.CreateCommand();
2237+
// This query itself will be part of the history and will have the query tag
2238+
command.CommandText = "SELECT QUERY_TAG FROM table(information_schema.query_history_by_session())";
2239+
var queryTag = command.ExecuteScalar();
2240+
2241+
Assert.AreEqual(expectedQueryTag, queryTag);
2242+
}
2243+
}
2244+
22272245
}
22282246
}
22292247

Snowflake.Data.Tests/UnitTests/SFSessionPropertyTest.cs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,38 @@ public static IEnumerable<TestCase> ConnectionStringTestCases()
470470
{ SFSessionProperty.ALLOWUNDERSCORESINHOST, "true" }
471471
}
472472
};
473+
var testQueryTag = "Test QUERY_TAG 12345";
474+
var testCaseQueryTag = new TestCase()
475+
{
476+
ConnectionString = $"ACCOUNT={defAccount};USER={defUser};PASSWORD={defPassword};QUERY_TAG={testQueryTag}",
477+
ExpectedProperties = new SFSessionProperties()
478+
{
479+
{ SFSessionProperty.ACCOUNT, $"{defAccount}" },
480+
{ SFSessionProperty.USER, defUser },
481+
{ SFSessionProperty.HOST, $"{defAccount}.snowflakecomputing.com" },
482+
{ SFSessionProperty.AUTHENTICATOR, defAuthenticator },
483+
{ SFSessionProperty.SCHEME, defScheme },
484+
{ SFSessionProperty.CONNECTION_TIMEOUT, defConnectionTimeout },
485+
{ SFSessionProperty.PASSWORD, defPassword },
486+
{ SFSessionProperty.PORT, defPort },
487+
{ SFSessionProperty.VALIDATE_DEFAULT_PARAMETERS, "true" },
488+
{ SFSessionProperty.USEPROXY, "false" },
489+
{ SFSessionProperty.INSECUREMODE, "false" },
490+
{ SFSessionProperty.DISABLERETRY, "false" },
491+
{ SFSessionProperty.FORCERETRYON404, "false" },
492+
{ SFSessionProperty.CLIENT_SESSION_KEEP_ALIVE, "false" },
493+
{ SFSessionProperty.FORCEPARSEERROR, "false" },
494+
{ SFSessionProperty.BROWSER_RESPONSE_TIMEOUT, defBrowserResponseTime },
495+
{ SFSessionProperty.RETRY_TIMEOUT, defRetryTimeout },
496+
{ SFSessionProperty.MAXHTTPRETRIES, defMaxHttpRetries },
497+
{ SFSessionProperty.INCLUDERETRYREASON, defIncludeRetryReason },
498+
{ SFSessionProperty.DISABLEQUERYCONTEXTCACHE, defDisableQueryContextCache },
499+
{ SFSessionProperty.DISABLE_CONSOLE_LOGIN, defDisableConsoleLogin },
500+
{ SFSessionProperty.ALLOWUNDERSCORESINHOST, "false" },
501+
{ SFSessionProperty.QUERY_TAG, testQueryTag }
502+
}
503+
};
504+
473505
return new TestCase[]
474506
{
475507
simpleTestCase,
@@ -482,7 +514,8 @@ public static IEnumerable<TestCase> ConnectionStringTestCases()
482514
testCaseWithDisableConsoleLogin,
483515
testCaseComplicatedAccountName,
484516
testCaseUnderscoredAccountName,
485-
testCaseUnderscoredAccountNameWithEnabledAllowUnderscores
517+
testCaseUnderscoredAccountNameWithEnabledAllowUnderscores,
518+
testCaseQueryTag
486519
};
487520
}
488521

Snowflake.Data/Core/SFStatement.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,9 @@ class SFStatement
110110
private const string SF_QUERY_RESULT_PATH = "/queries/{0}/result";
111111

112112
private const string SF_PARAM_MULTI_STATEMENT_COUNT = "MULTI_STATEMENT_COUNT";
113-
113+
114+
private const string SF_PARAM_QUERY_TAG = "QUERY_TAG";
115+
114116
private const int SF_QUERY_IN_PROGRESS = 333333;
115117

116118
private const int SF_QUERY_IN_PROGRESS_ASYNC = 333334;
@@ -141,10 +143,13 @@ class SFStatement
141143
// the query id of the last query
142144
string _lastQueryId = null;
143145

146+
private string _queryTag = null;
147+
144148
internal SFStatement(SFSession session)
145149
{
146150
SfSession = session;
147151
_restRequester = session.restRequester;
152+
_queryTag = session._queryTag;
148153
}
149154

150155
internal string GetBindStage() => _bindStage;
@@ -195,7 +200,16 @@ private SFRestRequest BuildQueryRequest(string sql, Dictionary<string, BindingDT
195200
// remove it from parameter bindings so it won't break
196201
// parameter binding feature
197202
bindings.Remove(SF_PARAM_MULTI_STATEMENT_COUNT);
198-
}
203+
}
204+
205+
if (_queryTag != null)
206+
{
207+
if (bodyParameters == null)
208+
{
209+
bodyParameters = new Dictionary<string, string>();
210+
}
211+
bodyParameters[SF_PARAM_QUERY_TAG] = _queryTag;
212+
}
199213

200214
QueryRequest postBody = new QueryRequest();
201215
postBody.sqlText = sql;

Snowflake.Data/Core/Session/SFSession.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ public class SFSession
8383

8484
internal int _maxRetryTimeout;
8585

86+
internal String _queryTag;
87+
8688
internal void ProcessLoginResponse(LoginResponse authnResponse)
8789
{
8890
if (authnResponse.success)
@@ -168,6 +170,7 @@ internal SFSession(
168170
connectionTimeout = extractedProperties.TimeoutDuration();
169171
properties.TryGetValue(SFSessionProperty.CLIENT_CONFIG_FILE, out var easyLoggingConfigFile);
170172
_easyLoggingStarter.Init(easyLoggingConfigFile);
173+
properties.TryGetValue(SFSessionProperty.QUERY_TAG, out _queryTag);
171174
_maxRetryCount = extractedProperties.maxHttpRetries;
172175
_maxRetryTimeout = extractedProperties.retryTimeout;
173176
}

Snowflake.Data/Core/Session/SFSessionProperty.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ internal enum SFSessionProperty
9494
[SFSessionPropertyAttr(required = false, defaultValue = "true")]
9595
DISABLE_CONSOLE_LOGIN,
9696
[SFSessionPropertyAttr(required = false, defaultValue = "false")]
97-
ALLOWUNDERSCORESINHOST
97+
ALLOWUNDERSCORESINHOST,
98+
[SFSessionPropertyAttr(required = false)]
99+
QUERY_TAG
98100
}
99101

100102
class SFSessionPropertyAttr : Attribute

0 commit comments

Comments
 (0)