Skip to content

Commit 0ea5b74

Browse files
authored
MONGOCRYPT-870 drop prefixPreview and suffixPreview (mongodb#1184)
* replace "prefixPreview" and "suffixPreview" query types with "prefix" and "suffix" * replace "textPreview' algorithm with "string"
1 parent 74df5a2 commit 0ea5b74

21 files changed

Lines changed: 281 additions & 91 deletions

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22

33
## Unreleased
44

5+
### Added
6+
- Stable support for prefix and suffix queries:
7+
- The `prefixPreview` query type is replaced with `prefix`.
8+
- The `suffixPreview` query type is replaced with `suffix`.
9+
- Use the `string` algorithm (formerly `textPreview`) for `prefix`, `suffix`, and `substringPreview` query types.
10+
11+
### Removed
12+
- Support for the experimental `prefixPreview` and `suffixPreview` query types.
13+
514
<!-- TODO: add entries for next release -->
615

716
## 1.18.1

bindings/python/test/test_mongocrypt.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,9 +1030,9 @@ async def test_text_query(self):
10301030
value = bson.encode({"v": "foo"})
10311031
encrypted = await encrypter.encrypt(
10321032
value,
1033-
"textPreview",
1033+
"string",
10341034
key_id=key_id,
1035-
query_type="suffixPreview",
1035+
query_type="suffix",
10361036
contention_factor=0,
10371037
text_opts=text_opts,
10381038
)
@@ -1500,9 +1500,9 @@ def test_text_query(self):
15001500
value = bson.encode({"v": "foo"})
15011501
encrypted = encrypter.encrypt(
15021502
value,
1503-
"textPreview",
1503+
"string",
15041504
key_id=key_id,
1505-
query_type="suffixPreview",
1505+
query_type="suffix",
15061506
contention_factor=0,
15071507
text_opts=text_opts,
15081508
)

src/mc-efc-private.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ typedef enum _supported_query_type_flags {
3232
SUPPORTS_SUBSTRING_PREVIEW_QUERIES = 1 << 3,
3333
SUPPORTS_SUFFIX_QUERIES = 1 << 4,
3434
SUPPORTS_PREFIX_QUERIES = 1 << 5,
35+
// prefixPreview and suffixPreview are dropped. Setting this results in an error.
36+
SUPPORTS_SUFFIX_PREVIEW_DEPRECATED_QUERIES = 1 << 6,
37+
SUPPORTS_PREFIX_PREVIEW_DEPRECATED_QUERIES = 1 << 7,
3538
} supported_query_type_flags;
3639

3740
typedef struct _mc_EncryptedField_t {

src/mc-efc.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@ static bool _parse_query_type_string(const char *queryType, supported_query_type
3535
*out = SUPPORTS_RANGE_PREVIEW_DEPRECATED_QUERIES;
3636
} else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_STR), qtv)) {
3737
*out = SUPPORTS_SUBSTRING_PREVIEW_QUERIES;
38-
} else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED_STR), qtv)
39-
|| mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUFFIX_STR), qtv)) {
38+
} else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUFFIX_STR), qtv)) {
4039
*out = SUPPORTS_SUFFIX_QUERIES;
41-
} else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED_STR), qtv)
42-
|| mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_PREFIX_STR), qtv)) {
40+
} else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_PREFIX_STR), qtv)) {
4341
*out = SUPPORTS_PREFIX_QUERIES;
42+
} else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED_STR), qtv)) {
43+
*out = SUPPORTS_SUFFIX_PREVIEW_DEPRECATED_QUERIES;
44+
} else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED_STR), qtv)) {
45+
*out = SUPPORTS_PREFIX_PREVIEW_DEPRECATED_QUERIES;
4446
} else {
4547
return false;
4648
}
@@ -176,6 +178,20 @@ static bool _parse_field(mc_EncryptedFieldConfig_t *efc, bson_t *field, mongocry
176178
return false;
177179
}
178180

