Skip to content

Commit

Permalink
enable structured types and add vectors documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-knozderko committed Oct 9, 2024
1 parent 3664e2e commit c3e59ff
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 48 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ How execute a query, use query bindings, run queries synchronously and asynchron

Using structured types: [Structured types](doc/StructuredTypes.md)

## Vector type

Using vector type: [Vector type](doc/VectorType.md)

## Stage Files

Using stage files within PUT/GET commands:
Expand Down
32 changes: 16 additions & 16 deletions Snowflake.Data.Tests/IntegrationTests/StructuredArraysIT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public void TestSelectArray()
Assert.IsTrue(reader.Read());

// act
var array = reader.GetStucturedArray<string>(0);
var array = reader.GetArray<string>(0);

// assert
Assert.AreEqual(3, array.Length);
Expand All @@ -54,7 +54,7 @@ public void TestSelectArrayOfObjects()
Assert.IsTrue(reader.Read());

// act
var array = reader.GetStucturedArray<Identity>(0);
var array = reader.GetArray<Identity>(0);

// assert
Assert.AreEqual(2, array.Length);
Expand All @@ -79,7 +79,7 @@ public void TestSelectArrayOfArrays()
Assert.IsTrue(reader.Read());

// act
var array = reader.GetStucturedArray<string[]>(0);
var array = reader.GetArray<string[]>(0);

// assert
Assert.AreEqual(2, array.Length);
Expand All @@ -104,7 +104,7 @@ public void TestSelectArrayOfMap()
Assert.IsTrue(reader.Read());

// act
var array = reader.GetStucturedArray<Dictionary<string, string>>(0);
var array = reader.GetArray<Dictionary<string, string>>(0);

// assert
Assert.AreEqual(1, array.Length);
Expand Down Expand Up @@ -134,7 +134,7 @@ public void TestSelectSemiStructuredTypesInArray(string valueSfString, string ex
Assert.IsTrue(reader.Read());

// act
var array = reader.GetStucturedArray<string>(0);
var array = reader.GetArray<string>(0);

// assert
Assert.NotNull(array);
Expand All @@ -159,7 +159,7 @@ public void TestSelectArrayOfIntegers()
Assert.IsTrue(reader.Read());

// act
var array = reader.GetStucturedArray<int>(0);
var array = reader.GetArray<int>(0);

// assert
Assert.AreEqual(3, array.Length);
Expand All @@ -184,7 +184,7 @@ public void TestSelectArrayOfLong()
Assert.IsTrue(reader.Read());

// act
var array = reader.GetStucturedArray<long>(0);
var array = reader.GetArray<long>(0);

// assert
Assert.AreEqual(3, array.Length);
Expand All @@ -209,7 +209,7 @@ public void TestSelectArrayOfFloats()
Assert.IsTrue(reader.Read());

// act
var array = reader.GetStucturedArray<float>(0);
var array = reader.GetArray<float>(0);

// assert
Assert.AreEqual(3, array.Length);
Expand All @@ -234,7 +234,7 @@ public void TestSelectArrayOfDoubles()
Assert.IsTrue(reader.Read());

// act
var array = reader.GetStucturedArray<double>(0);
var array = reader.GetArray<double>(0);

// assert
Assert.AreEqual(3, array.Length);
Expand All @@ -259,7 +259,7 @@ public void TestSelectArrayOfDoublesWithExponentNotation()
Assert.IsTrue(reader.Read());

// act
var array = reader.GetStucturedArray<double>(0);
var array = reader.GetArray<double>(0);

// assert
Assert.AreEqual(2, array.Length);
Expand All @@ -284,7 +284,7 @@ public void TestSelectStringArrayWithNulls()
Assert.IsTrue(reader.Read());

// act
var array = reader.GetStucturedArray<string>(0);
var array = reader.GetArray<string>(0);

// assert
Assert.AreEqual(3, array.Length);
Expand All @@ -309,7 +309,7 @@ public void TestSelectIntArrayWithNulls()
Assert.IsTrue(reader.Read());

// act
var array = reader.GetStucturedArray<int?>(0);
var array = reader.GetArray<int?>(0);

// assert
Assert.AreEqual(3, array.Length);
Expand All @@ -334,7 +334,7 @@ public void TestSelectNullArray()
Assert.IsTrue(reader.Read());

// act
var nullArray = reader.GetStucturedArray<string>(0);
var nullArray = reader.GetArray<string>(0);

// assert
Assert.IsNull(nullArray);
Expand All @@ -358,7 +358,7 @@ public void TestThrowExceptionForInvalidArray()
Assert.IsTrue(reader.Read());

// act
var thrown = Assert.Throws<SnowflakeDbException>(() => reader.GetStucturedArray<string>(0));
var thrown = Assert.Throws<SnowflakeDbException>(() => reader.GetArray<string>(0));

// assert
SnowflakeDbExceptionAssert.HasErrorCode(thrown, SFError.STRUCTURED_TYPE_READ_DETAILED_ERROR);
Expand All @@ -384,7 +384,7 @@ public void TestThrowExceptionForInvalidArrayElement()
Assert.IsTrue(reader.Read());

// act
var thrown = Assert.Throws<SnowflakeDbException>(() => reader.GetStucturedArray<Guid>(0));
var thrown = Assert.Throws<SnowflakeDbException>(() => reader.GetArray<Guid>(0));

// assert
SnowflakeDbExceptionAssert.HasErrorCode(thrown, SFError.STRUCTURED_TYPE_READ_ERROR);
Expand All @@ -411,7 +411,7 @@ public void TestThrowExceptionForNextedInvalidElement()
Assert.IsTrue(reader.Read());

// act
var thrown = Assert.Throws<SnowflakeDbException>(() => reader.GetStucturedArray<AnnotatedClassForConstructorConstruction>(0));
var thrown = Assert.Throws<SnowflakeDbException>(() => reader.GetArray<AnnotatedClassForConstructorConstruction>(0));

// assert
SnowflakeDbExceptionAssert.HasErrorCode(thrown, SFError.STRUCTURED_TYPE_READ_DETAILED_ERROR);
Expand Down
33 changes: 6 additions & 27 deletions Snowflake.Data/Client/SnowflakeDbDataReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ public override int GetValues(object[] values)
return count;
}

