Skip to content

Commit 14f2941

Browse files
committed
GODRIVER-3123 QE Range Protocol V2
1 parent 8b69159 commit 14f2941

12 files changed

+168
-55
lines changed

mongo/client_encryption.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,12 @@ func transformExplicitEncryptionOptions(opts ...*options.EncryptOptions) *mcopts
204204
if eo.RangeOptions.Precision != nil {
205205
transformedRange.Precision = eo.RangeOptions.Precision
206206
}
207-
transformedRange.Sparsity = eo.RangeOptions.Sparsity
207+
if eo.RangeOptions.Sparsity != nil {
208+
transformedRange.Sparsity = eo.RangeOptions.Sparsity
209+
}
210+
if eo.RangeOptions.TrimFactor != nil {
211+
transformedRange.TrimFactor = eo.RangeOptions.TrimFactor
212+
}
208213
transformed.SetRangeOptions(transformedRange)
209214
}
210215
return transformed
@@ -230,7 +235,7 @@ func (ce *ClientEncryption) Encrypt(ctx context.Context, val bson.RawValue,
230235
// 2. An Aggregate Expression of this form:
231236
// {$and: [{$gt: [<fieldpath>, <value1>]}, {$lt: [<fieldpath>, <value2>]}]
232237
// $gt may also be $gte. $lt may also be $lte.
233-
// Only supported for queryType "rangePreview"
238+
// Only supported for queryType "range"
234239
// Beta: The Range algorithm is experimental only. It is not intended for public use. It is subject to breaking changes.
235240
func (ce *ClientEncryption) EncryptExpression(ctx context.Context, expr interface{}, result interface{}, opts ...*options.EncryptOptions) error {
236241
transformed := transformExplicitEncryptionOptions(opts...)

mongo/integration/client_side_encryption_prose_test.go

Lines changed: 107 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2465,8 +2465,7 @@ func TestClientSideEncryptionProse(t *testing.T) {
24652465
}
24662466
})
24672467

