#[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
.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#[pgx(sql = ..)]
.
Functions can accept and return any type which pgx
supports. pgx
supports many PostgreSQL types by default.
New types can be defined via PostgresType
or PostgresEnum
.
Without any arguments or returns:
use pgx::*;
#[pg_extern]
fn foo() { todo!() }
Arguments
It’s possible to pass even complex arguments:
use pgx::*;
#[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 pgx::*;
#[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 pgx::*;
#[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 pgx::*;
#[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 pgx::*;
#[pg_extern]
fn floop() -> impl Iterator<Item = (name!(a, i32), name!(b, i32))> {
None.into_iter() // Help type inference...
}
#[pg_extern]
fn singlular_floop() -> (name!(a, i32), name!(b, i32)) {
todo!()
}
The name!()
macro may only be used in return position inside the Item
of an impl Iterator
.
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 pgx::*;
#[pg_extern]
fn example_arg(animals: pg_sys::Oid) {
todo!()
}
#[pg_extern]
fn example_return() -> pg_sys::Oid {
todo!()
}