summaryrefslogtreecommitdiff
path: root/dbtests/queryutiltests.cpp
diff options
context:
space:
mode:
authorAntonin Kral <a.kral@bobek.cz>2012-08-29 20:54:51 +0200
committerAntonin Kral <a.kral@bobek.cz>2012-08-29 20:54:51 +0200
commit83957b73f9177f6e38bd5375bd93ca1f6a47188c (patch)
treef20b7d6ac9a9c64ff5bb6b5910a24abbb356b1d5 /dbtests/queryutiltests.cpp
parent5071d203970edd4c995493d810abe20987e76fe9 (diff)
Imported Upstream version 2.2.0upstream/2.2.0
Diffstat (limited to 'dbtests/queryutiltests.cpp')
-rw-r--r--dbtests/queryutiltests.cpp1002
1 files changed, 0 insertions, 1002 deletions
diff --git a/dbtests/queryutiltests.cpp b/dbtests/queryutiltests.cpp
deleted file mode 100644
index c3dd64d12dd..00000000000
--- a/dbtests/queryutiltests.cpp
+++ /dev/null
@@ -1,1002 +0,0 @@
-// queryutiltests.cpp : query utility unit tests
-//
-
-/**
- * Copyright (C) 2009 10gen Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "pch.h"
-#include "../db/queryutil.h"
-#include "../db/querypattern.h"
-#include "../db/instance.h"
-#include "../db/pdfile.h"
-#include "dbtests.h"
-
-namespace QueryUtilTests {
-
- namespace FieldRangeTests {
- class Base {
- public:
- virtual ~Base() {}
- void run() {
- const FieldRangeSet s( "ns", query(), true );
- checkElt( lower(), s.range( "a" ).min() );
- checkElt( upper(), s.range( "a" ).max() );
- ASSERT_EQUALS( lowerInclusive(), s.range( "a" ).minInclusive() );
- ASSERT_EQUALS( upperInclusive(), s.range( "a" ).maxInclusive() );
- }
- protected:
- virtual BSONObj query() = 0;
- virtual BSONElement lower() { return minKey.firstElement(); }
- virtual bool lowerInclusive() { return true; }
- virtual BSONElement upper() { return maxKey.firstElement(); }
- virtual bool upperInclusive() { return true; }
- static void checkElt( BSONElement expected, BSONElement actual ) {
- if ( expected.woCompare( actual, false ) ) {
- log() << "expected: " << expected << ", got: " << actual;
- ASSERT( false );
- }
- }
- };
-
-
- class NumericBase : public Base {
- public:
- NumericBase() {
- o = BSON( "min" << -numeric_limits<double>::max() << "max" << numeric_limits<double>::max() );
- }
-
- virtual BSONElement lower() { return o["min"]; }
- virtual BSONElement upper() { return o["max"]; }
- private:
- BSONObj o;
- };
-
- class Empty : public Base {
- virtual BSONObj query() { return BSONObj(); }
- };
-
- class Eq : public Base {
- public:
- Eq() : o_( BSON( "a" << 1 ) ) {}
- virtual BSONObj query() { return o_; }
- virtual BSONElement lower() { return o_.firstElement(); }
- virtual BSONElement upper() { return o_.firstElement(); }
- BSONObj o_;
- };
-
- class DupEq : public Eq {
- public:
- virtual BSONObj query() { return BSON( "a" << 1 << "b" << 2 << "a" << 1 ); }
- };
-
- class Lt : public NumericBase {
- public:
- Lt() : o_( BSON( "-" << 1 ) ) {}
- virtual BSONObj query() { return BSON( "a" << LT << 1 ); }
- virtual BSONElement upper() { return o_.firstElement(); }
- virtual bool upperInclusive() { return false; }
- BSONObj o_;
- };
-
- class Lte : public Lt {
- virtual BSONObj query() { return BSON( "a" << LTE << 1 ); }
- virtual bool upperInclusive() { return true; }
- };
-
- class Gt : public NumericBase {
- public:
- Gt() : o_( BSON( "-" << 1 ) ) {}
- virtual BSONObj query() { return BSON( "a" << GT << 1 ); }
- virtual BSONElement lower() { return o_.firstElement(); }
- virtual bool lowerInclusive() { return false; }
- BSONObj o_;
- };
-
- class Gte : public Gt {
- virtual BSONObj query() { return BSON( "a" << GTE << 1 ); }
- virtual bool lowerInclusive() { return true; }
- };
-
- class TwoLt : public Lt {
- virtual BSONObj query() { return BSON( "a" << LT << 1 << LT << 5 ); }
- };
-
- class TwoGt : public Gt {
- virtual BSONObj query() { return BSON( "a" << GT << 0 << GT << 1 ); }
- };
-
- class EqGte : public Eq {
- virtual BSONObj query() { return BSON( "a" << 1 << "a" << GTE << 1 ); }
- };
-
- class EqGteInvalid {
- public:
- void run() {
- FieldRangeSet frs( "ns", BSON( "a" << 1 << "a" << GTE << 2 ), true );
- ASSERT( !frs.matchPossible() );
- }
- };
-
- struct RegexBase : Base {
- void run() { //need to only look at first interval
- FieldRangeSet s( "ns", query(), true );
- checkElt( lower(), s.range( "a" ).intervals()[0]._lower._bound );
- checkElt( upper(), s.range( "a" ).intervals()[0]._upper._bound );
- ASSERT_EQUALS( lowerInclusive(), s.range( "a" ).intervals()[0]._lower._inclusive );
- ASSERT_EQUALS( upperInclusive(), s.range( "a" ).intervals()[0]._upper._inclusive );
- }
- };
-
- class Regex : public RegexBase {
- public:
- Regex() : o1_( BSON( "" << "abc" ) ), o2_( BSON( "" << "abd" ) ) {}
- virtual BSONObj query() {
- BSONObjBuilder b;
- b.appendRegex( "a", "^abc" );
- return b.obj();
- }
- virtual BSONElement lower() { return o1_.firstElement(); }
- virtual BSONElement upper() { return o2_.firstElement(); }
- virtual bool upperInclusive() { return false; }
- BSONObj o1_, o2_;
- };
-
- class RegexObj : public RegexBase {
- public:
- RegexObj() : o1_( BSON( "" << "abc" ) ), o2_( BSON( "" << "abd" ) ) {}
- virtual BSONObj query() { return BSON("a" << BSON("$regex" << "^abc")); }
- virtual BSONElement lower() { return o1_.firstElement(); }
- virtual BSONElement upper() { return o2_.firstElement(); }
- virtual bool upperInclusive() { return false; }
- BSONObj o1_, o2_;
- };
-
- class UnhelpfulRegex : public RegexBase {
- public:
- UnhelpfulRegex() {
- BSONObjBuilder b;
- b.appendMinForType("lower", String);
- b.appendMaxForType("upper", String);
- limits = b.obj();
- }
-
- virtual BSONObj query() {
- BSONObjBuilder b;
- b.appendRegex( "a", "abc" );
- return b.obj();
- }
- virtual BSONElement lower() { return limits["lower"]; }
- virtual BSONElement upper() { return limits["upper"]; }
- virtual bool upperInclusive() { return false; }
- BSONObj limits;
- };
-
- class In : public Base {
- public:
- In() : o1_( BSON( "-" << -3 ) ), o2_( BSON( "-" << 44 ) ) {}
- virtual BSONObj query() {
- vector< int > vals;
- vals.push_back( 4 );
- vals.push_back( 8 );
- vals.push_back( 44 );
- vals.push_back( -1 );
- vals.push_back( -3 );
- vals.push_back( 0 );
- BSONObjBuilder bb;
- bb.append( "$in", vals );
- BSONObjBuilder b;
- b.append( "a", bb.done() );
- return b.obj();
- }
- virtual BSONElement lower() { return o1_.firstElement(); }
- virtual BSONElement upper() { return o2_.firstElement(); }
- BSONObj o1_, o2_;
- };
-
- class Equality {
- public:
- void run() {
- FieldRangeSet s( "ns", BSON( "a" << 1 ), true );
- ASSERT( s.range( "a" ).equality() );
- FieldRangeSet s2( "ns", BSON( "a" << GTE << 1 << LTE << 1 ), true );
- ASSERT( s2.range( "a" ).equality() );
- FieldRangeSet s3( "ns", BSON( "a" << GT << 1 << LTE << 1 ), true );
- ASSERT( !s3.range( "a" ).equality() );
- FieldRangeSet s4( "ns", BSON( "a" << GTE << 1 << LT << 1 ), true );
- ASSERT( !s4.range( "a" ).equality() );
- FieldRangeSet s5( "ns", BSON( "a" << GTE << 1 << LTE << 1 << GT << 1 ), true );
- ASSERT( !s5.range( "a" ).equality() );
- FieldRangeSet s6( "ns", BSON( "a" << GTE << 1 << LTE << 1 << LT << 1 ), true );
- ASSERT( !s6.range( "a" ).equality() );
- }
- };
-
- class SimplifiedQuery {
- public:
- void run() {
- FieldRangeSet frs( "ns", BSON( "a" << GT << 1 << GT << 5 << LT << 10 << "b" << 4 << "c" << LT << 4 << LT << 6 << "d" << GTE << 0 << GT << 0 << "e" << GTE << 0 << LTE << 10 ), true );
- BSONObj simple = frs.simplifiedQuery();
- cout << "simple: " << simple << endl;
- ASSERT( !simple.getObjectField( "a" ).woCompare( fromjson( "{$gt:5,$lt:10}" ) ) );
- ASSERT_EQUALS( 4, simple.getIntField( "b" ) );
- ASSERT( !simple.getObjectField( "c" ).woCompare( BSON("$gte" << -numeric_limits<double>::max() << "$lt" << 4 ) ) );
- ASSERT( !simple.getObjectField( "d" ).woCompare( BSON("$gt" << 0 << "$lte" << numeric_limits<double>::max() ) ) );
- ASSERT( !simple.getObjectField( "e" ).woCompare( fromjson( "{$gte:0,$lte:10}" ) ) );
- }
- };
-
- class QueryPatternBase {
- protected:
- static QueryPattern p( const BSONObj &query, const BSONObj &sort = BSONObj() ) {
- return FieldRangeSet( "", query, true ).pattern( sort );
- }
- };
-
- class QueryPatternTest : public QueryPatternBase {
- public:
- void run() {
- ASSERT( p( BSON( "a" << 1 ) ) == p( BSON( "a" << 1 ) ) );
- ASSERT( p( BSON( "a" << 1 ) ) == p( BSON( "a" << 5 ) ) );
- ASSERT( p( BSON( "a" << 1 ) ) != p( BSON( "b" << 1 ) ) );
- ASSERT( p( BSON( "a" << 1 ) ) != p( BSON( "a" << LTE << 1 ) ) );
- ASSERT( p( BSON( "a" << 1 ) ) != p( BSON( "a" << 1 << "b" << 2 ) ) );
- ASSERT( p( BSON( "a" << 1 << "b" << 3 ) ) != p( BSON( "a" << 1 ) ) );
- ASSERT( p( BSON( "a" << LT << 1 ) ) == p( BSON( "a" << LTE << 5 ) ) );
- ASSERT( p( BSON( "a" << LT << 1 << GTE << 0 ) ) == p( BSON( "a" << LTE << 5 << GTE << 0 ) ) );
- ASSERT( p( BSON( "a" << 1 ) ) < p( BSON( "a" << 1 << "b" << 1 ) ) );
- ASSERT( !( p( BSON( "a" << 1 << "b" << 1 ) ) < p( BSON( "a" << 1 ) ) ) );
- ASSERT( p( BSON( "a" << 1 ), BSON( "b" << 1 ) ) == p( BSON( "a" << 4 ), BSON( "b" << "a" ) ) );
- ASSERT( p( BSON( "a" << 1 ), BSON( "b" << 1 ) ) == p( BSON( "a" << 4 ), BSON( "b" << -1 ) ) );
- ASSERT( p( BSON( "a" << 1 ), BSON( "b" << 1 ) ) != p( BSON( "a" << 4 ), BSON( "c" << 1 ) ) );
- ASSERT( p( BSON( "a" << 1 ), BSON( "b" << 1 << "c" << -1 ) ) == p( BSON( "a" << 4 ), BSON( "b" << -1 << "c" << 1 ) ) );
- ASSERT( p( BSON( "a" << 1 ), BSON( "b" << 1 << "c" << 1 ) ) != p( BSON( "a" << 4 ), BSON( "b" << 1 ) ) );
- ASSERT( p( BSON( "a" << 1 ), BSON( "b" << 1 ) ) != p( BSON( "a" << 4 ), BSON( "b" << 1 << "c" << 1 ) ) );
- }
- };
-
- class QueryPatternNeConstraint : public QueryPatternBase {
- public:
- void run() {
- ASSERT( p( BSON( "a" << NE << 5 ) ) != p( BSON( "a" << GT << 1 ) ) );
- ASSERT( p( BSON( "a" << NE << 5 ) ) != p( BSONObj() ) );
- ASSERT( p( BSON( "a" << NE << 5 ) ) == p( BSON( "a" << NE << "a" ) ) );
- }
- };
-
- class NoWhere {
- public:
- void run() {
- ASSERT_EQUALS( 0, FieldRangeSet( "ns", BSON( "$where" << 1 ), true ).nNontrivialRanges() );
- }
- };
-
- class Numeric {
- public:
- void run() {
- FieldRangeSet f( "", BSON( "a" << 1 ), true );
- ASSERT( f.range( "a" ).min().woCompare( BSON( "a" << 2.0 ).firstElement() ) < 0 );
- ASSERT( f.range( "a" ).min().woCompare( BSON( "a" << 0.0 ).firstElement() ) > 0 );
- }
- };
-
- class InLowerBound {
- public:
- void run() {
- FieldRangeSet f( "", fromjson( "{a:{$gt:4,$in:[1,2,3,4,5,6]}}" ), true );
- ASSERT( f.range( "a" ).min().woCompare( BSON( "a" << 5.0 ).firstElement(), false ) == 0 );
- ASSERT( f.range( "a" ).max().woCompare( BSON( "a" << 6.0 ).firstElement(), false ) == 0 );
- }
- };
-
- class InUpperBound {
- public:
- void run() {
- FieldRangeSet f( "", fromjson( "{a:{$lt:4,$in:[1,2,3,4,5,6]}}" ), true );
- ASSERT( f.range( "a" ).min().woCompare( BSON( "a" << 1.0 ).firstElement(), false ) == 0 );
- ASSERT( f.range( "a" ).max().woCompare( BSON( "a" << 3.0 ).firstElement(), false ) == 0 );
- }
- };
-
- class UnionBound {
- public:
- void run() {
- FieldRangeSet frs( "", fromjson( "{a:{$gt:1,$lt:9},b:{$gt:9,$lt:12}}" ), true );
- FieldRange ret = frs.range( "a" );
- ret |= frs.range( "b" );
- ASSERT_EQUALS( 2U, ret.intervals().size() );
- }
- };
-
- class MultiBound {
- public:
- void run() {
- FieldRangeSet frs1( "", fromjson( "{a:{$in:[1,3,5,7,9]}}" ), true );
- FieldRangeSet frs2( "", fromjson( "{a:{$in:[2,3,5,8,9]}}" ), true );
- FieldRange fr1 = frs1.range( "a" );
- FieldRange fr2 = frs2.range( "a" );
- fr1 &= fr2;
- ASSERT( fr1.min().woCompare( BSON( "a" << 3.0 ).firstElement(), false ) == 0 );
- ASSERT( fr1.max().woCompare( BSON( "a" << 9.0 ).firstElement(), false ) == 0 );
- vector< FieldInterval > intervals = fr1.intervals();
- vector< FieldInterval >::const_iterator j = intervals.begin();
- double expected[] = { 3, 5, 9 };
- for( int i = 0; i < 3; ++i, ++j ) {
- ASSERT_EQUALS( expected[ i ], j->_lower._bound.number() );
- ASSERT( j->_lower._inclusive );
- ASSERT( j->_lower == j->_upper );
- }
- ASSERT( j == intervals.end() );
- }
- };
-
- class DiffBase {
- public:
- virtual ~DiffBase() {}
- void run() {
- FieldRangeSet frs( "", fromjson( obj().toString() ), true );
- FieldRange ret = frs.range( "a" );
- ret -= frs.range( "b" );
- check( ret );
- }
- protected:
- void check( const FieldRange &fr ) {
- vector< FieldInterval > fi = fr.intervals();
- ASSERT_EQUALS( len(), fi.size() );
- int i = 0;
- for( vector< FieldInterval >::const_iterator j = fi.begin(); j != fi.end(); ++j ) {
- ASSERT_EQUALS( nums()[ i ], j->_lower._bound.numberInt() );
- ASSERT_EQUALS( incs()[ i ], j->_lower._inclusive );
- ++i;
- ASSERT_EQUALS( nums()[ i ], j->_upper._bound.numberInt() );
- ASSERT_EQUALS( incs()[ i ], j->_upper._inclusive );
- ++i;
- }
- }
- virtual unsigned len() const = 0;
- virtual const int *nums() const = 0;
- virtual const bool *incs() const = 0;
- virtual BSONObj obj() const = 0;
- };
-
- class TwoRangeBase : public DiffBase {
- public:
- TwoRangeBase( string obj, int low, int high, bool lowI, bool highI )
- : _obj( obj ) {
- _n[ 0 ] = low;
- _n[ 1 ] = high;
- _b[ 0 ] = lowI;
- _b[ 1 ] = highI;
- }
- private:
- virtual unsigned len() const { return 1; }
- virtual const int *nums() const { return _n; }
- virtual const bool *incs() const { return _b; }
- virtual BSONObj obj() const { return fromjson( _obj ); }
- string _obj;
- int _n[ 2 ];
- bool _b[ 2 ];
- };
-
- struct Diff1 : public TwoRangeBase {
- Diff1() : TwoRangeBase( "{a:{$gt:1,$lt:2},b:{$gt:3,$lt:4}}", 1, 2, false, false ) {}
- };
-
- struct Diff2 : public TwoRangeBase {
- Diff2() : TwoRangeBase( "{a:{$gt:1,$lt:2},b:{$gt:2,$lt:4}}", 1, 2, false, false ) {}
- };
-
- struct Diff3 : public TwoRangeBase {
- Diff3() : TwoRangeBase( "{a:{$gt:1,$lte:2},b:{$gt:2,$lt:4}}", 1, 2, false, true ) {}
- };
-
- struct Diff4 : public TwoRangeBase {
- Diff4() : TwoRangeBase( "{a:{$gt:1,$lt:2},b:{$gte:2,$lt:4}}", 1, 2, false, false) {}
- };
-
- struct Diff5 : public TwoRangeBase {
- Diff5() : TwoRangeBase( "{a:{$gt:1,$lte:2},b:{$gte:2,$lt:4}}", 1, 2, false, false) {}
- };
-
- struct Diff6 : public TwoRangeBase {
- Diff6() : TwoRangeBase( "{a:{$gt:1,$lte:3},b:{$gte:2,$lt:4}}", 1, 2, false, false) {}
- };
-
- struct Diff7 : public TwoRangeBase {
- Diff7() : TwoRangeBase( "{a:{$gt:1,$lte:3},b:{$gt:2,$lt:4}}", 1, 2, false, true) {}
- };
-
- struct Diff8 : public TwoRangeBase {
- Diff8() : TwoRangeBase( "{a:{$gt:1,$lt:4},b:{$gt:2,$lt:4}}", 1, 2, false, true) {}
- };
-
- struct Diff9 : public TwoRangeBase {
- Diff9() : TwoRangeBase( "{a:{$gt:1,$lt:4},b:{$gt:2,$lte:4}}", 1, 2, false, true) {}
- };
-
- struct Diff10 : public TwoRangeBase {
- Diff10() : TwoRangeBase( "{a:{$gt:1,$lte:4},b:{$gt:2,$lte:4}}", 1, 2, false, true) {}
- };
-
- class SplitRangeBase : public DiffBase {
- public:
- SplitRangeBase( string obj, int low1, bool low1I, int high1, bool high1I, int low2, bool low2I, int high2, bool high2I )
- : _obj( obj ) {
- _n[ 0 ] = low1;
- _n[ 1 ] = high1;
- _n[ 2 ] = low2;
- _n[ 3 ] = high2;
- _b[ 0 ] = low1I;
- _b[ 1 ] = high1I;
- _b[ 2 ] = low2I;
- _b[ 3 ] = high2I;
- }
- private:
- virtual unsigned len() const { return 2; }
- virtual const int *nums() const { return _n; }
- virtual const bool *incs() const { return _b; }
- virtual BSONObj obj() const { return fromjson( _obj ); }
- string _obj;
- int _n[ 4 ];
- bool _b[ 4 ];
- };
-
- struct Diff11 : public SplitRangeBase {
- Diff11() : SplitRangeBase( "{a:{$gt:1,$lte:4},b:{$gt:2,$lt:4}}", 1, false, 2, true, 4, true, 4, true) {}
- };
-
- struct Diff12 : public SplitRangeBase {
- Diff12() : SplitRangeBase( "{a:{$gt:1,$lt:5},b:{$gt:2,$lt:4}}", 1, false, 2, true, 4, true, 5, false) {}
- };
-
- struct Diff13 : public TwoRangeBase {
- Diff13() : TwoRangeBase( "{a:{$gt:1,$lt:5},b:{$gt:1,$lt:4}}", 4, 5, true, false) {}
- };
-
- struct Diff14 : public SplitRangeBase {
- Diff14() : SplitRangeBase( "{a:{$gte:1,$lt:5},b:{$gt:1,$lt:4}}", 1, true, 1, true, 4, true, 5, false) {}
- };
-
- struct Diff15 : public TwoRangeBase {
- Diff15() : TwoRangeBase( "{a:{$gt:1,$lt:5},b:{$gte:1,$lt:4}}", 4, 5, true, false) {}
- };
-
- struct Diff16 : public TwoRangeBase {
- Diff16() : TwoRangeBase( "{a:{$gte:1,$lt:5},b:{$gte:1,$lt:4}}", 4, 5, true, false) {}
- };
-
- struct Diff17 : public TwoRangeBase {
- Diff17() : TwoRangeBase( "{a:{$gt:1,$lt:5},b:{$gt:0,$lt:4}}", 4, 5, true, false) {}
- };
-
- struct Diff18 : public TwoRangeBase {
- Diff18() : TwoRangeBase( "{a:{$gt:1,$lt:5},b:{$gt:0,$lte:4}}", 4, 5, false, false) {}
- };
-
- struct Diff19 : public TwoRangeBase {
- Diff19() : TwoRangeBase( "{a:{$gte:1,$lte:5},b:{$gte:0,$lte:1}}", 1, 5, false, true) {}
- };
-
- struct Diff20 : public TwoRangeBase {
- Diff20() : TwoRangeBase( "{a:{$gt:1,$lte:5},b:{$gte:0,$lte:1}}", 1, 5, false, true) {}
- };
-
- struct Diff21 : public TwoRangeBase {
- Diff21() : TwoRangeBase( "{a:{$gte:1,$lte:5},b:{$gte:0,$lt:1}}", 1, 5, true, true) {}
- };
-
- struct Diff22 : public TwoRangeBase {
- Diff22() : TwoRangeBase( "{a:{$gt:1,$lte:5},b:{$gte:0,$lt:1}}", 1, 5, false, true) {}
- };
-
- struct Diff23 : public TwoRangeBase {
- Diff23() : TwoRangeBase( "{a:{$gt:1,$lte:5},b:{$gte:0,$lt:0.5}}", 1, 5, false, true) {}
- };
-
- struct Diff24 : public TwoRangeBase {
- Diff24() : TwoRangeBase( "{a:{$gt:1,$lte:5},b:0}", 1, 5, false, true) {}
- };
-
- struct Diff25 : public TwoRangeBase {
- Diff25() : TwoRangeBase( "{a:{$gte:1,$lte:5},b:0}", 1, 5, true, true) {}
- };
-
- struct Diff26 : public TwoRangeBase {
- Diff26() : TwoRangeBase( "{a:{$gt:1,$lte:5},b:1}", 1, 5, false, true) {}
- };
-
- struct Diff27 : public TwoRangeBase {
- Diff27() : TwoRangeBase( "{a:{$gte:1,$lte:5},b:1}", 1, 5, false, true) {}
- };
-
- struct Diff28 : public SplitRangeBase {
- Diff28() : SplitRangeBase( "{a:{$gte:1,$lte:5},b:3}", 1, true, 3, false, 3, false, 5, true) {}
- };
-
- struct Diff29 : public TwoRangeBase {
- Diff29() : TwoRangeBase( "{a:{$gte:1,$lte:5},b:5}", 1, 5, true, false) {}
- };
-
- struct Diff30 : public TwoRangeBase {
- Diff30() : TwoRangeBase( "{a:{$gte:1,$lt:5},b:5}", 1, 5, true, false) {}
- };
-
- struct Diff31 : public TwoRangeBase {
- Diff31() : TwoRangeBase( "{a:{$gte:1,$lt:5},b:6}", 1, 5, true, false) {}
- };
-
- struct Diff32 : public TwoRangeBase {
- Diff32() : TwoRangeBase( "{a:{$gte:1,$lte:5},b:6}", 1, 5, true, true) {}
- };
-
- class EmptyBase : public DiffBase {
- public:
- EmptyBase( string obj )
- : _obj( obj ) {}
- private:
- virtual unsigned len() const { return 0; }
- virtual const int *nums() const { return 0; }
- virtual const bool *incs() const { return 0; }
- virtual BSONObj obj() const { return fromjson( _obj ); }
- string _obj;
- };
-
- struct Diff33 : public EmptyBase {
- Diff33() : EmptyBase( "{a:{$gte:1,$lte:5},b:{$gt:0,$lt:6}}" ) {}
- };
-
- struct Diff34 : public EmptyBase {
- Diff34() : EmptyBase( "{a:{$gte:1,$lte:5},b:{$gte:1,$lt:6}}" ) {}
- };
-
- struct Diff35 : public EmptyBase {
- Diff35() : EmptyBase( "{a:{$gt:1,$lte:5},b:{$gte:1,$lt:6}}" ) {}
- };
-
- struct Diff36 : public EmptyBase {
- Diff36() : EmptyBase( "{a:{$gt:1,$lte:5},b:{$gt:1,$lt:6}}" ) {}
- };
-
- struct Diff37 : public TwoRangeBase {
- Diff37() : TwoRangeBase( "{a:{$gte:1,$lte:5},b:{$gt:1,$lt:6}}", 1, 1, true, true ) {}
- };
-
- struct Diff38 : public EmptyBase {
- Diff38() : EmptyBase( "{a:{$gt:1,$lt:5},b:{$gt:0,$lt:5}}" ) {}
- };
-
- struct Diff39 : public EmptyBase {
- Diff39() : EmptyBase( "{a:{$gt:1,$lt:5},b:{$gt:0,$lte:5}}" ) {}
- };
-
- struct Diff40 : public EmptyBase {
- Diff40() : EmptyBase( "{a:{$gt:1,$lte:5},b:{$gt:0,$lte:5}}" ) {}
- };
-
- struct Diff41 : public TwoRangeBase {
- Diff41() : TwoRangeBase( "{a:{$gte:1,$lte:5},b:{$gt:0,$lt:5}}", 5, 5, true, true ) {}
- };
-
- struct Diff42 : public EmptyBase {
- Diff42() : EmptyBase( "{a:{$gt:1,$lt:5},b:{$gt:1,$lt:5}}" ) {}
- };
-
- struct Diff43 : public EmptyBase {
- Diff43() : EmptyBase( "{a:{$gt:1,$lt:5},b:{$gt:1,$lte:5}}" ) {}
- };
-
- struct Diff44 : public EmptyBase {
- Diff44() : EmptyBase( "{a:{$gt:1,$lt:5},b:{$gte:1,$lt:5}}" ) {}
- };
-
- struct Diff45 : public EmptyBase {
- Diff45() : EmptyBase( "{a:{$gt:1,$lt:5},b:{$gte:1,$lte:5}}" ) {}
- };
-
- struct Diff46 : public TwoRangeBase {
- Diff46() : TwoRangeBase( "{a:{$gt:1,$lte:5},b:{$gt:1,$lt:5}}", 5, 5, true, true ) {}
- };
-
- struct Diff47 : public EmptyBase {
- Diff47() : EmptyBase( "{a:{$gt:1,$lte:5},b:{$gt:1,$lte:5}}" ) {}
- };
-
- struct Diff48 : public TwoRangeBase {
- Diff48() : TwoRangeBase( "{a:{$gt:1,$lte:5},b:{$gte:1,$lt:5}}", 5, 5, true, true ) {}
- };
-
- struct Diff49 : public EmptyBase {
- Diff49() : EmptyBase( "{a:{$gt:1,$lte:5},b:{$gte:1,$lte:5}}" ) {}
- };
-
- struct Diff50 : public TwoRangeBase {
- Diff50() : TwoRangeBase( "{a:{$gte:1,$lt:5},b:{$gt:1,$lt:5}}", 1, 1, true, true ) {}
- };
-
- struct Diff51 : public TwoRangeBase {
- Diff51() : TwoRangeBase( "{a:{$gte:1,$lt:5},b:{$gt:1,$lte:5}}", 1, 1, true, true ) {}
- };
-
- struct Diff52 : public EmptyBase {
- Diff52() : EmptyBase( "{a:{$gte:1,$lt:5},b:{$gte:1,$lt:5}}" ) {}
- };
-
- struct Diff53 : public EmptyBase {
- Diff53() : EmptyBase( "{a:{$gte:1,$lt:5},b:{$gte:1,$lte:5}}" ) {}
- };
-
- struct Diff54 : public SplitRangeBase {
- Diff54() : SplitRangeBase( "{a:{$gte:1,$lte:5},b:{$gt:1,$lt:5}}", 1, true, 1, true, 5, true, 5, true ) {}
- };
-
- struct Diff55 : public TwoRangeBase {
- Diff55() : TwoRangeBase( "{a:{$gte:1,$lte:5},b:{$gt:1,$lte:5}}", 1, 1, true, true ) {}
- };
-
- struct Diff56 : public TwoRangeBase {
- Diff56() : TwoRangeBase( "{a:{$gte:1,$lte:5},b:{$gte:1,$lt:5}}", 5, 5, true, true ) {}
- };
-
- struct Diff57 : public EmptyBase {
- Diff57() : EmptyBase( "{a:{$gte:1,$lte:5},b:{$gte:1,$lte:5}}" ) {}
- };
-
- struct Diff58 : public TwoRangeBase {
- Diff58() : TwoRangeBase( "{a:1,b:{$gt:1,$lt:5}}", 1, 1, true, true ) {}
- };
-
- struct Diff59 : public EmptyBase {
- Diff59() : EmptyBase( "{a:1,b:{$gte:1,$lt:5}}" ) {}
- };
-
- struct Diff60 : public EmptyBase {
- Diff60() : EmptyBase( "{a:2,b:{$gte:1,$lt:5}}" ) {}
- };
-
- struct Diff61 : public EmptyBase {
- Diff61() : EmptyBase( "{a:5,b:{$gte:1,$lte:5}}" ) {}
- };
-
- struct Diff62 : public TwoRangeBase {
- Diff62() : TwoRangeBase( "{a:5,b:{$gt:1,$lt:5}}", 5, 5, true, true ) {}
- };
-
- struct Diff63 : public EmptyBase {
- Diff63() : EmptyBase( "{a:5,b:5}" ) {}
- };
-
- struct Diff64 : public TwoRangeBase {
- Diff64() : TwoRangeBase( "{a:{$gte:1,$lte:2},b:{$gt:0,$lte:1}}", 1, 2, false, true ) {}
- };
-
- class DiffMulti1 : public DiffBase {
- public:
- void run() {
- FieldRangeSet frs( "", fromjson( "{a:{$gt:1,$lt:9},b:{$gt:0,$lt:2},c:3,d:{$gt:4,$lt:5},e:{$gt:7,$lt:10}}" ), true );
- FieldRange ret = frs.range( "a" );
- FieldRange other = frs.range( "b" );
- other |= frs.range( "c" );
- other |= frs.range( "d" );
- other |= frs.range( "e" );
- ret -= other;
- check( ret );
- }
- protected:
- virtual unsigned len() const { return 3; }
- virtual const int *nums() const { static int n[] = { 2, 3, 3, 4, 5, 7 }; return n; }
- virtual const bool *incs() const { static bool b[] = { true, false, false, true, true, true }; return b; }
- virtual BSONObj obj() const { return BSONObj(); }
- };
-
- class DiffMulti2 : public DiffBase {
- public:
- void run() {
- FieldRangeSet frs( "", fromjson( "{a:{$gt:1,$lt:9},b:{$gt:0,$lt:2},c:3,d:{$gt:4,$lt:5},e:{$gt:7,$lt:10}}" ), true );
- FieldRange mask = frs.range( "a" );
- FieldRange ret = frs.range( "b" );
- ret |= frs.range( "c" );
- ret |= frs.range( "d" );
- ret |= frs.range( "e" );
- ret -= mask;
- check( ret );
- }
- protected:
- virtual unsigned len() const { return 2; }
- virtual const int *nums() const { static int n[] = { 0, 1, 9, 10 }; return n; }
- virtual const bool *incs() const { static bool b[] = { false, true, true, false }; return b; }
- virtual BSONObj obj() const { return BSONObj(); }
- };
-
- } // namespace FieldRangeTests
-
- namespace FieldRangeSetTests {
-
- class Intersect {
- public:
- void run() {
- FieldRangeSet frs1( "", fromjson( "{b:{$in:[5,6]},c:7,d:{$in:[8,9]}}" ), true );
- FieldRangeSet frs2( "", fromjson( "{a:1,b:5,c:{$in:[7,8]},d:{$in:[8,9]},e:10}" ), true );
- frs1 &= frs2;
- ASSERT_EQUALS( fromjson( "{a:1,b:5,c:7,d:{$gte:8,$lte:9},e:10}" ), frs1.simplifiedQuery( BSONObj() ) );
- }
- };
-
- class MultiKeyIntersect {
- public:
- void run() {
- FieldRangeSet frs1( "", BSONObj(), false );
- FieldRangeSet frs2( "", BSON( "a" << GT << 4 ), false );
- FieldRangeSet frs3( "", BSON( "a" << LT << 6 ), false );
- // An intersection with a trivial range is allowed.
- frs1 &= frs2;
- ASSERT_EQUALS( frs2.simplifiedQuery( BSONObj() ), frs1.simplifiedQuery( BSONObj() ) );
- // An intersection with a nontrivial range is not allowed, as it might prevent a valid
- // multikey match.
- frs1 &= frs3;
- ASSERT_EQUALS( frs2.simplifiedQuery( BSONObj() ), frs1.simplifiedQuery( BSONObj() ) );
- // Now intersect with a fully contained range.
- FieldRangeSet frs4( "", BSON( "a" << GT << 6 ), false );
- frs1 &= frs4;
- ASSERT_EQUALS( frs4.simplifiedQuery( BSONObj() ), frs1.simplifiedQuery( BSONObj() ) );
- }
- };
-
- class MultiKeyDiff {
- public:
- void run() {
- FieldRangeSet frs1( "", BSON( "a" << GT << 4 ), false );
- FieldRangeSet frs2( "", BSON( "a" << GT << 6 ), false );
- // Range subtraction is no different for multikey ranges.
- frs1 -= frs2;
- ASSERT_EQUALS( BSON( "a" << GT << 4 << LTE << 6 ), frs1.simplifiedQuery( BSONObj() ) );
- }
- };
-
- class MatchPossible {
- public:
- void run() {
- FieldRangeSet frs1( "", BSON( "a" << GT << 4 ), true );
- ASSERT( frs1.matchPossible() );
- // Conflicting constraints invalid for a single key set.
- FieldRangeSet frs2( "", BSON( "a" << GT << 4 << LT << 2 ), true );
- ASSERT( !frs2.matchPossible() );
- // Conflicting constraints not possible for a multi key set.
- FieldRangeSet frs3( "", BSON( "a" << GT << 4 << LT << 2 ), false );
- ASSERT( frs3.matchPossible() );
- }
- };
-
- class MatchPossibleForIndex {
- public:
- void run() {
- // Conflicting constraints not possible for a multi key set.
- FieldRangeSet frs1( "", BSON( "a" << GT << 4 << LT << 2 ), false );
- ASSERT( frs1.matchPossibleForIndex( BSON( "a" << 1 ) ) );
- // Conflicting constraints for a multi key set.
- FieldRangeSet frs2( "", BSON( "a" << GT << 4 << LT << 2 ), true );
- ASSERT( !frs2.matchPossibleForIndex( BSON( "a" << 1 ) ) );
- // If the index doesn't include the key, it is not single key invalid.
- ASSERT( frs2.matchPossibleForIndex( BSON( "b" << 1 ) ) );
- // If the index key is not an index, the set is not single key invalid.
- ASSERT( frs2.matchPossibleForIndex( BSON( "$natural" << 1 ) ) );
- ASSERT( frs2.matchPossibleForIndex( BSONObj() ) );
- }
- };
-
- } // namespace FieldRangeSetTests
-
- namespace FieldRangeSetPairTests {
-
- class NoNontrivialRanges {
- public:
- void run() {
- FieldRangeSetPair frsp1( "", BSONObj() );
- ASSERT( frsp1.noNontrivialRanges() );
- FieldRangeSetPair frsp2( "", BSON( "a" << 1 ) );
- ASSERT( !frsp2.noNontrivialRanges() );
- FieldRangeSetPair frsp3( "", BSON( "a" << GT << 1 ) );
- ASSERT( !frsp3.noNontrivialRanges() );
- // A single key invalid constraint is still nontrivial.
- FieldRangeSetPair frsp4( "", BSON( "a" << GT << 1 << LT << 0 ) );
- ASSERT( !frsp4.noNontrivialRanges() );
- // Still nontrivial if multikey invalid.
- frsp4 -= frsp4.frsForIndex( 0, -1 );
- ASSERT( !frsp4.noNontrivialRanges() );
- }
- };
-
- class MatchPossible {
- public:
- void run() {
- // Match possible for simple query.
- FieldRangeSetPair frsp1( "", BSON( "a" << 1 ) );
- ASSERT( frsp1.matchPossible() );
- // Match possible for single key invalid query.
- FieldRangeSetPair frsp2( "", BSON( "a" << GT << 1 << LT << 0 ) );
- ASSERT( frsp2.matchPossible() );
- // Match not possible for multi key invalid query.
- frsp1 -= frsp1.frsForIndex( 0, - 1 );
- ASSERT( !frsp1.matchPossible() );
- }
- };
-
- class IndexBase {
- public:
- IndexBase() : _ctx( ns() ) , indexNum_( 0 ) {
- string err;
- userCreateNS( ns(), BSONObj(), err, false );
- }
- ~IndexBase() {
- if ( !nsd() )
- return;
- string s( ns() );
- dropNS( s );
- }
- protected:
- static const char *ns() { return "unittests.FieldRangeSetPairTests"; }
- static NamespaceDetails *nsd() { return nsdetails( ns() ); }
- IndexDetails *index( const BSONObj &key ) {
- stringstream ss;
- ss << indexNum_++;
- string name = ss.str();
- client_.resetIndexCache();
- client_.ensureIndex( ns(), key, false, name.c_str() );
- NamespaceDetails *d = nsd();
- for( int i = 0; i < d->nIndexes; ++i ) {
- if ( d->idx(i).keyPattern() == key /*indexName() == name*/ || ( d->idx(i).isIdIndex() && IndexDetails::isIdIndexPattern( key ) ) )
- return &d->idx(i);
- }
- assert( false );
- return 0;
- }
- int indexno( const BSONObj &key ) {
- return nsd()->idxNo( *index(key) );
- }
- static DBDirectClient client_;
- private:
- dblock lk_;
- Client::Context _ctx;
- int indexNum_;
- };
- DBDirectClient IndexBase::client_;
-
- class MatchPossibleForIndex : public IndexBase {
- public:
- void run() {
- int a = indexno( BSON( "a" << 1 ) );
- int b = indexno( BSON( "b" << 1 ) );
- IndexBase::client_.insert( ns(), BSON( "a" << BSON_ARRAY( 1 << 2 ) << "b" << 1 ) );
- // Valid ranges match possible for both indexes.
- FieldRangeSetPair frsp1( ns(), BSON( "a" << GT << 1 << LT << 4 << "b" << GT << 1 << LT << 4 ) );
- ASSERT( frsp1.matchPossibleForIndex( nsd(), a, BSON( "a" << 1 ) ) );
- ASSERT( frsp1.matchPossibleForIndex( nsd(), b, BSON( "b" << 1 ) ) );
- // Single key invalid range means match impossible for single key index.
- FieldRangeSetPair frsp2( ns(), BSON( "a" << GT << 4 << LT << 1 << "b" << GT << 4 << LT << 1 ) );
- ASSERT( frsp2.matchPossibleForIndex( nsd(), a, BSON( "a" << 1 ) ) );
- ASSERT( !frsp2.matchPossibleForIndex( nsd(), b, BSON( "b" << 1 ) ) );
- }
- };
-
- } // namespace FieldRangeSetPairTests
-
- class All : public Suite {
- public:
- All() : Suite( "queryutil" ) {}
-
- void setupTests() {
- add< FieldRangeTests::Empty >();
- add< FieldRangeTests::Eq >();
- add< FieldRangeTests::DupEq >();
- add< FieldRangeTests::Lt >();
- add< FieldRangeTests::Lte >();
- add< FieldRangeTests::Gt >();
- add< FieldRangeTests::Gte >();
- add< FieldRangeTests::TwoLt >();
- add< FieldRangeTests::TwoGt >();
- add< FieldRangeTests::EqGte >();
- add< FieldRangeTests::EqGteInvalid >();
- add< FieldRangeTests::Regex >();
- add< FieldRangeTests::RegexObj >();
- add< FieldRangeTests::UnhelpfulRegex >();
- add< FieldRangeTests::In >();
- add< FieldRangeTests::Equality >();
- add< FieldRangeTests::SimplifiedQuery >();
- add< FieldRangeTests::QueryPatternTest >();
- add< FieldRangeTests::QueryPatternNeConstraint >();
- add< FieldRangeTests::NoWhere >();
- add< FieldRangeTests::Numeric >();
- add< FieldRangeTests::InLowerBound >();
- add< FieldRangeTests::InUpperBound >();
- add< FieldRangeTests::UnionBound >();
- add< FieldRangeTests::MultiBound >();
- add< FieldRangeTests::Diff1 >();
- add< FieldRangeTests::Diff2 >();
- add< FieldRangeTests::Diff3 >();
- add< FieldRangeTests::Diff4 >();
- add< FieldRangeTests::Diff5 >();
- add< FieldRangeTests::Diff6 >();
- add< FieldRangeTests::Diff7 >();
- add< FieldRangeTests::Diff8 >();
- add< FieldRangeTests::Diff9 >();
- add< FieldRangeTests::Diff10 >();
- add< FieldRangeTests::Diff11 >();
- add< FieldRangeTests::Diff12 >();
- add< FieldRangeTests::Diff13 >();
- add< FieldRangeTests::Diff14 >();
- add< FieldRangeTests::Diff15 >();
- add< FieldRangeTests::Diff16 >();
- add< FieldRangeTests::Diff17 >();
- add< FieldRangeTests::Diff18 >();
- add< FieldRangeTests::Diff19 >();
- add< FieldRangeTests::Diff20 >();
- add< FieldRangeTests::Diff21 >();
- add< FieldRangeTests::Diff22 >();
- add< FieldRangeTests::Diff23 >();
- add< FieldRangeTests::Diff24 >();
- add< FieldRangeTests::Diff25 >();
- add< FieldRangeTests::Diff26 >();
- add< FieldRangeTests::Diff27 >();
- add< FieldRangeTests::Diff28 >();
- add< FieldRangeTests::Diff29 >();
- add< FieldRangeTests::Diff30 >();
- add< FieldRangeTests::Diff31 >();
- add< FieldRangeTests::Diff32 >();
- add< FieldRangeTests::Diff33 >();
- add< FieldRangeTests::Diff34 >();
- add< FieldRangeTests::Diff35 >();
- add< FieldRangeTests::Diff36 >();
- add< FieldRangeTests::Diff37 >();
- add< FieldRangeTests::Diff38 >();
- add< FieldRangeTests::Diff39 >();
- add< FieldRangeTests::Diff40 >();
- add< FieldRangeTests::Diff41 >();
- add< FieldRangeTests::Diff42 >();
- add< FieldRangeTests::Diff43 >();
- add< FieldRangeTests::Diff44 >();
- add< FieldRangeTests::Diff45 >();
- add< FieldRangeTests::Diff46 >();
- add< FieldRangeTests::Diff47 >();
- add< FieldRangeTests::Diff48 >();
- add< FieldRangeTests::Diff49 >();
- add< FieldRangeTests::Diff50 >();
- add< FieldRangeTests::Diff51 >();
- add< FieldRangeTests::Diff52 >();
- add< FieldRangeTests::Diff53 >();
- add< FieldRangeTests::Diff54 >();
- add< FieldRangeTests::Diff55 >();
- add< FieldRangeTests::Diff56 >();
- add< FieldRangeTests::Diff57 >();
- add< FieldRangeTests::Diff58 >();
- add< FieldRangeTests::Diff59 >();
- add< FieldRangeTests::Diff60 >();
- add< FieldRangeTests::Diff61 >();
- add< FieldRangeTests::Diff62 >();
- add< FieldRangeTests::Diff63 >();
- add< FieldRangeTests::Diff64 >();
- add< FieldRangeTests::DiffMulti1 >();
- add< FieldRangeTests::DiffMulti2 >();
- add< FieldRangeSetTests::Intersect >();
- add< FieldRangeSetTests::MultiKeyIntersect >();
- add< FieldRangeSetTests::MultiKeyDiff >();
- add< FieldRangeSetTests::MatchPossible >();
- add< FieldRangeSetTests::MatchPossibleForIndex >();
- add< FieldRangeSetPairTests::NoNontrivialRanges >();
- add< FieldRangeSetPairTests::MatchPossible >();
- add< FieldRangeSetPairTests::MatchPossibleForIndex >();
- }
- } myall;
-
-} // namespace QueryUtilTests
-