<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Thu Feb 08 08:36:47 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>[GODRIVER-1621] options.Update().SetUpsert(true) being reset after each collection.updateOne</title>
                <link>https://jira.mongodb.org/browse/GODRIVER-1621</link>
                <project id="14289" key="GODRIVER">Go Driver</project>
                    <description>&lt;p&gt;If I setup an opts variable, like this:&lt;/p&gt;

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

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;opts := options.Update().SetUpsert(true)&lt;/p&gt;

&lt;p&gt;```&lt;/p&gt;

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

&lt;p&gt;Then I run collection.updateOne using that opts variable, then try to run another collection.UpdateOne using that opts variable it gives an error which does not describe that the problem is that the upsert option is not set to true and there is no existing document that matches the filter,.&lt;/p&gt;

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

&lt;p&gt;If I just reset the opts variable after each collection.updateOne, like this:&lt;/p&gt;

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

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;opts := options.Update().SetUpsert(true)&lt;/p&gt;

&lt;p&gt;```&lt;/p&gt;

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

&lt;p&gt;Then it works as intended.&#160; The error is ambiguous and I do not understand the reason that it would reset the options each time when the options are stored in a variable.&lt;/p&gt;</description>
                <environment>Linux 4.9.0-11-amd64</environment>
        <key id="1357634">GODRIVER-1621</key>
            <summary>options.Update().SetUpsert(true) being reset after each collection.updateOne</summary>
                <type id="1" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14703&amp;avatarType=issuetype">Bug</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="andrewhodel@gmail.com">Andrew Hodel</reporter>
                        <labels>
                    </labels>
                <created>Wed, 20 May 2020 19:41:58 +0000</created>
                <updated>Fri, 27 Oct 2023 13:16:28 +0000</updated>
                            <resolved>Fri, 22 May 2020 00:02:21 +0000</resolved>
                                    <version>1.1.4</version>
                                                    <component>CRUD</component>
                                        <votes>0</votes>
                                    <watches>2</watches>
                                                                                                                <comments>
                            <comment id="3103965" author="divjot.arora" created="Fri, 22 May 2020 04:17:39 +0000"  >&lt;p&gt;Variadic is just a way for saying &quot;give us any number of options instances&quot;.&lt;/p&gt;

&lt;p&gt;Yes, the driver absolutely does not change the variable passed in as the options argument. We only take options as pointers rather than a value because some of the options structs are large and copying wouldn&apos;t be efficient.&lt;/p&gt;

&lt;p&gt;Variable scope within an if-statement, or any other scope-defining block, can be weird. If you use &quot;:=&quot;, you actually define a new variable which is only valid for that scope. This variable can have the same name as one from an outer scope, which can cause confusing issues. This is called shadowing. See&#160;&lt;a href=&quot;https://yourbasic.org/golang/gotcha-shadowing-variables/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://yourbasic.org/golang/gotcha-shadowing-variables/&lt;/a&gt;&#160;for an example.&lt;/p&gt;</comment>
                            <comment id="3103962" author="JIRAUSER1251601" created="Fri, 22 May 2020 04:12:01 +0000"  >&lt;p&gt;So are you saying that variadic is just an incorrect way of describing arguments as default values should work just fine or is that some problem elsewhere?&lt;/p&gt;

&lt;p&gt;More importantly are you just saying that the driver does not change the variable passed as the option argument and that Go still argues about pointers, variables and references in regards to the scope or access to change?&lt;/p&gt;

&lt;p&gt;Or are you just saying variable scope within an if statement is wierd? LOL&lt;/p&gt;



&lt;p&gt;Thank You,&lt;br/&gt;
Andrew Hodel&lt;/p&gt;
</comment>
                            <comment id="3103957" author="divjot.arora" created="Fri, 22 May 2020 04:04:09 +0000"  >&lt;p&gt;The language doesn&apos;t have default function parameter values, so if the UpdateOne function didn&apos;t take a variadic number of parameters, you&apos;d always have to specify &lt;tt&gt;nil&lt;/tt&gt; even if you didn&apos;t want to give any options.&lt;/p&gt;

