Documentation Index
Fetch the complete documentation index at: https://moridb.sh/docs/llms.txt
Use this file to discover all available pages before exploring further.
Overview
| Property | Value |
|---|---|
| Engine ID | mssql |
| Wire Protocol | TDS (Tabular Data Stream) |
| Classifier | Regex-based (no Go-native T-SQL parser exists) |
| Shadow | Docker mcr.microsoft.com/mssql/server:2022-latest |
| Container Timeout | 300 seconds (ARM emulation is slow) |
| Field | Description | Default |
|---|---|---|
host | Database host | — |
port | Database port | 1433 |
user | Username | — |
password | Password | — |
database | Database name | — |
encrypt | Encryption setting | — |
trust_server_cert | Trust server certificate | — |
Differences from PostgreSQL
- Regex-based classification — No Go-native T-SQL parser exists. The classifier handles all common T-SQL patterns including bracket-quoted identifiers,
TOP N,OFFSET/FETCH,MERGE INTO,sp_executesql, and DBCC commands. - MERGE INTO — MSSQL’s upsert syntax (equivalent to
INSERT ... ON CONFLICT). Classified asHasOnConflictand routed through the hydration path. - IDENTITY columns — Uses
IDENTITYinstead of sequences. Offsets applied viaDBCC CHECKIDENT. Hydration wraps inserts withSET IDENTITY_INSERT ON/OFF. sp_executesql/sp_prepare— TDS RPC model for parameterized queries.sp_prepareis forwarded to prod (to obtain a handle),sp_executeis classified and routed per-statement with full parameter extraction.- Cursor materialization — Dirty tables are materialized into shadow temp tables before cursor open. The cursor SQL is rewritten (UTF-16LE) to reference temp tables.
- JOIN via materialization — JOINs on dirty tables use full materialization rather than per-row patching. Functionally correct but materializes entire dirty tables.
- Aggregate re-aggregation — COUNT-only in-memory re-aggregation. SUM/AVG/MIN/MAX use temp table materialization path.
- Cross-table UPDATE…FROM — Detects FROM clause in UPDATE statements and hydrates all referenced tables.
- No RELEASE SAVEPOINT — T-SQL has no
RELEASE SAVEPOINT. Savepoints are created withSAVE TRANand rolled back withROLLBACK TRAN <name>. - No
ctidequivalent — PK-less tables use full-row hash-based deduplication. - Bracket quoting — Uses
[identifier]instead of"identifier". - TDS-wrapped TLS not implemented — Set
encrypt=falsein the connection string. For encrypted connections, use a TLS-terminating tunnel/sidecar. - MARS disabled — Multiple Active Result Sets are stripped from PRELOGIN.
Known Limitations
- TDS-wrapped TLS not implemented —
encrypt=falserequired. - MARS disabled — applications must not rely on Multiple Active Result Sets.
- Aggregate re-aggregation limited to COUNT (SUM/AVG/MIN/MAX use materialization).
- JOIN patching uses materialization (no per-row patching).
- Unsupported operations: BULK INSERT, EXEC/EXECUTE (stored procedures).
- Functions aren’t supported yet because it’s really hard to determine if the function is non-mutating or not.
- CTE updates/deletes/upserts might produce incorrect subsequent merged read results.
- Performance: Rare, but some extremely complex JOINs over large tables might be slow either because (a) the prod data needed is too large or (b) the query is too complex and the safety mechanism decides to materialize the result into a temporary table locally. If this happens, try passing in
--max-rowsduringmori start, which will cap the number of rows pulled from prod.

