Skip to content

Commit 1fe2fde

Browse files
impl FromDatum for CString (pgcentralfoundation#1896)
As much as I would like FromDatum to unexist, it should probably be usable for all std types we even half-support, especially since it's less dubious, in several ways, than the `&'a CStr` impl.
1 parent d834720 commit 1fe2fde

File tree

1 file changed

+33
-4
lines changed

1 file changed

+33
-4
lines changed

pgrx/src/datum/from.rs

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use crate::{
1313
pg_sys, varlena, varlena_to_byte_slice, AllocatedByPostgres, IntoDatum, PgBox, PgMemoryContexts,
1414
};
15+
use alloc::ffi::CString;
1516
use core::{ffi::CStr, mem::size_of};
1617
use std::num::NonZeroUsize;
1718

@@ -448,7 +449,7 @@ impl FromDatum for char {
448449
}
449450

450451
/// for cstring
451-
impl<'a> FromDatum for &'a core::ffi::CStr {
452+
impl<'a> FromDatum for &'a CStr {
452453
#[inline]
453454
unsafe fn from_polymorphic_datum(
454455
datum: pg_sys::Datum,
@@ -458,7 +459,7 @@ impl<'a> FromDatum for &'a core::ffi::CStr {
458459
if is_null || datum.is_null() {
459460
None
460461
} else {
461-
Some(core::ffi::CStr::from_ptr(datum.cast_mut_ptr()))
462+
Some(CStr::from_ptr(datum.cast_mut_ptr()))
462463
}
463464
}
464465

@@ -474,14 +475,42 @@ impl<'a> FromDatum for &'a core::ffi::CStr {
474475
if is_null || datum.is_null() {
475476
None
476477
} else {
477-
let copy = memory_context
478-
.switch_to(|_| core::ffi::CStr::from_ptr(pg_sys::pstrdup(datum.cast_mut_ptr())));
478+
let copy =
479+
memory_context.switch_to(|_| CStr::from_ptr(pg_sys::pstrdup(datum.cast_mut_ptr())));
479480

480481
Some(copy)
481482
}
482483
}
483484
}
484485

486+
impl FromDatum for CString {
487+
#[inline]
488+
unsafe fn from_polymorphic_datum(
489+
datum: pg_sys::Datum,
490+
is_null: bool,
491+
_: pg_sys::Oid,
492+
) -> Option<CString> {
493+
if is_null || datum.is_null() {
494+
None
495+
} else {
496+
Some(CStr::from_ptr(datum.cast_mut_ptr()).to_owned())
497+
}
498+
}
499+
500+
/// Nonsensical because CString is always allocated within Rust memory.
501+
unsafe fn from_datum_in_memory_context(
502+
_memory_context: PgMemoryContexts,
503+
datum: pg_sys::Datum,
504+
is_null: bool,
505+
_typoid: pg_sys::Oid,
506+
) -> Option<Self>
507+
where
508+
Self: Sized,
509+
{
510+
Self::from_polymorphic_datum(datum, is_null, _typoid)
511+
}
512+
}
513+
485514
/// for bytea
486515
impl<'a> FromDatum for &'a [u8] {
487516
#[inline]

0 commit comments

Comments
 (0)