a function to let us stash an object in a function call's "fn_extra" space and ensure it's automatically freed
//!
//! Other than the exported macros, typically these functions are not necessary to call directly
//! as they're used behind the scenes by the code generated by the `#[pg_extern]` macro.
-use crate::{pg_sys, FromDatum, PgBox};
+use crate::{pg_sys, void_mut_ptr, FromDatum, PgBox, PgMemoryContexts};
/// A macro for specifying default argument values so they get propery translated to SQL in
/// `CREATE FUNCTION` statements
@@ -202,6 +202,20 @@ pub fn pg_return_void() -> pg_sys::Datum {
0 as pg_sys::Datum
}
+pub fn pg_func_extra<ReturnType, DefaultValue: FnOnce() -> ReturnType>(
+ fcinfo: pg_sys::FunctionCallInfo,
+ default: DefaultValue,
+) -> PgBox<ReturnType> {
+ let fcinfo = PgBox::from_pg(fcinfo);
+ let mut flinfo = PgBox::from_pg(fcinfo.flinfo);
+ if flinfo.fn_extra.is_null() {
+ flinfo.fn_extra = PgMemoryContexts::For(flinfo.fn_mcxt).leak_and_drop_on_delete(default())
+ as void_mut_ptr;
+ }
+
+ PgBox::from_pg(flinfo.fn_extra as *mut ReturnType)
+}
+
/// As `#[pg_extern]` functions are wrapped with a different signature, this
/// allows you to directly call them.
///
