* GinBsonExtractQueryNotIn generates the index term needed to match * inequality 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. * Additionally, we return the root term as well. This is used in * consistent to produce the inverse set of the items in the array. * The query is expe
| 2537 | * i.e. a BsonElement. |
| 2538 | */ |
| 2539 | static Datum * |
| 2540 | GinBsonExtractQueryNotIn(BsonExtractQueryArgs *args) |
| 2541 | { |
| 2542 | int32 *nentries = args->nentries; |
| 2543 | bool **partialmatch = args->partialmatch; |
| 2544 | Pointer **extra_data = args->extra_data; |
| 2545 | int32_t termCount, index; |
| 2546 | Datum *entries; |
| 2547 | pgbsonelement queryElement = args->filterElement; |
| 2548 | |
| 2549 | if (queryElement.bsonValue.value_type != BSON_TYPE_ARRAY) |
| 2550 | { |
| 2551 | ereport(ERROR, (errcode(ERRCODE_DOCUMENTDB_BADVALUE), errmsg( |
| 2552 | "Expected 'array' type for $in but found '%s' type", |
| 2553 | BsonTypeName(queryElement.bsonValue.value_type)))); |
| 2554 | } |
| 2555 | |
| 2556 | bson_iter_t arrayIter; |
| 2557 | bson_iter_init_from_data(&arrayIter, queryElement.bsonValue.value.v_doc.data, |
| 2558 | queryElement.bsonValue.value.v_doc.data_len); |
| 2559 | |
| 2560 | termCount = 0; |
| 2561 | while (bson_iter_next(&arrayIter)) |
| 2562 | { |
| 2563 | const bson_value_t *arrayValue = bson_iter_value(&arrayIter); |
| 2564 | |
| 2565 | /* Make sure there is no $op (except $regex) in the $in/$nin array. It fails with exact same error for both $in/$nin. */ |
| 2566 | if (!IsValidBsonDocumentForDollarInOrNinOp(arrayValue)) |
| 2567 | { |
| 2568 | ereport(ERROR, (errcode(ERRCODE_DOCUMENTDB_BADVALUE), errmsg( |
| 2569 | "cannot nest $ under $in"))); |
| 2570 | } |
| 2571 | termCount++; |
| 2572 | } |
| 2573 | |
| 2574 | /* we generate 5 more possible terms 1 for the root term, root exists term, |
| 2575 | * the non exists term, multi-key term and the truncated term if needed. |
| 2576 | * We also may add the literal undefined if there's $ne null. |
| 2577 | */ |
| 2578 | termCount += 6; |
| 2579 | entries = (Datum *) palloc(sizeof(Datum) * termCount); |
| 2580 | index = 0; |
| 2581 | |
| 2582 | bson_iter_init_from_data(&arrayIter, queryElement.bsonValue.value.v_doc.data, |
| 2583 | queryElement.bsonValue.value.v_doc.data_len); |
| 2584 | DollarArrayOpQueryData *queryData = palloc0(sizeof(DollarArrayOpQueryData)); |
| 2585 | |
| 2586 | /* The last slot is used to store the pointer to the info (bool) whether any |
| 2587 | * of the array elements inside $nin is null or not. Hence a '+ 1' here. |
| 2588 | * The other slots are pointer to the regex patterns, if they exists, in |
| 2589 | * in the $nin array */ |
| 2590 | *extra_data = (Pointer *) palloc0((sizeof(Pointer) * (termCount + 1))); |
| 2591 | *partialmatch = (bool *) palloc0(sizeof(bool) * termCount); |
| 2592 | bool *partialMatchArray = *partialmatch; |
| 2593 | Pointer *extraDataArray = *extra_data; |
| 2594 | |
| 2595 | while (bson_iter_next(&arrayIter)) |
| 2596 | { |
no test coverage detected