<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Wed Feb 07 22:03:29 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>[CXX-1659] cursor::begin() is invalid after using std::distance</title>
                <link>https://jira.mongodb.org/browse/CXX-1659</link>
                <project id="11980" key="CXX">C++ Driver</project>
                    <description>&lt;p&gt;I try to understand how the iterators of mongo-cxx-driver work.&lt;/p&gt;

&lt;p&gt;I create a document using&#160;bsoncxx::builder::basic::make_document and&#160;bsoncxx::builder::basic::kvp like this:&lt;/p&gt;

&lt;p&gt;&#160;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;mongocxx::instance inst{};&lt;/p&gt;

&lt;p&gt;std::tm tm;&lt;/p&gt;

&lt;p&gt;std::stringstream ss(&quot;1922-03-28&quot;);&lt;/p&gt;

&lt;p&gt;ss &amp;gt;&amp;gt; std::get_time(&amp;amp;tm, &quot;%Y-%m-%d&quot;);&lt;/p&gt;

&lt;p&gt;auto tp = std::chrono::system_clock::from_time_t(std::mktime(&amp;amp;tm));&lt;/p&gt;

&lt;p&gt;auto doc = make_document(kvp(&quot;name&quot;, &quot;John doe&quot;),&lt;/p&gt;

&lt;p&gt;&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;kvp(&quot;dob&quot;, bsoncxx::types::b_date(tp)),&lt;/p&gt;

&lt;p&gt;&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;kvp(&quot;id&quot;, &quot;abcde&quot;),&lt;/p&gt;

&lt;p&gt;&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;kvp(&quot;sex&quot;, &quot;M&quot;));&lt;/p&gt;

&lt;p&gt;auto client = mongocxx::client(mongocxx::uri());&lt;/p&gt;

&lt;p&gt;auto collection = client&lt;span class=&quot;error&quot;&gt;&amp;#91;&amp;quot;patientdb_test&amp;quot;&amp;#93;&lt;/span&gt;&lt;span class=&quot;error&quot;&gt;&amp;#91;&amp;quot;patient&amp;quot;&amp;#93;&lt;/span&gt;;&lt;/p&gt;

&lt;p&gt;collection.insert_one(doc.view());&lt;/p&gt;

&lt;p&gt;delay(2000); // Wait during two seconds.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&#160;&lt;/p&gt;

&lt;p&gt;After that, I search all documents:&lt;/p&gt;

&lt;p&gt;&#160;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;auto cursor = collection.find({});&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&#160;&lt;/p&gt;

&lt;p&gt;Finally, I test the cursor to see if it&apos;s empty and the number of element found using std::distance function:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;if(cursor.begin() != cursor.end())&lt;/p&gt;

