-
-
Notifications
You must be signed in to change notification settings - Fork 256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Support User Defined types #499
Comments
Closed
If we had rust-lang/rust#95174 we could do like this and then capture it with the SQL generator macros: #![feature(adt_const_params)]
mod pgx {
pub trait UserDefined<const SQL_TYPE: &'static str> {}
pub struct UserDefinedType<const T: &'static str>;
}
struct SomeUserType;
impl pgx::UserDefined<"BEAN"> for SomeUserType { }
fn user_function(
arg: SomeUserType
) -> SomeUserType {
unimplemented!();
}
fn other_user_function(
arg: pgx::UserDefinedType<"BEET">
) -> SomeUserType {
unimplemented!();
} |
From a "Correct Rust" level, this is what we const IMPORTANT_SQL_TYPE: &'static str = "Bean";
const UNIMPORTANT_SQL_TYPE: &'static str = "Beet";
#[pgx::pg_extern(return_sql_type = UNIMPORTANT_SQL_TYPE)]
fn user_function(
arg: #[pgx(sql_type = IMPORTANT_SQL_TYPE)] pgx::UserDefinedType
) -> pgx::UserDefinedType {
unimplemented!();
} However the aesthetic of this isn't super desirable. So it might be preferable if we have something like const IMPORTANT_SQL_TYPE: &'static str = "Bean";
const UNIMPORTANT_SQL_TYPE: &'static str = "Beet";
#[pgx::pg_extern]
fn user_function(
arg: pgx::user_defined!(IMPORTANT_SQL_TYPE)
) -> pgx::user_defined!(UNIMPORTANT_SQL_TYPE) {
unimplemented!();
} Expand into the "correct" form. |
Merged
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
pgx
should be able to handle user defined types (such as those defined viaCREATE TYPE...
) in function argument and return value position.Since user defined types can be created, removed, or altered at runtime, the
pgx
extension itself cannot possibly know the structure of the type at build time, thus we cannot possibly create some equivalent Rust type and define a mapping between them.Instead,
pgx
needs to determine that some type is a user defined type, and use someUserDefinedType
type which provides someserde_json::Value
-like interface with runtime safety. We can determine the runtime layout of a type via inspecting the result of a query like\dT+ example.type_name
in psql, there are also methods via SPI through thepg_catalog.pg_type
table.So if the user defined something like:
However this doesn't communicate enough information to the SQL generator to create a valid function signature (unless we fall back to something like
any
, which is undesirable).In order to augment this information we could use something like a
type!()
macro that operates similar to thename!()
macro. We could also consider having some traitpgx::UserDefinedType
which users could do like:It's important to note though that the
struct
does not (and cannot) map directly to the type, instead, thepgx::UserDefinedType
trait would need to provide methods.The text was updated successfully, but these errors were encountered: