# 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
| **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
| 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
| 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
| 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
| 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.