fix: Treat non-setof computed relationships as M2O/O2M
Fixes #2481 Signed-off-by: Wolfgang Walther <walther@technowledgy.de>
This commit is contained in:
committed by
Wolfgang Walther
parent
88b5966a44
commit
f9f572a5d2
@@ -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
|
- #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
|
- #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
|
- #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
|
### Changed
|
||||||
|
|
||||||
|
|||||||
@@ -727,12 +727,12 @@ allComputedRels =
|
|||||||
computed_rels as (
|
computed_rels as (
|
||||||
select
|
select
|
||||||
(parse_ident(p.pronamespace::regnamespace::text))[1] as schema,
|
(parse_ident(p.pronamespace::regnamespace::text))[1] as schema,
|
||||||
p.proname::text as name,
|
p.proname::text as name,
|
||||||
arg_schema.nspname::text as rel_table_schema,
|
arg_schema.nspname::text as rel_table_schema,
|
||||||
arg_name.typname::text as rel_table_name,
|
arg_name.typname::text as rel_table_name,
|
||||||
ret_schema.nspname::text as rel_ftable_schema,
|
ret_schema.nspname::text as rel_ftable_schema,
|
||||||
ret_name.typname::text as rel_ftable_name,
|
ret_name.typname::text as rel_ftable_name,
|
||||||
p.prorows = 1 as single_row
|
not p.proretset or p.prorows = 1 as single_row
|
||||||
from pg_proc p
|
from pg_proc p
|
||||||
join pg_type arg_name on arg_name.oid = p.proargtypes[0]
|
join pg_type arg_name on arg_name.oid = p.proargtypes[0]
|
||||||
join pg_namespace arg_schema on arg_schema.oid = arg_name.typnamespace
|
join pg_namespace arg_schema on arg_schema.oid = arg_name.typnamespace
|
||||||
|
|||||||
@@ -12,14 +12,24 @@ import SpecHelper
|
|||||||
|
|
||||||
spec :: SpecWith ((), Application)
|
spec :: SpecWith ((), Application)
|
||||||
spec = describe "computed relationships" $ do
|
spec = describe "computed relationships" $ do
|
||||||
it "can define a many-to-one relationship and embed" $
|
it "can define a many-to-one relationship with SETOF and ROWS 1 and embed" $
|
||||||
get "/videogames?select=name,designers:computed_designers(name)"
|
get "/videogames?select=name,designer:computed_designers(name)"
|
||||||
`shouldRespondWith`
|
`shouldRespondWith`
|
||||||
[json|[
|
[json|[
|
||||||
{"name":"Civilization I","designers":{"name":"Sid Meier"}},
|
{"name":"Civilization I","designer":{"name":"Sid Meier"}},
|
||||||
{"name":"Civilization II","designers":{"name":"Sid Meier"}},
|
{"name":"Civilization II","designer":{"name":"Sid Meier"}},
|
||||||
{"name":"Final Fantasy I","designers":{"name":"Hironobu Sakaguchi"}},
|
{"name":"Final Fantasy I","designer":{"name":"Hironobu Sakaguchi"}},
|
||||||
{"name":"Final Fantasy II","designers":{"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] }
|
]|] { matchHeaders = [matchContentTypeJson] }
|
||||||
|
|
||||||
it "can define a one-to-many relationship and embed" $
|
it "can define a one-to-many relationship and embed" $
|
||||||
@@ -48,6 +58,16 @@ spec = describe "computed relationships" $ do
|
|||||||
{ matchStatus = 200
|
{ matchStatus = 200
|
||||||
, matchHeaders = ["Content-Range" <:> "0-1/2"]
|
, 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
|
it "works with rpc" $ do
|
||||||
get "/rpc/getallvideogames?select=name,designer:computed_designers(name)"
|
get "/rpc/getallvideogames?select=name,designer:computed_designers(name)"
|
||||||
|
|||||||
Vendored
+4
@@ -2737,6 +2737,10 @@ CREATE FUNCTION test.computed_designers(test.videogames) RETURNS SETOF test.desi
|
|||||||
SELECT * FROM test.designers WHERE id = $1.designer_id;
|
SELECT * FROM test.designers WHERE id = $1.designer_id;
|
||||||
$$ LANGUAGE sql STABLE ROWS 1;
|
$$ 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 $$
|
CREATE FUNCTION test.computed_videogames(test.designers) RETURNS SETOF test.videogames AS $$
|
||||||
SELECT * FROM test.videogames WHERE designer_id = $1.id;
|
SELECT * FROM test.videogames WHERE designer_id = $1.id;
|
||||||
$$ LANGUAGE sql STABLE;
|
$$ LANGUAGE sql STABLE;
|
||||||
|
|||||||
Reference in New Issue
Block a user