Uploaded image for project: 'C++ Driver'
  1. C++ Driver
  2. CXX-1152

Context enforcement for BSON stream builder doesn't play nicely with statements that leave open sub-documents or sub-arrays

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 3.2.0-rc0
    • Affects Version/s: None
    • Component/s: BSON, Documentation
    • Labels:

      BSON stream builders feature the ability to stream keys and values across multiple statements, including values that leave open new sub-documents and sub-arrays. As a result, the type system cannot have knowledge of what the current level of depth is for a BSON stream builder, or what the type of its current context is. This leads to unintuitive behaviors.

      Consider the following code snippet (modified from the test case "[] with large nesting levels") that uses a document stream builder to build the document {"a": {"b": {"c": 1}}}:

      // Example 1:
      bsoncxx::stream::builder::document doc;
      doc << "a" << open_document;
      doc << "b" << open_document;
      doc << "c" << 1;
      doc << close_document;
      doc << close_document;

      This above code snippet correctly builds this document. However, this code compiles only because all of the above statements happen to be valid in key context (since the type of "doc" is a derived class of bsoncxx::builder::stream::key_context).

      Things start to get wonky when attempting to use stream builders in a statement where multiple levels of depth are backtracked:

      // Example 2:
      bsoncxx::stream::builder::document doc;
      doc << "a" << open_document << "b" << open_document;
      doc << "c" << 1;
      doc << close_document << close_document;  // Doesn't compile!  Can't append close_document to a closed_context.

      Or, when a statement leaves open a sub-document or sub-array which provides a different context than the top-level BSON datum type provides:

      // Example 3:
      bsoncxx::stream::builder::document doc;
      doc << "x" << open_array;
      doc << 1;  // Doesn't compile!  "doc" isn't an array_context.
      doc << close_array;  // Doesn't compile!  "doc" isn't an array_context.

      The fact that "example 1" compiles and runs but "example 2" and "example 3" fail to compile reveals a fundamental design flaw in the stream builder. The stream builder should be changed such that either all three examples compile, or all three examples fail to compile.

            sam.rossi@mongodb.com Samuel Rossi (Inactive)
            rassi J Rassi
            0 Vote for this issue
            3 Start watching this issue