2468-
// GODRIVER-3123. When we implement this feature, lower the min server version to 8.0.1
2469-
qeRunOpts22 := qeRunOpts.MaxServerVersion("7.99.99")
2468+
qeRunOpts22 := qeRunOpts.MinServerVersion("8.0")
24702469
mt.RunOpts("22. range explicit encryption", qeRunOpts22, func(mt *mtest.T) {
24712470
type testcase struct {
24722471
typeStr string
@@ -2480,6 +2479,8 @@ func TestClientSideEncryptionProse(t *testing.T) {
24802479
twoHundredOne bson.RawValue
24812480
}
24822481

2482+
trimFactor := int32(1)
2483+
sparsity := int64(1)
24832484
precision := int32(2)
24842485

24852486
d128_0, err := primitive.ParseDecimal128("0")
@@ -2499,7 +2500,8 @@ func TestClientSideEncryptionProse(t *testing.T) {
24992500
field: "encryptedDecimalNoPrecision",
25002501
typeBson: bson.TypeDecimal128,
25012502
rangeOpts: options.RangeOptions{
2502-
Sparsity: 1,
2503+
TrimFactor: &trimFactor,
2504+
Sparsity: &sparsity,
25032505
},
25042506
zero: bson.RawValue{Type: bson.TypeDecimal128, Value: bsoncore.AppendDecimal128(nil, d128_0)},
25052507
six: bson.RawValue{Type: bson.TypeDecimal128, Value: bsoncore.AppendDecimal128(nil, d128_6)},
@@ -2512,10 +2514,11 @@ func TestClientSideEncryptionProse(t *testing.T) {
25122514
field: "encryptedDecimalPrecision",
25132515
typeBson: bson.TypeDecimal128,
25142516
rangeOpts: options.RangeOptions{
2515-
Min: &bson.RawValue{Type: bson.TypeDecimal128, Value: bsoncore.AppendDecimal128(nil, d128_0)},
2516-
Max: &bson.RawValue{Type: bson.TypeDecimal128, Value: bsoncore.AppendDecimal128(nil, d128_200)},
2517-
Sparsity: 1,
2518-
Precision: &precision,
2517+
Min: &bson.RawValue{Type: bson.TypeDecimal128, Value: bsoncore.AppendDecimal128(nil, d128_0)},
2518+
Max: &bson.RawValue{Type: bson.TypeDecimal128, Value: bsoncore.AppendDecimal128(nil, d128_200)},
2519+
TrimFactor: &trimFactor,
2520+
Sparsity: &sparsity,
2521+
Precision: &precision,
25192522
},
25202523
zero: bson.RawValue{Type: bson.TypeDecimal128, Value: bsoncore.AppendDecimal128(nil, d128_0)},
25212524
six: bson.RawValue{Type: bson.TypeDecimal128, Value: bsoncore.AppendDecimal128(nil, d128_6)},
@@ -2528,7 +2531,8 @@ func TestClientSideEncryptionProse(t *testing.T) {
25282531
field: "encryptedDoubleNoPrecision",
25292532
typeBson: bson.TypeDouble,
25302533
rangeOpts: options.RangeOptions{
2531-
Sparsity: 1,
2534+
TrimFactor: &trimFactor,
2535+
Sparsity: &sparsity,
25322536
},
25332537
zero: bson.RawValue{Type: bson.TypeDouble, Value: bsoncore.AppendDouble(nil, 0)},
25342538
six: bson.RawValue{Type: bson.TypeDouble, Value: bsoncore.AppendDouble(nil, 6)},
@@ -2541,10 +2545,11 @@ func TestClientSideEncryptionProse(t *testing.T) {
25412545
field: "encryptedDoublePrecision",
25422546
typeBson: bson.TypeDouble,
25432547
rangeOpts: options.RangeOptions{
2544-
Min: &bson.RawValue{Type: bson.TypeDouble, Value: bsoncore.AppendDouble(nil, 0)},
2545-
Max: &bson.RawValue{Type: bson.TypeDouble, Value: bsoncore.AppendDouble(nil, 200)},
2546-
Sparsity: 1,
2547-
Precision: &precision,
2548+
Min: &bson.RawValue{Type: bson.TypeDouble, Value: bsoncore.AppendDouble(nil, 0)},
2549+
Max: &bson.RawValue{Type: bson.TypeDouble, Value: bsoncore.AppendDouble(nil, 200)},
2550+
TrimFactor: &trimFactor,
2551+
Sparsity: &sparsity,
2552+
Precision: &precision,
25482553
},
25492554
zero: bson.RawValue{Type: bson.TypeDouble, Value: bsoncore.AppendDouble(nil, 0)},
25502555
six: bson.RawValue{Type: bson.TypeDouble, Value: bsoncore.AppendDouble(nil, 6)},
@@ -2557,9 +2562,10 @@ func TestClientSideEncryptionProse(t *testing.T) {
25572562
field: "encryptedDate",
25582563
typeBson: bson.TypeDateTime,
25592564
rangeOpts: options.RangeOptions{
2560-
Min: &bson.RawValue{Type: bson.TypeDateTime, Value: bsoncore.AppendDateTime(nil, 0)},
2561-
Max: &bson.RawValue{Type: bson.TypeDateTime, Value: bsoncore.AppendDateTime(nil, 200)},
2562-
Sparsity: 1,
2565+
Min: &bson.RawValue{Type: bson.TypeDateTime, Value: bsoncore.AppendDateTime(nil, 0)},
2566+
Max: &bson.RawValue{Type: bson.TypeDateTime, Value: bsoncore.AppendDateTime(nil, 200)},
2567+
TrimFactor: &trimFactor,
2568+
Sparsity: &sparsity,
25632569
},
25642570
zero: bson.RawValue{Type: bson.TypeDateTime, Value: bsoncore.AppendDateTime(nil, 0)},
25652571
six: bson.RawValue{Type: bson.TypeDateTime, Value: bsoncore.AppendDateTime(nil, 6)},
@@ -2572,9 +2578,10 @@ func TestClientSideEncryptionProse(t *testing.T) {
25722578
field: "encryptedInt",
25732579
typeBson: bson.TypeInt32,
25742580
rangeOpts: options.RangeOptions{
2575-
Min: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 0)},
2576-
Max: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 200)},
2577-
Sparsity: 1,
2581+
Min: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 0)},
2582+
Max: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 200)},
2583+
TrimFactor: &trimFactor,
2584+
Sparsity: &sparsity,
25782585
},
25792586
zero: bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 0)},
25802587
six: bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 6)},
@@ -2587,9 +2594,10 @@ func TestClientSideEncryptionProse(t *testing.T) {
25872594
field: "encryptedLong",
25882595
typeBson: bson.TypeInt64,
25892596
rangeOpts: options.RangeOptions{
2590-
Min: &bson.RawValue{Type: bson.TypeInt64, Value: bsoncore.AppendInt64(nil, 0)},
2591-
Max: &bson.RawValue{Type: bson.TypeInt64, Value: bsoncore.AppendInt64(nil, 200)},
2592-
Sparsity: 1,
2597+
Min: &bson.RawValue{Type: bson.TypeInt64, Value: bsoncore.AppendInt64(nil, 0)},
2598+
Max: &bson.RawValue{Type: bson.TypeInt64, Value: bsoncore.AppendInt64(nil, 200)},
2599+
TrimFactor: &trimFactor,
2600+
Sparsity: &sparsity,
25932601
},
25942602
zero: bson.RawValue{Type: bson.TypeInt64, Value: bsoncore.AppendInt64(nil, 0)},
25952603
six: bson.RawValue{Type: bson.TypeInt64, Value: bsoncore.AppendInt64(nil, 6)},
@@ -2645,7 +2653,7 @@ func TestClientSideEncryptionProse(t *testing.T) {
26452653
// Insert 0, 6, 30, and 200.
26462654
coll := encryptedClient.Database("db").Collection("explicit_encryption")
26472655
eo := options.Encrypt().
2648-
SetAlgorithm("RangePreview").
2656+
SetAlgorithm("Range").
26492657
SetKeyID(key1ID).
26502658
SetContentionFactor(0).
26512659
SetRangeOptions(test.rangeOpts)
@@ -2692,7 +2700,7 @@ func TestClientSideEncryptionProse(t *testing.T) {
26922700
defer clientEncryption.Close(context.Background())
26932701
defer encryptedClient.Disconnect(context.Background())
26942702
eo := options.Encrypt().
2695-
SetAlgorithm("RangePreview").
2703+
SetAlgorithm("Range").
26962704
SetKeyID(key1ID).
26972705
SetContentionFactor(0).
26982706
SetRangeOptions(test.rangeOpts)
@@ -2708,10 +2716,10 @@ func TestClientSideEncryptionProse(t *testing.T) {
27082716
defer clientEncryption.Close(context.Background())
27092717
defer encryptedClient.Disconnect(context.Background())
27102718
eo := options.Encrypt().
2711-
SetAlgorithm("RangePreview").
2719+
SetAlgorithm("Range").
27122720
SetKeyID(key1ID).
27132721
SetContentionFactor(0).
2714-
SetQueryType("rangePreview").
2722+
SetQueryType("range").
27152723
SetRangeOptions(test.rangeOpts)
27162724

27172725
expr := bson.M{
@@ -2750,10 +2758,10 @@ func TestClientSideEncryptionProse(t *testing.T) {
27502758
defer clientEncryption.Close(context.Background())
27512759
defer encryptedClient.Disconnect(context.Background())
27522760
eo := options.Encrypt().
2753-
SetAlgorithm("RangePreview").
2761+
SetAlgorithm("Range").
27542762
SetKeyID(key1ID).
27552763
SetContentionFactor(0).
2756-
SetQueryType("rangePreview").
2764+
SetQueryType("range").
27572765
SetRangeOptions(test.rangeOpts)
27582766

27592767
expr := bson.M{
@@ -2792,10 +2800,10 @@ func TestClientSideEncryptionProse(t *testing.T) {
27922800
defer clientEncryption.Close(context.Background())
27932801
defer encryptedClient.Disconnect(context.Background())
27942802
eo := options.Encrypt().
2795-
SetAlgorithm("RangePreview").
2803+
SetAlgorithm("Range").
27962804
SetKeyID(key1ID).
27972805
SetContentionFactor(0).
2798-
SetQueryType("rangePreview").
2806+
SetQueryType("range").
27992807
SetRangeOptions(test.rangeOpts)
28002808

28012809
expr := bson.M{
@@ -2829,10 +2837,10 @@ func TestClientSideEncryptionProse(t *testing.T) {
28292837
defer clientEncryption.Close(context.Background())
28302838
defer encryptedClient.Disconnect(context.Background())
28312839
eo := options.Encrypt().
2832-
SetAlgorithm("RangePreview").
2840+
SetAlgorithm("Range").
28332841
SetKeyID(key1ID).
28342842
SetContentionFactor(0).
2835-
SetQueryType("rangePreview").
2843+
SetQueryType("range").
28362844
SetRangeOptions(test.rangeOpts)
28372845

28382846
expr := bson.M{
@@ -2868,7 +2876,7 @@ func TestClientSideEncryptionProse(t *testing.T) {
28682876
defer clientEncryption.Close(context.Background())
28692877
defer encryptedClient.Disconnect(context.Background())
28702878
eo := options.Encrypt().
2871-
SetAlgorithm("RangePreview").
2879+
SetAlgorithm("Range").
28722880
SetKeyID(key1ID).
28732881
SetContentionFactor(0).
28742882
SetRangeOptions(test.rangeOpts)
@@ -2882,7 +2890,7 @@ func TestClientSideEncryptionProse(t *testing.T) {
28822890
defer clientEncryption.Close(context.Background())
28832891
defer encryptedClient.Disconnect(context.Background())
28842892
eo := options.Encrypt().
2885-
SetAlgorithm("RangePreview").
2893+
SetAlgorithm("Range").
28862894
SetKeyID(key1ID).
28872895
SetContentionFactor(0).
28882896
SetRangeOptions(test.rangeOpts)
@@ -2909,7 +2917,7 @@ func TestClientSideEncryptionProse(t *testing.T) {
29092917
ro := test.rangeOpts
29102918
ro.SetPrecision(2)
29112919
eo := options.Encrypt().
2912-
SetAlgorithm("RangePreview").
2920+
SetAlgorithm("Range").
29132921
SetKeyID(key1ID).
29142922
SetContentionFactor(0).
29152923
SetRangeOptions(ro)
@@ -2921,6 +2929,71 @@ func TestClientSideEncryptionProse(t *testing.T) {
29212929
})
29222930
}
29232931
})
2932+
2933+
mt.RunOpts("22. range explicit encryption applies defaults", qeRunOpts22, func(mt *mtest.T) {
2934+
err := mt.Client.Database("keyvault").Collection("datakeys").Drop(context.Background())
2935+
assert.Nil(mt, err, "error on Drop: %v", err)
2936+
2937+
testVal := bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 123)}
2938+
2939+
keyVaultClient, err := mongo.Connect(context.Background(), options.Client().ApplyURI(mtest.ClusterURI()))
2940+
assert.Nil(mt, err, "error on Connect: %v", err)
2941+
2942+
ceo := options.ClientEncryption().
2943+
SetKeyVaultNamespace("keyvault.datakeys").
2944+
SetKmsProviders(fullKmsProvidersMap)
2945+
clientEncryption, err := mongo.NewClientEncryption(keyVaultClient, ceo)
2946+
assert.Nil(mt, err, "error on NewClientEncryption: %v", err)
2947+
2948+
dkOpts := options.DataKey()
2949+
keyID, err := clientEncryption.CreateDataKey(context.Background(), "local", dkOpts)
2950+
assert.Nil(mt, err, "error in CreateDataKey: %v", err)
2951+
2952+
eo := options.Encrypt().
2953+
SetAlgorithm("Range").
2954+
SetKeyID(keyID).
2955+
SetContentionFactor(0).
2956+
SetRangeOptions(options.RangeOptions{
2957+
Min: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 0)},
2958+
Max: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 1000)},
2959+
})
2960+
payloadDefaults, err := clientEncryption.Encrypt(context.Background(), testVal, eo)
2961+
assert.Nil(mt, err, "error in Encrypt: %v", err)
2962+
2963+
mt.Run("Case 1: uses libmongocrypt defaults", func(mt *mtest.T) {
2964+
trimFactor := int32(6)
2965+
sparsity := int64(2)
2966+
eo := options.Encrypt().
2967+
SetAlgorithm("Range").
2968+
SetKeyID(keyID).
2969+
SetContentionFactor(0).
2970+
SetRangeOptions(options.RangeOptions{
2971+
Min: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 0)},
2972+
Max: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 1000)},
2973+
TrimFactor: &trimFactor,
2974+
Sparsity: &sparsity,
2975+
})
2976+
payload, err := clientEncryption.Encrypt(context.Background(), testVal, eo)
2977+
assert.Nil(mt, err, "error in Encrypt: %v", err)
2978+
assert.Equalf(mt, len(payload.Data), len(payloadDefaults.Data), "the returned payload size is expected to be %d", len(payloadDefaults.Data))
2979+
})
2980+
2981+
mt.Run("Case 2: accepts trimFactor 0", func(mt *mtest.T) {
2982+
trimFactor := int32(0)
2983+
eo := options.Encrypt().
2984+
SetAlgorithm("Range").
2985+
SetKeyID(keyID).
2986+
SetContentionFactor(0).
2987+
SetRangeOptions(options.RangeOptions{
2988+
Min: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 0)},
2989+
Max: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 1000)},
2990+
TrimFactor: &trimFactor,
2991+
})
2992+
payload, err := clientEncryption.Encrypt(context.Background(), testVal, eo)
2993+
assert.Nil(mt, err, "error in Encrypt: %v", err)
2994+
assert.Greater(t, len(payload.Data), len(payloadDefaults.Data), "the returned payload size is expected to be greater than %d", len(payloadDefaults.Data))
2995+
})
2996+
})
29242997
}
29252998

