summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/aggregation/expressions/date_from_string.js236
-rw-r--r--src/mongo/db/pipeline/expression.cpp73
-rw-r--r--src/mongo/db/pipeline/expression.h19
-rw-r--r--src/mongo/db/pipeline/expression_test.cpp39
-rw-r--r--src/mongo/db/query/datetime/date_time_support.cpp46
-rw-r--r--src/mongo/db/query/datetime/date_time_support.h5
6 files changed, 0 insertions, 418 deletions
diff --git a/jstests/aggregation/expressions/date_from_string.js b/jstests/aggregation/expressions/date_from_string.js
deleted file mode 100644
index a6fc7b9b09b..00000000000
--- a/jstests/aggregation/expressions/date_from_string.js
+++ /dev/null
@@ -1,236 +0,0 @@
-load("jstests/aggregation/extras/utils.js"); // For assertErrorCode
-
-(function() {
- "use strict";
-
- const coll = db.date_from_string;
-
- /* --------------------------------------------------------------------------------------- */
- /* Normal format tests. */
-
- coll.drop();
- assert.writeOK(coll.insert({_id: 0}));
-
- let testCases = [
- {expect: "2017-07-04T11:56:02Z", inputString: "2017-07-04T11:56:02Z"},
- {expect: "2017-07-04T11:56:02.813Z", inputString: "2017-07-04T11:56:02.813Z"},
- {expect: "2017-07-04T11:56:02.810Z", inputString: "2017-07-04T11:56:02.81Z"},
- {expect: "2017-07-04T11:56:02.800Z", inputString: "2017-07-04T11:56:02.8Z"},
- {expect: "2017-07-04T11:56:02Z", inputString: "2017-07-04T11:56.02"},
- {expect: "2017-07-04T11:56:02.813Z", inputString: "2017-07-04T11:56.02.813"},
- {expect: "2017-07-04T11:56:02.810Z", inputString: "2017-07-04T11:56.02.81"},
- {expect: "2017-07-04T11:56:02.800Z", inputString: "2017-07-04T11:56.02.8"},
- ];
- testCases.forEach(function(testCase) {
- assert.eq(
- [{_id: 0, date: ISODate(testCase.expect)}],
- coll.aggregate(
- {$project: {date: {'$dateFromString': {"dateString": testCase.inputString}}}})
- .toArray(),
- tojson(testCase));
- });
-
- /* --------------------------------------------------------------------------------------- */
- /* Normal format tests from data. */
-
- coll.drop();
- assert.writeOK(coll.insert([
- {_id: 0, dateString: "2017-07-06T12:35:37Z"},
- {_id: 1, dateString: "2017-07-06T12:35:37.513Z"},
- {_id: 2, dateString: "2017-07-06T12:35:37"},
- {_id: 3, dateString: "2017-07-06T12:35:37.513"},
- {_id: 4, dateString: "1960-07-10T12:10:37.448"},
- ]));
-
- assert.eq(
- [
- {"_id": 0, "date": ISODate("2017-07-06T12:35:37Z")},
- {"_id": 1, "date": ISODate("2017-07-06T12:35:37.513Z")},
- {"_id": 2, "date": ISODate("2017-07-06T12:35:37Z")},
- {"_id": 3, "date": ISODate("2017-07-06T12:35:37.513Z")},
- {"_id": 4, "date": ISODate("1960-07-10T12:10:37.448Z")},
- ],
- coll.aggregate([
- {
- $project: {date: {'$dateFromString': {dateString: "$dateString"}}},
- },
- {$sort: {_id: 1}}
- ])
- .toArray());
-
- assert.eq(
- [
- {"_id": 0, "date": new Date(1499344537000)},
- {"_id": 1, "date": new Date(1499344537513)},
- {"_id": 2, "date": new Date(1499344537000)},
- {"_id": 3, "date": new Date(1499344537513)},
- {"_id": 4, "date": new Date(-299072962552)},
- ],
- coll.aggregate([
- {
- $project: {date: {'$dateFromString': {dateString: "$dateString"}}},
- },
- {$sort: {_id: 1}}
- ])
- .toArray());
-
- /* --------------------------------------------------------------------------------------- */
- /* BI format tests. */
-
- coll.drop();
- assert.writeOK(coll.insert({_id: 0}));
-
- let pipelines = [
- {
- expect: "2017-01-01T00:00:00Z",
- pipeline: {$project: {date: {'$dateFromString': {"dateString": "2017-01-01 00:00:00"}}}}
- },
- {
- expect: "2017-07-01T00:00:00Z",
- pipeline: {$project: {date: {'$dateFromString': {"dateString": "2017-07-01 00:00:00"}}}}
- },
- {
- expect: "2017-07-06T00:00:00Z",
- pipeline: {$project: {date: {'$dateFromString': {"dateString": "2017-07-06"}}}}
- },
- {
- expect: "2017-07-06T00:00:00Z",
- pipeline: {$project: {date: {'$dateFromString': {"dateString": "2017-07-06 00:00:00"}}}}
- },
- {
- expect: "2017-07-06T11:00:00Z",
- pipeline: {$project: {date: {'$dateFromString': {"dateString": "2017-07-06 11:00:00"}}}}
- },
- {
- expect: "2017-07-06T11:36:00Z",
- pipeline: {$project: {date: {'$dateFromString': {"dateString": "2017-07-06 11:36:00"}}}}
- },
- {
- expect: "2017-07-06T11:36:54Z",
- pipeline: {$project: {date: {'$dateFromString': {"dateString": "2017-07-06 11:36:54"}}}}
- },
- ];
- pipelines.forEach(function(pipeline) {
- assert.eq([{_id: 0, date: ISODate(pipeline.expect)}],
- coll.aggregate(pipeline.pipeline).toArray(),
- tojson(pipeline));
- });
-
- /* --------------------------------------------------------------------------------------- */
- /* BI format tests from data. */
-
- coll.drop();
- assert.writeOK(coll.insert([
- {_id: 0, dateString: "2017-01-01 00:00:00"},
- {_id: 1, dateString: "2017-07-01 00:00:00"},
- {_id: 2, dateString: "2017-07-06"},
- {_id: 3, dateString: "2017-07-06 00:00:00"},
- {_id: 4, dateString: "2017-07-06 11:00:00"},
- {_id: 5, dateString: "2017-07-06 11:36:00"},
- {_id: 6, dateString: "2017-07-06 11:36:54"},
- ]));
-
- assert.eq(
- [
- {"_id": 0, "date": ISODate("2017-01-01T00:00:00Z")},
- {"_id": 1, "date": ISODate("2017-07-01T00:00:00Z")},
- {"_id": 2, "date": ISODate("2017-07-06T00:00:00Z")},
- {"_id": 3, "date": ISODate("2017-07-06T00:00:00Z")},
- {"_id": 4, "date": ISODate("2017-07-06T11:00:00Z")},
- {"_id": 5, "date": ISODate("2017-07-06T11:36:00Z")},
- {"_id": 6, "date": ISODate("2017-07-06T11:36:54Z")}
- ],
- coll.aggregate([
- {
- $project: {date: {'$dateFromString': {dateString: "$dateString"}}},
- },
- {$sort: {_id: 1}}
- ])
- .toArray());
-
- /* --------------------------------------------------------------------------------------- */
- /* Wacky format tests from data. */
-
- coll.drop();
- assert.writeOK(coll.insert([
- {_id: 0, dateString: "July 4th, 2017"},
- {_id: 1, dateString: "July 4th, 2017 12:39:30 BST"},
- {_id: 2, dateString: "July 4th, 2017 11am"},
- {_id: 3, dateString: "July 4th, 2017 12pm"},
- {_id: 4, dateString: "7/4/17"},
- {_id: 5, dateString: "04-07-2017"},
- {_id: 6, dateString: "2017-Jul-04 noon"},
- {_id: 7, dateString: "2017-07-04 12:48:07 GMT+0545"},
- {_id: 8, dateString: "2017-07-04 12:48:07 GMT-0200"},
- ]));
-
- assert.eq(
- [
- {"_id": 0, "date": ISODate("2017-07-04T00:00:00Z")},
- {"_id": 1, "date": ISODate("2017-07-04T11:39:30Z")},
- {"_id": 2, "date": ISODate("2017-07-04T11:00:00Z")},
- {"_id": 3, "date": ISODate("2017-07-04T12:00:00Z")},
- {"_id": 4, "date": ISODate("2017-07-04T00:00:00Z")},
- {"_id": 5, "date": ISODate("2017-07-04T00:00:00Z")},
- {"_id": 6, "date": ISODate("2017-07-04T12:00:00Z")},
- {"_id": 7, "date": ISODate("2017-07-04T07:03:07Z")},
- {"_id": 8, "date": ISODate("2017-07-04T14:48:07Z")},
- ],
- coll.aggregate([
- {
- $project: {date: {'$dateFromString': {dateString: "$dateString"}}},
- },
- {$sort: {_id: 1}}
- ])
- .toArray());
-
- /* --------------------------------------------------------------------------------------- */
- /* Testing whether it throws the right assert for missing elements of a date/time string. */
-
- coll.drop();
-
- assert.writeOK(coll.insert([
- {_id: 0},
- ]));
-
- pipelines = [
- [{'$project': {date: {'$dateFromString': {dateString: "July 4th"}}}}],
- [{'$project': {date: {'$dateFromString': {dateString: "2017, 12:50:53"}}}}],
- ];
-
- pipelines.forEach(function(pipeline) {
- assertErrorCode(coll, pipeline, 40545, tojson(pipeline));
- });
-
- /* --------------------------------------------------------------------------------------- */
- /* NULL returns. */
-
- coll.drop();
- assert.writeOK(coll.insert([
- {_id: 0, date: new ISODate("2017-06-19T15:13:25.713Z")},
- {_id: 1, date: new ISODate("2017-06-19T15:13:25.713Z"), tz: null},
- {_id: 2, date: new ISODate("2017-06-19T15:13:25.713Z"), tz: undefined},
- ]));
-
- pipelines = [
- [{$project: {date: {'$dateFromString': {"dateString": "$tz"}}}}, {$sort: {_id: 1}}],
- ];
- pipelines.forEach(function(pipeline) {
- assert.eq([{_id: 0, date: null}, {_id: 1, date: null}, {_id: 2, date: null}],
- coll.aggregate(pipeline).toArray(),
- tojson(pipeline));
- });
-
- /* --------------------------------------------------------------------------------------- */
- /* Parse errors. */
-
- let pipeline = {$project: {date: {'$dateFromString': "no-object"}}};
- assertErrorCode(coll, pipeline, 40540);
-
- pipeline = {$project: {date: {'$dateFromString': {"unknown": "$tz"}}}};
- assertErrorCode(coll, pipeline, 40541);
-
- pipeline = {$project: {date: {'$dateFromString': {"dateString": 5}}}};
- assertErrorCode(coll, pipeline, 40543);
-
-})();
diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp
index 8b3b15143b8..798d05ca285 100644
--- a/src/mongo/db/pipeline/expression.cpp
+++ b/src/mongo/db/pipeline/expression.cpp
@@ -1314,79 +1314,6 @@ void ExpressionDateFromParts::addDependencies(DepsTracker* deps) const {
}
}
-/* ---------------------- ExpressionDateFromString --------------------- */
-
-REGISTER_EXPRESSION(dateFromString, ExpressionDateFromString::parse);
-intrusive_ptr<Expression> ExpressionDateFromString::parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps) {
-
- uassert(40540,
- str::stream() << "$dateFromString only supports an object as an argument, found: "
- << typeName(expr.type()),
- expr.type() == BSONType::Object);
-
- BSONElement dateStringElem;
- const BSONObj args = expr.embeddedObject();
- for (auto&& arg : args) {
- if (arg.fieldNameStringData() == "dateString"_sd) {
- dateStringElem = arg;
- } else {
- uasserted(40541,
- str::stream() << "Unrecognized argument to $dateFromString: "
- << arg.fieldName());
- }
- }
-
- uassert(40542, "Missing 'dateString' parameter to $dateFromString", dateStringElem);
-
- return new ExpressionDateFromString(expCtx, parseOperand(expCtx, dateStringElem, vps));
-}
-
-ExpressionDateFromString::ExpressionDateFromString(
- const boost::intrusive_ptr<ExpressionContext>& expCtx, intrusive_ptr<Expression> dateString)
- : Expression(expCtx), _dateString(dateString) {}
-
-intrusive_ptr<Expression> ExpressionDateFromString::optimize() {
- _dateString = _dateString->optimize();
-
- if (dynamic_cast<ExpressionConstant*>(_dateString.get())) {
- // Everything is a constant, so we can turn into a constant.
- return ExpressionConstant::create(getExpressionContext(), evaluate(Document{}));
- }
- return this;
-}
-
-Value ExpressionDateFromString::serialize(bool explain) const {
- return Value(
- Document{{"$dateFromString", Document{{"dateString", _dateString->serialize(explain)}}}});
-}
-
-Value ExpressionDateFromString::evaluate(const Document& root) const {
- const Value dateString = _dateString->evaluate(root);
-
- if (dateString.nullish()) {
- return Value(BSONNULL);
- }
-
- uassert(40543,
- str::stream() << "$dateFromString requires that 'dateString' be a string, found: "
- << typeName(dateString.getType())
- << " with value "
- << dateString.toString(),
- dateString.getType() == BSONType::String);
- const std::string& dateTimeString = dateString.getString();
-
- auto tzdb = TimeZoneDatabase::get(getExpressionContext()->opCtx->getServiceContext());
-
- return Value(tzdb->fromString(dateTimeString));
-}
-
-void ExpressionDateFromString::addDependencies(DepsTracker* deps) const {
- _dateString->addDependencies(deps);
-}
-
/* ---------------------- ExpressionDateToParts ----------------------- */
REGISTER_EXPRESSION(dateToParts, ExpressionDateToParts::parse);
diff --git a/src/mongo/db/pipeline/expression.h b/src/mongo/db/pipeline/expression.h
index c7889305aa0..aad2ced9b55 100644
--- a/src/mongo/db/pipeline/expression.h
+++ b/src/mongo/db/pipeline/expression.h
@@ -828,25 +828,6 @@ private:
typedef ExpressionFixedArity<ExpressionCond, 3> Base;
};
-class ExpressionDateFromString final : public Expression {
-public:
- boost::intrusive_ptr<Expression> optimize() final;
- Value serialize(bool explain) const final;
- Value evaluate(const Document&) const final;
- void addDependencies(DepsTracker*) const final;
-
- static boost::intrusive_ptr<Expression> parse(
- const boost::intrusive_ptr<ExpressionContext>& expCtx,
- BSONElement expr,
- const VariablesParseState& vps);
-
-private:
- ExpressionDateFromString(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- boost::intrusive_ptr<Expression> dateString);
-
- boost::intrusive_ptr<Expression> _dateString;
-};
-
class ExpressionDateFromParts final : public Expression {
public:
boost::intrusive_ptr<Expression> optimize() final;
diff --git a/src/mongo/db/pipeline/expression_test.cpp b/src/mongo/db/pipeline/expression_test.cpp
index 3ae780066e0..f89735aff56 100644
--- a/src/mongo/db/pipeline/expression_test.cpp
+++ b/src/mongo/db/pipeline/expression_test.cpp
@@ -4884,45 +4884,6 @@ TEST_F(DateExpressionTest, DoesResultInNullIfGivenNullishInput) {
} // namespace DateExpressionsTest
-namespace ExpressionDateFromStringTest {
-
-// This provides access to an ExpressionContext that has a valid ServiceContext with a
-// TimeZoneDatabase via getExpCtx(), but we'll use a different name for this test suite.
-using ExpressionDateFromStringTest = AggregationContextFixture;
-
-TEST_F(ExpressionDateFromStringTest, SerializesToObjectSyntax) {
- auto expCtx = getExpCtx();
-
- // Test that it serializes to the full format if given an object specification.
- BSONObj spec = BSON("$dateFromString" << BSON("dateString"
- << "2017-07-04T13:06:44Z"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- auto expectedSerialization = Value(
- Document{{"$dateFromString",
- Document{{"dateString", Document{{"$const", "2017-07-04T13:06:44Z"_sd}}}}}});
- ASSERT_VALUE_EQ(dateExp->serialize(true), expectedSerialization);
- ASSERT_VALUE_EQ(dateExp->serialize(false), expectedSerialization);
-}
-
-TEST_F(ExpressionDateFromStringTest, OptimizesToConstantIfAllInputsAreConstant) {
- auto expCtx = getExpCtx();
- auto spec = BSON("$dateFromString" << BSON("dateString"
- << "2017-07-04T13:09:57Z"));
- auto dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
-
- Date_t dateVal = Date_t::fromMillisSinceEpoch(1499173797000);
- ASSERT_VALUE_EQ(Value(dateVal), dateExp->evaluate(Document{}));
-
- // Test that it does *not* become a constant if dateString is not a constant.
- spec = BSON("$dateFromString" << BSON("dateString"
- << "$date"));
- dateExp = Expression::parseExpression(expCtx, spec, expCtx->variablesParseState);
- ASSERT_FALSE(dynamic_cast<ExpressionConstant*>(dateExp->optimize().get()));
-}
-
-} // namespace ExpressionDateFromStringTest
-
class All : public Suite {
public:
All() : Suite("expression") {}
diff --git a/src/mongo/db/query/datetime/date_time_support.cpp b/src/mongo/db/query/datetime/date_time_support.cpp
index 88ba04d5549..1356356665d 100644
--- a/src/mongo/db/query/datetime/date_time_support.cpp
+++ b/src/mongo/db/query/datetime/date_time_support.cpp
@@ -122,52 +122,6 @@ TimeZone TimeZoneDatabase::utcZone() {
return TimeZone{nullptr};
}
-extern "C" {
-static timelib_tzinfo* timezonedatabase_gettzinfowrapper(char* tz_id,
- const _timelib_tzdb* db,
- int* error) {
- uasserted(
- 40544,
- str::stream()
- << "passing a time zone identifier as part of the string is not allowed, found: \""
- << tz_id
- << "\"");
-
- return nullptr;
-}
-
-} // extern "C"
-
-Date_t TimeZoneDatabase::fromString(StringData dateString) const {
- std::unique_ptr<timelib_time, TimeZone::TimelibTimeDeleter> t(
- timelib_strtotime(const_cast<char*>(dateString.toString().c_str()),
- dateString.size(),
- nullptr,
- _timeZoneDatabase.get(),
- timezonedatabase_gettzinfowrapper));
-
- // If the time portion is fully missing, initialize to 0. This allows for the '%Y-%m-%d' format
- // to be passed too, which is what the BI connector may request
- if (t->h == TIMELIB_UNSET && t->i == TIMELIB_UNSET && t->s == TIMELIB_UNSET) {
- t->h = t->i = t->s = t->f = 0;
- }
-
- if (t->y == TIMELIB_UNSET || t->m == TIMELIB_UNSET || t->d == TIMELIB_UNSET ||
- t->h == TIMELIB_UNSET || t->i == TIMELIB_UNSET || t->s == TIMELIB_UNSET) {
- uasserted(40545,
- str::stream()
- << "an incomplete date/time string has been found, with elements missing: \""
- << dateString
- << "\"");
- }
-
- timelib_update_ts(t.get(), nullptr);
- timelib_unixtime2local(t.get(), t->sse);
-
- return Date_t::fromMillisSinceEpoch((static_cast<double>(t->sse) + static_cast<double>(t->f)) *
- 1000);
-}
-
TimeZone TimeZoneDatabase::getTimeZone(StringData timeZoneId) const {
auto tz = _timeZones.find(timeZoneId);
if (tz != _timeZones.end()) {
diff --git a/src/mongo/db/query/datetime/date_time_support.h b/src/mongo/db/query/datetime/date_time_support.h
index 0482cb70827..6f1e43aafad 100644
--- a/src/mongo/db/query/datetime/date_time_support.h
+++ b/src/mongo/db/query/datetime/date_time_support.h
@@ -303,11 +303,6 @@ public:
std::unique_ptr<TimeZoneDatabase> timeZoneDatabase);
/**
- * Use the timezone database to create a Date_t from a string.
- */
- Date_t fromString(StringData dateString) const;
-
- /**
* Returns a TimeZone object representing the UTC time zone.
*/
static TimeZone utcZone();