#[pg_extern]
Expand description
Declare a function as #[pg_extern]
to indicate that it can be used by Postgres as a UDF.
Optionally accepts the following attributes:
immutable
: Corresponds toIMMUTABLE
.strict
: Corresponds toSTRICT
.- In most cases,
#[pg_extern]
can detect when noOption<T>
s are used, and automatically set this.
- In most cases,
stable
: Corresponds toSTABLE
.volatile
: Corresponds toVOLATILE
.raw
: Corresponds toRAW
.security_definer
: Corresponds toSECURITY DEFINER
security_invoker
: Corresponds toSECURITY INVOKER
parallel_safe
: Corresponds toPARALLEL SAFE
.parallel_unsafe
: Corresponds toPARALLEL UNSAFE
.parallel_restricted
: Corresponds toPARALLEL RESTRICTED
.no_guard
: Do not use#[pg_guard]
with the function.sql
: Same arguments as#[pgrx(sql = ..)]
.name
: Specifies target function name. Defaults to Rust function name.
Functions can accept and return any type which pgrx
supports. pgrx
supports many PostgreSQL types by default.
New types can be defined via PostgresType
or PostgresEnum
.
Without any arguments or returns:
use pgrx::*;
#[pg_extern]
fn foo() { todo!() }
§Arguments
It’s possible to pass even complex arguments:
use pgrx::*;
#[pg_extern]
fn boop(
a: i32,
b: Option<i32>,
c: Vec<i32>,
d: Option<Vec<Option<i32>>>
) { todo!() }
It’s possible to set argument defaults, set by PostgreSQL when the function is invoked:
use pgrx::*;
#[pg_extern]
fn boop(a: default!(i32, 11111)) { todo!() }
#[pg_extern]
fn doop(
a: default!(Vec<Option<&str>>, "ARRAY[]::text[]"),
b: default!(String, "'note the inner quotes!'")
) { todo!() }
The default!()
macro may only be used in argument position.
It accepts 2 arguments:
- A type
- A
bool
, numeric, or SQL string to represent the default."NULL"
is a possible value, as is"'string'"
If the default SQL entity created by the extension: ensure it is added to requires
as a dependency:
use pgrx::*;
#[pg_extern]
fn default_value() -> i32 { todo!() }
#[pg_extern(
requires = [ default_value, ],
)]
fn do_it(
a: default!(i32, "default_value()"),
) { todo!() }
§Returns
It’s possible to return even complex values, as well:
use pgrx::*;
#[pg_extern]
fn boop() -> i32 { todo!() }
#[pg_extern]
fn doop() -> Option<i32> { todo!() }
#[pg_extern]
fn swoop() -> Option<Vec<Option<i32>>> { todo!() }
#[pg_extern]
fn floop() -> (i32, i32) { todo!() }
Like in PostgreSQL, it’s possible to return tables using iterators and the name!()
macro:
use pgrx::*;
#[pg_extern]
fn floop<'a>() -> TableIterator<'a, (name!(a, i32), name!(b, i32))> {
TableIterator::new(None.into_iter())
}
#[pg_extern]
fn singular_floop() -> (name!(a, i32), name!(b, i32)) {
todo!()
}
The name!()
macro may only be used in return position inside the T
of a TableIterator<'a, T>
.
It accepts 2 arguments:
- A name, such as
example
- A type
§Special Cases
pg_sys::Oid
is a special cased type alias, in order to use it as an argument or return it must be
passed with it’s full module path (pg_sys::Oid
) in order to be resolved.
use pgrx::*;
#[pg_extern]
fn example_arg(animals: pg_sys::Oid) {
todo!()
}
#[pg_extern]
fn example_return() -> pg_sys::Oid {
todo!()
}