这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 3 additions & 63 deletions docs/graphql/manual/api-reference/mutation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -238,34 +238,11 @@ Mutation Response
^^^^^^^^^^^^^^^^^
.. code-block:: none

# if table has atleast one primary key or
# one unique constraint with not null columns
{
affected_rows
returning {
col-field1
col-field2
..
relation1{
relation1-field1
relation1-field2
..
}
relation2{
relation2-field1
relation2-field2
..
}
..
}
}

# if table has no primary key or unique constraints
{
affected_rows
returning {
col-field1
col-field2
response-field1
response-field2
..
}
}
Expand All @@ -274,22 +251,6 @@ E.g.:

.. code-block:: graphql

# if table has atleast one primary key or
# one unique constraint with not null columns
{
affected_rows
returning {
id
author_id
articles{
id
title
content
}
}
}

# if table has no primary key or unique constraints
{
affected_rows
returning {
Expand All @@ -305,8 +266,6 @@ E.g.:

.. code-block:: none

# if table has atleast one primary key or
# one unique constraint with not null columns
objects: [
{
field1: value,
Expand All @@ -323,23 +282,12 @@ E.g.:
},
..
]

# if table has no primary key or unique constraints
objects: [
{
col_field1: value,
col_field2: value
..
},
..
]
# no nested objects

E.g.:

.. code-block:: graphql

# if table has atleast one primary key or
# one unique constraint with not null columns
objects: [
{
title: "Software is eating the world",
Expand All @@ -353,14 +301,6 @@ E.g.:
}
]

# if table has no primary key or unique constraints
objects: [
{
title: "Software is eating the world",
content: "This week, Hewlett-Packard..."
}
]

.. _ConflictClause:

**on_conflict** argument
Expand Down
6 changes: 2 additions & 4 deletions docs/graphql/manual/mutations/delete.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,8 @@ See the :ref:`delete mutation API reference <delete_syntax>` for the full specif

.. note::

- If a table is not in the ``public`` Postgres schema, the delete mutation field will be of the format
``delete_<schema_name>_<table_name>``.
- To fetch nested objects using relationships in the mutation response, the table needs to have either a primary
key or a unique constraint with not null columns.
If a table is not in the ``public`` Postgres schema, the delete mutation field will be of the format
``delete_<schema_name>_<table_name>``.

Delete based on an object's fields
----------------------------------
Expand Down
15 changes: 2 additions & 13 deletions docs/graphql/manual/mutations/insert.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,8 @@ See the :ref:`insert mutation API reference <insert_upsert_syntax>` for the full

.. note::

- If a table is not in the ``public`` Postgres schema, the insert mutation field will be of the format
``insert_<schema_name>_<table_name>``.
- To fetch nested objects using relationships in the mutation response, the table needs to have either a primary
key or a unique constraint with not null columns.
If a table is not in the ``public`` Postgres schema, the insert mutation field will be of the format
``insert_<schema_name>_<table_name>``.

Insert a single object
----------------------
Expand Down Expand Up @@ -217,10 +215,6 @@ Insert an object and get a nested object in response
}
}

.. note::

For this to work, the parent table (*in this case,* ``article``) needs to have either a primary key or a
unique constraint.

Insert an object and its nested object in the same mutation
-----------------------------------------------------------
Expand Down Expand Up @@ -276,11 +270,6 @@ in the response
}
}

.. note::

For this to work, the parent table (*in this case,* ``article``) needs to have either a primary key or a
unique constraint.

Insert an object with a JSONB column
------------------------------------
**Example:** Insert a new ``author`` object with a JSONB ``address`` column
Expand Down
3 changes: 1 addition & 2 deletions docs/graphql/manual/mutations/update.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,9 @@ See the :ref:`update mutation API reference <update_syntax>` for the full specif

- At least any one of ``_set``, ``_inc`` operators or the jsonb operators ``_append``, ``_prepend``, ``_delete_key``,
``_delete_elem``, ``_delete_at_path`` is required.

