From 8c2feaae1a0a41c938dcd58a5792e4ff6903961d Mon Sep 17 00:00:00 2001 From: Harry Xi <44687000+sfc-gh-ext-simba-hx@users.noreply.github.com> Date: Thu, 12 Oct 2023 09:33:32 -0700 Subject: [PATCH] SNOW-933246: adding missed fix for HTAP parameter removal (#787) ### Description sdk issue 693 Some cases for HTAP metadata/parameter removal was missed in September release. Fix them and add test case as well. ### Checklist - [x] Code compiles correctly - [x] Code is formatted according to [Coding Conventions](../CodingConventions.md) - [x] Created tests which fail without the change (if possible) - [x] All tests passing (`dotnet test`) - [ ] Extended the README / documentation, if necessary - [x] Provide JIRA issue id (if possible) or GitHub issue id in PR name --- .../IntegrationTests/SFDbDataReaderIT.cs | 32 +++++++++++++++++++ .../UnitTests/SFSessionTest.cs | 6 ++++ Snowflake.Data/Core/ArrowResultSet.cs | 2 +- Snowflake.Data/Core/SFResultSet.cs | 2 +- Snowflake.Data/Core/SFResultSetMetaData.cs | 20 +++++------- Snowflake.Data/Core/Session/SFSession.cs | 19 +++++++++-- .../Core/Session/SFSessionParameter.cs | 2 ++ 7 files changed, 67 insertions(+), 16 deletions(-) diff --git a/Snowflake.Data.Tests/IntegrationTests/SFDbDataReaderIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFDbDataReaderIT.cs index 158abc7f0..f2613acf6 100755 --- a/Snowflake.Data.Tests/IntegrationTests/SFDbDataReaderIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFDbDataReaderIT.cs @@ -174,6 +174,38 @@ public void TestGetDate(string inputTimeStr) testGetDateAndOrTime(inputTimeStr, null, SFDataType.DATE); } + [Test] + public void TestDateOutputFormat() + { + using (IDbConnection conn = new SnowflakeDbConnection()) + { + conn.ConnectionString = ConnectionString; + conn.Open(); + IDbCommand cmd = conn.CreateCommand(); + + try + { + cmd.CommandText = "alter session set DATE_OUTPUT_FORMAT='MM/DD/YYYY'"; + cmd.ExecuteNonQuery(); + + cmd.CommandText = $"select TO_DATE('2013-05-17')"; + IDataReader reader = cmd.ExecuteReader(); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual("05/17/2013", reader.GetString(0)); + + reader.Close(); + } + finally + { + // set format back to default to avoid impact other test cases + cmd.CommandText = "alter session set DATE_OUTPUT_FORMAT='YYYY-MM-DD'"; + cmd.ExecuteNonQuery(); + } + + conn.Close(); + } + } [Test] [TestCase(null, null)] diff --git a/Snowflake.Data.Tests/UnitTests/SFSessionTest.cs b/Snowflake.Data.Tests/UnitTests/SFSessionTest.cs index 51635d662..b9530b83b 100644 --- a/Snowflake.Data.Tests/UnitTests/SFSessionTest.cs +++ b/Snowflake.Data.Tests/UnitTests/SFSessionTest.cs @@ -34,6 +34,12 @@ public void TestUpdateDatabaseAndSchema() Assert.AreEqual(databaseName, sfSession.database); Assert.AreEqual(schemaName, sfSession.schema); + + // when database or schema name is missing in the response, + // the cached value should keep unchanged + sfSession.UpdateDatabaseAndSchema(null, null); + Assert.AreEqual(databaseName, sfSession.database); + Assert.AreEqual(schemaName, sfSession.schema); } [Test] diff --git a/Snowflake.Data/Core/ArrowResultSet.cs b/Snowflake.Data/Core/ArrowResultSet.cs index 5c3103320..6bc0112c3 100755 --- a/Snowflake.Data/Core/ArrowResultSet.cs +++ b/Snowflake.Data/Core/ArrowResultSet.cs @@ -45,7 +45,7 @@ public ArrowResultSet(QueryExecResponseData responseData, SFStatement sfStatemen responseData.rowSet = null; - sfResultSetMetaData = new SFResultSetMetaData(responseData); + sfResultSetMetaData = new SFResultSetMetaData(responseData, this.sfStatement.SfSession); isClosed = false; diff --git a/Snowflake.Data/Core/SFResultSet.cs b/Snowflake.Data/Core/SFResultSet.cs index 2e20453ba..1f36a5cd2 100755 --- a/Snowflake.Data/Core/SFResultSet.cs +++ b/Snowflake.Data/Core/SFResultSet.cs @@ -39,7 +39,7 @@ public SFResultSet(QueryExecResponseData responseData, SFStatement sfStatement, _currentChunk = new SFResultChunk(responseData.rowSet); responseData.rowSet = null; - sfResultSetMetaData = new SFResultSetMetaData(responseData); + sfResultSetMetaData = new SFResultSetMetaData(responseData, this.sfStatement.SfSession); isClosed = false; diff --git a/Snowflake.Data/Core/SFResultSetMetaData.cs b/Snowflake.Data/Core/SFResultSetMetaData.cs index 1045109f4..25cf28ef8 100755 --- a/Snowflake.Data/Core/SFResultSetMetaData.cs +++ b/Snowflake.Data/Core/SFResultSetMetaData.cs @@ -37,24 +37,20 @@ class SFResultSetMetaData /// private Dictionary columnNameToIndexCache = new Dictionary(); - internal SFResultSetMetaData(QueryExecResponseData queryExecResponseData) + internal SFResultSetMetaData(QueryExecResponseData queryExecResponseData, SFSession session) { rowTypes = queryExecResponseData.rowType; columnCount = rowTypes.Count; statementType = findStatementTypeById(queryExecResponseData.statementTypeId); columnTypes = InitColumnTypes(); - - foreach (NameValueParameter parameter in queryExecResponseData.parameters) + + if (session.ParameterMap.ContainsKey(SFSessionParameter.DATE_OUTPUT_FORMAT)) { - switch(parameter.name) - { - case "DATE_OUTPUT_FORMAT": - dateOutputFormat = parameter.value; - break; - case "TIME_OUTPUT_FORMAT": - timeOutputFormat = parameter.value; - break; - } + dateOutputFormat = session.ParameterMap[SFSessionParameter.DATE_OUTPUT_FORMAT].ToString(); + } + if (session.ParameterMap.ContainsKey(SFSessionParameter.TIME_OUTPUT_FORMAT)) + { + timeOutputFormat = session.ParameterMap[SFSessionParameter.TIME_OUTPUT_FORMAT].ToString(); } } diff --git a/Snowflake.Data/Core/Session/SFSession.cs b/Snowflake.Data/Core/Session/SFSession.cs index ad9aa07cd..49586c08d 100755 --- a/Snowflake.Data/Core/Session/SFSession.cs +++ b/Snowflake.Data/Core/Session/SFSession.cs @@ -380,6 +380,13 @@ internal SFRestRequest BuildTimeoutRestRequest(Uri uri, Object body) internal void UpdateSessionParameterMap(List parameterList) { logger.Debug("Update parameter map"); + // with HTAP parameter removal parameters might not returned + // query response + if (parameterList is null) + { + return; + } + foreach (NameValueParameter parameter in parameterList) { if (Enum.TryParse(parameter.name, out SFSessionParameter parameterName)) @@ -432,8 +439,16 @@ internal RequestQueryContext GetQueryContextRequest() internal void UpdateDatabaseAndSchema(string databaseName, string schemaName) { - this.database = databaseName; - this.schema = schemaName; + // with HTAP session metadata removal database/schema + // might be not returened in query result + if (!String.IsNullOrEmpty(databaseName)) + { + this.database = databaseName; + } + if (!String.IsNullOrEmpty(schemaName)) + { + this.schema = schemaName; + } } internal void startHeartBeatForThisSession() diff --git a/Snowflake.Data/Core/Session/SFSessionParameter.cs b/Snowflake.Data/Core/Session/SFSessionParameter.cs index 4212f5b35..97fdcec23 100755 --- a/Snowflake.Data/Core/Session/SFSessionParameter.cs +++ b/Snowflake.Data/Core/Session/SFSessionParameter.cs @@ -12,5 +12,7 @@ internal enum SFSessionParameter CLIENT_STAGE_ARRAY_BINDING_THRESHOLD, CLIENT_SESSION_KEEP_ALIVE, QUERY_CONTEXT_CACHE_SIZE, + DATE_OUTPUT_FORMAT, + TIME_OUTPUT_FORMAT, } }