| 563 | |
| 564 | |
| 565 | static HeapTuple |
| 566 | PerformUpdateCore(Datum *databaseNameDatum, pgbson *updateSpec, |
| 567 | pgbsonsequence *updateDocs, text *transactionId, |
| 568 | TupleDesc resultTupDesc, WriteMode writeMode, |
| 569 | MemoryContext allocContext) |
| 570 | { |
| 571 | ThrowIfServerOrTransactionReadOnly(); |
| 572 | bson_iter_t updateCommandIter; |
| 573 | PgbsonInitIterator(updateSpec, &updateCommandIter); |
| 574 | |
| 575 | BatchUpdateResult batchResult; |
| 576 | memset(&batchResult, 0, sizeof(batchResult)); |
| 577 | batchResult.resultMemoryContext = allocContext; |
| 578 | |
| 579 | /* |
| 580 | * We first validate update command BSON and build a specification. |
| 581 | */ |
| 582 | MemoryContext oldContext = MemoryContextSwitchTo(allocContext); |
| 583 | BatchUpdateSpec *batchSpec = BuildBatchUpdateSpec(&updateCommandIter, updateDocs, |
| 584 | databaseNameDatum); |
| 585 | |
| 586 | Datum collectionNameDatum = CStringGetTextDatum(batchSpec->collectionName); |
| 587 | MongoCollection *collection = |
| 588 | GetMongoCollectionByNameDatum(*databaseNameDatum, collectionNameDatum, |
| 589 | RowExclusiveLock); |
| 590 | MemoryContextSwitchTo(oldContext); |
| 591 | |
| 592 | Datum values[2]; |
| 593 | bool isNulls[2] = { false, false }; |
| 594 | HeapTuple resultTuple; |
| 595 | if (collection == NULL) |
| 596 | { |
| 597 | /* We have to create the update spec here to ensure we track hasUpsert */ |
| 598 | oldContext = MemoryContextSwitchTo(allocContext); |
| 599 | BuildUpdates(batchSpec); |
| 600 | MemoryContextSwitchTo(oldContext); |
| 601 | |
| 602 | ValidateCollectionNameForUnauthorizedSystemNs(batchSpec->collectionName, |
| 603 | *databaseNameDatum); |
| 604 | |
| 605 | if (batchSpec->hasUpsert) |
| 606 | { |
| 607 | /* upsert on a non-existent collection creates the collection */ |
| 608 | collection = CreateCollectionForInsert(*databaseNameDatum, |
| 609 | collectionNameDatum); |
| 610 | } |
| 611 | else |
| 612 | { |
| 613 | /* |
| 614 | * Pure update without upsert on non-existent collection is a noop, |
| 615 | * but we still need to report (write) errors due to invalid query |
| 616 | * / update documents. |
| 617 | */ |
| 618 | batchResult.ok = 1; |
| 619 | batchResult.rowsMatched = 0; |
| 620 | batchResult.rowsModified = 0; |
| 621 | batchResult.writeErrors = ValidateQueryAndUpdateDocuments(batchSpec); |
| 622 | batchResult.upserted = NIL; |
no test coverage detected