fix: Fatal error when requesting limit=0 and db-max-rows is set (#2560)

This commit is contained in:
Laurence Isla
2022-11-04 18:14:16 -05:00
committed by GitHub
parent c8e4f38984
commit b8c5d212ea
5 changed files with 19 additions and 3 deletions
+1
View File
@@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Fixed ### Fixed
- #2548, Fix regression when embedding views with partial references to multi column FKs - @wolfgangwalther - #2548, Fix regression when embedding views with partial references to multi column FKs - @wolfgangwalther
- #2558, Fix regression when requesting limit=0 and `db-max-row` is set - @laurenceisla
## [10.1.0] - 2022-10-28 ## [10.1.0] - 2022-10-28
+2 -2
View File
@@ -59,8 +59,8 @@ import PostgREST.MediaType (MTPlanAttrs (..),
MTPlanFormat (..), MTPlanFormat (..),
MediaType (..)) MediaType (..))
import PostgREST.RangeQuery (NonnegRange, allRange, import PostgREST.RangeQuery (NonnegRange, allRange,
convertToLimitZeroRange,
hasLimitZero, hasLimitZero,
limitZeroRange,
rangeRequested) rangeRequested)
import PostgREST.SchemaCache (SchemaCache (..)) import PostgREST.SchemaCache (SchemaCache (..))
import PostgREST.SchemaCache.Identifiers (FieldName, import PostgREST.SchemaCache.Identifiers (FieldName,
@@ -354,7 +354,7 @@ apiRequest conf sCache req reqBody queryparams@QueryParams{..} PathInfo{pathName
-- Bypass all the ranges and send only the limit zero range (0 <= x <= -1) if -- Bypass all the ranges and send only the limit zero range (0 <= x <= -1) if
-- limit=0 is present in the query params (not allowed for the Range header) -- limit=0 is present in the query params (not allowed for the Range header)
ranges = HM.insert "limit" (if hasLimitZero limitRange then limitZeroRange else headerAndLimitRange) qsRanges ranges = HM.insert "limit" (convertToLimitZeroRange limitRange headerAndLimitRange) qsRanges
-- The only emptyRange allowed is the limit zero range -- The only emptyRange allowed is the limit zero range
isInvalidRange = topLevelRange == emptyRange && not (hasLimitZero limitRange) isInvalidRange = topLevelRange == emptyRange && not (hasLimitZero limitRange)
+2 -1
View File
@@ -40,6 +40,7 @@ import PostgREST.Config (AppConfig (..))
import PostgREST.Error (Error (..)) import PostgREST.Error (Error (..))
import PostgREST.Query.SqlFragment (sourceCTEName) import PostgREST.Query.SqlFragment (sourceCTEName)
import PostgREST.RangeQuery (NonnegRange, allRange, import PostgREST.RangeQuery (NonnegRange, allRange,
convertToLimitZeroRange,
restrictRange) restrictRange)
import PostgREST.SchemaCache (SchemaCache (..)) import PostgREST.SchemaCache (SchemaCache (..))
import PostgREST.SchemaCache.Identifiers (FieldName, import PostgREST.SchemaCache.Identifiers (FieldName,
@@ -123,7 +124,7 @@ treeRestrictRange _ (ActionMutate _) request = Right request
treeRestrictRange maxRows _ request = pure $ nodeRestrictRange maxRows <$> request treeRestrictRange maxRows _ request = pure $ nodeRestrictRange maxRows <$> request
where where
nodeRestrictRange :: Maybe Integer -> ReadPlan -> ReadPlan nodeRestrictRange :: Maybe Integer -> ReadPlan -> ReadPlan
nodeRestrictRange m q@ReadPlan{range_=r} = q{range_=restrictRange m r } nodeRestrictRange m q@ReadPlan{range_=r} = q{range_= convertToLimitZeroRange r (restrictRange m r) }
-- add relationships to the nodes of the tree by traversing the forest while keeping track of the parentNode(https://stackoverflow.com/questions/22721064/get-the-parent-of-a-node-in-data-tree-haskell#comment34627048_22721064) -- add relationships to the nodes of the tree by traversing the forest while keeping track of the parentNode(https://stackoverflow.com/questions/22721064/get-the-parent-of-a-node-in-data-tree-haskell#comment34627048_22721064)
-- also adds aliasing -- also adds aliasing
+7
View File
@@ -12,6 +12,7 @@ module PostgREST.RangeQuery (
, allRange , allRange
, limitZeroRange , limitZeroRange
, hasLimitZero , hasLimitZero
, convertToLimitZeroRange
, NonnegRange , NonnegRange
, rangeStatusHeader , rangeStatusHeader
, contentRangeH , contentRangeH
@@ -86,6 +87,12 @@ limitZeroRange = Range (BoundaryBelow 0) (BoundaryAbove (-1))
hasLimitZero :: Range Integer -> Bool hasLimitZero :: Range Integer -> Bool
hasLimitZero r = rangeUpper r == rangeUpper limitZeroRange hasLimitZero r = rangeUpper r == rangeUpper limitZeroRange
-- Used to convert a range into a special limitZeroRange if it has a
-- limit=0 in order to bypass validations for empty ranges.
convertToLimitZeroRange :: Range Integer -> Range Integer -> Range Integer
convertToLimitZeroRange range fallbackRange =
if hasLimitZero range then limitZeroRange else fallbackRange
rangeStatusHeader :: NonnegRange -> Int64 -> Maybe Int64 -> (Status, Header) rangeStatusHeader :: NonnegRange -> Int64 -> Maybe Int64 -> (Status, Header)
rangeStatusHeader topLevelRange queryTotal tableTotal = rangeStatusHeader topLevelRange queryTotal tableTotal =
let lower = rangeOffset topLevelRange let lower = rangeOffset topLevelRange
@@ -114,3 +114,10 @@ spec =
{ "first_name": "Daniel B.", "last_name": "Lyon" }, { "first_name": "Daniel B.", "last_name": "Lyon" },
{ "first_name": "Edwin S.", "last_name": "Smith" } ]|] { "first_name": "Edwin S.", "last_name": "Smith" } ]|]
{ matchStatus = 200 } { matchStatus = 200 }
context "max-rows is set and limits are requested" $ do
it "should work with limit 0" $
get "/items?limit=0"
`shouldRespondWith`
[json| [] |]
{ matchHeaders = ["Content-Range" <:> "*/*"] }