summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Larkin-York <dan.larkin-york@mongodb.com>2021-01-29 21:38:43 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-02-08 17:46:17 +0000
commit0963c63a150d99713efbc5ff5221dc34c56718c8 (patch)
treedab1e777621b902ce8d4b51339b01464801038ac
parent7d63d668f001f63672905e8d5f63275c09ba84cd (diff)
downloadmongo-0963c63a150d99713efbc5ff5221dc34c56718c8.tar.gz
SERVER-54018 Restrict metadata and time fields to top-level fields
-rw-r--r--jstests/noPassthroughWithMongod/timeseries_create.js3
-rw-r--r--src/mongo/db/commands/dbcommands.cpp15
-rw-r--r--src/mongo/db/commands/write_commands/write_commands.cpp2
-rw-r--r--src/mongo/db/timeseries/timeseries.idl12
4 files changed, 25 insertions, 7 deletions
diff --git a/jstests/noPassthroughWithMongod/timeseries_create.js b/jstests/noPassthroughWithMongod/timeseries_create.js
index e4ba3a59518..4f59f90e56c 100644
--- a/jstests/noPassthroughWithMongod/timeseries_create.js
+++ b/jstests/noPassthroughWithMongod/timeseries_create.js
@@ -109,6 +109,9 @@ testInvalidTimeseriesOptions({timeField: "time", expireAfterSeconds: ""}, ErrorC
testInvalidTimeseriesOptions({timeField: "time", expireAfterSeconds: NumberLong(-10)},
ErrorCodes.CannotCreateIndex);
testInvalidTimeseriesOptions({timeField: "time", invalidOption: {}}, 40415);
+testInvalidTimeseriesOptions({timeField: "sub.time"}, ErrorCodes.InvalidOptions);
+testInvalidTimeseriesOptions({timeField: "time", metaField: "sub.meta"}, ErrorCodes.InvalidOptions);
+testInvalidTimeseriesOptions({timeField: "time", metaField: "time"}, ErrorCodes.InvalidOptions);
testCompatibleCreateOptions({storageEngine: {}});
testCompatibleCreateOptions({indexOptionDefaults: {}});
diff --git a/src/mongo/db/commands/dbcommands.cpp b/src/mongo/db/commands/dbcommands.cpp
index ba09b7ab525..86b13499dda 100644
--- a/src/mongo/db/commands/dbcommands.cpp
+++ b/src/mongo/db/commands/dbcommands.cpp
@@ -406,6 +406,18 @@ public:
timeseriesNotAllowedWith("pipeline"),
!cmd.getPipeline());
+ auto hasDot = [](StringData field) -> bool {
+ return field.find('.') != std::string::npos;
+ };
+ auto mustBeTopLevel = [&cmd](StringData field) -> std::string {
+ return str::stream()
+ << cmd.getNamespace() << ": '" << field << "' must be a top-level field "
+ << "and not contain a '.'";
+ };
+ uassert(ErrorCodes::InvalidOptions,
+ mustBeTopLevel("timeField"),
+ !hasDot(timeseries->getTimeField()));
+
if (auto metaField = timeseries->getMetaField()) {
uassert(ErrorCodes::InvalidOptions,
"'metaField' cannot be \"_id\"",
@@ -413,6 +425,9 @@ public:
uassert(ErrorCodes::InvalidOptions,
"'metaField' cannot be the same as 'timeField'",
*metaField != timeseries->getTimeField());
+ uassert(ErrorCodes::InvalidOptions,
+ mustBeTopLevel("metaField"),
+ !hasDot(*metaField));
}
}
diff --git a/src/mongo/db/commands/write_commands/write_commands.cpp b/src/mongo/db/commands/write_commands/write_commands.cpp
index e746a09f803..c4df53257c8 100644
--- a/src/mongo/db/commands/write_commands/write_commands.cpp
+++ b/src/mongo/db/commands/write_commands/write_commands.cpp
@@ -736,7 +736,7 @@ public:
std::vector<std::pair<Future<BucketCatalog::CommitInfo>, size_t>> bucketsToWaitOn;
auto insert = [&](size_t index) {
auto [bucketId, commitInfo] =
- bucketCatalog.insert(opCtx, ns(), _batch.getDocuments()[start + index]);
+ bucketCatalog.insert(opCtx, ns(), _batch.getDocuments()[index]);
if (commitInfo) {
bucketsToWaitOn.push_back({std::move(*commitInfo), index});
} else {
diff --git a/src/mongo/db/timeseries/timeseries.idl b/src/mongo/db/timeseries/timeseries.idl
index 6065394097e..64bd20b3bb6 100644
--- a/src/mongo/db/timeseries/timeseries.idl
+++ b/src/mongo/db/timeseries/timeseries.idl
@@ -61,14 +61,14 @@ structs:
strict: true
fields:
timeField:
- description: "The name of the field to be used for time. Inserted documents must
- have this field, and the field must be of the BSON UTC datetime type
- (0x9)"
+ description: "The name of the top-level field to be used for time. Inserted
+ documents must have this field, and the field must be of the BSON UTC
+ datetime type (0x9)"
type: string
metaField:
- description: "The name of the field describing the series. This field is used to
- group related data and may be of any BSON type. This may not be
- \"_id\" or the same as 'timeField'."
+ description: "The name of the top-level field describing the series. This field is
+ used to group related data and may be of any BSON type. This may not
+ be \"_id\" or the same as 'timeField'."
type: string
optional: true
expireAfterSeconds: