• Stars
    star
    392
  • Rank 109,735 (Top 3 %)
  • Language
    Rust
  • License
    MIT License
  • Created over 5 years ago
  • Updated almost 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

💽🕸 Postgres library to run WebAssembly binaries.

Wasmer logo Wasmer Postgres Wasmer Slack Channel

A complete and mature WebAssembly runtime for Postgres based on Wasmer. It's an original way to extend your favorite database capabilities.

Features:

  • Easy to use: The wasmer API mimics the standard WebAssembly API,
  • Fast: wasmer executes the WebAssembly modules as fast as possible, close to native speed,
  • Safe: All calls to WebAssembly will be fast, but more importantly, completely safe and sandboxed.

Note: The project is still in heavy development. This is a 0.1.0 version. Some API are missing and are under implementation. But it's fun to play with it.

Installation

The project comes in two parts:

  1. A shared library, and
  2. A PL/pgSQL extension.

To compile the former, run just build (Postgres server headers are required, see pg_config --includedir-server). To install the latter, run just install. After that, run CREATE EXTENSION wasm in a Postgres shell. A new function will appear: wasm_init; it must be called with the absolute path to the shared library. It looks like this:

$ # Build the shared library.
$ just build

$ # Install the extension in the Postgres tree.
$ just install

$ # Activate and initialize the extension.
$ just host=$host database=$database activate

And you are ready to go!

Note: On macOS, the shared library extension is .dylib, on Windows, it is .dll, and on other distributions, it is .so.

Note 2: Yes, you need just.

Supported Postgres versions

So far, the extension works on Postgres 10 only. It doesn't work with Postgres 11 yet (follow this issue if you want to learn more). Any help is welcomed!

Usage & documentation

Consider the examples/simple.rs program:

#[no_mangle]
pub extern fn sum(x: i32, y: i32) -> i32 {
    x + y
}

Once compiled to WebAssembly, one obtains a similar WebAssembly binary to examples/simple.wasm (download it). To use the sum exported function, first, create a new instance of the WebAssembly module, and second, call the sum function.

To instantiate a WebAssembly module, the wasm_new_instance function must be used. It has two arguments:

  1. The absolute path to the WebAssembly module, and
  2. A namespace used to prefix exported functions in SQL.

For instance, calling wasm_new_instance('/path/to/simple.wasm', 'ns') will create the ns_sum function that is a direct call to the sum exported function of the WebAssembly instance. Thus:

-- New instance of the `simple.wasm` WebAssembly module.
SELECT wasm_new_instance('/absolute/path/to/simple.wasm', 'ns');

-- Call a WebAssembly exported function!
SELECT ns_sum(1, 2);

--  ns_sum
-- --------
--       3
-- (1 row)

Isn't it awesome? Calling Rust from Postgres through WebAssembly!

Let's inspect a little bit further the ns_sum function:

\x
\df+ ns_sum
Schema              | public
Name                | ns_sum
Result data type    | integer
Argument data types | integer, integer
Type                | normal
Volatility          | volatile
Parallel            | unsafe
Owner               | …
Security            | invoker
Access privileges   |
Language            | plpgsql
Source code         | …
Description         |

The Postgres ns_sum signature is (integer, integer) -> integer, which maps the Rust sum signature (i32, i32) -> i32.

So far, only the WebAssembly types i32, i64 and v128 are supported; they respectively map to integer, bigint and decimal in Postgres. Floats are partly implemented for the moment.

Inspect a WebAssembly instance

The extension provides two foreign data wrappers, gathered together in the wasm foreign schema:

  • wasm.instances is a table with the id and wasm_file columns, respectively for the instance ID, and the path of the WebAssembly module,
  • wasm.exported_functions is a table with the instance_id, name, inputs and output columns, respectively for the instance ID of the exported function, its name, its input types (already formatted for Postgres), and its output types (already formatted for Postgres).

Let's see:

-- Select all WebAssembly instances.
SELECT * FROM wasm.instances;

--                   id                  |          wasm_file
-- --------------------------------------+-------------------------------
--  426e17af-c32f-5027-ad73-239e5450dd91 | /absolute/path/to/simple.wasm
-- (1 row)

-- Select all exported functions for a specific instance.
SELECT
    name,
    inputs,
    outputs
FROM
    wasm.exported_functions
WHERE
    instance_id = '426e17af-c32f-5027-ad73-239e5450dd91';

--   name  |     inputs      | outputs
-- --------+-----------------+---------
--  ns_sum | integer,integer | integer
-- (1 row)

Benchmarks

Benchmarks are useless most of the time, but it shows that WebAssembly can be a credible alternative to procedural languages such as PL/pgSQL. Please, don't take those numbers for granted, it can change at any time, but it shows promising results:

Benchmark Runtime Time (ms) Ratio
Fibonacci (n = 50) postgres-ext-wasm 0.206
PL/pgSQL 0.431
Fibonacci (n = 500) postgres-ext-wasm 0.217
PL/pgSQL 2.189 10×
Fibonacci (n = 5000) postgres-ext-wasm 0.257
PL/pgSQL 18.643 73×

Test

Once the library is built, run the following commands:

$ just pg-start
$ just test

License

The entire project is under the MIT License. Please read the LICENSE file.

More Repositories

1

wasmer

🚀 The leading Wasm Runtime supporting WASIX, WASI and Emscripten
Rust
16,915
star
2

wasmer-go

🐹🕸️ WebAssembly runtime for Go
Go
2,679
star
3

wasmer-python

🐍🕸 WebAssembly runtime for Python
Rust
1,999
star
4

wasmer-php

🐘🕸️ WebAssembly runtime for PHP
PHP
964
star
5

winterjs

Winter is coming... ❄️
JavaScript
844
star
6

wasmer-js

Monorepo for Javascript WebAssembly packages by Wasmer
Rust
828
star
7

kernel-wasm

Sandboxed kernel mode WebAssembly runtime.
C
702
star
8

wasmer-java

☕ WebAssembly runtime for Java
Java
544
star
9

awesome-wasi

😎 Curated list of awesome things regarding WebAssembly WASI ecosystem.
476
star
10

wasmer-ruby

💎🕸 WebAssembly runtime for Ruby
Rust
462
star
11

wapm-cli

📦 WebAssembly Package Manager (CLI)
Rust
368
star
12

webassembly.sh

Open-source and installable PWA terminal powered by WebAssembly, WAPM, and Wasmer-JS 🖥
JavaScript
269
star
13

wasmer-rust-example

Example of WebAssembly embedding in Rust using Wasmer
Rust
163
star
14

ate

Distributed immutable data store with strong encryption and authentication
Rust
129
star
15

vscode-wasm

WebAssembly extension for VSCode
Rust
122
star
16

wai

A language binding generator for `wai` (a precursor to WebAssembly interface types)
Rust
110
star
17

rusty_jsc

Rust bindings for the JavaScriptCore engine.
Rust
86
star
18

wasmer-c-api

Example of the C API to embed the Wasmer runtime
C
76
star
19

io-devices-lib

Library for interacting with the Wasmer Experimental IO Devices
WebAssembly
51
star
20

wasmer-pack

Rust
49
star
21

sonde-rs

A library to compile USDT probes into a Rust library
Rust
44
star
22

old-docs.wasmer.io

Wasmer Documentation (for standalone and embedded use cases)
WebAssembly
41
star
23

wasmer-install

Wasmer Binary Installer https://wasmer.io/
Shell
39
star
24

loupe

Profiling tool for Rust code.
Rust
35
star
25

c-wasm-simd128-example

Example C++ repo emitting Wasm SIMD 128 instructions
C++
30
star
26

wasmer-nginx-example

