Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3604,7 +3604,9 @@ Before you call <xref:Microsoft.Data.SqlClient.SqlCommand.Prepare%2A>, specify t

If you call an `Execute` method after calling <xref:Microsoft.Data.SqlClient.SqlCommand.Prepare%2A>, any parameter value that is larger than the value specified by the <xref:Microsoft.Data.SqlClient.SqlParameter.Size%2A> property is automatically truncated to the original specified size of the parameter, and no truncation errors are returned.

Output parameters (whether prepared or not) must have a user-specified data type. If you specify a variable length data type, you must also specify the maximum <xref:Microsoft.Data.SqlClient.SqlParameter.Size%2A>.
Output parameters (whether prepared or not) must have a user-specified data type. If you specify a variable length data type except vector, you must also specify the maximum <xref:Microsoft.Data.SqlClient.SqlParameter.Size%2A>.

For vector data types, the <xref:Microsoft.Data.SqlClient.SqlParameter.Size%2A> property is ignored. The size of the vector is inferred from the <xref:Microsoft.Data.SqlClient.SqlParameter.Value%2A> of type <xref:Microsoft.Data.SqlTypes.SqlVector%2A>.

Prior to Visual Studio 2010, <xref:Microsoft.Data.SqlClient.SqlCommand.Prepare%2A> threw an exception. Beginning in Visual Studio 2010, this method does not throw an exception.

Expand Down
25 changes: 10 additions & 15 deletions doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,11 @@
<summary>Represents a vector value in SQL Server.</summary>
</SqlVector>
<ctor1>
<param name="length"></param>
<summary>
Constructs a null vector of the given length. SQL Server requires vector arguments to specify their length even when null.
</summary>
<exception cref="T:System.ArgumentOutOfRangeException">
Vector length must be non-negative.
</exception>
</ctor1>
<ctor2>
<param name="memory"></param>
<summary>
Constructs a vector with the given values.
</summary>
</ctor2>
</ctor1>
<IsNull>
<inheritdoc/>
</IsNull>
Expand All @@ -37,13 +28,17 @@
Returns the number of elements in the vector.
</summary>
</Length>
<Size>
<summary>
Returns the number of bytes required to represent this vector when communicating with SQL Server.
</summary>
</Size>
<Memory>
<summary>Returns the vector values as a memory region. No copies are made.</summary>
</Memory>
<CreateNull>
<param name="length"></param>
<summary>
Constructs a null vector of the given length. SQL Server requires vector arguments to specify their length even when null.
</summary>
<exception cref="T:System.ArgumentOutOfRangeException">
Vector length must be non-negative.
</exception>
</CreateNull>
</members>
</docs>
Original file line number Diff line number Diff line change
Expand Up @@ -123,23 +123,21 @@ public SqlJson(System.Text.Json.JsonDocument jsonDoc) { }
}

