Hello and welcome to The Beginning of The End!
You may have seen some largely-inscrutable rambling about "object lifetimes" and "memory contexts" from me in various comments, logs, and issues. You may have also heard that this has effectively stalled all forward feature work. You may have noticed this has been the case for months now.
The long and short of it is that pgrx never actually fully built-in the actual lifetimes of objects in Postgres into its various types. As more and more interlocking parts grew, between things like the type unboxing in trait FromDatum
, or the bounded memory context of Spi::connect
, eventually many supposedly-safe interfaces arose which proved wildly unsafe in reality due to this mesh of interactions. Internal portions of pgrx relied on expeditious hacks to ignore the growing problems, until this rotten foundation yielded an enormous crop of soundness issues over the year of 2023. Even when not exploitable, they prevent otherwise-trivial enhancements in terms of speed or memory usage.
Key elements of a new foundation have landed in pgrx, which allow ascribing lifetimes to every datum and every memory context that a Postgres extension will encounter. There is much more work to be done to actually make it so all Rust code has to flow through these new interfaces. This alpha release is an extremely "preview" release to allow assessing some of the damage from the first set of breaking changes, so that some initial feedback and triage can occur. There will, unfortunately, be more breaking changes on the horizon.
There are so many small changes that I am simply going to summarize the main point of them:
Many Macros Expand Subtly Differently
If your extension now breaks in some inscrutable way that you cannot otherwise discern, the problem is probably hidden in macro expansion. This cannot really be diagnosed except using cargo expand
diffed against previous expansions. A most likely issue is that something that previously hid a lifetime during expansion or writes it as 'static now propagates it by name or as the anonymous '_ lifetime.
Datum<'src>
There are now lifetime-bound Datums. Expect to see them in more places.
UnboxDatum<As<'src> = Type<'src>>
Expect to see this or a similar signature a lot: there are new conversion traits which use a generic associated type or similar sneaky tactics to allow "clamping down" the lifetime to a bound, unless the produced type is always 'static by being a simple value like i32
.
&'mcx MemCx<'_>
You will see more and more references to this type, which is a memory context that encodes an inner invariant lifetime, in signatures. If one of these is currently in-scope, then please remember it is always unsafe
to manipulate the static mut CurrentMemoryContext
in Postgres, but it is doubly so then. In general, when designing your own types using pgrx, you should prefer designing code that uses a signature like that of MemoryContextAlloc
instead of palloc
if you are at all uncertain.
Full Changelog: v0.11.0...v0.12.0-alpha.0