mirror of https://github.com/mongodb/mongo
332 lines
12 KiB
JavaScript
332 lines
12 KiB
JavaScript
/**
|
|
* Tests $dateTrunc expression.
|
|
* @tags: [
|
|
* ]
|
|
*/
|
|
import "jstests/libs/query/sbe_assert_error_override.js";
|
|
|
|
import {executeAggregationTestCase} from "jstests/libs/query/aggregation_pipeline_utils.js";
|
|
|
|
const testDB = db.getSiblingDB(jsTestName());
|
|
const coll = testDB.collection;
|
|
|
|
// Drop the test database.
|
|
assert.commandWorked(testDB.dropDatabase());
|
|
|
|
const someDate = new Date("2020-11-01T18:23:36Z");
|
|
const aggregationPipelineWithDateTrunc = [
|
|
{
|
|
$project: {
|
|
_id: false,
|
|
date_trunc: {$dateTrunc: {date: "$date", unit: "$unit", binSize: "$binSize", timezone: "$timeZone"}},
|
|
},
|
|
},
|
|
];
|
|
const aggregationPipelineWithDateTruncAndStartOfWeek = [
|
|
{
|
|
$project: {
|
|
_id: false,
|
|
date_trunc: {
|
|
$dateTrunc: {
|
|
date: "$date",
|
|
unit: "$unit",
|
|
binSize: "$binSize",
|
|
timezone: "$timeZone",
|
|
startOfWeek: "$startOfWeek",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
];
|
|
const testCases = [
|
|
{
|
|
// Parameters are constants, timezone is not specified.
|
|
pipeline: [
|
|
{
|
|
$project: {
|
|
_id: true,
|
|
date_trunc: {$dateTrunc: {date: new Date("2020-11-01T18:23:36Z"), unit: "hour", binSize: 2}},
|
|
},
|
|
},
|
|
],
|
|
inputDocuments: [{_id: 1}],
|
|
expectedResults: [{_id: 1, date_trunc: new Date("2020-11-01T18:00:00Z")}],
|
|
},
|
|
{
|
|
// Parameters are field paths.
|
|
pipeline: aggregationPipelineWithDateTruncAndStartOfWeek,
|
|
inputDocuments: [
|
|
{
|
|
date: new Date("2021-12-01T18:23:36Z"),
|
|
unit: "hour",
|
|
binSize: 4,
|
|
timeZone: "America/New_York",
|
|
startOfWeek: "IGNORED", // Ignored when unit is not week.
|
|
},
|
|
],
|
|
expectedResults: [{date_trunc: new Date("2021-12-01T17:00:00Z")}],
|
|
},
|
|
// Expression parsing tests.
|
|
{
|
|
// Invalid $dateTrunc expression - not an object.
|
|
pipeline: [{$project: {_id: false, date_trunc: {$dateTrunc: "A"}}}],
|
|
inputDocuments: [],
|
|
expectedErrorCode: 5439007,
|
|
},
|
|
{
|
|
// Invalid $dateTrunc expression - invalid parameter.
|
|
pipeline: [{$project: {_id: false, date_trunc: {$dateTrunc: {endDate: 1}}}}],
|
|
inputDocuments: [],
|
|
expectedErrorCode: 5439008,
|
|
},
|
|
{
|
|
// Invalid $dateTrunc expression - missing 'date' parameter.
|
|
pipeline: [{$project: {_id: false, date_trunc: {$dateTrunc: {unit: "week"}}}}],
|
|
inputDocuments: [],
|
|
expectedErrorCode: 5439009,
|
|
},
|
|
{
|
|
// Invalid $dateTrunc expression - missing 'unit' parameter.
|
|
pipeline: [{$project: {_id: false, date_trunc: {$dateTrunc: {date: someDate}}}}],
|
|
inputDocuments: [],
|
|
expectedErrorCode: 5439010,
|
|
},
|
|
// Evaluation tests.
|
|
{
|
|
// Default values are used for optional parameters (startOfWeek: "Sunday", binSize: 1,
|
|
// timezone: "UTC").
|
|
pipeline: [{$project: {_id: false, date_trunc: {$dateTrunc: {date: "$date", unit: "week"}}}}],
|
|
inputDocuments: [
|
|
{
|
|
date: new Date("2021-02-15T18:23:36Z"),
|
|
},
|
|
],
|
|
expectedResults: [{date_trunc: new Date("2021-02-14T00:00:00Z")}],
|
|
},
|
|
{
|
|
// Optional parameters are accepted.
|
|
pipeline: aggregationPipelineWithDateTruncAndStartOfWeek,
|
|
inputDocuments: [
|
|
{
|
|
date: new Date("2000-01-30T18:00:00Z"),
|
|
unit: "week",
|
|
binSize: 2,
|
|
timeZone: "America/New_York",
|
|
startOfWeek: "mon",
|
|
},
|
|
],
|
|
expectedResults: [{date_trunc: new Date("2000-01-17T05:00:00Z")}],
|
|
},
|
|
{
|
|
// 'date' is object id.
|
|
pipeline: [
|
|
{
|
|
$project: {_id: false, date_trunc: {$dateTrunc: {date: "$_id", unit: "minute", binSize: 10}}},
|
|
},
|
|
],
|
|
inputDocuments: [{_id: new ObjectId("507c7f79bcf86cd7994f6c0e") /* timestamp 2012-10-15T21:26:17Z*/}],
|
|
expectedResults: [{date_trunc: new Date("2012-10-15T21:20:00Z")}],
|
|
},
|
|
{
|
|
// 'date' is a timestamp.
|
|
pipeline: [
|
|
{
|
|
$project: {_id: false, date_trunc: {$dateTrunc: {date: "$ts", unit: "second", binSize: 10}}},
|
|
},
|
|
],
|
|
inputDocuments: [{ts: new Timestamp(1350336377 /*2012-10-15T21:26:17Z*/, 0)}],
|
|
expectedResults: [{date_trunc: new Date("2012-10-15T21:26:10Z")}],
|
|
},
|
|
{
|
|
// Invalid 'date' type.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [{date: "string", unit: "hour", binSize: 1, timeZone: "UTC"}],
|
|
expectedErrorCode: 5439012,
|
|
},
|
|
{
|
|
// Missing 'date' value in the document, invalid other fields.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [{unit: "H", binSize: "string", timeZone: 1}],
|
|
expectedResults: [{date_trunc: null}],
|
|
},
|
|
{
|
|
// Null 'date'.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [{date: null, unit: "hour", binSize: 1, timeZone: "UTC"}],
|
|
expectedResults: [{date_trunc: null}],
|
|
},
|
|
{
|
|
// Null 'unit'.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [{date: someDate, unit: null, binSize: 1, timeZone: "UTC"}],
|
|
expectedResults: [{date_trunc: null}],
|
|
},
|
|
{
|
|
// Missing 'unit' value in the document, invalid other fields.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [{date: "Invalid", binSize: "Invalid", timeZone: "Invalid"}],
|
|
expectedResults: [{date_trunc: null}],
|
|
expectedErrorCode: 5439017,
|
|
},
|
|
{
|
|
// Invalid 'unit' type.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [{date: someDate, unit: 1, binSize: 1, timeZone: "UTC"}],
|
|
expectedErrorCode: 5439013,
|
|
},
|
|
{
|
|
// Invalid 'unit' value.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [{date: someDate, unit: "century", binSize: 1, timeZone: "UTC"}],
|
|
expectedErrorCode: ErrorCodes.FailedToParse,
|
|
},
|
|
{
|
|
// Null 'binSize'.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [{date: someDate, unit: "hour", binSize: null, timeZone: "UTC"}],
|
|
expectedResults: [{date_trunc: null}],
|
|
},
|
|
{
|
|
// Missing 'binSize' value in the document, invalid other fields.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [{date: "Invalid", unit: "invalid", timeZone: "Invalid"}],
|
|
expectedResults: [{date_trunc: null}],
|
|
},
|
|
{
|
|
// Invalid 'binSize' type - string.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [{date: someDate, unit: "hour", binSize: "Number", timeZone: "UTC"}],
|
|
expectedErrorCode: 5439017,
|
|
},
|
|
{
|
|
// Invalid 'binSize' value.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [{date: someDate, unit: "hour", binSize: 0, timeZone: "UTC"}],
|
|
expectedErrorCode: 5439018,
|
|
},
|
|
{
|
|
// Invalid 'binSize' value - a float-point number not convertable to an integer is
|
|
// rejected.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [{date: someDate, unit: "hour", binSize: 2.5, timeZone: "UTC"}],
|
|
expectedErrorCode: 5439017,
|
|
},
|
|
{
|
|
// 'binSize' decimal value is accepted.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [
|
|
{
|
|
date: new Date("2020-01-30T18:59:00Z"),
|
|
unit: "minute",
|
|
binSize: NumberDecimal("15"),
|
|
timeZone: "UTC",
|
|
},
|
|
],
|
|
expectedResults: [
|
|
{
|
|
date_trunc: new Date("2020-01-30T18:45:00Z"),
|
|
},
|
|
],
|
|
},
|
|
{
|
|
// 'binSize' long value is accepted.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [
|
|
{
|
|
date: new Date("2020-01-30T18:59:00Z"),
|
|
unit: "day",
|
|
binSize: NumberLong("1"),
|
|
timeZone: "UTC",
|
|
},
|
|
],
|
|
expectedResults: [
|
|
{
|
|
date_trunc: new Date("2020-01-30T00:00:00Z"),
|
|
},
|
|
],
|
|
},
|
|
{
|
|
// 'binSize' int value is accepted.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [
|
|
{
|
|
date: new Date("2020-01-30T18:59:00.003Z"),
|
|
unit: "millisecond",
|
|
binSize: NumberInt("1000"),
|
|
timeZone: "UTC",
|
|
},
|
|
],
|
|
expectedResults: [
|
|
{
|
|
date_trunc: new Date("2020-01-30T18:59:00.000Z"),
|
|
},
|
|
],
|
|
},
|
|
{
|
|
// Null 'timezone'.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [{date: someDate, unit: "hour", binSize: 1, timeZone: null}],
|
|
expectedResults: [{date_trunc: null}],
|
|
},
|
|
{
|
|
// Missing 'timezone' value in the document, invalid other fields. Result could be a null
|
|
// answer or an error code depending whether pipeline is optimized.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [{date: 1, unit: "century", binSize: "1"}],
|
|
expectedResults: [{date_trunc: null}],
|
|
expectedErrorCode: [ErrorCodes.FailedToParse, 5439017],
|
|
},
|
|
{
|
|
// Invalid 'timezone' type.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [{date: someDate, unit: "hour", binSize: 1, timeZone: 1}],
|
|
expectedErrorCode: 40517,
|
|
},
|
|
{
|
|
// Invalid 'timezone' value.
|
|
pipeline: aggregationPipelineWithDateTrunc,
|
|
inputDocuments: [{date: someDate, unit: "hour", binSize: 1, timeZone: "America/Invalid"}],
|
|
expectedErrorCode: 40485,
|
|
},
|
|
{
|
|
// Null 'startOfWeek'.
|
|
pipeline: aggregationPipelineWithDateTruncAndStartOfWeek,
|
|
inputDocuments: [{date: someDate, unit: "week", startOfWeek: null}],
|
|
expectedResults: [{date_trunc: null}],
|
|
},
|
|
{
|
|
// Missing 'startOfWeek' value in the document, invalid other fields.
|
|
pipeline: aggregationPipelineWithDateTruncAndStartOfWeek,
|
|
inputDocuments: [{date: 1, unit: "week", binSize: "", timeZone: 1}],
|
|
expectedResults: [{date_trunc: null}],
|
|
expectedErrorCode: 5439017,
|
|
},
|
|
{
|
|
// Invalid 'startOfWeek' type.
|
|
pipeline: aggregationPipelineWithDateTruncAndStartOfWeek,
|
|
inputDocuments: [{date: someDate, unit: "week", binSize: 1, timeZone: "GMT", startOfWeek: 1}],
|
|
expectedErrorCode: 5439015,
|
|
},
|
|
{
|
|
// Invalid 'startOfWeek' type, unit is not the week.
|
|
pipeline: aggregationPipelineWithDateTruncAndStartOfWeek,
|
|
inputDocuments: [
|
|
{
|
|
date: new Date("2020-01-30T18:59:00.000Z"),
|
|
binSize: 1,
|
|
unit: "year",
|
|
timeZone: "GMT",
|
|
startOfWeek: 1,
|
|
},
|
|
],
|
|
expectedResults: [{date_trunc: new Date("2020-01-01T00:00:00.000Z")}],
|
|
},
|
|
{
|
|
// Invalid 'startOfWeek' value.
|
|
pipeline: aggregationPipelineWithDateTruncAndStartOfWeek,
|
|
inputDocuments: [{date: someDate, unit: "week", binSize: 1, timeZone: "GMT", startOfWeek: "FRIDIE"}],
|
|
expectedErrorCode: 5439016,
|
|
},
|
|
];
|
|
testCases.forEach((testCase) => executeAggregationTestCase(coll, testCase));
|