Review of MySQL/MariaDB UDF library

Hello everyone,

I am hoping for a review of udf, which is a crate aiming to make it easy to write UDFs (user-defined functions) for MariaDB and MySQL Quick relevant links:

In udf/examples, basic_sum and sequence are my two working examples - please disregard the others for now.

UDFs are just dynamic libraries that provide three functions:

  • An init function, takes a config struct and a list of arguments. Validates arguments or sets type coercion, sets max arg length (for caller's optimization), allocates if needed. Arguments may or may not be present at this time, depending on if they are constant.
  • A process function that takes arguments (these will always be present) and returns data of a fixed type - either char*, long long, or double. If returning a string (char*) over a fixed length, it must be allocated in the first step (which is why I had to use GATs here, as I'll cover later)
  • "Aggregate" UDFs have two more functions, but they are fairly trivial
  • A deinit function - I don't need to expose this one since Rust handles it

To represent this, I have chosen to provide two traits - one for basic UDFs BasicUdf that is required, and a AggregateUdf for aggregate UDFs. The user can implement any of these on a struct and use my macro #[register] on the impl blocks. The Returns type within the trait specifies whether the function will be a string, integer, or float. If it is a long string, it needs to return a reference to a field in the implemented struct (hence GATs).

Relevant types (from my library) are:

  • ArgList<S>, a collection of SQL arguments, this is a wrapper around UDF_ARGS
  • SqlArg<S> a single SQL argument that has a value (SqlResult type) and an attribute (its name). S is a ZST, either Init or Process, which allows for some additional methods to be used that are only relevant during the init step.
  • SqlResult lines up with a SQL type (string/bytes [u8], integer i54, real f64, or decimal also [u8])
  • InitCfg, a wrapper around UDF_INIT

I think I am planning to change InitCfg to use some interior mutability (like I do for SqlArg) to clean up the init function signature, since mutability of cfg isn't needed in most use cases.

I am mostly looking for feedback on the function signatures within the traits, and organization of public types, since that will be the most set in stone.

Thank you anyone who is able to take a look! I am happy to answer any follow up questions.