| 1217 | |
| 1218 | |
| 1219 | static void |
| 1220 | GenerateArrayPath(bson_iter_t *bsonIter, const char *pathToInsert, |
| 1221 | uint32_t pathtoInsertLength, bool inArrayContext, |
| 1222 | bool isArrayTerm, GenerateTermsContext *context, |
| 1223 | bool isCheckForArrayTermsWithNestedDocument, |
| 1224 | bool isPathMatchedRecursively) |
| 1225 | { |
| 1226 | check_stack_depth(); |
| 1227 | CHECK_FOR_INTERRUPTS(); |
| 1228 | |
| 1229 | bson_iter_t containerIter; |
| 1230 | if (!bson_iter_recurse(bsonIter, &containerIter)) |
| 1231 | { |
| 1232 | return; |
| 1233 | } |
| 1234 | |
| 1235 | /* Count the array terms - to pre-allocate the term Datum pointers */ |
| 1236 | const bson_value_t *arrayValue = bson_iter_value(bsonIter); |
| 1237 | int32_t arrayCapacityEstimate = Max(1, (int) log2(arrayValue->value.v_doc.data_len)); |
| 1238 | |
| 1239 | StringInfoData pathBuilderBuffer = { 0 }; |
| 1240 | initStringInfo(&pathBuilderBuffer); |
| 1241 | bool useReducedWildcardTerms = true; |
| 1242 | int32_t termCount[INDEX_MAX_KEYS] = { 0 }; |
| 1243 | bool recursiveMatchStatus[INDEX_MAX_KEYS] = { 0 }; |
| 1244 | int32_t numRecursiveMatches = 0; |
| 1245 | int32_t currentRecursivePathCount = context->currentRecursivePathIndex( |
| 1246 | context->pathDataState); |
| 1247 | bool considerNestedDocumentTerms = context->enableCompositeReducedCorrelatedTerms && |
| 1248 | context->updateCorrelatedTermPaths != NULL && |
| 1249 | context->maxPaths > 1; |
| 1250 | for (int i = 0; i < context->maxPaths; i++) |
| 1251 | { |
| 1252 | GinEntryPathData *pathData = context->getPathDataFunc(context->pathDataState, i); |
| 1253 | termCount[i] = pathData->terms.index; |
| 1254 | recursiveMatchStatus[i] = context->enableCompositeReducedCorrelatedTerms && |
| 1255 | context->isRecursivePathMatch(context->pathDataState, |
| 1256 | i); |
| 1257 | numRecursiveMatches += recursiveMatchStatus[i] ? 1 : 0; |
| 1258 | |
| 1259 | /* TODO: Handle wildcard and non-wildcard composite indexes: |
| 1260 | * in the scenario where we have { a.$**: 1, b: 1, c: 1} |
| 1261 | * we need this to only apply to the wildcard term being generated. |
| 1262 | */ |
| 1263 | useReducedWildcardTerms = useReducedWildcardTerms && |
| 1264 | pathData->useReducedWildcardTerms; |
| 1265 | EnsureTermCapacity(&pathData->terms, arrayCapacityEstimate); |
| 1266 | } |
| 1267 | |
| 1268 | /* Only consider this path if there's > 1 matches in an array path (otherwise they're all linearly |
| 1269 | * independent index terms anyway) |
| 1270 | */ |
| 1271 | considerNestedDocumentTerms = considerNestedDocumentTerms && numRecursiveMatches > 1; |
| 1272 | |
| 1273 | bool someArrayPathsHaveTerms[INDEX_MAX_KEYS] = { 0 }; |
| 1274 | bool someArrayPathsHaveNoTerms[INDEX_MAX_KEYS] = { 0 }; |
| 1275 | while (bson_iter_next(&containerIter)) |
| 1276 | { |
no test coverage detected