* ProcessBatchDeletion iterates over the deletes array and executes each * deletion in a subtransaction, to allow us to continue after an error. * * If batchSpec->isOrdered is false, we continue with remaining tasks an * error. * * We Use subtransactions which effectively * does each delete operation in a separate transaction. */
| 602 | * does each delete operation in a separate transaction. |
| 603 | */ |
| 604 | static void |
| 605 | ProcessBatchDeletion(MongoCollection *collection, BatchDeletionSpec *batchSpec, |
| 606 | bool forceInline, text *transactionId, |
| 607 | BatchDeletionResult *batchResult) |
| 608 | { |
| 609 | PostProcessDeleteBatchSpec(batchSpec); |
| 610 | List *deletions = batchSpec->deletionsProcessed; |
| 611 | bool isOrdered = batchSpec->isOrdered; |
| 612 | |
| 613 | /* |
| 614 | * Execute the query inside a sub-transaction, so we can restore order |
| 615 | * after a failure. |
| 616 | */ |
| 617 | MemoryContext oldContext = CurrentMemoryContext; |
| 618 | ResourceOwner oldOwner = CurrentResourceOwner; |
| 619 | |
| 620 | batchResult->ok = 1; |
| 621 | batchResult->rowsDeleted = 0; |
| 622 | batchResult->writeErrors = NIL; |
| 623 | |
| 624 | /* declared volatile because of the longjmp in PG_CATCH */ |
| 625 | volatile int deleteIndex = 0; |
| 626 | |
| 627 | ListCell *deletionCell = NULL; |
| 628 | foreach(deletionCell, deletions) |
| 629 | { |
| 630 | CHECK_FOR_INTERRUPTS(); |
| 631 | |
| 632 | DeletionSpec *deletionSpec = lfirst(deletionCell); |
| 633 | |
| 634 | /* declared volatile because of the longjmp in PG_CATCH */ |
| 635 | volatile uint64 rowsDeleted = 0; |
| 636 | volatile bool isSuccess = false; |
| 637 | |
| 638 | /* use a subtransaction to correctly handle failures */ |
| 639 | BeginInternalSubTransaction(NULL); |
| 640 | |
| 641 | PG_TRY(); |
| 642 | { |
| 643 | rowsDeleted = ProcessDeletion(collection, deletionSpec, forceInline, |
| 644 | transactionId); |
| 645 | |
| 646 | /* Commit the inner transaction, return to outer xact context */ |
| 647 | ReleaseCurrentSubTransaction(); |
| 648 | MemoryContextSwitchTo(oldContext); |
| 649 | CurrentResourceOwner = oldOwner; |
| 650 | |
| 651 | isSuccess = true; |
| 652 | } |
| 653 | PG_CATCH(); |
| 654 | { |
| 655 | MemoryContextSwitchTo(oldContext); |
| 656 | ErrorData *errorData = CopyErrorDataAndFlush(); |
| 657 | |
| 658 | /* Abort inner transaction */ |
| 659 | RollbackAndReleaseCurrentSubTransaction(); |
| 660 | MemoryContextSwitchTo(oldContext); |
| 661 | CurrentResourceOwner = oldOwner; |
no test coverage detected