@@ -158,28 +158,28 @@ static std::pair<IndexDefinitions, MultikeynessTrie> buildIndexSpecsOptimizer(
158
158
159
159
std::pair<IndexDefinitions, MultikeynessTrie> result;
160
160
std::string indexHintName;
161
- bool skipAllIndexes = false ;
161
+
162
+ // True if the query has a $natural hint, indicating that we must use a collection scan.
163
+ bool hasNaturalHint = false ;
164
+
162
165
if (indexHint) {
163
166
const BSONElement element = indexHint->firstElement ();
164
167
const StringData fieldName = element.fieldNameStringData ();
165
- if (fieldName == " $natural " _sd ) {
168
+ if (fieldName == query_request_helper:: kNaturalSortField ) {
166
169
// Do not add indexes.
167
- skipAllIndexes = true ;
170
+ hasNaturalHint = true ;
168
171
} else if (fieldName == " $hint" _sd && element.type () == BSONType::String) {
169
172
indexHintName = element.valueStringData ().toString ();
170
173
}
171
174
172
- disableScan = !skipAllIndexes ;
175
+ disableScan = !hasNaturalHint ;
173
176
}
174
177
175
178
const IndexCatalog& indexCatalog = *collection->getIndexCatalog ();
176
179
177
180
auto indexIterator =
178
181
indexCatalog.getIndexIterator (opCtx, IndexCatalog::InclusionPolicy::kReady );
179
182
180
- const bool queryHasNaturalHint = indexHint && !indexHint->isEmpty () &&
181
- indexHint->firstElementFieldNameStringData () == query_request_helper::kNaturalSortField ;
182
-
183
183
while (indexIterator->more ()) {
184
184
const IndexCatalogEntry& catalogEntry = *indexIterator->next ();
185
185
const IndexDescriptor& descriptor = *catalogEntry.descriptor ();
@@ -196,32 +196,25 @@ static std::pair<IndexDefinitions, MultikeynessTrie> buildIndexSpecsOptimizer(
196
196
continue ;
197
197
}
198
198
199
- // If there is a $natural hint, we should not assert here as we will not use the index.
200
- const bool isSpecialIndex =
201
- descriptor.infoObj ().hasField (IndexDescriptor::kExpireAfterSecondsFieldName ) ||
199
+ // Check for special indexes. We do not want to try to build index metadata for a special
200
+ // index (since we do not support those yet in CQF) but we should allow the query to go
201
+ // through CQF if there is a $natural hint.
202
+ if (descriptor.infoObj ().hasField (IndexDescriptor::kExpireAfterSecondsFieldName ) ||
202
203
descriptor.isSparse () || descriptor.getIndexType () != IndexType::INDEX_BTREE ||
203
- !descriptor.collation ().isEmpty ();
204
- if (!queryHasNaturalHint && isSpecialIndex) {
205
- uasserted (ErrorCodes::InternalErrorNotSupported, " Unsupported index type" );
206
- }
207
-
208
- // We do not want to try to build index metadata for a special index (since we do not
209
- // support those yet in CQF) but we should allow the query to go through CQF if there is a
210
- // $natural hint.
211
- if (queryHasNaturalHint && isSpecialIndex) {
204
+ !descriptor.collation ().isEmpty ()) {
205
+ uassert (
206
+ ErrorCodes::InternalErrorNotSupported, " Unsupported index type" , hasNaturalHint);
212
207
continue ;
213
208
}
214
209
215
210
if (indexHint) {
216
211
if (indexHintName.empty ()) {
217
- if (!SimpleBSONObjComparator::kInstance .evaluate (descriptor.keyPattern () ==
218
- *indexHint)) {
219
- // Index key pattern does not match hint.
220
- skipIndex = true ;
221
- }
222
- } else if (indexHintName != descriptor.indexName ()) {
223
- // Index name does not match hint.
224
- skipIndex = true ;
212
+ // Index hint is a key pattern. Check if it matches this descriptor's key pattern.
213
+ skipIndex = SimpleBSONObjComparator::kInstance .evaluate (descriptor.keyPattern () !=
214
+ *indexHint);
215
+ } else {
216
+ // Index hint is an index name. Check if it matches the descriptor's name.
217
+ skipIndex = indexHintName != descriptor.indexName ();
225
218
}
226
219
}
227
220
@@ -331,7 +324,7 @@ static std::pair<IndexDefinitions, MultikeynessTrie> buildIndexSpecsOptimizer(
331
324
}
332
325
}
333
326
// For now we assume distribution is Centralized.
334
- if (!skipIndex && !skipAllIndexes ) {
327
+ if (!skipIndex && !hasNaturalHint ) {
335
328
result.first .emplace (descriptor.indexName (), std::move (indexDef));
336
329
}
337
330
}
@@ -864,7 +857,10 @@ boost::optional<ExecParams> getSBEExecutorViaCascadesOptimizer(
864
857
865
858
const auto & collection = collections.getMainCollection ();
866
859
867
- validateCommandOptions (canonicalQuery, collection, indexHint, involvedCollections);
860
+ const boost::optional<BSONObj>& hint =
861
+ (indexHint && !indexHint->isEmpty () ? indexHint : boost::none);
862
+
863
+ validateCommandOptions (canonicalQuery, collection, hint, involvedCollections);
868
864
869
865
const bool requireRID = canonicalQuery ? canonicalQuery->getForceGenerateRecordId () : false ;
870
866
const bool collectionExists = static_cast <bool >(collection);
@@ -882,7 +878,7 @@ boost::optional<ExecParams> getSBEExecutorViaCascadesOptimizer(
882
878
collection,
883
879
involvedCollections,
884
880
nss,
885
- indexHint ,
881
+ hint ,
886
882
scanProjName,
887
883
uuidStr,
888
884
scanDefName,
0 commit comments