DuckDB MSSQL Extension

September 18, 2026 ยท View on GitHub

A DuckDB extension for connecting to Microsoft SQL Server databases using native TDS protocol - no ODBC, JDBC, or external drivers required.

๐Ÿ“ˆ Community Extension Downloads

Weekly downloads of the mssql DuckDB community extension

๐Ÿ“Š Interactive chart โ€” queried live in your browser with DuckDB-Wasm.

Regenerated weekly and served from GitHub Pages, so it stays current without a commit. Counts are a Cloudflare estimate of INSTALL mssql FROM community events, aggregated across DuckDB versions and platforms. Source: DuckDB Community Extensions download metrics.

Experimental: This extension is under active development. APIs and behavior may change between releases. We welcome contributions, bug reports, and testing feedback!

Documentation

Full documentation lives at hugr-lab.github.io/mssql-extension โ€” connections and authentication (SQL, Azure AD / Entra ID, Kerberos, Windows SSPI), catalog integration, query pushdown, bulk loading over BCP, DML, transactions, the complete settings reference, and performance tuning.

Quick pointers:

Getting Startedinstall, ATTACH, first queries
Connections & Authconnection strings, secrets, Azure AD, Kerberos
Writing DataCOPY (bulk load), CTAS, INSERT/UPDATE/DELETE
Settings Referenceevery mssql_* setting with defaults
Troubleshootingcommon errors and limitations
ArticlesMedium deep dives on design and performance

Contributor docs stay in the repository: DATAMODEL.md (layered architecture), docs/ (internals), docs/TESTING.md, CLAUDE.md (development guidelines).

Features

  • Native TDS protocol implementation (no external dependencies)
  • Stream query results directly into DuckDB without buffering
  • Full DuckDB catalog integration with three-part naming and lazy metadata loading
  • Filter pushdown: WHERE clauses are translated to T-SQL and evaluated by SQL Server, including mapped functions (year, lower, LIKE patterns, arithmetic). Anything the translator declines is applied locally instead โ€” with the string-comparison caveat below
  • Row-count estimates reported to the DuckDB optimizer, so join order around an MSSQL scan is planned rather than guessed
  • Row identity (rowid) for tables with a primary key or a usable unique index, which is what UPDATE/DELETE target rows by
  • Connection pooling with configurable limits and automatic session reset
  • TLS with the server certificate verified by default; Encrypt, TrustServerCertificate and HostNameInCertificate mean what they mean in the Microsoft drivers
  • Full DML support: INSERT (with RETURNING), UPDATE, DELETE โ€” every statement atomic; an INSERT above 1000 rows loads through the BCP protocol
  • CREATE TABLE AS SELECT (CTAS) with streaming and type mapping
  • High-performance COPY TO via TDS BulkLoadBCP protocol
  • Transaction support: BEGIN/COMMIT/ROLLBACK with connection pinning
  • Multi-statement SQL batches via mssql_scan() (e.g., temp table workflows)
  • DuckDB secret management for secure credential storage
  • Azure AD authentication (service principal, CLI, interactive device code flow)
  • Kerberos / Windows SSPI integrated authentication โ€” POSIX (kinit / keytab / raw credentials) and Windows (current logon session via secur32.dll)
  • Custom Application Name propagated to SQL Server APP_NAME() / sys.dm_exec_sessions.program_name
  • ATTACH-time credential validation (opt-out via lazy_validation true)
  • Experimental: ORDER BY pushdown to SQL Server (opt-in via mssql_order_pushdown setting)

A note on string comparisons. A pushed predicate is evaluated by SQL Server, so it follows the column's collation, not DuckDB's byte comparison: on a case-insensitive collation WHERE name = 'abc' matches 'ABC' โ€” the same answer SSMS gives. This applies to UPDATE and DELETE too, where it changes which rows are modified. It also means a predicate that pushes and the same predicate evaluated locally can disagree on a case-insensitive column (#272). See String comparisons and collation.

Quick Start

Prerequisites

  • DuckDB v1.4.1 or later (minimum supported version)
  • SQL Server 2019 or later accessible on network

Step 1: Install Extension

INSTALL mssql FROM community;
LOAD mssql;

Step 2: Connect to SQL Server

CREATE SECRET my_sqlserver (
    TYPE mssql,
    host 'localhost',
    port 1433,
    database 'master',
    user 'sa',
    password 'YourPassword123'
);

ATTACH '' AS sqlserver (TYPE mssql, SECRET my_sqlserver);

Option B: Using Connection String

ATTACH 'Server=localhost,1433;Database=master;User Id=sa;Password=YourPassword123'
    AS sqlserver (TYPE mssql);

Step 3: Query Data

-- List schemas
SELECT schema_name FROM duckdb_schemas() WHERE database_name = 'sqlserver';

-- List tables in dbo schema
SELECT table_name FROM duckdb_tables() WHERE database_name = 'sqlserver' AND schema_name = 'dbo';

-- Query a table
FROM sqlserver.dbo.my_table LIMIT 10;

Step 4: Disconnect

DETACH sqlserver;
DROP SECRET my_sqlserver;

Support MSSQL Extension

MSSQL Extension is an open-source DuckDB extension maintained in spare time.

If it helps you or your organization, consider sponsoring its development through GitHub Sponsors.

Your support helps fund maintenance, bug fixes, testing, and new features.

Contributing

Issues and pull requests are welcome. Build and test instructions: Development ยท docs/TESTING.md.

Third-Party Licenses

The hugr-lab/mssql-extension release binaries statically link the following third-party components:

  • OpenSSL (TLS / cryptography), licensed under the Apache License, Version 2.0. ยฉ The OpenSSL Project Authors and contributors. Version pinned via vcpkg.json. License text: LICENSES/openssl-LICENSE.txt
  • The simdutf library (Unicode transcoding via SIMD), used under the MIT License option of its dual Apache-2.0/MIT licensing. ยฉ Daniel Lemire and simdutf contributors. License text: LICENSES/simdutf-LICENSE-MIT.txt

License

This project is licensed under the MIT License. See the LICENSE file for details.