* ExtractUpdateCandidateFromSPI extracts the update candidate fields from * the current SPI result set. Must be called while SPI context is still * active (before SPI_finish) so that SPI_datumTransfer can copy data out. * * Expects columns: ctid, object_id, document, tableoid. */
| 3619 | * Expects columns: ctid, object_id, document, tableoid. |
| 3620 | */ |
| 3621 | static void |
| 3622 | ExtractUpdateCandidateFromSPI(UpdateOneParams *updateOneParams, |
| 3623 | UpdateCandidate *updateCandidate, |
| 3624 | bool getOriginalDocument) |
| 3625 | { |
| 3626 | int rowIndex = 0; |
| 3627 | |
| 3628 | bool typeByValue = false; |
| 3629 | bool isNull = false; |
| 3630 | |
| 3631 | int columnNumber = 1; |
| 3632 | Datum tidDatum = SPI_getbinval(SPI_tuptable->vals[rowIndex], |
| 3633 | SPI_tuptable->tupdesc, |
| 3634 | columnNumber, &isNull); |
| 3635 | Assert(!isNull); |
| 3636 | |
| 3637 | int typeLength = sizeof(ItemPointerData); |
| 3638 | tidDatum = SPI_datumTransfer(tidDatum, typeByValue, typeLength); |
| 3639 | |
| 3640 | updateCandidate->tid = DatumGetItemPointer(tidDatum); |
| 3641 | |
| 3642 | columnNumber = 2; |
| 3643 | Datum objectIdDatum = SPI_getbinval(SPI_tuptable->vals[rowIndex], |
| 3644 | SPI_tuptable->tupdesc, |
| 3645 | columnNumber, &isNull); |
| 3646 | Assert(!isNull); |
| 3647 | |
| 3648 | typeLength = -1; |
| 3649 | objectIdDatum = SPI_datumTransfer(objectIdDatum, typeByValue, typeLength); |
| 3650 | |
| 3651 | updateCandidate->objectId = objectIdDatum; |
| 3652 | |
| 3653 | columnNumber = 3; |
| 3654 | Datum originalDocumentDatum = SPI_getbinval(SPI_tuptable->vals[rowIndex], |
| 3655 | SPI_tuptable->tupdesc, |
| 3656 | columnNumber, &isNull); |
| 3657 | Assert(!isNull); |
| 3658 | |
| 3659 | columnNumber = 4; |
| 3660 | Datum tableOidDatum = SPI_getbinval(SPI_tuptable->vals[rowIndex], |
| 3661 | SPI_tuptable->tupdesc, |
| 3662 | columnNumber, &isNull); |
| 3663 | Assert(!isNull); |
| 3664 | updateCandidate->tableOid = DatumGetObjectId(tableOidDatum); |
| 3665 | |
| 3666 | /* Do this inside the SPI context so that the memory gets cleaned up once we close the SPI session. */ |
| 3667 | pgbson *originalDoc = DatumGetPgBson(originalDocumentDatum); |
| 3668 | pgbson *updatedDocument = |
| 3669 | BsonUpdateDocumentWithSource(originalDoc, updateOneParams->update, |
| 3670 | updateOneParams->query, |
| 3671 | updateOneParams->arrayFilters, |
| 3672 | updateOneParams->variableSpec, |
| 3673 | updateCandidate->tid, updateCandidate->tableOid); |
| 3674 | |
| 3675 | if (updatedDocument != NULL) |
| 3676 | { |
| 3677 | Datum updatedDatum = PointerGetDatum(updatedDocument); |
| 3678 | updateCandidate->updatedDocument = SPI_datumTransfer(updatedDatum, |
no test coverage detected