[SERVER-13401] Javascript (2 issues): loop variable evaluation error Created: 28/Mar/14 Updated: 10/Dec/14 Resolved: 02/Jul/14 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Shell |
| Affects Version/s: | 2.4.9 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Minor - P4 |
| Reporter: | Raf Oid | Assignee: | Ramon Fernandez Marina |
| Resolution: | Done | Votes: | 0 |
| Labels: | javascript | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
|||||||||||||||||||||||||||||||
| Operating System: | ALL | |||||||||||||||||||||||||||||||
| Steps To Reproduce: | Script body:
============================================== When executing this script I get the following result:
If I change the for loop like this:
I get:
So with this modification I get a valid result, but still see some strange SyntaxError.
|
|||||||||||||||||||||||||||||||
| Participants: | ||||||||||||||||||||||||||||||||
| Description |
|
This bug is actually submitted for 2 issues: |
| Comments |
| Comment by Thomas Rueckstiess [ 02/Jul/14 ] | ||||
|
Hi Raf, The issue here is that you are using the interactive mode with the syntax mongo < test.js, rather then script mode, with mongo test.js (notice the missing <). In interactive mode, code blocks are passed to v8 one-at-a-time, and evaluation will continue even if a statement generates an error (the same way that the mongo shell continues to accept statements if you submit one that generates an error). In script mode, the whole script is passed to v8 at once, and the shell will stop the script at the first error. The "SyntaxError: Unexpected end of input" error exhibits an actual bug in interactive mode with the shell. The shell thinks that "for (...)" is a complete statement, so it passes that line of input to v8, which spits out an error since the for loop has no body. If instead, as you demonstrate, if you write "for (...) {", the shell realizes that it is expecting multiple lines of input, and waits for the brace to be completed before passing it to v8. The correct workaround here, however, is to use script mode, which avoids this issue entirely (since the whole file is passed to v8 at once). As for your comment
find() returns a cursor object, but creating a cursor object alone doesn't actually make the query be sent to the server, you need to call .next() on it or otherwise iterate through the result set in order for the query to be sent over the wire. There's an exception though: in interactive mode, evaluating a cursor object causes the first batch of results to be requested, and the first 10 to be returned and displayed. This is why "db.foo.find()" in interactive mode results in a query being sent, but "db.foo.find()" in script mode doesn't. The "last" one is the only query being executed, since in javascript a for() loop evaluates the last statement in the last iteration of the loop. You should probably switch to script mode (see above), and then change line 18 to something like
If you have further questions about the mongo shell, please feel free to post them on the mongodb-users group (http://groups.google.com/group/mongodb-user) or Stack Overflow with the mongodb tag. Thanks, | ||||
| Comment by Raf Oid [ 05/Jun/14 ] | ||||
|
The proposed workaround worked for the FOR loop, but gives me again unexpected result. With the modified repro steps below, the first query is printed out in the FOR loop, but is not executed. The more queries I add into "qs" array, I see that all of them are being printed out, but only the last one is executed. It seems to be like a major problem! REPRO: ,grades:["A", "C", 5, 1.4, {gr:"good"}],type:4}); ,grades:["F", "F", 3.5, 4, {gr:[1,2,3]}], type:6.3}); var qs = }} for (i = 0; i < qs.length; i++) { RESULT: Query: {"$query":{"type":4}} Query: {"$query":{"user": {"fn":"Bob","ln":"Marley"}}} , "grades" : [ "A", "C", 5, 1.4, { "gr" : "good" } ], "type" : 4 } | ||||
| Comment by Ramon Fernandez Marina [ 28/May/14 ] | ||||
|
rafoid thanks for your report, I can reproduce the behavior you describe. The easiest workaround is to move the opening of the for block to the same line as the for:
|