Skip to content

Commit

Permalink
SNOW-981350 Structured types for json format - work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-knozderko committed Jun 7, 2024
1 parent db8e4d5 commit 3dd32c0
Show file tree
Hide file tree
Showing 10 changed files with 768 additions and 61 deletions.
98 changes: 98 additions & 0 deletions Snowflake.Data.Tests/Client/Address.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using System.Collections.Generic;

namespace Snowflake.Data.Tests.IntegrationTests
{
public class Address
{
public string city { get; set; }
public string state { get; set; }
public Zip zip { get; set; }

public Address()
{
}

public Address(string city, string state, Zip zip)
{
this.city = city;
this.state = state;
this.zip = zip;
}
}

public class Zip
{
public string prefix { get; set; }
public string postfix { get; set; }

public Zip()
{
}

public Zip(string prefix, string postfix)
{
this.prefix = prefix;
this.postfix = postfix;
}
}

public class Identity
{
public string Name { get; set; }

public Identity()
{
}

public Identity(string name)
{
Name = name;
}

protected bool Equals(Identity other)
{
return Name == other.Name;
}

public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((Identity)obj);
}

public override int GetHashCode()
{
return (Name != null ? Name.GetHashCode() : 0);
}
}

public class Grades
{
public string[] Names { get; set; }

public Grades()
{
}

public Grades(string[] names)
{
Names = names;
}
}

public class GradesWithList
{
public List<string> Names { get; set; }

public GradesWithList()
{
}

public GradesWithList(List<string> names)
{
Names = names;
}
}
}
212 changes: 212 additions & 0 deletions Snowflake.Data.Tests/IntegrationTests/StructuredTypesIT.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
using System.Collections.Generic;
using NUnit.Framework;
using Snowflake.Data.Client;

