Skip to content

Fix unique_constraint support (en-US errors) - #188

Merged
mjaric merged 10 commits into
masterfrom
fix/issue-173-unique-constraint
Aug 19, 2026
Merged

mjaric merged 10 commits into
masterfrom
fix/issue-173-unique-constraint

Conversation

@mjaric

@mjaric mjaric commented Aug 19, 2026

Copy link
Copy Markdown
Member

Fixes #173.

What changed

  • lib/tds/errors.csv: the en-US row for error 2627 used the literal server placeholder %.*ls instead of a regex capture group, so Tds.Error.get_constraint_violations/2 returned [] for every en-US message and Ecto's unique_constraint never fired. The row now uses the same (\S+?) capture as all other locales.
  • lib/tds.ex: query!/prepare!/execute!/close! no longer re-raise a new Tds.Error built from msg_text only; the original error is re-raised so the mssql metadata (number, msg_text) survives to callers such as Ecto's constraint mapping.
  • lib/tds/protocol.ex: handle_close now runs with state :executing, matching the internal auto-close path in handle_execute. A server error response to sp_unprepare (e.g. closing an already-closed handle) previously hit a missing Tds.Messages.parse(:ready, ...) clause and crashed the connection process instead of returning {:error, %Tds.Error{}}.
  • Tests: unit tests for constraint extraction (2627/2601 en-US, unknown code) and integration tests asserting each bang function re-raises Tds.Error with mssql metadata intact.

Verification

Full test suite against a live SQL Server instance: 112 tests, 0 failures.

mjaric added 2 commits August 19, 2026 10:18
The en-US row for MSSQL error 2627 in errors.csv used the literal
server placeholder '%.*ls' instead of a regex capture group, so
Tds.Error.get_constraint_violations/2 returned [] for every en-US
message and Ecto.Changeset.unique_constraint never fired (issue #173).
The row now uses the same '(\\S+?)' capture as all other locales.

query!/prepare!/execute!/close! no longer re-raise a new Tds.Error
built from msg_text only; the original error is re-raised so the
:mssql metadata (number, msg_text) survives to callers such as Ecto's
constraint mapping.

Adds unit tests for constraint extraction (2627/2601 en-US, unknown
code) and integration tests asserting query!/prepare!/execute!
re-raise Tds.Error with mssql metadata intact.
handle_close now runs with state :executing, matching the internal
auto-close path in handle_execute. Previously a server error response
to sp_unprepare (e.g. closing an already-closed handle) was decoded
with state :ready, for which Tds.Messages.parse/3 has no clause, so
the connection process crashed instead of returning {:error,
%Tds.Error{}}.
@mjaric
mjaric force-pushed the fix/issue-173-unique-constraint branch from 045f1b0 to e9ce174 Compare August 19, 2026 08:18
@mjaric mjaric added the bug label Aug 19, 2026
mjaric added 8 commits August 19, 2026 11:28
apt has no download timeout by default, so runner network flakes hang
'apt-get update' indefinitely (observed on run 32232000436: the lint
job's apt step sat idle for ~18 minutes until cancellation while the
other three jobs finished the same step in under a minute). Add a 30s
acquire timeout with up to 3 attempts and cap the step at 10 minutes.
There is no mssql/server:2024-latest tag; Microsoft skipped from
2022 to 2025 (available tags: 2017-latest, 2019-latest, 2022-latest,
2025-latest). Use 2025-latest as the newest major version.
@mjaric
mjaric merged commit f67d0a7 into master Aug 19, 2026
4 checks passed
@mjaric
mjaric deleted the fix/issue-173-unique-constraint branch August 19, 2026 11:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Does not support unique_constraint properly

1 participant