Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SNOW-834812 Adding connection parameter QUERY_TAG. #916

Merged
merged 1 commit into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ The following table lists all valid connection properties:
<br />

| Connection Property | Required | Comment |
| ------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|--------------------------------| -------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ACCOUNT | Yes | Your full account name might include additional segments that identify the region and cloud platform where your account is hosted |
| 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). |
| DB | No | |
Expand Down Expand Up @@ -163,10 +163,11 @@ The following table lists all valid connection properties:
| 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. |
| PROXYUSER | No | The username for authenticating to the proxy server. <br/> <br/> This parameter was introduced in v2.0.4. |
| 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. |
| 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. |
| 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. |
| 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. |
| CLIENT_CONFIG_FILE | No | The location of the client configuration json file. In this file you can configure easy logging feature. |
| 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. |
| 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. |

<br />

Expand Down
18 changes: 18 additions & 0 deletions Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2224,6 +2224,24 @@ public void TestNativeOktaSuccess()
}
}

[Test]
public void TestConnectStringWithQueryTag()
{
using (var conn = new SnowflakeDbConnection())
{
string expectedQueryTag = "Test QUERY_TAG 12345";
conn.ConnectionString = ConnectionString + $";query_tag={expectedQueryTag}";

conn.Open();
var command = conn.CreateCommand();
// This query itself will be part of the history and will have the query tag
command.CommandText = "SELECT QUERY_TAG FROM table(information_schema.query_history_by_session())";
var queryTag = command.ExecuteScalar();

Assert.AreEqual(expectedQueryTag, queryTag);
}
}

}
}

Expand Down
35 changes: 34 additions & 1 deletion Snowflake.Data.Tests/UnitTests/SFSessionPropertyTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,38 @@ public static IEnumerable<TestCase> ConnectionStringTestCases()
{ SFSessionProperty.ALLOWUNDERSCORESINHOST, "true" }
}
};
var testQueryTag = "Test QUERY_TAG 12345";
var testCaseQueryTag = new TestCase()
{
ConnectionString = $"ACCOUNT={defAccount};USER={defUser};PASSWORD={defPassword};QUERY_TAG={testQueryTag}",
ExpectedProperties = new SFSessionProperties()
{
{ SFSessionProperty.ACCOUNT, $"{defAccount}" },
{ SFSessionProperty.USER, defUser },
{ SFSessionProperty.HOST, $"{defAccount}.snowflakecomputing.com" },
{ SFSessionProperty.AUTHENTICATOR, defAuthenticator },
{ SFSessionProperty.SCHEME, defScheme },
{ SFSessionProperty.CONNECTION_TIMEOUT, defConnectionTimeout },
{ SFSessionProperty.PASSWORD, defPassword },
{ SFSessionProperty.PORT, defPort },
{ SFSessionProperty.VALIDATE_DEFAULT_PARAMETERS, "true" },
{ SFSessionProperty.USEPROXY, "false" },
{ SFSessionProperty.INSECUREMODE, "false" },
{ SFSessionProperty.DISABLERETRY, "false" },
{ SFSessionProperty.FORCERETRYON404, "false" },
{ SFSessionProperty.CLIENT_SESSION_KEEP_ALIVE, "false" },
{ SFSessionProperty.FORCEPARSEERROR, "false" },
{ SFSessionProperty.BROWSER_RESPONSE_TIMEOUT, defBrowserResponseTime },
{ SFSessionProperty.RETRY_TIMEOUT, defRetryTimeout },
{ SFSessionProperty.MAXHTTPRETRIES, defMaxHttpRetries },
{ SFSessionProperty.INCLUDERETRYREASON, defIncludeRetryReason },
{ SFSessionProperty.DISABLEQUERYCONTEXTCACHE, defDisableQueryContextCache },
{ SFSessionProperty.DISABLE_CONSOLE_LOGIN, defDisableConsoleLogin },
{ SFSessionProperty.ALLOWUNDERSCORESINHOST, "false" },
{ SFSessionProperty.QUERY_TAG, testQueryTag }
}
};

return new TestCase[]
{
simpleTestCase,
Expand All @@ -482,7 +514,8 @@ public static IEnumerable<TestCase> ConnectionStringTestCases()
testCaseWithDisableConsoleLogin,
testCaseComplicatedAccountName,
testCaseUnderscoredAccountName,
testCaseUnderscoredAccountNameWithEnabledAllowUnderscores
testCaseUnderscoredAccountNameWithEnabledAllowUnderscores,
testCaseQueryTag
};
}

Expand Down
18 changes: 16 additions & 2 deletions Snowflake.Data/Core/SFStatement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ class SFStatement
private const string SF_QUERY_RESULT_PATH = "/queries/{0}/result";

private const string SF_PARAM_MULTI_STATEMENT_COUNT = "MULTI_STATEMENT_COUNT";


private const string SF_PARAM_QUERY_TAG = "QUERY_TAG";

private const int SF_QUERY_IN_PROGRESS = 333333;

private const int SF_QUERY_IN_PROGRESS_ASYNC = 333334;
Expand Down Expand Up @@ -141,10 +143,13 @@ class SFStatement
// the query id of the last query
string _lastQueryId = null;

private string _queryTag = null;

internal SFStatement(SFSession session)
{
SfSession = session;
_restRequester = session.restRequester;
_queryTag = session._queryTag;
}

internal string GetBindStage() => _bindStage;
Expand Down Expand Up @@ -195,7 +200,16 @@ private SFRestRequest BuildQueryRequest(string sql, Dictionary<string, BindingDT
// remove it from parameter bindings so it won't break
// parameter binding feature
bindings.Remove(SF_PARAM_MULTI_STATEMENT_COUNT);
}
}

if (_queryTag != null)
{
if (bodyParameters == null)
{
bodyParameters = new Dictionary<string, string>();
}
bodyParameters[SF_PARAM_QUERY_TAG] = _queryTag;
}

QueryRequest postBody = new QueryRequest();
postBody.sqlText = sql;
Expand Down
3 changes: 3 additions & 0 deletions Snowflake.Data/Core/Session/SFSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ public class SFSession

internal int _maxRetryTimeout;

internal String _queryTag;

internal void ProcessLoginResponse(LoginResponse authnResponse)
{
if (authnResponse.success)
Expand Down Expand Up @@ -168,6 +170,7 @@ internal SFSession(
connectionTimeout = extractedProperties.TimeoutDuration();
properties.TryGetValue(SFSessionProperty.CLIENT_CONFIG_FILE, out var easyLoggingConfigFile);
_easyLoggingStarter.Init(easyLoggingConfigFile);
properties.TryGetValue(SFSessionProperty.QUERY_TAG, out _queryTag);
_maxRetryCount = extractedProperties.maxHttpRetries;
_maxRetryTimeout = extractedProperties.retryTimeout;
}
Expand Down
4 changes: 3 additions & 1 deletion Snowflake.Data/Core/Session/SFSessionProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ internal enum SFSessionProperty
[SFSessionPropertyAttr(required = false, defaultValue = "true")]
DISABLE_CONSOLE_LOGIN,
[SFSessionPropertyAttr(required = false, defaultValue = "false")]
ALLOWUNDERSCORESINHOST
ALLOWUNDERSCORESINHOST,
[SFSessionPropertyAttr(required = false)]
QUERY_TAG
}

class SFSessionPropertyAttr : Attribute
Expand Down
Loading