fix: Treat non-setof computed relationships as M2O/O2M

Fixes #2481

Signed-off-by: Wolfgang Walther <walther@technowledgy.de>
This commit is contained in:
Wolfgang Walther
2022-10-27 19:50:38 +02:00
committed by Wolfgang Walther
parent 88b5966a44
commit f9f572a5d2
4 changed files with 37 additions and 12 deletions
+1
View File
@@ -20,6 +20,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- #2356, Fix a regression in openapi output with mode follow-privileges - @wolfgangwalther
- #2283, Fix infinite recursion when loading schema cache with self-referencing view - @wolfgangwalther
- #2343, Return status code 200 for PATCH requests which don't affect any rows - @wolfgangwalther
- #2481, Treat computed relationships not marked SETOF as M2O/O2O relationship - @wolfgangwalther
### Changed
+6 -6
View File
@@ -727,12 +727,12 @@ allComputedRels =
computed_rels as (
select
(parse_ident(p.pronamespace::regnamespace::text))[1] as schema,
p.proname::text as name,
arg_schema.nspname::text as rel_table_schema,
arg_name.typname::text as rel_table_name,
ret_schema.nspname::text as rel_ftable_schema,
ret_name.typname::text as rel_ftable_name,
p.prorows = 1 as single_row
p.proname::text as name,
arg_schema.nspname::text as rel_table_schema,
arg_name.typname::text as rel_table_name,
ret_schema.nspname::text as rel_ftable_schema,
ret_name.typname::text as rel_ftable_name,
not p.proretset or p.prorows = 1 as single_row
from pg_proc p
join pg_type arg_name on arg_name.oid = p.proargtypes[0]
join pg_namespace arg_schema on arg_schema.oid = arg_name.typnamespace
+26 -6
View File
@@ -12,14 +12,24 @@ import SpecHelper
spec :: SpecWith ((), Application)
spec = describe "computed relationships" $ do
it "can define a many-to-one relationship and embed" $
get "/videogames?select=name,designers:computed_designers(name)"
it "can define a many-to-one relationship with SETOF and ROWS 1 and embed" $
get "/videogames?select=name,designer:computed_designers(name)"
`shouldRespondWith`
[json|[
{"name":"Civilization I","designers":{"name":"Sid Meier"}},
{"name":"Civilization II","designers":{"name":"Sid Meier"}},
{"name":"Final Fantasy I","designers":{"name":"Hironobu Sakaguchi"}},
{"name":"Final Fantasy II","designers":{"name":"Hironobu Sakaguchi"}}
{"name":"Civilization I","designer":{"name":"Sid Meier"}},
{"name":"Civilization II","designer":{"name":"Sid Meier"}},
{"name":"Final Fantasy I","designer":{"name":"Hironobu Sakaguchi"}},
{"name":"Final Fantasy II","designer":{"name":"Hironobu Sakaguchi"}}
]|] { matchHeaders = [matchContentTypeJson] }
it "can define a many-to-one relationship without SETOF and embed" $
get "/videogames?select=name,designer:computed_designers_noset(name)"
`shouldRespondWith`
[json|[
{"name":"Civilization I","designer":{"name":"Sid Meier"}},
{"name":"Civilization II","designer":{"name":"Sid Meier"}},
{"name":"Final Fantasy I","designer":{"name":"Hironobu Sakaguchi"}},
{"name":"Final Fantasy II","designer":{"name":"Hironobu Sakaguchi"}}
]|] { matchHeaders = [matchContentTypeJson] }
it "can define a one-to-many relationship and embed" $
@@ -48,6 +58,16 @@ spec = describe "computed relationships" $ do
{ matchStatus = 200
, matchHeaders = ["Content-Range" <:> "0-1/2"]
}
request methodGet "/videogames?select=name,designer:computed_designers_noset!inner(name)&designer.name=like.*Hironobu*"
[("Prefer", "count=exact")] ""
`shouldRespondWith`
[json|[
{"name":"Final Fantasy I","designer":{"name":"Hironobu Sakaguchi"}},
{"name":"Final Fantasy II","designer":{"name":"Hironobu Sakaguchi"}}
]|]
{ matchStatus = 200
, matchHeaders = ["Content-Range" <:> "0-1/2"]
}
it "works with rpc" $ do
get "/rpc/getallvideogames?select=name,designer:computed_designers(name)"
+4
View File
@@ -2737,6 +2737,10 @@ CREATE FUNCTION test.computed_designers(test.videogames) RETURNS SETOF test.desi
SELECT * FROM test.designers WHERE id = $1.designer_id;
$$ LANGUAGE sql STABLE ROWS 1;
CREATE FUNCTION test.computed_designers_noset(test.videogames) RETURNS test.designers AS $$
SELECT * FROM test.designers WHERE id = $1.designer_id;
$$ LANGUAGE sql STABLE;
CREATE FUNCTION test.computed_videogames(test.designers) RETURNS SETOF test.videogames AS $$
SELECT * FROM test.videogames WHERE designer_id = $1.id;
$$ LANGUAGE sql STABLE;