- If a table is not in the ``public`` Postgres schema, the update mutation field will be of the format
``update_<schema_name>_<table_name>``.
- To fetch nested objects using relationships in the mutation response, the table needs to have either a primary
key or a unique constraint with not null columns.

Update based on an object's fields
----------------------------------
Expand Down
4 changes: 0 additions & 4 deletions docs/graphql/manual/mutations/upsert.rst
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,6 @@ You can specify ``on_conflict`` clause while inserting nested objects
}
}

.. note::

For this to work, the parent table (*in this case,* ``author``) needs to have either a primary key or a
unique constraint.

.. admonition:: Edge-cases

Expand Down
10 changes: 5 additions & 5 deletions server/src-lib/Hasura/GraphQL/Context.hs
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,15 @@ data UpdOpCtx
, _uocHeaders :: ![T.Text]
, _uocFilter :: !AnnBoolExpSQL
, _uocPresetCols :: !PreSetCols
, _uocUniqCols :: !(Maybe [PGColInfo])
, _uocAllCols :: ![PGColInfo]
} deriving (Show, Eq)

data DelOpCtx
= DelOpCtx
{ _docTable :: !QualifiedTable
, _docHeaders :: ![T.Text]
, _docFilter :: !AnnBoolExpSQL
, _docUniqCols :: !(Maybe [PGColInfo])
{ _docTable :: !QualifiedTable
, _docHeaders :: ![T.Text]
, _docFilter :: !AnnBoolExpSQL
, _docAllCols :: ![PGColInfo]
} deriving (Show, Eq)

data OpCtx
Expand Down
1 change: 0 additions & 1 deletion server/src-lib/Hasura/GraphQL/Resolve/ContextTypes.hs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ data InsCtx
, icSet :: !PreSetCols
, icRelations :: !RelationInfoMap
, icUpdPerm :: !(Maybe UpdPermForIns)
, icUniqCols :: !(Maybe [PGColInfo])
} deriving (Show, Eq)

type InsCtxMap = Map.HashMap QualifiedTable InsCtx
Expand Down
67 changes: 21 additions & 46 deletions server/src-lib/Hasura/GraphQL/Resolve/Insert.hs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ data AnnIns a
, _aiView :: !QualifiedTable
, _aiTableCols :: ![PGColInfo]
, _aiDefVals :: !(Map.HashMap PGCol S.SQLExp)
, _aiUniqCols :: !(Maybe [PGColInfo])
} deriving (Show, Eq, Functor, Foldable, Traversable)

type SingleObjIns = AnnIns AnnInsObj
Expand Down Expand Up @@ -121,14 +120,14 @@ traverseInsObj rim (gName, annVal) defVal@(AnnInsObj cols objRels arrRels) =
throw500 $ "relation " <> relName <<> " not found"

let rTable = riRTable relInfo
InsCtx rtView rtCols rtDefVals rtRelInfoMap rtUpdPerm rtUniqCols <- getInsCtx rTable
InsCtx rtView rtCols rtDefVals rtRelInfoMap rtUpdPerm <- getInsCtx rTable

withPathK (G.unName gName) $ case riType relInfo of
ObjRel -> do
dataObj <- asObject dataVal
annDataObj <- mkAnnInsObj rtRelInfoMap dataObj
ccM <- forM onConflictM $ parseOnConflict rTable rtUpdPerm
let singleObjIns = AnnIns annDataObj ccM rtView rtCols rtDefVals rtUniqCols
let singleObjIns = AnnIns annDataObj ccM rtView rtCols rtDefVals
objRelIns = RelIns singleObjIns relInfo
return (AnnInsObj cols (objRelIns:objRels) arrRels)

Expand All @@ -139,7 +138,7 @@ traverseInsObj rim (gName, annVal) defVal@(AnnInsObj cols objRels arrRels) =
dataObj <- asObject arrDataVal
mkAnnInsObj rtRelInfoMap dataObj
ccM <- forM onConflictM $ parseOnConflict rTable rtUpdPerm
let multiObjIns = AnnIns annDataObjs ccM rtView rtCols rtDefVals rtUniqCols
let multiObjIns = AnnIns annDataObjs ccM rtView rtCols rtDefVals
arrRelIns = RelIns multiObjIns relInfo
return (AnnInsObj cols objRels (arrRelIns:arrRels))
-- if array relation insert input data has empty objects
Expand Down Expand Up @@ -200,7 +199,8 @@ mkInsertQ vn onConflictM insCols tableCols defVals role = do
(givenCols, args) <- flip runStateT Seq.Empty $ toSQLExps insCols
let sqlConflict = RI.toSQLConflict <$> onConflictM
sqlExps = mkSQLRow defVals givenCols
sqlInsert = S.SQLInsert vn tableCols [sqlExps] sqlConflict $ Just S.returningStar
valueExp = S.ValuesExp [S.TupleExp sqlExps]
sqlInsert = S.SQLInsert vn tableCols valueExp sqlConflict $ Just S.returningStar
adminIns = return (CTEExp (S.CTEInsert sqlInsert) args, Nothing)
nonAdminInsert = do
ccM <- mapM RI.extractConflictCtx onConflictM
Expand All @@ -209,19 +209,6 @@ mkInsertQ vn onConflictM insCols tableCols defVals role = do

bool nonAdminInsert adminIns $ isAdmin role

mkBoolExp
:: (MonadError QErr m, MonadState PrepArgs m)
=> QualifiedTable -> [(PGColInfo, PGColValue)]
-> m S.BoolExp
mkBoolExp _ [] = return $ S.BELit False
mkBoolExp tn colInfoVals =
RB.toSQLBoolExp (S.mkQual tn) . BoolAnd <$>
mapM (fmap BoolFld . uncurry f) colInfoVals
where
f ci@(PGColInfo _ colTy _) colVal =
AVCol ci . pure . AEQ True <$>
prepare (AnnPGVal Nothing True colTy colVal)

asSingleObject
:: MonadError QErr m
=> [ColVals] -> m (Maybe ColVals)
Expand Down Expand Up @@ -250,18 +237,9 @@ mkSelCTE
-> [PGColInfo]
-> Maybe ColVals
-> m CTEExp
mkSelCTE tn uniqCols colValM = do
(whereExp, args) <- case colValM of
Nothing -> return (S.BELit False, Seq.empty)
Just colVal -> do
colInfoWithVals <- fetchFromColVals colVal uniqCols id
flip runStateT Seq.Empty $ mkBoolExp tn colInfoWithVals
let sqlSel = S.mkSelect { S.selExtr = [S.selectStar]
, S.selFrom = Just $ S.mkSimpleFromExp tn
, S.selWhere = Just $ S.WhereFrag whereExp
}

return $ CTEExp (S.CTESelect sqlSel) args
mkSelCTE tn allCols colValM = do
selCTE <- mkSelCTEFromColVals tn allCols $ maybe [] pure colValM
return $ CTEExp selCTE Seq.Empty

execCTEExp
:: Bool
Expand Down Expand Up @@ -389,32 +367,29 @@ insertObj strfyNum role tn singleObjIns addCols = do
addInsCols = mkPGColWithTypeAndVal allCols addCols
finalInsCols = cols <> objRelInsCols <> addInsCols

-- prepare final returning columns
let arrDepCols = concatMap (map fst . riMapping . _riRelInfo) arrRels
arrDepColsWithInfo = getColInfos arrDepCols allCols

-- prepare insert query as with expression
(CTEExp cte insPArgs, ccM) <-
mkInsertQ vn onConflictM finalInsCols (map pgiName allCols) defVals role
uniqCols <- onNothing uniqColsM $ throw500 "unique columns not found in relational insert"

