-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mutation using volatile function and relationship giving stale results #6865
Comments
(internal note for implementation) If we are generating SQL of this form for volatile functions, it is incorrect:
For non-volatile functions, the above would work, i.e, we can treat begin
modified_rows <- do mutation
response <- modified_rows join relationship_tables
commit The same approach has to be taken to process a volatile-function's response. |
Probably, I ran in the same issue. In the core, I expose a volatile function as mutation. Minimal example: create table users (
id uuid NOT NULL,
PRIMARY KEY (id)
);
create table phones (
id uuid NOT NULL DEFAULT gen_random_uuid(),
userid uuid NOT NULL
REFERENCES users(id),
phone text,
PRIMARY KEY (id)
);
CREATE FUNCTION insert_user_derived(phone text)
RETURNS SETOF users AS $BODY$
WITH
InsertedUser AS (
INSERT INTO users (id) VALUES (gen_random_uuid())
RETURNING *
),
InsertedPhones AS (
INSERT INTO phones (userid, phone)
SELECT id, phone FROM InsertedUser
)
SELECT * FROM InsertedUser;
$BODY$ LANGUAGE sql VOLATILE; Now, hasura generates something like: -- look at the query plan: it seems like this function isn't executed
explain analyse select *
from insert_user_derived('0000000')
where
-- usually there is clause of select permission for `users` table,
-- but to make example more thin, just check if any entry is visible
exists (select * from users)
or exists (select * from phones); Playground: https://www.db-fiddle.com/f/kHANnWCdxMLiTFtJa8dWiK/0 EDIT: because of permission check, the in hasura used function is executed, but it returns no results. Is there any workaround? |
Any updates on this? |
I am also running into this bug. I am working around it for now by doing a trivial update in a separate field in the same mutation, e.g. mutation MyMutation($id: uuid) {
volatile_function(args: { id: $id}) {
id
}
update_thing_by_pk(pk_columns: { id: $id}, _set: {modified_on: "now()"}) {
id
relationship_modified_by_volatile_function {
id
}
} But I would definitely expect the graphql engine to better account for volatile functions and their potential to have side effects. |
It would be really great to get this solved, it would prevent us from writing duplicate re-fetchs or hackish workarounds |
Just encountered this bug today for the first time. Would be great to see this fixed someday. |
Hello,
First of all, thank you for this amazing tool!
I'm building a mutation with a tracked Postgres volatile function.
I have a
blogposts
andtags
types linked by a many-to-many relationshipHere is the related schema.
Then I have a volatile function to update a blogpost, it deletes the old tag relationships, add the new ones and update the tile field:
Here is the associated GraphQL mutation as I use it:
The problem is the following: when performing the mutation, the relationship results returned are not the last one, they are the ones before the mutation.
For instance, if before the mutation I had only one tag and after the mutation, I have 3 tags, the fields returned by the mutation will only contain one tag.
I suspect that Hasura is joining the result from the function with the many-to-many table, and the Postgres optimizer might run the select for the tag part before the function so I get stale results.
Indeed running this SQL return the same problem:
However, decomposing in 2 queries works:
IMO it's a problem because you don't want stale results returned from a mutation.
Maybe I do something wrong, or there is a solution, but I could not find anything.
Thanks for your help.
The text was updated successfully, but these errors were encountered: