pgx-named-columns
The pgx
Rust crate (github · crates · docs) is a really nice library to develop PostgreSQL extensions in Rust. Given the following Rust code:
```rust const ALPHABET: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
fn alphabet(length: i8) -> impl Iterator ...you can use the Note how the column names are defined in Rust, line 3 and 4, using an inert declarative macro. There is currently no other way to define them. This is a problem for 2 reasons :
* Column names cannot easily be reused accross two different function that are expected to return the same value. i.e. you can't easily create an These problems could easily be solved by using a Hence, the creation of this library : using filthy procedural macro hacks, including having the macro open a Rust file twice to read data outside the item it is applied to, it makes it possible to use a structure as returned rows. There are millions of way this can fail due to how badly implemented it is, but it should work for the general use-case. Here's how it looks : ```rust
const ALPHABET: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; struct IndexedLetter {
idx: i8,
letter: char,
} fn alphabet(length: i8) -> impl Iterator The path in the attribute parameters is probably the ugliest aspect of the macro, it is used to find the definition of alphabet
function inside your database.sql
select alphabet(8);
alphabet_reverse
function that returns the exact same columns without copy-pasting code. This become a big problem when you don't have 2, but 50 columns.
* It isn't clear at first glance which value of the returned tuples corresponds to which column name. If your tuple contains a lot of columns of the same type, it's incredibly easy to mix them up.struct
as the impl Iterator
's item, but due to the way procedural macros work, they cannot access type-level information when they run. The only proper way to solve this would be a complete redesign of pgx
, which I cannot do. I opened pgx/issues#451.[pgexterncolumns("path/to/current/file.rs")]
IndexedLetter
.