<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Wed Feb 07 21:13:48 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>MongoDB Jira</title>
    <link>https://jira.mongodb.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>9.7.1</version>
        <build-number>970001</build-number>
        <build-date>13-04-2023</build-date>
    </build-info>


<item>
            <title>[CDRIVER-1983] BSON_TYPE_ARRAY - what is the right way to determine that the root document is an array?</title>
                <link>https://jira.mongodb.org/browse/CDRIVER-1983</link>
                <project id="10030" key="CDRIVER">C Driver</project>
                    <description>&lt;p&gt;Hi everyone,&lt;/p&gt;

&lt;p&gt;There are some API calls in &lt;tt&gt;mongoc&lt;/tt&gt; that require BSON arrays as their input. A good example would be aggregation pipelines for instance. But that&apos;s hardly the main cause for the following important question.&lt;/p&gt;

&lt;p&gt;When marshalling high-level language types to and from BSON, one encounters a problem with how to reliably determine if a &lt;b&gt;root&lt;/b&gt; document is an array. There is no such issue for &lt;b&gt;nested&lt;/b&gt; arrays because one can rely on the element&apos;s type - &lt;tt&gt;BSON_DOCUMENT&lt;/tt&gt; vs &lt;tt&gt;BSON_ARRAY&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;More specifically, if I want to build a root BSON array, I need to append elements with string keys &quot;0&quot;, &quot;1&quot;, &quot;2&quot;, etc. effectively converting them from the original indexes with &lt;tt&gt;bson_uint32_to_string()&lt;/tt&gt;. The output BSON will be like this:&lt;/p&gt;
&lt;p/&gt;
&lt;div id=&quot;syntaxplugin&quot; class=&quot;syntaxplugin&quot; style=&quot;border: 1px dashed #bbb; border-radius: 5px !important; overflow: auto; max-height: 30em;&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; width=&quot;100%&quot; style=&quot;font-size: 1em; line-height: 1.4em !important; font-weight: normal; font-style: normal; color: black;&quot;&gt;
		&lt;tbody &gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;  margin-top: 10px;   margin-bottom: 10px;  width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;{ &quot;0&quot; : &quot;aaa&quot;, &quot;1&quot; : &quot;bbb&quot;, &quot;2&quot; : &quot;ccc&quot;, ... }&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
			&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p/&gt;

&lt;p&gt;If I fail to do this, the underlying &lt;tt&gt;bson_append_array()&lt;/tt&gt; routine in &lt;tt&gt;mongoc&lt;/tt&gt; will complain in &lt;tt&gt;stderr&lt;/tt&gt; about improperly formed array keys.&lt;/p&gt;

&lt;p&gt;But what happens if I want to restore the original array in a high-level language from such a document? Obviously, I need to somehow determine that this document is indeed an array because it would otherwise be incorrect to marshal it back as a document (associative array) with string keys &quot;0&quot;, &quot;1&quot;, &quot;2&quot;, etc.&lt;/p&gt;

&lt;p&gt;Should I first parse &lt;b&gt;all&lt;/b&gt; the keys converting them from strings to integers and checking if they are in ascending order and then traverse the document again?&lt;/p&gt;

&lt;p&gt;If yes, there is no &lt;tt&gt;bson_string_to_uint32()&lt;/tt&gt; call for quick backward conversion, and I am left to use slow GLIBC calls like &lt;tt&gt;strtol()&lt;/tt&gt; to do that.&lt;/p&gt;

&lt;p&gt;If no, I can just check the first key and see if it is &quot;0&quot;, but that doesn&apos;t seem to be reliable to me because one can forge a document like &lt;p/&gt;
&lt;div id=&quot;syntaxplugin&quot; class=&quot;syntaxplugin&quot; style=&quot;border: 1px dashed #bbb; border-radius: 5px !important; overflow: auto; max-height: 30em;&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; width=&quot;100%&quot; style=&quot;font-size: 1em; line-height: 1.4em !important; font-weight: normal; font-style: normal; color: black;&quot;&gt;
		&lt;tbody &gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;  margin-top: 10px;   margin-bottom: 10px;  width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;{ &quot;0&quot; : &quot;aaa&quot;, &quot;2&quot; : &quot;bbb&quot;, &quot;4&quot; : &quot;ccc&quot; }&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
			&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p/&gt; which will lose information if treated like an array.&lt;/p&gt;

