From 70e0a3e91af3841ad4f6db057e42c877802cbd48 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Wed, 25 Sep 2024 12:56:30 +0300 Subject: [PATCH 1/4] Added oids_of macro --- pgrx-tests/src/tests/spi_tests.rs | 19 ++++++------------- pgrx/src/datum/mod.rs | 17 +++++++++++++++++ pgrx/src/prelude.rs | 13 ++++++++----- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/pgrx-tests/src/tests/spi_tests.rs b/pgrx-tests/src/tests/spi_tests.rs index 05b16ee616..2df12a2fe8 100644 --- a/pgrx-tests/src/tests/spi_tests.rs +++ b/pgrx-tests/src/tests/spi_tests.rs @@ -17,8 +17,7 @@ mod tests { use std::error::Error; use pgrx::prelude::*; - use pgrx::spi; - use pgrx::spi::Query; + use pgrx::spi::{self, Query}; #[pg_test(error = "syntax error at or near \"THIS\"")] fn test_spi_failure() -> Result<(), spi::Error> { @@ -253,10 +252,8 @@ mod tests { None, &[], )?; - let prepared = client.prepare( - "SELECT * FROM tests.cursor_table WHERE id = $1", - &[PgBuiltInOids::INT4OID.oid()], - )?; + let prepared = + client.prepare("SELECT * FROM tests.cursor_table WHERE id = $1", &oids_of![i32])?; client.open_cursor(&prepared, args); unreachable!(); }) @@ -376,8 +373,7 @@ mod tests { #[pg_test] fn test_prepared_statement() -> Result<(), spi::Error> { let rc = Spi::connect(|client| { - let prepared = - client.prepare("SELECT $1", &[PgOid::BuiltIn(PgBuiltInOids::INT4OID)])?; + let prepared = client.prepare("SELECT $1", &oids_of![i32])?; client.select(&prepared, None, &[42.into()])?.first().get::(1) })?; @@ -388,8 +384,7 @@ mod tests { #[pg_test] fn test_prepared_statement_argument_mismatch() { let err = Spi::connect(|client| { - let prepared = - client.prepare("SELECT $1", &[PgOid::BuiltIn(PgBuiltInOids::INT4OID)])?; + let prepared = client.prepare("SELECT $1", &oids_of![i32])?; client.select(&prepared, None, &[]).map(|_| ()) }) .unwrap_err(); @@ -403,9 +398,7 @@ mod tests { #[pg_test] fn test_owned_prepared_statement() -> Result<(), spi::Error> { let prepared = Spi::connect(|client| { - Ok::<_, spi::Error>( - client.prepare("SELECT $1", &[PgOid::BuiltIn(PgBuiltInOids::INT4OID)])?.keep(), - ) + Ok::<_, spi::Error>(client.prepare("SELECT $1", &oids_of![i32])?.keep()) })?; let rc = Spi::connect(|client| { client.select(&prepared, None, &[42.into()])?.first().get::(1) diff --git a/pgrx/src/datum/mod.rs b/pgrx/src/datum/mod.rs index cc5a7ba3eb..d321c13197 100644 --- a/pgrx/src/datum/mod.rs +++ b/pgrx/src/datum/mod.rs @@ -204,3 +204,20 @@ impl<'src, T: IntoDatum> From for DatumWithOid<'src> { /// A tagging trait to indicate a user type is also meant to be used by Postgres /// Implemented automatically by `#[derive(PostgresType)]` pub trait PostgresType {} + +/// Creates a [`Vec`] containing identifiers of the provded types. +/// +/// # Examples +/// +/// ``` +/// use pgrx::{oids_of, datum::IntoDatum}; +/// let v = oids_of![i32, f64]; +/// assert_eq!(v[0], i32::type_oid().into()); +/// assert_eq!(v[1], f64::type_oid().into()); +/// ``` +#[macro_export] +macro_rules! oids_of { + ($($t:path),* $(,)?) => ({ + [$(::pgrx::pg_sys::PgOid::from(<$t>::type_oid())),*] + }); +} diff --git a/pgrx/src/prelude.rs b/pgrx/src/prelude.rs index 44e2a67878..fa0fec391c 100644 --- a/pgrx/src/prelude.rs +++ b/pgrx/src/prelude.rs @@ -29,12 +29,15 @@ pub use crate::pgbox::{AllocatedByPostgres, AllocatedByRust, PgBox, WhoAllocated // These could be factored into a temporal type module that could be easily imported for code which works with them. // However, reexporting them seems fine for now. -pub use crate::datum::{ - datetime_support::*, AnyNumeric, Array, ArraySliceError, Date, FromDatum, Interval, IntoDatum, - Numeric, PgVarlena, PostgresType, Range, RangeBound, RangeSubType, Time, TimeWithTimeZone, - Timestamp, TimestampWithTimeZone, VariadicArray, -}; pub use crate::inoutfuncs::{InOutFuncs, PgVarlenaInOutFuncs}; +pub use crate::{ + datum::{ + datetime_support::*, AnyNumeric, Array, ArraySliceError, Date, FromDatum, Interval, + IntoDatum, Numeric, PgVarlena, PostgresType, Range, RangeBound, RangeSubType, Time, + TimeWithTimeZone, Timestamp, TimestampWithTimeZone, VariadicArray, + }, + oids_of, +}; // Trigger support pub use crate::trigger_support::{ From d29d80430ee80c9fc13b3a4c2e6d8ed02d7711d8 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Thu, 26 Sep 2024 14:48:11 +0300 Subject: [PATCH 2/4] Macro hygiene and zero sized array --- pgrx/src/datum/mod.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pgrx/src/datum/mod.rs b/pgrx/src/datum/mod.rs index d321c13197..8db28e358c 100644 --- a/pgrx/src/datum/mod.rs +++ b/pgrx/src/datum/mod.rs @@ -217,7 +217,10 @@ pub trait PostgresType {} /// ``` #[macro_export] macro_rules! oids_of { - ($($t:path),* $(,)?) => ({ - [$(::pgrx::pg_sys::PgOid::from(<$t>::type_oid())),*] - }); + () =>( + [$crate::pg_sys::PgOid::Invalid; 0] + ); + ($($t:path),+ $(,)?) => ( + [$($crate::pg_sys::PgOid::from(<$t>::type_oid())),*] + ); } From add2824cbfe91deb95783a659dd667206851ab28 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Mon, 25 Nov 2024 16:03:10 +0300 Subject: [PATCH 3/4] Doc improvement --- pgrx/src/datum/mod.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/pgrx/src/datum/mod.rs b/pgrx/src/datum/mod.rs index 8db28e358c..b26fd24d7a 100644 --- a/pgrx/src/datum/mod.rs +++ b/pgrx/src/datum/mod.rs @@ -211,9 +211,14 @@ pub trait PostgresType {} /// /// ``` /// use pgrx::{oids_of, datum::IntoDatum}; -/// let v = oids_of![i32, f64]; -/// assert_eq!(v[0], i32::type_oid().into()); -/// assert_eq!(v[1], f64::type_oid().into()); +/// let oids = oids_of![i32, f64]; +/// assert_eq!(oids[0], i32::type_oid().into()); +/// assert_eq!(oids[1], f64::type_oid().into()); +/// +/// // the usual conversions or coercions are available +/// let oid_vec = oids_of![i8, i16].to_vec(); +/// let no_oid = &oids_of![]; +/// assert_eq!(no_oid.len(), 0); /// ``` #[macro_export] macro_rules! oids_of { From 9a274b0fc72411c07f128afdcf91fb730f1aec55 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Mon, 25 Nov 2024 16:30:35 +0300 Subject: [PATCH 4/4] Suggestions Co-authored-by: Jubilee --- pgrx/src/datum/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pgrx/src/datum/mod.rs b/pgrx/src/datum/mod.rs index b26fd24d7a..4c1b854ed0 100644 --- a/pgrx/src/datum/mod.rs +++ b/pgrx/src/datum/mod.rs @@ -205,12 +205,13 @@ impl<'src, T: IntoDatum> From for DatumWithOid<'src> { /// Implemented automatically by `#[derive(PostgresType)]` pub trait PostgresType {} -/// Creates a [`Vec`] containing identifiers of the provded types. +/// Creates an array of [`pg_sys::Oid`] with the OID of each provided type /// /// # Examples /// /// ``` /// use pgrx::{oids_of, datum::IntoDatum}; +/// /// let oids = oids_of![i32, f64]; /// assert_eq!(oids[0], i32::type_oid().into()); /// assert_eq!(oids[1], f64::type_oid().into()); @@ -223,6 +224,7 @@ pub trait PostgresType {} #[macro_export] macro_rules! oids_of { () =>( + // avoid coercions to an ambiguously-typed array or slice [$crate::pg_sys::PgOid::Invalid; 0] ); ($($t:path),+ $(,)?) => (