This is a simple example of Nginx running with wasmer
HTML
29
star
27

wasmer-ocaml

OCaml bindings for Wasmer
OCaml
28
star
28

cargo-wasmer

A cargo sub-command for publishing Rust crates to the WebAssembly Package Manager.
Rust
24
star
29

wasm-fuzz

Fuzzer for Wasm and Wasmer
JavaScript
22
star
30

wasmer.io

The Wasmer.io website
JavaScript
21
star
31

wasmer-bench

This is a repo for benchmarking Wasmer (compilation & runtime)
Rust
20
star
32

wcgi-wordpress-demo

PHP
15
star
33

wcgi-php-template

PHP
14
star
34

docs.wasmer.io

The Wasmer Docs Website (website deployed using Wasmer Edge)
MDX
14
star
35

setup-wasmer

GitHub action for setting up Wasmer
TypeScript
14
star
36

c-http-server

A very simple http server in c
JavaScript
13
star
37

rust-wasm-simd128-example

Example Rust repo emitting Wasm SIMD 128 instructions
Rust
10
star
38

wasm-debug

A runtime-independent crate for transforming Wasm-DWARF
Rust
9
star
39

wasmer-terminal-js

The WebAssembly terminal, revamped!
Rust
7
star
40

rust-cli-app-example

Example CLI app written in rust for Wasmer
Rust
7
star
41

wapm-publish

GitHub action for publishing to WAPM
TypeScript
7
star
42

wasmer-rust-customabi-example

An example repo to demonstrate how to create a module with a custom ABI to then use it from an embedder
Rust
6
star
43

wasm-interface-cli

A binary for verifying Wasm interfaces
Rust
6
star
44

interface-types

The `wasmer-interface-types` crate
Rust
5
star
45

ewasm-workshop

Ewasm workshow with Wasmer Metering
Rust
5
star
46

sgp4

Rust
5
star
47

llvm-custom-builds

Sandbox to produce custom LLVM builds for various platforms
Shell
5
star
48

sha2

A WebAssembly interface to Rust's sha2 crate
Rust
5
star
49

wasm-python-api

WebAssembly Python standard API prototype
Python
4
star
50

python-flask-example

Sample Python Flask server for Wasmer Edge
Python
4
star
51

shared-buffer

An abstraction over buffers backed by memory-mapped files or bytes in memory
Rust
3
star
52

wcgi-rust-template

Rust
3
star
53

wasmer-toml

Split out the wapm.toml parsing from wasmerio/wapm-cli
Rust
3
star
54

wasmer-nightly

Nightly releases of Wasmer
3
star
55

llvm-build

LLVM Distribution for being used with Wasmer
3
star
56

js-service-worker-example

Sample for a js service worker running on Wasmer Edge.
JavaScript
3
star
57

wasi-tests

Integration tests for WASI
Rust
2
star
58

.github

Github profile
2
star
59

wasmer-js-example

Wasmer-JS example
2
star
60

edge-react-starter

Wasmer Edge + Vite + React + TS starter template. Deploy it like it's hot 🚀
CSS
1
star
61

rustfft

Rustfft for WASM, published on WAPM
Rust
1
star
62

inline-c

Rust
1
star
63

speed.wasmer.io

Speed tracker of Wasmer
CSS
1
star
64

windows-llvm-build

Build of LLVM in Windows
1
star
65

wasmer-edge-support

1
star
66

zig2wapm

CI script to clone zig/zig to wapm.io
Shell
1
star
67

wasm4-on-wapm

This is a demo repo to showcase how to upload your WASM-4 games to WAPM
1
star
68

wai-hashids

Hashids demonstration with WAI
Rust
1
star
69

astro-starter-a1d

Astro
1
star
70

flask-starter-324

Python
1
star
71

wasmerio-flask-template

Python
1
star
72

wasmer-integration-tests

Integration tests between Edge and the backend
Rust
1
star