Skip to content

Commit 194b44b

Browse files
authored
RUST-1271 Support clustered indexes for all collections (#659)
1 parent edb65e1 commit 194b44b

File tree

5 files changed

+476
-2
lines changed

5 files changed

+476
-2
lines changed

src/db/options.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::time::Duration;
22

3+
use bson::doc;
34
use serde::{Deserialize, Serialize};
45
use serde_with::skip_serializing_none;
56
use typed_builder::TypedBuilder;
@@ -106,6 +107,9 @@ pub struct CreateCollectionOptions {
106107

107108
/// Options for supporting change stream pre- and post-images.
108109
pub change_stream_pre_and_post_images: Option<ChangeStreamPreAndPostImages>,
110+
111+
/// Options for clustered collections.
112+
pub clustered_index: Option<ClusteredIndex>,
109113
}
110114

111115
/// Specifies how strictly the database should apply validation rules to existing documents during
@@ -135,6 +139,37 @@ pub enum ValidationAction {
135139
Warn,
136140
}
137141

142+
/// Specifies options for a clustered collection. Some fields have required values; the `Default`
143+
/// impl uses those values.
144+
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
145+
#[serde(rename_all = "camelCase")]
146+
#[non_exhaustive]
147+
pub struct ClusteredIndex {
148+
/// Key pattern; currently required to be `{_id: 1}`.
149+
pub key: Document,
150+
151+
/// Currently required to be `true`.
152+
pub unique: bool,
153+
154+
/// Optional; will be automatically generated if not provided.
155+
pub name: Option<String>,
156+
157+
/// Optional; currently must be `2` if provided.
158+
#[serde(skip_serializing_if = "Option::is_none")]
159+
pub v: Option<i32>,
160+
}
161+
162+
impl Default for ClusteredIndex {
163+
fn default() -> Self {
164+
Self {
165+
key: doc! { "_id": 1 },
166+
unique: true,
167+
name: None,
168+
v: None,
169+
}
170+
}
171+
}
172+
138173
/// Specifies default configuration for indexes created on a collection, including the _id index.
139174
#[derive(Clone, Debug, TypedBuilder, PartialEq, Serialize, Deserialize)]
140175
#[serde(rename_all = "camelCase")]

src/index/options.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,20 @@ pub struct IndexOptions {
111111
/// A flag that determines whether the index is hidden from the query planner. A
112112
/// hidden index is not evaluated as part of the query plan selection.
113113
pub hidden: Option<bool>,
114+
115+
#[builder(default, setter(skip))]
116+
clustered: Option<bool>,
117+
}
118+
119+
impl IndexOptions {
120+
/// Optionally specifies that this index is clustered. This is not a valid option to provide to
121+
/// 'create_indexes', but can appear in the options returned for an index via 'list_indexes'.
122+
/// To create a clustered index, create a new collection using the 'clustered_index' option.
123+
///
124+
/// This options is only supported by servers >= 6.0.
125+
pub fn clustered(&self) -> Option<bool> {
126+
self.clustered
127+
}
114128
}
115129

116130
/// The version of the index. Version 0 Indexes are disallowed as of MongoDB 3.2.

src/test/spec/json/collection-management/README.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,4 @@ Collection Management Tests
33
===========================
44

55
This directory contains tests for collection management. They are implemented
6-
in the `Unified Test Format <../../unified-test-format/unified-test-format.rst>`__
7-
and require schema version 1.0.
6+
in the `Unified Test Format <../../unified-test-format/unified-test-format.rst>`__.
Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
{
2+
"description": "clustered-indexes",
3+
"schemaVersion": "1.4",
4+
"runOnRequirements": [
5+
{
6+
"minServerVersion": "5.3",
7+
"serverless": "forbid"
8+
}
9+
],
10+
"createEntities": [
11+
{
12+
"client": {
13+
"id": "client0",
14+
"observeEvents": [
15+
"commandStartedEvent"
16+
]
17+
}
18+
},
19+
{
20+
"database": {
21+
"id": "database0",
22+
"client": "client0",
23+
"databaseName": "ci-tests"
24+
}
25+
},
26+
{
27+
"collection": {
28+
"id": "collection0",
29+
"database": "database0",
30+
"collectionName": "test"
31+
}
32+
}
33+
],
34+
"initialData": [
35+
{
36+
"collectionName": "test",
37+
"databaseName": "ci-tests",
38+
"documents": []
39+
}
40+
],
41+
"tests": [
42+
{
43+
"description": "createCollection with clusteredIndex",
44+
"operations": [
45+
{
46+
"name": "dropCollection",
47+
"object": "database0",
48+
"arguments": {
49+
"collection": "test"
50+
}
51+
},
52+
{
53+
"name": "createCollection",
54+
"object": "database0",
55+
"arguments": {
56+
"collection": "test",
57+
"clusteredIndex": {
58+
"key": {
59+
"_id": 1
60+
},
61+
"unique": true,
62+
"name": "test index"
63+
}
64+
}
65+
},
66+
{
67+
"name": "assertCollectionExists",
68+
"object": "testRunner",
69+
"arguments": {
70+
"databaseName": "ci-tests",
71+
"collectionName": "test"
72+
}
73+
}
74+
],
75+
"expectEvents": [
76+
{
77+
"client": "client0",
78+
"events": [
79+
{
80+
"commandStartedEvent": {
81+
"command": {
82+
"drop": "test"
83+
},
84+
"databaseName": "ci-tests"
85+
}
86+
},
87+
{
88+
"commandStartedEvent": {
89+
"command": {
90+
"create": "test",
91+
"clusteredIndex": {
92+
"key": {
93+
"_id": 1
94+
},
95+
"unique": true,
96+
"name": "test index"
97+
}
98+
},
99+
"databaseName": "ci-tests"
100+
}
101+
}
102+
]
103+
}
104+
]
105+
},
106+
{
107+
"description": "listCollections includes clusteredIndex",
108+
"operations": [
109+
{
110+
"name": "dropCollection",
111+
"object": "database0",
112+
"arguments": {
113+
"collection": "test"
114+
}
115+
},
116+
{
117+
"name": "createCollection",
118+
"object": "database0",
119+
"arguments": {
120+
"collection": "test",
121+
"clusteredIndex": {
122+
"key": {
123+
"_id": 1
124+
},
125+
"unique": true,
126+
"name": "test index"
127+
}
128+
}
129+
},
130+
{
131+
"name": "listCollections",
132+
"object": "database0",
133+
"arguments": {
134+
"filter": {
135+
"name": {
136+
"$eq": "test"
137+
}
138+
}
139+
},
140+
"expectResult": [
141+
{
142+
"name": "test",
143+
"options": {
144+
"clusteredIndex": {
145+
"key": {
146+
"_id": 1
147+
},
148+
"unique": true,
149+
"name": "test index",
150+
"v": {
151+
"$$type": [
152+
"int",
153+
"long"
154+
]
155+
}
156+
}
157+
}
158+
}
159+
]
160+
}
161+
],
162+
"expectEvents": [
163+
{
164+
"client": "client0",
165+
"events": [
166+
{
167+
"commandStartedEvent": {
168+
"command": {
169+
"drop": "test"
170+
},
171+
"databaseName": "ci-tests"
172+
}
173+
},
174+
{
175+
"commandStartedEvent": {
176+
"command": {
177+
"create": "test",
178+
"clusteredIndex": {
179+
"key": {
180+
"_id": 1
181+
},
182+
"unique": true,
183+
"name": "test index"
184+
}
185+
},
186+
"databaseName": "ci-tests"
187+
}
188+
},
189+
{
190+
"commandStartedEvent": {
191+
"command": {
192+
"listCollections": 1,
193+
"filter": {
194+
"name": {
195+
"$eq": "test"
196+
}
197+
}
198+
},
199+
"databaseName": "ci-tests"
200+
}
201+
}
202+
]
203+
}
204+
]
205+
},
206+
{
207+
"description": "listIndexes returns the index",
208+
"operations": [
209+
{
210+
"name": "dropCollection",
211+
"object": "database0",
212+
"arguments": {
213+
"collection": "test"
214+
}
215+
},
216+
{
217+
"name": "createCollection",
218+
"object": "database0",
219+
"arguments": {
220+
"collection": "test",
221+
"clusteredIndex": {
222+
"key": {
223+
"_id": 1
224+
},
225+
"unique": true,
226+
"name": "test index"
227+
}
228+
}
229+
},
230+
{
231+
"name": "listIndexes",
232+
"object": "collection0",
233+
"expectResult": [
234+
{
235+
"key": {
236+
"_id": 1
237+
},
238+
"name": "test index",
239+
"clustered": true,
240+
"unique": true,
241+
"v": {
242+
"$$type": [
243+
"int",
244+
"long"
245+
]
246+
}
247+
}
248+
]
249+
}
250+
],
251+
"expectEvents": [
252+
{
253+
"client": "client0",
254+
"events": [
255+
{
256+
"commandStartedEvent": {
257+
"command": {
258+
"drop": "test"
259+
},
260+
"databaseName": "ci-tests"
261+
}
262+
},
263+
{
264+
"commandStartedEvent": {
265+
"command": {
266+
"create": "test",
267+
"clusteredIndex": {
268+
"key": {
269+
"_id": 1
270+
},
271+
"unique": true,
272+
"name": "test index"
273+
}
274+
},
275+
"databaseName": "ci-tests"
276+
}
277+
},
278+
{
279+
"commandStartedEvent": {
280+
"command": {
281+
"listIndexes": "test"
282+
},
283+
"databaseName": "ci-tests"
284+
}
285+
}
286+
]
287+
}
288+
]
289+
}
290+
]
291+
}

0 commit comments

Comments
 (0)