&lt;p&gt;{&lt;/p&gt;

&lt;p&gt;&#160; &#160; &#160; auto it = cursor.begin();&lt;/p&gt;

&lt;p&gt;&#160; &#160; &#160;if(std::distance(it, cursor.end()) == 1)&lt;/p&gt;

&lt;p&gt;&#160; &#160; &#160; {&#160; &#160; &#160; &#160; &#160; &#160;&#160;&lt;/p&gt;

&lt;p&gt;&#160; &#160; &#160; &#160; &#160; &#160; &#160;if (cursor.begin() != cursor.end()) // &amp;lt;--- Segmentation fault&lt;/p&gt;

&lt;p&gt;&#160; &#160; &#160; &#160; &#160; &#160; &#160;&lt;/p&gt;
&lt;div class=&quot;error&quot;&gt;&lt;span class=&quot;error&quot;&gt;Unknown macro: {

&#160; &#160; &#160; &#160; &#160; &#160; &#160;}&lt;/span&gt; &lt;/div&gt;

&lt;p&gt;&#160; &#160; &#160; }&lt;/p&gt;

&lt;p&gt;}&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;I don&apos;t understand why the begin iterator change after the call of std::distance method.&lt;/p&gt;

&lt;p&gt;Is this a bug or do I use the cursor wrongly?&lt;/p&gt;</description>
                <environment>macOS X 10.13.6, Apple LLVM version 10.0.0 (clang-1000.11.45.2)&lt;br/&gt;
Target: x86_64-apple-darwin17.7.0&lt;br/&gt;
Thread model: posix</environment>
        <key id="612097">CXX-1659</key>
            <summary>cursor::begin() is invalid after using std::distance</summary>
                <type id="3" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14718&amp;avatarType=issuetype">Task</type>
                                            <priority id="3" iconUrl="https://jira.mongodb.org/images/icons/priorities/major.svg">Major - P3</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="Athius">Romain LEGUAY [X]</reporter>
                        <labels>
                            <label>cursor</label>
                    </labels>
                <created>Mon, 1 Oct 2018 08:49:28 +0000</created>
                <updated>Fri, 27 Oct 2023 13:13:39 +0000</updated>
                            <resolved>Tue, 2 Oct 2018 13:25:34 +0000</resolved>
                                    <version>3.3.1</version>
                                                                        <votes>0</votes>
                                    <watches>4</watches>
                                                                                                                <comments>
                            <comment id="2020209" author="athius" created="Tue, 2 Oct 2018 10:27:48 +0000"  >&lt;p&gt;Thank you for this great answer.&lt;/p&gt;

&lt;p&gt;I will use for now collection::count for my unit tests.&lt;/p&gt;

&lt;p&gt;&#160;&lt;/p&gt;</comment>
                            <comment id="2019679" author="kevin.albertson" created="Mon, 1 Oct 2018 19:54:56 +0000"  >&lt;p&gt;Also, if you only need to retrieve the count of documents in a collection (without iterating over individual documents later), it&apos;s much more efficient to use &lt;a href=&quot;http://mongocxx.org/api/current/classmongocxx_1_1collection.html#aea1a320131a4adead60332ff3a8d4027&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;collection::count&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;collection::count specifically will be deprecated in the 3.4.0 release in favor of two new methods: collection::count_documents and collection::estimated_document_count. But upgrading will be straightforward.&lt;/p&gt;</comment>
                            <comment id="2019509" author="kevin.albertson" created="Mon, 1 Oct 2018 18:14:18 +0000"  >&lt;p&gt;Right, you&apos;ll need to copy. Dereferencing the cursor iterator gives back a bsoncxx::document::view. This is a non-owning view of the bson document. You can copy this into an owning bsoncxx::document::value. The following example shows how to do that (using explicit types and an ordinary for loop):&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;    std::vector&amp;lt;bsoncxx::document::value&amp;gt; docs;&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;    for (mongocxx::cursor::iterator iter = cursor.begin();&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;         iter != cursor.end();&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;         iter++) {&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;        bsoncxx::document::view doc_view = *iter;&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;        // Copy the document view into a document value in the vector.&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;        docs.emplace_back(doc_view);&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;    }&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;    std::cout &amp;lt;&amp;lt; &quot;count is &quot; &amp;lt;&amp;lt; docs.size() &amp;lt;&amp;lt; std::endl;&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;The docs page on &lt;a href=&quot;http://mongocxx.org/mongocxx-v3/working-with-bson/#value&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;Working with BSON&lt;/a&gt; gives a bit more information on the view and value types. Hope that helps!&lt;/p&gt;

&lt;p&gt;I agree that cursor.current() might be a more logical sounding name. But having the standard begin/end functions allows us to use cursors like any STL iterator. For example, cursors can be used in range loops:&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;for (bsoncxx::document::view doc : collection.find(query)) {&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;     std::cout &amp;lt;&amp;lt; bsoncxx::to_json(doc) &amp;lt;&amp;lt; std::endl;&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;</comment>
                            <comment id="2019411" author="athius" created="Mon, 1 Oct 2018 17:10:57 +0000"  >&lt;p&gt;Thank you for your answer,&lt;/p&gt;

&lt;p&gt;I found the error: when I use the test Framework Catch2 and do a&lt;/p&gt;

&lt;p&gt;CHECK(cursor.begin() != cursor.end())&lt;/p&gt;

&lt;p&gt;And continue even if it&apos;s false.... so&#160;I obtained the segmentation fault.&lt;/p&gt;

&lt;p&gt;To put all bsoncxx::document::value inside a std::vector, I suppose we need to use std::copy or similar algorithm?&lt;/p&gt;

&lt;p&gt;Do you think cursor.current() would be a better name than cursor.begin()?&lt;/p&gt;

&lt;p&gt;&#160;&lt;/p&gt;</comment>
                            <comment id="2019123" author="kevin.albertson" created="Mon, 1 Oct 2018 14:57:02 +0000"  >&lt;p&gt;Hi &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=Athius&quot; class=&quot;user-hover&quot; rel=&quot;Athius&quot;&gt;Athius&lt;/a&gt;,&lt;/p&gt;

&lt;p&gt;Once results are returned in a cursor, subsequent calls to begin point to the next remaining result. &lt;a href=&quot;http://mongocxx.org/api/current/classmongocxx_1_1cursor.html#aabebe83225a2cf94474f60b2fce4f14d&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;Documented here&lt;/a&gt;. So once you iterate an iterator returned from cursor.begin(), subsequent calls to cursor.begin() return an iterator at the point where you left off.&lt;/p&gt;

&lt;p&gt;The call you have to std::distance iterates until the end. If you need to retrieve the count before iterating over, you could buffer the documents in a &lt;tt&gt;std::vector&lt;/tt&gt; or similar.&lt;/p&gt;

&lt;p&gt;However, the segmentation fault seems odd to me. That call to cursor.begin() should return the end iterator, and I&apos;ve checked with my own test. Can you provide a compilable example?&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|htzmhz:</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>