Skip to content

Commit

Permalink
Merge branch 'master' into pool/SNOW-860872-connection-pool
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-knozderko committed Jun 7, 2024
2 parents a4349d7 + db8e4d5 commit 4c8d516
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 57 deletions.
38 changes: 35 additions & 3 deletions Snowflake.Data.Tests/IntegrationTests/SFDbCommandIT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1621,7 +1621,7 @@ public void TestGetResultsOfUnknownQueryIdWithConfiguredRetry()
conn.Close();
}
}

[Test]
public void TestSetQueryTagOverridesConnectionString()
{
Expand All @@ -1630,16 +1630,48 @@ public void TestSetQueryTagOverridesConnectionString()
string expectedQueryTag = "Test QUERY_TAG 12345";
string connectQueryTag = "Test 123";
conn.ConnectionString = ConnectionString + $";query_tag={connectQueryTag}";

conn.Open();
var command = conn.CreateCommand();
((SnowflakeDbCommand)command).QueryTag = expectedQueryTag;
// 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);
}
}

[Test]
public void TestCommandWithCommentEmbedded()
{
using (var conn = new SnowflakeDbConnection(ConnectionString))
{
conn.Open();
var command = conn.CreateCommand();

command.CommandText = "\r\nselect '--'\r\n";
var reader = command.ExecuteReader();

Assert.IsTrue(reader.Read());
Assert.AreEqual("--", reader.GetString(0));
}
}

[Test]
public async Task TestCommandWithCommentEmbeddedAsync()
{
using (var conn = new SnowflakeDbConnection(ConnectionString))
{
conn.Open();
var command = conn.CreateCommand();

command.CommandText = "\r\nselect '--'\r\n";
var reader = await command.ExecuteReaderAsync().ConfigureAwait(false);

Assert.IsTrue(await reader.ReadAsync().ConfigureAwait(false));
Assert.AreEqual("--", reader.GetString(0));
}
}
}
}
9 changes: 9 additions & 0 deletions Snowflake.Data.Tests/Snowflake.Data.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<LangVersion>9</LangVersion>
<DefineConstants>$(SEQUENTIAL_ENV)</DefineConstants>
<AssemblyOriginatorKeyFile>..\sign\publicKey.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<DelaySign>true</DelaySign>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JunitXml.TestLogger" Version="3.1.12" />
Expand All @@ -37,6 +40,12 @@
<Reference Include="System.Net.Http.WebRequest" />
</ItemGroup>

<ItemGroup>
<None Include="..\sign\publicKey.snk">
<Link>publicKey.snk</Link>
</None>
</ItemGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>full</DebugType>
<DebugSymbols>True</DebugSymbols>
Expand Down
44 changes: 16 additions & 28 deletions Snowflake.Data.Tests/UnitTests/SFStatementTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,10 @@ public void TestServiceName()
[Test]
public void TestTrimSqlBlockComment()
{
Mock.MockRestSessionExpiredInQueryExec restRequester = new Mock.MockRestSessionExpiredInQueryExec();
SFSession sfSession = new SFSession("account=test;user=test;password=test", null, restRequester);
sfSession.Open();
SFStatement statement = new SFStatement(sfSession);
SFBaseResultSet resultSet = statement.Execute(0, "/*comment*/select 1/*comment*/", null, false, false);
Assert.AreEqual(true, resultSet.Next());
Assert.AreEqual("1", resultSet.GetString(0));
const string SqlSource = "/*comment*/select 1/*comment*/";
const string SqlExpected = "select 1";

Assert.AreEqual(SqlExpected, SFStatement.TrimSql(SqlSource));
}

/// <summary>
Expand All @@ -85,13 +82,10 @@ public void TestTrimSqlBlockComment()
[Test]
public void TestTrimSqlBlockCommentMultiline()
{
Mock.MockRestSessionExpiredInQueryExec restRequester = new Mock.MockRestSessionExpiredInQueryExec();
SFSession sfSession = new SFSession("account=test;user=test;password=test", null, restRequester);
sfSession.Open();
SFStatement statement = new SFStatement(sfSession);
SFBaseResultSet resultSet = statement.Execute(0, "/*comment\r\ncomment*/select 1/*comment\r\ncomment*/", null, false, false);
Assert.AreEqual(true, resultSet.Next());
Assert.AreEqual("1", resultSet.GetString(0));
const string SqlSource = "/*comment\r\ncomment*/select 1/*comment\r\ncomment*/";
const string SqlExpected = "select 1";

Assert.AreEqual(SqlExpected, SFStatement.TrimSql(SqlSource));
}

