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 |