&lt;p&gt;Going back to the original question in the description though, I don&apos;t think the discussion about variadics is relevant. Your original bug report was that you were constructing an UpdateOptions as&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;options.Update().SetUpsert(&lt;/span&gt;&lt;span style=&quot;color: #006699; font-weight: bold; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;true&lt;/span&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 passing that to a &lt;tt&gt;Collection.UpdateOne&lt;/tt&gt; call. After the call, the &lt;tt&gt;upsert&lt;/tt&gt; value was not set to true anymore (I&apos;m not sure if this means it was set to false or nil).&lt;/p&gt;

&lt;p&gt;You later said that the issue was no longer happening, indicating that it was probably something else. I also provided a code sample demonstrating that the &lt;tt&gt;UpdateOne&lt;/tt&gt; call does not change the options values you pass in. It constructs new ones, but does not change yours.&lt;/p&gt;

&lt;p&gt;Given all of this, I think we can close out this issue as &quot;works as designed&quot;. Do you agree?&lt;/p&gt;</comment>
                            <comment id="3103953" author="JIRAUSER1251601" created="Fri, 22 May 2020 03:57:01 +0000"  >&lt;p&gt;Can you explain how Go does not have default options and what that has to do with a function argument?&lt;/p&gt;

&lt;p&gt;My understanding if this was really an issue was that this driver, not Go had changed a variable. &lt;/p&gt;

&lt;p&gt;Are you trying to say that Go cannot change a variable unless it is passed a pointer?  That does not seem to be true with a variable . &lt;/p&gt;



&lt;p&gt;Thank You,&lt;br/&gt;
Andrew Hodel&lt;/p&gt;
</comment>
                            <comment id="3103945" author="divjot.arora" created="Fri, 22 May 2020 03:22:41 +0000"  >&lt;p&gt;&amp;gt;&#160;Why would we need to repeat options being changed by another call to the same function?&lt;/p&gt;

&lt;p&gt;You shouldn&apos;t need to do. The CRUD function calls do not change the options structs you pass into them. The code sample I linked in my previous comment shows that a call to &lt;tt&gt;UpdateOne&lt;/tt&gt; does not modify any of the values on the &lt;tt&gt;UpdateOptions&lt;/tt&gt; passed to it.&lt;/p&gt;

&lt;p&gt;&amp;gt;&#160;why would you need to merge update options when they are an argument to a function?&lt;/p&gt;

&lt;p&gt;You might&apos;ve noticed that the signatures for our CRUD functions are like&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;UpdateOne(filter &lt;/span&gt;&lt;span style=&quot;color: #006699; font-weight: bold; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;interface&lt;/span&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;{}, update &lt;/span&gt;&lt;span style=&quot;color: #006699; font-weight: bold; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;interface&lt;/span&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;{}, opts ...*options.UpdateOptions)&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&#160;&lt;tt&gt;opts&lt;/tt&gt; parameter is variadic. This was done because Go doesn&apos;t have default options and we didn&apos;t want to require users to pass in an explicit{{nil}} if they didn&apos;t want to specify options. The downside is that this API technically allows you to pass in more than one instance of UpdateOptions. To get around this, we wrote a{{MergeUpdateOptions}} functions that can take any number of UpdateOptions and combine them into a new instance. This is done by creating a new instance and then setting its fields based on the ones passed to the functions by the user.&lt;/p&gt;

&lt;p&gt;&amp;#8211; Divjot&lt;/p&gt;</comment>
                            <comment id="3103916" author="JIRAUSER1251601" created="Fri, 22 May 2020 02:27:01 +0000"  >&lt;p&gt;Why would we need to repeat options being changed by another call to the same function?&lt;/p&gt;

&lt;p&gt;Or better, why would you need to merge update options when they are an argument to a function?&lt;/p&gt;

&lt;p&gt;Are we going back through the argument of a function argument? If so how are we not trillionaires lol?&lt;/p&gt;



&lt;p&gt;Thank You,&lt;br/&gt;
Andrew Hodel&lt;/p&gt;
</comment>
                            <comment id="3103871" author="divjot.arora" created="Fri, 22 May 2020 01:18:43 +0000"  >&lt;p&gt;Hi &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=andrewhodel%40gmail.com&quot; class=&quot;user-hover&quot; rel=&quot;andrewhodel@gmail.com&quot;&gt;andrewhodel@gmail.com&lt;/a&gt;,&lt;/p&gt;

&lt;p&gt;I&apos;d closed as &quot;works as designed&quot; because of your comment that it seemed to be working. This is our usual way of closing tickets where there doesn&apos;t seem to be a bug.&lt;/p&gt;

&lt;p&gt;The flow for the UpdateOne/UpdateMany methods is that they call &lt;tt&gt;options.MergeUpdateOptions&lt;/tt&gt; (&lt;a href=&quot;https://github.com/mongodb/mongo-go-driver/blob/master/mongo/options/updateoptions.go#L75&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/mongodb/mongo-go-driver/blob/master/mongo/options/updateoptions.go#L75&lt;/a&gt;), which combines the variadic &lt;tt&gt;options.UpdateOptions&lt;/tt&gt; instances passed to the method into a single instance. As you can see, the MergeUpdateOptions method doesn&apos;t alter any of its arguments and instead creates a new UpdateOptions instances to represent the merged options.&lt;/p&gt;

&lt;p&gt;I&apos;ve also written up a small gist to verify the behavior at&#160;&lt;a href=&quot;https://github.com/mongodb/mongo-go-driver/blob/master/mongo/options/updateoptions.go#L75&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/mongodb/mongo-go-driver/blob/master/mongo/options/updateoptions.go#L75&lt;/a&gt;. After an UpdateOne/UpdateMany call, the &lt;tt&gt;Upsert&lt;/tt&gt; vale in the options struct remains &lt;tt&gt;true&lt;/tt&gt; in my test.&lt;/p&gt;

&lt;p&gt;If you have any other questions about the method flow, feel free to comment here and I can re-open the ticket if necessary.&lt;/p&gt;

&lt;p&gt;&amp;#8211; Divjot&lt;/p&gt;</comment>
                            <comment id="3103855" author="JIRAUSER1251601" created="Fri, 22 May 2020 01:06:01 +0000"  >&lt;p&gt;I don&#8217;t know about works as designed because you never commented on the flow and I never read the source code. &lt;/p&gt;



&lt;p&gt;Thank You,&lt;br/&gt;
Andrew Hodel&lt;/p&gt;
</comment>
                            <comment id="3102892" author="JIRAUSER1251601" created="Thu, 21 May 2020 18:03:02 +0000"  >&lt;p&gt;Sure&lt;/p&gt;

&lt;p&gt;On Thu, May 21, 2020 at 8:49 AM Divjot Arora (Jira) &amp;lt;jira@mongodb.org&amp;gt;&lt;/p&gt;
</comment>
                            <comment id="3102293" author="divjot.arora" created="Thu, 21 May 2020 14:49:05 +0000"  >&lt;p&gt;Hi &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=andrewhodel%40gmail.com&quot; class=&quot;user-hover&quot; rel=&quot;andrewhodel@gmail.com&quot;&gt;andrewhodel@gmail.com&lt;/a&gt;,&lt;/p&gt;

&lt;p&gt;Can this ticket be closed? If not, can you provide a minimal code sample that reliably reproduces the issue?&lt;/p&gt;

&lt;p&gt;&amp;#8211; Divjot&lt;/p&gt;</comment>
                            <comment id="3098272" author="JIRAUSER1251601" created="Wed, 20 May 2020 20:39:33 +0000"  >&lt;p&gt;Well, now that seems to be working.&#160; Must have been another issue somewhere.&lt;/p&gt;</comment>
                            <comment id="3098139" author="JIRAUSER1251601" created="Wed, 20 May 2020 19:42:54 +0000"  >&lt;p&gt;Bah, the reset is obviously without := and with = only.&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|hx9iin:</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>