RI.setConflictCtx ccM
MutateResp affRows colVals <-
mutateAndFetchCols tn (uniqCols `union` arrDepColsWithInfo) (cte, insPArgs) strfyNum
MutateResp affRows colVals <- mutateAndFetchCols tn allCols (cte, insPArgs) strfyNum
colValM <- asSingleObject colVals
cteExp <- mkSelCTE tn uniqCols colValM
cteExp <- mkSelCTE tn allCols colValM

arrRelAffRows <- bool (withArrRels arrDepColsWithInfo colValM) (return 0) $ null arrRels
arrRelAffRows <- bool (withArrRels colValM) (return 0) $ null arrRels
let totAffRows = objRelAffRows + affRows + arrRelAffRows

return (totAffRows, cteExp)
where
AnnIns annObj onConflictM vn allCols defVals uniqColsM = singleObjIns
AnnIns annObj onConflictM vn allCols defVals = singleObjIns
AnnInsObj cols objRels arrRels = annObj

withArrRels arrDepCols colValM = do
arrRelDepCols = flip getColInfos allCols $
concatMap (map fst . riMapping . _riRelInfo) arrRels

withArrRels colValM = do
colVal <- onNothing colValM $ throw400 NotSupported cannotInsArrRelErr
arrDepColsWithVal <- fetchFromColVals colVal arrDepCols pgiName
arrDepColsWithVal <- fetchFromColVals colVal arrRelDepCols pgiName

arrInsARows <- forM arrRels $ insertArrRel strfyNum role arrDepColsWithVal

Expand All @@ -438,7 +413,7 @@ insertMultipleObjects
insertMultipleObjects strfyNum role tn multiObjIns addCols mutFlds errP =
bool withoutRelsInsert withRelsInsert anyRelsToInsert
where
AnnIns insObjs onConflictM vn tableColInfos defVals uniqCols = multiObjIns
AnnIns insObjs onConflictM vn tableColInfos defVals = multiObjIns
singleObjInserts = multiToSingles multiObjIns
insCols = map _aioColumns insObjs
allInsObjRels = concatMap _aioObjRels insObjs
Expand All @@ -460,7 +435,7 @@ insertMultipleObjects strfyNum role tn multiObjIns addCols mutFlds errP =
rowsWithCol <- mapM toSQLExps withAddCols
return $ map (mkSQLRow defVals) rowsWithCol

let insQP1 = RI.InsertQueryP1 tn vn tableCols sqlRows onConflictM mutFlds uniqCols
let insQP1 = RI.InsertQueryP1 tn vn tableCols sqlRows onConflictM mutFlds tableColInfos
p1 = (insQP1, prepArgs)
bool (RI.nonAdminInsert strfyNum p1) (RI.insertP2 strfyNum p1) $ isAdmin role

Expand Down Expand Up @@ -502,11 +477,11 @@ convertInsert role tn fld = prefixErrPath fld $ do
bool (withNonEmptyObjs annVals mutFlds) (withEmptyObjs mutFlds) $ null annVals
where
withNonEmptyObjs annVals mutFlds = do
InsCtx vn tableCols defValMap relInfoMap updPerm uniqCols <- getInsCtx tn
InsCtx vn tableCols defValMap relInfoMap updPerm <- getInsCtx tn
annObjs <- mapM asObject annVals
annInsObjs <- forM annObjs $ mkAnnInsObj relInfoMap
conflictClauseM <- forM onConflictM $ parseOnConflict tn updPerm
let multiObjIns = AnnIns annInsObjs conflictClauseM vn tableCols defValMap uniqCols
let multiObjIns = AnnIns annInsObjs conflictClauseM vn tableCols defValMap
strfyNum <- stringifyNum <$> asks getter
return $ prefixErrPath fld $ insertMultipleObjects strfyNum role tn
multiObjIns [] mutFlds "objects"
Expand Down
Loading