diff options
author | Davis Haupt <davis.haupt@mongodb.com> | 2022-04-21 17:28:25 +0000 |
---|---|---|
committer | Davis Haupt <davis.haupt@mongodb.com> | 2022-06-21 20:52:32 +0000 |
commit | 816918e7ebb03cd74fdfb935590d14fc9e8d0210 (patch) | |
tree | ffb03f14c0167cdb2a513da2c1a688dfef5999a7 | |
parent | c6430dd53bed6f12017da8ff7531c5b5ec12cc26 (diff) | |
download | mongo-816918e7ebb03cd74fdfb935590d14fc9e8d0210.tar.gz |
SERVER-65864 Parse $densify step as a NumberLong when using a date unit
(cherry picked from commit 8be84724601090e093d6d7ccfa4536a187c41edc)
-rw-r--r-- | jstests/aggregation/sources/densify/libs/parse_util.js | 14 | ||||
-rw-r--r-- | src/mongo/db/pipeline/document_source_densify.cpp | 14 | ||||
-rw-r--r-- | src/mongo/db/pipeline/document_source_densify_test.cpp | 2 |
3 files changed, 24 insertions, 6 deletions
diff --git a/jstests/aggregation/sources/densify/libs/parse_util.js b/jstests/aggregation/sources/densify/libs/parse_util.js index 7ccedefd81d..d2e6ba4e489 100644 --- a/jstests/aggregation/sources/densify/libs/parse_util.js +++ b/jstests/aggregation/sources/densify/libs/parse_util.js @@ -139,6 +139,20 @@ let parseUtil = (function(db, coll, stageName, options = {}) { }), 5733402, "a bounding array must be an ascending array of either two dates or two numbers"); + // Non-whole number step with date bounds + assert.commandFailedWithCode( + run({ + [stageName]: { + field: "a", + range: { + step: 1.1, + bounds: [new ISODate("2020-01-01"), new ISODate("2020-01-03")], + unit: "second" + } + } + }), + 6586400, + "The step parameter in a range satement must be a whole number when densifying a date range"); // Positive test cases assert.commandWorked(run({[stageName]: {field: "a", range: {step: 1.0, bounds: [1, 2]}}})); diff --git a/src/mongo/db/pipeline/document_source_densify.cpp b/src/mongo/db/pipeline/document_source_densify.cpp index 0325dbaa775..740ef193431 100644 --- a/src/mongo/db/pipeline/document_source_densify.cpp +++ b/src/mongo/db/pipeline/document_source_densify.cpp @@ -56,6 +56,10 @@ RangeStatement RangeStatement::parse(RangeSpec spec) { optional<TimeUnit> unit = [&]() { if (auto unit = spec.getUnit()) { + uassert(6586400, + "The step parameter in a range statement must be a whole number when " + "densifying a date range", + step.integral64Bit()); return optional<TimeUnit>(parseTimeUnit(unit.get())); } else { return optional<TimeUnit>(boost::none); @@ -275,8 +279,8 @@ DocumentSourceInternalDensify::DocGenerator::DocGenerator(DensifyValue min, // Extra checks for date step + unit. tassert(5733501, "Unit must be specified with a date step", _range.getUnit()); tassert(5733505, - "Step must be representable as an integer for date densification", - _range.getStep().integral()); + "Step must be a whole number for date densification", + _range.getStep().integral64Bit()); } else { tassert(5733506, "Unit must not be specified with non-date values", !_range.getUnit()); } @@ -877,7 +881,7 @@ DensifyValue DensifyValue::increment(const RangeStatement& range) const { }, [&](Date_t date) { return DensifyValue(dateAdd( - date, range.getUnit().value(), range.getStep().getDouble(), timezone())); + date, range.getUnit().value(), range.getStep().coerceToLong(), timezone())); }}, _value); } @@ -891,7 +895,7 @@ DensifyValue DensifyValue::decrement(const RangeStatement& range) const { }, [&](Date_t date) { return DensifyValue(dateAdd( - date, range.getUnit().value(), -range.getStep().getDouble(), timezone())); + date, range.getUnit().value(), -range.getStep().coerceToLong(), timezone())); }}, _value); } @@ -906,7 +910,7 @@ bool DensifyValue::isOnStepRelativeTo(DensifyValue base, RangeStatement range) c }, [&](Date_t date) { auto unit = range.getUnit().value(); - double step = range.getStep().getDouble(); + long long step = range.getStep().coerceToLong(); auto baseDate = base.getDate(); // Months, quarters and years have variable lengths depending on leap days diff --git a/src/mongo/db/pipeline/document_source_densify_test.cpp b/src/mongo/db/pipeline/document_source_densify_test.cpp index 79b16303eb9..c1a0218e9eb 100644 --- a/src/mongo/db/pipeline/document_source_densify_test.cpp +++ b/src/mongo/db/pipeline/document_source_densify_test.cpp @@ -374,7 +374,7 @@ DEATH_TEST(DensifyGeneratorTest, DateMinMustBeLessThanMax, "lower or equal to") 5733502); } -DEATH_TEST(DensifyGeneratorTest, DateStepMustBeInt, "integer") { +DEATH_TEST(DensifyGeneratorTest, DateStepMustBeInt, "whole number") { size_t counter = 0; ASSERT_THROWS_CODE(GenClass(makeDate("2021-01-01T00:00:00.000Z"), RangeStatement(Value(1.5), |