mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 09:22:43 +03:00
Define IR types for AggregationPredicates.
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5258 GitOrigin-RevId: 172b9de69f44635c5700b3f75ce17304ec56c18a
This commit is contained in:
parent
6040cb065e
commit
0e921ca9a5
@ -443,6 +443,7 @@ library
|
||||
, Hasura.Backends.BigQuery.Instances.API
|
||||
, Hasura.Backends.BigQuery.Instances.Execute
|
||||
, Hasura.Backends.BigQuery.Instances.Schema
|
||||
, Hasura.Backends.BigQuery.Instances.SchemaCache
|
||||
, Hasura.Backends.BigQuery.Instances.Transport
|
||||
, Hasura.Backends.BigQuery.Instances.Types
|
||||
, Hasura.Backends.BigQuery.Instances.Metadata
|
||||
@ -477,6 +478,7 @@ library
|
||||
, Hasura.Backends.MSSQL.Instances.Execute
|
||||
, Hasura.Backends.MSSQL.Instances.Metadata
|
||||
, Hasura.Backends.MSSQL.Instances.Schema
|
||||
, Hasura.Backends.MSSQL.Instances.SchemaCache
|
||||
, Hasura.Backends.MSSQL.Instances.Transport
|
||||
, Hasura.Backends.MSSQL.Instances.Types
|
||||
, Hasura.Backends.MSSQL.Meta
|
||||
@ -512,6 +514,7 @@ library
|
||||
, Hasura.Backends.Postgres.Instances.Execute
|
||||
, Hasura.Backends.Postgres.Instances.Metadata
|
||||
, Hasura.Backends.Postgres.Instances.Schema
|
||||
, Hasura.Backends.Postgres.Instances.SchemaCache
|
||||
, Hasura.Backends.Postgres.Instances.Transport
|
||||
, Hasura.Backends.Postgres.Instances.Types
|
||||
, Hasura.Backends.Postgres.Schema.OnConflict
|
||||
@ -563,6 +566,7 @@ library
|
||||
, Hasura.Backends.MySQL.Instances.Types
|
||||
, Hasura.Backends.MySQL.Instances.Metadata
|
||||
, Hasura.Backends.MySQL.Instances.Schema
|
||||
, Hasura.Backends.MySQL.Instances.SchemaCache
|
||||
, Hasura.Backends.MySQL.Instances.Execute
|
||||
, Hasura.Backends.MySQL.Instances.Transport
|
||||
, Hasura.Backends.MySQL.SQL
|
||||
@ -576,6 +580,7 @@ library
|
||||
, Hasura.Backends.DataConnector.Adapter.ConfigTransform
|
||||
, Hasura.Backends.DataConnector.Adapter.Metadata
|
||||
, Hasura.Backends.DataConnector.Adapter.Schema
|
||||
, Hasura.Backends.DataConnector.Adapter.SchemaCache
|
||||
, Hasura.Backends.DataConnector.Adapter.Transport
|
||||
, Hasura.Backends.DataConnector.Adapter.Types
|
||||
, Hasura.Backends.DataConnector.Agent.Client
|
||||
@ -697,7 +702,9 @@ library
|
||||
, Hasura.RQL.Types.Roles.Internal
|
||||
, Hasura.RQL.Types.ScheduledTrigger
|
||||
, Hasura.RQL.Types.SchemaCache
|
||||
, Hasura.RQL.Types.SchemaCache.AggregationPredicates
|
||||
, Hasura.RQL.Types.SchemaCache.Build
|
||||
, Hasura.RQL.Types.SchemaCache.Instances
|
||||
, Hasura.RQL.Types.SchemaCacheTypes
|
||||
, Hasura.RQL.Types.Source
|
||||
, Hasura.RQL.Types.SourceCustomization
|
||||
@ -758,6 +765,7 @@ library
|
||||
, Hasura.RQL.DML.Types
|
||||
, Hasura.RQL.IR.Action
|
||||
, Hasura.RQL.IR.BoolExp
|
||||
, Hasura.RQL.IR.BoolExp.AggregationPredicates
|
||||
, Hasura.RQL.IR.Conflict
|
||||
, Hasura.RQL.IR.Delete
|
||||
, Hasura.RQL.IR.Insert
|
||||
|
@ -0,0 +1,12 @@
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
{-# OPTIONS_GHC -Wno-orphans #-}
|
||||
|
||||
-- This module houses type class instances on the BigQuery backend that relate
|
||||
-- to the Schema Cache.
|
||||
module Hasura.Backends.BigQuery.Instances.SchemaCache () where
|
||||
|
||||
import Hasura.RQL.Types.Backend
|
||||
import Hasura.RQL.Types.SchemaCacheTypes (GetAggregationPredicatesDeps)
|
||||
import Hasura.SQL.Backend (BackendType (BigQuery))
|
||||
|
||||
instance (Backend 'BigQuery) => GetAggregationPredicatesDeps 'BigQuery
|
@ -0,0 +1,12 @@
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
{-# OPTIONS_GHC -Wno-orphans #-}
|
||||
|
||||
-- This module houses type class instances on the DataConnector backends that relate
|
||||
-- to the Schema Cache.
|
||||
module Hasura.Backends.DataConnector.Adapter.SchemaCache () where
|
||||
|
||||
import Hasura.RQL.Types.Backend
|
||||
import Hasura.RQL.Types.SchemaCacheTypes (GetAggregationPredicatesDeps)
|
||||
import Hasura.SQL.Backend (BackendType (DataConnector))
|
||||
|
||||
instance (Backend 'DataConnector) => GetAggregationPredicatesDeps 'DataConnector
|
@ -0,0 +1,12 @@
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
{-# OPTIONS_GHC -Wno-orphans #-}
|
||||
|
||||
-- This module houses type class instances on the MSSQL backend that relate
|
||||
-- to the Schema Cache.
|
||||
module Hasura.Backends.MSSQL.Instances.SchemaCache () where
|
||||
|
||||
import Hasura.RQL.Types.Backend
|
||||
import Hasura.RQL.Types.SchemaCacheTypes (GetAggregationPredicatesDeps)
|
||||
import Hasura.SQL.Backend (BackendType (MSSQL))
|
||||
|
||||
instance (Backend 'MSSQL) => GetAggregationPredicatesDeps 'MSSQL
|
@ -0,0 +1,12 @@
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
{-# OPTIONS_GHC -Wno-orphans #-}
|
||||
|
||||
-- This module houses type class instances on the MySQL backend that relate
|
||||
-- to the Schema Cache.
|
||||
module Hasura.Backends.MySQL.Instances.SchemaCache () where
|
||||
|
||||
import Hasura.RQL.Types.Backend
|
||||
import Hasura.RQL.Types.SchemaCacheTypes (GetAggregationPredicatesDeps)
|
||||
import Hasura.SQL.Backend (BackendType (MySQL))
|
||||
|
||||
instance (Backend 'MySQL) => GetAggregationPredicatesDeps 'MySQL
|
@ -0,0 +1,12 @@
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
{-# OPTIONS_GHC -Wno-orphans #-}
|
||||
|
||||
-- This module houses type class instances on the Postgres backends that relate
|
||||
-- to the Schema Cache.
|
||||
module Hasura.Backends.Postgres.Instances.SchemaCache () where
|
||||
|
||||
import Hasura.RQL.Types.Backend
|
||||
import Hasura.RQL.Types.SchemaCacheTypes (GetAggregationPredicatesDeps)
|
||||
import Hasura.SQL.Backend (BackendType (Postgres))
|
||||
|
||||
instance (Backend ('Postgres pgKind)) => GetAggregationPredicatesDeps ('Postgres pgKind)
|
@ -25,7 +25,7 @@ import Hasura.RQL.Types.Common
|
||||
import Hasura.RQL.Types.Function
|
||||
import Hasura.RQL.Types.Metadata.Backend
|
||||
import Hasura.RQL.Types.Relationships.Local
|
||||
import Hasura.RQL.Types.SchemaCache
|
||||
import Hasura.RQL.Types.SchemaCache hiding (BoolExpCtx (..), BoolExpM (..))
|
||||
import Hasura.RQL.Types.Table
|
||||
import Hasura.SQL.Backend
|
||||
import Hasura.SQL.Types
|
||||
|
@ -52,6 +52,7 @@ import Hasura.RQL.Types.Permission
|
||||
import Hasura.RQL.Types.Relationships.Local
|
||||
import Hasura.RQL.Types.SchemaCache
|
||||
import Hasura.RQL.Types.SchemaCache.Build
|
||||
import Hasura.RQL.Types.SchemaCacheTypes
|
||||
import Hasura.RQL.Types.Table
|
||||
import Hasura.SQL.AnyBackend qualified as AB
|
||||
import Hasura.SQL.Types
|
||||
@ -213,7 +214,11 @@ addPermissionToMetadata permDef = case _pdPermission permDef of
|
||||
DelPerm' _ -> tmDeletePermissions %~ OMap.insert (_pdRole permDef) permDef
|
||||
|
||||
buildPermInfo ::
|
||||
(BackendMetadata b, QErrM m, TableCoreInfoRM b m) =>
|
||||
( BackendMetadata b,
|
||||
QErrM m,
|
||||
TableCoreInfoRM b m,
|
||||
GetAggregationPredicatesDeps b
|
||||
) =>
|
||||
SourceName ->
|
||||
TableName b ->
|
||||
FieldInfoMap (FieldInfo b) ->
|
||||
@ -292,7 +297,11 @@ runDropPerm permType (DropPerm source table role) = do
|
||||
|
||||
buildInsPermInfo ::
|
||||
forall b m.
|
||||
(QErrM m, TableCoreInfoRM b m, BackendMetadata b) =>
|
||||
( QErrM m,
|
||||
TableCoreInfoRM b m,
|
||||
BackendMetadata b,
|
||||
GetAggregationPredicatesDeps b
|
||||
) =>
|
||||
SourceName ->
|
||||
TableName b ->
|
||||
FieldInfoMap (FieldInfo b) ->
|
||||
@ -394,7 +403,11 @@ validateAllowedRootFields sourceName tableName roleName streamSubsCtx SelPerm {.
|
||||
|
||||
buildSelPermInfo ::
|
||||
forall b m.
|
||||
(QErrM m, TableCoreInfoRM b m, BackendMetadata b) =>
|
||||
( QErrM m,
|
||||
TableCoreInfoRM b m,
|
||||
BackendMetadata b,
|
||||
GetAggregationPredicatesDeps b
|
||||
) =>
|
||||
SourceName ->
|
||||
TableName b ->
|
||||
FieldInfoMap (FieldInfo b) ->
|
||||
@ -455,7 +468,11 @@ buildSelPermInfo source tableName fieldInfoMap roleName streamSubsCtx sp = withP
|
||||
|
||||
buildUpdPermInfo ::
|
||||
forall b m.
|
||||
(QErrM m, TableCoreInfoRM b m, BackendMetadata b) =>
|
||||
( QErrM m,
|
||||
TableCoreInfoRM b m,
|
||||
BackendMetadata b,
|
||||
GetAggregationPredicatesDeps b
|
||||
) =>
|
||||
SourceName ->
|
||||
TableName b ->
|
||||
FieldInfoMap (FieldInfo b) ->
|
||||
@ -498,7 +515,11 @@ buildUpdPermInfo source tn fieldInfoMap (UpdPerm colSpec set fltr check backendO
|
||||
|
||||
buildDelPermInfo ::
|
||||
forall b m.
|
||||
(QErrM m, TableCoreInfoRM b m, BackendMetadata b) =>
|
||||
( QErrM m,
|
||||
TableCoreInfoRM b m,
|
||||
BackendMetadata b,
|
||||
GetAggregationPredicatesDeps b
|
||||
) =>
|
||||
SourceName ->
|
||||
TableName b ->
|
||||
FieldInfoMap (FieldInfo b) ->
|
||||
|
@ -30,6 +30,7 @@ import Hasura.RQL.Types.Metadata.Backend
|
||||
import Hasura.RQL.Types.Permission
|
||||
import Hasura.RQL.Types.Relationships.Local
|
||||
import Hasura.RQL.Types.SchemaCache
|
||||
import Hasura.RQL.Types.SchemaCacheTypes
|
||||
import Hasura.RQL.Types.Table
|
||||
import Hasura.Server.Utils
|
||||
import Hasura.Session
|
||||
@ -78,7 +79,11 @@ data CreatePermP1Res a = CreatePermP1Res
|
||||
deriving (Show, Eq)
|
||||
|
||||
procBoolExp ::
|
||||
(QErrM m, TableCoreInfoRM b m, BackendMetadata b) =>
|
||||
( QErrM m,
|
||||
TableCoreInfoRM b m,
|
||||
BackendMetadata b,
|
||||
GetAggregationPredicatesDeps b
|
||||
) =>
|
||||
SourceName ->
|
||||
TableName b ->
|
||||
FieldInfoMap (FieldInfo b) ->
|
||||
|
@ -82,6 +82,7 @@ import Hasura.RQL.Types.Roles.Internal (CheckPermission (..))
|
||||
import Hasura.RQL.Types.ScheduledTrigger
|
||||
import Hasura.RQL.Types.SchemaCache
|
||||
import Hasura.RQL.Types.SchemaCache.Build
|
||||
import Hasura.RQL.Types.SchemaCache.Instances ()
|
||||
import Hasura.RQL.Types.SchemaCacheTypes
|
||||
import Hasura.RQL.Types.Source
|
||||
import Hasura.RQL.Types.SourceCustomization
|
||||
@ -477,7 +478,8 @@ buildSchemaCacheRule logger env = proc (metadata, invalidationKeys) -> do
|
||||
ArrowWriter (Seq CollectedInfo) arr,
|
||||
HasServerConfigCtx m,
|
||||
MonadError QErr m,
|
||||
BackendMetadata b
|
||||
BackendMetadata b,
|
||||
GetAggregationPredicatesDeps b
|
||||
) =>
|
||||
( HashMap SourceName (AB.AnyBackend PartiallyResolvedSource),
|
||||
SourceMetadata b,
|
||||
@ -710,7 +712,13 @@ buildSchemaCacheRule logger env = proc (metadata, invalidationKeys) -> do
|
||||
(|
|
||||
Inc.keyed
|
||||
( \_ exists ->
|
||||
AB.dispatchAnyBackendArrow @BackendMetadata @BackendMetadata
|
||||
-- Note that it's a bit of a coincidence that
|
||||
-- 'AB.dispatchAnyBackendArrow' accepts exactly two constraints,
|
||||
-- and that we happen to want to apply to exactly two
|
||||
-- constraints.
|
||||
-- Ideally the function should be able to take an arbitrary
|
||||
-- number of constraints.
|
||||
AB.dispatchAnyBackendArrow @BackendMetadata @GetAggregationPredicatesDeps
|
||||
( proc
|
||||
( partiallyResolvedSource :: PartiallyResolvedSource b,
|
||||
(allResolvedSources, remoteSchemaCtxMap, orderedRoles)
|
||||
|
@ -208,7 +208,8 @@ buildTablePermissions ::
|
||||
ArrowWriter (Seq CollectedInfo) arr,
|
||||
BackendMetadata b,
|
||||
HasServerConfigCtx m,
|
||||
Inc.Cacheable (Proxy b)
|
||||
Inc.Cacheable (Proxy b),
|
||||
GetAggregationPredicatesDeps b
|
||||
) =>
|
||||
( Proxy b,
|
||||
SourceName,
|
||||
@ -334,7 +335,8 @@ buildPermission ::
|
||||
Inc.Cacheable (Proxy b),
|
||||
MonadError QErr m,
|
||||
HasServerConfigCtx m,
|
||||
BackendMetadata b
|
||||
BackendMetadata b,
|
||||
GetAggregationPredicatesDeps b
|
||||
) =>
|
||||
( Proxy b,
|
||||
Inc.Dependency (TableCoreCache b),
|
||||
|
@ -501,21 +501,24 @@ instance
|
||||
) =>
|
||||
Hashable (AnnComputedFieldBoolExp b a)
|
||||
|
||||
-- | This type is used for boolean terms in GBoolExp in the schema; there are two kinds boolean
|
||||
-- | This type is used for boolean terms in GBoolExp in the schema; there are four kinds boolean
|
||||
-- terms:
|
||||
-- - operators on a column of the current table, using the 'OpExpG' kind of operators
|
||||
-- - arbitrary expressions on columns of tables in relationships (in the same source)
|
||||
-- - A computed field of the current table
|
||||
-- - aggregation operations on array relationships on the current tables.
|
||||
--
|
||||
-- This type is parameterized over the type of leaf values, the values on which we operate.
|
||||
data AnnBoolExpFld (backend :: BackendType) leaf
|
||||
= AVColumn (ColumnInfo backend) [OpExpG backend leaf]
|
||||
| AVRelationship (RelInfo backend) (AnnBoolExp backend leaf)
|
||||
| AVComputedField (AnnComputedFieldBoolExp backend leaf)
|
||||
| AVAggregationPredicates (AggregationPredicates backend leaf)
|
||||
deriving (Functor, Foldable, Traversable, Generic)
|
||||
|
||||
deriving instance
|
||||
( Backend b,
|
||||
Eq (AggregationPredicates b a),
|
||||
Eq (AnnBoolExp b a),
|
||||
Eq (AnnComputedFieldBoolExp b a),
|
||||
Eq (OpExpG b a)
|
||||
@ -524,6 +527,7 @@ deriving instance
|
||||
|
||||
deriving instance
|
||||
( Backend b,
|
||||
Show (AggregationPredicates b a),
|
||||
Show (AnnBoolExp b a),
|
||||
Show (AnnComputedFieldBoolExp b a),
|
||||
Show (OpExpG b a)
|
||||
@ -532,6 +536,7 @@ deriving instance
|
||||
|
||||
instance
|
||||
( Backend b,
|
||||
NFData (AggregationPredicates b a),
|
||||
NFData (AnnBoolExp b a),
|
||||
NFData (AnnComputedFieldBoolExp b a),
|
||||
NFData (OpExpG b a)
|
||||
@ -540,6 +545,7 @@ instance
|
||||
|
||||
instance
|
||||
( Backend b,
|
||||
Cacheable (AggregationPredicates b a),
|
||||
Cacheable (AnnBoolExp b a),
|
||||
Cacheable (AnnComputedFieldBoolExp b a),
|
||||
Cacheable (OpExpG b a)
|
||||
@ -548,6 +554,7 @@ instance
|
||||
|
||||
instance
|
||||
( Backend b,
|
||||
Hashable (AggregationPredicates b a),
|
||||
Hashable (AnnBoolExp b a),
|
||||
Hashable (AnnComputedFieldBoolExp b a),
|
||||
Hashable (OpExpG b a)
|
||||
@ -556,6 +563,7 @@ instance
|
||||
|
||||
instance
|
||||
( Backend b,
|
||||
ToJSONKeyValue (AggregationPredicates b a),
|
||||
ToJSONKeyValue (OpExpG b a),
|
||||
ToJSON a
|
||||
) =>
|
||||
@ -577,6 +585,7 @@ instance
|
||||
CFBEScalar opExps -> toJSON (function, object . pure . toJSONKeyValue <$> opExps)
|
||||
CFBETable _ boolExp -> toJSON (function, toJSON boolExp)
|
||||
)
|
||||
AVAggregationPredicates avAggregationPredicates -> toJSONKeyValue avAggregationPredicates
|
||||
|
||||
-- | A simple alias for the kind of boolean expressions used in the schema, that ties together
|
||||
-- 'GBoolExp', 'OpExpG', and 'AnnBoolExpFld'.
|
||||
|
183
server/src-lib/Hasura/RQL/IR/BoolExp/AggregationPredicates.hs
Normal file
183
server/src-lib/Hasura/RQL/IR/BoolExp/AggregationPredicates.hs
Normal file
@ -0,0 +1,183 @@
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
|
||||
-- | This module contains the default types and function that model aggregation
|
||||
-- predicates.
|
||||
module Hasura.RQL.IR.BoolExp.AggregationPredicates
|
||||
( AggregationPredicatesImplementation (..),
|
||||
AggregationPredicate (..),
|
||||
AggregationPredicateArguments (..),
|
||||
)
|
||||
where
|
||||
|
||||
import Data.Aeson
|
||||
import Data.Aeson.Extended (ToJSONKeyValue (..))
|
||||
import Data.Aeson.Key (fromText)
|
||||
import Hasura.Incremental (Cacheable)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.IR.BoolExp (AnnBoolExp, OpExpG)
|
||||
import Hasura.RQL.Types.Backend (Backend (Column))
|
||||
import Hasura.RQL.Types.Backend qualified as B
|
||||
import Hasura.RQL.Types.Relationships.Local (RelInfo)
|
||||
import Hasura.SQL.Backend (BackendType)
|
||||
|
||||
-- | This type the default non-empty implementation of the
|
||||
-- 'AggregationPredicates' type family of 'class Backend'.
|
||||
--
|
||||
-- This represents an _applied_ aggregation predicate, i.e. _not_ an aggegation
|
||||
-- function in isolation.
|
||||
--
|
||||
-- In the default schema implementation, this type results from parsing graphql such as:
|
||||
--
|
||||
-- table(_where(
|
||||
-- <relation>_aggregate:
|
||||
-- {<functionname>: {
|
||||
-- arguments: <arguments>,
|
||||
-- predicate: <predicate>,
|
||||
-- distinct: bool
|
||||
-- }
|
||||
-- }
|
||||
-- ))
|
||||
-- { ... }
|
||||
--
|
||||
-- Note that we make no attemt at modelling window functions or so-called
|
||||
-- 'analytical' functions such as 'percentile_cont'.
|
||||
data AggregationPredicatesImplementation (b :: BackendType) field = AggregationPredicatesImplementation
|
||||
{ aggRelation :: RelInfo b,
|
||||
aggPredicates :: [AggregationPredicate b field]
|
||||
}
|
||||
deriving stock (Foldable, Traversable, Functor, Generic)
|
||||
|
||||
deriving instance
|
||||
( B.Backend b,
|
||||
Eq (AggregationPredicate b field)
|
||||
) =>
|
||||
Eq (AggregationPredicatesImplementation b field)
|
||||
|
||||
deriving instance
|
||||
( B.Backend b,
|
||||
Show (AggregationPredicate b field)
|
||||
) =>
|
||||
Show (AggregationPredicatesImplementation b field)
|
||||
|
||||
instance
|
||||
( B.Backend b,
|
||||
Cacheable (AggregationPredicate b field)
|
||||
) =>
|
||||
Cacheable (AggregationPredicatesImplementation b field)
|
||||
|
||||
instance
|
||||
( B.Backend b,
|
||||
Hashable (AggregationPredicate b field)
|
||||
) =>
|
||||
Hashable (AggregationPredicatesImplementation b field)
|
||||
|
||||
instance
|
||||
( B.Backend b,
|
||||
NFData (AggregationPredicate b field)
|
||||
) =>
|
||||
NFData (AggregationPredicatesImplementation b field)
|
||||
|
||||
instance
|
||||
( ToJSON (AnnBoolExp b field),
|
||||
ToJSON (AggregationPredicate b field),
|
||||
ToJSON (OpExpG b field),
|
||||
B.Backend b
|
||||
) =>
|
||||
ToJSON (AggregationPredicatesImplementation b field)
|
||||
|
||||
instance
|
||||
( Backend b,
|
||||
ToJSONKeyValue (AggregationPredicate b field)
|
||||
) =>
|
||||
ToJSONKeyValue (AggregationPredicatesImplementation b field)
|
||||
where
|
||||
toJSONKeyValue AggregationPredicatesImplementation {..} =
|
||||
( fromText "aggregation_predicates",
|
||||
toJSON
|
||||
[ ("predicates" :: Text, toJSON $ map toJSONKeyValue aggPredicates),
|
||||
("relation", toJSON aggRelation)
|
||||
]
|
||||
)
|
||||
|
||||
data AggregationPredicate (b :: BackendType) field = AggregationPredicate
|
||||
{ aggPredFunctionName :: Text,
|
||||
aggPredDistinct :: Bool,
|
||||
aggPredFilter :: Maybe (AnnBoolExp b field),
|
||||
aggPredArguments :: AggregationPredicateArguments b,
|
||||
aggPredPredicate :: [OpExpG b field]
|
||||
}
|
||||
deriving stock (Foldable, Traversable, Functor, Generic)
|
||||
|
||||
deriving instance
|
||||
( B.Backend b,
|
||||
Eq (AnnBoolExp b field),
|
||||
Eq (OpExpG b field),
|
||||
Eq (AggregationPredicateArguments b)
|
||||
) =>
|
||||
Eq (AggregationPredicate b field)
|
||||
|
||||
deriving instance
|
||||
( B.Backend b,
|
||||
Show (AnnBoolExp b field),
|
||||
Show (OpExpG b field),
|
||||
Show (AggregationPredicateArguments b)
|
||||
) =>
|
||||
Show (AggregationPredicate b field)
|
||||
|
||||
instance
|
||||
( B.Backend b,
|
||||
Hashable (B.BooleanOperators b field),
|
||||
Hashable (AnnBoolExp b field),
|
||||
Hashable field
|
||||
) =>
|
||||
Hashable (AggregationPredicate b field)
|
||||
|
||||
instance
|
||||
( B.Backend b,
|
||||
Cacheable (AggregationPredicateArguments b),
|
||||
Cacheable (AnnBoolExp b field),
|
||||
Cacheable (OpExpG b field)
|
||||
) =>
|
||||
Cacheable (AggregationPredicate b field)
|
||||
|
||||
instance
|
||||
( B.Backend b,
|
||||
NFData (AggregationPredicateArguments b),
|
||||
NFData (AnnBoolExp b field),
|
||||
NFData (OpExpG b field)
|
||||
) =>
|
||||
NFData (AggregationPredicate b field)
|
||||
|
||||
instance
|
||||
( ToJSON (AggregationPredicateArguments b),
|
||||
ToJSON (AnnBoolExp b field),
|
||||
ToJSONKeyValue (OpExpG b field)
|
||||
) =>
|
||||
ToJSONKeyValue (AggregationPredicate b field)
|
||||
where
|
||||
toJSONKeyValue AggregationPredicate {..} =
|
||||
( fromText aggPredFunctionName,
|
||||
toJSON
|
||||
[ ("aggPredDistinct" :: Text, toJSON aggPredDistinct),
|
||||
("aggPredFilter", toJSON aggPredFilter),
|
||||
("aggPredArguments", toJSON aggPredArguments),
|
||||
("aggPredPredicate", toJSON (map toJSONKeyValue aggPredPredicate))
|
||||
]
|
||||
)
|
||||
|
||||
data AggregationPredicateArguments (b :: BackendType)
|
||||
= AggregationPredicateArgumentsStar
|
||||
| AggregationPredicateArguments (NonEmpty (Column b))
|
||||
deriving stock (Generic)
|
||||
|
||||
deriving instance B.Backend b => Eq (AggregationPredicateArguments b)
|
||||
|
||||
deriving instance B.Backend b => Show (AggregationPredicateArguments b)
|
||||
|
||||
instance Backend b => Hashable (AggregationPredicateArguments b)
|
||||
|
||||
instance Backend b => Cacheable (AggregationPredicateArguments b)
|
||||
|
||||
instance Backend b => NFData (AggregationPredicateArguments b)
|
||||
|
||||
instance (Backend b) => ToJSON (AggregationPredicateArguments b)
|
@ -86,7 +86,6 @@ class
|
||||
Ord (FunctionName b),
|
||||
Ord (ScalarType b),
|
||||
Data (TableName b),
|
||||
Traversable (BooleanOperators b),
|
||||
FromJSON (BackendConfig b),
|
||||
FromJSON (Column b),
|
||||
FromJSON (ConstraintName b),
|
||||
@ -152,12 +151,16 @@ class
|
||||
Eq (XStreamingSubscription b),
|
||||
Show (XStreamingSubscription b),
|
||||
-- Intermediate Representations
|
||||
Traversable (BooleanOperators b),
|
||||
Functor (BackendUpdate b),
|
||||
Foldable (BackendUpdate b),
|
||||
Traversable (BackendUpdate b),
|
||||
Functor (BackendInsert b),
|
||||
Foldable (BackendInsert b),
|
||||
Traversable (BackendInsert b)
|
||||
Traversable (BackendInsert b),
|
||||
Functor (AggregationPredicates b),
|
||||
Foldable (AggregationPredicates b),
|
||||
Traversable (AggregationPredicates b)
|
||||
) =>
|
||||
Backend (b :: BackendType)
|
||||
where
|
||||
@ -194,7 +197,6 @@ class
|
||||
type ScalarValue b :: Type
|
||||
type ScalarType b :: Type
|
||||
|
||||
type BooleanOperators b :: Type -> Type
|
||||
type SQLExpression b :: Type
|
||||
type ComputedFieldDefinition b :: Type
|
||||
|
||||
@ -215,6 +217,9 @@ class
|
||||
type FunctionArgument b :: Type
|
||||
|
||||
-- | Function input argument expression
|
||||
--
|
||||
-- It is parameterised over the type of fields, which changes during the IR
|
||||
-- translation phases.
|
||||
type FunctionArgumentExp b :: Type -> Type
|
||||
|
||||
-- | Computed field function argument values which are being implicitly inferred from table and/or session information
|
||||
@ -225,14 +230,36 @@ class
|
||||
|
||||
-- Backend-specific IR types
|
||||
|
||||
-- | Intermediate Representation of extensions to the shared set of boolean
|
||||
-- operators on table fields.
|
||||
--
|
||||
-- It is parameterised over the type of fields, which changes during the IR
|
||||
-- translation phases.
|
||||
type BooleanOperators b :: Type -> Type
|
||||
|
||||
-- | Intermediate Representation of aggregation predicates.
|
||||
-- The default implementation makes aggregation predicates uninstantiable.
|
||||
--
|
||||
-- It is parameterised over the type of fields, which changes during the IR
|
||||
-- translation phases.
|
||||
type AggregationPredicates b :: Type -> Type
|
||||
|
||||
type AggregationPredicates b = Const Void
|
||||
|
||||
-- | Intermediate Representation of Update Mutations.
|
||||
-- The default implementation makes update expressions uninstantiable.
|
||||
--
|
||||
-- It is parameterised over the type of fields, which changes during the IR
|
||||
-- translation phases.
|
||||
type BackendUpdate b :: Type -> Type
|
||||
|
||||
type BackendUpdate b = Const Void
|
||||
|
||||
-- | Intermediate Representation of Insert Mutations.
|
||||
-- The default implementation makes insert expressions uninstantiable.
|
||||
--
|
||||
-- It is parameterised over the type of fields, which changes during the IR
|
||||
-- translation phases.
|
||||
type BackendInsert b :: Type -> Type
|
||||
|
||||
type BackendInsert b = Const Void
|
||||
|
@ -30,8 +30,10 @@ import Network.HTTP.Client qualified as HTTP
|
||||
|
||||
class
|
||||
( Backend b,
|
||||
Eq (AggregationPredicates b (PartialSQLExp b)),
|
||||
Eq (BooleanOperators b (PartialSQLExp b)),
|
||||
Eq (FunctionArgumentExp b (PartialSQLExp b)),
|
||||
Hashable (AggregationPredicates b (PartialSQLExp b)),
|
||||
Hashable (BooleanOperators b (PartialSQLExp b)),
|
||||
Hashable (FunctionArgumentExp b (PartialSQLExp b))
|
||||
) =>
|
||||
|
@ -83,7 +83,6 @@ module Hasura.RQL.Types.SchemaCache
|
||||
getCols,
|
||||
getRels,
|
||||
getComputedFieldInfos,
|
||||
RelInfo (..),
|
||||
RolePermInfoMap,
|
||||
InsPermInfo (..),
|
||||
UpdPermInfo (..),
|
||||
@ -112,6 +111,9 @@ module Hasura.RQL.Types.SchemaCache
|
||||
initialResourceVersion,
|
||||
getBoolExpDeps,
|
||||
InlinedAllowlist,
|
||||
BoolExpM (..),
|
||||
BoolExpCtx (..),
|
||||
getOpExpDeps,
|
||||
)
|
||||
where
|
||||
|
||||
@ -711,21 +713,10 @@ getRemoteDependencies schemaCache sourceName =
|
||||
SORemoteSchemaPermission {} -> False
|
||||
SORole {} -> False
|
||||
|
||||
-- | The table type context of schema dependency discovery. Boolean expressions
|
||||
-- may refer to a so-called 'root table' (identified by a '$'-sign in the
|
||||
-- expression input syntax) or the 'current' table.
|
||||
data BoolExpCtx b = BoolExpCtx
|
||||
{ source :: SourceName,
|
||||
-- | Reference to the 'current' table type.
|
||||
currTable :: TableName b,
|
||||
-- | Reference to the 'root' table type.
|
||||
rootTable :: TableName b
|
||||
}
|
||||
|
||||
-- | Discover the schema dependencies of an @AnnBoolExpPartialSQL@.
|
||||
getBoolExpDeps ::
|
||||
forall b.
|
||||
Backend b =>
|
||||
(GetAggregationPredicatesDeps b) =>
|
||||
SourceName ->
|
||||
TableName b ->
|
||||
AnnBoolExpPartialSQL b ->
|
||||
@ -733,17 +724,9 @@ getBoolExpDeps ::
|
||||
getBoolExpDeps source tableName =
|
||||
runBoolExpM (BoolExpCtx {source = source, currTable = tableName, rootTable = tableName}) . getBoolExpDeps'
|
||||
|
||||
-- | The monad for doing schema dependency discovery for boolean expressions.
|
||||
-- maintains the table context of the expressions being translated.
|
||||
newtype BoolExpM b a = BoolExpM {unBoolExpM :: Reader (BoolExpCtx b) a}
|
||||
deriving (Functor, Applicative, Monad, MonadReader (BoolExpCtx b))
|
||||
|
||||
runBoolExpM :: BoolExpCtx b -> BoolExpM b a -> a
|
||||
runBoolExpM ctx = flip runReader ctx . unBoolExpM
|
||||
|
||||
getBoolExpDeps' ::
|
||||
forall b.
|
||||
Backend b =>
|
||||
(Backend b, GetAggregationPredicatesDeps b) =>
|
||||
AnnBoolExpPartialSQL b ->
|
||||
BoolExpM b [SchemaDependency]
|
||||
getBoolExpDeps' = \case
|
||||
@ -767,7 +750,7 @@ getBoolExpDeps' = \case
|
||||
|
||||
getColExpDeps ::
|
||||
forall b.
|
||||
Backend b =>
|
||||
(Backend b, GetAggregationPredicatesDeps b) =>
|
||||
AnnBoolExpFld b (PartialSQLExp b) ->
|
||||
BoolExpM b [SchemaDependency]
|
||||
getColExpDeps bexp = do
|
||||
@ -777,7 +760,7 @@ getColExpDeps bexp = do
|
||||
let columnName = ciColumn colInfo
|
||||
colDepReason = bool DRSessionVariable DROnType $ any hasStaticExp opExps
|
||||
colDep = mkColDep @b colDepReason source currTable columnName
|
||||
in (colDep :) <$> mkOpExpDeps opExps
|
||||
in (colDep :) <$> getOpExpDeps opExps
|
||||
AVRelationship relInfo relBoolExp ->
|
||||
let relationshipName = riName relInfo
|
||||
relationshipTable = riRTable relInfo
|
||||
@ -797,19 +780,24 @@ getColExpDeps bexp = do
|
||||
let computedFieldDep =
|
||||
mkComputedFieldDep' $
|
||||
bool DRSessionVariable DROnType $ any hasStaticExp opExps
|
||||
in (computedFieldDep :) <$> mkOpExpDeps opExps
|
||||
in (computedFieldDep :) <$> getOpExpDeps opExps
|
||||
CFBETable cfTable cfTableBoolExp ->
|
||||
(mkComputedFieldDep' DROnType :) <$> local (\e -> e {currTable = cfTable}) (getBoolExpDeps' cfTableBoolExp)
|
||||
where
|
||||
mkOpExpDeps :: [OpExpG b (PartialSQLExp b)] -> BoolExpM b [SchemaDependency]
|
||||
mkOpExpDeps opExps = do
|
||||
BoolExpCtx {source, rootTable, currTable} <- ask
|
||||
pure $ do
|
||||
RootOrCurrentColumn rootOrCol col <- mapMaybe opExpDepCol opExps
|
||||
let table = case rootOrCol of
|
||||
IsRoot -> rootTable
|
||||
IsCurrent -> currTable
|
||||
pure $ mkColDep @b DROnType source table col
|
||||
AVAggregationPredicates aggPreds -> getAggregationPredicateDeps aggPreds
|
||||
|
||||
getOpExpDeps ::
|
||||
forall b.
|
||||
(Backend b) =>
|
||||
[OpExpG b (PartialSQLExp b)] ->
|
||||
BoolExpM b [SchemaDependency]
|
||||
getOpExpDeps opExps = do
|
||||
BoolExpCtx {source, rootTable, currTable} <- ask
|
||||
pure $ do
|
||||
RootOrCurrentColumn rootOrCol col <- mapMaybe opExpDepCol opExps
|
||||
let table = case rootOrCol of
|
||||
IsRoot -> rootTable
|
||||
IsCurrent -> currTable
|
||||
pure $ mkColDep @b DROnType source table col
|
||||
|
||||
-- | Asking for a table's fields info without explicit @'SourceName' argument.
|
||||
-- The source name is implicitly inferred from @'SourceM' via @'TableCoreInfoRM'.
|
||||
|
@ -0,0 +1,46 @@
|
||||
-- | This module defines the schema dependency gathering aspect of the default
|
||||
-- implementation of aggregation predicates.
|
||||
module Hasura.RQL.Types.SchemaCache.AggregationPredicates
|
||||
( defaultGetAggregationPredicateDeps,
|
||||
)
|
||||
where
|
||||
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.IR.BoolExp (PartialSQLExp)
|
||||
import Hasura.RQL.IR.BoolExp.AggregationPredicates
|
||||
( AggregationPredicate (..),
|
||||
AggregationPredicatesImplementation (AggregationPredicatesImplementation),
|
||||
)
|
||||
import Hasura.RQL.Types.Backend (Backend)
|
||||
import Hasura.RQL.Types.Relationships.Local
|
||||
( RelInfo (..),
|
||||
)
|
||||
import Hasura.RQL.Types.SchemaCache
|
||||
import Hasura.RQL.Types.SchemaCacheTypes
|
||||
import Hasura.SQL.AnyBackend qualified as AB
|
||||
|
||||
defaultGetAggregationPredicateDeps ::
|
||||
forall b.
|
||||
(Backend b, GetAggregationPredicatesDeps b) =>
|
||||
AggregationPredicatesImplementation b (PartialSQLExp b) ->
|
||||
BoolExpM b [SchemaDependency]
|
||||
defaultGetAggregationPredicateDeps (AggregationPredicatesImplementation relInfo functions) = do
|
||||
BoolExpCtx {source, currTable} <- ask
|
||||
let relationshipName = riName relInfo
|
||||
relationshipTable = riRTable relInfo
|
||||
schemaDependency =
|
||||
SchemaDependency
|
||||
( SOSourceObj source $
|
||||
AB.mkAnyBackend $
|
||||
SOITableObj @b currTable (TORel relationshipName)
|
||||
)
|
||||
DROnType
|
||||
in (schemaDependency :) <$> local (\e -> e {currTable = relationshipTable}) (concat <$> traverse getFunctionDeps functions)
|
||||
where
|
||||
getFunctionDeps :: AggregationPredicate b (PartialSQLExp b) -> BoolExpM b [SchemaDependency]
|
||||
getFunctionDeps AggregationPredicate {..} =
|
||||
do
|
||||
BoolExpCtx {source, currTable} <- ask
|
||||
let filterDeps = maybe [] (getBoolExpDeps source currTable) aggPredFilter
|
||||
predicateDeps <- getOpExpDeps aggPredPredicate
|
||||
return $ filterDeps ++ predicateDeps
|
11
server/src-lib/Hasura/RQL/Types/SchemaCache/Instances.hs
Normal file
11
server/src-lib/Hasura/RQL/Types/SchemaCache/Instances.hs
Normal file
@ -0,0 +1,11 @@
|
||||
{-# OPTIONS_GHC -Wno-dodgy-exports #-}
|
||||
|
||||
--
|
||||
|
||||
module Hasura.RQL.Types.SchemaCache.Instances (module I) where
|
||||
|
||||
import Hasura.Backends.BigQuery.Instances.SchemaCache as I ()
|
||||
import Hasura.Backends.DataConnector.Adapter.SchemaCache as I ()
|
||||
import Hasura.Backends.MSSQL.Instances.SchemaCache as I ()
|
||||
import Hasura.Backends.MySQL.Instances.SchemaCache as I ()
|
||||
import Hasura.Backends.Postgres.Instances.SchemaCache as I ()
|
@ -1,7 +1,11 @@
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
|
||||
module Hasura.RQL.Types.SchemaCacheTypes
|
||||
( DependencyReason (..),
|
||||
( BoolExpM (..),
|
||||
GetAggregationPredicatesDeps (..),
|
||||
BoolExpCtx (..),
|
||||
DependencyReason (..),
|
||||
SchemaDependency (..),
|
||||
SchemaObjId (..),
|
||||
SourceObjId (..),
|
||||
@ -12,17 +16,20 @@ module Hasura.RQL.Types.SchemaCacheTypes
|
||||
reportDependentObjectsExist,
|
||||
reportSchemaObj,
|
||||
reportSchemaObjs,
|
||||
runBoolExpM,
|
||||
)
|
||||
where
|
||||
|
||||
import Data.Aeson
|
||||
import Data.Aeson.TH
|
||||
import Data.Aeson.Types
|
||||
import Data.Functor.Const
|
||||
import Data.Text qualified as T
|
||||
import Data.Text.Extended
|
||||
import Data.Text.NonEmpty
|
||||
import Hasura.Base.Error
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.IR.BoolExp (PartialSQLExp)
|
||||
import Hasura.RQL.Types.Backend
|
||||
import Hasura.RQL.Types.Common
|
||||
import Hasura.RQL.Types.ComputedField
|
||||
@ -215,3 +222,33 @@ purgeDependentObject source sourceObjId = case sourceObjId of
|
||||
throw500 $
|
||||
"unexpected dependent object: "
|
||||
<> reportSchemaObj (SOSourceObj source $ AB.mkAnyBackend sourceObjId)
|
||||
|
||||
-- | Type class to collect schema dependencies from backend-specific aggregation predicates.
|
||||
class Backend b => GetAggregationPredicatesDeps b where
|
||||
getAggregationPredicateDeps ::
|
||||
AggregationPredicates b (PartialSQLExp b) ->
|
||||
BoolExpM b [SchemaDependency]
|
||||
default getAggregationPredicateDeps ::
|
||||
(AggregationPredicates b ~ Const Void) =>
|
||||
AggregationPredicates b (PartialSQLExp b) ->
|
||||
BoolExpM b [SchemaDependency]
|
||||
getAggregationPredicateDeps = absurd . getConst
|
||||
|
||||
-- | The monad for doing schema dependency discovery for boolean expressions.
|
||||
-- maintains the table context of the expressions being translated.
|
||||
newtype BoolExpM b a = BoolExpM {unBoolExpM :: Reader (BoolExpCtx b) a}
|
||||
deriving (Functor, Applicative, Monad, MonadReader (BoolExpCtx b))
|
||||
|
||||
-- | The table type context of schema dependency discovery. Boolean expressions
|
||||
-- may refer to a so-called 'root table' (identified by a '$'-sign in the
|
||||
-- expression input syntax) or the 'current' table.
|
||||
data BoolExpCtx b = BoolExpCtx
|
||||
{ source :: SourceName,
|
||||
-- | Reference to the 'current' table type.
|
||||
currTable :: TableName b,
|
||||
-- | Reference to the 'root' table type.
|
||||
rootTable :: TableName b
|
||||
}
|
||||
|
||||
runBoolExpM :: BoolExpCtx b -> BoolExpM b a -> a
|
||||
runBoolExpM ctx = flip runReader ctx . unBoolExpM
|
||||
|
@ -44,6 +44,7 @@ import Hasura.RQL.Types.Action
|
||||
import Hasura.RQL.Types.Common
|
||||
import Hasura.RQL.Types.CustomTypes
|
||||
import Hasura.RQL.Types.Metadata.Instances ()
|
||||
import Hasura.RQL.Types.Relationships.Local
|
||||
import Hasura.RQL.Types.SchemaCache
|
||||
import Hasura.RQL.Types.Source
|
||||
import Hasura.RQL.Types.Table
|
||||
|
Loading…
Reference in New Issue
Block a user