From 2119080ab3f84be658b92cae0deae415ceb7f9c2 Mon Sep 17 00:00:00 2001
From: Juan Martinez Ramirez
<126511805+sfc-gh-jmartinez@users.noreply.github.com>
Date: Wed, 29 May 2024 16:25:19 -0600
Subject: [PATCH 1/3] SNOW-991583: Assembly delay sign (#956)
### Description
Add delay sign for Snowflake Data assemblies.
### 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
---
Snowflake.Data.Tests/Snowflake.Data.Tests.csproj | 9 +++++++++
Snowflake.Data/Snowflake.Data.csproj | 13 +++++++++++--
deploy.bat | 6 +++++-
sign/publicKey.snk | Bin 0 -> 160 bytes
4 files changed, 25 insertions(+), 3 deletions(-)
create mode 100644 sign/publicKey.snk
diff --git a/Snowflake.Data.Tests/Snowflake.Data.Tests.csproj b/Snowflake.Data.Tests/Snowflake.Data.Tests.csproj
index 0188d4552..aad9b2e84 100644
--- a/Snowflake.Data.Tests/Snowflake.Data.Tests.csproj
+++ b/Snowflake.Data.Tests/Snowflake.Data.Tests.csproj
@@ -11,6 +11,9 @@
true
9
$(SEQUENTIAL_ENV)
+ ..\sign\publicKey.snk
+ true
+ true
@@ -37,6 +40,12 @@
+
+
+ publicKey.snk
+
+
+
full
True
diff --git a/Snowflake.Data/Snowflake.Data.csproj b/Snowflake.Data/Snowflake.Data.csproj
index 4caf957af..e43d61ea1 100644
--- a/Snowflake.Data/Snowflake.Data.csproj
+++ b/Snowflake.Data/Snowflake.Data.csproj
@@ -15,6 +15,9 @@
3.1.0
Full
7.3
+ ..\sign\publicKey.snk
+ true
+ true
@@ -40,9 +43,9 @@
-
+
-
+
@@ -64,4 +67,10 @@
+
+
+
+ publicKey.snk
+
+
diff --git a/deploy.bat b/deploy.bat
index 90d0bb00f..6b808c371 100644
--- a/deploy.bat
+++ b/deploy.bat
@@ -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
\ No newline at end of file
diff --git a/sign/publicKey.snk b/sign/publicKey.snk
new file mode 100644
index 0000000000000000000000000000000000000000..7b78e9478ea641690a3c56b25873d25402a34366
GIT binary patch
literal 160
zcmV;R0AK$ABme*efB*oL000060ssI2Bme+XQ$aBR1ONa50098OS!6uFG3mR$c_0ZK
zIqbcdi#`x7_GE(#Gx02)gNp}7HiDFlwQIaVLlOD`oomV+z>CS%MucX6-IU$&K=hf+
zwr7EFw7A3faw
literal 0
HcmV?d00001
From 33fe6e89af03d3589411d0b7ce9d47e8b7a6478b Mon Sep 17 00:00:00 2001
From: Krzysztof Nozderko
Date: Fri, 7 Jun 2024 09:54:58 +0200
Subject: [PATCH 2/3] SNOW-1463590 Bump BouncyCastle.Cryptography dependency to
2.3.1 (#964)
### Description
SNOW-1463590 Bump BouncyCastle.Cryptography dependency to 2.3.1
### 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
---
Snowflake.Data/Snowflake.Data.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Snowflake.Data/Snowflake.Data.csproj b/Snowflake.Data/Snowflake.Data.csproj
index e43d61ea1..c66ce5594 100644
--- a/Snowflake.Data/Snowflake.Data.csproj
+++ b/Snowflake.Data/Snowflake.Data.csproj
@@ -29,7 +29,7 @@
-
+
From db8e4d590fee9ee1c7e9047ef7e59b74d91b5591 Mon Sep 17 00:00:00 2001
From: Dariusz Stempniak
Date: Fri, 7 Jun 2024 09:57:09 +0200
Subject: [PATCH 3/3] SNOW-1433638 sql trimming only for PUT/GET detection
(#957)
### Description
SNOW-1433638 sql trimming only for PUT/GET detection
Symbol -- cannot be treated as a string.
### 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
---
.../IntegrationTests/SFDbCommandIT.cs | 50 +++++++++++++++----
.../UnitTests/SFStatementTest.cs | 44 ++++++----------
Snowflake.Data/Core/SFStatement.cs | 44 ++++++++--------
3 files changed, 79 insertions(+), 59 deletions(-)
diff --git a/Snowflake.Data.Tests/IntegrationTests/SFDbCommandIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFDbCommandIT.cs
index 3a3cfb82f..8891e2e2a 100755
--- a/Snowflake.Data.Tests/IntegrationTests/SFDbCommandIT.cs
+++ b/Snowflake.Data.Tests/IntegrationTests/SFDbCommandIT.cs
@@ -129,7 +129,7 @@ public void TestCancelExecuteAsync()
}
catch
{
- // assert that cancel is not triggered by timeout, but external cancellation
+ // assert that cancel is not triggered by timeout, but external cancellation
Assert.IsTrue(externalCancel.IsCancellationRequested);
}
Thread.Sleep(2000);
@@ -503,7 +503,7 @@ public void TestRowsAffectedOverflowInt()
using (IDbConnection conn = new SnowflakeDbConnection(ConnectionString))
{
conn.Open();
-
+
CreateOrReplaceTable(conn, TableName, new []{"c1 NUMBER"});
using (IDbCommand command = conn.CreateCommand())
@@ -608,7 +608,7 @@ public void TestSimpleLargeResultSet()
conn.Close();
}
}
-
+
[Test, NonParallelizable]
public void TestUseV1ResultParser()
{
@@ -1021,13 +1021,13 @@ public void testPutArrayBindAsync()
private void ArrayBindTest(string connstr, string tableName, int size)
{
-
+
CancellationTokenSource externalCancel = new CancellationTokenSource(TimeSpan.FromSeconds(100));
using (DbConnection conn = new SnowflakeDbConnection())
{
conn.ConnectionString = connstr;
conn.Open();
-
+
CreateOrReplaceTable(conn, tableName, new []
{
"cola INTEGER",
@@ -1197,7 +1197,7 @@ public void testExecuteScalarAsyncSelect()
{
conn.ConnectionString = ConnectionString;
conn.Open();
-
+
CreateOrReplaceTable(conn, TableName, new []{"cola INTEGER"});
using (DbCommand cmd = conn.CreateCommand())
@@ -1624,7 +1624,7 @@ public void TestGetResultsOfUnknownQueryIdWithConfiguredRetry()
conn.Close();
}
}
-
+
[Test]
public void TestSetQueryTagOverridesConnectionString()
{
@@ -1633,16 +1633,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));
+ }
+ }
}
}
diff --git a/Snowflake.Data.Tests/UnitTests/SFStatementTest.cs b/Snowflake.Data.Tests/UnitTests/SFStatementTest.cs
index 24f0f4b0a..3f131e924 100755
--- a/Snowflake.Data.Tests/UnitTests/SFStatementTest.cs
+++ b/Snowflake.Data.Tests/UnitTests/SFStatementTest.cs
@@ -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));
}
///
@@ -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));
}
///
@@ -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));
}
///
@@ -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]
diff --git a/Snowflake.Data/Core/SFStatement.cs b/Snowflake.Data/Core/SFStatement.cs
index 787bfa5de..e84690d54 100644
--- a/Snowflake.Data/Core/SFStatement.cs
+++ b/Snowflake.Data/Core/SFStatement.cs
@@ -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;
@@ -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;
@@ -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.");
@@ -207,8 +207,8 @@ private SFRestRequest BuildQueryRequest(string sql, Dictionary();
}
bodyParameters[SF_PARAM_QUERY_TAG] = _queryTag;
- }
+ }
QueryRequest postBody = new QueryRequest();
postBody.sqlText = sql;
@@ -317,7 +317,7 @@ private void SetTimeout(int timeout)
this._timeoutTokenSource = timeout > 0 ? new CancellationTokenSource(timeout * 1000) :
new CancellationTokenSource(Timeout.InfiniteTimeSpan);
}
-
+
///
/// Register cancel callback. Two factors: either external cancellation token passed down from upper
/// layer or timeout reached. Whichever comes first would trigger query cancellation.
@@ -363,7 +363,7 @@ internal async Task ExecuteAsync(int timeout, string sql, Dicti
}
registerQueryCancellationCallback(timeout, cancellationToken);
-
+
int arrayBindingThreshold = 0;
if (SfSession.ParameterMap.ContainsKey(SFSessionParameter.CLIENT_STAGE_ARRAY_BINDING_THRESHOLD))
{
@@ -457,10 +457,10 @@ internal SFBaseResultSet Execute(int timeout, string sql, Dictionary bindings, bool describeOnly)
+ private SFBaseResultSet ExecuteSqlWithPutGet(int timeout, string sql, string trimmedSql, Dictionary bindings, bool describeOnly)
{
try
{
@@ -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();
@@ -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 bindings, bool describeOnly, bool asyncExec)
{
try
@@ -562,7 +562,7 @@ private SFBaseResultSet ExecuteSqlOtherThanPutGet(int timeout, string sql, Dicti
throw;
}
}
-
+
internal async Task GetResultWithIdAsync(string resultId, CancellationToken cancellationToken)
{
var req = BuildResultRequestWithId(resultId);
@@ -938,7 +938,7 @@ internal async Task GetQueryStatusAsync(string queryId, Cancellatio
///
/// The original sql query.
/// The query without the blanks and comments at the beginning.
- private string TrimSql(string originalSql)
+ internal static string TrimSql(string originalSql)
{
char[] sqlQueryBuf = originalSql.ToCharArray();
var builder = new StringBuilder();
@@ -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);