1- # Arrow SQL Server
1+ < h1 align = " center " > Arrow SQL Server</ h1 >
22
3- [ ![ Crates.io] ( https://img.shields.io/crates/v/arrow-sql-server.svg )] ( https://crates.io/crates/arrow-sql-server )
4- [ ![ Docs.rs] ( https://docs.rs/arrow-sql-server/badge.svg )] ( https://docs.rs/arrow-sql-server )
5- [ ![ License] ( https://img.shields.io/badge/license-Apache--2.0-blue.svg )] ( LICENSE )
3+ <p align =" center " >
4+ <a href =" https://crates.io/crates/arrow-sql-server " ><img alt =" Crates.io " src =" https://img.shields.io/crates/v/arrow-sql-server.svg " ></a >
5+ <a href =" https://docs.rs/arrow-sql-server " ><img alt =" Docs.rs " src =" https://docs.rs/arrow-sql-server/badge.svg " ></a >
6+ <a href =" LICENSE " ><img alt =" Apache 2.0 license " src =" https://img.shields.io/badge/license-Apache--2.0-blue.svg " ></a >
7+ </p >
68
7- Arrow SQL Server is a high-performance Apache Arrow ` RecordBatch ` bulk writer
8- for Microsoft SQL Server, built on the Tiberius TDS driver.
9+ <p align =" center " >
10+ <strong >Bulk-write Apache Arrow RecordBatch values to Microsoft SQL Server without an ODBC driver.</strong >
11+ </p >
912
10- The current API focuses on Arrow-to-SQL Server writes:
13+ <h2 align =" center " >
14+ Up to 4x faster than Arrow ODBC.<br >
15+ Uses 92% less memory.
16+ </h2 >
1117
12- - plan SQL Server-compatible schemas from Arrow schemas,
13- - render deterministic ` CREATE TABLE ` SQL,
14- - report unsupported mappings as structured diagnostics,
15- - write Arrow ` RecordBatch ` values with a selectable SQL Server bulk writer,
16- - emit sanitized writer and protocol tracing through ` tracing ` .
18+ < p align = " center " >
19+ Measured up to 3.9x the throughput of Arrow ODBC.< br >
20+ A fresh 0.3.0 run measured 2.67x the throughput and 17 MiB versus 213 MiB peak memory.< br >
21+ < a href = " docs/performance.md " >See the results, limitations, and reproduction command.</ a >
22+ </ p >
1723
18- SQL Server-to-Arrow reads are reserved for a later release.
24+ Arrow SQL Server is a Rust library for schema-aware, asynchronous SQL Server
25+ bulk loading. It plans Arrow schemas, generates SQL Server DDL, validates target
26+ tables, and writes batches through a direct Arrow-to-TDS path.
1927
20- ## Install
21-
22- ``` toml
23- [dependencies ]
24- arrow-sql-server = " 0.3"
25- ```
28+ ## Why Arrow SQL Server?
2629
27- ## Quick Start
30+ - ** Built for Arrow:** write ` RecordBatch ` values directly instead of converting
31+ them into application row objects.
32+ - ** Built for SQL Server:** explicit type planning, compatibility profiles,
33+ quoted identifiers, target-table validation, and bulk-load diagnostics.
34+ - ** No ODBC runtime:** the production path uses TDS through Tiberius, so your
35+ application does not need unixODBC or a Microsoft ODBC driver.
2836
29- Plan an Arrow schema and render SQL Server DDL:
37+ ## Is It a Good Fit?
3038
31- ``` rust
32- use arrow_schema :: { DataType , Field , Schema };
33- use arrow_sql_server :: {
34- CompatibilityLevel , MssqlProfile , MssqlVersion , PlanOptions , TableName ,
35- create_table_sql_from_mappings,
36- };
39+ | Use Arrow SQL Server when you need | This crate does not provide |
40+ | --- | --- |
41+ | Arrow-to-SQL Server bulk writes from Rust | SQL Server-to-Arrow reads |
42+ | Streaming writes across one or more batches | Connection pooling, retries, or job orchestration |
43+ | SQL Server-aware schema planning and DDL | A database-agnostic writer abstraction |
44+ | A direct TDS path without an ODBC deployment | Migrations, an ORM, or automatic table publishing workflows |
3745
38- fn main () -> arrow_sql_server :: Result <()> {
39- let schema = Schema :: new (vec! [
40- Field :: new (" id" , DataType :: Int64 , false ),
41- Field :: new (" name" , DataType :: Utf8 , true ),
42- ]);
46+ The crate can generate ` CREATE TABLE ` SQL, but it does not create or replace a
47+ table unless your application explicitly executes that SQL.
4348
44- let profile = MssqlProfile :: new (
45- MssqlVersion :: SqlServer2022 ,
46- CompatibilityLevel :: SQL_SERVER_2022 ,
47- )? ;
48- let outcome = profile . plan_arrow_schema (& schema , PlanOptions :: default ())? ;
49+ ## Install
4950
50- let table = TableName :: new (" dbo" , " people" )? ;
51- let ddl = create_table_sql_from_mappings (& table , outcome . mappings ());
51+ Arrow SQL Server 0.3 uses Arrow 58 types. Add the crates used by the examples:
5252
53- assert! ( ddl . contains ( " CREATE TABLE [dbo].[people] " ));
54- Ok (())
55- }
53+ ``` bash
54+ cargo add arrow-sql-server@0.3 arrow-array@58 arrow-schema@58
55+ cargo add tokio@1 --features macros,rt
5656```
5757
58- Write a batch to an existing SQL Server table:
58+ The minimum supported Rust version is 1.88.
59+
60+ ## Write a Batch
61+
62+ The target table must already match the planned schema. New applications should
63+ use ` WriteOptions::default() ` ; its ` Auto ` backend selects the optimized writer.
5964
6065``` rust
6166use arrow_array :: RecordBatch ;
6267use arrow_sql_server :: {
6368 CompatibilityLevel , MssqlProfile , MssqlVersion , PlanOptions , TableName ,
64- WriteBackend , WriteOptions , connect_mssql_client_from_ado_string,
69+ WriteOptions , WriteStats , connect_mssql_client_from_ado_string,
6570};
6671
6772async fn write_batch (
6873 connection_string : & str ,
6974 batch : & RecordBatch ,
70- ) -> arrow_sql_server :: Result <()> {
71- let mut client = connect_mssql_client_from_ado_string (connection_string ). await ? ;
75+ ) -> arrow_sql_server :: Result <WriteStats > {
7276 let profile = MssqlProfile :: new (
7377 MssqlVersion :: SqlServer2022 ,
7478 CompatibilityLevel :: SQL_SERVER_2022 ,
@@ -78,151 +82,51 @@ async fn write_batch(
7882 . into_value ();
7983
8084 let table = TableName :: new (" dbo" , " people" )? ;
85+ let mut client = connect_mssql_client_from_ado_string (connection_string ). await ? ;
8186 let mut writer = client
82- . bulk_writer (
83- table ,
84- planned_schema ,
85- WriteOptions {
86- backend : WriteBackend :: DirectRawBulk ,
87- .. WriteOptions :: default ()
88- },
89- )
87+ . bulk_writer (table , planned_schema , WriteOptions :: default ())
9088 . await ? ;
9189
9290 writer . write_batch (batch ). await ? ;
93- writer . finish (). await ? ;
94- Ok (())
91+ writer . finish (). await
9592}
9693```
9794
98- The connected writer validates target table metadata before sending rows. It
99- does not create the target table automatically; callers can use the DDL helper
100- when they want this crate to produce the table definition.
101-
102- ## Diagnostics
103-
104- Planning and write failures return structured diagnostics instead of requiring
105- string parsing. Diagnostics include severity, machine-readable code, field
106- context, row context when available, and message text.
107-
108- For user-facing write failure reports, use ` Error::safe_error_info() ` . It
109- exposes the write phase, inner error kind, sanitized summary, diagnostic codes,
110- and structured diagnostics when available while keeping dependency source text
111- out of default reports.
112-
113- For the complete planning surface, see
114- [ Arrow to SQL Server Type Mapping] ( docs/type-mapping.md ) .
115-
116- ## Writer Backends
117-
118- ` WriteBackend ` controls how planned Arrow rows are sent to SQL Server:
119-
120- | Backend | Purpose |
121- | --- | --- |
122- | ` Auto ` | Default selection. Currently resolves to ` DirectRawBulk ` . |
123- | ` BaselineTokenRow ` | Compatibility path using Tiberius ` TokenRow ` bulk load. |
124- | ` DirectFramedBulk ` | Direct Arrow-to-TDS row encoding through Tiberius framed writes. |
125- | ` DirectRawBulk ` | Optimized direct encoder plus raw bulk packet writes from the Tiberius fork. |
95+ For a complete first run that creates a table, writes a batch, and verifies the
96+ row count, follow [ Getting Started] ( docs/getting-started.md ) .
12697
127- The direct raw backend is the optimized production path for currently supported
128- mappings. The baseline backend remains useful for compatibility checks and
129- parity tests.
98+ ## Supported Data
13099
131- ## Observability
100+ The default planner and both production writers support common Arrow scalar
101+ types, including:
132102
133- Arrow SQL Server emits structured spans and events through ` tracing ` for schema
134- planning, writer initialization, batch writes, direct raw backend summaries,
135- and writer finish. It never installs a subscriber.
103+ - booleans and signed or unsigned integers,
104+ - floating-point values,
105+ - UTF-8 and binary arrays, including Arrow view arrays,
106+ - decimal values up to SQL Server precision 38,
107+ - dates, times, timestamps, and timezone-aware timestamps.
136108
137- Its ` tiberius-raw-bulk ` dependency also emits sanitized protocol tracing under
138- the ` tiberius_raw_bulk::protocol ` target. Those protocol events are emitted
139- inside active ` arrow_sql_server ` writer spans during connect, bulk-load, and
140- finish operations.
109+ Nested Arrow values and SQL Server-to-Arrow reads are not currently supported.
110+ See the [ complete type-mapping reference] ( docs/type-mapping.md ) for policies,
111+ runtime checks, and unsupported types.
141112
142- See [ Observability ] ( docs/observability.md ) for subscriber setup, span and event
143- names, safe field categories, redaction guarantees, and workflow integration .
113+ SQL Server profiles cover SQL Server 2016, 2017, 2019, 2022, and 2025 with
114+ compatibility-level validation .
144115
145- ## Examples
116+ ## Learn More
146117
147- Compile-checked examples that do not require SQL Server :
118+ Start here :
148119
149- ``` bash
150- cargo run --example schema_to_ddl
151- cargo run --example planning_diagnostics
152- cargo run --example backend_selection
153- cargo run --example policy_dependent_planning
154- ```
155-
156- SQL Server write example:
157-
158- ``` bash
159- ARROW_SQL_SERVER_EXAMPLE_MSSQL_URL=' server=tcp:localhost,1433;user=sa;password=...;TrustServerCertificate=true' \
160- cargo run --example sqlserver_batch_write
161- ```
162-
163- By default, the SQL Server example creates, writes to, and drops
164- ` [dbo].[arrow_sql_server_example_write] ` .
165-
166- ## Compatibility
167-
168- Choose the ` MssqlProfile ` that matches the SQL Server version and database
169- compatibility level you plan to write against:
170-
171- ``` rust
172- use arrow_sql_server :: {CompatibilityLevel , MssqlProfile , MssqlVersion };
173-
174- let profile = MssqlProfile :: new (
175- MssqlVersion :: SqlServer2022 ,
176- CompatibilityLevel :: SQL_SERVER_2022 ,
177- )? ;
178- ```
179-
180- The profile surface models SQL Server 2016, 2017, 2019, 2022, and 2025
181- version/compatibility-level pairs. Legacy convenience constructors such as
182- ` MssqlProfile::sql_server_2016_compat_100() ` and
183- ` MssqlProfile::sql_server_2017_compat_100() ` remain available for callers that
184- target those exact environments.
185-
186- Arrow SQL Server depends on the published ` tiberius-raw-bulk ` package as the
187- crate name ` tiberius ` and owns that compatibility boundary internally:
188-
189- ``` toml
190- tiberius = { package = " tiberius-raw-bulk" , version = " =0.12.3-raw-bulk.15" , default-features = false , features = [
191- " tds73" ,
192- " winauth" ,
193- " native-tls" ,
194- ] }
195- ```
196-
197- Downstream crates should normally depend only on ` arrow-sql-server ` and construct
198- SQL Server clients through ` connect_mssql_client_from_ado_string ` or
199- ` ConnectedMssqlClient ` .
200-
201- ## Feature Flags
202-
203- | Feature | Default | Purpose |
204- | --- | --- | --- |
205- | ` bench-profile ` | no | Enables benchmark-only direct write profiling hooks and forwards to ` tiberius/bulk-load-profile ` . |
206- | ` integration-tests ` | no | Enables SQL Server integration tests that require explicit environment setup or the xtask runner. |
207-
208- ## Validation
209-
210- Default local validation does not require SQL Server:
211-
212- ``` bash
213- cargo fmt --check
214- cargo clippy --workspace --all-targets --all-features -- -D warnings
215- cargo test --workspace
216- ```
217-
218- Run SQL Server integration tests through the xtask harness:
219-
220- ``` bash
221- cargo xtask sqlserver-test
222- cargo xtask sqlserver-compat-probe
223- ```
120+ - [ Getting Started] ( docs/getting-started.md ) : complete your first SQL Server
121+ write.
122+ - [ Type Mapping Reference] ( docs/type-mapping.md ) : check supported Arrow and SQL
123+ Server types.
124+ - [ Performance] ( docs/performance.md ) : understand the benchmark claim and its
125+ workload boundaries.
126+ - [ API Documentation] ( https://docs.rs/arrow-sql-server ) : browse public Rust
127+ types and methods.
224128
225- ## Documentation
129+ Advanced and maintainer documentation:
226130
227- See [ Documentation Index ] ( docs/README .md ) for the maintained user and maintainer
228- docs.
131+ - [ Observability ] ( docs/observability .md )
132+ - [ Documentation Index ] ( docs/README.md )
0 commit comments