mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 17:31:56 +03:00
chore(server): allow non-nullable NQ -> NQ object relationships
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9353 GitOrigin-RevId: 9da95675d224f3045509592c2515b7afa2500d00
This commit is contained in:
parent
b19eff22e9
commit
7d011644ac
@ -204,6 +204,7 @@ fromRemoteRelationFieldsG existingJoins joinColumns (IR.FieldName name, field) =
|
|||||||
IR.AnnRelationSelectG
|
IR.AnnRelationSelectG
|
||||||
(IR.RelName $ mkNonEmptyTextUnsafe name)
|
(IR.RelName $ mkNonEmptyTextUnsafe name)
|
||||||
joinColumns
|
joinColumns
|
||||||
|
IR.Nullable
|
||||||
annotatedRelationship
|
annotatedRelationship
|
||||||
|
|
||||||
-- | Top/root-level 'Select'. All descendent/sub-translations are collected to produce a root TSQL.Select.
|
-- | Top/root-level 'Select'. All descendent/sub-translations are collected to produce a root TSQL.Select.
|
||||||
|
@ -31,6 +31,7 @@ import Hasura.Backends.Postgres.Translate.Select.Internal.Helpers
|
|||||||
import Hasura.Backends.Postgres.Translate.Types
|
import Hasura.Backends.Postgres.Translate.Types
|
||||||
import Hasura.Prelude
|
import Hasura.Prelude
|
||||||
import Hasura.RQL.IR.Select (ConnectionSlice (SliceFirst, SliceLast))
|
import Hasura.RQL.IR.Select (ConnectionSlice (SliceFirst, SliceLast))
|
||||||
|
import Hasura.RQL.Types.Relationships.Local (Nullable (..))
|
||||||
|
|
||||||
generateSQLSelect ::
|
generateSQLSelect ::
|
||||||
-- | Pre join condition for lateral joins
|
-- | Pre join condition for lateral joins
|
||||||
@ -86,9 +87,9 @@ generateSQLSelect joinCondition selectSource selectNode =
|
|||||||
S.WhereFrag $ S.simplifyBoolExp $ S.BEBin S.AndOp joinCond whereCond
|
S.WhereFrag $ S.simplifyBoolExp $ S.BEBin S.AndOp joinCond whereCond
|
||||||
|
|
||||||
-- function to create a joined from item from two from items
|
-- function to create a joined from item from two from items
|
||||||
leftOuterJoin current new =
|
leftOuterJoin current (new, joinType) =
|
||||||
S.FIJoin
|
S.FIJoin
|
||||||
$ S.JoinExpr current S.LeftOuter new
|
$ S.JoinExpr current joinType new
|
||||||
$ S.JoinOn
|
$ S.JoinOn
|
||||||
$ S.BELit True
|
$ S.BELit True
|
||||||
|
|
||||||
@ -102,33 +103,40 @@ generateSQLSelect joinCondition selectSource selectNode =
|
|||||||
<> map computedFieldToFromItem (HashMap.toList computedFields)
|
<> map computedFieldToFromItem (HashMap.toList computedFields)
|
||||||
|
|
||||||
objectRelationToFromItem ::
|
objectRelationToFromItem ::
|
||||||
(ObjectRelationSource, SelectNode) -> S.FromItem
|
(ObjectRelationSource, SelectNode) -> (S.FromItem, S.JoinType)
|
||||||
objectRelationToFromItem (objectRelationSource, node) =
|
objectRelationToFromItem (objectRelationSource, node) =
|
||||||
let ObjectRelationSource _ colMapping objectSelectSource = objectRelationSource
|
let ObjectRelationSource
|
||||||
|
{ _orsRelationMapping = colMapping,
|
||||||
|
_orsSelectSource = objectSelectSource,
|
||||||
|
_orsNullable = nullable
|
||||||
|
} = objectRelationSource
|
||||||
alias = S.toTableAlias $ _ossPrefix objectSelectSource
|
alias = S.toTableAlias $ _ossPrefix objectSelectSource
|
||||||
source = objectSelectSourceToSelectSource objectSelectSource
|
source = objectSelectSourceToSelectSource objectSelectSource
|
||||||
select = generateSQLSelect (mkJoinCond baseSelectIdentifier colMapping) source node
|
select = generateSQLSelect (mkJoinCond baseSelectIdentifier colMapping) source node
|
||||||
in S.mkLateralFromItem select alias
|
joinType = case nullable of
|
||||||
|
Nullable -> S.LeftOuter
|
||||||
|
NotNullable -> S.Inner
|
||||||
|
in (S.mkLateralFromItem select alias, joinType)
|
||||||
|
|
||||||
arrayRelationToFromItem ::
|
arrayRelationToFromItem ::
|
||||||
(ArrayRelationSource, MultiRowSelectNode) -> S.FromItem
|
(ArrayRelationSource, MultiRowSelectNode) -> (S.FromItem, S.JoinType)
|
||||||
arrayRelationToFromItem (arrayRelationSource, arraySelectNode) =
|
arrayRelationToFromItem (arrayRelationSource, arraySelectNode) =
|
||||||
let ArrayRelationSource _ colMapping source = arrayRelationSource
|
let ArrayRelationSource _ colMapping source = arrayRelationSource
|
||||||
alias = S.toTableAlias $ _ssPrefix source
|
alias = S.toTableAlias $ _ssPrefix source
|
||||||
select =
|
select =
|
||||||
generateSQLSelectFromArrayNode source arraySelectNode
|
generateSQLSelectFromArrayNode source arraySelectNode
|
||||||
$ mkJoinCond baseSelectIdentifier colMapping
|
$ mkJoinCond baseSelectIdentifier colMapping
|
||||||
in S.mkLateralFromItem select alias
|
in (S.mkLateralFromItem select alias, S.LeftOuter)
|
||||||
|
|
||||||
arrayConnectionToFromItem ::
|
arrayConnectionToFromItem ::
|
||||||
(ArrayConnectionSource, MultiRowSelectNode) -> S.FromItem
|
(ArrayConnectionSource, MultiRowSelectNode) -> (S.FromItem, S.JoinType)
|
||||||
arrayConnectionToFromItem (arrayConnectionSource, arraySelectNode) =
|
arrayConnectionToFromItem (arrayConnectionSource, arraySelectNode) =
|
||||||
let selectWith = connectionToSelectWith baseSelectAlias arrayConnectionSource arraySelectNode
|
let selectWith = connectionToSelectWith baseSelectAlias arrayConnectionSource arraySelectNode
|
||||||
alias = S.toTableAlias $ _ssPrefix $ _acsSource arrayConnectionSource
|
alias = S.toTableAlias $ _ssPrefix $ _acsSource arrayConnectionSource
|
||||||
in S.FISelectWith (S.Lateral True) selectWith alias
|
in (S.FISelectWith (S.Lateral True) selectWith alias, S.LeftOuter)
|
||||||
|
|
||||||
computedFieldToFromItem ::
|
computedFieldToFromItem ::
|
||||||
(ComputedFieldTableSetSource, MultiRowSelectNode) -> S.FromItem
|
(ComputedFieldTableSetSource, MultiRowSelectNode) -> (S.FromItem, S.JoinType)
|
||||||
computedFieldToFromItem (computedFieldTableSource, node) =
|
computedFieldToFromItem (computedFieldTableSource, node) =
|
||||||
let ComputedFieldTableSetSource _ source = computedFieldTableSource
|
let ComputedFieldTableSetSource _ source = computedFieldTableSource
|
||||||
internalSelect = generateSQLSelect (S.BELit True) source $ _mrsnSelectNode node
|
internalSelect = generateSQLSelect (S.BELit True) source $ _mrsnSelectNode node
|
||||||
@ -138,7 +146,7 @@ generateSQLSelect joinCondition selectSource selectNode =
|
|||||||
{ S.selExtr = _mrsnTopExtractors node,
|
{ S.selExtr = _mrsnTopExtractors node,
|
||||||
S.selFrom = Just $ S.FromExp [S.mkSelFromItem internalSelect alias]
|
S.selFrom = Just $ S.FromExp [S.mkSelFromItem internalSelect alias]
|
||||||
}
|
}
|
||||||
in S.mkLateralFromItem select alias
|
in (S.mkLateralFromItem select alias, S.LeftOuter)
|
||||||
|
|
||||||
-- | Create a select query
|
-- | Create a select query
|
||||||
generateSQLSelectFromArrayNode ::
|
generateSQLSelectFromArrayNode ::
|
||||||
|
@ -130,7 +130,7 @@ processOrderByItems sourcePrefix' fieldAlias' similarArrayFields distOnCols = \c
|
|||||||
(tableIdentifierToIdentifier relSourcePrefix)
|
(tableIdentifierToIdentifier relSourcePrefix)
|
||||||
(S.FISimple relTable Nothing)
|
(S.FISimple relTable Nothing)
|
||||||
(toSQLBoolExp (S.QualTable relTable) relFilter)
|
(toSQLBoolExp (S.QualTable relTable) relFilter)
|
||||||
relSource = ObjectRelationSource relName colMapping selectSource
|
relSource = ObjectRelationSource relName colMapping selectSource Nullable
|
||||||
pure
|
pure
|
||||||
( relSource,
|
( relSource,
|
||||||
HashMap.singleton relOrderByAlias relOrdByExp,
|
HashMap.singleton relOrderByAlias relOrdByExp,
|
||||||
|
@ -291,7 +291,7 @@ processAnnFields sourcePrefix fieldAlias similarArrFields annFields tCase = do
|
|||||||
AFNodeId _ sn tn pKeys -> pure $ mkNodeId sn tn pKeys
|
AFNodeId _ sn tn pKeys -> pure $ mkNodeId sn tn pKeys
|
||||||
AFColumn c -> toSQLCol c
|
AFColumn c -> toSQLCol c
|
||||||
AFObjectRelation objSel -> withWriteObjectRelation $ do
|
AFObjectRelation objSel -> withWriteObjectRelation $ do
|
||||||
let AnnRelationSelectG relName relMapping annObjSel = objSel
|
let AnnRelationSelectG relName relMapping nullable annObjSel = objSel
|
||||||
AnnObjectSelectG objAnnFields target targetFilter = annObjSel
|
AnnObjectSelectG objAnnFields target targetFilter = annObjSel
|
||||||
objRelSourcePrefix = mkObjectRelationTableAlias sourcePrefix relName
|
objRelSourcePrefix = mkObjectRelationTableAlias sourcePrefix relName
|
||||||
sourcePrefixes = mkSourcePrefixes objRelSourcePrefix
|
sourcePrefixes = mkSourcePrefixes objRelSourcePrefix
|
||||||
@ -314,7 +314,7 @@ processAnnFields sourcePrefix fieldAlias similarArrFields annFields tCase = do
|
|||||||
(_pfThis sourcePrefixes)
|
(_pfThis sourcePrefixes)
|
||||||
(S.FIIdentifier nativeQueryIdentifier)
|
(S.FIIdentifier nativeQueryIdentifier)
|
||||||
(toSQLBoolExp (S.QualifiedIdentifier nativeQueryIdentifier Nothing) targetFilter)
|
(toSQLBoolExp (S.QualifiedIdentifier nativeQueryIdentifier Nothing) targetFilter)
|
||||||
objRelSource = ObjectRelationSource relName relMapping selectSource
|
objRelSource = ObjectRelationSource relName relMapping selectSource nullable
|
||||||
pure
|
pure
|
||||||
( objRelSource,
|
( objRelSource,
|
||||||
HashMap.fromList [annFieldsExtr],
|
HashMap.fromList [annFieldsExtr],
|
||||||
@ -326,7 +326,7 @@ processAnnFields sourcePrefix fieldAlias similarArrFields annFields tCase = do
|
|||||||
(_pfThis sourcePrefixes)
|
(_pfThis sourcePrefixes)
|
||||||
(S.FISimple tableFrom Nothing)
|
(S.FISimple tableFrom Nothing)
|
||||||
(toSQLBoolExp (S.QualTable tableFrom) targetFilter)
|
(toSQLBoolExp (S.QualTable tableFrom) targetFilter)
|
||||||
objRelSource = ObjectRelationSource relName relMapping selectSource
|
objRelSource = ObjectRelationSource relName relMapping selectSource Nullable
|
||||||
pure
|
pure
|
||||||
( objRelSource,
|
( objRelSource,
|
||||||
HashMap.fromList [annFieldsExtr],
|
HashMap.fromList [annFieldsExtr],
|
||||||
@ -496,7 +496,7 @@ processArrayRelation ::
|
|||||||
processArrayRelation sourcePrefixes fieldAlias relAlias arrSel _tCase =
|
processArrayRelation sourcePrefixes fieldAlias relAlias arrSel _tCase =
|
||||||
case arrSel of
|
case arrSel of
|
||||||
ASSimple annArrRel -> withWriteArrayRelation $ do
|
ASSimple annArrRel -> withWriteArrayRelation $ do
|
||||||
let AnnRelationSelectG _ colMapping sel = annArrRel
|
let AnnRelationSelectG _ colMapping _ sel = annArrRel
|
||||||
permLimitSubQuery =
|
permLimitSubQuery =
|
||||||
maybe PLSQNotRequired PLSQRequired $ _tpLimit $ _asnPerm sel
|
maybe PLSQNotRequired PLSQRequired $ _tpLimit $ _asnPerm sel
|
||||||
(source, nodeExtractors) <-
|
(source, nodeExtractors) <-
|
||||||
@ -514,7 +514,7 @@ processArrayRelation sourcePrefixes fieldAlias relAlias arrSel _tCase =
|
|||||||
()
|
()
|
||||||
)
|
)
|
||||||
ASAggregate aggSel -> withWriteArrayRelation $ do
|
ASAggregate aggSel -> withWriteArrayRelation $ do
|
||||||
let AnnRelationSelectG _ colMapping sel = aggSel
|
let AnnRelationSelectG _ colMapping _ sel = aggSel
|
||||||
(source, nodeExtractors, topExtr) <-
|
(source, nodeExtractors, topExtr) <-
|
||||||
processAnnAggregateSelect sourcePrefixes fieldAlias sel
|
processAnnAggregateSelect sourcePrefixes fieldAlias sel
|
||||||
pure
|
pure
|
||||||
@ -524,7 +524,7 @@ processArrayRelation sourcePrefixes fieldAlias relAlias arrSel _tCase =
|
|||||||
()
|
()
|
||||||
)
|
)
|
||||||
ASConnection connSel -> withWriteArrayConnection $ do
|
ASConnection connSel -> withWriteArrayConnection $ do
|
||||||
let AnnRelationSelectG _ colMapping sel = connSel
|
let AnnRelationSelectG _ colMapping _ sel = connSel
|
||||||
(source, topExtractor, nodeExtractors) <-
|
(source, topExtractor, nodeExtractors) <-
|
||||||
processConnectionSelect sourcePrefixes fieldAlias relAlias colMapping sel
|
processConnectionSelect sourcePrefixes fieldAlias relAlias colMapping sel
|
||||||
pure
|
pure
|
||||||
|
@ -12,7 +12,7 @@ module Hasura.Backends.Postgres.Translate.Types
|
|||||||
DistinctAndOrderByExpr (ASorting),
|
DistinctAndOrderByExpr (ASorting),
|
||||||
JoinTree (..),
|
JoinTree (..),
|
||||||
MultiRowSelectNode (..),
|
MultiRowSelectNode (..),
|
||||||
ObjectRelationSource (ObjectRelationSource),
|
ObjectRelationSource (..),
|
||||||
ObjectSelectSource (ObjectSelectSource, _ossPrefix),
|
ObjectSelectSource (ObjectSelectSource, _ossPrefix),
|
||||||
PermissionLimitSubQuery (..),
|
PermissionLimitSubQuery (..),
|
||||||
SelectNode (SelectNode),
|
SelectNode (SelectNode),
|
||||||
@ -38,6 +38,7 @@ import Hasura.NativeQuery.Metadata (InterpolatedQuery)
|
|||||||
import Hasura.Prelude
|
import Hasura.Prelude
|
||||||
import Hasura.RQL.IR.Select
|
import Hasura.RQL.IR.Select
|
||||||
import Hasura.RQL.Types.Common
|
import Hasura.RQL.Types.Common
|
||||||
|
import Hasura.RQL.Types.Relationships.Local (Nullable)
|
||||||
|
|
||||||
data SourcePrefixes = SourcePrefixes
|
data SourcePrefixes = SourcePrefixes
|
||||||
{ -- | Current source prefix
|
{ -- | Current source prefix
|
||||||
@ -169,7 +170,8 @@ objectSelectSourceToSelectSource ObjectSelectSource {..} =
|
|||||||
data ObjectRelationSource = ObjectRelationSource
|
data ObjectRelationSource = ObjectRelationSource
|
||||||
{ _orsRelationshipName :: RelName,
|
{ _orsRelationshipName :: RelName,
|
||||||
_orsRelationMapping :: HashMap.HashMap Postgres.PGCol Postgres.PGCol,
|
_orsRelationMapping :: HashMap.HashMap Postgres.PGCol Postgres.PGCol,
|
||||||
_orsSelectSource :: ObjectSelectSource
|
_orsSelectSource :: ObjectSelectSource,
|
||||||
|
_orsNullable :: Nullable
|
||||||
}
|
}
|
||||||
deriving (Generic, Show)
|
deriving (Generic, Show)
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ import Hasura.RQL.Types.Backend
|
|||||||
import Hasura.RQL.Types.BackendType
|
import Hasura.RQL.Types.BackendType
|
||||||
import Hasura.RQL.Types.Column (ColumnType, fromCol)
|
import Hasura.RQL.Types.Column (ColumnType, fromCol)
|
||||||
import Hasura.RQL.Types.Common
|
import Hasura.RQL.Types.Common
|
||||||
|
import Hasura.RQL.Types.Relationships.Local (Nullable (..))
|
||||||
import Hasura.RQL.Types.ResultCustomization
|
import Hasura.RQL.Types.ResultCustomization
|
||||||
import Hasura.RQL.Types.Schema.Options qualified as Options
|
import Hasura.RQL.Types.Schema.Options qualified as Options
|
||||||
import Hasura.RemoteSchema.SchemaCache
|
import Hasura.RemoteSchema.SchemaCache
|
||||||
@ -197,11 +198,11 @@ convertRemoteSourceRelationship
|
|||||||
|
|
||||||
relationshipField = case relationship of
|
relationshipField = case relationship of
|
||||||
SourceRelationshipObject s ->
|
SourceRelationshipObject s ->
|
||||||
AFObjectRelation $ AnnRelationSelectG relName columnMapping s
|
AFObjectRelation $ AnnRelationSelectG relName columnMapping Nullable s
|
||||||
SourceRelationshipArray s ->
|
SourceRelationshipArray s ->
|
||||||
AFArrayRelation $ ASSimple $ AnnRelationSelectG relName columnMapping s
|
AFArrayRelation $ ASSimple $ AnnRelationSelectG relName columnMapping Nullable s
|
||||||
SourceRelationshipArrayAggregate s ->
|
SourceRelationshipArrayAggregate s ->
|
||||||
AFArrayRelation $ ASAggregate $ AnnRelationSelectG relName columnMapping s
|
AFArrayRelation $ ASAggregate $ AnnRelationSelectG relName columnMapping Nullable s
|
||||||
|
|
||||||
argumentIdField =
|
argumentIdField =
|
||||||
( fromCol @b argumentIdColumn,
|
( fromCol @b argumentIdColumn,
|
||||||
|
@ -1448,7 +1448,7 @@ relationshipField table ri = runMaybeT do
|
|||||||
$ P.subselection_ relFieldName desc selectionSetParser
|
$ P.subselection_ relFieldName desc selectionSetParser
|
||||||
<&> \fields ->
|
<&> \fields ->
|
||||||
IR.AFObjectRelation
|
IR.AFObjectRelation
|
||||||
$ IR.AnnRelationSelectG (riName ri) (riMapping ri)
|
$ IR.AnnRelationSelectG (riName ri) (riMapping ri) Nullable
|
||||||
$ IR.AnnObjectSelectG fields (IR.FromTable otherTableName)
|
$ IR.AnnObjectSelectG fields (IR.FromTable otherTableName)
|
||||||
$ deduplicatePermissions
|
$ deduplicatePermissions
|
||||||
$ IR._tpFilter
|
$ IR._tpFilter
|
||||||
@ -1460,7 +1460,7 @@ relationshipField table ri = runMaybeT do
|
|||||||
otherTableParser <&> \selectExp ->
|
otherTableParser <&> \selectExp ->
|
||||||
IR.AFArrayRelation
|
IR.AFArrayRelation
|
||||||
$ IR.ASSimple
|
$ IR.ASSimple
|
||||||
$ IR.AnnRelationSelectG (riName ri) (riMapping ri)
|
$ IR.AnnRelationSelectG (riName ri) (riMapping ri) Nullable
|
||||||
$ deduplicatePermissions' selectExp
|
$ deduplicatePermissions' selectExp
|
||||||
relAggFieldName = applyFieldNameCaseCust tCase $ relFieldName <> Name.__aggregate
|
relAggFieldName = applyFieldNameCaseCust tCase $ relFieldName <> Name.__aggregate
|
||||||
relAggDesc = Just $ G.Description "An aggregate relationship"
|
relAggDesc = Just $ G.Description "An aggregate relationship"
|
||||||
@ -1479,8 +1479,8 @@ relationshipField table ri = runMaybeT do
|
|||||||
pure
|
pure
|
||||||
$ catMaybes
|
$ catMaybes
|
||||||
[ Just arrayRelField,
|
[ Just arrayRelField,
|
||||||
fmap (IR.AFArrayRelation . IR.ASAggregate . IR.AnnRelationSelectG (riName ri) (riMapping ri)) <$> remoteAggField,
|
fmap (IR.AFArrayRelation . IR.ASAggregate . IR.AnnRelationSelectG (riName ri) (riMapping ri) Nullable) <$> remoteAggField,
|
||||||
fmap (IR.AFArrayRelation . IR.ASConnection . IR.AnnRelationSelectG (riName ri) (riMapping ri)) <$> remoteConnectionField
|
fmap (IR.AFArrayRelation . IR.ASConnection . IR.AnnRelationSelectG (riName ri) (riMapping ri) Nullable) <$> remoteConnectionField
|
||||||
]
|
]
|
||||||
|
|
||||||
tablePermissionsInfo :: (Backend b) => SelPermInfo b -> TablePerms b
|
tablePermissionsInfo :: (Backend b) => SelPermInfo b -> TablePerms b
|
||||||
|
@ -200,11 +200,11 @@ parseLogicalModelField relationshipInfo column logimoField = do
|
|||||||
( LogicalModelField
|
( LogicalModelField
|
||||||
{ lmfType =
|
{ lmfType =
|
||||||
LogicalModelTypeReference
|
LogicalModelTypeReference
|
||||||
(LogicalModelTypeReferenceC {lmtrReference})
|
(LogicalModelTypeReferenceC {lmtrNullable, lmtrReference})
|
||||||
}
|
}
|
||||||
) -> do
|
) -> do
|
||||||
-- we currently ignore nullability and assume the field is nullable
|
|
||||||
relName <- hoistMaybe $ columnToRelName @b column
|
relName <- hoistMaybe $ columnToRelName @b column
|
||||||
|
|
||||||
-- lookup the reference in the data source
|
-- lookup the reference in the data source
|
||||||
relationship <-
|
relationship <-
|
||||||
InsOrdHashMap.lookup relName relationshipInfo
|
InsOrdHashMap.lookup relName relationshipInfo
|
||||||
@ -215,14 +215,14 @@ parseLogicalModelField relationshipInfo column logimoField = do
|
|||||||
<> commaSeparated (map relNameToTxt (InsOrdHashMap.keys relationshipInfo))
|
<> commaSeparated (map relNameToTxt (InsOrdHashMap.keys relationshipInfo))
|
||||||
<> "]."
|
<> "]."
|
||||||
)
|
)
|
||||||
logicalModelObjectRelationshipField @b @r @m @n lmtrReference relationship
|
logicalModelObjectRelationshipField @b @r @m @n lmtrReference (nullableFromBool lmtrNullable) relationship
|
||||||
( LogicalModelField
|
( LogicalModelField
|
||||||
{ lmfType =
|
{ lmfType =
|
||||||
LogicalModelTypeArray
|
LogicalModelTypeArray
|
||||||
( LogicalModelTypeArrayC
|
( LogicalModelTypeArrayC
|
||||||
{ lmtaArray =
|
{ lmtaArray =
|
||||||
LogicalModelTypeReference (LogicalModelTypeReferenceC {lmtrReference}),
|
LogicalModelTypeReference (LogicalModelTypeReferenceC {lmtrReference, lmtrNullable = innerNullability}),
|
||||||
lmtaNullable
|
lmtaNullable = arrayNullability
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -232,9 +232,12 @@ parseLogicalModelField relationshipInfo column logimoField = do
|
|||||||
relName <- hoistMaybe $ columnToRelName @b column
|
relName <- hoistMaybe $ columnToRelName @b column
|
||||||
-- lookup the reference in the data source
|
-- lookup the reference in the data source
|
||||||
relationship <- hoistMaybe $ InsOrdHashMap.lookup relName relationshipInfo
|
relationship <- hoistMaybe $ InsOrdHashMap.lookup relName relationshipInfo
|
||||||
let nullability = if lmtaNullable then Nullable else NotNullable
|
|
||||||
|
|
||||||
logicalModelArrayRelationshipField @b @r @m @n lmtrReference nullability relationship
|
logicalModelArrayRelationshipField @b @r @m @n
|
||||||
|
lmtrReference
|
||||||
|
(nullableFromBool arrayNullability)
|
||||||
|
(nullableFromBool innerNullability)
|
||||||
|
relationship
|
||||||
( LogicalModelField
|
( LogicalModelField
|
||||||
{ lmfType =
|
{ lmfType =
|
||||||
LogicalModelTypeArray
|
LogicalModelTypeArray
|
||||||
@ -250,6 +253,10 @@ parseLogicalModelField relationshipInfo column logimoField = do
|
|||||||
) ->
|
) ->
|
||||||
throw500 "Nested arrays are not currently implemented"
|
throw500 "Nested arrays are not currently implemented"
|
||||||
|
|
||||||
|
nullableFromBool :: Bool -> Nullable
|
||||||
|
nullableFromBool True = Nullable
|
||||||
|
nullableFromBool False = NotNullable
|
||||||
|
|
||||||
defaultLogicalModelSelectionSet ::
|
defaultLogicalModelSelectionSet ::
|
||||||
forall b r m n.
|
forall b r m n.
|
||||||
( MonadBuildSchema b r m n,
|
( MonadBuildSchema b r m n,
|
||||||
@ -421,9 +428,10 @@ logicalModelObjectRelationshipField ::
|
|||||||
MonadBuildSchema b r m n
|
MonadBuildSchema b r m n
|
||||||
) =>
|
) =>
|
||||||
LogicalModelName ->
|
LogicalModelName ->
|
||||||
|
Nullable ->
|
||||||
RelInfo b ->
|
RelInfo b ->
|
||||||
MaybeT (SchemaT r m) (FieldParser n (AnnotatedField b))
|
MaybeT (SchemaT r m) (FieldParser n (AnnotatedField b))
|
||||||
logicalModelObjectRelationshipField logicalModelName ri | riType ri == ObjRel =
|
logicalModelObjectRelationshipField logicalModelName nullability ri | riType ri == ObjRel =
|
||||||
case riTarget ri of
|
case riTarget ri of
|
||||||
RelTargetNativeQuery nativeQueryName -> do
|
RelTargetNativeQuery nativeQueryName -> do
|
||||||
nativeQueryInfo <- lift $ askNativeQueryInfo nativeQueryName
|
nativeQueryInfo <- lift $ askNativeQueryInfo nativeQueryName
|
||||||
@ -443,16 +451,22 @@ logicalModelObjectRelationshipField logicalModelName ri | riType ri == ObjRel =
|
|||||||
relFieldName <- lift $ textToName $ relNameToTxt $ riName ri
|
relFieldName <- lift $ textToName $ relNameToTxt $ riName ri
|
||||||
|
|
||||||
let objectRelDesc = Just $ G.Description "An object relationship"
|
let objectRelDesc = Just $ G.Description "An object relationship"
|
||||||
|
|
||||||
nativeQueryParser <- MaybeT $ selectNativeQueryObject nativeQueryInfo relFieldName objectRelDesc
|
nativeQueryParser <- MaybeT $ selectNativeQueryObject nativeQueryInfo relFieldName objectRelDesc
|
||||||
|
|
||||||
|
-- this only affects the generated GraphQL type
|
||||||
|
let nullabilityModifier =
|
||||||
|
case nullability of
|
||||||
|
Nullable -> id
|
||||||
|
NotNullable -> IP.nonNullableField
|
||||||
|
|
||||||
pure
|
pure
|
||||||
|
$ nullabilityModifier
|
||||||
$ nativeQueryParser
|
$ nativeQueryParser
|
||||||
<&> \selectExp ->
|
<&> \selectExp ->
|
||||||
IR.AFObjectRelation (IR.AnnRelationSelectG (riName ri) (riMapping ri) selectExp)
|
IR.AFObjectRelation (IR.AnnRelationSelectG (riName ri) (riMapping ri) nullability selectExp)
|
||||||
RelTargetTable _otherTableName -> do
|
RelTargetTable _otherTableName -> do
|
||||||
throw500 "Object relationships from logical models to tables are not implemented"
|
throw500 "Object relationships from logical models to tables are not implemented"
|
||||||
logicalModelObjectRelationshipField _ _ =
|
logicalModelObjectRelationshipField _ _ _ =
|
||||||
hoistMaybe Nothing -- the target logical model expected an object relationship, but this was an array
|
hoistMaybe Nothing -- the target logical model expected an object relationship, but this was an array
|
||||||
|
|
||||||
-- | Field parsers for a logical model relationship
|
-- | Field parsers for a logical model relationship
|
||||||
@ -463,9 +477,10 @@ logicalModelArrayRelationshipField ::
|
|||||||
) =>
|
) =>
|
||||||
LogicalModelName ->
|
LogicalModelName ->
|
||||||
Nullable ->
|
Nullable ->
|
||||||
|
Nullable ->
|
||||||
RelInfo b ->
|
RelInfo b ->
|
||||||
MaybeT (SchemaT r m) (FieldParser n (AnnotatedField b))
|
MaybeT (SchemaT r m) (FieldParser n (AnnotatedField b))
|
||||||
logicalModelArrayRelationshipField logicalModelName nullability ri | riType ri == ArrRel =
|
logicalModelArrayRelationshipField logicalModelName arrayNullability innerNullability ri | riType ri == ArrRel =
|
||||||
case riTarget ri of
|
case riTarget ri of
|
||||||
RelTargetNativeQuery nativeQueryName -> do
|
RelTargetNativeQuery nativeQueryName -> do
|
||||||
nativeQueryInfo <- lift $ askNativeQueryInfo nativeQueryName
|
nativeQueryInfo <- lift $ askNativeQueryInfo nativeQueryName
|
||||||
@ -485,15 +500,15 @@ logicalModelArrayRelationshipField logicalModelName nullability ri | riType ri =
|
|||||||
|
|
||||||
let objectRelDesc = Just $ G.Description "An array relationship"
|
let objectRelDesc = Just $ G.Description "An array relationship"
|
||||||
|
|
||||||
nativeQueryParser <- MaybeT $ selectNativeQuery nativeQueryInfo relFieldName nullability objectRelDesc
|
nativeQueryParser <- MaybeT $ selectNativeQuery nativeQueryInfo relFieldName arrayNullability objectRelDesc
|
||||||
|
|
||||||
pure
|
pure
|
||||||
$ nativeQueryParser
|
$ nativeQueryParser
|
||||||
<&> \selectExp ->
|
<&> \selectExp ->
|
||||||
IR.AFArrayRelation
|
IR.AFArrayRelation
|
||||||
$ IR.ASSimple
|
$ IR.ASSimple
|
||||||
$ IR.AnnRelationSelectG (riName ri) (riMapping ri) selectExp
|
$ IR.AnnRelationSelectG (riName ri) (riMapping ri) innerNullability selectExp
|
||||||
RelTargetTable _otherTableName -> do
|
RelTargetTable _otherTableName -> do
|
||||||
throw500 "Array relationships from logical models to tables are not implemented"
|
throw500 "Array relationships from logical models to tables are not implemented"
|
||||||
logicalModelArrayRelationshipField _ _ _ =
|
logicalModelArrayRelationshipField _ _ _ _ =
|
||||||
hoistMaybe Nothing -- the target logical model expected an array relationship, but this was an object
|
hoistMaybe Nothing -- the target logical model expected an array relationship, but this was an object
|
||||||
|
@ -292,7 +292,7 @@ convExtRel sqlGen fieldInfoMap relName mAlias selQ sessVarBldr prepValBldr = do
|
|||||||
when misused $ throw400 UnexpectedPayload objRelMisuseMsg
|
when misused $ throw400 UnexpectedPayload objRelMisuseMsg
|
||||||
pure
|
pure
|
||||||
$ Left
|
$ Left
|
||||||
$ AnnRelationSelectG (fromMaybe relName mAlias) colMapping
|
$ AnnRelationSelectG (fromMaybe relName mAlias) colMapping Nullable
|
||||||
$ AnnObjectSelectG (_asnFields annSel) (FromTable relTableName)
|
$ AnnObjectSelectG (_asnFields annSel) (FromTable relTableName)
|
||||||
$ _tpFilter
|
$ _tpFilter
|
||||||
$ _asnPerm annSel
|
$ _asnPerm annSel
|
||||||
@ -303,6 +303,7 @@ convExtRel sqlGen fieldInfoMap relName mAlias selQ sessVarBldr prepValBldr = do
|
|||||||
$ AnnRelationSelectG
|
$ AnnRelationSelectG
|
||||||
(fromMaybe relName mAlias)
|
(fromMaybe relName mAlias)
|
||||||
colMapping
|
colMapping
|
||||||
|
Nullable
|
||||||
annSel
|
annSel
|
||||||
where
|
where
|
||||||
pgWhenRelErr = "only relationships can be expanded"
|
pgWhenRelErr = "only relationships can be expanded"
|
||||||
|
@ -18,6 +18,7 @@ module Hasura.RQL.IR.Select.Lenses
|
|||||||
aarAnnSelect,
|
aarAnnSelect,
|
||||||
aarColumnMapping,
|
aarColumnMapping,
|
||||||
aarRelationshipName,
|
aarRelationshipName,
|
||||||
|
aarNullable,
|
||||||
anosSupportsNestedObjects,
|
anosSupportsNestedObjects,
|
||||||
anosColumn,
|
anosColumn,
|
||||||
anosFields,
|
anosFields,
|
||||||
|
@ -12,12 +12,14 @@ import Hasura.Prelude
|
|||||||
import Hasura.RQL.Types.Backend
|
import Hasura.RQL.Types.Backend
|
||||||
import Hasura.RQL.Types.BackendType
|
import Hasura.RQL.Types.BackendType
|
||||||
import Hasura.RQL.Types.Common
|
import Hasura.RQL.Types.Common
|
||||||
|
import Hasura.RQL.Types.Relationships.Local (Nullable)
|
||||||
|
|
||||||
-- Local relationship
|
-- Local relationship
|
||||||
|
|
||||||
data AnnRelationSelectG (b :: BackendType) a = AnnRelationSelectG
|
data AnnRelationSelectG (b :: BackendType) a = AnnRelationSelectG
|
||||||
{ _aarRelationshipName :: RelName, -- Relationship name
|
{ _aarRelationshipName :: RelName, -- Relationship name
|
||||||
_aarColumnMapping :: HashMap (Column b) (Column b), -- Column of left table to join with
|
_aarColumnMapping :: HashMap (Column b) (Column b), -- Column of left table to join with
|
||||||
|
_aarNullable :: Nullable, -- is the target object allowed to be missing?
|
||||||
_aarAnnSelect :: a -- Current table. Almost ~ to SQL Select
|
_aarAnnSelect :: a -- Current table. Almost ~ to SQL Select
|
||||||
}
|
}
|
||||||
deriving stock (Functor, Foldable, Traversable)
|
deriving stock (Functor, Foldable, Traversable)
|
||||||
|
Loading…
Reference in New Issue
Block a user