Skip to content

Commit

Permalink
Require FromDatum::from_polymorphic_datum (#749)
Browse files Browse the repository at this point in the history
* Require `FromDatum::from_polymorphic_datum`

This also implies defaulting `FromDatum::from_datum` which just
calls `FromDatum::from_polymorphic_datum` with `pg_sys::InvalidOid`.
Polymorphic types like AnyElement should generally override this
on implementing, and non-polymorphic types should ignore
the third parameter, while others may want a pass-through behavior.
  • Loading branch information
workingjubilee authored Oct 7, 2022
1 parent 6aaad98 commit 2ed0cb1
Show file tree
Hide file tree
Showing 25 changed files with 215 additions and 90 deletions.
2 changes: 1 addition & 1 deletion pgx-examples/bgworker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub extern "C" fn _PG_init() {
#[pg_guard]
#[no_mangle]
pub extern "C" fn background_worker_main(arg: pg_sys::Datum) {
let arg = unsafe { i32::from_datum(arg, false, pg_sys::INT4OID) };
let arg = unsafe { i32::from_polymorphic_datum(arg, false, pg_sys::INT4OID) };

// these are the signals we want to receive. If we don't attach the SIGTERM handler, then
// we'll never be able to exit via an external notification
Expand Down
2 changes: 1 addition & 1 deletion pgx-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ fn impl_postgres_enum(ast: DeriveInput) -> proc_macro2::TokenStream {
stream.extend(quote! {
impl ::pgx::datum::FromDatum for #enum_ident {
#[inline]
unsafe fn from_datum(datum: ::pgx::pg_sys::Datum, is_null: bool, typeoid: ::pgx::pg_sys::Oid) -> Option<#enum_ident> {
unsafe fn from_polymorphic_datum(datum: ::pgx::pg_sys::Datum, is_null: bool, typeoid: ::pgx::pg_sys::Oid) -> Option<#enum_ident> {
if is_null {
None
} else {
Expand Down
11 changes: 4 additions & 7 deletions pgx/src/datum/anyarray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,17 @@ impl AnyArray {

#[inline]
pub fn into<T: FromDatum>(&self) -> Option<T> {
unsafe { T::from_datum(self.datum(), false, self.oid()) }
unsafe { T::from_polymorphic_datum(self.datum(), false, self.oid()) }
}
}

impl FromDatum for AnyArray {
const GET_TYPOID: bool = true;

#[inline]
unsafe fn from_datum(
datum: pg_sys::Datum,
is_null: bool,
typoid: pg_sys::Oid,
) -> Option<AnyArray> {
FromDatum::from_polymorphic_datum(datum, is_null, typoid)
unsafe fn from_datum(_datum: pg_sys::Datum, _is_null: bool) -> Option<AnyArray> {
debug_assert!(false, "Can't create a polymorphic type using from_datum, call FromDatum::from_polymorphic_datum instead");
None
}

#[inline]
Expand Down
11 changes: 4 additions & 7 deletions pgx/src/datum/anyelement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,17 @@ impl AnyElement {

#[inline]
pub fn into<T: FromDatum>(&self) -> Option<T> {
unsafe { T::from_datum(self.datum(), false, self.oid()) }
unsafe { T::from_polymorphic_datum(self.datum(), false, self.oid()) }
}
}

impl FromDatum for AnyElement {
const GET_TYPOID: bool = true;

#[inline]
unsafe fn from_datum(
datum: pg_sys::Datum,
is_null: bool,
typoid: pg_sys::Oid,
) -> Option<AnyElement> {
FromDatum::from_polymorphic_datum(datum, is_null, typoid)
unsafe fn from_datum(_datum: pg_sys::Datum, _is_null: bool) -> Option<AnyElement> {
debug_assert!(false, "Can't create a polymorphic type using from_datum, call FromDatum::from_polymorphic_datum instead");
None
}

#[inline]
Expand Down
16 changes: 8 additions & 8 deletions pgx/src/datum/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ impl<'a, T: FromDatum> Array<'a, T> {
None
} else {
Some(unsafe {
T::from_datum(
T::from_polymorphic_datum(
self.elem_slice[i],
self.null_slice.get(i)?,
self.raw.as_ref().map(|r| r.oid()).unwrap_or_default(),
Expand Down Expand Up @@ -502,18 +502,18 @@ impl<'a, T: FromDatum> Iterator for ArrayIntoIterator<'a, T> {

impl<'a, T: FromDatum> FromDatum for VariadicArray<'a, T> {
#[inline]
unsafe fn from_datum(
unsafe fn from_polymorphic_datum(
datum: pg_sys::Datum,
is_null: bool,
oid: pg_sys::Oid,
) -> Option<VariadicArray<'a, T>> {
Array::from_datum(datum, is_null, oid).map(Self)
Array::from_polymorphic_datum(datum, is_null, oid).map(Self)
}
}

impl<'a, T: FromDatum> FromDatum for Array<'a, T> {
#[inline]
unsafe fn from_datum(
unsafe fn from_polymorphic_datum(
datum: pg_sys::Datum,
is_null: bool,
_typoid: u32,
Expand All @@ -536,15 +536,15 @@ impl<'a, T: FromDatum> FromDatum for Array<'a, T> {

impl<T: FromDatum> FromDatum for Vec<T> {
#[inline]
unsafe fn from_datum(
unsafe fn from_polymorphic_datum(
datum: pg_sys::Datum,
is_null: bool,
typoid: pg_sys::Oid,
) -> Option<Vec<T>> {
if is_null {
None
} else {
let array = Array::<T>::from_datum(datum, is_null, typoid).unwrap();
let array = Array::<T>::from_polymorphic_datum(datum, is_null, typoid).unwrap();
let mut v = Vec::with_capacity(array.len());

for element in array.iter() {
Expand All @@ -557,15 +557,15 @@ impl<T: FromDatum> FromDatum for Vec<T> {

impl<T: FromDatum> FromDatum for Vec<Option<T>> {
#[inline]
unsafe fn from_datum(
unsafe fn from_polymorphic_datum(
datum: pg_sys::Datum,
is_null: bool,
typoid: pg_sys::Oid,
) -> Option<Vec<Option<T>>> {
if is_null || datum.is_null() {
None
} else {
let array = Array::<T>::from_datum(datum, is_null, typoid).unwrap();
let array = Array::<T>::from_polymorphic_datum(datum, is_null, typoid).unwrap();
let mut v = Vec::with_capacity(array.len());

for element in array.iter() {
Expand Down
6 changes: 5 additions & 1 deletion pgx/src/datum/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ impl IntoDatum for Date {
}

impl FromDatum for Date {
unsafe fn from_datum(datum: pg_sys::Datum, is_null: bool, _: pg_sys::Oid) -> Option<Self>
unsafe fn from_polymorphic_datum(
datum: pg_sys::Datum,
is_null: bool,
_: pg_sys::Oid,
) -> Option<Self>
where
Self: Sized,
{
Expand Down
Loading

0 comments on commit 2ed0cb1

Please sign in to comment.