graphile / crystal

🔮 Graphile's Crystal Monorepo; home to Grafast, PostGraphile, pg-introspection, pg-sql2 and much more!
https://graphile.org/
Other
12.62k stars 571 forks source link

Foreign Key on Composite Type #2137

Closed drewwestphal closed 3 months ago

drewwestphal commented 3 months ago

Filing at @benjie's request.

Summary

VERSION: Beta.26 and Beta.28

I've added a composite type as a column on a view. That composite type has keys which reference another view which I've successfully linked to other schema objects with smart tags. I'm trying to add a smart tag to link to the composite type to the view using the view primary key and the fields in the composite type. I cannot get the schema to reflect the link. The docs say @foreignKey can apply to Composite types (one direction only) . How do I accomplish this linkage?

Originally posted in discord

Steps to reproduce

These objects are all visible in the schema, but the connection still isn't.

  1. Create a view with a @primaryKey
  2. Create a composite type with a @foreignKey
  3. The link will not appear

Expected results

The records show up with a Connection in the GraphQL schema

Actual results

No connection is visible

Additional context

Notes about my setup if they are relevant

  1. My schema has viewPrim (with a @primaryKey) and view2 and composite type ctfk
  2. view2.someColumn is a composite type which has column of type ctfk
  3. ctfk contains the @foreignKey reference

Unsuccessful fixes

  1. The foreignKey parser is pretty strict, it's possible that it requires that there be a space between image_set and (; or that you have trailing spaces that are invalidating it. -- space does not change the behavior
  2. Comments on both regclass and regtype -- removing the not null comments from composite type columns does not resolve the issue

Images shared in discord originally image image image image image

Possible fixes

it's definitely possible that V5 doesn't support @foreignKey on composite types. I'm not sure if we have any tests for that

benjie commented 3 months ago

Table definitely works:

drop schema if exists test cascade;
create schema test;
set search_path to test;

create table tbl1 (
  id serial primary key,
  text text
);

insert into tbl1 (text) values
  ('HI'),
  ('BYE');

create type type1 as (
  tbl1_id int,
  t text
);
comment on type type1 is '@foreignKey (tbl1_id) references tbl1';
create function test() returns setof type1 as $$
  select *
  from (values
    (1, 'hi'),
    (2, 'bye')
  ) t;
$$ language sql stable;

can query like:

{
  test {
    nodes {
      tbl1Id
      t
      tbl1ByTbl1Id {
        id
        text
      }
    }
  }
}
benjie commented 3 months ago

Also works just fine replacing the table with a view:

drop schema if exists test cascade;
create schema test;
set search_path to test;

create view tbl1 as
  select *
  from (values
    (1, 'HI'),
    (2, 'BYE')
  ) as t (id, text);
comment on view tbl1 is '@primaryKey id';

create type type1 as (
  tbl1_id int,
  t text
);
comment on type type1 is '@foreignKey (tbl1_id) references tbl1';
create function test() returns setof type1 as $$
  select *
  from (values
    (1, 'hi'),
    (2, 'bye')
  ) t;
$$ language sql stable;
benjie commented 3 months ago

This was tested using benjie/ouch-my-finger

benjie commented 3 months ago

[semi-automated message] To keep things manageable I'm going to close this issue as I think it's solved; but if not or you require further help please re-open it.