&lt;p&gt;So, what is the &lt;b&gt;official canonical way&lt;/b&gt; to marshal root BSON arrays back to a high-level language?&lt;/p&gt;

&lt;p&gt;Of course, this leaves one lingering with a question as why BSON is designed the way that it needs string keys &quot;0&quot;, &quot;1&quot;, &quot;2&quot;,... for arrays at all instead of having a proper way to format arrays without them. This can be done fairly easily retaining backward compatibility.&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;</description>
                <environment></environment>
        <key id="343143">CDRIVER-1983</key>
            <summary>BSON_TYPE_ARRAY - what is the right way to determine that the root document is an array?</summary>
                <type id="3" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14718&amp;avatarType=issuetype">Task</type>
                                            <priority id="4" iconUrl="https://jira.mongodb.org/images/icons/priorities/minor.svg">Minor - P4</priority>
                        <status id="6" iconUrl="https://jira.mongodb.org/images/icons/statuses/closed.png" description="The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.">Closed</status>
                    <statusCategory id="3" key="done" colorName="success"/>
                                    <resolution id="13202">Works as Designed</resolution>
                                        <assignee username="-1">Unassigned</assignee>
                                    <reporter username="neoxic">Arseny Vakhrushev</reporter>
                        <labels>
                    </labels>
                <created>Fri, 6 Jan 2017 05:39:41 +0000</created>
                <updated>Fri, 27 Oct 2023 13:14:22 +0000</updated>
                            <resolved>Tue, 17 Jan 2017 19:56:11 +0000</resolved>
                                                                                        <votes>0</votes>
                                    <watches>4</watches>
                                                                                                                <comments>
                            <comment id="1479961" author="neoxic" created="Thu, 19 Jan 2017 01:58:42 +0000"  >&lt;p&gt;Single-typed arrays are a good development indeed! And I strongly vote for it.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The case where a MongoDB client has a document and doesn&apos;t know whether it&apos;s an array or not arises very rarely - essentially, only in mongoc_collection_aggregate.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;That is indeed a very rare problem I wouldn&apos;t vote for solving solely. That&apos;s why I created a question instead of an issue in the first place.&lt;/p&gt;

&lt;p&gt;But if you are really following me, you can see that these things ...&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;The need to fiddle with integer/string keys via bson_uint32_to_string();&lt;/li&gt;
	&lt;li&gt;The need to store ugly string keys &quot;0&quot;, &quot;1&quot;, &quot;2&quot; ... in documents which will save space;&lt;/li&gt;
	&lt;li&gt;The need to report ugly array errors to stderr;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;... are present independently from the initial issue. They are always side-by-side with arrays in &lt;tt&gt;libbson&lt;/tt&gt;, and they aren&apos;t looking great. Moreover, they can&apos;t and won&apos;t be fixed by single-typed arrays alone except, of course, if you deprecate &lt;tt&gt;BSON_TYPE_ARRAY&lt;/tt&gt; altogether making it impossible to have mixed-type arrays. This will make BSON incompatible with JSON though.&lt;/p&gt;</comment>
                            <comment id="1479952" author="jesse" created="Thu, 19 Jan 2017 01:44:25 +0000"  >&lt;p&gt;Arseny, thanks for your five cents. That&apos;s an interesting proposal. However, it solves a very rare problem. The case where a MongoDB client has a document and doesn&apos;t know whether it&apos;s an array or not arises very rarely - essentially, only in mongoc_collection_aggregate.&lt;/p&gt;

&lt;p&gt;We have a better and more radical proposal that we plan to implement within the next few server releases: fixed-type arrays, &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-9380&quot; title=&quot;Add single-type arrays&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-9380&quot;&gt;SERVER-9380&lt;/a&gt;. If we&apos;re going to make the effort to deeply change the structure of BSON, then fixed-type arrays are a better investment. Please watch and vote for that ticket.&lt;/p&gt;</comment>
                            <comment id="1478743" author="neoxic" created="Wed, 18 Jan 2017 04:45:23 +0000"  >&lt;p&gt;Yes, I am aware about &lt;tt&gt;bson_uint32_to_string()&lt;/tt&gt;&apos;s pregenerated values. That&apos;s what I meant by saying that the opposite operation should be at least as fast to be worth the efforts put into &lt;tt&gt;bson_uint32_to_string()&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;I must admit that the design of arrays in BSON doesn&apos;t look nice and clean to me. May I ask you why the hassle with converting integer keys to strings, storing them (they occupy space), converting them back to check, etc. exists? Wouldn&apos;t it be much cleaner to specify arrays without keys altogether?&lt;/p&gt;