29262999
func getWatcher(mt *mtest.T, streamType mongo.StreamType, cpt *cseProseTest) watcher {

mongo/options/encryptoptions.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ const (
1717
QueryTypeEquality string = "equality"
1818
)
1919

20-
// RangeOptions specifies index options for a Queryable Encryption field supporting "rangePreview" queries.
20+
// RangeOptions specifies index options for a Queryable Encryption field supporting "range" queries.
2121
// Beta: The Range algorithm is experimental only. It is not intended for public use. It is subject to breaking changes.
2222
type RangeOptions struct {
23-
Min *bson.RawValue
24-
Max *bson.RawValue
25-
Sparsity int64
26-
Precision *int32
23+
Min *bson.RawValue
24+
Max *bson.RawValue
25+
Sparsity *int64
26+
TrimFactor *int32
27+
Precision *int32
2728
}
2829

2930
// EncryptOptions represents options to explicitly encrypt a value.
@@ -81,7 +82,7 @@ func (e *EncryptOptions) SetContentionFactor(contentionFactor int64) *EncryptOpt
8182
return e
8283
}
8384

84-
// SetRangeOptions specifies the options to use for explicit encryption with range. It is only valid to set if algorithm is "rangePreview".
85+
// SetRangeOptions specifies the options to use for explicit encryption with range. It is only valid to set if algorithm is "range".
8586
// Beta: The Range algorithm is experimental only. It is not intended for public use. It is subject to breaking changes.
8687
func (e *EncryptOptions) SetRangeOptions(ro RangeOptions) *EncryptOptions {
8788
e.RangeOptions = &ro
@@ -105,7 +106,14 @@ func (ro *RangeOptions) SetMax(max bson.RawValue) *RangeOptions {
105106
// SetSparsity sets the range index sparsity.
106107
// Beta: The Range algorithm is experimental only. It is not intended for public use. It is subject to breaking changes.
107108
func (ro *RangeOptions) SetSparsity(sparsity int64) *RangeOptions {
108-
ro.Sparsity = sparsity
109+
ro.Sparsity = &sparsity
110+
return ro
111+
}
112+
113+
// SetTrimFactor sets the range index trim factor.
114+
// Beta: The Range algorithm is experimental only. It is not intended for public use. It is subject to breaking changes.
115+
func (ro *RangeOptions) SetTrimFactor(trimFactor int32) *RangeOptions {
116+
ro.TrimFactor = &trimFactor
109117
return ro
110118
}
111119

testdata/client-side-encryption-prose/range-encryptedFields-Date.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010
"path": "encryptedDate",
1111
"bsonType": "date",
1212
"queries": {
13-
"queryType": "rangePreview",
13+
"queryType": "range",
1414
"contention": {
1515
"$numberLong": "0"
1616
},
17+
"trimFactor": {
18+
"$numberInt": "1"
19+
},
1720
"sparsity": {
1821
"$numberLong": "1"
1922
},

testdata/client-side-encryption-prose/range-encryptedFields-DecimalNoPrecision.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010
"path": "encryptedDecimalNoPrecision",
1111
"bsonType": "decimal",
1212
"queries": {
13-
"queryType": "rangePreview",
13+
"queryType": "range",
1414
"contention": {
1515
"$numberLong": "0"
1616
},
17+
"trimFactor": {
18+
"$numberInt": "1"
19+
},
1720
"sparsity": {
1821
"$numberLong": "1"
1922
}

testdata/client-side-encryption-prose/range-encryptedFields-DecimalPrecision.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010
"path": "encryptedDecimalPrecision",
1111
"bsonType": "decimal",
1212
"queries": {
13-
"queryType": "rangePreview",
13+
"queryType": "range",
1414
"contention": {
1515
"$numberLong": "0"
1616
},
17+
"trimFactor": {
18+
"$numberInt": "1"
19+
},
1720
"sparsity": {
1821
"$numberLong": "1"
1922
},

0 commit comments

Comments
 (0)