Skip to content

Conversation

@sfc-gh-ext-simba-lf
Copy link
Collaborator

Description

Add arrow support for structured types

Checklist

  • Code compiles correctly
  • Code is formatted according to Coding Conventions
  • Created tests which fail without the change (if possible)
  • All tests passing (dotnet test)
  • Extended the README / documentation, if necessary
  • Provide JIRA issue id (if possible) or GitHub issue id in PR name

…nector-net into SNOW-1488703-Arrow-Support-For-Structured-Types

# Conflicts:
#	Snowflake.Data.Tests/IntegrationTests/StructuredArraysIT.cs
#	Snowflake.Data.Tests/IntegrationTests/StructuredMapsIT.cs
#	Snowflake.Data.Tests/IntegrationTests/StructuredObjectsIT.cs
@sfc-gh-snowflakedb-snyk-sa
Copy link
Contributor

sfc-gh-snowflakedb-snyk-sa commented May 21, 2025

🎉 Snyk checks have passed. No issues have been found so far.

security/snyk check is complete. No issues have been found. (View Details)

license/snyk check is complete. No issues have been found. (View Details)

@codecov
Copy link

codecov bot commented May 21, 2025

❌ 3 Tests Failed:

Tests completed Failed Passed Skipped
3496 3 3493 123
View the full list of 4 ❄️ flaky test(s)
Snowflake.Data.Tests.IntegrationTests.MaxLobSizeIT::TestSelectOnSpecifiedSize_ARROW_4194304

Flake rate in main: 16.67% (Passed 25 times, Failed 5 times)

