* GinBsonExtractQueryIn generates the index term needed to match * equality on an array of dotted path and values. * In this case, we can simply return the terms as the value stored * in the index will be exactly the value being queried. * The query is expected to be of the format {path}{typeCode}{value} * i.e. a BsonElement. */
| 2409 | * i.e. a BsonElement. |
| 2410 | */ |
| 2411 | static Datum * |
| 2412 | GinBsonExtractQueryIn(BsonExtractQueryArgs *args) |
| 2413 | { |
| 2414 | int32 *nentries = args->nentries; |
| 2415 | bool **partialmatch = args->partialmatch; |
| 2416 | Pointer **extra_data = args->extra_data; |
| 2417 | int32_t inArraySize = 0, index = 0; |
| 2418 | Datum *entries; |
| 2419 | pgbsonelement queryElement = args->filterElement; |
| 2420 | |
| 2421 | if (queryElement.bsonValue.value_type != BSON_TYPE_ARRAY) |
| 2422 | { |
| 2423 | ereport(ERROR, (errcode(ERRCODE_DOCUMENTDB_BADVALUE), errmsg( |
| 2424 | "$in must contain an array of values"))); |
| 2425 | } |
| 2426 | |
| 2427 | bson_iter_t arrayIter; |
| 2428 | bson_iter_init_from_data(&arrayIter, queryElement.bsonValue.value.v_doc.data, |
| 2429 | queryElement.bsonValue.value.v_doc.data_len); |
| 2430 | |
| 2431 | bool arrayHasNull = false; |
| 2432 | while (bson_iter_next(&arrayIter)) |
| 2433 | { |
| 2434 | const bson_value_t *arrayValue = bson_iter_value(&arrayIter); |
| 2435 | |
| 2436 | /* if it is bson document and valid one for $in/$nin array. It fails with exact same error for both $in/$nin. */ |
| 2437 | if (!IsValidBsonDocumentForDollarInOrNinOp(arrayValue)) |
| 2438 | { |
| 2439 | ereport(ERROR, (errcode(ERRCODE_DOCUMENTDB_BADVALUE), errmsg( |
| 2440 | "cannot nest $ under $in"))); |
| 2441 | } |
| 2442 | |
| 2443 | inArraySize++; |
| 2444 | arrayHasNull = arrayHasNull || arrayValue->value_type == BSON_TYPE_NULL; |
| 2445 | } |
| 2446 | |
| 2447 | if (arrayHasNull) |
| 2448 | { |
| 2449 | /* one for undefined, root term, root Exists, the non exists term, and multi-key. */ |
| 2450 | inArraySize += 5; |
| 2451 | } |
| 2452 | |
| 2453 | /* allocate an additional one for truncation if necessary */ |
| 2454 | inArraySize++; |
| 2455 | |
| 2456 | DollarArrayOpQueryData *inQueryData = palloc0(sizeof(DollarArrayOpQueryData)); |
| 2457 | inQueryData->arrayHasNull = arrayHasNull; |
| 2458 | entries = (Datum *) palloc(sizeof(Datum) * inArraySize); |
| 2459 | bson_iter_init_from_data(&arrayIter, queryElement.bsonValue.value.v_doc.data, |
| 2460 | queryElement.bsonValue.value.v_doc.data_len); |
| 2461 | |
| 2462 | /* The last slot is used to store the pointer to the info (bool) whether any |
| 2463 | * of the array elements inside $in is null or not. Hence a '+ 1' here. |
| 2464 | * The other slots are pointer to the regex patterns, if they exists, in |
| 2465 | * in the $in array */ |
| 2466 | *extra_data = (Pointer *) palloc0((sizeof(Pointer) * (inArraySize + 1))); |
| 2467 | *partialmatch = (bool *) palloc0(sizeof(bool) * inArraySize); |
| 2468 |
no test coverage detected