Crates.io | scylla-udf-macros |
lib.rs | scylla-udf-macros |
version | 0.1.0 |
source | src |
created_at | 2023-02-15 15:20:52.677894 |
updated_at | 2023-02-15 15:20:52.677894 |
description | Implementation of scylla-udf macros |
homepage | |
repository | https://github.com/scylladb/scylla-rust-udf |
max_upload_size | |
id | 785799 |
size | 21,669 |
This crate allows writing pure Rust functions that can be used as Scylla UDFs.
Note: this crate is officially supported and ready to use. However, UDFs are still an experimental feature in ScyllaDB, and the crate has not been widely used, which is why it's still in beta and its API is subject to change. We appreciate bug reports and pull requests!
To use this helper library in Scylla you'll need:
wasm32-wasi
rustup target add wasm32-wasi
rust-std-static-wasm32-wasi
wasm2wat
parser
wabt
packageWe recommend a setup with cargo.
cargo new --lib
[lib]
crate-type = ["cdylib"]
scylla_udf::export_udf
macro.cargo build --target=wasm32-wasi
.wasm
binary. Let's assume it's target/wasm32-wasi/debug/abc.wasm
.wasm-opt -O3 target/wasm32-wasi/debug/abc.wasm
(can be combined with using cargo build --release
profile)wat
:wasm2wat target/wasm32-wasi/debug/abc.wasm > target/wasm32/wasi/debug/abc.wat
The resulting target/wasm32/wasi/debug/abc.wat
code can now be used directly in a CREATE FUNCTION
statement. The resulting code will most likely
contain '
characters, so it may be necessary to first replace them with ''
, so that they're usable in a CQL string.
For example, if you have an Rust UDF that joins a list of words using commas, you can create a Scylla UDF using the following statement:
CREATE FUNCTION commas(string list<text>) CALLED ON NULL INPUT RETURNS text AS ' (module ...) '
The argument and return value types used in functions annotated with #[export_udf]
must all map to CQL types used in the CREATE FUNCTION
statements used in Scylla, according to the tables below.
If the Scylla function is created with types that do not match the types used in the Rust function, calling the UDF will fail or produce arbitrary results.
CQL Type | Rust type |
---|---|
ASCII | String |
BIGINT | i64 |
BLOB | Vec<u8> |
BOOLEAN | bool |
COUNTER | scylla_udf::Counter |
DATE | chrono::NaiveDate |
DECIMAL | bigdecimal::Decimal |
DOUBLE | f64 |
DURATION | scylla_udf::CqlDuration |
FLOAT | f32 |
INET | std::net::IpAddr |
INT | i32 |
SMALLINT | i16 |
TEXT | String |
TIME | scylla_udf::Time |
TIMESTAMP | scylla_udf::Timestamp |
TIMEUUID | uuid::Uuid |
TINYINT | i8 |
UUID | uuid::Uuid |
VARCHAR | String |
VARINT | num_bigint::BigInt |
If a CQL type T
maps to Rust type RustT
, you can use it as a collection parameter:
CQL Type | Rust type |
---|---|
LIST<T> | Vec<RustT> |
MAP<T> | std::collections::BTreeMap<RustT>, std::collections::HashMap<RustT> |
SET<T> | Vec<RustT>, std::collections::BTreeSet<RustT>, std::collections::HashSet<RustT> |
If CQL types T1
, T2
, ... map to Rust types RustT1
, RustT2
, ..., you can use them in tuples:
CQL Type | Rust type |
---|---|
TUPLE<T1, T2, ...> | (RustT1, RustT2, ...) |
If a CQL Value of type T, that's mapped to type RustT, may be a null (possible in non-RETURNS NULL ON NULL INPUT
UDFs),
the type used in the Rust function should be Option<RustT>.
In general, try to follow the same rules as in https://github.com/scylladb/scylla-rust-driver/blob/main/CONTRIBUTING.md
This crate is meant to be compiled to a wasm32-wasi
target and ran in a WASM runtime. The tests that use WASM-specific code will most likely not succeed when executed in a different way (in particular, with a simple cargo test
command).
For example, if you have the wasmtime runtime installed and in PATH
, you can use the following command to run tests:
CARGO_TARGET_WASM32_WASI_RUNNER="wasmtime --allow-unknown-exports" cargo test --target=wasm32-wasi