Stack Traces | 193s run time
--TearDown
   at Snowflake.Data.Core.SFSession.ProcessLoginResponse(LoginResponse authnResponse) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Session/SFSession.cs:line 154
   at Snowflake.Data.Core.Authenticator.BaseAuthenticator.Login() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data.../Core/Authenticator/IAuthenticator.cs:line 92
   at Snowflake.Data.Core.Authenticator.KeyPairAuthenticator.Authenticate() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data.../Core/Authenticator/KeyPairAuthenticator.cs:line 69
   at Snowflake.Data.Core.SFSession.Open() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Session/SFSession.cs:line 301
   at Snowflake.Data.Core.Session.SessionPool.NewSession(String connectionString, SessionPropertiesContext sessionContext, SessionCreationToken sessionCreationToken) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data........./Core/Session/SessionPool.cs:line 416
   at Snowflake.Data.Core.Session.SessionPool.NewNonPoolingSession(String connectionString, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data........./Core/Session/SessionPool.cs:line 408
   at Snowflake.Data.Core.Session.SessionPool.GetSession(String connStr, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data........./Core/Session/SessionPool.cs:line 165
   at Snowflake.Data.Core.Session.ConnectionPoolManager.GetSession(String connectionString, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data.../Core/Session/ConnectionPoolManager.cs:line 31
   at Snowflake.Data.Client.SnowflakeDbConnectionPool.GetSession(String connectionString, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs:line 33
   at Snowflake.Data.Client.SnowflakeDbConnection.Open() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data/Client/SnowflakeDbConnection.cs:line 290
   at Snowflake.Data.Tests.IntegrationTests.MaxLobSizeIT.TearDown() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data.Tests/IntegrationTests/MaxLobSizeIT.cs:line 95
   at InvokeStub_MaxLobSizeIT.TearDown(Object, Object, IntPtr*)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Snowflake.Data.Tests.IntegrationTests.SFConnectionIT::TestNonProxyHostShouldBypassProxyServer("*a*","a")

Flake rate in main: 14.29% (Passed 6 times, Failed 1 times)

Stack Traces | 265s run time
at Snowflake.Data.Core.Session.SessionPool.NewSession(String connectionString, SessionPropertiesContext sessionContext, SessionCreationToken sessionCreationToken) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data...................../Core/Session/SessionPool.cs:line 444
   at Snowflake.Data.Core.Session.SessionPool.NewNonPoolingSession(String connectionString, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data...................../Core/Session/SessionPool.cs:line 408
   at Snowflake.Data.Core.Session.SessionPool.GetSession(String connStr, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data...................../Core/Session/SessionPool.cs:line 165
   at Snowflake.Data.Core.Session.ConnectionPoolManager.GetSession(String connectionString, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Session/ConnectionPoolManager.cs:line 31
   at Snowflake.Data.Client.SnowflakeDbConnectionPool.GetSession(String connectionString, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs:line 33
   at Snowflake.Data.Client.SnowflakeDbConnection.Open() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data/Client/SnowflakeDbConnection.cs:line 290
   at Snowflake.Data.Tests.IntegrationTests.SFConnectionIT.TestNonProxyHostShouldBypassProxyServer(String regexHost, String proxyHost) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs:line 1639
   at InvokeStub_SFConnectionIT.TestNonProxyHostShouldBypassProxyServer(Object, Span`1)
   at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
--AggregateException
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.get_Result()
   at Snowflake.Data.Core.RestRequester.Post[T](IRestRequest request) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data/Core/RestRequester.cs:line 51
   at Snowflake.Data.Core.Authenticator.BaseAuthenticator.Login() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Authenticator/IAuthenticator.cs:line 90
   at Snowflake.Data.Core.Authenticator.KeyPairAuthenticator.Authenticate() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Authenticator/KeyPairAuthenticator.cs:line 69
   at Snowflake.Data.Core.SFSession.Open() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Session/SFSession.cs:line 301
   at Snowflake.Data.Core.Session.SessionPool.NewSession(String connectionString, SessionPropertiesContext sessionContext, SessionCreationToken sessionCreationToken) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data...................../Core/Session/SessionPool.cs:line 416
--TaskCanceledException
   at System.Threading.Tasks.Task.GetExceptions(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.get_Result()
   at Snowflake.Data.Core.RestRequester.Post[T](IRestRequest request) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data/Core/RestRequester.cs:line 51
   at Snowflake.Data.Core.Authenticator.BaseAuthenticator.Login() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Authenticator/IAuthenticator.cs:line 90
   at Snowflake.Data.Core.Authenticator.KeyPairAuthenticator.Authenticate() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Authenticator/KeyPairAuthenticator.cs:line 69
   at Snowflake.Data.Core.SFSession.Open() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Session/SFSession.cs:line 301
   at Snowflake.Data.Core.Session.SessionPool.NewSession(String connectionString, SessionPropertiesContext sessionContext, SessionCreationToken sessionCreationToken) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data...................../Core/Session/SessionPool.cs:line 416
   at Snowflake.Data.Core.Session.SessionPool.NewNonPoolingSession(String connectionString, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data...................../Core/Session/SessionPool.cs:line 408
   at Snowflake.Data.Core.Session.SessionPool.GetSession(String connStr, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data...................../Core/Session/SessionPool.cs:line 165
   at Snowflake.Data.Core.Session.ConnectionPoolManager.GetSession(String connectionString, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Session/ConnectionPoolManager.cs:line 31
   at Snowflake.Data.Client.SnowflakeDbConnectionPool.GetSession(String connectionString, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs:line 33
   at Snowflake.Data.Client.SnowflakeDbConnection.Open() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data/Client/SnowflakeDbConnection.cs:line 290
   at Snowflake.Data.Tests.IntegrationTests.SFConnectionIT.TestNonProxyHostShouldBypassProxyServer(String regexHost, String proxyHost) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs:line 1639
   at InvokeStub_SFConnectionIT.TestNonProxyHostShouldBypassProxyServer(Object, Span`1)
   at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at NUnit.Framework.Internal.Reflect.InvokeMethod(MethodInfo method, Object fixture, Object[] args)
   at NUnit.Framework.Internal.MethodWrapper.Invoke(Object fixture, Object[] args)
   at NUnit.Framework.Internal.Commands.TestMethodCommand.InvokeTestMethod(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.TestMethodCommand.RunTestMethod(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.TestMethodCommand.Execute(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__0()
   at NUnit.Framework.Internal.Commands.DelegatingTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.Execute(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__0()
   at NUnit.Framework.Internal.Commands.DelegatingTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.Execute(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.BeforeTestCommand.Execute(TestExecutionContext context)
   at NUnit.Framework.Internal.Execution.SimpleWorkItem.<>c__DisplayClass4_0.<PerformWork>b__0()
   at NUnit.Framework.Internal.ContextUtils.<>c__DisplayClass1_0`1.<DoIsolated>b__0(Object _)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at NUnit.Framework.Internal.ContextUtils.DoIsolated(ContextCallback callback, Object state)
   at NUnit.Framework.Internal.ContextUtils.DoIsolated[T](Func`1 func)
   at NUnit.Framework.Internal.Execution.SimpleWorkItem.PerformWork()
   at NUnit.Framework.Internal.Execution.WorkItem.RunOnCurrentThread()
   at NUnit.Framework.Internal.Execution.WorkItem.Execute()
   at NUnit.Framework.Internal.Execution.TestWorker.TestWorkerThreadProc()
   at System.Threading.Thread.StartHelper.Callback(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
Snowflake.Data.Tests.IntegrationTests.SFConnectionIT::TestNonProxyHostShouldBypassProxyServer("^*{0}*$")

Flake rate in main: 14.29% (Passed 6 times, Failed 1 times)

Stack Traces | 244s run time
at Snowflake.Data.Core.Session.SessionPool.NewSession(String connectionString, SessionPropertiesContext sessionContext, SessionCreationToken sessionCreationToken) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data...................../Core/Session/SessionPool.cs:line 444
   at Snowflake.Data.Core.Session.SessionPool.NewNonPoolingSession(String connectionString, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data...................../Core/Session/SessionPool.cs:line 408
   at Snowflake.Data.Core.Session.SessionPool.GetSession(String connStr, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data...................../Core/Session/SessionPool.cs:line 165
   at Snowflake.Data.Core.Session.ConnectionPoolManager.GetSession(String connectionString, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Session/ConnectionPoolManager.cs:line 31
   at Snowflake.Data.Client.SnowflakeDbConnectionPool.GetSession(String connectionString, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs:line 33
   at Snowflake.Data.Client.SnowflakeDbConnection.Open() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data/Client/SnowflakeDbConnection.cs:line 290
   at Snowflake.Data.Tests.IntegrationTests.SFConnectionIT.TestNonProxyHostShouldBypassProxyServer(String regexHost, String proxyHost) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs:line 1639
   at InvokeStub_SFConnectionIT.TestNonProxyHostShouldBypassProxyServer(Object, Span`1)
   at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
--AggregateException
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.get_Result()
   at Snowflake.Data.Core.RestRequester.Post[T](IRestRequest request) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data/Core/RestRequester.cs:line 51
   at Snowflake.Data.Core.Authenticator.BaseAuthenticator.Login() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Authenticator/IAuthenticator.cs:line 90
   at Snowflake.Data.Core.Authenticator.KeyPairAuthenticator.Authenticate() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Authenticator/KeyPairAuthenticator.cs:line 69
   at Snowflake.Data.Core.SFSession.Open() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Session/SFSession.cs:line 301
   at Snowflake.Data.Core.Session.SessionPool.NewSession(String connectionString, SessionPropertiesContext sessionContext, SessionCreationToken sessionCreationToken) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data...................../Core/Session/SessionPool.cs:line 416
--TaskCanceledException
   at System.Threading.Tasks.Task.GetExceptions(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.get_Result()
   at Snowflake.Data.Core.RestRequester.Post[T](IRestRequest request) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data/Core/RestRequester.cs:line 51
   at Snowflake.Data.Core.Authenticator.BaseAuthenticator.Login() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Authenticator/IAuthenticator.cs:line 90
   at Snowflake.Data.Core.Authenticator.KeyPairAuthenticator.Authenticate() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Authenticator/KeyPairAuthenticator.cs:line 69
   at Snowflake.Data.Core.SFSession.Open() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Session/SFSession.cs:line 301
   at Snowflake.Data.Core.Session.SessionPool.NewSession(String connectionString, SessionPropertiesContext sessionContext, SessionCreationToken sessionCreationToken) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data...................../Core/Session/SessionPool.cs:line 416
   at Snowflake.Data.Core.Session.SessionPool.NewNonPoolingSession(String connectionString, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data...................../Core/Session/SessionPool.cs:line 408
   at Snowflake.Data.Core.Session.SessionPool.GetSession(String connStr, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data...................../Core/Session/SessionPool.cs:line 165
   at Snowflake.Data.Core.Session.ConnectionPoolManager.GetSession(String connectionString, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data....../Core/Session/ConnectionPoolManager.cs:line 31
   at Snowflake.Data.Client.SnowflakeDbConnectionPool.GetSession(String connectionString, SessionPropertiesContext sessionContext) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data/Client/SnowflakeDbConnectionPool.cs:line 33
   at Snowflake.Data.Client.SnowflakeDbConnection.Open() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data/Client/SnowflakeDbConnection.cs:line 290
   at Snowflake.Data.Tests.IntegrationTests.SFConnectionIT.TestNonProxyHostShouldBypassProxyServer(String regexHost, String proxyHost) in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs:line 1639
   at InvokeStub_SFConnectionIT.TestNonProxyHostShouldBypassProxyServer(Object, Span`1)
   at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at NUnit.Framework.Internal.Reflect.InvokeMethod(MethodInfo method, Object fixture, Object[] args)
   at NUnit.Framework.Internal.MethodWrapper.Invoke(Object fixture, Object[] args)
   at NUnit.Framework.Internal.Commands.TestMethodCommand.InvokeTestMethod(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.TestMethodCommand.RunTestMethod(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.TestMethodCommand.Execute(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__0()
   at NUnit.Framework.Internal.Commands.DelegatingTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.Execute(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__0()
   at NUnit.Framework.Internal.Commands.DelegatingTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.Execute(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.BeforeTestCommand.Execute(TestExecutionContext context)
   at NUnit.Framework.Internal.Execution.SimpleWorkItem.<>c__DisplayClass4_0.<PerformWork>b__0()
   at NUnit.Framework.Internal.ContextUtils.<>c__DisplayClass1_0`1.<DoIsolated>b__0(Object _)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at NUnit.Framework.Internal.ContextUtils.DoIsolated(ContextCallback callback, Object state)
   at NUnit.Framework.Internal.ContextUtils.DoIsolated[T](Func`1 func)
   at NUnit.Framework.Internal.Execution.SimpleWorkItem.PerformWork()
   at NUnit.Framework.Internal.Execution.WorkItem.RunOnCurrentThread()
   at NUnit.Framework.Internal.Execution.WorkItem.Execute()
   at NUnit.Framework.Internal.Execution.TestWorker.TestWorkerThreadProc()
   at System.Threading.Thread.StartHelper.Callback(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
Snowflake.Data.Tests.IntegrationTests.SFConnectionITAsync::TestAsyncDefaultLoginTimeout

Flake rate in main: 14.29% (Passed 6 times, Failed 1 times)

Stack Traces | 314s run time
at Snowflake.Data.Tests.IntegrationTests.SFConnectionITAsync.TestAsyncDefaultLoginTimeout() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs:line 2057

1)    at Snowflake.Data.Tests.IntegrationTests.SFConnectionITAsync.TestAsyncDefaultLoginTimeout() in .../snowflake-connector-net/snowflake-connector-net/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs:line 2057

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@sfc-gh-ext-simba-lf sfc-gh-ext-simba-lf marked this pull request as ready for review May 22, 2025 20:27
@sfc-gh-ext-simba-lf sfc-gh-ext-simba-lf requested a review from a team as a code owner May 22, 2025 20:27
@sfc-gh-pszpakowski sfc-gh-pszpakowski requested review from sfc-gh-mgemra and removed request for sfc-gh-dstempniak October 7, 2025 19:14
case DoubleArray doubles: return doubles.GetValue(index);
case FloatArray floats: return floats.GetValue(index);
case Decimal128Array decimals: return decimals.GetValue(index);
case Int32Array ints: return ints.GetValue(index);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason for not including Int8Array, Int16Array, BinaryArray, Date32Array and FixedSizeListArray? I see all of them are handled in ExtractCell method.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed them when going through the list of cases. They are added now

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to make a test for FixedSizeListArray and found that ARRAY_CONSTRUCT and OBJECT_CONSTRUCT does not support VECTOR and that's why FixedSizeListArray wasn't initially included

Also just to let you know, currently the response always return number arrays in either Decimal128Array or DoubleArray regardless of the numeric data type they were assigned in ARRAY_CONSTRUCT

var json = stringValue == null ? null : JObject.Parse(stringValue);
return JsonToStructuredTypeConverter.ConvertMap<TKey, TValue>(fields, json);
var val = GetValue(ordinal);
if (val is string stringValue)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Isn't this more readable? Here and in GetArray

                switch (val)
                {
                    case string stringValue:
                    {
                        var json = JObject.Parse(stringValue);
                        return JsonToStructuredTypeConverter.ConvertObject<T>(fields, json);
                    }
                    case Dictionary<string, object> structArray:
                        return ArrowConverter.ConvertObject<T>(structArray);
                    default:
                        return null;
                }

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced with switch case for all the Get methods

return result;
}

private static object ConvertValue(object value, Type targetType)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use switch case for clarity

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 44 to 69
private static void MapPropertiesByNames(object obj, Dictionary<string, object> dict, Type type)
{
foreach (var kvp in dict)
{
var prop = type.GetProperty(kvp.Key, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
if (prop != null)
{
var converted = ConvertValue(kvp.Value, prop.PropertyType);
prop.SetValue(obj, converted);
}
else
{
foreach (var property in type.GetProperties())
{
foreach (var attr in property.GetCustomAttributes().OfType<SnowflakeColumn>())
{
if (attr?.Name == kvp.Key)
{
var converted = ConvertValue(kvp.Value, property.PropertyType);
property.SetValue(obj, converted);
}
}
}
}
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private static void MapPropertiesByNames(object obj, Dictionary<string, object> dict, Type type)
{
foreach (var kvp in dict)
{
var prop = type.GetProperty(kvp.Key, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
if (prop != null)
{
var converted = ConvertValue(kvp.Value, prop.PropertyType);
prop.SetValue(obj, converted);
}
else
{
foreach (var property in type.GetProperties())
{
foreach (var attr in property.GetCustomAttributes().OfType<SnowflakeColumn>())
{
if (attr?.Name == kvp.Key)
{
var converted = ConvertValue(kvp.Value, property.PropertyType);
property.SetValue(obj, converted);
}
}
}
}
}
}
private static void MapPropertiesByNames(object obj, Dictionary<string, object> dict, Type type)
{
foreach (var kvp in dict)
{
var prop = FindPropertyByName(type, kvp.Key);
if (prop != null)
{
var converted = ConvertValue(kvp.Value, prop.PropertyType);
prop.SetValue(obj, converted);
}
}
}
private static PropertyInfo FindPropertyByName(Type type, string name)
{
var prop = type.GetProperty(name, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
if (prop != null)
return prop;
return type.GetProperties()
.FirstOrDefault(p => p.GetCustomAttributes()
.OfType<SnowflakeColumn>()
.Any(attr => attr?.Name == name));
}

IMO, it's more readable

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

if (type.GetCustomAttributes(false).Any(attribute => attribute.GetType() == typeof(SnowflakeObject)))
{
var constructionMethod = JsonToStructuredTypeConverter.GetConstructionMethod(type);
if (constructionMethod == SnowflakeObjectConstructionMethod.PROPERTIES_NAMES)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use switch case for nested if statements to improve clarity

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored to switch case

private static void MapPropertiesByOrder(object obj, Dictionary<string, object> dict, Type type)
{
var index = 0;
foreach (var property in type.GetProperties())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the order of properties guaranteed in type.GetProperties()?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the docs, the order is only guaranteed for .NET 7 and above

I checked its JSON counterpart and it also uses type.GetProperties(). One option could be ordering by metadata

if (index >= dict.Count)
break;

var attributes = property.GetCustomAttributes().OfType<SnowflakeColumn>().ToList();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the order of the attributes guaranteed in property.GetCustomAttributes()?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There doesn't seem to be a guarantee that GetCustomAttributes() will always list attributes in the same order on all .NET versions

It's replaced to get the first or default value instead of a list similar to JsonToStructuredTypeConverter

var result = new T[list.Count];
for (int i = 0; i < list.Count; i++)
{
if (targetType.IsGenericType && targetType.GetGenericTypeDefinition() == typeof(Nullable<>))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it checked inside the for loop? Let's move it outside

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, it's now outside the for loop

return CallMethod(targetType, objDict, nameof(ConvertObject));
if (value is Dictionary<object, object> mapDict)
{
var genericArgs = targetType.GetGenericArguments();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we do some kind of validation here? For example, should we check that the targetType is, in fact, a dictionary and has 2 generic arguments?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added validation for targetType and the length of the generic arguments

@sfc-gh-mgemra
Copy link
Collaborator

sfc-gh-mgemra commented Oct 28, 2025

Please also update the changelog

@sfc-gh-ext-simba-lf
Copy link
Collaborator Author

Please also update the changelog

Updated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants