Skip to content

Commit

Permalink
Merge pull request #628 from supabase/feat/relationships-is-one-to-one
Browse files Browse the repository at this point in the history
feat(relationships): include `is_one_to_one`
  • Loading branch information
soedirgo authored Nov 1, 2023
2 parents 994808b + d087241 commit b269dd3
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/lib/PostgresMetaRelationships.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export default class PostgresMetaRelationships {
schema: vtkd.view_schema,
relation: vtkd.view_name,
columns: viewColumns,
is_one_to_one: r.is_one_to_one,
referenced_schema: r.referenced_schema,
referenced_relation: r.referenced_relation,
referenced_columns: r.referenced_columns,
Expand All @@ -104,6 +105,7 @@ export default class PostgresMetaRelationships {
schema: r.schema,
relation: r.relation,
columns: r.columns,
is_one_to_one: r.is_one_to_one,
referenced_schema: tvkd.view_schema,
referenced_relation: tvkd.view_name,
referenced_columns: viewColumns,
Expand All @@ -119,6 +121,7 @@ export default class PostgresMetaRelationships {
schema: vtkd.view_schema,
relation: vtkd.view_name,
columns: viewColumns,
is_one_to_one: r.is_one_to_one,
referenced_schema: tvkd.view_schema,
referenced_relation: tvkd.view_name,
referenced_columns: referencedViewColumns,
Expand Down
22 changes: 21 additions & 1 deletion src/lib/sql/table_relationships.sql
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
-- Adapted from
-- https://github.com/PostgREST/postgrest/blob/f9f0f79fa914ac00c11fbf7f4c558e14821e67e2/src/PostgREST/SchemaCache.hs#L722
WITH
pks_uniques_cols AS (
SELECT
connamespace,
conrelid,
jsonb_agg(column_info.cols) as cols
FROM pg_constraint
JOIN lateral (
SELECT array_agg(cols.attname order by cols.attnum) as cols
FROM ( select unnest(conkey) as col) _
JOIN pg_attribute cols on cols.attrelid = conrelid and cols.attnum = col
) column_info ON TRUE
WHERE
contype IN ('p', 'u') and
connamespace::regnamespace::text <> 'pg_catalog'
GROUP BY connamespace, conrelid
)
SELECT
traint.conname AS foreign_key_name,
ns1.nspname AS schema,
tab.relname AS relation,
column_info.cols AS columns,
ns2.nspname AS referenced_schema,
other.relname AS referenced_relation,
column_info.refs AS referenced_columns
column_info.refs AS referenced_columns,
(column_info.cols IN (SELECT * FROM jsonb_array_elements(pks_uqs.cols))) AS is_one_to_one
FROM pg_constraint traint
JOIN LATERAL (
SELECT
Expand All @@ -21,4 +39,6 @@ JOIN pg_namespace ns1 ON ns1.oid = traint.connamespace
JOIN pg_class tab ON tab.oid = traint.conrelid
JOIN pg_class other ON other.oid = traint.confrelid
JOIN pg_namespace ns2 ON ns2.oid = other.relnamespace
LEFT JOIN pks_uniques_cols pks_uqs ON pks_uqs.connamespace = traint.connamespace AND pks_uqs.conrelid = traint.conrelid
WHERE traint.contype = 'f'
AND traint.conparentid = 0
1 change: 1 addition & 0 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ export const postgresRelationshipSchema = Type.Object({
schema: Type.String(),
relation: Type.String(),
columns: Type.Array(Type.String()),
is_one_to_one: Type.Boolean(),
referenced_schema: Type.String(),
referenced_relation: Type.String(),
referenced_columns: Type.Array(Type.String()),
Expand Down
2 changes: 2 additions & 0 deletions src/server/templates/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ export interface Database {
(relationship) => `{
foreignKeyName: ${JSON.stringify(relationship.foreign_key_name)}
columns: ${JSON.stringify(relationship.columns)}
isOneToOne: ${relationship.is_one_to_one}
referencedRelation: ${JSON.stringify(relationship.referenced_relation)}
referencedColumns: ${JSON.stringify(relationship.referenced_columns)}
}`
Expand Down Expand Up @@ -235,6 +236,7 @@ export interface Database {
(relationship) => `{
foreignKeyName: ${JSON.stringify(relationship.foreign_key_name)}
columns: ${JSON.stringify(relationship.columns)}
isOneToOne: ${relationship.is_one_to_one}
referencedRelation: ${JSON.stringify(relationship.referenced_relation)}
referencedColumns: ${JSON.stringify(relationship.referenced_columns)}
}`
Expand Down
5 changes: 5 additions & 0 deletions test/db/00-init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,8 @@ $$;

create or replace function public.polymorphic_function(text) returns void language sql as '';
create or replace function public.polymorphic_function(bool) returns void language sql as '';

create table user_details (
user_id int8 references users(id) primary key,
details text
);
18 changes: 18 additions & 0 deletions test/lib/tables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,15 @@ test('list', async () => {
"target_table_name": "users",
"target_table_schema": "public",
},
{
"constraint_name": "user_details_user_id_fkey",
"source_column_name": "user_id",
"source_schema": "public",
"source_table_name": "user_details",
"target_column_name": "id",
"target_table_name": "users",
"target_table_schema": "public",
},
],
"replica_identity": "DEFAULT",
"rls_enabled": false,
Expand Down Expand Up @@ -176,6 +185,15 @@ test('list without columns', async () => {
"target_table_name": "users",
"target_table_schema": "public",
},
{
"constraint_name": "user_details_user_id_fkey",
"source_column_name": "user_id",
"source_schema": "public",
"source_table_name": "user_details",
"target_column_name": "id",
"target_table_name": "users",
"target_table_schema": "public",
},
],
"replica_identity": "DEFAULT",
"rls_enabled": false,
Expand Down
37 changes: 37 additions & 0 deletions test/server/typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ test('typegen', async () => {
{
foreignKeyName: "memes_category_fkey"
columns: ["category"]
isOneToOne: false
referencedRelation: "category"
referencedColumns: ["id"]
}
Expand All @@ -87,12 +88,44 @@ test('typegen', async () => {
{
foreignKeyName: "todos_user-id_fkey"
columns: ["user-id"]
isOneToOne: false
referencedRelation: "users"
referencedColumns: ["id"]
},
{
foreignKeyName: "todos_user-id_fkey"
columns: ["user-id"]
isOneToOne: false
referencedRelation: "users_view"
referencedColumns: ["id"]
}
]
}
user_details: {
Row: {
details: string | null
user_id: number
}
Insert: {
details?: string | null
user_id: number
}
Update: {
details?: string | null
user_id?: number
}
Relationships: [
{
foreignKeyName: "user_details_user_id_fkey"
columns: ["user_id"]
isOneToOne: true
referencedRelation: "users"
referencedColumns: ["id"]
},
{
foreignKeyName: "user_details_user_id_fkey"
columns: ["user_id"]
isOneToOne: true
referencedRelation: "users_view"
referencedColumns: ["id"]
}
Expand Down Expand Up @@ -149,12 +182,14 @@ test('typegen', async () => {
{
foreignKeyName: "todos_user-id_fkey"
columns: ["user-id"]
isOneToOne: false
referencedRelation: "users"
referencedColumns: ["id"]
},
{
foreignKeyName: "todos_user-id_fkey"
columns: ["user-id"]
isOneToOne: false
referencedRelation: "users_view"
referencedColumns: ["id"]
}
Expand All @@ -180,12 +215,14 @@ test('typegen', async () => {
{
foreignKeyName: "todos_user-id_fkey"
columns: ["user-id"]
isOneToOne: false
referencedRelation: "users"
referencedColumns: ["id"]
},
{
foreignKeyName: "todos_user-id_fkey"
columns: ["user-id"]
isOneToOne: false
referencedRelation: "users_view"
referencedColumns: ["id"]
}
Expand Down

0 comments on commit b269dd3

Please sign in to comment.