SERVER-115373 Reject $type queries on _id field with invalid types (array, regex, undefined) ,add _id check #1624
+164
−0
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Background & Impact
When users mistakenly query the
_idfield with invalid types (array, regex, undefined), such as:db.collection.find({_id: {$type: 'array'}})
db.collection.find({_id: {$type: 4}})This can cause serious performance issues:
_idindex effectively because it cannot determine valid index bounds for types that can never exist (array type)Since the
_idfield can never contain Array, RegEx, or Undefined types (enforced at write time bystorage_validation.cpp), such queries are meaningless and will always return empty results while potentially causing full table scans.Solution
Add parse-time validation to reject
$typequeries on the_idfield when the requested type is invalid. This:"The '_id' field cannot be queried by type <typename>"storage_validation.cpp::storageValidIdField()Changes
expression_parser.cpp::parseType()to reject invalid types (Array, RegEx, Undefined) for_idfieldInvalidIdFielderror codeexpression_parser_test.cppTest Coverage
Error cases:
{_id: {$type: 'array'}}/{_id: {$type: 4}}{_id: {$type: 'regex'}}/{_id: {$type: 11}}{_id: {$type: 'undefined'}}/{_id: {$type: 6}}{_id: {$type: ['array', 'objectId']}}(mixed valid/invalid)Success cases:
{_id: {$type: 'string'}}/{_id: {$type: 'objectId'}}/{_id: {$type: 'number'}}{a: {$type: 'array'}}(non-_id field){_id.a: {$type: 'array'}}(nested path within _id){a._id: {$type: 'array'}}(not top-level _id)