diff options
author | David Percy <david.percy@mongodb.com> | 2022-11-15 16:40:41 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2023-05-17 19:49:10 +0000 |
commit | d34931161eb5ec47029f8c69d731ed9360f51b9a (patch) | |
tree | c41bdce23d1166010f9f923dfce1b3cc975e7bea | |
parent | ac697ae13dcb5567e34fe5a98bfa3ea2fdedb175 (diff) | |
download | mongo-v5.0.tar.gz |
SERVER-71387 Add missing typecheck for range-based windowv5.0
-rw-r--r-- | jstests/aggregation/sources/setWindowFields/range_wrong_type.js | 36 | ||||
-rw-r--r-- | src/mongo/db/pipeline/window_function/partition_iterator.cpp | 9 |
2 files changed, 43 insertions, 2 deletions
diff --git a/jstests/aggregation/sources/setWindowFields/range_wrong_type.js b/jstests/aggregation/sources/setWindowFields/range_wrong_type.js new file mode 100644 index 00000000000..26001c40888 --- /dev/null +++ b/jstests/aggregation/sources/setWindowFields/range_wrong_type.js @@ -0,0 +1,36 @@ +/** + * Test that a window of the form [+N, unbounded] does not trigger a tassert + * on mixed-type input. + * + * Originally intended to reproduce SERVER-71387. + */ +(function() { +"use strict"; + +const coll = db.set_window_fields_range_wrong_type; +coll.drop(); +assert.commandWorked(coll.insert([ + // Numbers sort before strings, so we'll scan {a: 2} first. + {a: 2}, + {a: 'xyz'}, +])); + +const err = assert.throws(() => { + return coll + .aggregate({ + $setWindowFields: { + sortBy: {a: 1}, + output: { + // The lower bound +3 excludes the current document {a: 2}. + // The only remaining document is {a: 'xyz'}. + // We wrongly consider {a: 'xyz'} to be 'within' the lower bound. + // Then, when we search for the upper bound, we are surprised + // to be starting from 'xyz' which is the wrong type. + b: {$max: 5, window: {range: [+3, 'unbounded']}}, + }, + } + }) + .toArray(); +}); +assert.eq(err.code, 5429414, err); +})(); diff --git a/src/mongo/db/pipeline/window_function/partition_iterator.cpp b/src/mongo/db/pipeline/window_function/partition_iterator.cpp index 95a0935d86c..7ec49c6132f 100644 --- a/src/mongo/db/pipeline/window_function/partition_iterator.cpp +++ b/src/mongo/db/pipeline/window_function/partition_iterator.cpp @@ -302,8 +302,13 @@ optional<std::pair<int, int>> PartitionIterator::getEndpointsRangeBased( for (int i = start; (doc = (*this)[i]); ++i) { Value v = (*_sortExpr)->evaluate(*doc, &_expCtx->variables); if (!lessThan(v, threshold)) { - // This is the first doc we've scanned that crossed the threshold. - return i; + // This is the first doc we've scanned that crossed the threshold, + // so it's the first doc in the window (as long as it's the expected type). + if (hasExpectedType(v)) { + return i; + } else { + return boost::none; + } } } // We scanned every document in the partition, and none crossed the |