From 861974c735917e88384f45e71f57f97f46b0498f Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 11 Sep 2024 09:30:55 -0700 Subject: [PATCH] The crown jewel of this entire exercise --- pgrx/src/callconv.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/pgrx/src/callconv.rs b/pgrx/src/callconv.rs index 49103fec9..a54b4745d 100644 --- a/pgrx/src/callconv.rs +++ b/pgrx/src/callconv.rs @@ -10,14 +10,15 @@ #![deny(unsafe_op_in_unsafe_fn)] //! Helper implementations for returning sets and tables from `#[pg_extern]`-style functions -use crate::datum::Datum; use crate::datum::{ AnyArray, AnyElement, AnyNumeric, Date, FromDatum, Inet, Internal, Interval, IntoDatum, Json, JsonB, Numeric, PgVarlena, Time, TimeWithTimeZone, Timestamp, TimestampWithTimeZone, UnboxDatum, Uuid, }; +use crate::datum::{BorrowDatum, Datum}; use crate::datum::{Range, RangeSubType}; use crate::heap_tuple::PgHeapTuple; +use crate::layout::PassBy; use crate::nullable::Nullable; use crate::pg_sys; use crate::pgbox::*; @@ -267,6 +268,20 @@ argue_from_datum! { 'fcx; Inet, Internal, Json, JsonB, Uuid, PgRelation } argue_from_datum! { 'fcx; pg_sys::BOX, pg_sys::ItemPointerData, pg_sys::Oid, pg_sys::Point } argue_from_datum! { 'fcx; &'fcx str, &'fcx CStr, &'fcx [u8] } +unsafe impl<'fcx, T> ArgAbi<'fcx> for &T +where + T: BorrowDatum, +{ + unsafe fn unbox_arg_unchecked(arg: Arg<'_, 'fcx>) -> Self { + let ptr: *mut u8 = match T::PASS { + Some(PassBy::Ref) => arg.2.value.cast_mut_ptr(), + Some(PassBy::Value) => ptr::addr_of!(arg.0.raw_args()[arg.1].value).cast_mut().cast(), + _ => todo!(), + }; + unsafe { &*T::point_from(ptr) } + } +} + /// How to return a value from Rust to Postgres /// /// This bound is necessary to distinguish things which can be returned from a `#[pg_extern] fn`.