&lt;p&gt;Let&apos;s assume we could extend the document specification, so:&lt;/p&gt;
&lt;p/&gt;
&lt;div id=&quot;syntaxplugin&quot; class=&quot;syntaxplugin&quot; style=&quot;border: 1px dashed #bbb; border-radius: 5px !important; overflow: auto; max-height: 30em;&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; width=&quot;100%&quot; style=&quot;font-size: 1em; line-height: 1.4em !important; font-weight: normal; font-style: normal; color: black;&quot;&gt;
		&lt;tbody &gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;  margin-top: 10px;   margin-bottom: 10px;  width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;document ::= int32 e_list &quot;\x00&quot;&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
			&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p/&gt;
&lt;p&gt;becomes:&lt;/p&gt;
&lt;p/&gt;
&lt;div id=&quot;syntaxplugin&quot; class=&quot;syntaxplugin&quot; style=&quot;border: 1px dashed #bbb; border-radius: 5px !important; overflow: auto; max-height: 30em;&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; width=&quot;100%&quot; style=&quot;font-size: 1em; line-height: 1.4em !important; font-weight: normal; font-style: normal; color: black;&quot;&gt;
		&lt;tbody &gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;  margin-top: 10px;   margin-bottom: 10px;  width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;document ::= int32 e_list &quot;\x00&quot; (value*)&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
			&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p/&gt;
&lt;p&gt;and we demand that either the &lt;tt&gt;e_list&lt;/tt&gt; part or the &lt;tt&gt;(value*)&lt;/tt&gt; part should be empty. In other words, one must not mix associative and sequential parts together.&lt;/p&gt;

&lt;p&gt;With this:&lt;br/&gt;
1) We will retain backward compatibility when the &lt;tt&gt;(value*)&lt;/tt&gt; part is absent;&lt;br/&gt;
2) We will be able to quickly determine if the document is array-like by comparing the first key to &quot;\x00&quot;;&lt;br/&gt;
3) No need to fiddle with integer/string keys via &lt;tt&gt;bson_uint32_to_string()&lt;/tt&gt;;&lt;br/&gt;
4) No need to store ugly string keys &quot;0&quot;, &quot;1&quot;, &quot;2&quot; ... in documents which will save space;&lt;br/&gt;
4) No need to report ugly array errors to &lt;tt&gt;stderr&lt;/tt&gt;;&lt;br/&gt;
5) We can get rid of the &lt;tt&gt;BSON_TYPE_ARRAY&lt;/tt&gt; type in the future or continue using it for backward compatibility;&lt;/p&gt;

&lt;p&gt;Yes, this might imply a new set of &lt;tt&gt;bson_append_&lt;/tt&gt;-like functions or extending the existing ones, but the API will look much cleaner and the above benefits seem to be attainable for a small effort.&lt;/p&gt;

&lt;p&gt;Just my five cents...&lt;/p&gt;</comment>
                            <comment id="1478737" author="jesse" created="Wed, 18 Jan 2017 04:12:22 +0000"  >&lt;p&gt;That&apos;s correct. Consider either comparing the first key to &quot;0&quot; or, if you need to check all N keys, then generate each key &quot;i&quot; from 0 to N with bson_uint32_to_string and compare the i&apos;th key to the current key. Note that bson_uint32_to_string has &lt;b&gt;pregenerated&lt;/b&gt; the first 1000 keys so it&apos;s effectively only the strncmp of a very short string that you&apos;re paying for. &lt;/p&gt;</comment>
                            <comment id="1478720" author="neoxic" created="Wed, 18 Jan 2017 03:04:15 +0000"  >&lt;p&gt;Now we&apos;re cooking. To iterate all the top-level keys quickly and check their &lt;b&gt;integer&lt;/b&gt; values, there clearly should be some kind of the opposite to &lt;tt&gt;bson_uint32_to_string()&lt;/tt&gt;, namely &lt;tt&gt;bson_string_to_uint32()&lt;/tt&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;There is no bson_string_to_uint32() call for quick backward conversion, and I am left to use slow GLIBC calls like strtol() to do that.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Otherwise, all the effort put into &lt;tt&gt;bson_uint32_to_string()&lt;/tt&gt; to speed up conversion of integer keys goes waste on the way back.&lt;/p&gt;

