Rust has quietly taken over the layer of software that moves data around: high-throughput services, CLIs, Kubernetes operators, the agents and collectors that sit next to a warehouse and feed it. Teams building those things expect a database driver to be one line in Cargo.toml and nothing else.
For IBM Netezza, that driver did not exist. The realistic route was ODBC: install IBM’s client libraries at the operating-system level, configure them, repeat in every container image, and accept that your tidy static Rust binary now drags a C dependency stack behind it. For a language whose whole deployment story is “one binary, any container”, that is a poor fit.
So we wrote the missing driver: a pure-Rust crate that speaks the Netezza wire protocol directly over a TCP socket. No ODBC. No C client libraries. No dependencies at all, in fact, which is rarer than it sounds.
Zero dependencies is a feature, not a boast
The crate’s dependency list is empty. Even the MD5 and SHA-256 the appliance’s login handshake requires are implemented inside the crate, tested against the official specification vectors, because pulling in a crypto crate would have broken the property we care about: the driver builds anywhere Rust builds, including on machines that cannot reach crates.io at all.
That property is not academic. The enterprise environments Netezza lives in are exactly the ones with locked-down networks, internal mirrors, and air-gapped build hosts. We hit this ourselves while building the driver: our own build machine’s web filter blocks crates.io. The driver compiled anyway, which is the point.
It also means static binaries work the way Rust developers expect. Build against musl, drop the binary into a scratch container, and it connects to the appliance. There is nothing to install in the image.
One code path for both appliance generations
Like the rest of our driver programme, this crate uses one connect-time code path that classic NPS 7.x racks and current NPS 11 systems both accept: same handshake, same result decoding, and crucially the same external-table behaviour. The appliance negotiates MD5 authentication on old racks and SHA-256 on new ones; the driver handles both. We test every feature against a live NPS 7.2 appliance and a live NPS 11.2 system before we call it done, and the feature table below passed on both.
The parts that usually get skipped
A driver that can run SELECT 1 is a demo. The work is in the rest, and it is in.
Real table scans on Netezza do not arrive in the same format as computed results; they stream the appliance engine’s own binary tuple format, little-endian, with a null bitmap and packed fields. The driver decodes the full type system from it: every integer width, floats, NUMERIC up to 38 digits, dates, times, timestamps, intervals, and both character families, including the European encoding Netezza uses for CHAR and VARCHAR on disk. An accented name, a euro sign, and a column of Chinese all come back byte-exact.
Parameters are bound injection-safely: quotes doubled, everything else left alone, because on Netezza a backslash in a string is a literal backslash and “escaping” it would corrupt data. We test with hostile input; O'Brien; DROP TABLE x-- comes back out as an inert string.
External tables, the appliance’s bulk load and unload path, work in both directions: unload a query to a local file at wire speed, load a file into a table, and receive the appliance’s load diagnostics (.nzlog, .nzbad) when rows are rejected. This is the mechanism a Rust ETL service actually wants, and it is usually the first thing missing from a community driver.
TLS is an optional cargo feature that binds the system OpenSSL directly, about ten foreign functions, no crates. It handles the deliberately awkward case: the self-signed, weak-by-modern-standards certificates that old NPS 7 racks present, which default OpenSSL settings reject outright. Set one field and the session is encrypted, on either generation.
Honest edges
The API is deliberately small: connect, query, parameterised query, execute. Values come back as optional strings rendered exactly as the appliance’s text format, which suits the data-plumbing programs Rust gets used for. There is no async interface yet, no connection pool, and no ORM integration; those are candidates for later increments, and until then the driver refuses cleanly rather than pretending. When a server requires TLS and the feature is not compiled in, you get an error saying so, not a silent downgrade.
Publication to crates.io is coming soon, so the driver will be one cargo add away.
The dependency count of a database driver is part of its security surface. Zero is a nice number.
Where you get it
We did not build this for ourselves. Our software is written in Python, so nothing in our stack uses it; it exists because the gap did, and because other teams kept falling into it. If your team has a Rust service that needs Netezza and the ODBC detour has kept it on the backlog, the detour is gone. Talk to us if you want it in your own estate.
Built from the published open source Netezza drivers (IBM/nzpy and IBM/nzalchemy under Apache-2.0, IBM/nzgo under MIT), verified live against both NPS 7.2 and NPS 11.2, and produced without decompiling, disassembling or inspecting any IBM proprietary binary.
Running Netezza? Let’s talk. Smart Associates has been engineering on IBM Netezza for two decades: disaster recovery, migrations, performance and the deep platform work in between. If any of the above sounds familiar, why not get in touch.
