Skip to content

feat: deprecate TDS 7.1 support - #1768

Merged
arthurschreiber merged 1 commit into
masterfrom
deprecate-tds-7-1
Aug 31, 2026
Merged

feat: deprecate TDS 7.1 support#1768
arthurschreiber merged 1 commit into
masterfrom
deprecate-tds-7-1

Conversation

@arthurschreiber

@arthurschreiber arthurschreiber commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

TDS 7.1 is only spoken by SQL Server 2000, which left extended support in April 2013, and it is the only protocol version that requires the pre-7.2 legacy paths (client-side emulated transaction state, 32-bit row counts, and other wire format differences). Every other maintained SQL Server driver has already dropped support for servers this old.

This PR emits a deprecation warning - once per process, typed as DeprecationWarning with the code TEDIOUS_DEP_TDS71 - when a connection negotiates TDS 7.1, so remaining users are surfaced before support is removed in the next major version:

(node:12345) [TEDIOUS_DEP_TDS71] DeprecationWarning: Support for TDS 7.1 (used by SQL Server 2000) is deprecated and will be removed in a future version of `tedious`.

The warning is keyed off the version negotiated in the server's LOGINACK response rather than the configured tdsVersion option, so it fires both when 7_1 is configured explicitly and when a server downgrades the connection. Being a proper DeprecationWarning means --trace-deprecation, --throw-deprecation, and --no-deprecation all apply, and process.on('warning') handlers can filter on warning.code.

The README and the tdsVersion option documentation are updated to mark 7_1 as deprecated.

Rollout

  1. This PR ships the warning in a v20 minor release.
  2. TDS 7.1 support is then removed in the next major version, which deletes all pre-7.2 code paths - including the emulated transaction state bookkeeping currently under discussion in fix: only update emulated transaction state when the statement succeeds #1767.

🤖 Generated with Claude Code

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-08-31T17:01:53.441586Z 34b0ce6 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@claude

claude Bot commented Aug 31, 2026

Copy link
Copy Markdown

Review

Overall this is a small, well-scoped change with solid test coverage (a real socket-based integration-style test rather than mocks). A few notes:

Code quality

  • src/token/handler.ts:364token.tdsVersion < '7_2' is a lexicographic string comparison, not a numeric/version comparison. It happens to produce the right answer for every value currently in versions ('7_1' < '7_2' → true, '7_3_A'/'7_4'/'8_0' < '7_2' → false), but that's incidental — it relies on all version strings sharing the same <digit>_<digit...> shape. Since the PR is specifically about TDS 7.1 (per the description, "only spoken by SQL Server 2000"), an explicit token.tdsVersion === '7_1' would say exactly what's meant and not depend on string-ordering happening to line up with version ordering. Alternatively, compare the numeric values already defined in src/tds-versions.ts (versions[token.tdsVersion] < versions['7_2']) if a range check is actually intended for future pre-7.2 versions.

Correctness

  • The warning is keyed off the negotiated version from the server's LOGINACK (token.tdsVersion), not the client's requested tdsVersion option — that's correct per the stated goal ("when a connection negotiates TDS 7.1"), since a server could in principle force a downgrade regardless of what was requested.
  • Confirmed DEFAULT_TDS_VERSION is '7_4' (src/connection.ts:190), so this only fires for users who explicitly opt into 7.1 (or a server that negotiates down to it) — low blast radius, no surprise warnings for the default config.
  • The tds71DeprecationWarning singleton with an emitted flag is a reasonable way to get "once per process" semantics without extra dependencies. It's only imported via the internal ../../src/token/handler path in the test, not re-exported from src/tedious.ts, so it doesn't leak onto the public API surface despite living in the same module as the exported handler classes.

