Skip to content

Fix | Write DateOnly instances to sql_variant columns of table-valued parameters as date values - #4439

Merged
priyankatiwari08 merged 3 commits into
dotnet:mainfrom
edwardneal:fix/dateonly-tvp-variant
Aug 24, 2026
Merged

priyankatiwari08 merged 3 commits into
dotnet:mainfrom
edwardneal:fix/dateonly-tvp-variant

Conversation

@edwardneal

Copy link
Copy Markdown
Contributor

Description

This builds on #4294, and handles the only other issue I saw while investigating #3934.

If a user-defined table type exists with a column of type sql_variant, client applications can insert a DateOnly instance into this. It's supposed to be sent with a type of date, but is actually sent as a datetime.

Besides a point around correctness, it presents an issue when sending DateOnly instances which are valid values for date but not for datetime: these values overflow.

This PR fixes the issue, transporting all DateOnly instances with the date type on modern .NET. On .NET Framework, there's no DateOnly type - and thus there's no way for the client to encapsulate a date value within a sql_variant column.

@ErikEJ, this covers the only other way to write DateOnly instances to SQL Server and should hopefully completely close #3934. SqlClient will continue to read DateTime instances by default, but this is needed for backwards compatibility purposes.

NB: similar issues also exist with TimeOnly instances. TdsParser assumes that only TimeSpan instances will be written as times, so there are failures to cast in a few different places.

Issues

Builds on #4294. Possible resolution to #3934.

Testing

#4294 added the relevant tests, with an exemption carved out for this use case. I've removed the exemption and verified that it covers the test case.

Instances of DateOnly stored within a SqlDataRecord field of type Variant will now be sent as dates, not datetimes.

By extension: sending DateOnly instances with values outside the acceptable range for a datetime will no longer throw overflow exceptions.
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@ErikEJ ErikEJ left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@paulmedynski paulmedynski moved this from To triage to Backlog in SqlClient Board Jul 16, 2026
@cheenamalhotra cheenamalhotra added this to the 7.1.0-preview3 milestone Jul 20, 2026
@cheenamalhotra cheenamalhotra moved this from Backlog to In review in SqlClient Board Jul 20, 2026
@cheenamalhotra

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).

@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 11.11111% with 24 lines in your changes missing coverage. Please review.
✅ Project coverage is 62.64%. Comparing base (fdebcd2) to head (226969c).
⚠️ Report is 66 commits behind head on main.

Files with missing lines Patch % Lines
...c/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs 9.09% 20 Missing ⚠️
...c/Microsoft/Data/SqlClient/Server/SqlDataRecord.cs 0.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4439      +/-   ##
==========================================
- Coverage   65.83%   62.64%   -3.20%     
==========================================
  Files         287      283       -4     
  Lines       43763    66949   +23186     
==========================================
+ Hits        28812    41938   +13126     
- Misses      14951    25011   +10060     
Flag Coverage Δ
CI-SqlClient ?
PR-SqlClient-Project 62.64% <11.11%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

benrr101
benrr101 previously approved these changes Jul 22, 2026

@benrr101 benrr101 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Small change but seems pretty important!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses a correctness issue when sending DateOnly values into sql_variant columns in table-valued parameters (TVPs): the value was being transported as datetime rather than date, which can overflow for DateOnly min/max values and yields an incorrect base type.

Changes:

  • Updates TVP/SMI value-setting logic so DateOnly written to sql_variant is transported with base type date (modern .NET only).
  • Relaxes variant metadata assertions to allow SqlDbType.Date where variant-type metadata is tracked.
  • Updates manual variant tests to remove the prior overflow/“datetime” exemptions now that the scenario should succeed.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/DateTimeVariantTests.cs Removes expected overflow exceptions / base-type overrides for DateOnly in sql_variant TVP scenarios.
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs Routes DateOnly through date-specific variant metadata handling for TVP writes; also adjusts sql-value retrieval logic for SqlDbType.Date.
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/SqlRecordBuffer.cs Allows SqlDbType.Date in the debug assertion for variant metadata.

Ensure that SqlDataRecord.GetSqlValue doesn't return a DateOnly instance.

Apply the same pattern as SqlDataReader - directly expose the original variant type metadata, and base the decision on that.
@apoorvdeshmukh

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).

@priyankatiwari08
priyankatiwari08 merged commit 7054399 into dotnet:main Aug 24, 2026
358 checks passed
@github-project-automation github-project-automation Bot moved this from In review to Done in SqlClient Board Aug 24, 2026
priyankatiwari08 added a commit that referenced this pull request Aug 25, 2026
Both are user-facing fixes merged into the preview3 milestone that were
not yet captured in the release notes or CHANGELOG:

- #4439: DateOnly values in sql_variant TVP columns were sent as datetime
  instead of date, overflowing for values outside the datetime range.
- #4445: ServerCertificate pin validation was skipped when the platform
  reported no TLS policy errors, and an unloadable certificate file fell
  back to host-name validation instead of failing closed.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8c691319-4c66-40f6-a88e-b453937052f1
@edwardneal
edwardneal deleted the fix/dateonly-tvp-variant branch August 25, 2026 19:13
This was referenced Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Support sql_variant containing DateOnly as native SQL date without client conversion

8 participants