Comments (6)
Not sure if PGX has api to access TopTransactionId. But one way that i can think of to address this is to track the mtime of the source code / .so file in the in-memory map. On function execution, compare the in memory mtime of the function with the actual mtime of the source code / .so file. If the user function has been modified, the it should reload the function from the .so file.
from plrust.
PGX can add the relevant header if necessary.
from plrust.
I feel apprehensive about CREATE OR REPLACE FUNCTION in general, honestly. In the concurrent function creation case, with two sessions connected to Postgres, isn't this always a form of race condition?
We can create a coherent model for when to build, load, rebuild, and discard symbols, and use various tricks like symbol generations to make sure we're always using the correct symbol... but I don't think "two sessions open a transaction and try to commit creating the same function, and the second one will clobber the first, because even though they both think they are creating the same function, one will actually be OR REPLACE" is a situation where working around that with more and more epicycles is going to get us anywhere useful, as we then have to account for ROLLBACK as well. Postgres avoids trying to unload symbols because dlclose
is somewhat incoherent to begin with, and probably is for Rust's std as well, and security advisories have been issued against CREATE OR REPLACE FUNCTION
.
PGX allows it in user code, but that's with the admonishment that CREATE OR REPLACE FUNCTION is a dubious choice... but it's different when you're loading an entire extension, instead of building up the user code in the language, function by function.
from plrust.
I think the issue does not necessary applies to two racing CREATE OR REPLACE
. It could be some situation where one session performs a CREATE OR REPLACE
and the function is up-to-date on this session. But on the other sessions the function is now stale.
# On Session1
postgres=> SELECT foo(1);
foo
-----
1
(1 row)
# On Session2
postgres=> SELECT foo(1);
foo
-----
1
(1 row)
# Update the function on Session1, the function is up-to-date
postgres=> CREATE OR REPLACE FUNCTION foo(i int) RETURNS INT AS
postgres-> $$
postgres$> Some(i.unwrap() + 1)
postgres$> $$ LANGUAGE plrust;
NOTICE: INFO plrust::plrust: unloaded function
at src/plrust.rs:40
CREATE FUNCTION
postgres=> SELECT foo (1);
foo
-----
2
(1 row)
# However in Session2, the function is stale
postgres=> SELECT foo(1);
foo
-----
1
(1 row)
For plpgsql, this is handled properly
# Session1
postgres=# SELECT test_plpgsql(1);
test_plpgsql
--------------
1
(1 row)
# Session2
postgres=# SELECT test_plpgsql(1);
test_plpgsql
--------------
1
(1 row)
# Update the function on Session1
postgres=# CREATE OR REPLACE FUNCTION test_plpgsql(i int)
RETURNS int AS
$$
BEGIN
RETURN i + 1;
END
$$ LANGUAGE plpgsql;
CREATE FUNCTION
postgres=# SELECT test_plpgsql(1);
test_plpgsql
--------------
2
(1 row)
# On Session2
postgres=# SELECT test_plpgsql(1);
test_plpgsql
--------------
2
(1 row)
from plrust.
I know that part, I'm just annoyed because of the other implications.
e.g. whatever we use to approach this has to do something to avoid rebuilding and replacing the function and opening new sharedlibs with new symbols constantly or else it becomes distressingly plausible to just repeatedly issue CREATE OR REPLACE FUNCTION until the machine runs out of hard drive space and memory. But this becomes comparatively easier if we always know whether we're creating instance "generation 0" for a function or advancing the generation by 1.
from plrust.
This has been fixed. We now track the xmin
of the row from pg_catalog.pg_proc
. And if that's different than what we previously loaded we then (attempt to) unload the function and reload the new version.
from plrust.
Related Issues (20)
- Call a function from another function HOT 6
- Add a function to list all the allowlisted crates with their respective versions, features HOT 2
- Plrustc will not compile on alpine/postgres. HOT 3
- Compiling multiple functions together HOT 7
- fix `plrust/build` to dynamically determine pgrx version HOT 1
- Some examples appear to always ERROR HOT 4
- Support for custom (opaque) type HOT 5
- plrustc does not seem to catch `include!` macro properly HOT 3
- env/option_env failing to be linted by plrustc HOT 7
- Accessing JsonbContainer HOT 12
- UDF load time is high when compared to PL/PGSQL HOT 2
- How to return an array of any dimenion from pl/rust function.
- Enhancement to prevent cargo from recompiling allowlisted dependencies. HOT 7
- plrust installation fails when postgres 15 compiled with gprof profiler HOT 2
- Publish to https://database.dev/ HOT 9
- enumerated type as function arg? HOT 7
- JSonb extract slower in Pl/Rust than in Pl/PgSql HOT 3
- Postgres Triggers, achieve different behaviour on INSERT, UPDATE, etc.
- Problem with clap v4.5.4 HOT 5
- seg faults when working with composite types HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from plrust.