* bson_update_document processes the update operation on a given document. * The first argument is the source document to apply the updates on. * If an empty document is specified, it is assumed to be an 'upsert' * The second argument is a bson element that is the update spec. This is of the form: * { "": }. * The third argument is the query spec used to form this up
| 166 | * This is the C entry point for the update_bson_document SQL UDF, which returns a scalar bson value. |
| 167 | */ |
| 168 | Datum |
| 169 | bson_update_document(PG_FUNCTION_ARGS) |
| 170 | { |
| 171 | /* Validate scalar bson return type (update_bson_document UDF). */ |
| 172 | TupleDesc tupleDescriptor = NULL; |
| 173 | Oid resultTypeId = InvalidOid; |
| 174 | if (get_call_result_type(fcinfo, &resultTypeId, &tupleDescriptor) != TYPEFUNC_SCALAR) |
| 175 | { |
| 176 | elog(ERROR, "return type must be a scalar type"); |
| 177 | } |
| 178 | |
| 179 | if (resultTypeId != BsonTypeId()) |
| 180 | { |
| 181 | elog(ERROR, "return type must be a single bson value"); |
| 182 | } |
| 183 | |
| 184 | if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2)) |
| 185 | { |
| 186 | /* be on the safe side fwiw */ |
| 187 | ereport(ERROR, (errmsg("sourceDocument / updateSpec / querySpec " |
| 188 | "cannot be NULL"))); |
| 189 | } |
| 190 | |
| 191 | pgbson *sourceDocument = PG_GETARG_PGBSON(0); |
| 192 | pgbson *updateSpecDoc = PG_GETARG_PGBSON(1); |
| 193 | pgbson *querySpecDoc = PG_GETARG_PGBSON(2); |
| 194 | pgbson *arrayFiltersDoc = PG_GETARG_MAYBE_NULL_PGBSON(3); |
| 195 | |
| 196 | bson_value_t variableSpec = { 0 }; |
| 197 | if (PG_NARGS() > 4 && !PG_ARGISNULL(4)) |
| 198 | { |
| 199 | pgbson *variableSpecDoc = PG_GETARG_PGBSON(4); |
| 200 | variableSpec = ConvertPgbsonToBsonValue(variableSpecDoc); |
| 201 | } |
| 202 | |
| 203 | pgbsonelement updateSpecElement; |
| 204 | PgbsonToSinglePgbsonElement(updateSpecDoc, &updateSpecElement); |
| 205 | bson_value_t querySpec = ConvertPgbsonToBsonValue(querySpecDoc); |
| 206 | pgbsonelement arrayFiltersBase = { 0 }; |
| 207 | bson_value_t *arrayFilters = NULL; |
| 208 | |
| 209 | if (arrayFiltersDoc != NULL) |
| 210 | { |
| 211 | PgbsonToSinglePgbsonElement(arrayFiltersDoc, &arrayFiltersBase); |
| 212 | arrayFilters = &arrayFiltersBase.bsonValue; |
| 213 | } |
| 214 | |
| 215 | BsonUpdateSource updateSource = { 0 }; |
| 216 | if (PG_NARGS() > 7) |
| 217 | { |
| 218 | if (!PG_ARGISNULL(6)) |
| 219 | { |
| 220 | updateSource.ctid = (ItemPointer) DatumGetPointer(PG_GETARG_DATUM(6)); |
| 221 | } |
| 222 | if (!PG_ARGISNULL(7) && PG_GETARG_OID(7) != InvalidOid) |
| 223 | { |
| 224 | updateSource.tableOid = PG_GETARG_OID(7); |
| 225 | } |
nothing calls this directly
no test coverage detected