mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
BUG SERVER-29 matcher access objects in arrays correctly
This commit is contained in:
parent
cb9e6153dd
commit
b9617339d4
@ -405,6 +405,7 @@ namespace mongo {
|
||||
int ret = matchesNe( fieldName, *i, obj, deep );
|
||||
if ( ret != 1 )
|
||||
return ret;
|
||||
// code to handle 0 (missing) return value doesn't deal with nin yet
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -414,18 +415,36 @@ namespace mongo {
|
||||
e = obj.getFieldUsingIndexNames(fieldName, constrainIndexKey_);
|
||||
assert( !e.eoo() );
|
||||
} else {
|
||||
if ( isArr ) {
|
||||
BSONObjIterator ai(obj);
|
||||
bool found = false;
|
||||
while ( ai.more() ) {
|
||||
BSONElement z = ai.next();
|
||||
if ( z.type() == Object ) {
|
||||
BSONObj eo = z.embeddedObject();
|
||||
int cmp = matchesDotted(fieldName, toMatch, eo, compareOp, deep);
|
||||
if ( cmp > 0 ) {
|
||||
if ( deep ) *deep = true;
|
||||
return 1;
|
||||
} else if ( cmp < 0 ) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return found ? -1 : 0;
|
||||
}
|
||||
const char *p = strchr(fieldName, '.');
|
||||
if ( p ) {
|
||||
string left(fieldName, p-fieldName);
|
||||
|
||||
BSONElement e = obj.getField(left.c_str());
|
||||
if ( e.eoo() )
|
||||
BSONElement se = obj.getField(left.c_str());
|
||||
if ( se.eoo() )
|
||||
return 0;
|
||||
if ( e.type() != Object && e.type() != Array )
|
||||
if ( se.type() != Object && se.type() != Array )
|
||||
return -1;
|
||||
|
||||
BSONObj eo = e.embeddedObject();
|
||||
return matchesDotted(p+1, toMatch, eo, compareOp, deep, e.type() == Array);
|
||||
BSONObj eo = se.embeddedObject();
|
||||
return matchesDotted(p+1, toMatch, eo, compareOp, deep, se.type() == Array);
|
||||
} else {
|
||||
e = obj.getField(fieldName);
|
||||
}
|
||||
@ -444,22 +463,8 @@ namespace mongo {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( isArr ) {
|
||||
BSONObjIterator ai(obj);
|
||||
while ( ai.more() ) {
|
||||
BSONElement z = ai.next();
|
||||
if ( z.type() == Object ) {
|
||||
BSONObj eo = z.embeddedObject();
|
||||
int cmp = matchesDotted(fieldName, toMatch, eo, compareOp, deep);
|
||||
if ( cmp > 0 ) {
|
||||
if ( deep ) *deep = true;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( e.eoo() ) {
|
||||
// 0 indicatse "missing element"
|
||||
// 0 indicates "missing element"
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
|
@ -449,6 +449,19 @@ namespace QueryTests {
|
||||
}
|
||||
};
|
||||
|
||||
class SubobjectInArray : public ClientBase {
|
||||
public:
|
||||
~SubobjectInArray() {
|
||||
client().dropCollection( "querytests.SubobjectInArray" );
|
||||
}
|
||||
void run() {
|
||||
const char *ns = "querytests.SubobjectInArray";
|
||||
client().insert( ns, fromjson( "{a:[{b:{c:1}}]}" ) );
|
||||
ASSERT( !client().findOne( ns, BSON( "a.b.c" << 1 ) ).isEmpty() );
|
||||
ASSERT( !client().findOne( ns, fromjson( "{'a.c':null}" ) ).isEmpty() );
|
||||
}
|
||||
};
|
||||
|
||||
class All : public UnitTest::Suite {
|
||||
public:
|
||||
All() {
|
||||
@ -473,6 +486,7 @@ namespace QueryTests {
|
||||
add< AutoResetIndexCache >();
|
||||
add< UniqueIndex >();
|
||||
add< UniqueIndexPreexistingData >();
|
||||
add< SubobjectInArray >();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -26,7 +26,7 @@ doTest = function() {
|
||||
assert.eq( 4, t.find( { a: { $nin: [ 2 ] } } ).count() );
|
||||
|
||||
t.save( { a: [ { b: [ 10, 11 ] }, 11 ] } );
|
||||
assert.eq( 7, t.find( { 'a.b': { $nin: [ 10 ] } } ).count() );
|
||||
assert.eq( 0, t.find( { 'a.b': { $nin: [ 10 ] } } ).count() );
|
||||
assert.eq( 7, t.find( { a: { $nin: [ 11 ] } } ).count() );
|
||||
|
||||
t.save( { a: { b: [ 20, 30 ] } } );
|
||||
|
Loading…
Reference in New Issue
Block a user