feat: Allow limit=0 in query params to return an empty array

This commit is contained in:
Laurence Isla
2022-04-28 17:14:29 -05:00
committed by GitHub
parent d2aa50be52
commit 5ad8800773
4 changed files with 27 additions and 7 deletions
+11
View File
@@ -10,6 +10,8 @@ module PostgREST.RangeQuery (
, restrictRange
, rangeGeq
, allRange
, limitZeroRange
, hasLimitZero
, NonnegRange
, rangeStatusHeader
, contentRangeH
@@ -74,6 +76,15 @@ rangeLeq :: Integer -> NonnegRange
rangeLeq n =
Range BoundaryBelowAll (BoundaryAbove n)
-- Special case to allow limit 0 queries
-- https://github.com/PostgREST/postgrest/issues/1121
-- 0 <= x <= -1
limitZeroRange :: Range Integer
limitZeroRange = Range (BoundaryBelow 0) (BoundaryAbove (-1))
hasLimitZero :: Range Integer -> Bool
hasLimitZero r = rangeUpper r == rangeUpper limitZeroRange
rangeStatusHeader :: NonnegRange -> Int64 -> Maybe Int64 -> (Status, Header)
rangeStatusHeader topLevelRange queryTotal tableTotal =
let lower = rangeOffset topLevelRange
+10 -2
View File
@@ -50,6 +50,8 @@ import PostgREST.DbStructure.Identifiers (FieldName,
import PostgREST.DbStructure.Proc (ProcDescription (..),
ProcParam (..), ProcsMap)
import PostgREST.RangeQuery (NonnegRange, allRange,
hasLimitZero,
limitZeroRange,
rangeRequested)
import PostgREST.Request.Preferences (PreferCount (..),
PreferParameters (..),
@@ -180,7 +182,7 @@ apiRequest :: AppConfig -> DbStructure -> Request -> RequestBody -> QueryParams.
apiRequest conf@AppConfig{..} dbStructure req reqBody queryparams@QueryParams{..}
| isJust profile && fromJust profile `notElem` configDbSchemas = Left $ UnacceptableSchema $ toList configDbSchemas
| isTargetingProc && method `notElem` ["HEAD", "GET", "POST"] = Left ActionInappropriate
| topLevelRange == emptyRange = Left InvalidRange
| isInvalidRange = Left InvalidRange
| shouldParsePayload && isLeft payload = either (Left . InvalidBody) witness payload
| not expectParams && not (L.null qsParams) = Left $ ParseRequestError "Unexpected param or filter missing operator" ("Failed to parse " <> show qsParams)
| otherwise = do
@@ -330,8 +332,14 @@ apiRequest conf@AppConfig{..} dbStructure req reqBody queryparams@QueryParams{..
lookupHeader = flip lookup hdrs
Preferences.Preferences{..} = Preferences.fromHeaders hdrs
headerRange = rangeRequested hdrs
limitRange = fromMaybe allRange (M.lookup "limit" qsRanges)
headerAndLimitRange = rangeIntersection headerRange limitRange
ranges = M.insert "limit" (rangeIntersection headerRange (fromMaybe allRange (M.lookup "limit" qsRanges))) qsRanges
-- 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)
ranges = M.insert "limit" (if hasLimitZero limitRange then limitZeroRange else headerAndLimitRange) qsRanges
-- The only emptyRange allowed is the limit zero range
isInvalidRange = topLevelRange == emptyRange && not (hasLimitZero limitRange)
{-|
Find the best match from a list of content types accepted by the