Skip to content

Commit

Permalink
fix: Embed views with different column ordering correctly
Browse files Browse the repository at this point in the history
This fixes a regression introduced in d271942.

The order of relColumns in the schema cache is now consistently matching the order of columns in foreign key definitions.

Resolves PostgREST#2518

Signed-off-by: Wolfgang Walther <[email protected]>
  • Loading branch information
wolfgangwalther committed Oct 24, 2022
1 parent ca338ae commit 2158f3d
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- #2348, Add `db-pool-acquisition-timeout` configuration option, time in seconds to wait to acquire a connection. - @robx
- #2428, Fix opening an empty transaction on failed resource embedding - @steve-chavez
- #2455, Fix embedding the same table multiple times - @steve-chavez
- #2518, Fix a regression when embedding views where base tables have a different column order for FK columns - @wolfgangwalther

### Deprecated

Expand Down
16 changes: 10 additions & 6 deletions src/PostgREST/SchemaCache.hs
Original file line number Diff line number Diff line change
Expand Up @@ -679,9 +679,9 @@ allM2OandO2ORels pgVer =
FROM pg_constraint traint
JOIN LATERAL (
SELECT
array_agg(row(cols.attname, refs.attname) order by cols.attnum) AS cols_and_fcols,
jsonb_agg(cols.attname order by cols.attnum) AS cols
FROM ( SELECT unnest(traint.conkey) AS col, unnest(traint.confkey) AS ref) _
array_agg(row(cols.attname, refs.attname) order by ord) AS cols_and_fcols,
jsonb_agg(cols.attname order by ord) AS cols
FROM unnest(traint.conkey, traint.confkey) WITH ORDINALITY AS _(col, ref, ord)
JOIN pg_attribute cols ON cols.attrelid = traint.conrelid AND cols.attnum = col
JOIN pg_attribute refs ON refs.attrelid = traint.confrelid AND refs.attnum = ref
) AS column_info ON TRUE
Expand Down Expand Up @@ -757,17 +757,21 @@ allViewsKeyDependencies =
contype::text as contype,
conname,
conrelid as resorigtbl,
unnest(conkey) as resorigcol
col as resorigcol,
ord
from pg_constraint
left join lateral unnest(conkey) with ordinality as _(col, ord) on true
where contype IN ('p', 'f')
union
-- fk referenced col
select
concat(contype, '_ref') as contype,
conname,
confrelid,
unnest(confkey)
col,
ord
from pg_constraint
left join lateral unnest(confkey) with ordinality as _(col, ord) on true
where contype='f'
),
views as (
Expand Down Expand Up @@ -897,7 +901,7 @@ allViewsKeyDependencies =
rec.view_name,
pks_fks.conname as constraint_name,
pks_fks.contype as constraint_type,
array_agg(row(col.attname, vcol.attname) order by col.attnum) as column_dependencies
array_agg(row(col.attname, vcol.attname) order by pks_fks.ord) as column_dependencies
from recursion rec
join pg_class tbl on tbl.oid = rec.resorigtbl
join pg_attribute col on col.attrelid = tbl.oid and col.attnum = rec.resorigcol
Expand Down
3 changes: 3 additions & 0 deletions test/spec/Feature/Query/QuerySpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,9 @@ spec actualPgVersion = do
{"tournament":"tournament_3","player_view":{"first_name":"first_name_3"}}] |]
{ matchHeaders = [matchContentTypeJson] }

it "works when embedding two views that refer to tables with different column ordering" $
get "/v1?select=v2(*)" `shouldRespondWith` 200

it "can embed a view that has group by" $
get "/projects_count_grouped_by?select=number_of_projects,client:clients(name)&order=number_of_projects" `shouldRespondWith`
[json|
Expand Down
18 changes: 18 additions & 0 deletions test/spec/fixtures/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2859,3 +2859,21 @@ create or replace function jsbaz(fee) returns setof baz as $$
join johnsmith js on js.baz_id = b.baz_id
where js.fee_id = $1.fee_id
$$ stable language sql;


-- issue https://github.com/PostgREST/postgrest/issues/2518
create table a (
primary key (c1, c2),
c1 int,
c2 bool
);

create table b (
c2 bool,
c1 int,
foreign key (c1, c2) references a
);

create view test.v1 as table test.a;

create view test.v2 as table test.b;

0 comments on commit 2158f3d

Please sign in to comment.