Skip to content
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

Computed fields on related table are not recalculated when returned in mutation data. #337

Open
ncrmro opened this issue Mar 7, 2023 · 1 comment
Assignees
Labels
triage-required Pending triage from maintainers

Comments

@ncrmro
Copy link

ncrmro commented Mar 7, 2023

Describe the bug
I have two tables linked by a foreign key the parent has a computed field, when performing a mutation the parent computed columns return their original values rather than the value post mutation.

I have confirmed the row is updated on refresh web page or when querying the database directly.

To Reproduce
Steps to reproduce the behavior:

CREATE TABLE parent
(
    id    uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    count int2
);

CREATE TABLE child
(
    id        uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    parent_id uuid REFERENCES parent NOT NULL,
    count     int2
);

CREATE OR REPLACE FUNCTION _count(rec parent)
    RETURNS smallint
    STABLE
    LANGUAGE sql
AS
$$
SELECT SUM(count)
FROM child
WHERE parent_id = rec.id
$$;
query ParentQuery {
  parentCollection {
    edges {
      node {
        id
        count
        childCollection {
          edges {
            node {
              count
            }
          }
        }
      }
    }
  }
}

mutation ChildMutation($id: UUID!, $count: Int!) {
  updatechildCollection(
    filter: { id: { eq: $id } }
    set: { count: $count }
  ) {
    records {
      id
      count
      parent {
        id
        count
      }
    }
  }
}

Expected behavior
I expect the related fields computed column to correctly return an updated value.

Screenshots
If applicable, add screenshots to help explain your problem.

Versions:

  • PostgreSQL: public.ecr.aws/supabase/postgres:15.1.0.42-rc2
  • pg_graphql commit ref: Not sure but supabase -v is 1.38.7

Additional context
Add any other context about the problem here.

@ncrmro ncrmro added the triage-required Pending triage from maintainers label Mar 7, 2023
@ncrmro ncrmro changed the title Computed columns on related table are not recalculated when returned in mutation data. Computed fields on related table are not recalculated when returned in mutation data. Mar 7, 2023
imor added a commit that referenced this issue Oct 30, 2023
@imor
Copy link
Contributor

imor commented Oct 30, 2023

Hi @ncrmro,

Computed field functions written in SQL should be marked volatile to avoid stale results from mutations. This is a direct consequence of Postgres volatility category behaviour. Quoting from the docs:

For functions written in SQL or in any of the standard procedural languages, there is a second important property determined by the volatility category, namely the visibility of any data changes that have been made by the SQL command that is calling the function. A VOLATILE function will see such changes, a STABLE or IMMUTABLE function will not. This behavior is implemented using the snapshotting behavior of MVCC (see Chapter 13): STABLE and IMMUTABLE functions use a snapshot established as of the start of the calling query, whereas VOLATILE functions obtain a fresh snapshot at the start of each query they execute.

I have updated the docs in #443 with this suggestion.

In other words, to fix stale results, change your function to this:

CREATE OR REPLACE FUNCTION _count(rec parent)
    RETURNS smallint
    VOLATILE
    LANGUAGE sql
AS
$$
SELECT SUM(count)
FROM child
WHERE parent_id = rec.id
$$;

olirice added a commit that referenced this issue Oct 30, 2023
add test case and docs for issue #337
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triage-required Pending triage from maintainers
Projects
None yet
Development

No branches or pull requests

3 participants