/// <summary>
Expand All @@ -100,13 +94,10 @@ public void TestTrimSqlBlockCommentMultiline()
[Test]
public void TestTrimSqlLineComment()
{
Mock.MockRestSessionExpiredInQueryExec restRequester = new Mock.MockRestSessionExpiredInQueryExec();
SFSession sfSession = new SFSession("account=test;user=test;password=test", null, restRequester);
sfSession.Open();
SFStatement statement = new SFStatement(sfSession);
SFBaseResultSet resultSet = statement.Execute(0, "--comment\r\nselect 1\r\n--comment", null, false, false);
Assert.AreEqual(true, resultSet.Next());
Assert.AreEqual("1", resultSet.GetString(0));
const string SqlSource = "--comment\r\nselect 1\r\n--comment";
const string SqlExpected = "select 1\r\n--comment";

Assert.AreEqual(SqlExpected, SFStatement.TrimSql(SqlSource));
}

/// <summary>
Expand All @@ -115,13 +106,10 @@ public void TestTrimSqlLineComment()
[Test]
public void TestTrimSqlLineCommentWithClosingNewline()
{
Mock.MockRestSessionExpiredInQueryExec restRequester = new Mock.MockRestSessionExpiredInQueryExec();
SFSession sfSession = new SFSession("account=test;user=test;password=test", null, restRequester);
sfSession.Open();
SFStatement statement = new SFStatement(sfSession);
SFBaseResultSet resultSet = statement.Execute(0, "--comment\r\nselect 1\r\n--comment\r\n", null, false, false);
Assert.AreEqual(true, resultSet.Next());
Assert.AreEqual("1", resultSet.GetString(0));
const string SqlSource = "--comment\r\nselect 1\r\n--comment\r\n";
const string SqlExpected = "select 1";

Assert.AreEqual(SqlExpected, SFStatement.TrimSql(SqlSource));
}

[Test]
Expand Down
44 changes: 22 additions & 22 deletions Snowflake.Data/Core/SFStatement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +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 All @@ -124,8 +124,8 @@ class SFStatement
private readonly IRestRequester _restRequester;

private CancellationTokenSource _timeoutTokenSource;
// Merged cancellation token source for all cancellation signal.

// Merged cancellation token source for all cancellation signal.
// Cancel callback will be registered under token issued by this source.
private CancellationTokenSource _linkedCancellationTokenSource;

Expand All @@ -151,21 +151,21 @@ internal SFStatement(SFSession session)
_restRequester = session.restRequester;
_queryTag = session._queryTag;
}
internal SFStatement(SFSession session, string queryTag)

internal SFStatement(SFSession session, string queryTag)
{
SfSession = session;
_restRequester = session.restRequester;
_queryTag = queryTag ?? session._queryTag;
_queryTag = queryTag ?? session._queryTag;
}

internal string GetBindStage() => _bindStage;

private void AssignQueryRequestId()
{
lock (_requestIdLock)
{

if (_requestId != null)
{
logger.Info("Another query is running.");
Expand Down Expand Up @@ -207,16 +207,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 Expand Up @@ -317,7 +317,7 @@ private void SetTimeout(int timeout)
this._timeoutTokenSource = timeout > 0 ? new CancellationTokenSource(timeout * 1000) :
new CancellationTokenSource(Timeout.InfiniteTimeSpan);
}

/// <summary>
/// Register cancel callback. Two factors: either external cancellation token passed down from upper
/// layer or timeout reached. Whichever comes first would trigger query cancellation.
Expand Down Expand Up @@ -363,7 +363,7 @@ internal async Task<SFBaseResultSet> ExecuteAsync(int timeout, string sql, Dicti
}

registerQueryCancellationCallback(timeout, cancellationToken);

int arrayBindingThreshold = 0;
if (SfSession.ParameterMap.ContainsKey(SFSessionParameter.CLIENT_STAGE_ARRAY_BINDING_THRESHOLD))
{
Expand Down Expand Up @@ -457,10 +457,10 @@ internal SFBaseResultSet Execute(int timeout, string sql, Dictionary<string, Bin
{
throw new NotImplementedException("Get and Put are not supported in async execution mode");
}
return ExecuteSqlWithPutGet(timeout, trimmedSql, bindings, describeOnly);
return ExecuteSqlWithPutGet(timeout, sql, trimmedSql, bindings, describeOnly);
}

return ExecuteSqlOtherThanPutGet(timeout, trimmedSql, bindings, describeOnly, asyncExec);
return ExecuteSqlOtherThanPutGet(timeout, sql, bindings, describeOnly, asyncExec);
}
finally
{
Expand All @@ -469,7 +469,7 @@ internal SFBaseResultSet Execute(int timeout, string sql, Dictionary<string, Bin
}
}

private SFBaseResultSet ExecuteSqlWithPutGet(int timeout, string sql, Dictionary<string, BindingDTO> bindings, bool describeOnly)
private SFBaseResultSet ExecuteSqlWithPutGet(int timeout, string sql, string trimmedSql, Dictionary<string, BindingDTO> bindings, bool describeOnly)
{
try
{
Expand All @@ -484,7 +484,7 @@ private SFBaseResultSet ExecuteSqlWithPutGet(int timeout, string sql, Dictionary
logger.Debug("PUT/GET queryId: " + (response.data != null ? response.data.queryId : "Unknown"));

SFFileTransferAgent fileTransferAgent =
new SFFileTransferAgent(sql, SfSession, response.data, CancellationToken.None);
new SFFileTransferAgent(trimmedSql, SfSession, response.data, CancellationToken.None);

// Start the file transfer
fileTransferAgent.execute();
Expand All @@ -507,7 +507,7 @@ private SFBaseResultSet ExecuteSqlWithPutGet(int timeout, string sql, Dictionary
throw new SnowflakeDbException(ex, SFError.INTERNAL_ERROR);
}
}

private SFBaseResultSet ExecuteSqlOtherThanPutGet(int timeout, string sql, Dictionary<string, BindingDTO> bindings, bool describeOnly, bool asyncExec)
{
try
Expand Down Expand Up @@ -562,7 +562,7 @@ private SFBaseResultSet ExecuteSqlOtherThanPutGet(int timeout, string sql, Dicti
throw;
}
}

internal async Task<SFBaseResultSet> GetResultWithIdAsync(string resultId, CancellationToken cancellationToken)
{
var req = BuildResultRequestWithId(resultId);
Expand Down Expand Up @@ -938,7 +938,7 @@ internal async Task<QueryStatus> GetQueryStatusAsync(string queryId, Cancellatio
/// </summary>
/// <param name="originalSql">The original sql query.</param>
/// <returns>The query without the blanks and comments at the beginning.</returns>
private string TrimSql(string originalSql)
internal static string TrimSql(string originalSql)
{
char[] sqlQueryBuf = originalSql.ToCharArray();
var builder = new StringBuilder();
Expand Down Expand Up @@ -1054,7 +1054,7 @@ internal SFBaseResultSet ExecuteTransfer(string sql)
false);

PutGetStageInfo stageInfo = new PutGetStageInfo();

SFFileTransferAgent fileTransferAgent =
new SFFileTransferAgent(sql, SfSession, response.data, ref _uploadStream, _destFilename, _stagePath, CancellationToken.None);

Expand Down
15 changes: 12 additions & 3 deletions Snowflake.Data/Snowflake.Data.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
<Version>3.1.0</Version>
<DebugType>Full</DebugType>
<LangVersion>7.3</LangVersion>
<AssemblyOriginatorKeyFile>..\sign\publicKey.snk</AssemblyOriginatorKeyFile>
<DelaySign>true</DelaySign>
<SignAssembly>true</SignAssembly>
</PropertyGroup>

<ItemGroup>
Expand All @@ -26,7 +29,7 @@
<PackageReference Include="Mono.Unix" Version="7.1.0-final.1.21458.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="log4net" Version="2.0.12" />
<PackageReference Include="BouncyCastle.Cryptography" Version="2.2.1" />
<PackageReference Include="BouncyCastle.Cryptography" Version="2.3.1" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.34.0" />
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
</ItemGroup>
Expand All @@ -40,9 +43,9 @@
</ItemGroup>

<ItemGroup Condition="'$(Configuration)' != 'Release'">
<InternalsVisibleTo Include="Snowflake.Data.Tests" />
<InternalsVisibleTo Include="Snowflake.Data.Tests,PublicKey=0024000004800000940000000602000000240000525341310004000001000100c159643cbf31e9bbbe7920091c39ecbd988b3e102df664830b33f12c9d838b07463682948cb56bbc414311fa019d6bca1dc08bc9d54684667fdd94ddf140f499ccb66795322128ba1804d8342fec912cea2704fe09c82dbf03bf10817330537d57e8177d92c205e93278245d18a84f185c53d1c5d917171c9807ac769ae9dfcb" />
<!--needed by Moq to be able to mock internal interfaces-->
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2,PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7" />
</ItemGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
Expand All @@ -68,4 +71,10 @@
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>

<ItemGroup>
<None Include="..\sign\publicKey.snk">
<Link>publicKey.snk</Link>
</None>
</ItemGroup>
</Project>
6 changes: 5 additions & 1 deletion deploy.bat
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ SET API_KEY=%2
SET ROOT_DIR=%~dp0
cd %ROOT_DIR%

dotnet pack Snowflake.Data\Snowflake.Data.csproj -c Release --force -v n --output %ROOT_DIR%
dotnet build Snowflake.Data\Snowflake.Data.csproj -c Release --force -v n

REM command to sign with strong name Snowflake.Data.dll should be here

dotnet pack Snowflake.Data\Snowflake.Data.csproj -c Release --force -v n --no-build --output %ROOT_DIR%

dotnet nuget push Snowflake.Data.%VERSION%.nupkg -k %API_KEY% -s https://api.nuget.org/v3/index.json
Binary file added sign/publicKey.snk
Binary file not shown.

0 comments on commit 4c8d516

Please sign in to comment.