From 2de97de879a2a5a7842935daf3390980eb4cb19e Mon Sep 17 00:00:00 2001 From: Pakanon Pantisawat Date: Mon, 29 Jun 2026 14:49:45 +0700 Subject: [PATCH 1/2] fix(plugin-mssql): set TEXTSIZE 2147483647 on connect FreeTDS inherits TDS protocol default of 2048 bytes for nvarchar(max)/text columns, silently truncating large cell values on copy. SET TEXTSIZE at connect time fixes both the batch and streaming query paths. --- Plugins/MSSQLDriverPlugin/FreeTDSConnection.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Plugins/MSSQLDriverPlugin/FreeTDSConnection.swift b/Plugins/MSSQLDriverPlugin/FreeTDSConnection.swift index cd29197e1..bbe216a34 100644 --- a/Plugins/MSSQLDriverPlugin/FreeTDSConnection.swift +++ b/Plugins/MSSQLDriverPlugin/FreeTDSConnection.swift @@ -179,6 +179,11 @@ nonisolated final class FreeTDSConnection: @unchecked Sendable { lock.lock() _isConnected = true lock.unlock() + + // FreeTDS default TEXTSIZE is 2048. Set to 2 GB so nvarchar(max)/text columns return in full. + _ = dbcmd(proc, "SET TEXTSIZE 2147483647") + _ = dbsqlexec(proc) + _ = dbresults(proc) } func switchDatabase(_ database: String) async throws { From ba7da61683eb7d35aa54ae552e1dda2cad5b59fb Mon Sep 17 00:00:00 2001 From: Ngo Quoc Dat Date: Tue, 30 Jun 2026 05:16:54 +0700 Subject: [PATCH 2/2] refactor(plugin-mssql): drain results and log TEXTSIZE failures on connect --- CHANGELOG.md | 1 + .../MSSQLDriverPlugin/FreeTDSConnection.swift | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56f52c07d..bfcfaa5f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Switching between sidebar tables no longer leaves extra blank space above the list. (#1675) - SSH tunnels no longer pin a CPU core after the connection drops. A dropped tunnel is now detected and torn down instead of spinning in its relay loop. (#1769) - Restored table tabs now load with the current page size instead of the page size from the previous session. +- MSSQL: large `nvarchar(max)` and `text` values no longer truncate to 2048 bytes when copied or viewed. TEXTSIZE is raised at connect time. (#1783) ## [0.53.0] - 2026-06-25 diff --git a/Plugins/MSSQLDriverPlugin/FreeTDSConnection.swift b/Plugins/MSSQLDriverPlugin/FreeTDSConnection.swift index bbe216a34..4f6354b10 100644 --- a/Plugins/MSSQLDriverPlugin/FreeTDSConnection.swift +++ b/Plugins/MSSQLDriverPlugin/FreeTDSConnection.swift @@ -180,10 +180,20 @@ nonisolated final class FreeTDSConnection: @unchecked Sendable { _isConnected = true lock.unlock() - // FreeTDS default TEXTSIZE is 2048. Set to 2 GB so nvarchar(max)/text columns return in full. - _ = dbcmd(proc, "SET TEXTSIZE 2147483647") - _ = dbsqlexec(proc) - _ = dbresults(proc) + applyMaxTextSize(proc) + } + + private func applyMaxTextSize(_ proc: UnsafeMutablePointer) { + guard dbcmd(proc, "SET TEXTSIZE \(Int32.max)") != FAIL, dbsqlexec(proc) != FAIL else { + freetdsLogger.error("Failed to raise TEXTSIZE; large text columns may be truncated to the 2048-byte default") + return + } + while true { + let resCode = dbresults(proc) + if resCode == FAIL || resCode == Int32(NO_MORE_RESULTS) { + break + } + } } func switchDatabase(_ database: String) async throws {