tds-driver 0.2.0

A TDS (Microsoft SQL Server) driver for Rust
Documentation
# TDS Protocol Compatibility


This document tracks `tds-driver`'s coverage of the Microsoft Tabular Data
Stream (MS-TDS) protocol. It is a maintained snapshot โ€” code references may
drift; treat the ratings as the source of truth and file an issue for
discrepancies.

Legend: โœ… full ยท ๐ŸŸก partial ยท โŒ missing ยท N/A not applicable.

## Protocol-version support


| TDS version | SQL Server | Rating | Notes |
|---|---|---|---|
| **8.0** | 2022 | โœ… Full | TLS-before-prelogin "strict" mode (`EncryptionLevel::Strict`), `tds/8.0` ALPN, and client-certificate (mutual-TLS) login on native-tls + rustls. 8.0 reuses 7.4 tokens over mandatory TLS; the only backend caveat is that opentls cannot advertise ALPN (see below). |
| **7.4** | 2012โ€“2019 | โœ… Full | Login (`FeatureLevel::SqlServerN`), routing ENVCHANGE, `fReadOnlyIntent`, FedAuth prelogin option + FeatureExt, FEATUREEXTACK, FEDAUTHINFO (0xEE), SESSIONSTATE (0xE4). The only deferral is *transparent reconnect* โ€” SESSIONSTATE is decoded and stored, but not yet replayed to silently re-establish a dropped session. |
| **7.3 A/B** | 2008 / R2 | โœ… Full (`tds73`) | date / time / datetime2 / datetimeoffset types, NBCROW. |
| **7.2** | 2005 | โœ… Full | PLP / varchar(max), XML, MARS / transaction-descriptor headers, SQL_VARIANT (read + write), UDT (0xF0) raw-value decode. |
| **7.1** | 2000 | โŒ None | Rejected: `Client::connect` fails with `Error::Protocol` on a LOGINACK below 7.2, as SqlClient's does. Every SQL batch, RPC and Transaction Manager request carries an ALL_HEADERS block, which 7.2 introduced (MS-TDS 2.2.5.3), and every token is read in its 7.2 layout, including INFO tokens sent before LOGINACK, so a 7.1 server's login can also fail to parse first. Never tested against SQL Server 2000. |
| **7.0** | 7.0 | โŒ None | Rejected at connect, as 7.1 is. Not a target. |

There is **no Microsoft "TDS 6.0"** โ€” the Microsoft protocol line is
7.0 โ†’ 7.1 โ†’ 7.2 โ†’ 7.3A โ†’ 7.3B โ†’ 7.4 โ†’ 8.0. Sybase-era TDS 4.2/5.0 predate
MS-TDS and are a separate protocol lineage, out of scope for this driver.
TDS 8.0 has no distinct LOGIN7 version โ€” it reuses 7.4 tokens over mandatory
TLS, so "8.0" is a transport/ALPN distinction.

**Summary:** TDS 7.2 through 8.0 are fully supported. The only remaining
elements are optional and rarely used: transparent session recovery (the
SESSIONSTATE token is decoded and stored, just not replayed on reconnect),
CLR UDT *object* deserialization (raw bytes are surfaced), and `tds/8.0` ALPN
on the opentls backend (an upstream-crate limitation) โ€” none of which any
standard query, bulk-load, RPC, or transaction path depends on.

## Feature matrix


### Client โ†’ server messages

| Message | Status |
|---|---|
| PRELOGIN (0x12) | โœ… (VERSION/ENCRYPTION/INSTOPT/THREADID/MARS emitted; server options decoded and INSTOPT validated) |
| LOGIN7 (0x10) | โœ… |
| SQL Batch (0x01) | โœ… |
| RPC request (0x03) | โœ… by-ID procs and named procs, incl. OUT params and table-valued parameters (#328) |
| Bulk load (0x07) | โœ… whole-table and column-list |
| SSPI (0x11) | โœ… |
| FedAuth token | โœ… via LOGIN7 FeatureExt |
| Attention / cancel (0x06) | โœ… (`Client::cancel_query`) |
| Transaction Manager request (0x0E) | โœ… (`begin`/`commit`/`rollback`/`save` with isolation levels) |

### Server โ†’ client tokens

| Token | Status |
|---|---|
| COLMETADATA, ROW, NBCROW, DONE/PROC/INPROC | โœ… |
| ENVCHANGE, ERROR/INFO, LOGINACK | โœ… |
| RETURNVALUE, RETURNSTATUS, ORDER, SSPI | โœ… |
| FEATUREEXTACK | โœ… |
| ALTMETADATA / ALTROW (compute-by) | โœ… |
| COLINFO (0xA5) | โœ… |
| TABNAME (0xA4) | โœ… |
| FEDAUTHINFO (0xEE) | โœ… (STSURL + SPN surfaced for AAD flows) |
| SESSIONSTATE (0xE4) | โœ… decoded + stored (transparent-reconnect replay not yet implemented) |

### Data types

| Type | Status |
|---|---|
| Fixed-len ints/bit/float/money/datetime(4) | โœ… |
| Nullable var-len (Intn/Bitn/Floatn/Guid/Money/Datetimen/Decimaln/Numericn) | โœ… |
| Char/binary + collation, Text/NText/Image | โœ… |
| PLP (max types), XML | โœ… |
| date / time / datetime2 / datetimeoffset (7.3) | โœ… (`tds73`) |
| Numeric / Decimal (incl. automatic scale rescaling of params) | โœ… |
| SQL_VARIANT (0x62) | โœ… read + write |
| UDT (0xF0) | โœ… raw-value decode (surfaced as bytes; CLR object deserialization out of scope) |

### Encryption & auth

| Feature | Status |
|---|---|
| Encryption NotSupported / Off / On / Required | โœ… |
| Strict (TDS 8.0, TLS-first) | โœ… (`tds80`) |
| `tds/8.0` ALPN | ๐ŸŸก native-tls + rustls โœ…, opentls โŒ (backend cannot advertise ALPN) |
| ENCRYPT_CLIENT_CERT (mutual TLS) | โœ… (`Config::client_certificate` / `client_certificate_pkcs12`) |
| SQL auth (zeroized) | โœ… |
| Windows NTLM/SSPI (Windows `winauth`; Unix `sspi-rs`) | โœ… |
| Kerberos/GSSAPI (Unix `integrated-auth-gssapi`) | โœ… |
| AAD / federated token | โœ… (`AuthMethod::aad_token`) |

## Remaining optional items


None of the following block standard operation; they are tracked for
completeness and would be additive, backward-compatible features:

- **Transparent session recovery** โ€” the SESSIONSTATE token is already decoded
  and stored; replaying it to silently re-establish a dropped connection is the
  remaining step.
- **CLR UDT object deserialization** โ€” UDT values are decoded to raw bytes;
  interpreting them into CLR objects (e.g. `geometry`) is left to the caller.
- **opentls `tds/8.0` ALPN** โ€” verified infeasible with `opentls` 0.2.1's public
  API (no ALPN setter; the wrapped `SslConnector` is private). Use native-tls or
  rustls for TDS 8.0 strict mode. Tracked upstream against the `opentls` crate.