plrust
plrust copied to clipboard
A Rust procedural language handler for PostgreSQL
plrust
Extension for PostgreSQL
Support for plrust
in PostgreSQL functions.
CREATE EXTENSION IF NOT EXISTS plrust;
CREATE OR REPLACE FUNCTION sum_array(a BIGINT[]) RETURNS BIGINT
IMMUTABLE STRICT
LANGUAGE PLRUST AS
$$
[dependencies]
# Add Cargo.toml dependencies here.
[code]
Some(a.into_iter().map(|v| v.unwrap_or_default()).sum())
$$;
SELECT sum_array(ARRAY[1,2,3]);
/*
sum_array
----------------
6
(1 row)
*/
Options
There are two postgresql.conf
settings that must be configured:
Option | Description |
---|---|
plrust.pg_config |
The full path of the pg_config binary. |
plrust.work_dir |
The directory where pl/rust will build functions with cargo. |
plrust.tracing_level |
A tracing directive. (Default info ) |
Using PL/Rust with Postgrestd
PL/Rust currently supports being used with an experimental fork of Rust's std entitled postgrestd
which supports an
x86_64-unknown-linux-postgres
target. This is built via the build
script, which pulls in postgrestd
.
Doing so places a copy of the necessary libraries used by Rust for std
into the appropriate "sysroot",
which is the location that rustc will look for building those libraries.
Further usage requires setting the PLRUST_TARGET
to the appropriate tuple, as this is still an experimental feature,
and so is not currently set by default. Passing --features target_postgrestd
to cargo
also works. These are subtly different:
-
PLRUST_TARGET
is evaluated when the PL/Rust handler builds a function -
--features target_postgrestd
is evaluated when the PL/Rust handler is built -
PLRUST_TARGET
prevails overtarget_postgrestd
if both are set
This initial build process requires a normal installation of Rust via rustup
and for the relevant location to be writeable on the building host.
cd plrust
./build
PLRUST_TARGET="x86_64-unknown-linux-postgres" cargo build
Installation
PL/Rust is a
pgx
extension.If you're already familiar with
pgx
you'll find you already know how to hack on, package, and use PL/Rust.
First, ensure cargo pgx
installed & initialized:
cargo install cargo-pgx
cargo pgx init --pg14 download
Then, add some configuration to the postgresql.conf
and ensure there is a
writable work_dir
:
PG_CONFIG=$(find ~/.pgx/14.*/pgx-install/bin/pg_config)
SCRATCH_DIR=/home/${USER}/git/zombodb/plrust/scratch
cat <<-EOF >> ~/.pgx/data-14/postgresql.conf
plrust.pg_config = '${PG_CONFIG}'
plrust.work_dir = '${SCRATCH_DIR}'
EOF
mkdir -p scratch
chmod -R 777 scratch
It's possible to test debug builds inside a working PostgreSQL:
$ cargo pgx run
Stopping Postgres v12
building extension with features ``
"cargo" "build" "--no-default-features"
Finished dev [unoptimized + debuginfo] target(s) in 0.56s
installing extension
Copying control file to `target/release/plrust-pg14/usr/share/postgresql/14/extension/plrust.control`
Copying shared library to `target/release/plrust-pg14/usr/lib/postgresql/14/lib/plrust.so`
Writing extension schema to `target/release/plrust-pg12/usr/share/postgresql/14/extension/plrust--1.0.sql`
Finished installing plrust
Starting Postgres v14 on port 28812
Re-using existing database plrust
psql (14.2)
Type "help" for help.
plrust=# \dx
List of installed extensions
Name | Version | Schema | Description
---------+---------+------------+------------------------------
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
(1 row)
plrust=# CREATE EXTENSION IF NOT EXISTS plrust;
CREATE EXTENSION
plrust=# \dx
List of installed extensions
Name | Version | Schema | Description
---------+---------+------------+------------------------------
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
plrust | 1.0 | plrust | plrust: Created by pgx
(2 rows)
To install it to the locally running PostgreSQL server:
cargo pgx install
Creating a distributable
cargo pgx package
The output should resemble the following:
$ cargo pgx package
building extension with features ``
"cargo" "build" "--release" "--message-format=json-render-diagnostics"
Compiling plrust v0.0.0 (/home/${USER}/git/zombodb/plrust)
Finished release [optimized] target(s) in 28.37s
installing extension
Copying control file to `target/release/plrust-pg14/usr/share/postgresql/14/extension/plrust.control`
Copying shared library to `target/release/plrust-pg14/usr/lib/postgresql/14/lib/plrust.so`
Writing extension schema to `target/release/plrust-pg12/usr/share/postgresql/14/extension/plrust--1.0.sql`
Finished installing plrust
The directory tree inside target/release/plrust-pg14/
contains a tree corresponding to the local
where the extension should be placed.
From here, you can use an archive or a tool like fpm
to distribute the artifact to
the target.
Once installed in the right directory, connect via psql
:
psql=# CREATE EXTENSION IF NOT EXISTS plrust;
CREATE EXTENSION
plrust=# \dx
List of installed extensions
Name | Version | Schema | Description
---------+---------+------------+------------------------------
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
plrust | 1.0 | plrust | plrust: Created by pgx
(2 rows)
plrust=# \dx+ plrust
Objects in extension "plrust"
Object description
-----------------------------------------
function plrust.plrust_call_handler()
function plrust.plrust_validator(oid)
function plrust.recompile_function(oid)
language plrust
(4 rows)