From 540c8697a358f6002b65e56cc64d72297c2cd093 Mon Sep 17 00:00:00 2001 From: usamoi Date: Wed, 25 Jun 2025 21:13:56 +0800 Subject: [PATCH 1/2] fix ci on beta rust --- cargo-pgrx/src/command/info.rs | 2 +- cargo-pgrx/src/command/schema.rs | 2 +- pgrx-macros/src/lib.rs | 4 ++-- pgrx-pg-sys/src/include.rs | 6 ++++++ pgrx-tests/src/tests/hooks_tests.rs | 2 ++ pgrx-tests/src/tests/trigger_tests.rs | 4 +++- .../table-iterators-arent-immortal.rs | 2 +- .../table-iterators-arent-immortal.stderr | 18 +++--------------- pgrx/src/datum/into.rs | 2 +- pgrx/src/fn_call.rs | 2 +- pgrx/src/lwlock.rs | 4 ++-- pgrx/src/rel.rs | 2 +- pgrx/src/spi/cursor.rs | 2 +- pgrx/src/tupdesc.rs | 4 ++-- 14 files changed, 27 insertions(+), 29 deletions(-) diff --git a/cargo-pgrx/src/command/info.rs b/cargo-pgrx/src/command/info.rs index f673d45cac..84e732a2b2 100644 --- a/cargo-pgrx/src/command/info.rs +++ b/cargo-pgrx/src/command/info.rs @@ -78,7 +78,7 @@ impl CommandExecute for Info { } } -fn version(ver: &str) -> Cow { +fn version(ver: &str) -> Cow<'_, str> { if ver.starts_with("pg") { Cow::Borrowed(ver) } else { diff --git a/cargo-pgrx/src/command/schema.rs b/cargo-pgrx/src/command/schema.rs index 9b4a951396..21d8aa1d97 100644 --- a/cargo-pgrx/src/command/schema.rs +++ b/cargo-pgrx/src/command/schema.rs @@ -594,7 +594,7 @@ fn compute_sql(package_name: &str, manifest: &Manifest) -> eyre::Result<()> { Ok(()) } -fn parse_object(data: &[u8]) -> object::Result { +fn parse_object(data: &[u8]) -> object::Result> { let kind = object::FileKind::parse(data)?; match kind { diff --git a/pgrx-macros/src/lib.rs b/pgrx-macros/src/lib.rs index 37c70bdfcc..b070451806 100644 --- a/pgrx-macros/src/lib.rs +++ b/pgrx-macros/src/lib.rs @@ -967,7 +967,7 @@ fn impl_postgres_type(ast: DeriveInput) -> syn::Result #[::pgrx::pgrx_macros::pg_extern(immutable,parallel_safe)] pub fn #funcname_in #generics(input: Option<&::core::ffi::CStr>) -> Option<#name #generics> { input.map_or_else(|| { - for m in <#name as ::pgrx::inoutfuncs::InOutFuncs>::NULL_ERROR_MESSAGE { + if let Some(m) = <#name as ::pgrx::inoutfuncs::InOutFuncs>::NULL_ERROR_MESSAGE { ::pgrx::pg_sys::error!("{m}"); } None @@ -990,7 +990,7 @@ fn impl_postgres_type(ast: DeriveInput) -> syn::Result #[::pgrx::pgrx_macros::pg_extern(immutable,parallel_safe)] pub fn #funcname_in #generics(input: Option<&::core::ffi::CStr>) -> Option<::pgrx::datum::PgVarlena<#name #generics>> { input.map_or_else(|| { - for m in <#name as ::pgrx::inoutfuncs::PgVarlenaInOutFuncs>::NULL_ERROR_MESSAGE { + if let Some(m) = <#name as ::pgrx::inoutfuncs::PgVarlenaInOutFuncs>::NULL_ERROR_MESSAGE { ::pgrx::pg_sys::error!("{m}"); } None diff --git a/pgrx-pg-sys/src/include.rs b/pgrx-pg-sys/src/include.rs index 0e35f07bc2..08b979df32 100644 --- a/pgrx-pg-sys/src/include.rs +++ b/pgrx-pg-sys/src/include.rs @@ -5,6 +5,7 @@ #[cfg(all(feature = "pg13", not(docsrs)))] pub(crate) mod pg13 { #![allow(clippy::all)] + #![allow(unknown_lints, unnecessary_transmutes)] include!(concat!(env!("OUT_DIR"), "/pg13.rs")); } #[cfg(all(feature = "pg13", docsrs))] @@ -13,6 +14,7 @@ pub(crate) mod pg13; #[cfg(all(feature = "pg14", not(docsrs)))] pub(crate) mod pg14 { #![allow(clippy::all)] + #![allow(unknown_lints, unnecessary_transmutes)] include!(concat!(env!("OUT_DIR"), "/pg14.rs")); } #[cfg(all(feature = "pg14", docsrs))] @@ -21,6 +23,7 @@ pub(crate) mod pg14; #[cfg(all(feature = "pg15", not(docsrs)))] pub(crate) mod pg15 { #![allow(clippy::all)] + #![allow(unknown_lints, unnecessary_transmutes)] include!(concat!(env!("OUT_DIR"), "/pg15.rs")); } #[cfg(all(feature = "pg15", docsrs))] @@ -29,6 +32,7 @@ pub(crate) mod pg15; #[cfg(all(feature = "pg16", not(docsrs)))] pub(crate) mod pg16 { #![allow(clippy::all)] + #![allow(unknown_lints, unnecessary_transmutes)] include!(concat!(env!("OUT_DIR"), "/pg16.rs")); } #[cfg(all(feature = "pg16", docsrs))] @@ -37,6 +41,7 @@ pub(crate) mod pg16; #[cfg(all(feature = "pg17", not(docsrs)))] pub(crate) mod pg17 { #![allow(clippy::all)] + #![allow(unknown_lints, unnecessary_transmutes)] include!(concat!(env!("OUT_DIR"), "/pg17.rs")); } #[cfg(all(feature = "pg17", docsrs))] @@ -45,6 +50,7 @@ pub(crate) mod pg17; #[cfg(all(feature = "pg18", not(docsrs)))] pub(crate) mod pg18 { #![allow(clippy::all)] + #![allow(unknown_lints, unnecessary_transmutes)] include!(concat!(env!("OUT_DIR"), "/pg18.rs")); } #[cfg(all(feature = "pg18", docsrs))] diff --git a/pgrx-tests/src/tests/hooks_tests.rs b/pgrx-tests/src/tests/hooks_tests.rs index 05dfe3961a..36bfc170f0 100644 --- a/pgrx-tests/src/tests/hooks_tests.rs +++ b/pgrx-tests/src/tests/hooks_tests.rs @@ -7,6 +7,8 @@ //LICENSE All rights reserved. //LICENSE //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. +#![allow(deprecated, static_mut_refs)] + #[cfg(any(test, feature = "pg_test"))] #[pgrx::pg_schema] mod tests { diff --git a/pgrx-tests/src/tests/trigger_tests.rs b/pgrx-tests/src/tests/trigger_tests.rs index a92b16b635..14b724a0fd 100644 --- a/pgrx-tests/src/tests/trigger_tests.rs +++ b/pgrx-tests/src/tests/trigger_tests.rs @@ -74,7 +74,9 @@ mod tests { } #[pg_trigger] - fn signature_aliased_both(_trigger: AliasedBorrowedPgTrigger) -> AliasedTriggerResult<'_> { + fn signature_aliased_both( + _trigger: AliasedBorrowedPgTrigger<'_>, + ) -> AliasedTriggerResult<'_> { unimplemented!("Only testing signature compiles") } } diff --git a/pgrx-tests/tests/compile-fail/table-iterators-arent-immortal.rs b/pgrx-tests/tests/compile-fail/table-iterators-arent-immortal.rs index b92efcaa34..7c0577bfc9 100644 --- a/pgrx-tests/tests/compile-fail/table-iterators-arent-immortal.rs +++ b/pgrx-tests/tests/compile-fail/table-iterators-arent-immortal.rs @@ -3,7 +3,7 @@ use pgrx::prelude::*; #[pg_extern] fn returns_tuple_with_lifetime( value: &'static str, -) -> TableIterator<(name!(a, &'static str), name!(b, Option<&'static str>))> { +) -> TableIterator<'static, (name!(a, &'static str), name!(b, Option<&'static str>))> { TableIterator::once((value, Some(value))) } diff --git a/pgrx-tests/tests/compile-fail/table-iterators-arent-immortal.stderr b/pgrx-tests/tests/compile-fail/table-iterators-arent-immortal.stderr index 331cb9420c..d8e1536eb1 100644 --- a/pgrx-tests/tests/compile-fail/table-iterators-arent-immortal.stderr +++ b/pgrx-tests/tests/compile-fail/table-iterators-arent-immortal.stderr @@ -1,17 +1,5 @@ -warning: elided lifetime has a name - --> tests/compile-fail/table-iterators-arent-immortal.rs:6:19 - | -6 | ) -> TableIterator<(name!(a, &'static str), name!(b, Option<&'static str>))> { - | ^ this elided lifetime gets resolved as `'static` - | - = note: `#[warn(elided_named_lifetimes)]` on by default -help: consider specifying it explicitly - | -6 | ) -> TableIterator<'static, (name!(a, &'static str), name!(b, Option<&'static str>))> { - | ++++++++ - error[E0521]: borrowed data escapes outside of function - --> tests/compile-fail/table-iterators-arent-immortal.rs:6:78 + --> tests/compile-fail/table-iterators-arent-immortal.rs:6:87 | 3 | #[pg_extern] | ------------ @@ -19,8 +7,8 @@ error[E0521]: borrowed data escapes outside of function | lifetime `'fcx` defined here | in this procedural macro expansion ... -6 | ) -> TableIterator<(name!(a, &'static str), name!(b, Option<&'static str>))> { - | ______________________________________________________________________________^ +6 | ) -> TableIterator<'static, (name!(a, &'static str), name!(b, Option<&'static str>))> { + | _______________________________________________________________________________________^ 7 | | TableIterator::once((value, Some(value))) 8 | | } | | ^ diff --git a/pgrx/src/datum/into.rs b/pgrx/src/datum/into.rs index 31d6d6bb1c..4d8bc82d38 100644 --- a/pgrx/src/datum/into.rs +++ b/pgrx/src/datum/into.rs @@ -378,7 +378,7 @@ impl<'a> IntoDatum for &'a [u8] { // and the `dest` was freshly allocated, thus non-overlapping std::ptr::copy_nonoverlapping( self.as_ptr(), - addr_of_mut!((*varattrib_4b).va_data).cast::(), + addr_of_mut!((&mut *varattrib_4b).va_data).cast::(), self.len(), ); diff --git a/pgrx/src/fn_call.rs b/pgrx/src/fn_call.rs index bf1f2ccabb..37b769e7ce 100644 --- a/pgrx/src/fn_call.rs +++ b/pgrx/src/fn_call.rs @@ -410,7 +410,7 @@ fn lookup_fn(fname: &str, args: &[&dyn FnCallArg]) -> Result { /// Parses an arbitrary string as if it is a SQL identifier. If it's not, [`FnCallError::InvalidIdentifier`] /// is returned -fn parse_sql_ident(ident: &str) -> Result> { +fn parse_sql_ident(ident: &str) -> Result> { unsafe { direct_function_call::>( pg_sys::parse_ident, diff --git a/pgrx/src/lwlock.rs b/pgrx/src/lwlock.rs index c6e7827e5e..99889d837a 100644 --- a/pgrx/src/lwlock.rs +++ b/pgrx/src/lwlock.rs @@ -51,7 +51,7 @@ impl PgLwLock { } /// Obtain a shared lock (which comes with `&T` access) - pub fn share(&self) -> PgLwLockShareGuard { + pub fn share(&self) -> PgLwLockShareGuard<'_, T> { unsafe { let shared = self.inner.get().read().as_ref().expect("PgLwLock was not initialized"); pg_sys::LWLockAcquire((*shared).lock_ptr, pg_sys::LWLockMode::LW_SHARED); @@ -60,7 +60,7 @@ impl PgLwLock { } /// Obtain an exclusive lock (which comes with `&mut T` access) - pub fn exclusive(&self) -> PgLwLockExclusiveGuard { + pub fn exclusive(&self) -> PgLwLockExclusiveGuard<'_, T> { unsafe { let shared = self.inner.get().read().as_ref().expect("PgLwLock was not initialized"); pg_sys::LWLockAcquire((*shared).lock_ptr, pg_sys::LWLockMode::LW_EXCLUSIVE); diff --git a/pgrx/src/rel.rs b/pgrx/src/rel.rs index 8206e2e0c6..aedbe2b809 100644 --- a/pgrx/src/rel.rs +++ b/pgrx/src/rel.rs @@ -235,7 +235,7 @@ impl PgRelation { /// // assert that the tuple descriptor has 12 attributes /// assert_eq!(tupdesc.len(), 12); /// ``` - pub fn tuple_desc(&self) -> PgTupleDesc { + pub fn tuple_desc(&self) -> PgTupleDesc<'_> { PgTupleDesc::from_relation(self) } diff --git a/pgrx/src/spi/cursor.rs b/pgrx/src/spi/cursor.rs index 8aaa547577..5efb8cbe36 100644 --- a/pgrx/src/spi/cursor.rs +++ b/pgrx/src/spi/cursor.rs @@ -72,7 +72,7 @@ impl SpiCursor<'_> { /// Fetch up to `count` rows from the cursor, moving forward /// /// If `fetch` runs off the end of the available rows, an empty [`SpiTupleTable`] is returned. - pub fn fetch(&mut self, count: libc::c_long) -> SpiResult { + pub fn fetch(&mut self, count: libc::c_long) -> SpiResult> { // SAFETY: no concurrent access unsafe { pg_sys::SPI_tuptable = std::ptr::null_mut(); diff --git a/pgrx/src/tupdesc.rs b/pgrx/src/tupdesc.rs index 226b747302..db4de853ab 100644 --- a/pgrx/src/tupdesc.rs +++ b/pgrx/src/tupdesc.rs @@ -142,7 +142,7 @@ impl<'a> PgTupleDesc<'a> { } /// wrap the `pg_sys::TupleDesc` contained by the specified `PgRelation` - pub fn from_relation(parent: &PgRelation) -> PgTupleDesc { + pub fn from_relation(parent: &PgRelation) -> PgTupleDesc<'_> { PgTupleDesc { // SAFETY: `parent` is a Rust reference, and as such its rd_att attribute will be property initialized tupdesc: Some(unsafe { PgBox::from_pg(parent.rd_att) }), @@ -232,7 +232,7 @@ impl<'a> PgTupleDesc<'a> { } /// Iterate over our attributes - pub fn iter(&self) -> TupleDescIterator { + pub fn iter(&self) -> TupleDescIterator<'_> { TupleDescIterator { tupdesc: self, curr: 0 } } From 29f01f93bfff29b9cb72e47e7877bf94460b9a1b Mon Sep 17 00:00:00 2001 From: usamoi Date: Wed, 25 Jun 2025 19:49:56 +0800 Subject: [PATCH 2/2] improve pg_magic_func --- cargo-pgrx/src/templates/lib_rs | 2 +- pgrx-examples/aggregate/src/lib.rs | 2 +- pgrx-examples/arrays/src/lib.rs | 2 +- pgrx-examples/bad_ideas/src/lib.rs | 2 +- pgrx-examples/bgworker/src/lib.rs | 2 +- pgrx-examples/bytea/src/lib.rs | 2 +- pgrx-examples/composite_type/src/lib.rs | 2 +- pgrx-examples/custom_libname/src/lib.rs | 2 +- pgrx-examples/custom_sql/src/lib.rs | 2 +- pgrx-examples/custom_types/src/lib.rs | 2 +- pgrx-examples/datetime/src/lib.rs | 2 +- pgrx-examples/errors/src/lib.rs | 2 +- pgrx-examples/nostd/src/lib.rs | 2 +- pgrx-examples/numeric/src/lib.rs | 2 +- pgrx-examples/operators/src/lib.rs | 2 +- pgrx-examples/pgtrybuilder/src/lib.rs | 2 +- pgrx-examples/range/src/lib.rs | 2 +- pgrx-examples/schemas/src/lib.rs | 2 +- pgrx-examples/shmem/src/lib.rs | 2 +- pgrx-examples/spi/src/lib.rs | 2 +- pgrx-examples/spi_srf/src/lib.rs | 2 +- pgrx-examples/srf/src/lib.rs | 2 +- pgrx-examples/strings/src/lib.rs | 2 +- pgrx-examples/triggers/src/lib.rs | 2 +- .../versioned_custom_libname_so/src/lib.rs | 2 +- pgrx-examples/versioned_so/src/lib.rs | 2 +- pgrx-examples/wal_decoder/src/lib.rs | 2 +- pgrx-tests/src/lib.rs | 2 +- pgrx/src/lib.rs | 290 ++++++++---------- 29 files changed, 149 insertions(+), 197 deletions(-) diff --git a/cargo-pgrx/src/templates/lib_rs b/cargo-pgrx/src/templates/lib_rs index 609f68a66f..15a8a0e6c4 100644 --- a/cargo-pgrx/src/templates/lib_rs +++ b/cargo-pgrx/src/templates/lib_rs @@ -1,6 +1,6 @@ use pgrx::prelude::*; -::pgrx::pg_module_magic!(c"{name}", pgrx::pg_sys::PG_VERSION); +::pgrx::pg_module_magic!(name, version); #[pg_extern] fn hello_{name}() -> &'static str {{ diff --git a/pgrx-examples/aggregate/src/lib.rs b/pgrx-examples/aggregate/src/lib.rs index a6487a257b..863c9fcf0f 100644 --- a/pgrx-examples/aggregate/src/lib.rs +++ b/pgrx-examples/aggregate/src/lib.rs @@ -14,7 +14,7 @@ use pgrx::StringInfo; use serde::{Deserialize, Serialize}; use std::str::FromStr; -pgrx::pg_module_magic!(c"aggregate", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[derive(Copy, Clone, PostgresType, Serialize, Deserialize)] #[pgvarlena_inoutfuncs] diff --git a/pgrx-examples/arrays/src/lib.rs b/pgrx-examples/arrays/src/lib.rs index ec7eee1a66..59a3f24f47 100644 --- a/pgrx-examples/arrays/src/lib.rs +++ b/pgrx-examples/arrays/src/lib.rs @@ -10,7 +10,7 @@ use pgrx::prelude::*; use serde::*; -pgrx::pg_module_magic!(c"arrays", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[pg_extern] fn sq_euclid_pgrx(a: Array, b: Array) -> f32 { diff --git a/pgrx-examples/bad_ideas/src/lib.rs b/pgrx-examples/bad_ideas/src/lib.rs index bce21aca7a..b815aacbe6 100644 --- a/pgrx-examples/bad_ideas/src/lib.rs +++ b/pgrx-examples/bad_ideas/src/lib.rs @@ -14,7 +14,7 @@ use std::io::{Read, Write}; use std::panic::catch_unwind; use std::process::Command; -pgrx::pg_module_magic!(c"bad_ideas", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[pg_extern] fn panic(s: &str) -> bool { diff --git a/pgrx-examples/bgworker/src/lib.rs b/pgrx-examples/bgworker/src/lib.rs index e8992d9427..67f49477d9 100644 --- a/pgrx-examples/bgworker/src/lib.rs +++ b/pgrx-examples/bgworker/src/lib.rs @@ -26,7 +26,7 @@ use std::time::Duration; this background worker */ -pgrx::pg_module_magic!(c"bgworker", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[pg_guard] pub extern "C-unwind" fn _PG_init() { diff --git a/pgrx-examples/bytea/src/lib.rs b/pgrx-examples/bytea/src/lib.rs index 0307303013..f3ba772fe2 100644 --- a/pgrx-examples/bytea/src/lib.rs +++ b/pgrx-examples/bytea/src/lib.rs @@ -11,7 +11,7 @@ use libflate::gzip::{Decoder, Encoder}; use pgrx::prelude::*; use std::io::{Read, Write}; -pgrx::pg_module_magic!(c"bytea", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); /// gzip bytes. Postgres will automatically convert `text`/`varchar` data into `bytea` #[pg_extern] diff --git a/pgrx-examples/composite_type/src/lib.rs b/pgrx-examples/composite_type/src/lib.rs index 192cbc7ed8..b0b27e486d 100644 --- a/pgrx-examples/composite_type/src/lib.rs +++ b/pgrx-examples/composite_type/src/lib.rs @@ -23,7 +23,7 @@ using composite types. use pgrx::{opname, pg_operator, prelude::*}; // All `pgrx` extensions will do this: -pgrx::pg_module_magic!(c"composite_type", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); /* Composite types must be defined either before they are used. diff --git a/pgrx-examples/custom_libname/src/lib.rs b/pgrx-examples/custom_libname/src/lib.rs index 09769af199..5c9f89d228 100644 --- a/pgrx-examples/custom_libname/src/lib.rs +++ b/pgrx-examples/custom_libname/src/lib.rs @@ -9,7 +9,7 @@ //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. use pgrx::prelude::*; -pgrx::pg_module_magic!(c"custom_libname", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[pg_extern] fn hello_custom_libname() -> &'static str { diff --git a/pgrx-examples/custom_sql/src/lib.rs b/pgrx-examples/custom_sql/src/lib.rs index 802ed3b03f..1e1ad4edb6 100644 --- a/pgrx-examples/custom_sql/src/lib.rs +++ b/pgrx-examples/custom_sql/src/lib.rs @@ -10,7 +10,7 @@ use pgrx::prelude::*; use serde::{Deserialize, Serialize}; -pgrx::pg_module_magic!(c"custom_sql", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[pg_schema] mod home { diff --git a/pgrx-examples/custom_types/src/lib.rs b/pgrx-examples/custom_types/src/lib.rs index be6f84f744..177484c982 100644 --- a/pgrx-examples/custom_types/src/lib.rs +++ b/pgrx-examples/custom_types/src/lib.rs @@ -16,7 +16,7 @@ mod hstore_clone; mod ordered; mod rust_enum; -pgrx::pg_module_magic!(c"custom_types", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[cfg(test)] pub mod pg_test { diff --git a/pgrx-examples/datetime/src/lib.rs b/pgrx-examples/datetime/src/lib.rs index 7c0836a322..4acc0b608f 100644 --- a/pgrx-examples/datetime/src/lib.rs +++ b/pgrx-examples/datetime/src/lib.rs @@ -10,7 +10,7 @@ use pgrx::prelude::*; use rand::Rng; -pgrx::pg_module_magic!(c"datetime", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[pg_extern(name = "to_iso_string", immutable, parallel_safe)] fn to_iso_string(tsz: TimestampWithTimeZone) -> String { diff --git a/pgrx-examples/errors/src/lib.rs b/pgrx-examples/errors/src/lib.rs index a7983cf15b..0409d0f8e1 100644 --- a/pgrx-examples/errors/src/lib.rs +++ b/pgrx-examples/errors/src/lib.rs @@ -10,7 +10,7 @@ use pgrx::prelude::*; use pgrx::{error, info, warning, PgRelation, FATAL, PANIC}; -pgrx::pg_module_magic!(c"errors", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[pg_extern] fn array_with_null_and_panic(input: Vec>) -> i64 { diff --git a/pgrx-examples/nostd/src/lib.rs b/pgrx-examples/nostd/src/lib.rs index 63f0e9ff62..bda9b2d1f1 100644 --- a/pgrx-examples/nostd/src/lib.rs +++ b/pgrx-examples/nostd/src/lib.rs @@ -17,7 +17,7 @@ use serde::{Deserialize, Serialize}; use alloc::string::String; -pgrx::pg_module_magic!(c"nostd", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); /// standard Rust equality/comparison derives #[derive(Eq, PartialEq, Ord, Hash, PartialOrd)] diff --git a/pgrx-examples/numeric/src/lib.rs b/pgrx-examples/numeric/src/lib.rs index 3629ef8d4c..667eef9e43 100644 --- a/pgrx-examples/numeric/src/lib.rs +++ b/pgrx-examples/numeric/src/lib.rs @@ -10,7 +10,7 @@ #![allow(clippy::assign_op_pattern)] use pgrx::prelude::*; -pgrx::pg_module_magic!(c"numeric", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[pg_extern] fn add_numeric(a: Numeric<1000, 33>, b: Numeric<1000, 33>) -> Numeric<1000, 33> { diff --git a/pgrx-examples/operators/src/lib.rs b/pgrx-examples/operators/src/lib.rs index 4102d0a5dc..c21b08f183 100644 --- a/pgrx-examples/operators/src/lib.rs +++ b/pgrx-examples/operators/src/lib.rs @@ -13,7 +13,7 @@ use serde::{Deserialize, Serialize}; mod derived; mod pgvarlena; -pgrx::pg_module_magic!(c"operators", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[derive(PostgresType, Serialize, Deserialize, Eq, PartialEq)] pub struct MyType { diff --git a/pgrx-examples/pgtrybuilder/src/lib.rs b/pgrx-examples/pgtrybuilder/src/lib.rs index e517dc51af..8a297ad4d6 100644 --- a/pgrx-examples/pgtrybuilder/src/lib.rs +++ b/pgrx-examples/pgtrybuilder/src/lib.rs @@ -10,7 +10,7 @@ use pgrx::pg_sys::panic::CaughtError; use pgrx::prelude::*; -pgrx::pg_module_magic!(c"pgtrybuilder", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[pg_extern] fn is_valid_number(i: i32) -> i32 { diff --git a/pgrx-examples/range/src/lib.rs b/pgrx-examples/range/src/lib.rs index 7e28b0eec7..beecd9ad49 100644 --- a/pgrx-examples/range/src/lib.rs +++ b/pgrx-examples/range/src/lib.rs @@ -9,7 +9,7 @@ //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. use pgrx::prelude::*; -pgrx::pg_module_magic!(c"range", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[pg_extern] fn range(s: i32, e: i32) -> pgrx::Range { diff --git a/pgrx-examples/schemas/src/lib.rs b/pgrx-examples/schemas/src/lib.rs index 052065123f..7d79acc41e 100644 --- a/pgrx-examples/schemas/src/lib.rs +++ b/pgrx-examples/schemas/src/lib.rs @@ -13,7 +13,7 @@ use pgrx::prelude::*; use serde::{Deserialize, Serialize}; -pgrx::pg_module_magic!(c"schemas", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[derive(PostgresType, Serialize, Deserialize)] pub struct MyType(pub(crate) String); diff --git a/pgrx-examples/shmem/src/lib.rs b/pgrx-examples/shmem/src/lib.rs index 3a96d5cc46..655e558d0a 100644 --- a/pgrx-examples/shmem/src/lib.rs +++ b/pgrx-examples/shmem/src/lib.rs @@ -15,7 +15,7 @@ use pgrx::{pg_shmem_init, warning}; use serde::*; use std::sync::atomic::Ordering; -pgrx::pg_module_magic!(c"shmem", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); // types behind a `LwLock` must derive/implement `Copy` and `Clone` #[derive(Copy, Clone)] diff --git a/pgrx-examples/spi/src/lib.rs b/pgrx-examples/spi/src/lib.rs index 82b6413a53..de57e68069 100644 --- a/pgrx-examples/spi/src/lib.rs +++ b/pgrx-examples/spi/src/lib.rs @@ -9,7 +9,7 @@ //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. use pgrx::prelude::*; -pgrx::pg_module_magic!(c"spi", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); extension_sql!( r#" diff --git a/pgrx-examples/spi_srf/src/lib.rs b/pgrx-examples/spi_srf/src/lib.rs index a890adb78c..0789f2b7ac 100644 --- a/pgrx-examples/spi_srf/src/lib.rs +++ b/pgrx-examples/spi_srf/src/lib.rs @@ -9,7 +9,7 @@ //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. use pgrx::prelude::*; -pgrx::pg_module_magic!(c"spi_srf", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); extension_sql!( r#" diff --git a/pgrx-examples/srf/src/lib.rs b/pgrx-examples/srf/src/lib.rs index 76a4037e57..41423756a3 100644 --- a/pgrx-examples/srf/src/lib.rs +++ b/pgrx-examples/srf/src/lib.rs @@ -9,7 +9,7 @@ //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. use pgrx::prelude::*; -pgrx::pg_module_magic!(c"srf", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[pg_extern] fn generate_series(start: i64, finish: i64, step: default!(i64, 1)) -> SetOfIterator<'static, i64> { diff --git a/pgrx-examples/strings/src/lib.rs b/pgrx-examples/strings/src/lib.rs index f84353f26e..304fd3ea67 100644 --- a/pgrx-examples/strings/src/lib.rs +++ b/pgrx-examples/strings/src/lib.rs @@ -9,7 +9,7 @@ //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. use pgrx::prelude::*; -pgrx::pg_module_magic!(c"strings", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[pg_extern] fn return_static() -> &'static str { diff --git a/pgrx-examples/triggers/src/lib.rs b/pgrx-examples/triggers/src/lib.rs index 1b8288a2a4..3c51b4cb29 100644 --- a/pgrx-examples/triggers/src/lib.rs +++ b/pgrx-examples/triggers/src/lib.rs @@ -9,7 +9,7 @@ //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. use pgrx::prelude::*; -pgrx::pg_module_magic!(c"triggers", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[derive(thiserror::Error, Debug)] enum TriggerError { diff --git a/pgrx-examples/versioned_custom_libname_so/src/lib.rs b/pgrx-examples/versioned_custom_libname_so/src/lib.rs index 24e8cf0dd3..c9ef0f73f5 100644 --- a/pgrx-examples/versioned_custom_libname_so/src/lib.rs +++ b/pgrx-examples/versioned_custom_libname_so/src/lib.rs @@ -9,7 +9,7 @@ //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. use pgrx::prelude::*; -pgrx::pg_module_magic!(c"versioned_custom_libname_so", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[pg_extern] fn hello_versioned_custom_libname_so() -> &'static str { diff --git a/pgrx-examples/versioned_so/src/lib.rs b/pgrx-examples/versioned_so/src/lib.rs index 261a0faa33..70479ba373 100644 --- a/pgrx-examples/versioned_so/src/lib.rs +++ b/pgrx-examples/versioned_so/src/lib.rs @@ -9,7 +9,7 @@ //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. use pgrx::prelude::*; -pgrx::pg_module_magic!(c"versioned_so", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); #[pg_extern] fn hello_versioned_so() -> &'static str { diff --git a/pgrx-examples/wal_decoder/src/lib.rs b/pgrx-examples/wal_decoder/src/lib.rs index 6a90d3c21a..39b429ed14 100644 --- a/pgrx-examples/wal_decoder/src/lib.rs +++ b/pgrx-examples/wal_decoder/src/lib.rs @@ -4,7 +4,7 @@ use serde::ser::{SerializeStruct, Serializer}; use serde::Serialize; use std::alloc::{alloc, dealloc, Layout}; -pgrx::pg_module_magic!(c"wal_decoder", pgrx::pg_sys::PG_VERSION); +pgrx::pg_module_magic!(name, version); // An Action describe a change that occurred on a table #[derive(Serialize)] diff --git a/pgrx-tests/src/lib.rs b/pgrx-tests/src/lib.rs index 47a1a4f193..8de83fc09c 100644 --- a/pgrx-tests/src/lib.rs +++ b/pgrx-tests/src/lib.rs @@ -19,7 +19,7 @@ pub use framework::*; pub mod proptest; #[cfg(any(test, feature = "pg_test"))] -pgrx::pg_module_magic!(); +pgrx::pg_module_magic!(name, version); #[cfg(test)] pub mod pg_test { diff --git a/pgrx/src/lib.rs b/pgrx/src/lib.rs index 9474cd8749..1bea6fcc89 100644 --- a/pgrx/src/lib.rs +++ b/pgrx/src/lib.rs @@ -176,26 +176,15 @@ const _: () = { ///
///
 ///
-/// **Note**: Every [`pgrx`][crate] extension **must** have this macro called at top level (usually `src/lib.rs`) to be valid. You can use `pg_module_magic!()` or `pg_module_magic!(name, version)`
+/// **Note**: Every [`pgrx`][crate] extension **must** have this macro called at top level (usually `src/lib.rs`) to be valid. You can use `pg_module_magic!()`, `pg_module_magic!(name, version)` or `pg_module_magic!(name = c"custom_name", version = c"1.0.0")`
 ///
 /// 
/// /// This calls [`pg_magic_func!()`](pg_magic_func). #[macro_export] macro_rules! pg_module_magic { - () => { - $crate::pg_magic_func!(); - - // A marker function which must exist in the root of the extension for proper linking by the - // "pgrx_embed" binary during `cargo-pgrx schema` generation. - #[inline(never)] /* we don't want DCE to remove this as it *could* cause the compiler to decide to not link to us */ - #[doc(hidden)] - pub fn __pgrx_marker() { - // noop - } - }; - ($name:expr, $version:expr) => { - $crate::pg_magic_func!($name, $version); + ($($key:ident $(= $value:expr)?),*) => { + $crate::pg_magic_func!($($key $(= $value)?),*); // A marker function which must exist in the root of the extension for proper linking by the // "pgrx_embed" binary during `cargo-pgrx schema` generation. @@ -241,169 +230,132 @@ macro_rules! pg_module_magic { /// [Dynamic Loading]: https://www.postgresql.org/docs/current/xfunc-c.html#XFUNC-C-DYNLOAD #[macro_export] macro_rules! pg_magic_func { - () => { - #[no_mangle] + ($($key:ident $(= $value: expr)?),*) => { + #[unsafe(no_mangle)] #[allow(non_snake_case, unexpected_cfgs)] #[doc(hidden)] - pub extern "C-unwind" fn Pg_magic_func() -> &'static ::pgrx::pg_sys::Pg_magic_struct { - #[cfg(any( - feature = "pg13", - feature = "pg14", - feature = "pg15", - feature = "pg16", - feature = "pg17" - ))] - { - static MY_MAGIC: ::pgrx::pg_sys::Pg_magic_struct = - ::pgrx::pg_sys::Pg_magic_struct { - len: ::core::mem::size_of::<::pgrx::pg_sys::Pg_magic_struct>() as i32, - version: ::pgrx::pg_sys::PG_VERSION_NUM as i32 / 100, - funcmaxargs: ::pgrx::pg_sys::FUNC_MAX_ARGS as i32, - indexmaxkeys: ::pgrx::pg_sys::INDEX_MAX_KEYS as i32, - namedatalen: ::pgrx::pg_sys::NAMEDATALEN as i32, - float8byval: cfg!(target_pointer_width = "64") as i32, - #[cfg(any(feature = "pg15", feature = "pg16", feature = "pg17"))] - abi_extra: { - // we'll use what the bindings tell us, but if it ain't "PostgreSQL" then we'll - // raise a compilation error unless the `unsafe-postgres` feature is set - let magic = ::pgrx::pg_sys::FMGR_ABI_EXTRA.to_bytes_with_nul(); - let mut abi = [0 as ::pgrx::ffi::c_char; 32]; - let mut i = 0; - while i < magic.len() { - abi[i] = magic[i] as ::pgrx::ffi::c_char; - i += 1; - } - abi - }, - }; - - // since Postgres calls this first, register our panic handler now - // so we don't unwind into C / Postgres - ::pgrx::pg_sys::panic::register_pg_guard_panic_hook(); + pub extern "C" fn Pg_magic_func() -> &'static ::pgrx::pg_sys::Pg_magic_struct { + #[repr(transparent)] + struct AssertSync(T); + unsafe impl Sync for AssertSync {} - // return the magic - &MY_MAGIC - } + // since Postgres calls this first, register our panic handler now + // so we don't unwind into C / Postgres + ::pgrx::pg_sys::panic::register_pg_guard_panic_hook(); - #[cfg(feature = "pg18")] - { - struct PgMagicstruct(::pgrx::pg_sys::Pg_magic_struct); - unsafe impl Sync for PgMagicstruct {} - static MY_MAGIC: PgMagicstruct = PgMagicstruct(::pgrx::pg_sys::Pg_magic_struct { - len: ::core::mem::size_of::<::pgrx::pg_sys::Pg_magic_struct>() as i32, + static MY_MAGIC: AssertSync<::pgrx::pg_sys::Pg_magic_struct> = { + let len = ::core::mem::size_of::<::pgrx::pg_sys::Pg_magic_struct>() as i32; + let version = ::pgrx::pg_sys::PG_VERSION_NUM as i32 / 100; + let funcmaxargs = ::pgrx::pg_sys::FUNC_MAX_ARGS as i32; + let indexmaxkeys = ::pgrx::pg_sys::INDEX_MAX_KEYS as i32; + let namedatalen = ::pgrx::pg_sys::NAMEDATALEN as i32; + let float8byval = cfg!(target_pointer_width = "64") as i32; + #[cfg(not(any(feature = "pg13", feature = "pg14")))] + let abi_extra = { + // we'll use what the bindings tell us, but if it ain't "PostgreSQL" then we'll + // raise a compilation error unless the `unsafe-postgres` feature is set + let magic = ::pgrx::pg_sys::FMGR_ABI_EXTRA.to_bytes_with_nul(); + let mut abi = [0 as ::pgrx::ffi::c_char; 32]; + let mut i = 0; + while i < magic.len() { + abi[i] = magic[i] as ::pgrx::ffi::c_char; + i += 1; + } + abi + }; + let mut magic = ::pgrx::pg_sys::Pg_magic_struct { + len, + #[cfg(not(feature = "pg18"))] + version, + #[cfg(not(feature = "pg18"))] + funcmaxargs, + #[cfg(not(feature = "pg18"))] + indexmaxkeys, + #[cfg(not(feature = "pg18"))] + namedatalen, + #[cfg(not(feature = "pg18"))] + float8byval, + #[cfg(any(feature = "pg15", feature = "pg16", feature = "pg17"))] + abi_extra, + #[cfg(feature = "pg18")] abi_fields: ::pgrx::pg_sys::Pg_abi_values { - version: ::pgrx::pg_sys::PG_VERSION_NUM as i32 / 100, - funcmaxargs: ::pgrx::pg_sys::FUNC_MAX_ARGS as i32, - indexmaxkeys: ::pgrx::pg_sys::INDEX_MAX_KEYS as i32, - namedatalen: ::pgrx::pg_sys::NAMEDATALEN as i32, - float8byval: cfg!(target_pointer_width = "64") as i32, - abi_extra: { - // we'll use what the bindings tell us, but if it ain't "PostgreSQL" then we'll - // raise a compilation error unless the `unsafe-postgres` feature is set - let magic = ::pgrx::pg_sys::FMGR_ABI_EXTRA.to_bytes_with_nul(); - let mut abi = [0 as ::pgrx::ffi::c_char; 32]; - let mut i = 0; - while i < magic.len() { - abi[i] = magic[i] as ::pgrx::ffi::c_char; - i += 1; - } - abi - }, + version, + funcmaxargs, + indexmaxkeys, + namedatalen, + float8byval, + abi_extra, }, - name: std::ptr::null(), - version: std::ptr::null(), - }); - - // since Postgres calls this first, register our panic handler now - // so we don't unwind into C / Postgres - ::pgrx::pg_sys::panic::register_pg_guard_panic_hook(); - - // return the magic - &MY_MAGIC.0 - } - } - }; - - ($name:expr, $version:expr) => { - #[no_mangle] - #[allow(non_snake_case, unexpected_cfgs)] - #[doc(hidden)] - pub extern "C-unwind" fn Pg_magic_func() -> &'static ::pgrx::pg_sys::Pg_magic_struct { - #[cfg(any( - feature = "pg13", - feature = "pg14", - feature = "pg15", - feature = "pg16", - feature = "pg17" - ))] - { - static MY_MAGIC: ::pgrx::pg_sys::Pg_magic_struct = - ::pgrx::pg_sys::Pg_magic_struct { - len: ::core::mem::size_of::<::pgrx::pg_sys::Pg_magic_struct>() as i32, - version: ::pgrx::pg_sys::PG_VERSION_NUM as i32 / 100, - funcmaxargs: ::pgrx::pg_sys::FUNC_MAX_ARGS as i32, - indexmaxkeys: ::pgrx::pg_sys::INDEX_MAX_KEYS as i32, - namedatalen: ::pgrx::pg_sys::NAMEDATALEN as i32, - float8byval: cfg!(target_pointer_width = "64") as i32, - #[cfg(any(feature = "pg15", feature = "pg16", feature = "pg17"))] - abi_extra: { - // we'll use what the bindings tell us, but if it ain't "PostgreSQL" then we'll - // raise a compilation error unless the `unsafe-postgres` feature is set - let magic = ::pgrx::pg_sys::FMGR_ABI_EXTRA.to_bytes_with_nul(); - let mut abi = [0 as ::pgrx::ffi::c_char; 32]; - let mut i = 0; - while i < magic.len() { - abi[i] = magic[i] as ::pgrx::ffi::c_char; - i += 1; - } - abi - }, + #[cfg(feature = "pg18")] + name: ::core::ptr::null(), + #[cfg(feature = "pg18")] + version: ::core::ptr::null(), + }; + #[allow(unused_macros)] + macro_rules! field_update { + (name) => { + field_update!(name = { + const RAW: &str = env!("CARGO_PKG_NAME"); + const BUFFER: [u8; RAW.len() + 1] = { + let mut buffer = [0u8; RAW.len() + 1]; + let mut i = 0_usize; + while i < RAW.len() { + buffer[i] = RAW.as_bytes()[i]; + i += 1; + } + buffer + }; + const STR: &::core::ffi::CStr = + if let Ok(s) = ::core::ffi::CStr::from_bytes_with_nul(&BUFFER) { + s + } else { + panic!("there are null characters in CARGO_PKG_NAME") + }; + const { STR } + }); }; + (version) => { + field_update!(name = { + const RAW: &str = env!("CARGO_PKG_VERSION"); + const BUFFER: [u8; RAW.len() + 1] = { + let mut buffer = [0u8; RAW.len() + 1]; + let mut i = 0_usize; + while i < RAW.len() { + buffer[i] = RAW.as_bytes()[i]; + i += 1; + } + buffer + }; + const STR: &::core::ffi::CStr = + if let Ok(s) = ::core::ffi::CStr::from_bytes_with_nul(&BUFFER) { + s + } else { + panic!("there are null characters in CARGO_CRATE_VERSION") + }; + const { STR } + }); + }; + (name = $name:expr) => { + let name: &'static ::core::ffi::CStr = $name; + #[cfg(feature = "pg18")] + { + magic.name = ::core::ffi::CStr::as_ptr($name); + } + }; + (version = $version:expr) => { + let version: &'static ::core::ffi::CStr = $version; + #[cfg(feature = "pg18")] + { + magic.version = ::core::ffi::CStr::as_ptr($version); + } + }; + } + $(field_update!($key $(= $value)?);)* + AssertSync(magic) + }; - // since Postgres calls this first, register our panic handler now - // so we don't unwind into C / Postgres - ::pgrx::pg_sys::panic::register_pg_guard_panic_hook(); - - // return the magic - &MY_MAGIC - } - - #[cfg(feature = "pg18")] - { - struct PgMagicstruct(::pgrx::pg_sys::Pg_magic_struct); - unsafe impl Sync for PgMagicstruct {} - static MY_MAGIC: PgMagicstruct = PgMagicstruct(::pgrx::pg_sys::Pg_magic_struct { - len: ::core::mem::size_of::<::pgrx::pg_sys::Pg_magic_struct>() as i32, - abi_fields: ::pgrx::pg_sys::Pg_abi_values { - version: ::pgrx::pg_sys::PG_VERSION_NUM as i32 / 100, - funcmaxargs: ::pgrx::pg_sys::FUNC_MAX_ARGS as i32, - indexmaxkeys: ::pgrx::pg_sys::INDEX_MAX_KEYS as i32, - namedatalen: ::pgrx::pg_sys::NAMEDATALEN as i32, - float8byval: cfg!(target_pointer_width = "64") as i32, - abi_extra: { - // we'll use what the bindings tell us, but if it ain't "PostgreSQL" then we'll - // raise a compilation error unless the `unsafe-postgres` feature is set - let magic = ::pgrx::pg_sys::FMGR_ABI_EXTRA.to_bytes_with_nul(); - let mut abi = [0 as ::pgrx::ffi::c_char; 32]; - let mut i = 0; - while i < magic.len() { - abi[i] = magic[i] as ::pgrx::ffi::c_char; - i += 1; - } - abi - }, - }, - name: $name.as_ptr(), - version: $version.as_ptr(), - }); - - // since Postgres calls this first, register our panic handler now - // so we don't unwind into C / Postgres - ::pgrx::pg_sys::panic::register_pg_guard_panic_hook(); - - // return the magic - &MY_MAGIC.0 - } + // return the magic + &MY_MAGIC.0 } }; }