Fixes #126 -- minimingo fails on dotted queries if undefined is seen

This commit is contained in:
Avital Oliver
2012-08-20 15:07:32 -07:00
parent d17ddc93ac
commit c499f7c9da
2 changed files with 13 additions and 3 deletions

View File

@@ -532,6 +532,14 @@ Tinytest.add("minimongo - selector_compiler", function (test) {
match({"a.b": /a/}, {a: {b: "cat"}});
nomatch({"a.b": /a/}, {a: {b: "dog"}});
// trying to access a dotted field that is undefined at some point
// down the chain
nomatch({"a.b": 1}, {x: 2});
nomatch({"a.b.c": 1}, {a: {x: 2}});
nomatch({"a.b.c": 1}, {a: {b: {x: 2}}});
nomatch({"a.b.c": 1}, {a: {b: 1}});
nomatch({"a.b.c": 1}, {a: {b: 0}});
// dotted keypaths: literal objects
match({"a.b": {c: 1}}, {a: {b: {c: 1}}});
nomatch({"a.b": {c: 1}}, {a: {b: {c: 2}}});

View File

@@ -384,20 +384,22 @@ LocalCollection._exprForKeypathPredicate = function (keypath, value, literals) {
}
// now, deal with the orthogonal concern of dotted.key.paths and the
// (potentially multi-level) array searching they require
// (potentially multi-level) array searching they require.
// while at it, make sure to not throw an exception if we hit undefined while
// drilling down through the dotted parts
var ret = '';
var innermost = true;
while (keyparts.length) {
var part = keyparts.pop();
var formal = keyparts.length ? "x" : "doc";
if (innermost) {
ret = '(function(x){return ' + predcode + ';})(' + formal + '[' +
ret = '(function(x){return ' + predcode + ';})(' + formal + '&&' + formal + '[' +
JSON.stringify(part) + '])';
innermost = false;
} else {
// for all but the innermost level of a dotted expression,
// if the runtime type is an array, search it
ret = 'f._matches(' + formal + '[' + JSON.stringify(part) +
ret = 'f._matches(' + formal + '&&' + formal + '[' + JSON.stringify(part) +
'], function(x){return ' + ret + ';})';
}
}