Permalink
Browse files

SERVER-802 update explain format

  • Loading branch information...
1 parent 5ca4354 commit 94fab2e73fcdf50033b245ba7a9dd0174f253c27 @astaple astaple committed Jul 16, 2010
Showing with 85 additions and 71 deletions.
  1. +4 −10 db/btree.h
  2. +1 −1 db/cursor.h
  3. +1 −1 db/queryoptimizer.cpp
  4. +13 −0 db/queryutil.h
  5. +4 −4 jstests/arrayfind2.js
  6. +2 −2 jstests/hint1.js
  7. +2 −2 jstests/in3.js
  8. +22 −17 jstests/in4.js
  9. +10 −8 jstests/index7.js
  10. +1 −1 jstests/index_check2.js
  11. +4 −4 jstests/not2.js
  12. +2 −2 jstests/or4.js
  13. +2 −2 jstests/or5.js
  14. +6 −6 jstests/or6.js
  15. +11 −11 jstests/regex5.js
View
@@ -347,18 +347,12 @@ namespace mongo {
return key.replaceFieldNames( indexDetails.keyPattern() ).clientReadable();
}
- virtual BSONArray prettyIndexBounds() const {
- BSONArrayBuilder ba;
- if ( !bounds_.get() ) {
- ba << BSON_ARRAY( prettyKey( startKey ) << prettyKey( endKey ) );
+ virtual BSONObj prettyIndexBounds() const {
+ if ( !_independentFieldRanges ) {
+ return BSON( "start" << prettyKey( startKey ) << "end" << prettyKey( endKey ) );
} else {
- FieldRangeVector::Iterator i( *bounds_ );
- while( i.ok() ) {
- ba << BSON_ARRAY( prettyKey( i.startKey() ) << prettyKey( i.endKey() ) );
- i.advance();
- }
+ return bounds_->obj();
}
- return ba.arr();
}
void forgetEndKey() { endKey = BSONObj(); }
View
@@ -91,7 +91,7 @@ namespace mongo {
*/
virtual bool getsetdup(DiskLoc loc) = 0;
- virtual BSONArray prettyIndexBounds() const { return BSONArray(); }
+ virtual BSONObj prettyIndexBounds() const { return BSONArray(); }
virtual bool capped() const { return false; }
View
@@ -469,7 +469,7 @@ namespace mongo {
shared_ptr<Cursor> c = (*i)->newCursor();
BSONObjBuilder explain;
explain.append( "cursor", c->toString() );
- explain.appendArray( "indexBounds", c->prettyIndexBounds() );
+ explain.append( "indexBounds", c->prettyIndexBounds() );
arr.push_back( explain.obj() );
}
BSONObjBuilder b;
View
@@ -330,6 +330,19 @@ namespace mongo {
}
return b.obj();
}
+ BSONObj obj() const {
+ BSONObjBuilder b;
+ BSONObjIterator k( _keyPattern );
+ for( int i = 0; i < (int)_ranges.size(); ++i ) {
+ BSONArrayBuilder a( b.subarrayStart( k.next().fieldName() ) );
+ for( vector< FieldInterval >::const_iterator j = _ranges[ i ].intervals().begin();
+ j != _ranges[ i ].intervals().end(); ++j ) {
+ a << BSONArray( BSON_ARRAY( j->_lower._bound << j->_upper._bound ).clientReadable() );
+ }
+ a.done();
+ }
+ return b.obj();
+ }
bool matches( const BSONObj &obj ) const;
class Iterator {
public:
View
@@ -22,14 +22,14 @@ go( "no index" );
t.ensureIndex( { a : 1 } );
go( "index(a)" );
-assert.eq( [], t.find( { a : { $all : [ { $elemMatch : { x : 3 } } ] } } ).explain().indexBounds );
+assert.eq( {}, t.find( { a : { $all : [ { $elemMatch : { x : 3 } } ] } } ).explain().indexBounds );
t.ensureIndex( { "a.x": 1 } );
-assert.eq( [ [ {"a.x":3},{"a.x":3} ] ], t.find( { a : { $all : [ { $elemMatch : { x : 3 } } ] } } ).explain().indexBounds );
+assert.eq( {"a.x":[[3,3]]}, t.find( { a : { $all : [ { $elemMatch : { x : 3 } } ] } } ).explain().indexBounds );
// only first $elemMatch used to find bounds
-assert.eq( [ [ {"a.x":3},{"a.x":3} ] ], t.find( { a : { $all : [ { $elemMatch : { x : 3 } }, { $elemMatch : { y : 5 } } ] } } ).explain().indexBounds );
+assert.eq( {"a.x":[[3,3]]}, t.find( { a : { $all : [ { $elemMatch : { x : 3 } }, { $elemMatch : { y : 5 } } ] } } ).explain().indexBounds );
t.ensureIndex( { "a.x":1,"a.y":-1 } );
-assert.eq( [ [ {"a.x":3,"a.y":1.7976931348623157e+308},{"a.x":3,"a.y":4} ] ], t.find( { a : { $all : [ { $elemMatch : { x : 3, y : { $gt: 4 } } } ] } } ).explain().indexBounds );
+assert.eq( {"a.x":[[3,3]],"a.y":[[1.7976931348623157e+308,4]]}, t.find( { a : { $all : [ { $elemMatch : { x : 3, y : { $gt: 4 } } } ] } } ).explain().indexBounds );
View
@@ -6,5 +6,5 @@ p.save( { ts: new Date( 1 ), cls: "entry", verticals: "alleyinsider", live: true
p.ensureIndex( { ts: 1 } );
e = p.find( { live: true, ts: { $lt: new Date( 1234119308272 ) }, cls: "entry", verticals: " alleyinsider" } ).sort( { ts: -1 } ).hint( { ts: 1 } ).explain();
-assert.eq( e.indexBounds[0][0].ts.getTime(), new Date( 1234119308272 ).getTime() , "A" );
-assert.eq( 0 , e.indexBounds[0][1].ts.getTime() , "B" );
+assert.eq( e.indexBounds.ts[0][0].getTime(), new Date( 1234119308272 ).getTime() , "A" );
+assert.eq( 0 , e.indexBounds.ts[0][1].getTime() , "B" );
View
@@ -2,8 +2,8 @@ t = db.jstests_in3;
t.drop();
t.ensureIndex( {i:1} );
-assert.eq( [ [ {i:3}, {i:3} ] ], t.find( {i:{$in:[3]}} ).explain().indexBounds , "A1" );
-assert.eq( [ [ {i:3}, {i:3} ], [ {i:6}, {i:6} ] ], t.find( {i:{$in:[3,6]}} ).explain().indexBounds , "A2" );
+assert.eq( {i:[[3,3]]}, t.find( {i:{$in:[3]}} ).explain().indexBounds , "A1" );
+assert.eq( {i:[[3,3],[6,6]]}, t.find( {i:{$in:[3,6]}} ).explain().indexBounds , "A2" );
for ( var i=0; i<20; i++ )
t.insert( { i : i } );
View
@@ -1,23 +1,28 @@
t = db.jstests_in4;
function checkRanges( a, b ) {
- expectedCount = a;
- r = b;
-// printjson( r );
- assert.eq.automsg( "expectedCount", "r.length" );
- for( i in r ) {
- assert.eq.automsg( "r[ i ][ 0 ]", "r[ i ][ 1 ]" );
- }
+ assert.eq( a, b );
+// expectedCount = a;
+// r = b;
+//// printjson( r );
+// assert.eq.automsg( "expectedCount", "r.a.length" );
+// for( i in r.a ) {
+// assert.eq.automsg( "r.a[ i ][ 0 ]", "r.a[ i ][ 1 ]" );
+// }
+// assert.eq.automsg( "expectedCount", "r.b.length" );
+// for( i in r.b ) {
+// assert.eq.automsg( "r.b[ i ][ 0 ]", "r.b[ i ][ 1 ]" );
+// }
}
t.drop();
t.ensureIndex( {a:1,b:1} );
-checkRanges( 1, t.find( {a:2,b:3} ).explain().indexBounds );
-checkRanges( 2, t.find( {a:{$in:[2,3]},b:4} ).explain().indexBounds );
-checkRanges( 2, t.find( {a:2,b:{$in:[3,4]}} ).explain().indexBounds );
-checkRanges( 4, t.find( {a:{$in:[2,3]},b:{$in:[4,5]}} ).explain().indexBounds );
+checkRanges( {a:[[2,2]],b:[[3,3]]}, t.find( {a:2,b:3} ).explain().indexBounds );
+checkRanges( {a:[[2,2],[3,3]],b:[[4,4]]}, t.find( {a:{$in:[2,3]},b:4} ).explain().indexBounds );
+checkRanges( {a:[[2,2]],b:[[3,3],[4,4]]}, t.find( {a:2,b:{$in:[3,4]}} ).explain().indexBounds );
+checkRanges( {a:[[2,2],[3,3]],b:[[4,4],[5,5]]}, t.find( {a:{$in:[2,3]},b:{$in:[4,5]}} ).explain().indexBounds );
-assert.eq.automsg( "2", "t.find( {a:{$in:[2,3]},b:{$gt:4,$lt:10}} ).explain().indexBounds.length" );
+checkRanges( {a:[[2,2],[3,3]],b:[[4,10]]}, t.find( {a:{$in:[2,3]},b:{$gt:4,$lt:10}} ).explain().indexBounds );
t.save( {a:1,b:1} );
t.save( {a:2,b:4.5} );
@@ -28,7 +33,7 @@ assert.eq.automsg( "4", "t.findOne( {a:{$in:[2,3]},b:{$in:[4,5]}} ).b" );
t.drop();
t.ensureIndex( {a:1,b:1,c:1} );
-checkRanges( 2, t.find( {a:2,b:{$in:[3,4]},c:5} ).explain().indexBounds );
+checkRanges( {a:[[2,2]],b:[[3,3],[4,4]],c:[[5,5]]}, t.find( {a:2,b:{$in:[3,4]},c:5} ).explain().indexBounds );
t.save( {a:2,b:3,c:5} );
t.save( {a:2,b:3,c:4} );
@@ -41,8 +46,8 @@ assert.eq.automsg( "1", "t.find( {a:2,b:{$in:[3,4]},c:5} ).explain().nscanned" )
t.drop();
t.ensureIndex( {a:1,b:-1} );
ib = t.find( {a:2,b:{$in:[3,4]}} ).explain().indexBounds;
-checkRanges( 2, ib );
-assert.automsg( "ib[ 0 ][ 0 ].b > ib[ 1 ][ 0 ].b" );
+checkRanges( {a:[[2,2]],b:[[4,4],[3,3]]}, ib );
+assert.automsg( "ib.b[ 0 ][ 0 ] > ib.b[ 1 ][ 0 ]" );
ib = t.find( {a:2,b:{$in:[3,4]}} ).sort( {a:-1,b:1} ).explain().indexBounds;
-checkRanges( 2, ib );
-assert.automsg( "ib[ 0 ][ 0 ].b < ib[ 1 ][ 0 ].b" );
+checkRanges( {a:[[2,2]],b:[[3,3],[4,4]]}, ib );
+assert.automsg( "ib.b[ 0 ][ 0 ] < ib.b[ 1 ][ 0 ]" );
View
@@ -9,12 +9,14 @@ function noIndex( q ) {
}
function start( k, q, rev) {
- var s = q.explain().indexBounds[rev?1:0][0];
+ var exp = q.explain().indexBounds;
+ var s = {a:exp.a[rev?1:0][0],b:exp.b[0][0]};
assert.eq( k.a, s.a );
assert.eq( k.b, s.b );
}
function end( k, q, rev) {
- var e = q.explain().indexBounds[rev?1:0][1];
+ var exp = q.explain().indexBounds
+ var e = {a:exp.a[rev?1:0][1],b:exp.b[0][1]};
assert.eq( k.a, e.a );
assert.eq( k.b, e.b );
}
@@ -33,12 +35,12 @@ noIndex( f.find( { a: 5 } ).sort( { a: 1 } ).hint( { $natural: 1 } ) );
f.drop();
f.ensureIndex( { a: 1, b: 1 } );
-assert.eq( 1, f.find( { a: 1 } ).hint( { a: 1, b: 1 } ).explain().indexBounds[0][0].a );
-assert.eq( 1, f.find( { a: 1 } ).hint( { a: 1, b: 1 } ).explain().indexBounds[0][1].a );
-assert.eq( 1, f.find( { a: 1, c: 1 } ).hint( { a: 1, b: 1 } ).explain().indexBounds[0][0].a );
-assert.eq( 1, f.find( { a: 1, c: 1 } ).hint( { a: 1, b: 1 } ).explain().indexBounds[0][1].a );
-assert.eq( null, f.find( { a: 1, c: 1 } ).hint( { a: 1, b: 1 } ).explain().indexBounds[0][0].c );
-assert.eq( null, f.find( { a: 1, c: 1 } ).hint( { a: 1, b: 1 } ).explain().indexBounds[0][1].c );
+assert.eq( 1, f.find( { a: 1 } ).hint( { a: 1, b: 1 } ).explain().indexBounds.a[0][0] );
+assert.eq( 1, f.find( { a: 1 } ).hint( { a: 1, b: 1 } ).explain().indexBounds.a[0][1] );
+assert.eq( 1, f.find( { a: 1, c: 1 } ).hint( { a: 1, b: 1 } ).explain().indexBounds.a[0][0] );
+assert.eq( 1, f.find( { a: 1, c: 1 } ).hint( { a: 1, b: 1 } ).explain().indexBounds.a[0][1] );
+assert.eq( null, f.find( { a: 1, c: 1 } ).hint( { a: 1, b: 1 } ).explain().indexBounds.c );
+assert.eq( null, f.find( { a: 1, c: 1 } ).hint( { a: 1, b: 1 } ).explain().indexBounds.c );
start( { a: "a", b: 1 }, f.find( { a: /^a/, b: 1 } ).hint( { a: 1, b: 1 } ) );
start( { a: "a", b: 1 }, f.find( { a: /^a/, b: 1 } ).sort( { a: 1, b: 1 } ).hint( { a: 1, b: 1 } ) );
View
@@ -38,4 +38,4 @@ scanned3 = t.find(q3).explain().nscanned;
assert( scanned3 <= Math.max( scanned1 , scanned2 ) , "$all makes query optimizer not work well" );
exp3 = t.find( q3 ).explain();
-assert.eq( exp3.indexBounds[0][0], exp3.indexBounds[0][1], "$all range not a single key" );
+assert.eq( exp3.indexBounds.tags[0][0], exp3.indexBounds.tags[0][1], "$all range not a single key" );
View
@@ -93,11 +93,11 @@ indexed = function( query, min, max ) {
assert( exp.cursor.match( /Btree/ ), tojson( query ) );
assert( exp.allPlans.length == 1, tojson( query ) );
// just expecting one element per key
- for( i in exp.indexBounds[0][0] ) {
- assert.eq( exp.indexBounds[0][0][ i ], min );
+ for( i in exp.indexBounds ) {
+ assert.eq( exp.indexBounds[ i ][0][0], min );
}
- for( i in exp.indexBounds[0][1] ) {
- assert.eq( exp.indexBounds[0][1][ i ], max );
+ for( i in exp.indexBounds ) {
+ assert.eq( exp.indexBounds[ i ][0][1], max );
}
}
View
@@ -91,8 +91,8 @@ assert.eq.automsg( "'BtreeCursor b_1'", "t.find( {$or:[{}]} ).sort( {b:1} ).expl
assert.eq.automsg( "'BtreeCursor b_1'", "t.find( {$or:[{a:1},{a:3}]} ).sort( {b:1} ).explain().cursor" );
assert.eq.automsg( "'BtreeCursor b_1'", "t.find( {$or:[{a:1},{b:3}]} ).sort( {b:1} ).explain().cursor" );
assert.eq.automsg( "'BtreeCursor b_1'", "t.find( {$or:[{b:1}]} ).sort( {b:1} ).explain().cursor" );
-assert.eq.automsg( "1", "t.find( {$or:[{b:1}]} ).sort( {b:1} ).explain().indexBounds[ 0 ][ 0 ].b.$minElement" );
+assert.eq.automsg( "1", "t.find( {$or:[{b:1}]} ).sort( {b:1} ).explain().indexBounds.b[ 0 ][ 0 ].$minElement" );
assert.eq.automsg( "'BtreeCursor b_1'", "t.find( {$or:[{a:1}]} ).hint( {b:1} ).explain().cursor" );
assert.eq.automsg( "'BtreeCursor b_1'", "t.find( {$or:[{}]} ).hint( {b:1} ).explain().cursor" );
-assert.eq.automsg( "1", "t.find( {$or:[{b:1}]} ).hint( {b:1} ).explain().indexBounds[ 0 ][ 0 ].b" );
+assert.eq.automsg( "1", "t.find( {$or:[{b:1}]} ).hint( {b:1} ).explain().indexBounds.b[ 0 ][ 0 ]" );
View
@@ -9,8 +9,8 @@ assert.eq.automsg( "'BasicCursor'", "t.find( {$or:[{a:2},{b:3},{c:4}]} ).explain
assert.eq.automsg( "'BasicCursor'", "t.find( {$or:[{a:2},{b:3}]} ).sort( {c:1} ).explain().cursor" );
e = t.find( {$or:[{a:2},{b:3}]} ).sort( {a:1} ).explain();
assert.eq.automsg( "'BtreeCursor a_1'", "e.cursor" );
-assert.eq.automsg( "1", "e.indexBounds[ 0 ][ 0 ].a.$minElement" );
-assert.eq.automsg( "1", "e.indexBounds[ 0 ][ 1 ].a.$maxElement" );
+assert.eq.automsg( "1", "e.indexBounds.a[ 0 ][ 0 ].$minElement" );
+assert.eq.automsg( "1", "e.indexBounds.a[ 0 ][ 1 ].$maxElement" );
t.ensureIndex( {c:1} );
View
@@ -3,17 +3,17 @@ t.drop();
t.ensureIndex( {a:1} );
-assert.eq.automsg( "2", "t.find( {$or:[{a:{$gt:2}},{a:{$gt:0}}]} ).explain().clauses[ 1 ].indexBounds[ 0 ][ 1 ].a" );
-assert.eq.automsg( "2", "t.find( {$or:[{a:{$lt:2}},{a:{$lt:4}}]} ).explain().clauses[ 1 ].indexBounds[ 0 ][ 0 ].a" );
+assert.eq.automsg( "2", "t.find( {$or:[{a:{$gt:2}},{a:{$gt:0}}]} ).explain().clauses[ 1 ].indexBounds.a[ 0 ][ 1 ]" );
+assert.eq.automsg( "2", "t.find( {$or:[{a:{$lt:2}},{a:{$lt:4}}]} ).explain().clauses[ 1 ].indexBounds.a[ 0 ][ 0 ]" );
-assert.eq.automsg( "2", "t.find( {$or:[{a:{$gt:2,$lt:10}},{a:{$gt:0,$lt:5}}]} ).explain().clauses[ 1 ].indexBounds[ 0 ][ 1 ].a" );
-assert.eq.automsg( "0", "t.find( {$or:[{a:{$gt:2,$lt:10}},{a:{$gt:0,$lt:15}}]} ).explain().clauses[ 1 ].indexBounds[ 0 ][ 0 ].a" );
-assert.eq.automsg( "15", "t.find( {$or:[{a:{$gt:2,$lt:10}},{a:{$gt:0,$lt:15}}]} ).explain().clauses[ 1 ].indexBounds[ 0 ][ 1 ].a" );
+assert.eq.automsg( "2", "t.find( {$or:[{a:{$gt:2,$lt:10}},{a:{$gt:0,$lt:5}}]} ).explain().clauses[ 1 ].indexBounds.a[ 0 ][ 1 ]" );
+assert.eq.automsg( "0", "t.find( {$or:[{a:{$gt:2,$lt:10}},{a:{$gt:0,$lt:15}}]} ).explain().clauses[ 1 ].indexBounds.a[ 0 ][ 0 ]" );
+assert.eq.automsg( "15", "t.find( {$or:[{a:{$gt:2,$lt:10}},{a:{$gt:0,$lt:15}}]} ).explain().clauses[ 1 ].indexBounds.a[ 0 ][ 1 ]" );
// no separate clauses
assert.eq.automsg( "null", "t.find( {$or:[{a:{$gt:2,$lt:10}},{a:{$gt:3,$lt:5}}]} ).explain().clauses" );
-assert.eq.automsg( "20", "t.find( {$or:[{a:{$gt:2,$lt:10}},{a:{$gt:3,$lt:5}},{a:{$gt:20}}]} ).explain().clauses[ 1 ].indexBounds[ 0 ][ 0 ].a" );
+assert.eq.automsg( "20", "t.find( {$or:[{a:{$gt:2,$lt:10}},{a:{$gt:3,$lt:5}},{a:{$gt:20}}]} ).explain().clauses[ 1 ].indexBounds.a[ 0 ][ 0 ]" );
assert.eq.automsg( "null", "t.find( {$or:[{a:1},{b:2}]} ).hint( {a:1} ).explain().clauses" );
assert.eq.automsg( "2", "t.find( {$or:[{a:1},{a:3}]} ).hint( {a:1} ).explain().clauses.length" );
View
@@ -31,17 +31,17 @@ print( "now indexed" );
doit();
// check bound unions SERVER-322
-assert.eq( [
- [ {x:1},{x:1} ],
- [ {x:2.5},{x:2.5} ],
- [ {x:"a"},{x:"a"} ],
- [ {x:"b"},{x:"e"} ],
- [ {x:/^b/},{x:/^b/} ],
- [ {x:/^c/},{x:/^c/} ],
- [ {x:/^d/},{x:/^d/} ]
- ],
+assert.eq( {
+ x:[[1,1],
+ [2.5,2.5],
+ ["a","a"],
+ ["b","e"],
+ [/^b/,/^b/],
+ [/^c/,/^c/],
+ [/^d/,/^d/]]
+ },
t.find( { x : { $in: [ 1, 2.5, "a", "b", /^b/, /^c/, /^d/ ] } } ).explain().indexBounds );
// SERVER-505
-assert.eq( [ [ {x:"a"}, {x:"a"} ] ], t.find( { x : { $all: [ "a", /^a/ ] } } ).explain().indexBounds );
-assert.eq( [ [ {x:"a"}, {x:"b"} ] ], t.find( { x : { $all: [ /^a/ ] } } ).explain().indexBounds );
+assert.eq( {x:[["a","a"]]}, t.find( { x : { $all: [ "a", /^a/ ] } } ).explain().indexBounds );
+assert.eq( {x:[["a","b"]]}, t.find( { x : { $all: [ /^a/ ] } } ).explain().indexBounds );

0 comments on commit 94fab2e

Please sign in to comment.