-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
179 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// Check correct result set when bounds each match different multikeys SERVER-958 | ||
|
||
t = db.jstests_indexk; | ||
t.drop(); | ||
|
||
t.insert({a:[1,10]}); | ||
|
||
assert.eq( 1, t.count({a: {$gt:2, $lt:5}}) ); | ||
assert.eq( 1, t.count({a: {$gt:2}}) ); | ||
assert.eq( 1, t.count({a: {$lt:5}}) ); | ||
|
||
assert.eq( 1, t.count({a: {$gt:5, $lt:2}}) ); | ||
assert.eq( 1, t.count({a: {$gt:5}}) ); | ||
assert.eq( 1, t.count({a: {$lt:2}}) ); | ||
|
||
t.ensureIndex({a:1}); | ||
|
||
// Check that only one constraint limits the index range for a multikey index. | ||
// The constraint used is arbitrary, but testing current behavior here. | ||
|
||
assert.eq( 1, t.count({a: {$gt: 2, $lt:5}}) ); | ||
e = t.find({a: {$gt: 2, $lt:5}}).explain(); | ||
assert.eq( 1, e.nscanned ); | ||
assert.eq( 1, e.n ); | ||
assert.eq( 2, e.indexBounds.a[ 0 ][ 0 ] ); | ||
// Check that upper bound is large ( > 5 ). | ||
assert.lt( 1000, e.indexBounds.a[ 0 ][ 1 ] ); | ||
|
||
assert.eq( 1, t.count({a: {$lt: 5, $gt:2}}) ); | ||
e = t.find({a: {$lt: 5, $gt:2}}).explain(); | ||
assert.eq( 1, e.nscanned ); | ||
assert.eq( 1, e.n ); | ||
// Check that upper bound is low ( < 2 ). | ||
assert.gt( -1000, e.indexBounds.a[ 0 ][ 0 ] ); | ||
assert.eq( 5, e.indexBounds.a[ 0 ][ 1 ] ); | ||
|
||
// Now check cases where no match is possible with a single key index. | ||
|
||
assert.eq( 1, t.count({a: {$gt: 5, $lt:2}}) ); | ||
e = t.find({a: {$gt: 5, $lt:2}}).explain(); | ||
assert.eq( 1, e.nscanned ); | ||
assert.eq( 1, e.n ); | ||
assert.eq( 5, e.indexBounds.a[ 0 ][ 0 ] ); | ||
// Check that upper bound is low ( < 2 ). | ||
assert.lt( 1000, e.indexBounds.a[ 0 ][ 1 ] ); | ||
|
||
assert.eq( 1, t.count({a: {$lt: 2, $gt:5}}) ); | ||
e = t.find({a: {$lt: 2, $gt:5}}).explain(); | ||
assert.eq( 1, e.nscanned ); | ||
assert.eq( 1, e.n ); | ||
// Check that upper bound is large ( > 5 ). | ||
assert.gt( -1000, e.indexBounds.a[ 0 ][ 0 ] ); | ||
assert.eq( 2, e.indexBounds.a[ 0 ][ 1 ] ); | ||
|
||
assert.eq( 1, t.count({a: {$gt: 2}}) ); | ||
assert.eq( 1, t.count({a: {$lt: 5}}) ); | ||
|
||
// Check good performance of single key index |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Check fast detection of empty result set with a single key index SERVER-958. | ||
|
||
t = db.jstests_indexn; | ||
t.drop(); | ||
|
||
function checkImpossibleMatchDummyCursor( explain ) { | ||
assert.eq( 'BasicCursor', explain.cursor ); | ||
assert.eq( 0, explain.nscanned ); | ||
assert.eq( 0, explain.n ); | ||
} | ||
|
||
t.save( {a:1,b:[1,2]} ); | ||
|
||
t.ensureIndex( {a:1} ); | ||
t.ensureIndex( {b:1} ); | ||
|
||
assert.eq( 0, t.count( {a:{$gt:5,$lt:0}} ) ); | ||
// {a:1} is a single key index, so no matches are possible for this query | ||
checkImpossibleMatchDummyCursor( t.find( {a:{$gt:5,$lt:0}} ).explain() ); | ||
|
||
assert.eq( 0, t.count( {a:{$gt:5,$lt:0},b:2} ) ); | ||
checkImpossibleMatchDummyCursor( t.find( {a:{$gt:5,$lt:0},b:2} ).explain() ); | ||
|
||
assert.eq( 0, t.count( {a:{$gt:5,$lt:0},b:{$gt:0,$lt:5}} ) ); | ||
checkImpossibleMatchDummyCursor( t.find( {a:{$gt:5,$lt:0},b:{$gt:0,$lt:5}} ).explain() ); | ||
|
||
assert.eq( 1, t.count( {$or:[{a:{$gt:5,$lt:0}},{a:1}]} ) ); | ||
checkImpossibleMatchDummyCursor( t.find( {$or:[{a:{$gt:5,$lt:0}},{a:1}]} ).explain().clauses[ 0 ] ); | ||
|
||
// A following invalid range is eliminated. | ||
assert.eq( 1, t.count( {$or:[{a:1},{a:{$gt:5,$lt:0}}]} ) ); | ||
assert.eq( null, t.find( {$or:[{a:1},{a:{$gt:5,$lt:0}}]} ).explain().clauses ); | ||
|
||
t.save( {a:2} ); | ||
|
||
// An intermediate invalid range is eliminated. | ||
assert.eq( 2, t.count( {$or:[{a:1},{a:{$gt:5,$lt:0}},{a:2}]} ) ); | ||
explain = t.find( {$or:[{a:1},{a:{$gt:5,$lt:0}},{a:2}]} ).explain(); | ||
assert.eq( 2, explain.clauses.length ); | ||
assert.eq( [[1,1]], explain.clauses[ 0 ].indexBounds.a ); | ||
assert.eq( [[2,2]], explain.clauses[ 1 ].indexBounds.a ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Check that dummy basic cursors work correctly SERVER-958. | ||
|
||
t = db.jstests_indexo; | ||
t.drop(); | ||
|
||
function checkDummyCursor( explain ) { | ||
assert.eq( "BasicCursor", explain.cursor ); | ||
assert.eq( 0, explain.nscanned ); | ||
assert.eq( 0, explain.n ); | ||
} | ||
|
||
t.save( {a:1} ); | ||
|
||
t.ensureIndex( {a:1} ); | ||
|
||
// Match is impossible, so no documents should be scanned. | ||
checkDummyCursor( t.find( {a:{$gt:5,$lt:0}} ).explain() ); | ||
|
||
t.drop(); | ||
checkDummyCursor( t.find( {a:1} ).explain() ); | ||
|
||
t.save( {a:1} ); | ||
t.ensureIndex( {a:1} ); | ||
checkDummyCursor( t.find( {$or:[{a:{$gt:5,$lt:0}},{a:1}]} ).explain().clauses[ 0 ] ); | ||
|
||
t.drop(); | ||
t.save( {a:5,b:[1,2]} ); | ||
t.ensureIndex( {a:1,b:1} ); | ||
t.ensureIndex( {a:1} ); | ||
// The first clause will use index {a:1,b:1} with the current implementation. | ||
// The second clause has no valid values for index {a:1} so it will use a dummy cursor. | ||
checkDummyCursor( t.find( {$or:[{b:{$exists:true},a:{$gt:4}},{a:{$lt:6,$gt:4}}]} ).explain().clauses[ 1 ] ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Check elimination of proper range type when popping a $or clause SERVER-958. | ||
|
||
t = db.jstests_ori; | ||
t.drop(); | ||
|
||
t.ensureIndex( {a:1,b:1} ); | ||
t.ensureIndex( {a:1,c:1} ); | ||
|
||
t.save( {a:1,b:[2,3],c:4} ); | ||
t.save( {a:10,b:2,c:4} ); | ||
|
||
// Check that proper results are returned. | ||
|
||
assert.eq( 2, t.count( {$or:[{a:{$gt:0,$lt:5},b:2},{a:10,c:4}]} ) ); | ||
// Two $or clauses expected to be scanned. | ||
assert.eq( 2, t.find( {$or:[{a:{$gt:0,$lt:5},b:2},{a:10,c:4}]} ).explain().clauses.length ); | ||
assert.eq( 2, t.count( {$or:[{a:10,b:2},{a:{$gt:0,$lt:5},c:4}]} ) ); | ||
|
||
t.drop(); | ||
|
||
// Now try a different index order. | ||
|
||
t.ensureIndex( {b:1,a:1} ); | ||
t.ensureIndex( {a:1,c:1} ); | ||
|
||
t.save( {a:1,b:[2,3],c:4} ); | ||
t.save( {a:10,b:2,c:4} ); | ||
|
||
assert.eq( 2, t.count( {$or:[{a:{$gt:0,$lt:5},b:2},{a:10,c:4}]} ) ); | ||
assert.eq( 2, t.count( {$or:[{a:10,b:2},{a:{$gt:0,$lt:5},c:4}]} ) ); | ||
|
||
t.drop(); | ||
|
||
// Now eliminate a range. | ||
|
||
t.ensureIndex( {a:1} ); | ||
t.ensureIndex( {b:1} ); | ||
|
||
t.save( {a:[1,2],b:1} ); | ||
t.save( {a:10,b:1} ); | ||
|
||
assert.eq( 2, t.count( {$or:[{a:{$gt:0,$lt:5}},{a:10,b:1}]} ) ); | ||
// Because a:1 is multikey, the value a:10 is scanned with the first clause. | ||
assert.isnull( t.find( {$or:[{a:{$gt:0,$lt:5}},{a:10,b:1}]} ).explain().clauses ); | ||
|
||
assert.eq( 2, t.count( {$or:[{a:{$lt:5,$gt:0}},{a:10,b:1}]} ) ); | ||
// Now a:10 is not scanned in the first clause so the second clause is not eliminated. | ||
assert.eq( 2, t.find( {$or:[{a:{$lt:5,$gt:0}},{a:10,b:1}]} ).explain().clauses.length ); |