181+
if (query_types & SUPPORTS_PREFIX_PREVIEW_DEPRECATED_QUERIES) {
182+
CLIENT_ERR("Cannot use field '%s' with 'prefixPreview' queries. 'prefixPreview' is unsupported. Use 'prefix' "
183+
"instead.",
184+
field_path);
185+
return false;
186+
}
187+
188+
if (query_types & SUPPORTS_SUFFIX_PREVIEW_DEPRECATED_QUERIES) {
189+
CLIENT_ERR("Cannot use field '%s' with 'suffixPreview' queries. 'suffixPreview' is unsupported. Use 'suffix' "
190+
"instead.",
191+
field_path);
192+
return false;
193+
}
194+
179195
/* Prepend a new mc_EncryptedField_t */
180196
mc_EncryptedField_t *ef = bson_malloc0(sizeof(mc_EncryptedField_t));
181197
if (has_keyid) {

src/mongocrypt-ctx-encrypt.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,7 +1539,7 @@ static bool _fle2_finalize_explicit(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *
15391539
goto fail;
15401540
// fallthrough
15411541
case MONGOCRYPT_INDEX_TYPE_RANGE: marking.u.fle2.algorithm = MONGOCRYPT_FLE2_ALGORITHM_RANGE; break;
1542-
case MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW: marking.u.fle2.algorithm = MONGOCRYPT_FLE2_ALGORITHM_TEXT_SEARCH; break;
1542+
case MONGOCRYPT_INDEX_TYPE_STRING: marking.u.fle2.algorithm = MONGOCRYPT_FLE2_ALGORITHM_TEXT_SEARCH; break;
15431543
default:
15441544
// This might be unreachable because of other validation. Better safe than
15451545
// sorry.
@@ -1631,7 +1631,7 @@ static bool _fle2_finalize_explicit(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *
16311631
case MONGOCRYPT_INDEX_TYPE_EQUALITY:
16321632
case MONGOCRYPT_INDEX_TYPE_RANGEPREVIEW_DEPRECATED:
16331633
case MONGOCRYPT_INDEX_TYPE_RANGE:
1634-
case MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW:
1634+
case MONGOCRYPT_INDEX_TYPE_STRING:
16351635
// All QE indexed algorithms require contention factor.
16361636
BSON_ASSERT(ctx->opts.contention_factor.set); // Checked earlier in explicit_encrypt_init.
16371637
marking.u.fle2.maxContentionFactor = ctx->opts.contention_factor.value;
@@ -2088,18 +2088,18 @@ static bool explicit_encrypt_init(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *ms
20882088
if (ctx->opts.query_type.set) {
20892089
const mongocrypt_query_type_t qt = ctx->opts.query_type.value;
20902090
if (qt == MONGOCRYPT_QUERY_TYPE_PREFIX) {
2091-
if (!(ctx->opts.index_type.set && ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW)) {
2092-
return _mongocrypt_ctx_fail_w_msg(ctx, "prefix query type requires textPreview index type");
2091+
if (!(ctx->opts.index_type.set && ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_STRING)) {
2092+
return _mongocrypt_ctx_fail_w_msg(ctx, "prefix query type requires string index type");
20932093
}
20942094
}
20952095
if (qt == MONGOCRYPT_QUERY_TYPE_SUFFIX) {
2096-
if (!(ctx->opts.index_type.set && ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW)) {
2097-
return _mongocrypt_ctx_fail_w_msg(ctx, "suffix query type requires textPreview index type");
2096+
if (!(ctx->opts.index_type.set && ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_STRING)) {
2097+
return _mongocrypt_ctx_fail_w_msg(ctx, "suffix query type requires string index type");
20982098
}
20992099
}
21002100
if (qt == MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW) {
2101-
if (!(ctx->opts.index_type.set && ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW)) {
2102-
return _mongocrypt_ctx_fail_w_msg(ctx, "substringPreview query type requires textPreview index type");
2101+
if (!(ctx->opts.index_type.set && ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_STRING)) {
2102+
return _mongocrypt_ctx_fail_w_msg(ctx, "substringPreview query type requires string index type");
21032103
}
21042104
}
21052105
}
@@ -2113,14 +2113,14 @@ static bool explicit_encrypt_init(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *ms
21132113
return _mongocrypt_ctx_fail_w_msg(ctx, "cannot set range opts with equality index type");
21142114
}
21152115

2116-
if (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW) {
2117-
return _mongocrypt_ctx_fail_w_msg(ctx, "cannot set range opts with textPreview index type");
2116+
if (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_STRING) {
2117+
return _mongocrypt_ctx_fail_w_msg(ctx, "cannot set range opts with 'string' algorithm");
21182118
}
21192119
}
21202120

21212121
if (ctx->opts.textopts.set && ctx->opts.index_type.set) {
2122-
if (ctx->opts.index_type.value != MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW) {
2123-
return _mongocrypt_ctx_fail_w_msg(ctx, "cannot set text opts without textPreview index type");
2122+
if (ctx->opts.index_type.value != MONGOCRYPT_INDEX_TYPE_STRING) {
2123+
return _mongocrypt_ctx_fail_w_msg(ctx, "cannot set string opts without string index type");
21242124
}
21252125
}
21262126

@@ -2147,13 +2147,13 @@ static bool explicit_encrypt_init(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *ms
21472147
}
21482148

21492149
// Check required options for text algorithm are set:
2150-
if (ctx->opts.index_type.set && (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW)) {
2150+
if (ctx->opts.index_type.set && (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_STRING)) {
21512151
if (!ctx->opts.contention_factor.set) {
2152-
return _mongocrypt_ctx_fail_w_msg(ctx, "contention factor is required for textPreview algorithm");
2152+
return _mongocrypt_ctx_fail_w_msg(ctx, "contention factor is required for string algorithm");
21532153
}
21542154

21552155
if (!ctx->opts.textopts.set) {
2156-
return _mongocrypt_ctx_fail_w_msg(ctx, "text opts are required for textPreview algorithm");
2156+
return _mongocrypt_ctx_fail_w_msg(ctx, "string opts are required for string algorithm");
21572157
}
21582158
}
21592159

@@ -2183,7 +2183,7 @@ static bool explicit_encrypt_init(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *ms
21832183
case MONGOCRYPT_QUERY_TYPE_PREFIX:
21842184
case MONGOCRYPT_QUERY_TYPE_SUFFIX:
21852185
case MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW:
2186-
matches = (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW);
2186+
matches = (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_STRING);
21872187
break;
21882188
default:
21892189
CLIENT_ERR("unsupported value for query_type: %d", (int)ctx->opts.query_type.value);

src/mongocrypt-ctx.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,8 @@ bool mongocrypt_ctx_setopt_algorithm(mongocrypt_ctx_t *ctx, const char *algorith
245245
} else if (mstr_eq_ignore_case(algo_str, mstrv_lit(MONGOCRYPT_ALGORITHM_RANGEPREVIEW_DEPRECATED_STR))) {
246246
_mongocrypt_ctx_fail_w_msg(ctx, "Algorithm 'rangePreview' is deprecated, please use 'range'");
247247
return false;
248-
} else if (mstr_eq_ignore_case(algo_str, mstrv_lit(MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR))) {
249-
ctx->opts.index_type.value = MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW;
248+
} else if (mstr_eq_ignore_case(algo_str, mstrv_lit(MONGOCRYPT_ALGORITHM_STRING_STR))) {
249+
ctx->opts.index_type.value = MONGOCRYPT_INDEX_TYPE_STRING;
250250
ctx->opts.index_type.set = true;
251251
} else {
252252
char *error = bson_strdup_printf("unsupported algorithm string \"%.*s\"",
@@ -1028,15 +1028,11 @@ bool mongocrypt_ctx_setopt_query_type(mongocrypt_ctx_t *ctx, const char *query_t
10281028
ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_SUFFIX;
10291029
ctx->opts.query_type.set = true;
10301030
} else if (mstr_eq_ignore_case(qt_str, mstrv_lit(MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED_STR))) {
1031-
// TODO: MONGOCRYPT-870 disallow prefixPreview
1032-
// _mongocrypt_ctx_fail_w_msg(ctx, "Query type 'prefixPreview' is deprecated, please use 'prefix'");
1033-
ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_PREFIX;
1034-
ctx->opts.query_type.set = true;
1031+
_mongocrypt_ctx_fail_w_msg(ctx, "Query type 'prefixPreview' is deprecated, please use 'prefix'");
1032+
return false;
10351033
} else if (mstr_eq_ignore_case(qt_str, mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED_STR))) {
1036-
// TODO: MONGOCRYPT-870 disallow suffixPreview
1037-
// _mongocrypt_ctx_fail_w_msg(ctx, "Query type 'suffixPreview' is deprecated, please use 'suffix'");
1038-
ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_SUFFIX;
1039-
ctx->opts.query_type.set = true;
1034+
_mongocrypt_ctx_fail_w_msg(ctx, "Query type 'suffixPreview' is deprecated, please use 'suffix'");
1035+
return false;
10401036
} else if (mstr_eq_ignore_case(qt_str, mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_STR))) {
10411037
ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW;
10421038
ctx->opts.query_type.set = true;
@@ -1058,7 +1054,7 @@ const char *_mongocrypt_index_type_to_string(mongocrypt_index_type_t val) {
10581054
case MONGOCRYPT_INDEX_TYPE_EQUALITY: return "Equality";
10591055
case MONGOCRYPT_INDEX_TYPE_RANGE: return "Range";
10601056
case MONGOCRYPT_INDEX_TYPE_RANGEPREVIEW_DEPRECATED: return "RangePreview";
1061-
case MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW: return "TextPreview";
1057+
case MONGOCRYPT_INDEX_TYPE_STRING: return "String";
10621058
default: return "Unknown";
10631059
}
10641060
}

src/mongocrypt-private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ typedef enum {
156156
MONGOCRYPT_INDEX_TYPE_EQUALITY = 2,
157157
MONGOCRYPT_INDEX_TYPE_RANGE = 3,
158158
MONGOCRYPT_INDEX_TYPE_RANGEPREVIEW_DEPRECATED = 4,
159-
MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW = 5,
159+
MONGOCRYPT_INDEX_TYPE_STRING = 5,
160160
} mongocrypt_index_type_t;
161161

162162
bool _mongocrypt_validate_and_copy_string(const char *in, int32_t in_len, char **out) MONGOCRYPT_WARN_UNUSED_RESULT;

src/mongocrypt.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -716,8 +716,10 @@ bool mongocrypt_ctx_setopt_algorithm(mongocrypt_ctx_t *ctx, const char *algorith
716716
// DEPRECATED: support "RangePreview" has been removed in favor of "range".
717717
#define MONGOCRYPT_ALGORITHM_RANGEPREVIEW_DEPRECATED_STR "RangePreview"
718718
#define MONGOCRYPT_ALGORITHM_RANGE_STR "Range"
719-
/// NOTE: "textPreview" is experimental only and may be removed in a future non-major release.
720-
#define MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR "textPreview"
719+
/// DEPRECATED: "textPreview" has been removed. Use "string".
720+
#define MONGOCRYPT_ALGORITHM_TEXTPREVIEW_DEPRECATED_STR "textPreview"
721+
// String constant for setopt_algorithm "string" explicit encryption.
722+
#define MONGOCRYPT_ALGORITHM_STRING_STR "string"
721723

722724
/**
723725
* Identify the AWS KMS master key to use for creating a data key.
@@ -1555,9 +1557,9 @@ MONGOCRYPT_EXPORT
15551557
bool mongocrypt_ctx_setopt_algorithm_range(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *opts);
15561558

15571559
/**
1558-
* Set options for explicit encryption with the "textPreview" algorithm.
1560+
* Set options for explicit encryption with the "string" algorithm.
15591561
*
1560-
* NOTE: "textPreview" is experimental only and may be removed in a future non-major release.
1562+
* NOTE: Use of the "substringPreview" query type is experimental only and may be removed in a future non-major release.
15611563
* @p opts is a BSON document of the form:
15621564
* {
15631565
* "caseSensitive": bool,
@@ -1578,6 +1580,8 @@ bool mongocrypt_ctx_setopt_algorithm_range(mongocrypt_ctx_t *ctx, mongocrypt_bin
15781580
* }
15791581
*
15801582
* "prefix" and "suffix" can both be set.
1583+
*
1584+
* NOTE: Driver public APIs should use the name "string" rather than "text" to refer to options.
15811585
*/
15821586
MONGOCRYPT_EXPORT
15831587
bool mongocrypt_ctx_setopt_algorithm_text(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *opts);

test/data/cleanup/text-search/collinfo.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
"path": "textField2",
7575
"bsonType": "string",
7676
"queries": [{
77-
"queryType": "suffixPreview",
77+
"queryType": "suffix",
7878
"contention": {
7979
"$numberLong": "0"
8080
},
@@ -84,7 +84,7 @@
8484
"diacriticSensitive": false
8585
},
8686
{
87-
"queryType": "prefixPreview",
87+
"queryType": "prefix",
8888
"contention": {
8989
"$numberLong": "0"
9090
},

test/data/cleanup/text-search/encrypted-field-config-map.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
"path": "textField2",
7373
"bsonType": "string",
7474
"queries": [{
75-
"queryType": "suffixPreview",
75+
"queryType": "suffix",
7676
"contention": {
7777
"$numberLong": "0"
7878
},
@@ -82,7 +82,7 @@
8282
"diacriticSensitive": false
8383
},
8484
{
85-
"queryType": "prefixPreview",
85+
"queryType": "prefix",
8686
"contention": {
8787
"$numberLong": "0"
8888
},

0 commit comments

Comments
 (0)