PgBinaryProtocol.rs
· 2.1 KiB · Rust
Raw
if args.contains(&PostgresTypeAttribute::PgBinaryProtocol) {
// At this time, the `PostgresTypeAttribute` does not impact the way we generate
// the `recv` and `send` functions.
stream.extend(quote! {
#[doc(hidden)]
#[::pgrx::pgrx_macros::pg_extern(immutable, strict, parallel_safe)]
pub fn #funcname_recv #generics(
internal: ::pgrx::datum::Internal,
) -> #name #generics {
let buf = unsafe { internal.get_mut::<::pgrx::pg_sys::StringInfoData>().unwrap() };
let mut serialized = ::pgrx::StringInfo::new();
serialized.push_bytes(&[0u8; ::pgrx::pg_sys::VARHDRSZ]); // reserve space for the header
serialized.push_bytes(unsafe {
core::slice::from_raw_parts(
buf.data as *const u8,
buf.len as usize
)
});
let size = serialized.len();
let varlena = serialized.into_char_ptr();
unsafe{
::pgrx::set_varsize_4b(varlena as *mut ::pgrx::pg_sys::varlena, size as i32);
buf.cursor = buf.len;
::pgrx::datum::cbor_decode(varlena as *mut ::pgrx::pg_sys::varlena)
}
}
#[doc(hidden)]
#[::pgrx::pgrx_macros::pg_extern(immutable, strict, parallel_safe)]
pub fn #funcname_send #generics(input: #name #generics) -> Vec<u8> {
use ::pgrx::datum::{FromDatum, IntoDatum};
let Some(datum): Option<::pgrx::pg_sys::Datum> = input.into_datum() else {
::pgrx::error!("Datum of type `{}` is unexpectedly NULL.", stringify!(#name));
};
unsafe {
let Some(serialized): Option<Vec<u8>> = FromDatum::from_datum(datum, false) else {
::pgrx::error!("Failed to CBOR-serialize Datum to type `{}`.", stringify!(#name));
};
serialized
}
}
});
| 1 | if args.contains(&PostgresTypeAttribute::PgBinaryProtocol) { |
| 2 | // At this time, the `PostgresTypeAttribute` does not impact the way we generate |
| 3 | // the `recv` and `send` functions. |
| 4 | stream.extend(quote! { |
| 5 | #[doc(hidden)] |
| 6 | #[::pgrx::pgrx_macros::pg_extern(immutable, strict, parallel_safe)] |
| 7 | pub fn #funcname_recv #generics( |
| 8 | internal: ::pgrx::datum::Internal, |
| 9 | ) -> #name #generics { |
| 10 | let buf = unsafe { internal.get_mut::<::pgrx::pg_sys::StringInfoData>().unwrap() }; |
| 11 | |
| 12 | let mut serialized = ::pgrx::StringInfo::new(); |
| 13 | |
| 14 | serialized.push_bytes(&[0u8; ::pgrx::pg_sys::VARHDRSZ]); // reserve space for the header |
| 15 | serialized.push_bytes(unsafe { |
| 16 | core::slice::from_raw_parts( |
| 17 | buf.data as *const u8, |
| 18 | buf.len as usize |
| 19 | ) |
| 20 | }); |
| 21 | |
| 22 | let size = serialized.len(); |
| 23 | let varlena = serialized.into_char_ptr(); |
| 24 | |
| 25 | unsafe{ |
| 26 | ::pgrx::set_varsize_4b(varlena as *mut ::pgrx::pg_sys::varlena, size as i32); |
| 27 | buf.cursor = buf.len; |
| 28 | ::pgrx::datum::cbor_decode(varlena as *mut ::pgrx::pg_sys::varlena) |
| 29 | } |
| 30 | } |
| 31 | #[doc(hidden)] |
| 32 | #[::pgrx::pgrx_macros::pg_extern(immutable, strict, parallel_safe)] |
| 33 | pub fn #funcname_send #generics(input: #name #generics) -> Vec<u8> { |
| 34 | use ::pgrx::datum::{FromDatum, IntoDatum}; |
| 35 | let Some(datum): Option<::pgrx::pg_sys::Datum> = input.into_datum() else { |
| 36 | ::pgrx::error!("Datum of type `{}` is unexpectedly NULL.", stringify!(#name)); |
| 37 | }; |
| 38 | unsafe { |
| 39 | let Some(serialized): Option<Vec<u8>> = FromDatum::from_datum(datum, false) else { |
| 40 | ::pgrx::error!("Failed to CBOR-serialize Datum to type `{}`.", stringify!(#name)); |
| 41 | }; |
| 42 | serialized |
| 43 | } |
| 44 | } |
| 45 | }); |
| 46 |