* The core implementation of BsonUpdateDocument. * Processes an update based on the updateMetadata on the sourceDocument and updateSpec. * If updateDescription is non-NULL, the update description pgbson will be written to it. * * Returns NULL if update was a no-op. */
| 464 | * Returns NULL if update was a no-op. |
| 465 | */ |
| 466 | static pgbson * |
| 467 | BsonUpdateDocumentCore(pgbson *sourceDocument, const bson_value_t *updateSpec, |
| 468 | BsonUpdateMetadata *updateMetadata, |
| 469 | BsonUpdateSource *updateSource, |
| 470 | pgbson **updateDescription) |
| 471 | { |
| 472 | bson_iter_t sourceDocumentIterator; |
| 473 | PgbsonInitIterator(sourceDocument, &sourceDocumentIterator); |
| 474 | |
| 475 | /* An empty document will be processed as an upsert operation. */ |
| 476 | bool isUpsert = !bson_iter_next(&sourceDocumentIterator); |
| 477 | |
| 478 | if (isUpsert) |
| 479 | { |
| 480 | sourceDocument = updateMetadata->sourceDocOnUpsert; |
| 481 | } |
| 482 | |
| 483 | pgbson *document; |
| 484 | BsonUpdateTracker *updateTracker = NULL; |
| 485 | if (create_update_tracker_hook != NULL) |
| 486 | { |
| 487 | updateTracker = create_update_tracker_hook(updateSource); |
| 488 | } |
| 489 | |
| 490 | /* first look up the updateSpec to determine what kind of update it is. */ |
| 491 | switch (updateMetadata->updateType) |
| 492 | { |
| 493 | case UpdateType_ReplaceDocument: |
| 494 | { |
| 495 | /* Replacement is always treated as modified document, even if the content is the same */ |
| 496 | document = ProcessReplaceDocument(sourceDocument, updateSpec, |
| 497 | isUpsert); |
| 498 | break; |
| 499 | } |
| 500 | |
| 501 | case UpdateType_Operator: |
| 502 | { |
| 503 | document = ProcessUpdateOperatorWithState(sourceDocument, |
| 504 | updateMetadata->operatorState, |
| 505 | isUpsert, |
| 506 | updateTracker); |
| 507 | |
| 508 | break; |
| 509 | } |
| 510 | |
| 511 | case UpdateType_AggregationPipeline: |
| 512 | { |
| 513 | bool isReplacement = false; |
| 514 | document = ProcessAggregationPipelineUpdate(sourceDocument, |
| 515 | updateMetadata->aggregationState, |
| 516 | isUpsert, &isReplacement); |
| 517 | |
| 518 | /* |
| 519 | * TODO: Using PgbsonEquals() here might result in incorrectly deciding |
| 520 | * that the document has been updated. For example, since |
| 521 | * {"_id": 1, "a": 1, "b": 1} != {"_id": 1, "b": 1, "a": 1}, we |
| 522 | * would report that the document has been updated in following |
| 523 | * case, but this actually shouldn't be the case: |
no test coverage detected