graphql-engine-1.0.0: GraphQL API over Postgres
Safe HaskellSafe-Inferred
LanguageHaskell2010

Hasura.GraphQL.Execute.RemoteJoin.Types

Synopsis

Documentation

newtype JoinTree a Source #

A JoinTree represents the set of operations that need to be executed to enrich the response of a source with data from remote sources. A tree structure is used to capture the locations in the response where the join has to happpen as it offers an efficient traversal mechanism.

For a query such as this:

{ city { name code # weather is a remote relationship weather { forecast } state { # weather is a remote relationship weather { forecast } } } }

the join tree would look like [ , ("weather", Leaf RemoteJoinInfoOfWeather), , ("state", [ ("weather", Leaf RemoteJoinInfoOfWeather) ]) ]

Note that the same join tree will be emitted even if city is of type '[City]' and state is of type [State], we currently do not capture any information if any of the fields in the path expect json arrays. It is similar in spirit to a GraphQL selection set in this regard.

This structure is somewhat similar to a prefix tree such as Trie, but has two additional guarantees: - a JoinTree is never empty, - there cannot exist a pair of values for which one's prefix key is a subset of the other: every value is effectively a leaf.

Instances

Instances details
Foldable JoinTree Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Methods

fold :: Monoid m => JoinTree m -> m #

foldMap :: Monoid m => (a -> m) -> JoinTree a -> m #

foldMap' :: Monoid m => (a -> m) -> JoinTree a -> m #

foldr :: (a -> b -> b) -> b -> JoinTree a -> b #

foldr' :: (a -> b -> b) -> b -> JoinTree a -> b #

foldl :: (b -> a -> b) -> b -> JoinTree a -> b #

foldl' :: (b -> a -> b) -> b -> JoinTree a -> b #

foldr1 :: (a -> a -> a) -> JoinTree a -> a #

foldl1 :: (a -> a -> a) -> JoinTree a -> a #

toList :: JoinTree a -> [a] #

null :: JoinTree a -> Bool #

length :: JoinTree a -> Int #

elem :: Eq a => a -> JoinTree a -> Bool #

maximum :: Ord a => JoinTree a -> a #

minimum :: Ord a => JoinTree a -> a #

sum :: Num a => JoinTree a -> a #

product :: Num a => JoinTree a -> a #

Traversable JoinTree Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Methods

traverse :: Applicative f => (a -> f b) -> JoinTree a -> f (JoinTree b) #

sequenceA :: Applicative f => JoinTree (f a) -> f (JoinTree a) #

mapM :: Monad m => (a -> m b) -> JoinTree a -> m (JoinTree b) #

sequence :: Monad m => JoinTree (m a) -> m (JoinTree a) #

Functor JoinTree Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Methods

fmap :: (a -> b) -> JoinTree a -> JoinTree b #

(<$) :: a -> JoinTree b -> JoinTree a #

Semigroup (JoinTree a) Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Methods

(<>) :: JoinTree a -> JoinTree a -> JoinTree a #

sconcat :: NonEmpty (JoinTree a) -> JoinTree a #

stimes :: Integral b => b -> JoinTree a -> JoinTree a #

Generic (JoinTree a) Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Associated Types

type Rep (JoinTree a) :: Type -> Type #

Methods

from :: JoinTree a -> Rep (JoinTree a) x #

to :: Rep (JoinTree a) x -> JoinTree a #

Show a => Show (JoinTree a) Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Methods

showsPrec :: Int -> JoinTree a -> ShowS #

show :: JoinTree a -> String #

showList :: [JoinTree a] -> ShowS #

Eq a => Eq (JoinTree a) Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Methods

(==) :: JoinTree a -> JoinTree a -> Bool #

(/=) :: JoinTree a -> JoinTree a -> Bool #

type Rep (JoinTree a) Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

type Rep (JoinTree a) = D1 ('MetaData "JoinTree" "Hasura.GraphQL.Execute.RemoteJoin.Types" "graphql-engine-1.0.0-inplace" 'True) (C1 ('MetaCons "JoinTree" 'PrefixI 'True) (S1 ('MetaSel ('Just "unJoinTree") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (NEHashMap QualifiedFieldName (JoinNode a)))))

data QualifiedFieldName Source #

A field name annotated with an optional type name.

To deal with ambiguous join paths, such as those that emerge from GraphQL interfaces or GraphQL unions, we do not just keep track of the fields' name, but also, optionally, of their type. Whenever a selection set is deemed ambiguous, we insert a reserved field in the query to retrieve the typename, __hasura_internal_typename; when traversing the join tree, if that key is present, then we use it alongside the field name when querying the join tree (see traverseObject in the Join module).

We use Text for the representation of the field name instead of FieldName, for simplicity: the join tree is only meant to be queried using the values we get in the reponse, which will be unrestricted text.

Instances

Instances details
Generic QualifiedFieldName Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Associated Types

type Rep QualifiedFieldName :: Type -> Type #

Show QualifiedFieldName Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Eq QualifiedFieldName Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Hashable QualifiedFieldName Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

type Rep QualifiedFieldName Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

type Rep QualifiedFieldName = D1 ('MetaData "QualifiedFieldName" "Hasura.GraphQL.Execute.RemoteJoin.Types" "graphql-engine-1.0.0-inplace" 'False) (C1 ('MetaCons "QualifiedFieldName" 'PrefixI 'True) (S1 ('MetaSel ('Just "_qfTypeName") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 (Maybe Text)) :*: S1 ('MetaSel ('Just "_qfFieldName") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 Text)))

data JoinNode a Source #

Each leaf associates a mapping from typename to actual join info. This allows to disambiguate between different remote joins with the same name in a given selection set, which might happen with union or interface fragments.

Constructors

Leaf a 
Tree (JoinTree a) 

Instances

Instances details
Foldable JoinNode Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Methods

fold :: Monoid m => JoinNode m -> m #

foldMap :: Monoid m => (a -> m) -> JoinNode a -> m #

foldMap' :: Monoid m => (a -> m) -> JoinNode a -> m #

foldr :: (a -> b -> b) -> b -> JoinNode a -> b #

foldr' :: (a -> b -> b) -> b -> JoinNode a -> b #

foldl :: (b -> a -> b) -> b -> JoinNode a -> b #

foldl' :: (b -> a -> b) -> b -> JoinNode a -> b #

foldr1 :: (a -> a -> a) -> JoinNode a -> a #

foldl1 :: (a -> a -> a) -> JoinNode a -> a #

toList :: JoinNode a -> [a] #

null :: JoinNode a -> Bool #

length :: JoinNode a -> Int #

elem :: Eq a => a -> JoinNode a -> Bool #

maximum :: Ord a => JoinNode a -> a #

minimum :: Ord a => JoinNode a -> a #

sum :: Num a => JoinNode a -> a #

product :: Num a => JoinNode a -> a #

Traversable JoinNode Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Methods

traverse :: Applicative f => (a -> f b) -> JoinNode a -> f (JoinNode b) #

sequenceA :: Applicative f => JoinNode (f a) -> f (JoinNode a) #

mapM :: Monad m => (a -> m b) -> JoinNode a -> m (JoinNode b) #

sequence :: Monad m => JoinNode (m a) -> m (JoinNode a) #

Functor JoinNode Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Methods

fmap :: (a -> b) -> JoinNode a -> JoinNode b #

(<$) :: a -> JoinNode b -> JoinNode a #

Generic (JoinNode a) Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Associated Types

type Rep (JoinNode a) :: Type -> Type #

Methods

from :: JoinNode a -> Rep (JoinNode a) x #

to :: Rep (JoinNode a) x -> JoinNode a #

Show a => Show (JoinNode a) Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Methods

showsPrec :: Int -> JoinNode a -> ShowS #

show :: JoinNode a -> String #

showList :: [JoinNode a] -> ShowS #

Eq a => Eq (JoinNode a) Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Methods

(==) :: JoinNode a -> JoinNode a -> Bool #

(/=) :: JoinNode a -> JoinNode a -> Bool #

type Rep (JoinNode a) Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

type Rep (JoinNode a) = D1 ('MetaData "JoinNode" "Hasura.GraphQL.Execute.RemoteJoin.Types" "graphql-engine-1.0.0-inplace" 'False) (C1 ('MetaCons "Leaf" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 a)) :+: C1 ('MetaCons "Tree" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 (JoinTree a))))

getRemoteSchemaJoins :: RemoteJoins -> [RemoteSchemaJoin] Source #

Collect all the remote joins to a remote schema from a join tree.

data RemoteJoin Source #

An individual join entry point in a JoinTree.

Either a join against a source, or against a remote schema. In either case, the constructor will contain that particular join's information (a RemoteSourceJoin or RemoteSchemaJoin respectively) and, recursively, the set of follow-up RemoteJoins from that target, if any.

type JoinCallId = Int Source #

A unique id that gets assigned to each RemoteJoin (this is to avoid the requirement of Ord/Hashable implementation for RemoteJoin)

data JoinColumnAlias Source #

Disambiguates between FieldNames which are provided as part of the GraphQL selection provided by the user (i.e. JCSelected) and those which we need to retreive data but which are not expressly requested (i.e. JCPhantom).

After processing the remote join, we remove all phantom FieldNames and only return those which fall under the JCSelected branch of this type.

Constructors

JCSelected !FieldName

This fieldname is already part of the response.

JCPhantom !FieldName

This is explicitly added for the join.

Such keys will have to be removed from the response eventually.

getAliasFieldName :: JoinColumnAlias -> FieldName Source #

Extracts the field name from the JoinColumnAlias, regardless of whether the field is requested by the user of a "phantom" field.

getPhantomFields :: RemoteJoin -> [FieldName] Source #

Extracts the list of phantom field names out of a given RemoteJoin, i.e. the name of the fields that must be part of the query but were not requested by the user.

getJoinColumnMapping :: RemoteJoin -> HashMap FieldName JoinColumnAlias Source #

Extracts an abstracted field mapping for a particular RemoteJoin, using a common representation.

The RHS of the mapping uses JoinColumnAlias instead of FieldName to differentiate between selected fields and phantom fields (see JoinColumnAlias).

data RemoteSourceJoin b Source #

A RemoteSourceJoin contains all the contextual information required for the execution of a join against a source, translated from the IR's representation of a selection (see AnnFieldG).

Instances

Instances details
Generic (RemoteSourceJoin b) Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Associated Types

type Rep (RemoteSourceJoin b) :: Type -> Type #

(Backend b, Show (SourceRelationshipSelection b Void UnpreparedValue), Show (SourceConfig b)) => Show (RemoteSourceJoin b) Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

(Backend b, Eq (SourceRelationshipSelection b Void UnpreparedValue)) => Eq (RemoteSourceJoin b) Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

type Rep (RemoteSourceJoin b) Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

type Rep (RemoteSourceJoin b) = D1 ('MetaData "RemoteSourceJoin" "Hasura.GraphQL.Execute.RemoteJoin.Types" "graphql-engine-1.0.0-inplace" 'False) (C1 ('MetaCons "RemoteSourceJoin" 'PrefixI 'True) ((S1 ('MetaSel ('Just "_rsjSource") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 SourceName) :*: S1 ('MetaSel ('Just "_rsjSourceConfig") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (SourceConfig b))) :*: (S1 ('MetaSel ('Just "_rsjRelationship") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (SourceRelationshipSelection b Void UnpreparedValue)) :*: (S1 ('MetaSel ('Just "_rsjJoinColumns") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (HashMap FieldName (JoinColumnAlias, (Column b, ScalarType b)))) :*: S1 ('MetaSel ('Just "_rsjStringifyNum") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedStrict) (Rec0 StringifyNumbers)))))

data RemoteSchemaJoin Source #

A RemoteSchemaJoin contains all the contextual information required for the execution of a join against a remote schema, translated from the IR's representation of a selection (see AnnFieldG).

Constructors

RemoteSchemaJoin 

Fields

Instances

Instances details
Generic RemoteSchemaJoin Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Associated Types

type Rep RemoteSchemaJoin :: Type -> Type #

Eq RemoteSchemaJoin Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

type Rep RemoteSchemaJoin Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

newtype JoinArgument Source #

A map of fieldname to values extracted from each LHS row/object

For example, if a remote relationship weather on city table is defined as follows: city.weather = get_weather(city: city.code, cityState: city.state_code) a join argument for this join would have the values of columns code and state_code for each city row that participates in the join

Instances

Instances details
Generic JoinArgument Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Associated Types

type Rep JoinArgument :: Type -> Type #

Show JoinArgument Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Eq JoinArgument Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Hashable JoinArgument Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

type Rep JoinArgument Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

type Rep JoinArgument = D1 ('MetaData "JoinArgument" "Hasura.GraphQL.Execute.RemoteJoin.Types" "graphql-engine-1.0.0-inplace" 'True) (C1 ('MetaCons "JoinArgument" 'PrefixI 'True) (S1 ('MetaSel ('Just "unJoinArgument") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (HashMap FieldName Value))))

type JoinArgumentId = Int Source #

A unique id assigned to each join argument

data JoinArguments Source #

Constructors

JoinArguments 

Fields

  • _jalJoin :: !RemoteJoin

    The RemoteJoin associated with the join arguments within this structure.

  • _jalArguments :: !(HashMap JoinArgument JoinArgumentId)

    Arguments for which we must fetch a response from the remote, along with the identifiers that are used to stitch the final response together.

    NOTE: HashMap is used to deduplicate multiple JoinArguments so that we avoid fetching more data from a remote than is necessary (i.e. in the case of duplicate arguments).

  • _jalFieldName :: !FieldName

    The FieldName associated with the "replacement token" for this join argument.

    NOTE: We need this for query logging; ideally we would use the full path for the GraphQL query associated with this remote join, but we don't have access to that here so this is the next best thing to do.

Instances

Instances details
Generic JoinArguments Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

Associated Types

type Rep JoinArguments :: Type -> Type #

type Rep JoinArguments Source # 
Instance details

Defined in Hasura.GraphQL.Execute.RemoteJoin.Types

type Rep JoinArguments = D1 ('MetaData "JoinArguments" "Hasura.GraphQL.Execute.RemoteJoin.Types" "graphql-engine-1.0.0-inplace" 'False) (C1 ('MetaCons "JoinArguments" 'PrefixI 'True) (S1 ('MetaSel ('Just "_jalJoin") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 RemoteJoin) :*: (S1 ('MetaSel ('Just "_jalArguments") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (HashMap JoinArgument JoinArgumentId)) :*: S1 ('MetaSel ('Just "_jalFieldName") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 FieldName))))