Return correct type when invoking GetFieldType and GetProviderSpecificFieldType for vector float32 column#4105
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes SqlDataReader.GetFieldType() and GetProviderSpecificFieldType() to report the correct CLR type for vector(float32) columns (matching how GetValue() already materializes the value as SqlVector<float>), addressing issue #4104.
Changes:
- Update
SqlDataReaderto returntypeof(SqlVector<float>)forSqlDbTypeExtensions.Vector(float32) inGetFieldTypeInternal. - Apply the same correction to
GetProviderSpecificFieldTypeInternal. - Add a manual test covering both APIs for a
vector(float32)column.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDataReader.cs |
Special-cases Vector metadata so GetFieldType/GetProviderSpecificFieldType report SqlVector<float> instead of the metatype’s default byte[]. |
src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/VectorTest/NativeVectorFloat32Tests.cs |
Adds test coverage to validate the updated type reporting and alignment with GetValue(). |
|
Shouldn't this be fixed on the SqlBuffer layer. It already identifies SqlVector and does the deserialization. Something like diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs
index dc1abf1c..04683c3c 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs
@@ -1136,8 +1136,16 @@ namespace Microsoft.Data.SqlClient
case StorageType.String:
return String;
case StorageType.SqlBinary:
- case StorageType.Vector:
return ByteArray;
+ case StorageType.Vector:
+ var elementType = (MetaType.SqlVectorElementType)_value._vectorInfo._elementType;
+ switch (elementType)
+ {
+ case MetaType.SqlVectorElementType.Float32:
+ return GetSqlVector<float>();
+ default:
+ throw SQL.VectorTypeNotSupported(elementType.ToString());
+ }
case StorageType.SqlCachedBuffer:
{
// If we have a CachedBuffer, it's because it's an XMLTYPE column
@@ -1213,6 +1221,15 @@ namespace Microsoft.Data.SqlClient
case StorageType.Json:
return typeof(SqlJson);
// Time Date DateTime2 and DateTimeOffset have no direct Sql type to contain them
+ case StorageType.Vector:
+ var elementType = (MetaType.SqlVectorElementType)_value._vectorInfo._elementType;
+ switch (elementType)
+ {
+ case MetaType.SqlVectorElementType.Float32:
+ return typeof(SqlVector<float>);
+ default:
+ throw SQL.VectorTypeNotSupported(elementType.ToString());
+ }
}
}
else
@@ -1262,7 +1279,14 @@ namespace Microsoft.Data.SqlClient
case StorageType.Json:
return typeof(string);
case StorageType.Vector:
- return typeof(byte[]);
+ var elementType = (MetaType.SqlVectorElementType)_value._vectorInfo._elementType;
+ switch (elementType)
+ {
+ case MetaType.SqlVectorElementType.Float32:
+ return typeof(SqlVector<float>);
+ default:
+ throw SQL.VectorTypeNotSupported(elementType.ToString());
+ }
#if NET
case StorageType.Time:
return typeof(TimeOnly);I think this last hunk is the current issue. The type returned should be retrievable. Not sure if some of this should be extracted to a helper function or something though. And more than just Float32 could be supported these days, like Half Precision Float Vectors |
Thanks for the detailed analysis @rhuijben! You're right that And yes, support for Half precision vectors is coming soon in SqlClient. :) |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4105 +/- ##
==========================================
- Coverage 73.22% 66.55% -6.67%
==========================================
Files 280 274 -6
Lines 43000 65798 +22798
==========================================
+ Hits 31486 43794 +12308
- Misses 11514 22004 +10490
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Updated [DotNetEnv](https://github.com/tonerdo/dotnet-env) from 3.1.1 to 3.2.0. <details> <summary>Release notes</summary> _Sourced from [DotNetEnv's releases](https://github.com/tonerdo/dotnet-env/releases)._ ## 3.2.0 - Switch parsing to Superpower (from Sprache) - Fix utf8 parsing - Interpolated variables parsing Commits viewable in [compare view](tonerdo/dotnet-env@v3.1.1...v3.2.0). </details> Updated [Microsoft.AspNetCore.Authentication.Google](https://github.com/dotnet/dotnet) from 10.0.6 to 10.0.7. <details> <summary>Release notes</summary> _Sourced from [Microsoft.AspNetCore.Authentication.Google's releases](https://github.com/dotnet/dotnet/releases)._ No release notes found for this version range. Commits viewable in [compare view](https://github.com/dotnet/dotnet/commits). </details> Updated [Microsoft.Data.SqlClient](https://github.com/dotnet/sqlclient) from 7.0.0 to 7.0.1. <details> <summary>Release notes</summary> _Sourced from [Microsoft.Data.SqlClient's releases](https://github.com/dotnet/sqlclient/releases)._ ## 7.0.1 This update brings the following changes since the [7.0.0](https://github.com/dotnet/SqlClient/blob/release/7.0/release-notes/7.0/7.0.0.md) release: ### Fixed - Fixed `SqlBulkCopy` failing on SQL Server 2016 with `Invalid column name 'graph_type'` error. The column metadata query now uses dynamic SQL so that references to the `graph_type` column (introduced in SQL Server 2017) are not compiled on older versions that lack the column. ([#3714](dotnet/SqlClient#3714), [#4092](dotnet/SqlClient#4092), [#4147](dotnet/SqlClient#4147)) - Fixed `SqlBulkCopy` failing on Azure Synapse Analytics dedicated SQL pools. The column-list query previously used a variable-assignment pattern that Synapse does not support; it now uses `STRING_AGG` when targeting Synapse (engine edition 6) and falls back to the variable-assignment approach for SQL Server 2016 compatibility. ([#4149](dotnet/SqlClient#4149), [#4176](dotnet/SqlClient#4176), [#4182](dotnet/SqlClient#4182)) - Fixed `SqlDataReader.GetFieldType()` and `GetProviderSpecificFieldType()` returning `typeof(byte[])` instead of `typeof(SqlVector<float>)` for vector float32 columns. The methods now follow the same type-determination logic as `GetValue()`. ([#4104](dotnet/SqlClient#4104), [#4105](dotnet/SqlClient#4105), [#4152](dotnet/SqlClient#4152)) - Added missing `System.Data.Common` (v4.3.0) NuGet package dependency for .NET Framework consumers. The inbox `System.Data.Common` assembly on .NET Framework predates APIs such as `IDbColumnSchemaGenerator`; without the explicit NuGet dependency, consumers encountered `CS0012` compilation errors when using these types through `Microsoft.Data.SqlClient`. ([#4063](dotnet/SqlClient#4063), [#4074](dotnet/SqlClient#4074)) ### Changed - Enabled the User Agent TDS feature extension unconditionally. The `Switch.Microsoft.Data.SqlClient.EnableUserAgent` AppContext switch has been removed; the driver now always sends User Agent information during login. ([#4124](dotnet/SqlClient#4124), [#4154](dotnet/SqlClient#4154)) - Added type forwards from the core `Microsoft.Data.SqlClient` assembly to public types that were moved to the `Microsoft.Data.SqlClient.Extensions.Abstractions` package: `SqlAuthenticationMethod`, `SqlAuthenticationParameters`, `SqlAuthenticationProvider`, `SqlAuthenticationProviderException`, and `SqlAuthenticationToken`. This ensures binary compatibility for assemblies compiled against earlier versions of `Microsoft.Data.SqlClient` where these types lived in the core assembly. ([#4067](dotnet/SqlClient#4067), [#4117](dotnet/SqlClient#4117)) - Fixed API documentation include paths and duplicate doc snippets. ([#4084](dotnet/SqlClient#4084), [#4086](dotnet/SqlClient#4086), [#4107](dotnet/SqlClient#4107), [#4161](dotnet/SqlClient#4161)) ## Contributors We thank the following public contributors. Their efforts toward this project are very much appreciated. - [edwardneal](https://github.com/edwardneal) ## Target Platform Support - .NET Framework 4.6.2+ (Windows x86, Windows x64, Windows ARM64) - .NET 8.0+ (Windows x86, Windows x64, Windows ARM, Windows ARM64, Linux, macOS) ### Dependencies #### .NET 9.0 - Microsoft.Bcl.Cryptography 9.0.13 - Microsoft.Data.SqlClient.Extensions.Abstractions 1.0.0 - Microsoft.Data.SqlClient.Internal.Logging 1.0.0 - Microsoft.Data.SqlClient.SNI.runtime 6.0.2 - Microsoft.Extensions.Caching.Memory 9.0.13 - Microsoft.IdentityModel.JsonWebTokens 8.16.0 - Microsoft.IdentityModel.Protocols.OpenIdConnect 8.16.0 - Microsoft.SqlServer.Server 1.0.0 - System.Configuration.ConfigurationManager 9.0.13 - System.Security.Cryptography.Pkcs 9.0.13 #### .NET 8.0 - Microsoft.Bcl.Cryptography 8.0.0 - Microsoft.Data.SqlClient.Extensions.Abstractions 1.0.0 ... (truncated) Commits viewable in [compare view](dotnet/SqlClient@v7.0.0...v7.0.1). </details> Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Description
Fixes #4104.
GetFieldTypereturned type fromMetaType.ClassTypeThe fix follows similar pattern as
GetValueto determine correct type forVectormetatype.The fix has been extended to
GetProviderSpecificFieldTypewhich had similar issue.Issues
#4104
Testing
Extended NativeVectorFloat32Tests with test coverage for above APIs.
Guidelines
Please review the contribution guidelines before submitting a pull request: