Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: null filtering on embed when column=relation #2880

Merged
merged 1 commit into from
Jul 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- #2594, Fix unused index on jsonb/jsonb arrow filter and order (``/bets?data->>contractId=eq.1`` and ``/bets?order=data->>contractId``) - @steve-chavez
- #2861, Fix character and bit columns with fixed length not inserting/updating properly - @laurenceisla
+ Fixes the error "value too long for type character(1)" when the char length of the column was bigger than one.
- #2862, Fix null filtering on embedded resource when using a column name equal to the relation name - @steve-chave

## [11.1.0] - 2023-06-07

Expand Down
8 changes: 2 additions & 6 deletions src/PostgREST/Plan.hs
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,8 @@ addRelatedOrders (Node rp@ReadPlan{order,from} forest) = do

-- | Searches for null filters on embeds, e.g. `projects=not.is.null` on `GET /clients?select=*,projects(*)&projects=not.is.null`
--
-- (It doesn't err but uses an Either ApiRequestError type so it can combine with the other functions that modify the read plan tree)
--
-- Setup:
--
-- >>> let nullOp = OpExpr True (Is TriNull)
Expand Down Expand Up @@ -628,11 +630,6 @@ addRelatedOrders (Node rp@ReadPlan{order,from} forest) = do
--
-- >>> ReadPlan.where_ . rootLabel <$> addNullEmbedFilters (readPlanTree nonNullOp subForestPlan)
-- Right [CoercibleStmnt (CoercibleFilterNullEmbed False "clients_projects_1")]
--
-- It fails if operators other than is.null or not.is.null on the embedding are used.
--
-- >>> ReadPlan.where_ . rootLabel <$> addNullEmbedFilters (readPlanTree notEqOp subForestPlan)
-- Left (UnacceptableFilter "projects")
addNullEmbedFilters :: ReadPlanTree -> Either ApiRequestError ReadPlanTree
addNullEmbedFilters (Node rp@ReadPlan{where_=curLogic} forest) = do
let forestReadPlans = rootLabel <$> forest
Expand All @@ -647,7 +644,6 @@ addNullEmbedFilters (Node rp@ReadPlan{where_=curLogic} forest) = do
let foundRP = find (\ReadPlan{relName, relAlias} -> fld == fromMaybe relName relAlias) rPlans in
case (foundRP, opExpr) of
(Just ReadPlan{relAggAlias}, OpExpr b (Is TriNull)) -> Right $ CoercibleStmnt $ CoercibleFilterNullEmbed b relAggAlias
(Just ReadPlan{relName}, _) -> Left $ UnacceptableFilter relName
_ -> Right flt
flt@(CoercibleStmnt _) ->
Right flt
Expand Down
26 changes: 14 additions & 12 deletions test/spec/Feature/Query/RelatedQueriesSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -233,18 +233,6 @@ spec = describe "related queries" $ do
, matchHeaders = [matchContentTypeJson]
}

it "only works with is null or is not null operators" $
get "/projects?select=name,clients(*)&clients=eq.3" `shouldRespondWith`
[json|{
"code":"PGRST120",
"details":"Only is null or not is null filters are allowed on embedded resources",
"hint":null,
"message":"Bad operator on the 'clients' embedded resource"
}|]
{ matchStatus = 400
, matchHeaders = [matchContentTypeJson]
}

it "doesn't interfere filtering when embedding using the column name" $
get "/projects?select=name,client_id,client:client_id(name)&client_id=eq.2" `shouldRespondWith`
[json|[
Expand All @@ -254,3 +242,17 @@ spec = describe "related queries" $ do
{ matchStatus = 200
, matchHeaders = [matchContentTypeJson]
}

it "doesn't interfere filtering on column names used for disambiguation" $
get "/user_friend?select=*,user1(*)&user1=eq.a02fb934-3a4d-469b-a6b6-4fcd88b973cf" `shouldRespondWith`
[json|[]|]
{ matchStatus = 200
, matchHeaders = [matchContentTypeJson]
}

it "doesn't interfere filtering on column names that are the same as the relation name" $
get "/tournaments?select=*,status(*)&status=eq.3" `shouldRespondWith`
[json|[]|]
{ matchStatus = 200
, matchHeaders = [matchContentTypeJson]
}
21 changes: 21 additions & 0 deletions test/spec/fixtures/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3308,3 +3308,24 @@ CREATE TABLE bitchar_with_length (
bit bit(5),
char char(5)
);

--- https://github.com/PostgREST/postgrest/issues/2862
create table profiles (
id uuid primary key,
username text null
);

create table user_friend (
id bigint primary key,
user1 uuid references profiles (id),
user2 uuid references profiles (id)
);

create table status(
id bigint primary key
);

create table tournaments(
id bigint primary key,
status bigint references status(id)
);