Test coverage

  • test/unit/tds71-deprecation-test.ts is thorough: it spins up a fake TDS server, drives real PRELOGIN/LOGIN7 exchanges, and asserts both that the warning fires once across two 7.1 connections and that it's suppressed for 7.2+. Nice touch resetting tds71DeprecationWarning.emitted in beforeEach for isolation.
  • One gap: there's no negative test for a value that isn't a recognized TDS version string (shouldn't happen in practice since onLoginAck already guards on falsy tdsVersion, but worth a thought given the string-comparison point above).

Docs

  • README and the ConnectionOptions.tdsVersion JSDoc are updated consistently to flag 7_1 as deprecated. No other doc/config references to TDS 7.1 seem to need updating (no CHANGELOG.md in this repo).

Nothing blocking here — the string-comparison point is the only thing I'd actually push back on before merging, and it's a one-line fix.

@codecov

codecov Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.86%. Comparing base (760e96d) to head (34b0ce6).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1768      +/-   ##
==========================================
+ Coverage   80.71%   80.86%   +0.15%     
==========================================
  Files          90       90              
  Lines        4880     4887       +7     
  Branches      927      929       +2     
==========================================
+ Hits         3939     3952      +13     
+ Misses        643      638       -5     
+ Partials      298      297       -1     

☔ 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

TDS 7.1 is only spoken by SQL Server 2000, which left extended support
in April 2013, and it is the only protocol version that requires the
pre-7.2 legacy paths (client-side emulated transaction state, 32-bit
row counts, and other wire format differences). Every other maintained
SQL Server driver has already dropped it.

Emit a deprecation warning (once per process, with the warning code
`TEDIOUS_DEP_TDS71`) when a connection negotiates TDS 7.1, so
remaining users are surfaced before support is removed in the next
major version.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Aug 31, 2026

Copy link
Copy Markdown

Review: deprecate TDS 7.1 support (#1768)

Nice, focused change. I traced through the login flow and the version-comparison logic; overall it's correct and well tested. A few notes:

Correctness

  • token.tdsVersion < '7_2' is a string comparison (tdsVersion values are keys like '7_1', '7_2', '7_3_A', ..., not numbers). This happens to produce the right ordering today and mirrors the exact same pattern already used in done-token-parser.ts, colmetadata-token-parser.ts, and infoerror-token-parser.ts, so it's consistent with existing conventions rather than a new bug. Worth knowing the string-comparison trick is fragile if a future version string breaks the lexicographic-equals-numeric assumption (e.g. a hypothetical '7_10'), but that's a pre-existing pattern, not something introduced here.
  • The !token.tdsVersion guard a few lines above (handler.ts:349) ensures we never reach the deprecation check with an unknown/undefined version, so there's no risk of a spurious warning on unrecognized TDS versions. Good.
  • Once-per-process semantics are implemented correctly via the shared tds71DeprecationWarning.emitted flag, matching the PR description.

Code quality

  • tds71DeprecationWarning is a plain object with mutable state accessed directly by the test (tds71DeprecationWarning.emitted = false). It works, but a small reset()-style method (or resetting via a constructor/class) would avoid reaching into "private" state from the test file, since the export is already marked @private. Minor nit, not blocking.
  • Using process.emitWarning with type: 'DeprecationWarning' and a stable code: 'TEDIOUS_DEP_TDS71' is the right call here (vs. util.deprecate, which is meant for wrapping function calls rather than a runtime protocol-negotiation event). This also gives consumers a --throw-deprecation/NODE_OPTIONS friendly, filterable warning.

Test coverage

  • The new test/unit/tds71-deprecation-test.ts spins up a real fake TDS server and drives an actual Connection through PRELOGIN/LOGIN7, which is a much stronger test than mocking onLoginAck directly -- it validates the full negotiated path.
  • Good coverage of both the positive case (7.1 negotiated -> warning, once across two connections) and the negative case (7.4 negotiated -> no warning).
  • One gap: there's no direct unit test asserting the boundary at exactly '7_2' (i.e., confirming 7.2 itself doesn't warn) -- the negative test uses 7.4. Given the shared string-comparison logic already has coverage elsewhere in the suite, this is a minor gap rather than a real risk.

Docs

  • README and the ConnectionOptions.tdsVersion JSDoc are updated consistently to flag the deprecation. Good attention to detail keeping both in sync.

Security / performance

  • No concerns -- this only adds a conditional, process-scoped, one-time warning emission on an already-executed code path; no new attack surface or perf-sensitive hot path impact.

Overall this looks safe to merge; only minor nits above (test-state encapsulation, optional boundary test at exactly 7.2).

@arthurschreiber
arthurschreiber merged commit 3aba7c7 into master Aug 31, 2026
32 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 20.1.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant