fix: empty spread embeddings return unexpected SQL error
Fixes the SQL error from postgres when an empty spread embeddings like `...table()` is requested.
This commit is contained in:
committed by
Wolfgang Walther
parent
6ecacbc4cc
commit
d863065a51
@@ -9,6 +9,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
- Fix OpenAPI broken docs link by @taimoorzaeem in #4048
|
- Fix OpenAPI broken docs link by @taimoorzaeem in #4048
|
||||||
- Fix OpenAPI specification incorrectly exposing GET methods for volatile functions by @joelonsql in #4174
|
- Fix OpenAPI specification incorrectly exposing GET methods for volatile functions by @joelonsql in #4174
|
||||||
|
- Fix empty spread embeddings return unexpected SQL error by @taimoorzaeem in #3887
|
||||||
|
|
||||||
## [13.0.4] - 2025-06-17
|
## [13.0.4] - 2025-06-17
|
||||||
|
|
||||||
|
|||||||
@@ -70,21 +70,21 @@ readPlanToQuery node@(Node ReadPlan{select,from=mainQi,fromAlias,where_=logicFor
|
|||||||
|
|
||||||
getJoinSelects :: ReadPlanTree -> [SQL.Snippet]
|
getJoinSelects :: ReadPlanTree -> [SQL.Snippet]
|
||||||
getJoinSelects (Node ReadPlan{relSelect} _) =
|
getJoinSelects (Node ReadPlan{relSelect} _) =
|
||||||
mapMaybe relSelectToSnippet relSelect
|
join $ map relSelectToSnippet relSelect
|
||||||
where
|
where
|
||||||
relSelectToSnippet :: RelSelectField -> Maybe SQL.Snippet
|
relSelectToSnippet :: RelSelectField -> [SQL.Snippet]
|
||||||
relSelectToSnippet fld =
|
relSelectToSnippet fld =
|
||||||
let aggAlias = pgFmtIdent $ rsAggAlias fld
|
let aggAlias = pgFmtIdent $ rsAggAlias fld
|
||||||
in
|
in
|
||||||
case fld of
|
case fld of
|
||||||
JsonEmbed{rsEmptyEmbed = True} ->
|
JsonEmbed{rsEmptyEmbed = True} ->
|
||||||
Nothing
|
[]
|
||||||
JsonEmbed{rsSelName, rsEmbedMode = JsonObject} ->
|
JsonEmbed{rsSelName, rsEmbedMode = JsonObject} ->
|
||||||
Just $ "row_to_json(" <> aggAlias <> ".*)::jsonb AS " <> pgFmtIdent rsSelName
|
["row_to_json(" <> aggAlias <> ".*)::jsonb AS " <> pgFmtIdent rsSelName]
|
||||||
JsonEmbed{rsSelName, rsEmbedMode = JsonArray} ->
|
JsonEmbed{rsSelName, rsEmbedMode = JsonArray} ->
|
||||||
Just $ "COALESCE( " <> aggAlias <> "." <> aggAlias <> ", '[]') AS " <> pgFmtIdent rsSelName
|
["COALESCE( " <> aggAlias <> "." <> aggAlias <> ", '[]') AS " <> pgFmtIdent rsSelName]
|
||||||
Spread{rsSpreadSel, rsAggAlias} ->
|
Spread{rsSpreadSel, rsAggAlias} ->
|
||||||
Just $ intercalateSnippet ", " (pgFmtSpreadSelectItem rsAggAlias <$> rsSpreadSel)
|
pgFmtSpreadSelectItem rsAggAlias <$> rsSpreadSel
|
||||||
|
|
||||||
getJoins :: ReadPlanTree -> [SQL.Snippet]
|
getJoins :: ReadPlanTree -> [SQL.Snippet]
|
||||||
getJoins (Node _ []) = []
|
getJoins (Node _ []) = []
|
||||||
|
|||||||
@@ -600,3 +600,37 @@ spec =
|
|||||||
{ matchStatus = 200
|
{ matchStatus = 200
|
||||||
, matchHeaders = [matchContentTypeJson]
|
, matchHeaders = [matchContentTypeJson]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context "empty spreads embeds" $
|
||||||
|
it "should work return the same as empty embeddings" $ do
|
||||||
|
get "/actors?select=*,...films()"
|
||||||
|
`shouldRespondWith`
|
||||||
|
[json| [{"id":1,"name":"john"}, {"id":2,"name":"mary"}] |]
|
||||||
|
{ matchStatus = 200
|
||||||
|
, matchHeaders = [matchContentTypeJson]
|
||||||
|
}
|
||||||
|
|
||||||
|
get "/grandchild_entities?select=name,...child_entities(parent_name:name,...entities())"
|
||||||
|
`shouldRespondWith`
|
||||||
|
[json|
|
||||||
|
[{"name":"grandchild entity 1","parent_name":"child entity 1"},
|
||||||
|
{"name":"grandchild entity 2","parent_name":"child entity 1"},
|
||||||
|
{"name":"grandchild entity 3","parent_name":"child entity 2"},
|
||||||
|
{"name":"(grandchild,entity,4)","parent_name":"child entity 2"},
|
||||||
|
{"name":"(grandchild,entity,5)","parent_name":"child entity 2"}]
|
||||||
|
|]
|
||||||
|
{ matchStatus = 200
|
||||||
|
, matchHeaders = [matchContentTypeJson]
|
||||||
|
}
|
||||||
|
|
||||||
|
get "/factories?select=factory:name,...processes()"
|
||||||
|
`shouldRespondWith`
|
||||||
|
[json|
|
||||||
|
[{"factory":"Factory A"},
|
||||||
|
{"factory":"Factory B"},
|
||||||
|
{"factory":"Factory C"},
|
||||||
|
{"factory":"Factory D"}]
|
||||||
|
|]
|
||||||
|
{ matchStatus = 200
|
||||||
|
, matchHeaders = [matchContentTypeJson]
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user