Add mssql-tds support for incremental PLP parameter write path - #207
Draft
Shiwani Gupta (shiwanigupta0809) wants to merge 4 commits into
Draft
Add mssql-tds support for incremental PLP parameter write path#207Shiwani Gupta (shiwanigupta0809) wants to merge 4 commits into
Shiwani Gupta (shiwanigupta0809) wants to merge 4 commits into
Conversation
Extend the existing sp_executesql serialize flow with a data-at-execution pause point rather than adding a parallel send path. RpcParameter gains a data_at_exec marker; its serialize writes the parameter header and opens an unknown-length PLP value, then stops, reusing the same write_type_info the atomic path uses. begin_sp_executesql takes a single named_params list (some marked data_at_exec, mirroring ODBC SQL_DATA_AT_EXEC), partitions materialized vs streamed, sends materialized params through the normal path, and streams the rest via write_streamed_chunk/end_streamed_param. PacketWriter suspend/resume parks the in-progress message as owned client state, the write analogue of the incremental read pause. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
A failed write_streamed_chunk/end_streamed_param leaves a partial message on the wire, so re-parking it as Active let the caller keep appending to a corrupt message. Add abort_streamed_write to drop the message (state -> Idle, not resumable) and flag the connection for reset, matching msodbcsql's DAE teardown on a failed send. Add fault-injecting unit tests for both abort paths and e2e variations (empty value, many small chunks, connection reuse). Migrate the e2e test file to the current execute/ResultSet API. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Defer the PLP length field: the data-at-exec serialize now writes only the parameter header (status + TYPE_INFO), and the length field (PLP_UNKNOWN_LEN opener or PLP_NULL) is written lazily by the streaming driver. This lets a streamed parameter resolve to NULL before any data is sent, matching msodbcsql path 2 (SQLPutData(SQL_NULL_DATA)). Add write_streamed_null(); end_streamed_param emits PLP_NULL for a NULL-signalled param, the terminator for a value, or opener+terminator for an untouched (empty) param. Guard both orderings (chunk-after-null, null-after-chunk). Add unit and e2e tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Shiwani Gupta (shiwanigupta0809)
force-pushed
the
dev/shiwanigupta/plp-write
branch
from
August 10, 2026 16:27
f855799 to
907fd54
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds a data-at-execution (streamed) PLP parameter write path to mssql-tds for large nvarchar(max) / varchar(max) / varbinary(max) values in sp_executesql. The value is streamed to the server in chunks instead of being materialized up front, mirroring msodbcsql's incremental PLP write. This is the TDS-layer foundation for a later ODBC SQLPutData / SQLParamData. Scope: mssql-tds only.
What this adds
Streaming entry points on TdsClient, mirroring ODBC's begin/put/end:
begin_sp_executesql — sends the RPC prefix (headers, positional args, materialized params) + the first streamed param's header, parks the half-written message, returns NeedData.
write_streamed_chunk — appends one length-prefixed chunk (empty chunks ignored — a zero-length header is the terminator). Writes the unknown-length opener lazily on the first chunk.
write_streamed_null — marks the current param SQL NULL instead of streaming chunks (the SQLPutData(SQL_NULL_DATA) case).
end_streamed_param — closes the value (PLP_NULL, terminator, or opener+terminator for an empty value), then opens the next streamed param (NeedData) or finalizes and positions on the response (Done).
RpcParameter::data_at_exec() marker; PacketWriter::suspend/resume to park a half-written message across calls; SqlRpc::serialize_prefix to serialize up to materialized params without finalizing.
Testing
Unit (offline mock): header serialization, non-MAX/encrypted rejection, single/multi-chunk framing, empty-chunk skip, two-param lifecycle, materialized+streamed mix, multi-packet chunk, streamed-NULL framing + ordering guards, usage-error guards, and two fault-injection tests for the mid-stream abort.
E2E (live SQL Server): round-trips for nvarchar/varbinary/varchar(max), two params, mixed, multi-row, materialized NULL, streamed NULL, empty value, many small chunks, and connection reuse.
Not covered (deferred)
Always Encrypted on the streamed path (rejected); ODBC SQLPutData / SQLParamData (the next layer).
Related Issues
https://sqlclientdrivers.visualstudio.com/mssql-rs/_backlogs/backlog/mssql-rs%20Team/Features?workitem=46139
Checklist
cargo bfmtpassescargo bclippypassescargo btestpasses