From 191601f1296efe1b09dc13973a67af1a4f12ead7 Mon Sep 17 00:00:00 2001 From: SteveBash Date: Wed, 5 Oct 2016 14:46:12 -0500 Subject: [PATCH] Add ability to order by jsonb keys, fix #644 --- CHANGELOG.md | 1 + src/PostgREST/Parsers.hs | 4 ++-- src/PostgREST/QueryBuilder.hs | 2 +- src/PostgREST/Types.hs | 2 +- test/Feature/QuerySpec.hs | 8 ++++++++ test/fixtures/data.sql | 2 ++ 6 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2a2824bb..71cb84819 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Implement support for singular representation responses for POST/PATCH requests - @ehamberg - Include RPC endpoints in OpenAPI output - @begriffs, @LogvinovLeon - Custom request validation with `--pre-request` argument - @begriffs +- Ability to order by jsonb keys - @steve-chavez ### Fixed - Do not apply limit to parent items - @ruslantalpa diff --git a/src/PostgREST/Parsers.hs b/src/PostgREST/Parsers.hs index 4b5d6af8c..b9d56c642 100644 --- a/src/PostgREST/Parsers.hs +++ b/src/PostgREST/Parsers.hs @@ -136,7 +136,7 @@ pOrder = lexeme pOrderTerm `sepBy` char ',' pOrderTerm :: Parser OrderTerm pOrderTerm = try ( do - c <- pFieldName + c <- pField d <- optionMaybe (try $ pDelimiter *> ( try(string "asc" *> pure OrderAsc) <|> try(string "desc" *> pure OrderDesc) @@ -147,4 +147,4 @@ pOrderTerm = )) return $ OrderTerm c d nls ) - <|> OrderTerm <$> (toS <$> pFieldName) <*> pure Nothing <*> pure Nothing + <|> OrderTerm <$> pField <*> pure Nothing <*> pure Nothing diff --git a/src/PostgREST/QueryBuilder.hs b/src/PostgREST/QueryBuilder.hs index 438b997c1..61f71a85d 100644 --- a/src/PostgREST/QueryBuilder.hs +++ b/src/PostgREST/QueryBuilder.hs @@ -306,7 +306,7 @@ requestToQuery schema isParent (DbRead (Node (Select colSelects tbls conditions clause = intercalate "," (map queryTerm ts) queryTerm :: OrderTerm -> Text queryTerm t = " " - <> toS (pgFmtColumn qi $ otTerm t) <> " " + <> toS (pgFmtField qi $ otTerm t) <> " " <> maybe "" show (otDirection t) <> " " <> maybe "" show (otNullOrder t) <> " " (joins, selects) = foldr getQueryParts ([],[]) forest diff --git a/src/PostgREST/Types.hs b/src/PostgREST/Types.hs index 337ee6bfe..44439af38 100644 --- a/src/PostgREST/Types.hs +++ b/src/PostgREST/Types.hs @@ -77,7 +77,7 @@ instance Show OrderNulls where show OrderNullsLast = "nulls last" data OrderTerm = OrderTerm { - otTerm :: Text + otTerm :: Field , otDirection :: Maybe OrderDirection , otNullOrder :: Maybe OrderNulls } deriving (Show, Eq) diff --git a/test/Feature/QuerySpec.hs b/test/Feature/QuerySpec.hs index 1be41c015..a92e9525e 100644 --- a/test/Feature/QuerySpec.hs +++ b/test/Feature/QuerySpec.hs @@ -374,6 +374,14 @@ spec = do , matchHeaders = ["Content-Range" <:> "0-2/*"] } + it "by a json column property asc" $ + get "/json?order=data->>id.asc" `shouldRespondWith` + [json| [{"data": {"id": 0}}, {"data": {"id": 1, "foo": {"bar": "baz"}}}, {"data": {"id": 3}}] |] + + it "by a json column with two level property nulls first" $ + get "/json?order=data->foo->>bar.nullsfirst" `shouldRespondWith` + [json| [{"data": {"id": 3}}, {"data": {"id": 0}}, {"data": {"id": 1, "foo": {"bar": "baz"}}}] |] + it "without other constraints" $ get "/items?order=id.asc" `shouldRespondWith` 200 diff --git a/test/fixtures/data.sql b/test/fixtures/data.sql index 59aa2c357..11dd34f1a 100644 --- a/test/fixtures/data.sql +++ b/test/fixtures/data.sql @@ -213,6 +213,8 @@ SELECT pg_catalog.setval('items_id_seq', 15, true); TRUNCATE TABLE json CASCADE; INSERT INTO json VALUES ('{"foo":{"bar":"baz"},"id":1}'); +INSERT INTO json VALUES ('{"id":3}'); +INSERT INTO json VALUES ('{"id":0}'); --