internal T GetObject<T>(int ordinal)
public T GetObject<T>(int ordinal)
where T : class, new()
{
try
Expand Down Expand Up @@ -282,9 +282,11 @@ public T[] GetArray<T>(int ordinal)
{
var rowType = resultSet.sfResultSetMetaData.rowTypes[ordinal];
var fields = rowType.fields;
if (fields == null || fields.Count == 0 || !JsonToStructuredTypeConverter.IsVectorType(rowType.type))
var isArrayOrVector = JsonToStructuredTypeConverter.IsArrayType(rowType.type) ||
JsonToStructuredTypeConverter.IsVectorType(rowType.type);
if (fields == null || fields.Count == 0 || !isArrayOrVector)
{
throw new StructuredTypesReadingException($"Method GetArray<{typeof(T)}> can be used only for vector types");
throw new StructuredTypesReadingException($"Method GetArray<{typeof(T)}> can be used only for for structured array or vector types");
}

var stringValue = GetString(ordinal);
Expand All @@ -299,30 +301,7 @@ public T[] GetArray<T>(int ordinal)
}
}

internal T[] GetStucturedArray<T>(int ordinal)
{
try
{
var rowType = resultSet.sfResultSetMetaData.rowTypes[ordinal];
var fields = rowType.fields;
if (fields == null || fields.Count == 0 || !JsonToStructuredTypeConverter.IsArrayType(rowType.type))
{
throw new StructuredTypesReadingException($"Method GetArray<{typeof(T)}> can be used only for structured array");
}

var stringValue = GetString(ordinal);
var json = stringValue == null ? null : JArray.Parse(stringValue);
return JsonToStructuredTypeConverter.ConvertArray<T>(fields, json);
}
catch (Exception e)
{
if (e is SnowflakeDbException)
throw;
throw StructuredTypesReadingHandler.ToSnowflakeDbException(e, "when getting an array");
}
}

internal Dictionary<TKey, TValue> GetMap<TKey, TValue>(int ordinal)
public Dictionary<TKey, TValue> GetMap<TKey, TValue>(int ordinal)
{
try
{
Expand Down
6 changes: 1 addition & 5 deletions doc/StructuredTypes.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@ Currently, reading structured types is available only for JSON result format, so
ALTER SESSION SET DOTNET_QUERY_RESULT_FORMAT = JSON;
```

You can enable the feature by setting parameters:
```sql
ALTER SESSION SET ENABLE_STRUCTURED_TYPES_IN_CLIENT_RESPONSE = true;
ALTER SESSION SET IGNORE_CLIENT_VERSION_IN_STRUCTURED_TYPES_RESPONSE = true;
```
The structured types feature is enabled starting from v4.2.0 driver version.

## Structured types vs semi-structured types

Expand Down
18 changes: 18 additions & 0 deletions doc/VectorType.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Vector type

Vector type represents an array of either integer or float type and a fixed size.
Examples:
- `[4, 5, 6]::VECTOR(INT, 3)` is a 3 elements vector of integers
- `[1.1, 2.2]::VECTOR(FLOAT, 2)` is a 2 elements vector of floats

More about vectors you can read here: [Vector data types](https://docs.snowflake.com/en/sql-reference/data-types-vector).

The driver allows to read a vector column into `int[]` or `float[]` arrays by calling `T[] SnowflakeDbReader.GetArray<T>(int ordinal)`
method for either int or float types.

```csharp
var reader = (SnowflakeDbDataReader) command.ExecuteReader();
Assert.IsTrue(reader.Read());
int[] intVector = reader.GetArray<int>(0);
float[] floatVector = reader.GetArray<float>(1);
```

0 comments on commit c3e59ff

Please sign in to comment.