* GinBsonExtractRegex generates the index term needed to match * $regex on a dotted path and value. * In this case, We return a lower bound value of the min value for that path. * Since we set the PartialMatch value to be true, the min value will be considered * a lower bound for the indexed search. * We also pass 'extraData' being the regex text being queried. This will later be treated * a
| 2681 | * i.e. a BsonElement. |
| 2682 | */ |
| 2683 | static Datum * |
| 2684 | GinBsonExtractQueryRegex(BsonExtractQueryArgs *args) |
| 2685 | { |
| 2686 | int32 *nentries = args->nentries; |
| 2687 | bool **partialmatch = args->partialmatch; |
| 2688 | Pointer **extra_data = args->extra_data; |
| 2689 | pgbsonelement queryElement = args->filterElement; |
| 2690 | |
| 2691 | if ((queryElement.bsonValue.value_type != BSON_TYPE_UTF8) && |
| 2692 | (queryElement.bsonValue.value_type != BSON_TYPE_REGEX)) |
| 2693 | { |
| 2694 | ereport(ERROR, (errcode(ERRCODE_DOCUMENTDB_BADVALUE), errmsg( |
| 2695 | "$regex must be provided with a string value"))); |
| 2696 | } |
| 2697 | |
| 2698 | int32_t numEntries = 2; |
| 2699 | bool isRegexValue = false; |
| 2700 | if (queryElement.bsonValue.value_type == BSON_TYPE_REGEX) |
| 2701 | { |
| 2702 | numEntries++; |
| 2703 | isRegexValue = true; |
| 2704 | } |
| 2705 | |
| 2706 | *nentries = numEntries; |
| 2707 | Datum *entries = (Datum *) palloc(sizeof(Datum) * numEntries); |
| 2708 | *partialmatch = (bool *) palloc0(sizeof(bool) * numEntries); |
| 2709 | (*partialmatch)[0] = true; |
| 2710 | (*partialmatch)[1] = false; |
| 2711 | |
| 2712 | if (isRegexValue) |
| 2713 | { |
| 2714 | (*partialmatch)[2] = false; |
| 2715 | } |
| 2716 | |
| 2717 | *extra_data = (Pointer *) palloc(sizeof(Pointer) * numEntries); |
| 2718 | |
| 2719 | /* now create a bson for that path which has the min value for the field */ |
| 2720 | /* We set this as string.Empty but this can be set as the prefix expression */ |
| 2721 | /* for the regex (i.e. the lowest possible value that can match a regex) */ |
| 2722 | pgbsonelement emptyStringElement = queryElement; |
| 2723 | emptyStringElement.bsonValue.value_type = BSON_TYPE_UTF8; |
| 2724 | emptyStringElement.bsonValue.value.v_utf8.str = ""; |
| 2725 | emptyStringElement.bsonValue.value.v_utf8.len = 0; |
| 2726 | |
| 2727 | entries[0] = PointerGetDatum(SerializeBsonIndexTerm(&emptyStringElement, |
| 2728 | &args->termMetadata). |
| 2729 | indexTermVal); |
| 2730 | |
| 2731 | entries[1] = GenerateRootTruncatedTerm(&args->termMetadata); |
| 2732 | |
| 2733 | if (isRegexValue) |
| 2734 | { |
| 2735 | /* Also match for the regex itself */ |
| 2736 | entries[2] = PointerGetDatum(SerializeBsonIndexTerm(&queryElement, |
| 2737 | &args->termMetadata). |
| 2738 | indexTermVal); |
| 2739 | } |
| 2740 |
no test coverage detected