[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:
Related
related to SERVER-14430 Shell in interactive mode does not wa... Backlog
Operating System: ALL
Steps To Reproduce:

Script body:
==============================================

db.t.remove();
db.t.save({user:{fn:"Bob",ln:"Marley"},grades:["A", "C", 5, 1.4, {gr:"good"}],type:4});
db.t.save({user:{fn:"Chuck",ln:"Norris"},grades:["F", "F", 3.5, 4, {gr:[1,2,3]}], type:6.3});
db.t.save({user:{ln:"Washington"},grades:[{gr:[1,2,3]}]});
db.t.save({user:{fn:"Hello",ln:"World"}});
db.t.save({age:25, type:"offline"});
db.t.save({age:26, type:"online"});
db.t.save({age:27});
db.t.save({age:28, type:"single"});
db.t.save({age:40, type:"married"});
 
var qs = [{type:{$gt:4}}]
 
var i = 0;
for (i = 0; i < qs.length; i++)
{
  print("\nQuery: "+JSON.stringify(qs[i]));
  db.t.find(qs[i], {_id:0});
}

==============================================

When executing this script I get the following result:

C:\Downloads\mongodb\bin>mongo -quiet test < test.js
Fri Mar 28 10:53:22.512 SyntaxError: Unexpected end of input
Fri Mar 28 10:53:22.514 ReferenceError: i is not defined

If I change the for loop like this:

var i = 0;
for (i = 0; i < qs.length; i++)

I get:

C:\Downloads\mongodb\bin>mongo -quiet test < test.js
Fri Mar 28 10:54:53.021 SyntaxError: Unexpected end of input

Query: {"type":{"$gt":4}}
{ "user" : { "fn" : "Chuck", "ln" : "Norris" }, "grades" : [  "F",  "F",  3.5,  4,  {  "gr" : [  1,  2,  3 ] } ], "type"
 : 6.3 }

So with this modification I get a valid result, but still see some strange SyntaxError.

C:\Downloads\mongodb\bin>mongo -version
MongoDB shell version: 2.4.9

Participants:

 Description   

This bug is actually submitted for 2 issues:
1) unrecognized variable declaration within the loop and
2) irrelevant SyntaxError.



 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

I see that all of them are being printed out, but only the last one is executed.

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

printjson(db.t.find(qs\[i\], {_id:0}).toArray());

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,
Thomas

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:
================================
db.t.remove();
db.t.save({user:

{fn:"Bob",ln:"Marley"}

,grades:["A", "C", 5, 1.4,

{gr:"good"}

],type:4});
db.t.save({user:

{fn:"Chuck",ln:"Norris"}

,grades:["F", "F", 3.5, 4,

{gr:[1,2,3]}

], type:6.3});

var qs =
[
{$query:{type:4}},
{$query:{user:

{fn:"Bob",ln:"Marley"}

}}
];

for (i = 0; i < qs.length; i++) {
print("\nQuery: "+JSON.stringify(qs[i]));
db.t.find(qs[i], {_id:0});
}
================================

RESULT:
================================
MongoDB shell version: 2.4.9
connecting to: test

Query: {"$query":{"type":4}}

Query: {"$query":{"user":

{"fn":"Bob","ln":"Marley"}

}}
{ "user" :

{ "fn" : "Bob", "ln" : "Marley" }

, "grades" : [ "A", "C", 5, 1.4,

{ "gr" : "good" }

], "type" : 4 }
bye
================================

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:

for (i = 0; i < qs.length; i++) {
    print("\nQuery: "+JSON.stringify(qs[i]));
    db.t.find(qs[i], {_id:0});
}

Generated at Thu Feb 08 03:31:36 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.