namespace Snowflake.Data.Tests.IntegrationTests
{
[TestFixture]
public class StructuredTypesIT: SFBaseTest
{
private static string _tableName = "structured_types_tests";

[Test]
public void TestInsertStructuredTypeObject()
{
using (var connection = new SnowflakeDbConnection(ConnectionString))
{
// arrange
connection.Open();
CreateOrReplaceTable(connection, _tableName, new List<string> {"address OBJECT(city VARCHAR, state VARCHAR)"});
using (var command = connection.CreateCommand())
{
var addressAsSFString = "OBJECT_CONSTRUCT('city','San Mateo', 'state', 'CA')::OBJECT(city VARCHAR, state VARCHAR)";
command.CommandText = $"INSERT INTO {_tableName} SELECT {addressAsSFString}";
command.ExecuteNonQuery();
command.CommandText = $"SELECT * FROM {_tableName}";

// act
var reader = command.ExecuteReader();

// assert
Assert.IsTrue(reader.Read());
}
}
}

[Test]
public void TestSelectStructuredTypeObject()
{
using (var connection = new SnowflakeDbConnection(ConnectionString))
{
// arrange
connection.Open();
using (var command = connection.CreateCommand())
{
var addressAsSFString = "OBJECT_CONSTRUCT('city','San Mateo', 'state', 'CA')::OBJECT(city VARCHAR, state VARCHAR)";
command.CommandText = $"SELECT {addressAsSFString}";

// act
var reader = (SnowflakeDbDataReader) command.ExecuteReader();

// assert
Assert.IsTrue(reader.Read());
var address = reader.GetObject<Address>(0);
Assert.AreEqual("San Mateo", address.city);
Assert.AreEqual("CA", address.state);
Assert.IsNull(address.zip);
}
}
}

[Test]
[TestCase(StructureTypeConstructionMethod.PROPERTIES_NAMES)]
[TestCase(StructureTypeConstructionMethod.PROPERTIES_ORDER)]
[TestCase(StructureTypeConstructionMethod.CONSTRUCTOR)]
public void TestSelectNestedStructuredTypeObject(StructureTypeConstructionMethod constructionMethod)
{
using (var connection = new SnowflakeDbConnection(ConnectionString))
{
// arrange
connection.Open();
using (var command = connection.CreateCommand())
{
var addressAsSFString = "OBJECT_CONSTRUCT('city','San Mateo', 'state', 'CA', 'zip', OBJECT_CONSTRUCT('prefix', '00', 'postfix', '11'))::OBJECT(city VARCHAR, state VARCHAR, zip OBJECT(prefix VARCHAR, postfix VARCHAR))";
command.CommandText = $"SELECT {addressAsSFString}";

// act
var reader = (SnowflakeDbDataReader) command.ExecuteReader();

// assert
Assert.IsTrue(reader.Read());
var address = reader.GetObject<Address>(0, constructionMethod);
Assert.AreEqual("San Mateo", address.city);
Assert.AreEqual("CA", address.state);
Assert.NotNull(address.zip);
Assert.AreEqual("00", address.zip.prefix);
Assert.AreEqual("11", address.zip.postfix);
}
}
}

[Test]
public void TestSelectArray()
{
using (var connection = new SnowflakeDbConnection(ConnectionString))
{
// arrange
connection.Open();
using (var command = connection.CreateCommand())
{
var arrayOfNumberSFString = "ARRAY_CONSTRUCT('a','b','c')::ARRAY(TEXT)";
command.CommandText = $"SELECT {arrayOfNumberSFString}";

// act
var reader = (SnowflakeDbDataReader) command.ExecuteReader();

// assert
Assert.IsTrue(reader.Read());
var array = reader.GetArray<string>(0);
Assert.AreEqual(3, array.Length);
CollectionAssert.AreEqual(new []{ "a", "b", "c"}, array);
}
}
}

[Test]
public void TestSelectArrayOfObjects()
{
using (var connection = new SnowflakeDbConnection(ConnectionString))
{
// arrange
connection.Open();
using (var command = connection.CreateCommand())
{
var arrayOfObjects = "ARRAY_CONSTRUCT(OBJECT_CONSTRUCT('name', 'Alex'), OBJECT_CONSTRUCT('name', 'Brian'))::ARRAY(OBJECT(name VARCHAR))";
command.CommandText = $"SELECT {arrayOfObjects}";

// act
var reader = (SnowflakeDbDataReader) command.ExecuteReader();

// assert
Assert.IsTrue(reader.Read());
var array = reader.GetArray<Identity>(0);
Assert.AreEqual(2, array.Length);
CollectionAssert.AreEqual(new []{new Identity("Alex"), new Identity("Brian")}, array);
}
}
}


[Test]
public void TestSelectArrayOfArrays()
{
using (var connection = new SnowflakeDbConnection(ConnectionString))
{
// arrange
connection.Open();
using (var command = connection.CreateCommand())
{
var arrayOfObjects = "ARRAY_CONSTRUCT(ARRAY_CONSTRUCT('a', 'b'), ARRAY_CONSTRUCT('c', 'd'))::ARRAY(ARRAY(TEXT))";
command.CommandText = $"SELECT {arrayOfObjects}";

// act
var reader = (SnowflakeDbDataReader) command.ExecuteReader();

// assert
Assert.IsTrue(reader.Read());
var array = reader.GetArray<string[]>(0);
Assert.AreEqual(2, array.Length);
CollectionAssert.AreEqual(new []{ new [] {"a", "b"}, new [] {"c", "d"}}, array);
}
}
}

[Test]
public void TestSelectObjectWithArrays()
{
using (var connection = new SnowflakeDbConnection(ConnectionString))
{
// arrange
connection.Open();
using (var command = connection.CreateCommand())
{
var objectWithArray = "OBJECT_CONSTRUCT('names', ARRAY_CONSTRUCT('Excellent', 'Poor'))::OBJECT(names ARRAY(TEXT))";
command.CommandText = $"SELECT {objectWithArray}";

// act
var reader = (SnowflakeDbDataReader) command.ExecuteReader();

// assert
Assert.IsTrue(reader.Read());
var grades = reader.GetObject<Grades>(0);
Assert.NotNull(grades);
CollectionAssert.AreEqual(new [] {"Excellent", "Poor"}, grades.Names);
}
}
}

[Test]
public void TestSelectObjectWithList()
{
using (var connection = new SnowflakeDbConnection(ConnectionString))
{
// arrange
connection.Open();
using (var command = connection.CreateCommand())
{
var objectWithArray = "OBJECT_CONSTRUCT('names', ARRAY_CONSTRUCT('Excellent', 'Poor'))::OBJECT(names ARRAY(TEXT))";
command.CommandText = $"SELECT {objectWithArray}";

// act
var reader = (SnowflakeDbDataReader) command.ExecuteReader();

// assert
Assert.IsTrue(reader.Read());
var grades = reader.GetObject<GradesWithList>(0);
Assert.NotNull(grades);
CollectionAssert.AreEqual(new List<string> {"Excellent", "Poor"}, grades.Names);
}
}
}
}
}
Loading

0 comments on commit 3dd32c0

Please sign in to comment.