Beispiel #1
0
TEST(Path, NestedNoLeaf1) {
    ElementPath p;
    ASSERT(p.init("a.b").isOK());
    p.setTraverseLeafArray(false);

    BSONObj doc =
        BSON("a" << BSON_ARRAY(BSON("b" << 5) << 3 << BSONObj() << BSON("b" << BSON_ARRAY(9 << 11))
                                              << BSON("b" << 7)));

    BSONElementIterator cursor(&p, doc);

    ASSERT(cursor.more());
    BSONElementIterator::Context e = cursor.next();
    ASSERT_EQUALS(5, e.element().numberInt());
    ASSERT(!e.outerArray());

    ASSERT(cursor.more());
    e = cursor.next();
    ASSERT(e.element().eoo());
    ASSERT_EQUALS((string) "2", e.arrayOffset().fieldName());
    ASSERT(!e.outerArray());

    ASSERT(cursor.more());
    e = cursor.next();
    ASSERT_EQUALS(Array, e.element().type());
    ASSERT_EQUALS(2, e.element().Obj().nFields());
    ASSERT(e.outerArray());

    ASSERT(cursor.more());
    e = cursor.next();
    ASSERT_EQUALS(7, e.element().numberInt());
    ASSERT(!e.outerArray());

    ASSERT(!cursor.more());
}
Beispiel #2
0
// When the path (partially or in its entirety) refers to an array,
// the iteration logic does not return an EOO.
// what we want ideally.
TEST(Path, NestedPartialMatchArray) {
    ElementPath p;
    ASSERT(p.init("a.b").isOK());

    BSONObj doc = BSON("a" << BSON_ARRAY(4));

    BSONElementIterator cursor(&p, doc);

    ASSERT(!cursor.more());
}
Beispiel #3
0
TEST(Path, Root1) {
    ElementPath p;
    ASSERT(p.init("a").isOK());

    BSONObj doc = BSON("x" << 4 << "a" << 5);

    BSONElementIterator cursor(&p, doc);
    ASSERT(cursor.more());
    ElementIterator::Context e = cursor.next();
    ASSERT_EQUALS((string) "a", e.element().fieldName());
    ASSERT_EQUALS(5, e.element().numberInt());
    ASSERT(!cursor.more());
}
Beispiel #4
0
TEST(Path, ArrayIndex2) {
    ElementPath p;
    ASSERT(p.init("a.1").isOK());

    BSONObj doc = BSON("a" << BSON_ARRAY(5 << BSON_ARRAY(2 << 4) << 3));

    BSONElementIterator cursor(&p, doc);

    ASSERT(cursor.more());
    BSONElementIterator::Context e = cursor.next();
    ASSERT_EQUALS(Array, e.element().type());

    ASSERT(!cursor.more());
}
Beispiel #5
0
TEST(Path, RootArray2) {
    ElementPath p;
    ASSERT(p.init("a").isOK());
    p.setTraverseLeafArray(false);

    BSONObj doc = BSON("x" << 4 << "a" << BSON_ARRAY(5 << 6));

    BSONElementIterator cursor(&p, doc);

    ASSERT(cursor.more());
    BSONElementIterator::Context e = cursor.next();
    ASSERT(e.element().type() == Array);

    ASSERT(!cursor.more());
}
Beispiel #6
0
TEST(Path, ArrayIndexNested2) {
    ElementPath p;
    ASSERT(p.init("a.1.b").isOK());

    BSONObj doc = BSON("a" << BSON_ARRAY(5 << BSON_ARRAY(BSON("b" << 4)) << 3));

    BSONElementIterator cursor(&p, doc);

    ASSERT(cursor.more());
    BSONElementIterator::Context e = cursor.next();
    ASSERT_EQUALS(4, e.element().numberInt());


    ASSERT(!cursor.more());
}
Beispiel #7
0
// Note that this describes existing behavior and not necessarily
TEST(Path, NestedEmptyArray) {
    ElementPath p;
    ASSERT(p.init("a.b").isOK());

    BSONObj doc = BSON("a" << BSON("b" << BSONArray()));

    BSONElementIterator cursor(&p, doc);

    ASSERT(cursor.more());
    BSONElementIterator::Context e = cursor.next();
    ASSERT_EQUALS(Array, e.element().type());
    ASSERT_EQUALS(0, e.element().Obj().nFields());
    ASSERT(e.outerArray());

    ASSERT(!cursor.more());
}
Beispiel #8
0
TEST(Path, NestedPartialMatchScalar) {
    ElementPath p;
    ASSERT(p.init("a.b").isOK());

    BSONObj doc = BSON("a" << 4);

    BSONElementIterator cursor(&p, doc);

    ASSERT(cursor.more());
    BSONElementIterator::Context e = cursor.next();
    ASSERT(e.element().eoo());
    ASSERT(e.arrayOffset().eoo());
    ASSERT(!e.outerArray());

    ASSERT(!cursor.more());
}
static BSONElement extractKeyElementFromMatchable(const MatchableDocument& matchable,
                                                  const StringData& pathStr) {
    ElementPath path;
    path.init(pathStr);
    path.setTraverseNonleafArrays(false);
    path.setTraverseLeafArray(false);

    MatchableDocument::IteratorHolder matchIt(&matchable, &path);
    if (!matchIt->more())
        return BSONElement();

    BSONElement matchEl = matchIt->next().element();
    // We shouldn't have more than one element - we don't expand arrays
    dassert(!matchIt->more());

    return matchEl;
}
Beispiel #10
0
// SERVER-15899: test iteration using a path that generates no elements, but traverses a long
// array containing subdocuments with nested arrays.
TEST(Path, NonMatchingLongArrayOfSubdocumentsWithNestedArrays) {
    ElementPath p;
    ASSERT(p.init("a.b.x").isOK());

    // Build the document {a: [{b: []}, {b: []}, {b: []}, ...]}.
    BSONObj subdoc = BSON("b" << BSONArray());
    BSONArrayBuilder builder;
    for (int i = 0; i < 100 * 1000; ++i) {
        builder.append(subdoc);
    }
    BSONObj doc = BSON("a" << builder.arr());

    BSONElementIterator cursor(&p, doc);

    // The path "a.b.x" matches no elements.
    ASSERT(!cursor.more());
}
Beispiel #11
0
// When multiple arrays are traversed implicitly in the same path,
// ElementIterator::Context::arrayOffset() should always refer to the current offset of the
// outermost array that is implicitly traversed.
TEST(Path, NestedArrayImplicitTraversal) {
    ElementPath p;
    ASSERT(p.init("a.b").isOK());
    BSONObj doc = fromjson("{a: [{b: [2, 3]}, {b: [4, 5]}]}");
    BSONElementIterator cursor(&p, doc);

    ASSERT(cursor.more());
    ElementIterator::Context e = cursor.next();
    ASSERT_EQUALS(NumberInt, e.element().type());
    ASSERT_EQUALS(2, e.element().numberInt());
    ASSERT_EQUALS("0", e.arrayOffset().fieldNameStringData());

    ASSERT(cursor.more());
    e = cursor.next();
    ASSERT_EQUALS(NumberInt, e.element().type());
    ASSERT_EQUALS(3, e.element().numberInt());
    ASSERT_EQUALS("0", e.arrayOffset().fieldNameStringData());

    ASSERT(cursor.more());
    e = cursor.next();
    ASSERT_EQUALS(Array, e.element().type());
    ASSERT_BSONOBJ_EQ(BSON("0" << 2 << "1" << 3), e.element().Obj());
    ASSERT_EQUALS("0", e.arrayOffset().fieldNameStringData());

    ASSERT(cursor.more());
    e = cursor.next();
    ASSERT_EQUALS(NumberInt, e.element().type());
    ASSERT_EQUALS(4, e.element().numberInt());
    ASSERT_EQUALS("1", e.arrayOffset().fieldNameStringData());

    ASSERT(cursor.more());
    e = cursor.next();
    ASSERT_EQUALS(NumberInt, e.element().type());
    ASSERT_EQUALS(5, e.element().numberInt());
    ASSERT_EQUALS("1", e.arrayOffset().fieldNameStringData());

    ASSERT(cursor.more());
    e = cursor.next();
    ASSERT_EQUALS(Array, e.element().type());
    ASSERT_BSONOBJ_EQ(BSON("0" << 4 << "1" << 5), e.element().Obj());
    ASSERT_EQUALS("1", e.arrayOffset().fieldNameStringData());

    ASSERT(!cursor.more());
}
Beispiel #12
0
TEST(Path, ArrayIndex3) {
    ElementPath p;
    ASSERT(p.init("a.1").isOK());

    BSONObj doc = BSON("a" << BSON_ARRAY(5 << BSON("1" << 4) << 3));

    BSONElementIterator cursor(&p, doc);

    ASSERT(cursor.more());
    BSONElementIterator::Context e = cursor.next();
    ASSERT_EQUALS(4, e.element().numberInt());
    ASSERT(!e.outerArray());

    ASSERT(cursor.more());
    e = cursor.next();
    ASSERT_BSONOBJ_EQ(BSON("1" << 4), e.element().Obj());
    ASSERT(e.outerArray());

    ASSERT(!cursor.more());
}
Beispiel #13
0
TEST(Path, RootArray1) {
    ElementPath p;
    ASSERT(p.init("a").isOK());

    BSONObj doc = BSON("x" << 4 << "a" << BSON_ARRAY(5 << 6));

    BSONElementIterator cursor(&p, doc);

    ASSERT(cursor.more());
    BSONElementIterator::Context e = cursor.next();
    ASSERT_EQUALS(5, e.element().numberInt());

    ASSERT(cursor.more());
    e = cursor.next();
    ASSERT_EQUALS(6, e.element().numberInt());

    ASSERT(cursor.more());
    e = cursor.next();
    ASSERT_EQUALS(Array, e.element().type());

    ASSERT(!cursor.more());
}
Beispiel #14
0
// SERVER-14886: when an array is being traversed explictly at the same time that a nested array
// is being traversed implicitly, ElementIterator::Context::arrayOffset() should return the
// current offset of the array being implicitly traversed.
TEST(Path, ArrayOffsetWithImplicitAndExplicitTraversal) {
    ElementPath p;
    ASSERT(p.init("a.0.b").isOK());
    BSONObj doc = fromjson("{a: [{b: [2, 3]}, {b: [4, 5]}]}");
    BSONElementIterator cursor(&p, doc);

    ASSERT(cursor.more());
    ElementIterator::Context e = cursor.next();
    ASSERT_EQUALS(EOO, e.element().type());
    ASSERT_EQUALS("0", e.arrayOffset().fieldNameStringData());  // First elt of outer array.

    ASSERT(cursor.more());
    e = cursor.next();
    ASSERT_EQUALS(NumberInt, e.element().type());
    ASSERT_EQUALS(2, e.element().numberInt());
    ASSERT_EQUALS("0", e.arrayOffset().fieldNameStringData());  // First elt of inner array.

    ASSERT(cursor.more());
    e = cursor.next();
    ASSERT_EQUALS(NumberInt, e.element().type());
    ASSERT_EQUALS(3, e.element().numberInt());
    ASSERT_EQUALS("1", e.arrayOffset().fieldNameStringData());  // Second elt of inner array.

    ASSERT(cursor.more());
    e = cursor.next();
    ASSERT_EQUALS(Array, e.element().type());
    ASSERT_BSONOBJ_EQ(BSON("0" << 2 << "1" << 3), e.element().Obj());
    ASSERT(e.arrayOffset().eoo());

    ASSERT(cursor.more());
    e = cursor.next();
    ASSERT_EQUALS(EOO, e.element().type());
    ASSERT_EQUALS("1", e.arrayOffset().fieldNameStringData());  // Second elt of outer array.

    ASSERT(!cursor.more());
}