crystal icon indicating copy to clipboard operation
crystal copied to clipboard

Derived types include selector for the derived types when using relational polymorphism

Open FelixZY opened this issue 1 year ago • 0 comments

Consider a setup like this:

DROP SCHEMA if EXISTS "dansdata" cascade;

CREATE SCHEMA "dansdata";

CREATE TYPE dansdata.profile_type AS ENUM('individual', 'organization');

CREATE TABLE dansdata.profiles (
  id UUID DEFAULT gen_random_uuid () PRIMARY KEY,
  type dansdata.profile_type NOT NULL,
  name TEXT NOT NULL
);

comment ON TABLE dansdata.profiles IS $$
  @interface mode:relational type:type
  @type individual references:individuals
  @type organization references:organizations
  @name Profile

  Represents an entity with profile data.
$$;

CREATE TABLE dansdata.individuals (
  id UUID PRIMARY KEY REFERENCES dansdata.profiles (id) ON DELETE cascade
);

comment ON TABLE dansdata.individuals IS $$
  @name Individual

  Represents an individual person.
$$;

CREATE
OR REPLACE function dansdata.create_individual (name TEXT) returns dansdata.individuals AS $$
  WITH "profile" AS (
    INSERT INTO dansdata.profiles("type", "name") VALUES ('individual', name) RETURNING *
  ) INSERT INTO dansdata.individuals("id") (SELECT id from "profile") RETURNING *;
$$ language sql volatile strict security invoker;

CREATE TABLE dansdata.organizations (
  id UUID PRIMARY KEY REFERENCES dansdata.profiles (id) ON DELETE cascade
);

comment ON TABLE dansdata.organizations IS $$
  @name Organization

  Represents an organization.
$$;

CREATE
OR REPLACE function dansdata.create_organization (name TEXT) returns dansdata.organizations AS $$
  WITH "profile" AS (
    INSERT INTO dansdata.profiles("type", "name") VALUES ('organization', name) RETURNING *
  ) INSERT INTO dansdata.organizations("id") (SELECT id from "profile") RETURNING *;
$$ language sql volatile strict security invoker;

Based on the above setup, it is clear that each profile may be associated with only one of the individual or organization types. However, I am still able to write queries like this:

query {
  individuals {
    nodes {
      id
      type
      name
      # Why am I able to query for individual in here?
      individual {
        id
        type
        name
      }
      # Why am I able to query for organization in here?
      organization {
        id
        type
        name
      }
    }
  }
}

Expected results

I should be able to do this:

query {
  individuals {
    nodes {
      id
      type
      name
    }
  }
}

Actual results

I should not be able to do this:

query {
  individuals {
    nodes {
      id
      type
      name
      # Why am I able to query for individual in here?
      individual {
        id
        type
        name
      }
      # Why am I able to query for organization in here?
      organization {
        id
        type
        name
      }
    }
  }
}

Additional context

PostgreSQL: docker - postgis/postgis:16-3.4-alpine Node: v20.14.0 Postgraphile: 5.0.0-beta.26

FelixZY avatar Jun 08 '24 19:06 FelixZY