10
10
11
11
import Data.Aeson qualified as J
12
12
import Data.HashMap.Strict qualified as Map
13
+ import Data.HashMap.Strict.Extended qualified as Map
13
14
import Data.List qualified as L
14
15
import Data.Sequence qualified as Seq
15
16
import Data.Text qualified as T
@@ -55,7 +56,7 @@ convertToSQLTransaction (IR.AnnotatedInsert fieldName isSingle annIns mutationOu
55
56
then pure $ IR. buildEmptyMutResp mutationOutput
56
57
else
57
58
withPaths [" selectionSet" , fieldName, " args" , suffix] $
58
- insertMultipleObjects annIns [] userInfo mutationOutput planVars stringifyNum
59
+ insertMultipleObjects annIns mempty userInfo mutationOutput planVars stringifyNum
59
60
where
60
61
withPaths p x = foldr ($) x $ withPathK <$> p
61
62
suffix = bool " objects" " object" isSingle
@@ -70,7 +71,7 @@ insertMultipleObjects ::
70
71
MonadReader QueryTagsComment m
71
72
) =>
72
73
IR. MultiObjectInsert ('Postgres pgKind ) PG. SQLExp ->
73
- [( PGCol , PG. SQLExp)] ->
74
+ Map. HashMap PGCol PG. SQLExp ->
74
75
UserInfo ->
75
76
IR. MutationOutput ('Postgres pgKind ) ->
76
77
Seq. Seq Q. PrepArg ->
@@ -79,21 +80,21 @@ insertMultipleObjects ::
79
80
insertMultipleObjects multiObjIns additionalColumns userInfo mutationOutput planVars stringifyNum =
80
81
bool withoutRelsInsert withRelsInsert anyRelsToInsert
81
82
where
82
- IR. AnnotatedInsertData insObjs table checkCondition columnInfos defVals (BackendInsert conflictClause) = multiObjIns
83
+ IR. AnnotatedInsertData insObjs table checkCondition columnInfos presetRow (BackendInsert conflictClause) = multiObjIns
83
84
allInsObjRels = concatMap IR. getInsertObjectRelationships insObjs
84
85
allInsArrRels = concatMap IR. getInsertArrayRelationships insObjs
85
86
anyRelsToInsert = not $ null allInsArrRels && null allInsObjRels
86
87
87
88
withoutRelsInsert = do
88
89
indexedForM_ (IR. getInsertColumns <$> insObjs) \ column ->
89
- validateInsert (map fst column) [] (map fst additionalColumns)
90
- let columnValues = map (mkSQLRow defVals) $ union additionalColumns . IR. getInsertColumns <$> insObjs
91
- columnNames = Map. keys defVals
90
+ validateInsert (map fst column) [] (Map. keys additionalColumns)
91
+ let insObjRows = Map. fromList . IR. getInsertColumns <$> insObjs
92
+ ( columnNames, insertRows) = Map. homogenise PG. columnDefaultValue $ map ((presetRow <> additionalColumns) <> ) insObjRows
92
93
insertQuery =
93
94
IR. InsertQueryP1
94
95
table
95
- columnNames
96
- columnValues
96
+ (toList columnNames)
97
+ ( map Map. elems insertRows)
97
98
conflictClause
98
99
checkCondition
99
100
mutationOutput
@@ -105,7 +106,7 @@ insertMultipleObjects multiObjIns additionalColumns userInfo mutationOutput plan
105
106
106
107
withRelsInsert = do
107
108
insertRequests <- indexedForM insObjs \ obj -> do
108
- let singleObj = IR. AnnotatedInsertData (IR. Single obj) table checkCondition columnInfos defVals (BackendInsert conflictClause)
109
+ let singleObj = IR. AnnotatedInsertData (IR. Single obj) table checkCondition columnInfos presetRow (BackendInsert conflictClause)
109
110
insertObject singleObj additionalColumns userInfo planVars stringifyNum
110
111
let affectedRows = sum $ map fst insertRequests
111
112
columnValues = mapMaybe snd insertRequests
@@ -129,23 +130,23 @@ insertObject ::
129
130
MonadReader QueryTagsComment m
130
131
) =>
131
132
IR. SingleObjectInsert ('Postgres pgKind ) PG. SQLExp ->
132
- [( PGCol , PG. SQLExp)] ->
133
+ HashMap PGCol PG. SQLExp ->
133
134
UserInfo ->
134
135
Seq. Seq Q. PrepArg ->
135
136
StringifyNumbers ->
136
137
m (Int , Maybe (ColumnValues ('Postgres pgKind ) TxtEncodedVal ))
137
138
insertObject singleObjIns additionalColumns userInfo planVars stringifyNum = Tracing. trace (" Insert " <> qualifiedObjectToText table) do
138
- validateInsert (map fst columns) (map IR. _riRelationInfo objectRels) (map fst additionalColumns)
139
+ validateInsert (Map. keys columns) (map IR. _riRelationInfo objectRels) (Map. keys additionalColumns)
139
140
140
141
-- insert all object relations and fetch this insert dependent column values
141
142
objInsRes <- forM beforeInsert $ insertObjRel planVars userInfo stringifyNum
142
143
143
144
-- prepare final insert columns
144
145
let objRelAffRows = sum $ map fst objInsRes
145
- objRelDeterminedCols = concatMap snd objInsRes
146
- finalInsCols = columns <> objRelDeterminedCols <> additionalColumns
146
+ objRelDeterminedCols = Map. fromList $ concatMap snd objInsRes
147
+ finalInsCols = presetValues <> columns <> objRelDeterminedCols <> additionalColumns
147
148
148
- let cte = mkInsertQ table onConflict finalInsCols defaultValues checkCond
149
+ let cte = mkInsertQ table onConflict finalInsCols checkCond
149
150
150
151
PGE. MutateResp affRows colVals <-
151
152
liftTx $
@@ -157,8 +158,8 @@ insertObject singleObjIns additionalColumns userInfo planVars stringifyNum = Tra
157
158
158
159
return (totAffRows, colValM)
159
160
where
160
- IR. AnnotatedInsertData (IR. Single annObj) table checkCond allColumns defaultValues (BackendInsert onConflict) = singleObjIns
161
- columns = IR. getInsertColumns annObj
161
+ IR. AnnotatedInsertData (IR. Single annObj) table checkCond allColumns presetValues (BackendInsert onConflict) = singleObjIns
162
+ columns = Map. fromList $ IR. getInsertColumns annObj
162
163
objectRels = IR. getInsertObjectRelationships annObj
163
164
arrayRels = IR. getInsertArrayRelationships annObj
164
165
@@ -220,7 +221,7 @@ insertObjRel ::
220
221
m (Int , [(PGCol , PG. SQLExp )])
221
222
insertObjRel planVars userInfo stringifyNum objRelIns =
222
223
withPathK (relNameToTxt relName) $ do
223
- (affRows, colValM) <- withPathK " data" $ insertObject singleObjIns [] userInfo planVars stringifyNum
224
+ (affRows, colValM) <- withPathK " data" $ insertObject singleObjIns mempty userInfo planVars stringifyNum
224
225
colVal <- onNothing colValM $ throw400 NotSupported errMsg
225
226
retColsWithVals <- fetchFromColVals colVal rColInfos
226
227
let columns = flip mapMaybe (Map. toList mapCols) \ (column, target) -> do
@@ -256,9 +257,10 @@ insertArrRel ::
256
257
m Int
257
258
insertArrRel resCols userInfo planVars stringifyNum arrRelIns =
258
259
withPathK (relNameToTxt $ riName relInfo) $ do
259
- let additionalColumns = flip mapMaybe resCols \ (column, value) -> do
260
- target <- Map. lookup column mapping
261
- Just (target, value)
260
+ let additionalColumns = Map. fromList $
261
+ flip mapMaybe resCols \ (column, value) -> do
262
+ target <- Map. lookup column mapping
263
+ Just (target, value)
262
264
resBS <-
263
265
withPathK " data" $
264
266
insertMultipleObjects multiObjIns additionalColumns userInfo mutOutput planVars stringifyNum
@@ -270,8 +272,12 @@ insertArrRel resCols userInfo planVars stringifyNum arrRelIns =
270
272
mapping = riMapping relInfo
271
273
mutOutput = IR. MOutMultirowFields [(" affected_rows" , IR. MCount )]
272
274
273
- -- | validate an insert object based on insert columns,
274
- -- | insert object relations and additional columns from parent
275
+ -- | Validate an insert object based on insert columns,
276
+ -- insert object relations and additional columns from parent:
277
+ --
278
+ -- * There should be no overlap between 'insCols' and 'addCols'.
279
+ -- * There should be no overlap between any object relationship columns and
280
+ -- 'insCols' and 'addCols'.
275
281
validateInsert ::
276
282
(MonadError QErr m ) =>
277
283
-- | inserting columns
@@ -307,15 +313,14 @@ mkInsertQ ::
307
313
Backend ('Postgres pgKind ) =>
308
314
QualifiedTable ->
309
315
Maybe (IR. OnConflictClause ('Postgres pgKind ) PG. SQLExp ) ->
310
- [(PGCol , PG. SQLExp )] ->
311
316
Map. HashMap PGCol PG. SQLExp ->
312
317
(AnnBoolExpSQL ('Postgres pgKind ), Maybe (AnnBoolExpSQL ('Postgres pgKind ))) ->
313
318
PG. CTE
314
- mkInsertQ table onConflictM insCols defVals (insCheck, updCheck) =
319
+ mkInsertQ table onConflictM insertRow (insCheck, updCheck) =
315
320
let sqlConflict = PGT. toSQLConflict table <$> onConflictM
316
- sqlExps = mkSQLRow defVals insCols
321
+ sqlExps = Map. elems insertRow
317
322
valueExp = PG. ValuesExp [PG. TupleExp sqlExps]
318
- tableCols = Map. keys defVals
323
+ tableCols = Map. keys insertRow
319
324
sqlInsert =
320
325
PG. SQLInsert table tableCols valueExp sqlConflict
321
326
. Just
@@ -347,13 +352,6 @@ fetchFromColVals colVal reqCols =
347
352
TELit t -> PG. SELit t
348
353
return (ciColumn ci, pgColVal)
349
354
350
- mkSQLRow :: Map. HashMap PGCol PG. SQLExp -> [(PGCol , PG. SQLExp )] -> [PG. SQLExp ]
351
- mkSQLRow defVals withPGCol = map snd $
352
- flip map (Map. toList defVals) $
353
- \ (col, defVal) -> (col,) $ fromMaybe defVal $ Map. lookup col withPGColMap
354
- where
355
- withPGColMap = Map. fromList withPGCol
356
-
357
355
decodeEncJSON :: (J. FromJSON a , QErrM m ) => EncJSON -> m a
358
356
decodeEncJSON =
359
357
either (throw500 . T. pack) decodeValue
0 commit comments