&lt;p&gt;So, the only viable option to determine &quot;array-likeness&quot; right now is to check if the first key is &quot;0&quot;. Is that correct?&lt;/p&gt;</comment>
                            <comment id="1478646" author="jesse" created="Tue, 17 Jan 2017 23:26:01 +0000"  >&lt;p&gt;You can determine if the BSON is array-like by iterating all the top-level&lt;br/&gt;
keys and asserting they are the strings &quot;0&quot;, &quot;1&quot;, &quot;2&quot;, ....  As a&lt;br/&gt;
heuristic, check if the first key is the string &quot;0&quot;.&lt;/p&gt;

&lt;p&gt;On Tue, Jan 17, 2017 at 5:05 PM Arseny Vakhrushev (JIRA) &amp;lt;jira@mongodb.org&amp;gt;&lt;/p&gt;
</comment>
                            <comment id="1478547" author="neoxic" created="Tue, 17 Jan 2017 22:04:49 +0000"  >&lt;p&gt;Thanks for your attention, Jesse!&lt;br/&gt;
Hannes&apos; answer merely repeated what I actually asked - &quot;There&apos;s no way to determine if a root BSON is an array because there&apos;s no such thing as a root BSON array&quot;. Hope the following will not waste everyone&apos;s time including me....&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;There is no such thing called &quot;root BSON array&quot;. The &quot;root BSON&quot; is defined as a document per the spec, so the canonical container is always document.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;This is simply not true. To prove that, one can run:&lt;/p&gt;
&lt;p/&gt;
&lt;div id=&quot;syntaxplugin&quot; class=&quot;syntaxplugin&quot; style=&quot;border: 1px dashed #bbb; border-radius: 5px !important; overflow: auto; max-height: 30em;&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; width=&quot;100%&quot; style=&quot;font-size: 1em; line-height: 1.4em !important; font-weight: normal; font-style: normal; color: black;&quot;&gt;
		&lt;tbody &gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;  margin-top: 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;#include &amp;lt;mongoc.h&amp;gt;&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&amp;nbsp;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;int main() {&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	mongoc_client_t *client;&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	mongoc_collection_t *collection;&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	mongoc_cursor_t *cursor;&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	bson_t pipeline;&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&amp;nbsp;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	mongoc_init();&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&amp;nbsp;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	client = mongoc_client_new(&quot;mongodb://127.0.0.1&quot;);&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	BSON_ASSERT(client);&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	collection = mongoc_client_get_collection(client, &quot;test-database&quot;, &quot;test-collection&quot;);&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	BSON_ASSERT(collection);&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&amp;nbsp;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	bson_init(&amp;amp;pipeline);&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	BSON_APPEND_BOOL(&amp;amp;pipeline, &quot;a&quot;, true);&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&amp;nbsp;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	cursor = mongoc_collection_aggregate(collection, 0, &amp;amp;pipeline, 0, 0);&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	BSON_ASSERT(cursor);&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&amp;nbsp;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	bson_destroy(&amp;amp;pipeline);&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	mongoc_cursor_destroy(cursor);&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	mongoc_collection_destroy(collection);&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	mongoc_client_destroy(client);&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	mongoc_cleanup();&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;	return 0;&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   margin-bottom: 10px;  width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
			&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p/&gt;

&lt;p&gt;And the result is:&lt;/p&gt;
&lt;p/&gt;
&lt;div id=&quot;syntaxplugin&quot; class=&quot;syntaxplugin&quot; style=&quot;border: 1px dashed #bbb; border-radius: 5px !important; overflow: auto; max-height: 30em;&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; width=&quot;100%&quot; style=&quot;font-size: 1em; line-height: 1.4em !important; font-weight: normal; font-style: normal; color: black;&quot;&gt;
		&lt;tbody &gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;  margin-top: 10px;   margin-bottom: 10px;  width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;bson_append_array(): invalid array detected. first element of array parameter is not &quot;0&quot;.&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
			&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p/&gt;

&lt;p&gt;So clearly, &lt;tt&gt;mongoc&lt;/tt&gt; &lt;b&gt;does&lt;/b&gt; in fact internally &lt;b&gt;distinguish&lt;/b&gt; between root arrays and documents. Hence my initial question.&lt;/p&gt;

