Skip to content

Commit

Permalink
fixing issue #270
Browse files Browse the repository at this point in the history
  • Loading branch information
eeeebbbbrrrr committed Oct 27, 2021
1 parent fe311cd commit 64ea7c2
Show file tree
Hide file tree
Showing 10 changed files with 242 additions and 148 deletions.
16 changes: 12 additions & 4 deletions pgx-macros/src/rewriter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ impl PgGuardRewriter {
optional: bool,
) -> proc_macro2::TokenStream {
let generic_type = proc_macro2::TokenStream::from_str(types.first().unwrap()).unwrap();
let mut generic_type = syn::parse2::<syn::Type>(generic_type).unwrap();
pgx_utils::anonymonize_lifetimes(&mut generic_type);

let result_handler = if optional {
quote! {
Expand Down Expand Up @@ -348,6 +350,8 @@ impl PgGuardRewriter {

let composite_type = format!("({})", types.join(","));
let generic_type = proc_macro2::TokenStream::from_str(&composite_type).unwrap();
let mut generic_type = syn::parse2::<syn::Type>(generic_type).unwrap();
pgx_utils::anonymonize_lifetimes(&mut generic_type);

let result_handler = if optional {
quote! {
Expand Down Expand Up @@ -707,19 +711,22 @@ impl FunctionSignatureRewriter {
FnArg::Typed(ty) => match ty.pat.deref() {
Pat::Ident(ident) => {
let name = Ident::new(&format!("{}_", ident.ident), ident.span());
let type_ = &ty.ty;
let is_option = type_matches(type_, "Option");
let mut type_ = ty.ty.clone();
let is_option = type_matches(&type_, "Option");

if have_fcinfo {
panic!("When using `pg_sys::FunctionCallInfo` as an argument it must be the last argument")
}

let ts = if is_option {
let option_type = extract_option_type(type_);
let option_type = extract_option_type(&type_);
let mut option_type = syn::parse2::<syn::Type>(option_type).unwrap();
pgx_utils::anonymonize_lifetimes(&mut option_type);

quote_spanned! {ident.span()=>
let #name = pgx::pg_getarg::<#option_type>(fcinfo, #i);
}
} else if type_matches(type_, "pg_sys :: FunctionCallInfo") {
} else if type_matches(&type_, "pg_sys :: FunctionCallInfo") {
have_fcinfo = true;
quote_spanned! {ident.span()=>
let #name = fcinfo;
Expand All @@ -729,6 +736,7 @@ impl FunctionSignatureRewriter {
let #name = pgx::pg_getarg_datum_raw(fcinfo, #i) as #type_;
}
} else {
pgx_utils::anonymonize_lifetimes(&mut type_);
quote_spanned! {ident.span()=>
let #name = pgx::pg_getarg::<#type_>(fcinfo, #i).unwrap_or_else(|| panic!("{} is null", stringify!{#ident}));
}
Expand Down
2 changes: 1 addition & 1 deletion pgx-pg-sys/src/pg10.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ pub const PG_KRB_SRVNAM: &'static [u8; 9usize] = b"postgres\0";
pub const PG_MAJORVERSION: &'static [u8; 3usize] = b"10\0";
pub const PG_VERSION: &'static [u8; 6usize] = b"10.18\0";
pub const PG_VERSION_NUM: u32 = 100018;
pub const PG_VERSION_STR : & 'static [u8 ; 115usize] = b"PostgreSQL 10.18 on x86_64-apple-darwin20.4.0, compiled by Apple clang version 12.0.5 (clang-1205.0.22.11), 64-bit\0" ;
pub const PG_VERSION_STR : & 'static [u8 ; 114usize] = b"PostgreSQL 10.18 on x86_64-apple-darwin20.4.0, compiled by Apple clang version 13.0.0 (clang-1300.0.29.3), 64-bit\0" ;
pub const RELSEG_SIZE: u32 = 131072;
pub const SIZEOF_LONG: u32 = 8;
pub const SIZEOF_OFF_T: u32 = 8;
Expand Down
2 changes: 1 addition & 1 deletion pgx-pg-sys/src/pg11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ pub const PG_KRB_SRVNAM: &'static [u8; 9usize] = b"postgres\0";
pub const PG_MAJORVERSION: &'static [u8; 3usize] = b"11\0";
pub const PG_VERSION: &'static [u8; 6usize] = b"11.13\0";
pub const PG_VERSION_NUM: u32 = 110013;
pub const PG_VERSION_STR : & 'static [u8 ; 115usize] = b"PostgreSQL 11.13 on x86_64-apple-darwin20.4.0, compiled by Apple clang version 12.0.5 (clang-1205.0.22.11), 64-bit\0" ;
pub const PG_VERSION_STR : & 'static [u8 ; 114usize] = b"PostgreSQL 11.13 on x86_64-apple-darwin20.4.0, compiled by Apple clang version 13.0.0 (clang-1300.0.29.3), 64-bit\0" ;
pub const RELSEG_SIZE: u32 = 131072;
pub const SIZEOF_BOOL: u32 = 1;
pub const SIZEOF_LONG: u32 = 8;
Expand Down
2 changes: 1 addition & 1 deletion pgx-pg-sys/src/pg12.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ pub const PG_KRB_SRVNAM: &'static [u8; 9usize] = b"postgres\0";
pub const PG_MAJORVERSION: &'static [u8; 3usize] = b"12\0";
pub const PG_VERSION: &'static [u8; 5usize] = b"12.8\0";
pub const PG_VERSION_NUM: u32 = 120008;
pub const PG_VERSION_STR : & 'static [u8 ; 114usize] = b"PostgreSQL 12.8 on x86_64-apple-darwin20.4.0, compiled by Apple clang version 12.0.5 (clang-1205.0.22.11), 64-bit\0" ;
pub const PG_VERSION_STR : & 'static [u8 ; 113usize] = b"PostgreSQL 12.8 on x86_64-apple-darwin20.4.0, compiled by Apple clang version 13.0.0 (clang-1300.0.29.3), 64-bit\0" ;
pub const RELSEG_SIZE: u32 = 131072;
pub const SIZEOF_BOOL: u32 = 1;
pub const SIZEOF_LONG: u32 = 8;
Expand Down
2 changes: 1 addition & 1 deletion pgx-pg-sys/src/pg13.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ pub const PG_MINORVERSION_NUM: u32 = 4;
pub const PG_USE_STDBOOL: u32 = 1;
pub const PG_VERSION: &'static [u8; 5usize] = b"13.4\0";
pub const PG_VERSION_NUM: u32 = 130004;
pub const PG_VERSION_STR : & 'static [u8 ; 114usize] = b"PostgreSQL 13.4 on x86_64-apple-darwin20.4.0, compiled by Apple clang version 12.0.5 (clang-1205.0.22.11), 64-bit\0" ;
pub const PG_VERSION_STR : & 'static [u8 ; 113usize] = b"PostgreSQL 13.4 on x86_64-apple-darwin20.4.0, compiled by Apple clang version 13.0.0 (clang-1300.0.29.3), 64-bit\0" ;
pub const RELSEG_SIZE: u32 = 131072;
pub const SIZEOF_BOOL: u32 = 1;
pub const SIZEOF_LONG: u32 = 8;
Expand Down
2 changes: 1 addition & 1 deletion pgx-pg-sys/src/pg14.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ pub const PG_MINORVERSION_NUM: u32 = 0;
pub const PG_USE_STDBOOL: u32 = 1;
pub const PG_VERSION: &'static [u8; 5usize] = b"14.0\0";
pub const PG_VERSION_NUM: u32 = 140000;
pub const PG_VERSION_STR : & 'static [u8 ; 114usize] = b"PostgreSQL 14.0 on x86_64-apple-darwin20.4.0, compiled by Apple clang version 12.0.5 (clang-1205.0.22.11), 64-bit\0" ;
pub const PG_VERSION_STR : & 'static [u8 ; 113usize] = b"PostgreSQL 14.0 on x86_64-apple-darwin20.4.0, compiled by Apple clang version 13.0.0 (clang-1300.0.29.3), 64-bit\0" ;
pub const RELSEG_SIZE: u32 = 131072;
pub const SIZEOF_BOOL: u32 = 1;
pub const SIZEOF_LONG: u32 = 8;
Expand Down
27 changes: 27 additions & 0 deletions pgx-tests/src/tests/lifetime_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,30 @@ fn type_with_lifetime<'s>(_value: Option<CustomType<'s>>) {}

#[pg_extern]
fn type_ref_with_lifetime<'a>(_value: &'a str) {}

#[pg_extern]
fn returns_lifetime<'a>() -> Option<CustomType<'a>> {
None
}

#[pg_extern]
fn returns_ref_with_lifetime<'a>() -> &'a str {
""
}

#[pg_extern]
fn returns_option_ref_with_lifetime<'a>() -> Option<&'a str> {
None
}

#[pg_extern]
fn returns_tuple_with_lifetime(
value: &'static str,
) -> (name!(a, &'static str), name!(b, Option<&'static str>)) {
(value, Some(value))
}

#[pg_extern]
fn returns_iterator_with_lifetime<'a>(value: &'a str) -> impl std::iter::Iterator<Item = &'a str> {
value.split_whitespace()
}
67 changes: 67 additions & 0 deletions pgx-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,73 @@ pub fn categorize_trait_bound(bound: &TypeParamBound) -> CategorizedType {
}
}

pub fn anonymonize_lifetimes_in_type_path(value: syn::TypePath) -> syn::TypePath {
let mut ty = syn::Type::Path(value);
anonymonize_lifetimes(&mut ty);
match ty {
syn::Type::Path(type_path) => type_path,

// shouldn't happen
_ => panic!("not a TypePath"),
}
}

pub fn anonymonize_lifetimes(value: &mut syn::Type) {
match value {
syn::Type::Path(type_path) => {
for segment in &mut type_path.path.segments {
match &mut segment.arguments {
syn::PathArguments::AngleBracketed(bracketed) => {
for arg in &mut bracketed.args {
match arg {
// rename lifetimes to the anonymous lifetime
syn::GenericArgument::Lifetime(lifetime) => {
lifetime.ident = syn::Ident::new("_", lifetime.ident.span());
}

// recurse
syn::GenericArgument::Type(ty) => anonymonize_lifetimes(ty),
syn::GenericArgument::Binding(binding) => {
anonymonize_lifetimes(&mut binding.ty)
}
syn::GenericArgument::Constraint(constraint) => {
for bound in constraint.bounds.iter_mut() {
match bound {
syn::TypeParamBound::Lifetime(lifetime) => {
lifetime.ident =
syn::Ident::new("_", lifetime.ident.span())
}
_ => {}
}
}
}

// nothing to do otherwise
_ => {}
}
}
}
_ => {}
}
}
}

syn::Type::Reference(type_ref) => {
if let Some(lifetime) = type_ref.lifetime.as_mut() {
lifetime.ident = syn::Ident::new("_", lifetime.ident.span());
}
}

syn::Type::Tuple(type_tuple) => {
for elem in &mut type_tuple.elems {
anonymonize_lifetimes(elem);
}
}

_ => {}
}
}

#[cfg(test)]
mod tests {
use crate::{parse_extern_attributes, ExternArgs};
Expand Down
53 changes: 12 additions & 41 deletions pgx-utils/src/sql_entity_graph/pg_extern/argument.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::ops::Deref;

use proc_macro2::{Ident, Span, TokenStream as TokenStream2};
use crate::anonymonize_lifetimes;
use proc_macro2::{Span, TokenStream as TokenStream2};
use quote::{quote, ToTokens, TokenStreamExt};
use syn::{
parse::{Parse, ParseStream},
parse_quote, FnArg, GenericArgument, Pat, Token,
parse_quote, FnArg, Pat, Token,
};

/// A parsed `#[pg_extern]` argument.
Expand All @@ -27,7 +28,7 @@ impl Argument {

pub fn build_from_pat_type(value: syn::PatType) -> Result<Option<Self>, syn::Error> {
let mut true_ty = *value.ty.clone();
Self::anonymonize_lifetimes(&mut true_ty);
anonymonize_lifetimes(&mut true_ty);

let identifier = match *value.pat {
Pat::Ident(ref p) => p.ident.clone(),
Expand Down Expand Up @@ -137,7 +138,7 @@ impl Argument {
|| (saw_functioncallinfobasedata && segments.segments.len() == 1)
{
// It's a FunctionCallInfoBaseData, skipping
return Ok(None)
return Ok(None);
}
}
_ => (),
Expand All @@ -151,38 +152,6 @@ impl Argument {
default,
}))
}

fn anonymonize_lifetimes(value: &mut syn::Type) {
match value {
syn::Type::Path(type_path) => {
for segment in &mut type_path.path.segments {
match &mut segment.arguments {
syn::PathArguments::AngleBracketed(bracketed) => {
for arg in &mut bracketed.args {
match arg {
// rename lifetimes to the anonymous lifetime
GenericArgument::Lifetime(lifetime) => {
lifetime.ident = Ident::new("_", lifetime.ident.span());
}

// recurse
GenericArgument::Type(ty) => Self::anonymonize_lifetimes(ty),
_ => {}
}
}
}
_ => {}
}
}
}
syn::Type::Reference(type_ref) => {
if let Some(lifetime) = type_ref.lifetime.as_mut() {
lifetime.ident = Ident::new("_", lifetime.ident.span());
}
}
_ => {}
}
}
}

fn handle_default(
Expand Down Expand Up @@ -281,12 +250,14 @@ fn handle_default(

impl ToTokens for Argument {
fn to_tokens(&self, tokens: &mut TokenStream2) {
let pat = &self.pat;
let ty = &self.ty;
let default = self.default.iter();
let mut found_optional = false;
let mut found_variadic = false;
match self.ty {
let pat = &self.pat;
let default = self.default.iter();
let mut ty = self.ty.clone();
anonymonize_lifetimes(&mut ty);

match ty {
syn::Type::Path(ref type_path) => {
let path = &type_path.path;
for segment in &path.segments {
Expand All @@ -310,7 +281,7 @@ impl ToTokens for Argument {
}
_ => (),
};
let ty_string = self.ty.to_token_stream().to_string().replace(" ", "");
let ty_string = ty.to_token_stream().to_string().replace(" ", "");

let quoted = quote! {
pgx::datum::sql_entity_graph::PgExternArgumentEntity {
Expand Down
Loading

0 comments on commit 64ea7c2

Please sign in to comment.