Skip to content

tcdi/postgrestd

Repository files navigation

The Postgres Standard Library

postgrestd is a fork of the Rust standard library that implements a variant on the internal-only std::sys module plus additional targets that use this module. It replaces many of the bindings to the operating system with bindings to PostgreSQL's interfaces or to no-op functions, restricting what Rust code compiled with it can access through Safe Rust.

Key Features

The goal of this fork is to prevent Safe Rust code from accessing the operating system's ability to start a subprocesses or to access the shell environment that Postgres has been started in, either of which can amount to allowing code to roam free in the computing environment.

In the typical implementation of the Rust standard library, it uses a module, std::sys, that defines various system-specific bindings which either address platform-specific datatype compatibility concerns or directly bind against the host's system library (which is usually the C standard library, AKA libc). In practice, all functions that require platform varying functionality are implemented through this module, though the module itself may pull in code from elsewhere. Code using postgrestd varies by instead either stubbing out the code (returning Result::Err) or using the Postgres C API instead when it's necessary to implement basic functionality for the Rust runtime to function.

The primary functions reimplemented through Postgres are a global allocator using palloc. This is actually built and linked through the pallocator crate to guarantee it is the used allocator, as std's default allocator may be overridden through #[global_allocator], but only one #[global_allocator] may be linked in the entire build graph for a crate.

Result::Err allows Rust code that handles it appropriately to continue functioning. This currently is done for any function which is believed to violate the "trusted language" definition, to allow use in PL/Rust. Listing every single affected function is implausible, as there are many callers for std::sys and its internal API surface. This is also why other implementation strategies are not realistic: the surface functions of std can and will continue to slowly grow, and will have their internal implementations changed often, but they will remain implemented through the std::sys internal module, which changes much less frequently.

Code that relies on having access to the environment (i.e. doesn't handle an Err gracefully) will panic, which is converted via the pgx panic handler into raising an error that aborts the transaction.

Further documentation must reassess how impl Drop and unwinding account for Postgres.

Get Started

postgrestd is intended to be used as part of PL/Rust.

Getting Help

This is a part of the PL/Rust project. Join the pgx (Postgres Extensions in Rust) community on Discord and ask for help in plrust-#general!

Contributing

In addition to TCDI, the project is maintained by the pgx community.

We are most definitely open to contributions of any kind. Bug Reports, Feature Requests, Documentation, and even sponsorships.

License

postgrestd is distributed under the same terms that apply to the Rust standard library. This means it is primarily distributed under the terms of both the MIT license and the Apache License (Version 2.0), with portions covered by various BSD-like licenses. By contributing to this repository you accept that contributions to this repository may be upstreamed to the rustc repo to be redistributed with the Rust standard library.

See LICENSE-APACHE, LICENSE-MIT, and COPYRIGHT for details.