* SelectUpdateCandidate finds at most 1 document to update, locks the row, * writes the updated value of the document to updateCandidate (if no update happened it sets it to NULL), * and returns whether a document was found. */
| 3384 | * and returns whether a document was found. |
| 3385 | */ |
| 3386 | static bool |
| 3387 | SelectUpdateCandidate(MongoCollection *collection, int64 shardKeyHash, |
| 3388 | UpdateOneParams *updateOneParams, UpdateCandidate *updateCandidate, |
| 3389 | bool getOriginalDocument, bool *hasOnlyObjectIdFilter) |
| 3390 | { |
| 3391 | uint64 planId = QUERY_UPDATE_SELECT_UPDATE_CANDIDATE; |
| 3392 | SPI_connect(); |
| 3393 | |
| 3394 | List *sortFieldDocuments = updateOneParams->sort != NULL ? |
| 3395 | BsonValueDocumentDecomposeFields(updateOneParams->sort) : |
| 3396 | NIL; |
| 3397 | int argCount = list_length(sortFieldDocuments); |
| 3398 | |
| 3399 | bool queryHasNonIdFilters = false; |
| 3400 | bool isIdFilterCollationAwareIgnore = false; |
| 3401 | pgbson *objectIdFilter = |
| 3402 | GetObjectIdFilterFromQueryDocumentValue(updateOneParams->query, |
| 3403 | &queryHasNonIdFilters, |
| 3404 | &isIdFilterCollationAwareIgnore); |
| 3405 | *hasOnlyObjectIdFilter = objectIdFilter != NULL && !queryHasNonIdFilters; |
| 3406 | |
| 3407 | int nextSqlArgIndex = 1; |
| 3408 | bool foundDocument = false; |
| 3409 | |
| 3410 | StringInfoData updateQuery; |
| 3411 | initStringInfo(&updateQuery); |
| 3412 | |
| 3413 | appendStringInfo(&updateQuery, "SELECT ctid, object_id, document, tableoid FROM"); |
| 3414 | |
| 3415 | if (collection->shardTableName[0] != '\0') |
| 3416 | { |
| 3417 | appendStringInfo(&updateQuery, " %s.%s", ApiDataSchemaName, |
| 3418 | collection->shardTableName); |
| 3419 | } |
| 3420 | else |
| 3421 | { |
| 3422 | appendStringInfo(&updateQuery, " %s.documents_" UINT64_FORMAT, ApiDataSchemaName, |
| 3423 | collection->collectionId); |
| 3424 | } |
| 3425 | |
| 3426 | appendStringInfo(&updateQuery, " WHERE "); |
| 3427 | |
| 3428 | const bson_value_t *variableSpec = updateOneParams->variableSpec; |
| 3429 | pgbson *variableSpecBson = NULL; |
| 3430 | if (queryHasNonIdFilters) |
| 3431 | { |
| 3432 | variableSpecBson = variableSpec != NULL && |
| 3433 | variableSpec->value_type == BSON_TYPE_DOCUMENT ? |
| 3434 | PgbsonInitFromDocumentBsonValue(variableSpec) : NULL; |
| 3435 | } |
| 3436 | |
| 3437 | bool applyVariableSpec = variableSpecBson != NULL; |
| 3438 | bool hasFilter = false; |
| 3439 | if (queryHasNonIdFilters) |
| 3440 | { |
| 3441 | if (applyVariableSpec) |
| 3442 | { |
| 3443 | planId = QUERY_UPDATE_SELECT_UPDATE_CANDIDATE_NON_OBJECT_ID_LET_AND_COLLATION; |
no test coverage detected