Skip to content

RFC: Support User Defined types #499

Open
@Hoverbear

Description

@Hoverbear

pgx should be able to handle user defined types (such as those defined via CREATE 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 some UserDefinedType type which provides some serde_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 the pg_catalog.pg_type table.

So if the user defined something like:

#[pgx::pg_extern]
fn user_function(
    arg: pgx::UserDefinedType
) -> pgx::UserDefinedType {
    unimplemented!();
}

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 the name!() macro. We could also consider having some trait pgx::UserDefinedType which users could do like:

mod pgx {
    pub trait UserDefinedType {
        const SQL_TYPE: &'static str;
    }
}

struct SomeUserType;

impl pgx::UserDefinedType for SomeUserType {
    const SQL_TYPE: &'static str = "MySqlType";
}

#[pg_extern]
fn user_function(
    arg: SomeUserType
) -> SomeUserType {
    unimplemented!();
}

It's important to note though that the struct does not (and cannot) map directly to the type, instead, the pgx::UserDefinedType trait would need to provide methods.

Metadata

Metadata

Assignees

No one assigned

    Labels

    rfcrust+sqlInterop between Rust and SQL

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions