mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 09:22:43 +03:00
Adds an agent test for ordering by a single column aggregate function
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/7820 GitOrigin-RevId: 8455c2ba032173ade474f2744b43d1259f88c9b2
This commit is contained in:
parent
f1091a9aff
commit
2e8fc69394
@ -25,6 +25,7 @@ module Test.Data
|
|||||||
_ColumnFieldNumber,
|
_ColumnFieldNumber,
|
||||||
_ColumnFieldString,
|
_ColumnFieldString,
|
||||||
_ColumnFieldBoolean,
|
_ColumnFieldBoolean,
|
||||||
|
_ColumnFieldNull,
|
||||||
_RelationshipFieldRows,
|
_RelationshipFieldRows,
|
||||||
orderByColumn,
|
orderByColumn,
|
||||||
)
|
)
|
||||||
@ -36,7 +37,7 @@ import Control.Arrow (first, (>>>))
|
|||||||
import Control.Lens (Index, IxValue, Ixed, Traversal', ix, lens, (%~), (&), (^.), (^..), (^?), _Just)
|
import Control.Lens (Index, IxValue, Ixed, Traversal', ix, lens, (%~), (&), (^.), (^..), (^?), _Just)
|
||||||
import Data.Aeson (eitherDecodeStrict)
|
import Data.Aeson (eitherDecodeStrict)
|
||||||
import Data.Aeson qualified as J
|
import Data.Aeson qualified as J
|
||||||
import Data.Aeson.Lens (_Bool, _Number, _String)
|
import Data.Aeson.Lens (_Bool, _Null, _Number, _String)
|
||||||
import Data.Bifunctor (bimap)
|
import Data.Bifunctor (bimap)
|
||||||
import Data.ByteString (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
import Data.ByteString.Lazy qualified as BSL
|
import Data.ByteString.Lazy qualified as BSL
|
||||||
@ -518,6 +519,9 @@ _ColumnFieldString = API._ColumnFieldValue . _String
|
|||||||
_ColumnFieldBoolean :: Traversal' API.FieldValue Bool
|
_ColumnFieldBoolean :: Traversal' API.FieldValue Bool
|
||||||
_ColumnFieldBoolean = API._ColumnFieldValue . _Bool
|
_ColumnFieldBoolean = API._ColumnFieldValue . _Bool
|
||||||
|
|
||||||
|
_ColumnFieldNull :: Traversal' API.FieldValue ()
|
||||||
|
_ColumnFieldNull = API._ColumnFieldValue . _Null
|
||||||
|
|
||||||
_RelationshipFieldRows :: Traversal' API.FieldValue [HashMap API.FieldName API.FieldValue]
|
_RelationshipFieldRows :: Traversal' API.FieldValue [HashMap API.FieldName API.FieldValue]
|
||||||
_RelationshipFieldRows = API._RelationshipFieldValue . API.qrRows . _Just
|
_RelationshipFieldRows = API._RelationshipFieldValue . API.qrRows . _Just
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
|
|
||||||
module Test.Specs.QuerySpec.OrderBySpec (spec) where
|
module Test.Specs.QuerySpec.OrderBySpec (spec) where
|
||||||
|
|
||||||
import Control.Arrow ((>>>))
|
import Control.Arrow ((>>>))
|
||||||
@ -12,6 +14,7 @@ import Data.List.NonEmpty qualified as NonEmpty
|
|||||||
import Data.Maybe (fromMaybe, isJust)
|
import Data.Maybe (fromMaybe, isJust)
|
||||||
import Data.Ord (Down (..))
|
import Data.Ord (Down (..))
|
||||||
import Hasura.Backends.DataConnector.API
|
import Hasura.Backends.DataConnector.API
|
||||||
|
import Language.GraphQL.Draft.Syntax.QQ qualified as G
|
||||||
import Test.AgentAPI (queryGuarded)
|
import Test.AgentAPI (queryGuarded)
|
||||||
import Test.Data (TestData (..))
|
import Test.Data (TestData (..))
|
||||||
import Test.Data qualified as Data
|
import Test.Data qualified as Data
|
||||||
@ -357,6 +360,49 @@ spec TestData {..} Capabilities {..} = describe "Order By in Queries" $ do
|
|||||||
|
|
||||||
Data.responseRows receivedAlbums `rowsShouldBe` expectedArtists
|
Data.responseRows receivedAlbums `rowsShouldBe` expectedArtists
|
||||||
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
|
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
|
||||||
|
|
||||||
|
it "can order results by an aggregate function applied to a column of a related table" $ do
|
||||||
|
-- Order artists by their highest album id descending, but only artists that have any albums
|
||||||
|
let orderByRelations =
|
||||||
|
HashMap.fromList
|
||||||
|
[ ( _tdAlbumsRelationshipName,
|
||||||
|
OrderByRelation
|
||||||
|
Nothing
|
||||||
|
mempty
|
||||||
|
)
|
||||||
|
]
|
||||||
|
let orderBy =
|
||||||
|
OrderBy orderByRelations $
|
||||||
|
NonEmpty.fromList
|
||||||
|
[ OrderByElement [_tdAlbumsRelationshipName] (orderBySingleColumnAggregateMax (_tdColumnName "AlbumId") albumIdNameScalarType) Descending
|
||||||
|
]
|
||||||
|
let whereExp =
|
||||||
|
Exists
|
||||||
|
(RelatedTable _tdAlbumsRelationshipName)
|
||||||
|
(Not $ ApplyUnaryComparisonOperator IsNull (_tdCurrentComparisonColumn "AlbumId" albumIdNameScalarType))
|
||||||
|
let query =
|
||||||
|
artistsQueryRequest
|
||||||
|
& qrQuery . qOrderBy ?~ orderBy
|
||||||
|
& qrQuery . qWhere ?~ whereExp
|
||||||
|
& qrTableRelationships
|
||||||
|
.~ [ Data.onlyKeepRelationships [_tdAlbumsRelationshipName] _tdArtistsTableRelationships
|
||||||
|
]
|
||||||
|
receivedArtists <- queryGuarded query
|
||||||
|
|
||||||
|
let findRelatedAlbums (artist :: HashMap FieldName FieldValue) = fromMaybe [] do
|
||||||
|
artistId <- artist ^? Data.field "ArtistId" . Data._ColumnFieldNumber
|
||||||
|
pure $ filter (\album -> album ^? Data.field "ArtistId" . Data._ColumnFieldNumber == Just artistId) _tdAlbumsRows
|
||||||
|
|
||||||
|
let expectedArtists =
|
||||||
|
_tdArtistsRows
|
||||||
|
& fmap (\artist -> (artist, findRelatedAlbums artist))
|
||||||
|
& filter (\(_artist, albums) -> any (\album -> album ^? Data.field "AlbumId" . Data._ColumnFieldNull /= Just ()) albums)
|
||||||
|
& fmap (\(artist, albums) -> (artist, maximum $ (albums & fmap (\album -> album ^? Data.field "AlbumId" . Data._ColumnFieldNumber))))
|
||||||
|
& sortOn (\row -> (Down (row ^. _2)))
|
||||||
|
& fmap (^. _1)
|
||||||
|
|
||||||
|
Data.responseRows receivedArtists `rowsShouldBe` expectedArtists
|
||||||
|
_qrAggregates receivedArtists `jsonShouldBe` Nothing
|
||||||
where
|
where
|
||||||
albumsQuery :: Query
|
albumsQuery :: Query
|
||||||
albumsQuery =
|
albumsQuery =
|
||||||
@ -388,7 +434,11 @@ spec TestData {..} Capabilities {..} = describe "Order By in Queries" $ do
|
|||||||
query = Data.emptyQuery & qFields ?~ fields
|
query = Data.emptyQuery & qFields ?~ fields
|
||||||
in QueryRequest _tdInvoicesTableName [] query
|
in QueryRequest _tdInvoicesTableName [] query
|
||||||
|
|
||||||
|
orderBySingleColumnAggregateMax :: ColumnName -> ScalarType -> OrderByTarget
|
||||||
|
orderBySingleColumnAggregateMax columnName resultType = OrderBySingleColumnAggregate $ SingleColumnAggregate (SingleColumnAggregateFunction [G.name|max|]) columnName resultType
|
||||||
|
|
||||||
albumTitleScalarType = _tdFindColumnScalarType _tdAlbumsTableName "Title"
|
albumTitleScalarType = _tdFindColumnScalarType _tdAlbumsTableName "Title"
|
||||||
|
albumIdNameScalarType = _tdFindColumnScalarType _tdAlbumsTableName "AlbumId"
|
||||||
artistNameScalarType = _tdFindColumnScalarType _tdArtistsTableName "Name"
|
artistNameScalarType = _tdFindColumnScalarType _tdArtistsTableName "Name"
|
||||||
|
|
||||||
data NullableOrdered a
|
data NullableOrdered a
|
||||||
|
Loading…
Reference in New Issue
Block a user