chore(server): respect logical model array nullability

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9303
GitOrigin-RevId: 4d38a125a6889e2b0be34905e21a78036a77881e
This commit is contained in:
Daniel Harvey 2023-05-31 01:14:16 +01:00 committed by hasura-bot
parent 866ce9c3e7
commit 9de3db4729
5 changed files with 51 additions and 23 deletions

View File

@ -49,6 +49,7 @@ data LogicalModelColumn
| LogicalModelReference
{ logicalModelColumnName :: Text,
logicalModelColumnReference :: Text,
logicalModelColumnNullable :: Bool,
logicalModelColumnReferenceType :: ReferenceType
}
deriving (Show, Eq)
@ -67,6 +68,7 @@ logicalModelArrayReference name ref =
LogicalModelReference
{ logicalModelColumnName = name,
logicalModelColumnReference = ref,
logicalModelColumnNullable = False,
logicalModelColumnReferenceType = ArrayReference
}
@ -75,6 +77,7 @@ logicalModelObjectReference name ref =
LogicalModelReference
{ logicalModelColumnName = name,
logicalModelColumnReference = ref,
logicalModelColumnNullable = False,
logicalModelColumnReferenceType = ObjectReference
}
@ -103,20 +106,23 @@ trackLogicalModelCommand sourceName backendTypeConfig (LogicalModel {logicalMode
LogicalModelReference
{ logicalModelColumnReferenceType = ObjectReference,
logicalModelColumnReference,
logicalModelColumnName
logicalModelColumnName,
logicalModelColumnNullable
} ->
J.object
$ [ ("name" .= logicalModelColumnName),
( "type",
J.object
[ ("logical_model" .= logicalModelColumnReference)
[ "logical_model" .= logicalModelColumnReference,
"nullable" .= logicalModelColumnNullable
]
)
]
LogicalModelReference
{ logicalModelColumnReferenceType = ArrayReference,
logicalModelColumnReference,
logicalModelColumnName
logicalModelColumnName,
logicalModelColumnNullable
} ->
J.object
$ [ ("name" .= logicalModelColumnName),
@ -126,7 +132,8 @@ trackLogicalModelCommand sourceName backendTypeConfig (LogicalModel {logicalMode
J.object
$ [ ("logical_model" .= logicalModelColumnReference)
]
)
),
"nullable" .= logicalModelColumnNullable
]
)
]

View File

@ -331,9 +331,10 @@ class (BackendLogicalModelSelectSchema b) => BackendNativeQuerySelectSchema (b :
(MonadBuildSourceSchema b r m n) =>
NativeQueryInfo b ->
G.Name ->
Nullable ->
Maybe G.Description ->
SchemaT r m (Maybe (FieldParser n (AnnSimpleSelectG b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))))
selectNativeQuery _ _ _ = pure Nothing
selectNativeQuery _ _ _ _ = pure Nothing
selectNativeQueryObject ::
(MonadBuildSchema b r m n) =>

View File

@ -66,7 +66,7 @@ import Hasura.RQL.Types.Column
import Hasura.RQL.Types.Common (RelName (..), RelType (..), relNameToTxt)
import Hasura.RQL.Types.Metadata.Object
import Hasura.RQL.Types.Permission qualified as Permission
import Hasura.RQL.Types.Relationships.Local (RelInfo (..), RelTarget (..))
import Hasura.RQL.Types.Relationships.Local (Nullable (..), RelInfo (..), RelTarget (..))
import Hasura.RQL.Types.Roles (RoleName, adminRoleName)
import Hasura.RQL.Types.Source
import Hasura.RQL.Types.SourceCustomization
@ -128,6 +128,7 @@ buildLogicalModelFields ::
BackendLogicalModelSelectSchema b
) =>
InsOrdHashMap RelName (RelInfo b) ->
Nullable ->
LogicalModelInfo b ->
SchemaT
r
@ -137,8 +138,8 @@ buildLogicalModelFields ::
P.InputFieldsParser n (IR.SelectArgsG b (IR.UnpreparedValue b))
)
)
buildLogicalModelFields relationshipInfo logicalModel = runMaybeT $ do
selectionSetParser <- MaybeT $ logicalModelSelectionList @b @r @m @n relationshipInfo logicalModel
buildLogicalModelFields relationshipInfo nullability logicalModel = runMaybeT $ do
selectionSetParser <- MaybeT $ logicalModelSelectionList @b @r @m @n relationshipInfo nullability logicalModel
logicalModelsArgsParser <- lift $ logicalModelArguments @b @r @m @n logicalModel
pure (selectionSetParser, logicalModelsArgsParser)
@ -220,7 +221,8 @@ parseLogicalModelField relationshipInfo column logimoField = do
LogicalModelTypeArray
( LogicalModelTypeArrayC
{ lmtaArray =
LogicalModelTypeReference (LogicalModelTypeReferenceC {lmtrReference})
LogicalModelTypeReference (LogicalModelTypeReferenceC {lmtrReference}),
lmtaNullable
}
)
}
@ -230,7 +232,9 @@ parseLogicalModelField relationshipInfo column logimoField = do
relName <- hoistMaybe $ columnToRelName @b column
-- lookup the reference in the data source
relationship <- hoistMaybe $ InsOrdHashMap.lookup relName relationshipInfo
logicalModelArrayRelationshipField @b @r @m @n lmtrReference relationship
let nullability = if lmtaNullable then Nullable else NotNullable
logicalModelArrayRelationshipField @b @r @m @n lmtrReference nullability relationship
( LogicalModelField
{ lmfType =
LogicalModelTypeArray
@ -286,15 +290,26 @@ defaultLogicalModelSelectionSet relationshipInfo logicalModel = runMaybeT $ do
logicalModelSelectionList ::
(MonadBuildSchema b r m n, BackendLogicalModelSelectSchema b) =>
InsOrdHashMap RelName (RelInfo b) ->
Nullable ->
LogicalModelInfo b ->
SchemaT r m (Maybe (Parser 'Output n (AnnotatedFields b)))
logicalModelSelectionList relationshipInfo logicalModel =
fmap nonNullableObjectList <$> logicalModelSelectionSet relationshipInfo logicalModel
logicalModelSelectionList relationshipInfo nullability logicalModel =
fmap nullabilityModifier <$> logicalModelSelectionSet relationshipInfo logicalModel
where
nullabilityModifier =
case nullability of
Nullable -> nullableObjectList
NotNullable -> nonNullableObjectList
-- | Converts an output type parser from object_type to [object_type!]!
nonNullableObjectList :: Parser 'Output m a -> Parser 'Output m a
nonNullableObjectList =
P.nonNullableParser . P.multiple . P.nonNullableParser
-- \| Converts an output type parser from object_type to [object_type!]!
nonNullableObjectList :: Parser 'Output m a -> Parser 'Output m a
nonNullableObjectList =
P.nonNullableParser . P.multiple . P.nonNullableParser
-- \| Converts an output type parser from object_type to [object_type!]
nullableObjectList :: Parser 'Output m a -> Parser 'Output m a
nullableObjectList =
P.multiple . P.nonNullableParser
-- | Argument to filter rows returned from table selection
-- > where: table_bool_exp
@ -447,9 +462,10 @@ logicalModelArrayRelationshipField ::
MonadBuildSchema b r m n
) =>
LogicalModelName ->
Nullable ->
RelInfo b ->
MaybeT (SchemaT r m) (FieldParser n (AnnotatedField b))
logicalModelArrayRelationshipField logicalModelName ri | riType ri == ArrRel =
logicalModelArrayRelationshipField logicalModelName nullability ri | riType ri == ArrRel =
case riTarget ri of
RelTargetNativeQuery nativeQueryName -> do
nativeQueryInfo <- lift $ askNativeQueryInfo nativeQueryName
@ -469,7 +485,7 @@ logicalModelArrayRelationshipField logicalModelName ri | riType ri == ArrRel =
let objectRelDesc = Just $ G.Description "An array relationship"
nativeQueryParser <- MaybeT $ selectNativeQuery nativeQueryInfo relFieldName objectRelDesc
nativeQueryParser <- MaybeT $ selectNativeQuery nativeQueryInfo relFieldName nullability objectRelDesc
pure
$ nativeQueryParser
@ -479,5 +495,5 @@ logicalModelArrayRelationshipField logicalModelName ri | riType ri == ArrRel =
$ IR.AnnRelationSelectG (riName ri) (riMapping ri) selectExp
RelTargetTable _otherTableName -> do
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

View File

@ -30,6 +30,7 @@ import Hasura.RQL.IR.Select qualified as IR
import Hasura.RQL.IR.Value (Provenance (FromInternal), UnpreparedValue (UVParameter))
import Hasura.RQL.Types.Column qualified as Column
import Hasura.RQL.Types.Metadata.Object qualified as MO
import Hasura.RQL.Types.Relationships.Local (Nullable (..))
import Hasura.RQL.Types.Schema.Options qualified as Options
import Hasura.RQL.Types.Source
( SourceInfo (_siCustomization, _siName),
@ -106,13 +107,15 @@ defaultSelectNativeQuery ::
NativeQueryInfo b ->
-- field name
G.Name ->
-- are fields nullable?
Nullable ->
-- field description, if any
Maybe G.Description ->
SchemaT
r
m
(Maybe (P.FieldParser n (IR.AnnSimpleSelectG b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))))
defaultSelectNativeQuery NativeQueryInfo {..} fieldName description = runMaybeT $ do
defaultSelectNativeQuery NativeQueryInfo {..} fieldName nullability description = runMaybeT $ do
nativeQueryArgsParser <-
nativeQueryArgumentsSchema @b @r @m @n fieldName _nqiArguments
@ -129,7 +132,7 @@ defaultSelectNativeQuery NativeQueryInfo {..} fieldName description = runMaybeT
$ buildLogicalModelPermissions @b @r @m @n _nqiReturns
(selectionListParser, logicalModelsArgsParser) <-
MaybeT $ buildLogicalModelFields _nqiRelationships _nqiReturns
MaybeT $ buildLogicalModelFields _nqiRelationships nullability _nqiReturns
let sourceObj =
MO.MOSourceObjId
@ -175,7 +178,7 @@ defaultBuildNativeQueryRootFields ::
defaultBuildNativeQueryRootFields nqi@NativeQueryInfo {..} = do
let fieldName = getNativeQueryName _nqiRootFieldName
description = G.Description <$> _nqiDescription
(fmap . fmap . fmap) QDBMultipleRows (defaultSelectNativeQuery nqi fieldName description)
(fmap . fmap . fmap) QDBMultipleRows (defaultSelectNativeQuery nqi fieldName NotNullable description)
nativeQueryArgumentsSchema ::
forall b r m n.

View File

@ -21,6 +21,7 @@ import Hasura.RQL.IR.Select qualified as IR
import Hasura.RQL.IR.Value (Provenance (FromInternal), UnpreparedValue (UVParameter))
import Hasura.RQL.Types.Column qualified as Column
import Hasura.RQL.Types.Metadata.Object qualified as MO
import Hasura.RQL.Types.Relationships.Local (Nullable (..))
import Hasura.RQL.Types.Schema.Options qualified as Options
import Hasura.RQL.Types.Source
( SourceInfo (_siCustomization, _siName),
@ -65,7 +66,7 @@ defaultBuildStoredProcedureRootFields StoredProcedureInfo {..} = runMaybeT $ do
$ buildLogicalModelPermissions @b @r @m @n _spiReturns
(selectionSetParser, logicalModelsArgsParser) <-
MaybeT $ buildLogicalModelFields mempty _spiReturns
MaybeT $ buildLogicalModelFields mempty NotNullable _spiReturns
let arguments spArgs =
HashMap.mapWithKey