/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/SqlVector/*' />
public sealed class SqlVector<T> : System.Data.SqlTypes.INullable
public readonly struct SqlVector<T> : System.Data.SqlTypes.INullable
where T : unmanaged
{
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/ctor1/*' />
public SqlVector(int length) { }
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/ctor2/*' />
public SqlVector(System.ReadOnlyMemory<T> memory) { }
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/IsNull/*' />
public bool IsNull => throw null;
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/Null/*' />
public static SqlVector<T> Null => throw null;
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/Length/*' />
public int Length { get { throw null; } }
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/Size/*' />
public int Size { get { throw null; } }
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/Memory/*' />
public System.ReadOnlyMemory<T> Memory { get { throw null; } }
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/CreateNull/*' />
public static SqlVector<T> CreateNull(int length) { throw null; }
}
}
namespace Microsoft.Data.SqlClient
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2417,22 +2417,20 @@ public SqlJson(System.Text.Json.JsonDocument jsonDoc) { }
}

/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/SqlVector/*' />
public sealed class SqlVector<T> : System.Data.SqlTypes.INullable
public readonly struct SqlVector<T> : System.Data.SqlTypes.INullable
where T : unmanaged
{
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/ctor1/*' />
public SqlVector(int length) { }
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/ctor2/*' />
public SqlVector(System.ReadOnlyMemory<T> memory) { }
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/IsNull/*' />
public bool IsNull => throw null;
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/Null/*' />
public static SqlVector<T> Null => throw null;
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/Length/*' />
public int Length { get { throw null; } }
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/Size/*' />
public int Size { get { throw null; } }
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/Memory/*' />
public System.ReadOnlyMemory<T> Memory { get { throw null; } }
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/CreateNull/*' />
public static SqlVector<T> CreateNull(int length) { throw null; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -993,7 +993,7 @@ internal SqlVector<T> GetSqlVector<T>() where T : unmanaged
{
if (IsNull)
{
return new SqlVector<T>(_value._vectorInfo._elementCount);
return SqlVector<T>.CreateNull(_value._vectorInfo._elementCount);
}
return new SqlVector<T>(SqlBinary.Value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3365,10 +3365,7 @@ private T GetFieldValueFromSqlBufferInternal<T>(SqlBuffer data, _SqlMetaData met
{
if (typeof(T) == typeof(string) && metaData.metaType.SqlDbType == SqlDbTypeExtensions.Vector)
{
if (data.IsNull)
return (T)(object)data.String;
else
return (T)(object)data.GetSqlVector<float>().GetString();
return (T)(object)data.String;
}
// the requested type is likely to be one that isn't supported so try the cast and
// unless there is a null value conversion then feedback the cast exception with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ private object GetVectorReturnValue()
switch (elementType)
{
case MetaType.SqlVectorElementType.Float32:
return new SqlVector<float>(elementCount);
return SqlVector<float>.CreateNull(elementCount);
default:
throw SQL.VectorTypeNotSupported(elementType.ToString());
}
Expand Down Expand Up @@ -857,8 +857,13 @@ public override int Size
{
throw ADP.InvalidSizeValue(value);
}
PropertyChanging();
_size = value;

// We ignore the Size property for Vector types, as it is not applicable.
if (_metaType == null || _metaType.SqlDbType != SqlDbTypeExtensions.Vector)
{
PropertyChanging();
_size = value;
}
}
}
}
Expand Down Expand Up @@ -1970,7 +1975,8 @@ internal void Prepare(SqlCommand cmd)
{
throw ADP.PrepareParameterType(cmd);
}
else if (!ShouldSerializeSize() && !_metaType.IsFixed)
// For vector datatype we do not require size to be specified. It is inferred from the SqlParameter.Value.
else if (!ShouldSerializeSize() && !_metaType.IsFixed && _metaType.SqlDbType != SqlDbTypeExtensions.Vector)
{
throw ADP.PrepareParameterSize(cmd);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
namespace Microsoft.Data.SqlTypes;

/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/SqlVector/*' />
public sealed class SqlVector<T> : INullable, ISqlVector
public readonly struct SqlVector<T> : INullable, ISqlVector
where T : unmanaged
{
#region Constants
Expand All @@ -31,13 +31,13 @@ public sealed class SqlVector<T> : INullable, ISqlVector
private readonly byte _elementType;
private readonly byte _elementSize;
private readonly byte[] _tdsBytes;

private readonly int _size;

#endregion

#region Constructors

/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/ctor1/*' />
public SqlVector(int length)
private SqlVector(int length)
{
if (length < 0)
{
Expand All @@ -49,21 +49,24 @@ public SqlVector(int length)
IsNull = true;

Length = length;
Size = TdsEnums.VECTOR_HEADER_SIZE + (_elementSize * Length);
_size = TdsEnums.VECTOR_HEADER_SIZE + (_elementSize * Length);

_tdsBytes = Array.Empty<byte>();
Memory = new();
}

/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/ctor2/*' />
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/CreateNull/*' />
public static SqlVector<T> CreateNull(int length) => new(length);

/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/ctor1/*' />
public SqlVector(ReadOnlyMemory<T> memory)
{
(_elementType, _elementSize) = GetTypeFieldsOrThrow();

IsNull = false;

Length = memory.Length;
Size = TdsEnums.VECTOR_HEADER_SIZE + (_elementSize * Length);
_size = TdsEnums.VECTOR_HEADER_SIZE + (_elementSize * Length);

_tdsBytes = MakeTdsBytes(memory);
Memory = memory;
Expand All @@ -73,7 +76,7 @@ internal SqlVector(byte[] tdsBytes)
{
(_elementType, _elementSize) = GetTypeFieldsOrThrow();

(Length, Size) = GetCountsOrThrow(tdsBytes);
(Length, _size) = GetCountsOrThrow(tdsBytes);

IsNull = false;

Expand All @@ -99,25 +102,25 @@ internal string GetString()
#region Properties

/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/IsNull/*' />
public bool IsNull { get; init; }
public bool IsNull { get; }

/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/Null/*' />
public static SqlVector<T>? Null => null;

/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/Length/*' />
public int Length { get; init; }
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/Size/*' />
public int Size { get; init; }

public int Length { get; }

/// <include file='../../../../doc/snippets/Microsoft.Data.SqlTypes/SqlVector.xml' path='docs/members[@name="SqlVector"]/Memory/*' />
public ReadOnlyMemory<T> Memory { get; init; }
public ReadOnlyMemory<T> Memory { get; }

#endregion

#region ISqlVector Internal Properties
byte ISqlVector.ElementType => _elementType;
byte ISqlVector.ElementSize => _elementSize;
byte[] ISqlVector.VectorPayload => _tdsBytes;
int ISqlVector.Size => _size;

#endregion

#region Helpers
Expand Down Expand Up @@ -154,7 +157,7 @@ private byte[] MakeTdsBytes(ReadOnlyMemory<T> values)
// | Stream of Values | NN * sizeof(T) | [element bytes...] | Raw bytes for vector elements |
// +------------------------+-----------------+----------------------+--------------------------------------------------------------+

byte[] result = new byte[Size];
byte[] result = new byte[_size];

// Header Bytes
result[0] = VecHeaderMagicNo;
Expand Down
Loading
Loading