summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavis Haupt <davis.haupt@mongodb.com>2022-04-21 17:28:25 +0000
committerDavis Haupt <davis.haupt@mongodb.com>2022-06-21 20:52:32 +0000
commit816918e7ebb03cd74fdfb935590d14fc9e8d0210 (patch)
treeffb03f14c0167cdb2a513da2c1a688dfef5999a7
parentc6430dd53bed6f12017da8ff7531c5b5ec12cc26 (diff)
downloadmongo-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.js14
-rw-r--r--src/mongo/db/pipeline/document_source_densify.cpp14
-rw-r--r--src/mongo/db/pipeline/document_source_densify_test.cpp2
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),