summaryrefslogtreecommitdiff
path: root/src/mongo/dbtests/namespacetests.cpp
diff options
context:
space:
mode:
authoraaron <aaron@10gen.com>2013-03-15 08:19:59 -0700
committeraaron <aaron@10gen.com>2013-03-15 18:41:06 -0700
commit4c75c66c34bae94e61e805403ceca4e132856064 (patch)
tree1c5dbe444a55783ea9b7bc9c10b6603e9559c75a /src/mongo/dbtests/namespacetests.cpp
parente60c28a09c691a7c4d9447dab9347d15d85e5e39 (diff)
downloadmongo-4c75c66c34bae94e61e805403ceca4e132856064.tar.gz
SERVER-5848 Additional tests.
Diffstat (limited to 'src/mongo/dbtests/namespacetests.cpp')
-rw-r--r--src/mongo/dbtests/namespacetests.cpp561
1 files changed, 549 insertions, 12 deletions
diff --git a/src/mongo/dbtests/namespacetests.cpp b/src/mongo/dbtests/namespacetests.cpp
index 2f07ac18d95..d1baff95327 100644
--- a/src/mongo/dbtests/namespacetests.cpp
+++ b/src/mongo/dbtests/namespacetests.cpp
@@ -922,17 +922,123 @@ namespace NamespaceTests {
} // namespace IndexDetailsTests
- namespace IndexSpecTests {
+ namespace IndexSpecSuitability {
+
+ /** An index is helpful for a query on the indexed field. */
+ class IndexedQueryField {
+ public:
+ void run() {
+ IndexSpec spec( BSON( "a" << 1 ), BSONObj() );
+ FieldRangeSet frs( "n/a", BSON( "a" << 2 ), true , true );
+ // Checking a return value of HELPFUL instead of OPTIMAL is descriptive rather than
+ // normative. See SERVER-4485.
+ ASSERT_EQUALS( HELPFUL, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /** An index is useless for a query not on an indexed field. */
+ class NoIndexedQueryField {
+ public:
+ void run() {
+ IndexSpec spec( BSON( "a" << 1 ), BSONObj() );
+ FieldRangeSet frs( "n/a", BSON( "b" << 2 ), true , true );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /** An index is useless for a query on the child of the indexed field. */
+ class ChildOfIndexQueryField {
+ public:
+ void run() {
+ IndexSpec spec( BSON( "a" << 1 ), BSONObj() );
+ FieldRangeSet frs( "n/a", BSON( "a.b" << 2 ), true , true );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /** An index is useless for a query on the parent of the indexed field. */
+ class ParentOfIndexQueryField {
+ public:
+ void run() {
+ IndexSpec spec( BSON( "a.b" << 1 ), BSONObj() );
+ FieldRangeSet frs( "n/a", BSON( "a" << 2 ), true , true );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /**
+ * An index is useless for an equality query containing a field name completing the indexed
+ * field path.
+ */
+ class ObjectMatchCompletingIndexField {
+ public:
+ void run() {
+ IndexSpec spec( BSON( "a.b" << 1 ), BSONObj() );
+ FieldRangeSet frs( "n/a", BSON( "a" << BSON( "b" << 2 ) ), true , true );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /** An index is helpful for an ordering on the indexed field. */
+ class IndexedOrderField {
+ public:
+ void run() {
+ IndexSpec spec( BSON( "a" << 1 ), BSONObj() );
+ FieldRangeSet frs( "n/a", BSONObj(), true , true );
+ ASSERT_EQUALS( HELPFUL, spec.suitability( frs, BSON( "a" << 1 ) ) );
+ }
+ };
+
+ /** An index is helpful for a reverse direction ordering on the indexed field. */
+ class IndexedReverseOrderField {
+ public:
+ void run() {
+ IndexSpec spec( BSON( "a" << -1 ), BSONObj() );
+ FieldRangeSet frs( "n/a", BSONObj(), true , true );
+ ASSERT_EQUALS( HELPFUL, spec.suitability( frs, BSON( "a" << 1 ) ) );
+ }
+ };
+
+ /**
+ * An index is helpful for an ordering containing the indexed field, even if the first
+ * ordered field is not indexed. This is a descriptive rather than normative test.
+ */
+ class NonPrefixIndexedOrderField {
+ public:
+ void run() {
+ IndexSpec spec( BSON( "a" << 1 ), BSONObj() );
+ FieldRangeSet frs( "n/a", BSONObj(), true , true );
+ ASSERT_EQUALS( HELPFUL, spec.suitability( frs, BSON( "b" << 1 << "a" << 1 ) ) );
+ }
+ };
+
+ /** An index is useless for an ordering on an unindexed field. */
+ class NoIndexedOrderField {
+ public:
+ void run() {
+ IndexSpec spec( BSON( "a" << 1 ), BSONObj() );
+ FieldRangeSet frs( "n/a", BSONObj(), true , true );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSON( "b" << 1 ) ) );
+ }
+ };
- class Suitability {
+ /** An index is useless for an ordering on the child of an indexed field. */
+ class ChildOfIndexOrderField {
public:
void run() {
IndexSpec spec( BSON( "a" << 1 ), BSONObj() );
- FieldRangeSet frs1( "", BSON( "a" << 2 << "b" << 3 ), true , true );
- ASSERT_EQUALS( HELPFUL, spec.suitability( frs1 , BSONObj() ) );
- FieldRangeSet frs2( "", BSON( "b" << 3 ), true , true );
- ASSERT_EQUALS( USELESS, spec.suitability( frs2, BSONObj() ) );
- ASSERT_EQUALS( HELPFUL, spec.suitability( frs2, BSON( "a" << 1 ) ) );
+ FieldRangeSet frs( "n/a", BSONObj(), true , true );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSON( "a.b" << 1 ) ) );
+ }
+ };
+
+ /** An index is useless for an ordering on the parent of an indexed field. */
+ class ParentOfIndexOrderField {
+ public:
+ void run() {
+ IndexSpec spec( BSON( "a.b" << 1 ), BSONObj() );
+ FieldRangeSet frs( "n/a", BSONObj(), true , true );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSON( "a" << 1 ) ) );
}
};
@@ -941,15 +1047,406 @@ namespace NamespaceTests {
public:
void run() {
IndexSpec spec( BSON( "1" << 1 ), BSONObj() );
- FieldRangeSet frs1( "", BSON( "1" << 2 ), true , true );
+ FieldRangeSet frs1( "n/a", BSON( "1" << 2 ), true , true );
ASSERT_EQUALS( HELPFUL, spec.suitability( frs1, BSONObj() ) );
- FieldRangeSet frs2( "", BSON( "01" << 3), true , true );
+ FieldRangeSet frs2( "n/a", BSON( "01" << 3), true , true );
ASSERT_EQUALS( USELESS, spec.suitability( frs2, BSON( "01" << 1 ) ) );
- FieldRangeSet frs3( "", BSONObj() , true , true );
+ FieldRangeSet frs3( "n/a", BSONObj() , true , true );
ASSERT_EQUALS( HELPFUL, spec.suitability( frs3, BSON( "1" << 1 ) ) );
}
};
+ namespace TwoD {
+
+ /** A 2d index is optimal for a $within predicate on the indexed field. */
+ class Within {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:{$within:{$box:[[100,0],[120,100]]}}}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "2d" ) );
+ ASSERT_EQUALS( OPTIMAL, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /** A 2d index is useless for a $within predicate not on the indexed field. */
+ class WithinUnindexed {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:{$within:{$box:[[100,0],[120,100]]}}}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "b" << "2d" ) );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /** A 2d index is optimal for a $near predicate on the indexed field. */
+ class Near {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:{$near:[100,0]}}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "2d" ) );
+ ASSERT_EQUALS( OPTIMAL, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /**
+ * A 2d index is helpful for a location object equality predicate on the indexed field.
+ */
+ class LocationObject {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:{lat:4,lon:5}}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "2d" ) );
+ ASSERT_EQUALS( HELPFUL, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /**
+ * A 2d index is helpful for a predicate object on the indexed field. This is a
+ * descriptive rather than normative test. See SERVER-8644.
+ */
+ class PredicateObject {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:{$gt:4,$lt:5}}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "2d" ) );
+ ASSERT_EQUALS( HELPFUL, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /** A 2d index is helpful for an array equality predicate on the indexed field. */
+ class Array {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:[1,1]}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "2d" ) );
+ ASSERT_EQUALS( HELPFUL, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /** A 2d index is useless for a numeric equality predicate on the indexed field. */
+ class Number {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:1}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "2d" ) );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /** A 2d index is useless without a predicate on the indexed field. */
+ class Missing {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "2d" ) );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /**
+ * A 2d index is useless for a $near predicate on the indexed field within a $and
+ * clause. This is a descriptive rather than normative test. See SERVER-4572.
+ */
+ class InsideAnd {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{$and:[{a:{$near:[100,0]}}]}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "2d" ) );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /**
+ * A 2d index is optimal for a $near predicate on the indexed field adjacent to a $or
+ * expression.
+ */
+ class OutsideOr {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:{$near:[100,0]},$or:[{b:1}]}" );
+ OrRangeGenerator org( "n/a", query, true );
+ scoped_ptr<FieldRangeSetPair> frsp( org.topFrsp() );
+ IndexSpec spec( BSON( "a" << "2d" ) );
+ ASSERT_EQUALS( OPTIMAL,
+ spec.suitability( frsp->getSingleKeyFRS(), BSONObj() ) );
+ }
+ };
+
+ } // namespace TwoD
+
+ namespace S2 {
+
+ /** A 2dsphere index is optimal for a $geoIntersects predicate on the indexed field. */
+ class GeoIntersects {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:{$geoIntersects:{$geometry:{type:'Point',"
+ "coordinates:[40,5]}}}}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "2dsphere" ) );
+ ASSERT_EQUALS( OPTIMAL, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /** A 2dsphere index is useless for a $geoIntersects predicate on an unindexed field. */
+ class GeoIntersectsUnindexed {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:{$geoIntersects:{$geometry:{type:'Point',"
+ "coordinates:[40,5]}}}}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "b" << "2dsphere" ) );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /** A 2dsphere index is optimal for a $near predicate on the indexed field. */
+ class Near {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:{$near:[100,0]}}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "2dsphere" ) );
+ ASSERT_EQUALS( OPTIMAL, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /**
+ * A 2dsphere index is useless for a location object equality predicate on the indexed
+ * field.
+ */
+ class LocationObject {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:{lat:4,lon:5}}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "2dsphere" ) );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /** A 2dsphere index is useless for a predicate object on the indexed field. */
+ class PredicateObject {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:{$gt:4,$lt:5}}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "2dsphere" ) );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /** A 2dsphere index is helpful for an array equality predicate on the indexed field. */
+ class Array {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:[1,1]}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "2dsphere" ) );
+ ASSERT_EQUALS( HELPFUL, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /**
+ * A 2dsphere index is useless for a numeric equality predicate on the indexed field.
+ */
+ class Number {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:1}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "2dsphere" ) );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /** A 2dsphere index is useless without a predicate on the indexed field. */
+ class Missing {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "2dsphere" ) );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /**
+ * A 2dsphere index is useless for a $near predicate on the indexed field within a $and
+ * clause. This is a descriptive rather than normative test. See SERVER-4572.
+ */
+ class InsideAnd {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{$and:[{a:{$near:[100,0]}}]}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "2dsphere" ) );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /**
+ * A 2dsphere index is optimal for a $near predicate on the indexed field adjacent to a
+ * $or expression.
+ */
+ class OutsideOr {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:{$near:[100,0]},$or:[{b:1}]}" );
+ OrRangeGenerator org( "n/a", query, true );
+ scoped_ptr<FieldRangeSetPair> frsp( org.topFrsp() );
+ IndexSpec spec( BSON( "a" << "2dsphere" ) );
+ ASSERT_EQUALS( OPTIMAL,
+ spec.suitability( frsp->getSingleKeyFRS(), BSONObj() ) );
+ }
+ };
+
+ } // namespace S2
+
+ namespace Hashed {
+
+ /** A hashed index is helpful for an equality predicate on the indexed field. */
+ class Equality {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:5}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "hashed" ) );
+ ASSERT_EQUALS( HELPFUL, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /** A hashed index is useless for a range predicate on the indexed field. */
+ class GreaterThan {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:{$gt:4}}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "hashed" ) );
+ ASSERT_EQUALS( USELESS, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /** A hashed index is helpful for a set membership predicate on the indexed field. */
+ class InSet {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:{$in:[1,2]}}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "hashed" ) );
+ ASSERT_EQUALS( HELPFUL, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /**
+ * A hashed index is helpful for an equality predicate on the indexed field, within a
+ * singleton $and clause.
+ */
+ class AndEqualitySingleton {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{$and:[{a:5}]}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "hashed" ) );
+ ASSERT_EQUALS( HELPFUL, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /**
+ * A hashed index is helpful for an equality predicate on the indexed field, within a
+ * non singleton $and clause.
+ */
+ class AndEqualityNonSingleton {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{$and:[{a:5},{b:5}]}" );
+ FieldRangeSet frs( "n/a", query, true, true );
+ IndexSpec spec( BSON( "a" << "hashed" ) );
+ ASSERT_EQUALS( HELPFUL, spec.suitability( frs, BSONObj() ) );
+ }
+ };
+
+ /**
+ * A hashed index is helpful for an equality predicate on the indexed field, within a
+ * singleton $or clause.
+ */
+ class EqualityInsideSingletonOr {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{$or:[{a:5}]}" );
+ OrRangeGenerator org( "n/a", query, true );
+ scoped_ptr<FieldRangeSetPair> frsp( org.topFrsp() );
+ IndexSpec spec( BSON( "a" << "hashed" ) );
+ ASSERT_EQUALS( HELPFUL, spec.suitability( frsp->getSingleKeyFRS(),
+ BSONObj() ) );
+ }
+ };
+
+ /**
+ * A hashed index is helpful for an equality predicate on the indexed field, within a
+ * non standalone singleton $or clause.
+ */
+ class EqualityInsideNonStandaloneSingletonOr {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{z:5,$or:[{a:5}]}" );
+ OrRangeGenerator org( "n/a", query, true );
+ scoped_ptr<FieldRangeSetPair> frsp( org.topFrsp() );
+ IndexSpec spec( BSON( "a" << "hashed" ) );
+ ASSERT_EQUALS( HELPFUL, spec.suitability( frsp->getSingleKeyFRS(),
+ BSONObj() ) );
+ }
+ };
+
+ /**
+ * A hashed index is helpful for an equality predicate on the indexed field, within a
+ * non singleton $or clause.
+ */
+ class EqualityInsideNonSingletonOr {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{$or:[{a:5},{b:5}]}" );
+ OrRangeGenerator org( "n/a", query, true );
+ scoped_ptr<FieldRangeSetPair> frsp( org.topFrsp() );
+ IndexSpec spec( BSON( "a" << "hashed" ) );
+ ASSERT_EQUALS( HELPFUL, spec.suitability( frsp->getSingleKeyFRS(),
+ BSONObj() ) );
+ }
+ };
+
+ /**
+ * A hashed index is helpful for an equality predicate on the indexed field, adjacent to
+ * a $or clause.
+ */
+ class EqualityOutsideOr {
+ public:
+ void run() {
+ BSONObj query = fromjson( "{a:5,$or:[{z:5}]}" );
+ OrRangeGenerator org( "n/a", query, true );
+ scoped_ptr<FieldRangeSetPair> frsp( org.topFrsp() );
+ IndexSpec spec( BSON( "a" << "hashed" ) );
+ ASSERT_EQUALS( HELPFUL, spec.suitability( frsp->getSingleKeyFRS(),
+ BSONObj() ) );
+ }
+ };
+
+ } // namespace Hashed
+
+ // GeoHaystack does not implement its own suitability(). See SERVER-8645.
+
+ } // namespace IndexSpecSuitability
+
+ namespace IndexSpecTests {
+
/** A missing field is represented as null in a btree index. */
class BtreeIndexMissingField {
public:
@@ -1830,8 +2327,48 @@ namespace NamespaceTests {
add< IndexDetailsTests::MissingField >();
add< IndexDetailsTests::SubobjectMissing >();
add< IndexDetailsTests::CompoundMissing >();
- add< IndexSpecTests::Suitability >();
- add< IndexSpecTests::NumericFieldSuitability >();
+ add< IndexSpecSuitability::IndexedQueryField >();
+ add< IndexSpecSuitability::NoIndexedQueryField >();
+ add< IndexSpecSuitability::ChildOfIndexQueryField >();
+ add< IndexSpecSuitability::ParentOfIndexQueryField >();
+ add< IndexSpecSuitability::ObjectMatchCompletingIndexField >();
+ add< IndexSpecSuitability::NoIndexedQueryField >();
+ add< IndexSpecSuitability::IndexedOrderField >();
+ add< IndexSpecSuitability::IndexedReverseOrderField >();
+ add< IndexSpecSuitability::NonPrefixIndexedOrderField >();
+ add< IndexSpecSuitability::NoIndexedOrderField >();
+ add< IndexSpecSuitability::ChildOfIndexOrderField >();
+ add< IndexSpecSuitability::ParentOfIndexOrderField >();
+ add< IndexSpecSuitability::NumericFieldSuitability >();
+ add< IndexSpecSuitability::TwoD::Within >();
+ add< IndexSpecSuitability::TwoD::WithinUnindexed >();
+ add< IndexSpecSuitability::TwoD::Near >();
+ add< IndexSpecSuitability::TwoD::LocationObject >();
+ add< IndexSpecSuitability::TwoD::PredicateObject >();
+ add< IndexSpecSuitability::TwoD::Array >();
+ add< IndexSpecSuitability::TwoD::Number >();
+ add< IndexSpecSuitability::TwoD::Missing >();
+ add< IndexSpecSuitability::TwoD::InsideAnd >();
+ add< IndexSpecSuitability::TwoD::OutsideOr >();
+ add< IndexSpecSuitability::S2::GeoIntersects >();
+ add< IndexSpecSuitability::S2::GeoIntersectsUnindexed >();
+ add< IndexSpecSuitability::S2::Near >();
+ add< IndexSpecSuitability::S2::LocationObject >();
+ add< IndexSpecSuitability::S2::PredicateObject >();
+ add< IndexSpecSuitability::S2::Array >();
+ add< IndexSpecSuitability::S2::Number >();
+ add< IndexSpecSuitability::S2::Missing >();
+ add< IndexSpecSuitability::S2::InsideAnd >();
+ add< IndexSpecSuitability::S2::OutsideOr >();
+ add< IndexSpecSuitability::Hashed::Equality >();
+ add< IndexSpecSuitability::Hashed::GreaterThan >();
+ add< IndexSpecSuitability::Hashed::InSet >();
+ add< IndexSpecSuitability::Hashed::AndEqualitySingleton >();
+ add< IndexSpecSuitability::Hashed::AndEqualityNonSingleton >();
+ add< IndexSpecSuitability::Hashed::EqualityInsideSingletonOr >();
+ add< IndexSpecSuitability::Hashed::EqualityInsideNonStandaloneSingletonOr >();
+ add< IndexSpecSuitability::Hashed::EqualityInsideNonSingletonOr >();
+ add< IndexSpecSuitability::Hashed::EqualityOutsideOr >();
add< IndexSpecTests::BtreeIndexMissingField >();
add< IndexSpecTests::TwoDIndexMissingField >();
add< IndexSpecTests::HashedIndexMissingField >();