* ProcessBatchInsertion iterates over the inserts array and executes each * insertion in a subtransaction, to allow us to continue after an error. * * If batchSpec->isOrdered is false, we continue with remaining tasks and * track the error for the response. * * Using subtransactions is slightly different from Mongo, which effectively * does each insert operation in a separate transaction, b
| 836 | * the same overall UX. |
| 837 | */ |
| 838 | static void |
| 839 | ProcessBatchInsertion(MongoCollection *collection, BatchInsertionSpec *batchSpec, |
| 840 | text *transactionId, BatchInsertionResult *batchResult, |
| 841 | WriteMode writeMode) |
| 842 | { |
| 843 | batchResult->ok = 1; |
| 844 | batchResult->rowsInserted = 0; |
| 845 | batchResult->writeErrors = NIL; |
| 846 | |
| 847 | ExprEvalState *evalState = NULL; |
| 848 | |
| 849 | /* Document validation occurs regardless of whether the validation action is set to error or warn. |
| 850 | * If validation fails and the action is error, an error is thrown; if the action is warn, a warning is logged. |
| 851 | * Since we do not need to log a warning in this context, we will avoid calling ValidateSchemaOnDocumentInsert when the validation action is set to warn. |
| 852 | */ |
| 853 | if (CheckSchemaValidationEnabled(collection, batchSpec->bypassDocumentValidation)) |
| 854 | { |
| 855 | evalState = PrepareForSchemaValidation(collection->schemaValidator.validator, |
| 856 | batchResult->resultMemoryContext); |
| 857 | } |
| 858 | |
| 859 | /* |
| 860 | * We cannot pass the same transactionId to BatchInsert when there are |
| 861 | * multiple inserts, since they would be considered retries of each |
| 862 | * other. We pass NULL for batch insert to disable retryable writes. |
| 863 | */ |
| 864 | if (list_length(batchSpec->documents) == 1) |
| 865 | { |
| 866 | /* So at this point, we have a single document */ |
| 867 | int insertIndex = 0; |
| 868 | if (writeMode == WriteMode_Txn_Proc && transactionId == NULL) |
| 869 | { |
| 870 | DoSingleInsert(collection, batchSpec->insertShardOid, |
| 871 | linitial(batchSpec->documents), transactionId, |
| 872 | batchResult, insertIndex, evalState); |
| 873 | } |
| 874 | else |
| 875 | { |
| 876 | ereport(DEBUG1, (errmsg("Using single insert with subtransaction"))); |
| 877 | DoSingleInsertWithSubTxn(collection, batchSpec->insertShardOid, |
| 878 | linitial(batchSpec->documents), transactionId, |
| 879 | batchResult, insertIndex, evalState); |
| 880 | } |
| 881 | } |
| 882 | else |
| 883 | { |
| 884 | /* The else scenario - we have no transactionId (or we ignore it) |
| 885 | * and/or we have more than 1 document. Do a batch insert directly. |
| 886 | */ |
| 887 | DoBatchInsertNoTransactionId(collection, batchSpec, batchResult, evalState, |
| 888 | writeMode); |
| 889 | } |
| 890 | |
| 891 | if (evalState != NULL) |
| 892 | { |
| 893 | FreeExprEvalState(evalState, batchResult->resultMemoryContext); |
| 894 | } |
| 895 | } |
no test coverage detected