&lt;p&gt;If I am writing a binding to &lt;tt&gt;mongoc&lt;/tt&gt; for a high-level language, this leads to the following problem. When a high-level &lt;b&gt;array&lt;/b&gt; is converted to a type that wraps around &lt;tt&gt;bson_t&lt;/tt&gt; which is then fed to a &lt;tt&gt;mongoc_collection_aggregate()&lt;/tt&gt; wrapper for example, there should be a way to check the argument that it&apos;s a root BSON array to let the user know. Otherwise, I&apos;ll get the above error message in &lt;tt&gt;stderr&lt;/tt&gt; (which should in fact be propagated upwards btw).&lt;/p&gt;

&lt;p&gt;There are two ways to achieve that now:&lt;br/&gt;
1) I need to store additional information (a flag) along with a &lt;tt&gt;bson_t&lt;/tt&gt;;&lt;br/&gt;
2) I need to rely on the contents of a &lt;tt&gt;bson_t&lt;/tt&gt; itself to determine if it&apos;s a root array or not (note that I do exactly that for nested arrays relying on their type);&lt;/p&gt;

&lt;p&gt;A similar problem arises when I try to do transitions like:&lt;/p&gt;

&lt;p&gt;&lt;tt&gt;High-level Array type ---&amp;gt; Wrapper around bson_t ---&amp;gt; High-level Array type&lt;/tt&gt;&lt;/p&gt;

&lt;p&gt;I should be able to restore the initial high-level array from a wrapper type whenever I get a fresh copy of &lt;tt&gt;bson_t&lt;/tt&gt;. To do that, I need to know how to determine if &lt;tt&gt;bson_t&lt;/tt&gt; is an array. Hence my initial question.&lt;/p&gt;

&lt;p&gt;To elaborate further, consider that I am mapping two methods of a &lt;tt&gt;mongoc_gridfs_file_t&lt;/tt&gt;:&lt;br/&gt;
1) &lt;tt&gt;mongoc_gridfs_file_get_aliases()&lt;/tt&gt; - returns a root BSON array which I should be able to restore as a high-level array based on its contents;&lt;br/&gt;
2)  &lt;tt&gt;mongoc_gridfs_file_set_aliases()&lt;/tt&gt; - aniticipates a root BSON array; otherwise, it produces the same error message about invalid array keys;&lt;/p&gt;

&lt;p&gt;To summarize things up, the API complains about root documents not being &quot;properly formatted&quot; whereas there&apos;s no way to determine if documents &lt;b&gt;are&lt;/b&gt; indeed &quot;properly formatted&quot; &lt;b&gt;before&lt;/b&gt; providing them to other methods.&lt;/p&gt;

&lt;p&gt;Hope this will be useful....&lt;/p&gt;</comment>
                            <comment id="1478387" author="jesse" created="Tue, 17 Jan 2017 19:56:11 +0000"  >&lt;p&gt;We haven&apos;t heard back in a while, let us know if you have more questions.&lt;/p&gt;</comment>
                            <comment id="1471608" author="bjori" created="Fri, 6 Jan 2017 21:29:16 +0000"  >&lt;p&gt;I&apos;m not entirely following, so excuse me if I&apos;m being daft, but I think you are asking how to determine if the &quot;container BSON&quot; or &quot;root BSON&quot; is an array or document?&lt;/p&gt;

&lt;p&gt;There is no such thing called &quot;root BSON array&quot;. The &quot;root BSON&quot; is defined as a document per the spec, so the canonical container is always document.&lt;/p&gt;

&lt;p&gt;Does that make sense?&lt;/p&gt;</comment>
                            <comment id="1471595" author="rassi@10gen.com" created="Fri, 6 Jan 2017 21:17:37 +0000"  >&lt;p&gt;Moved to CDRIVER.&lt;/p&gt;</comment>
                            <comment id="1470967" author="neoxic" created="Fri, 6 Jan 2017 07:08:57 +0000"  >&lt;p&gt;Oh, sorry. This mostly pertains to CDRIVER and libbson, not CXX. Thanks!&lt;/p&gt;</comment>
                    </comments>
                    <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|hstgl3:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10558" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>9223372036854775807</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            </customfields>
    </item>
</channel>
</rss>