Skip to content

Commit 1addd28

Browse files
committed
MONGOCRYPT-830 only include queried type in FLE2TextSearchInsertSpec (#1047)
* skip ninja on macOS * only include queried type in `FLE2TextSearchInsertSpec`
1 parent cd0b26a commit 1addd28

File tree

8 files changed

+186
-14
lines changed

8 files changed

+186
-14
lines changed

.evergreen/config.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ functions:
106106
export LSAN_OPTIONS="suppressions=$LIBMONGOCRYPT_DIR/.lsan-suppressions"
107107
export VS_VERSION=${vs_version|}
108108
export VS_TARGET_ARCH=${vs_target_arch|amd64}
109-
export USE_NINJA=ON
109+
export USE_NINJA=${use_ninja|ON}
110110
env ${compile_env|} \
111111
bash "$EVG_DIR/env-run.sh" \
112112
bash "$EVG_DIR/build_all.sh"
@@ -151,7 +151,7 @@ functions:
151151
- command: "shell.exec"
152152
params:
153153
script: |-
154-
if test "$OS_NAME" != "windows"; then export USE_NINJA=ON; fi
154+
if test "$OS_NAME" != "windows"; then export USE_NINJA=${use_ninja|ON}; fi
155155
env ${compile_env|} CONFIGURE_ONLY=ON ${clang_env|CC=clang CXX=clang++} \
156156
bash libmongocrypt/.evergreen/build_all.sh
157157
./libmongocrypt/.evergreen/clang-tidy.sh
@@ -1624,6 +1624,8 @@ buildvariants:
16241624
run_on: macos-1100-arm64
16251625
expansions:
16261626
compile_env: MACOS_UNIVERSAL=ON CMAKE=/opt/homebrew/bin/cmake
1627+
# Disable Ninja to work around error "Bad CPU type in executable"
1628+
use_ninja: OFF
16271629
tasks:
16281630
- build-and-test-and-upload
16291631
- test-python

.evergreen/ensure-cmake.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ _download_cmake() {
5858
url="$url_base/cmake-$CMAKE_VERSION-Linux-$arch.tar.gz"
5959
;;
6060
macos)
61-
url="$url_base/cmake-$CMAKE_VERSION-macos10.10-universal.tar.gz"
61+
url="$url_base/cmake-$CMAKE_VERSION-macos-universal.tar.gz"
6262
# We're pulling out the app bundle contents, so we need to skip more intermediate directories
6363
strip_components=3
6464
;;

src/mc-textopts-private.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,11 @@ bool mc_TextOpts_to_FLE2TextSearchInsertSpec(const mc_TextOpts_t *txo,
7676
bson_t *out,
7777
mongocrypt_status_t *status);
7878

79+
enum _mongocrypt_query_type_t; // Forward declare.
80+
bool mc_TextOpts_to_FLE2TextSearchInsertSpec_for_query(const mc_TextOpts_t *txo,
81+
const bson_t *v,
82+
enum _mongocrypt_query_type_t query_type,
83+
bson_t *out,
84+
mongocrypt_status_t *status);
85+
7986
#endif // MC_TEXTOPTS_PRIVATE_H

src/mc-textopts.c

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "mc-textopts-private.h"
1818

19+
#include "mongocrypt-ctx-private.h" // mongocrypt_query_type_t
1920
#include "mongocrypt-private.h"
2021
#include "mongocrypt-util-private.h" // mc_bson_type_to_string
2122
#include "mongocrypt.h"
@@ -243,10 +244,13 @@ static bool append_TextOptsPerIndex(const mc_TextOptsPerIndex_t *txio, bson_t *o
243244
return true;
244245
}
245246

246-
bool mc_TextOpts_to_FLE2TextSearchInsertSpec(const mc_TextOpts_t *txo,
247-
const bson_t *v,
248-
bson_t *out,
249-
mongocrypt_status_t *status) {
247+
static bool TextOpts_to_FLE2TextSearchInsertSpec(const mc_TextOpts_t *txo,
248+
const bson_t *v,
249+
bool include_prefix,
250+
bool include_suffix,
251+
bool include_substring,
252+
bson_t *out,
253+
mongocrypt_status_t *status) {
250254
BSON_ASSERT_PARAM(txo);
251255
BSON_ASSERT_PARAM(v);
252256
BSON_ASSERT_PARAM(out);
@@ -277,7 +281,7 @@ bool mc_TextOpts_to_FLE2TextSearchInsertSpec(const mc_TextOpts_t *txo,
277281
return false;
278282
}
279283

280-
if (txo->prefix.set) {
284+
if (txo->prefix.set && include_prefix) {
281285
bson_t insert_spec;
282286
if (!BSON_APPEND_DOCUMENT_BEGIN(&child, "prefix", &insert_spec)) {
283287
CLIENT_ERR(ERROR_PREFIX "Error appending to BSON");
@@ -294,7 +298,7 @@ bool mc_TextOpts_to_FLE2TextSearchInsertSpec(const mc_TextOpts_t *txo,
294298
}
295299
}
296300

297-
if (txo->suffix.set) {
301+
if (txo->suffix.set && include_suffix) {
298302
bson_t insert_spec;
299303
if (!BSON_APPEND_DOCUMENT_BEGIN(&child, "suffix", &insert_spec)) {
300304
CLIENT_ERR(ERROR_PREFIX "Error appending to BSON");
@@ -311,7 +315,7 @@ bool mc_TextOpts_to_FLE2TextSearchInsertSpec(const mc_TextOpts_t *txo,
311315
}
312316
}
313317

314-
if (txo->substring.set) {
318+
if (txo->substring.set && include_substring) {
315319
bson_t insert_spec;
316320
if (!BSON_APPEND_DOCUMENT_BEGIN(&child, "substr", &insert_spec)) {
317321
CLIENT_ERR(ERROR_PREFIX "Error appending to BSON");
@@ -336,4 +340,46 @@ bool mc_TextOpts_to_FLE2TextSearchInsertSpec(const mc_TextOpts_t *txo,
336340
return true;
337341
}
338342

343+
bool mc_TextOpts_to_FLE2TextSearchInsertSpec(const mc_TextOpts_t *txo,
344+
const bson_t *v,
345+
bson_t *out,
346+
mongocrypt_status_t *status) {
347+
// FLE2TextSearchInsertSpec for insert includes all query types specified.
348+
return TextOpts_to_FLE2TextSearchInsertSpec(txo, v, true, true, true, out, status);
349+
}
350+
351+
bool mc_TextOpts_to_FLE2TextSearchInsertSpec_for_query(const mc_TextOpts_t *txo,
352+
const bson_t *v,
353+
mongocrypt_query_type_t query_type,
354+
bson_t *out,
355+
mongocrypt_status_t *status) {
356+
// FLE2TextSearchInsertSpec for query only includes query type specified.
357+
bool include_prefix = false;
358+
bool include_suffix = false;
359+
bool include_substring = false;
360+
361+
switch (query_type) {
362+
case MONGOCRYPT_QUERY_TYPE_RANGEPREVIEW_DEPRECATED:
363+
case MONGOCRYPT_QUERY_TYPE_RANGE:
364+
case MONGOCRYPT_QUERY_TYPE_EQUALITY:
365+
default: {
366+
CLIENT_ERR("Unexpected query type: %s\n", _mongocrypt_query_type_to_string(query_type));
367+
return false;
368+
}
369+
case MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW: {
370+
include_prefix = true;
371+
break;
372+
}
373+
case MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW: {
374+
include_suffix = true;
375+
break;
376+
}
377+
case MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW: {
378+
include_substring = true;
379+
break;
380+
}
381+
}
382+
return TextOpts_to_FLE2TextSearchInsertSpec(txo, v, include_prefix, include_suffix, include_substring, out, status);
383+
}
384+
339385
#undef ERROR_PREFIX

src/mongocrypt-ctx-encrypt.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,9 +1372,21 @@ static bool _fle2_finalize_explicit(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *
13721372
_mongocrypt_ctx_fail_w_msg(ctx, "unable to convert input to BSON");
13731373
goto fail;
13741374
}
1375-
if (!mc_TextOpts_to_FLE2TextSearchInsertSpec(&ctx->opts.textopts.value, &old_v, &new_v, ctx->status)) {
1376-
_mongocrypt_ctx_fail(ctx);
1377-
goto fail;
1375+
1376+
if (ctx->opts.query_type.set) {
1377+
if (!mc_TextOpts_to_FLE2TextSearchInsertSpec_for_query(&ctx->opts.textopts.value,
1378+
&old_v,
1379+
ctx->opts.query_type.value,
1380+
&new_v,
1381+
ctx->status)) {
1382+
_mongocrypt_ctx_fail(ctx);
1383+
goto fail;
1384+
}
1385+
} else {
1386+
if (!mc_TextOpts_to_FLE2TextSearchInsertSpec(&ctx->opts.textopts.value, &old_v, &new_v, ctx->status)) {
1387+
_mongocrypt_ctx_fail(ctx);
1388+
goto fail;
1389+
}
13781390
}
13791391

13801392
if (!bson_iter_init_find(&marking.u.fle2.v_iter, &new_v, "v")) {

src/mongocrypt-ctx-private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ typedef enum {
4040

4141
const char *_mongocrypt_index_type_to_string(mongocrypt_index_type_t val);
4242

43-
typedef enum {
43+
typedef enum _mongocrypt_query_type_t {
4444
MONGOCRYPT_QUERY_TYPE_EQUALITY = 1,
4545
MONGOCRYPT_QUERY_TYPE_RANGE = 2,
4646
MONGOCRYPT_QUERY_TYPE_RANGEPREVIEW_DEPRECATED = 3,

test/test-mc-textopts.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,93 @@ static void test_mc_TextOpts_to_FLE2TextSearchInsertSpec(_mongocrypt_tester_t *t
227227
}
228228
}
229229

230+
static void test_mc_TextOpts_to_FLE2TextSearchInsertSpec_for_query(_mongocrypt_tester_t *tester) {
231+
typedef struct {
232+
const char *desc;
233+
const char *in;
234+
const char *v;
235+
mongocrypt_query_type_t qt;
236+
const char *expectError;
237+
const char *expect;
238+
} testcase;
239+
240+
testcase tests[] = {
241+
{.desc = "Works with substring",
242+
.in = RAW_STRING({
243+
"caseSensitive" : true,
244+
"diacriticSensitive" : false,
245+
"substring" : {"strMaxLength" : 10, "strMinQueryLength" : 3, "strMaxQueryLength" : 8}
246+
}),
247+
.v = RAW_STRING({"v" : "test"}),
248+
.qt = MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW,
249+
.expect = RAW_STRING(
250+
{"v" : {"v" : "test", "casef" : true, "diacf" : false, "substr" : {"mlen" : 10, "ub" : 8, "lb" : 3}}})},
251+
{.desc = "Works with prefix",
252+
.in = RAW_STRING({
253+
"caseSensitive" : true,
254+
"diacriticSensitive" : false,
255+
"prefix" : {"strMinQueryLength" : 3, "strMaxQueryLength" : 8}
256+
}),
257+
.v = RAW_STRING({"v" : "test"}),
258+
.qt = MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW,
259+
.expect =
260+
RAW_STRING({"v" : {"v" : "test", "casef" : true, "diacf" : false, "prefix" : {"ub" : 8, "lb" : 3}}})},
261+
{.desc = "Works with suffix",
262+
.in = RAW_STRING({
263+
"caseSensitive" : true,
264+
"diacriticSensitive" : false,
265+
"suffix" : {"strMinQueryLength" : 3, "strMaxQueryLength" : 8}
266+
}),
267+
.v = RAW_STRING({"v" : "test"}),
268+
.qt = MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW,
269+
.expect =
270+
RAW_STRING({"v" : {"v" : "test", "casef" : true, "diacf" : false, "suffix" : {"ub" : 8, "lb" : 3}}})},
271+
{.desc = "Works with prefix + suffix when querying prefix",
272+
.in = RAW_STRING({
273+
"caseSensitive" : true,
274+
"diacriticSensitive" : false,
275+
"prefix" : {"strMinQueryLength" : 4, "strMaxQueryLength" : 9},
276+
"suffix" : {"strMinQueryLength" : 3, "strMaxQueryLength" : 8}
277+
}),
278+
.v = RAW_STRING({"v" : "test"}),
279+
.qt = MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW,
280+
.expect =
281+
RAW_STRING({"v" : {"v" : "test", "casef" : true, "diacf" : false, "prefix" : {"ub" : 9, "lb" : 4}}})},
282+
{.desc = "Works with prefix + suffix when querying suffix",
283+
.in = RAW_STRING({
284+
"caseSensitive" : true,
285+
"diacriticSensitive" : false,
286+
"prefix" : {"strMinQueryLength" : 4, "strMaxQueryLength" : 9},
287+
"suffix" : {"strMinQueryLength" : 3, "strMaxQueryLength" : 8}
288+
}),
289+
.v = RAW_STRING({"v" : "test"}),
290+
.qt = MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW,
291+
.expect =
292+
RAW_STRING({"v" : {"v" : "test", "casef" : true, "diacf" : false, "suffix" : {"ub" : 8, "lb" : 3}}})},
293+
};
294+
295+
for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
296+
testcase *test = tests + i;
297+
mongocrypt_status_t *status = mongocrypt_status_new();
298+
mc_TextOpts_t txo;
299+
TEST_PRINTF("running test_mc_TextOpts_to_FLE2TextSearchInsertSpec subtest: %s\n", test->desc);
300+
ASSERT_OK_STATUS(mc_TextOpts_parse(&txo, TMP_BSON_STR(test->in), status), status);
301+
bson_t out = BSON_INITIALIZER;
302+
bool ret =
303+
mc_TextOpts_to_FLE2TextSearchInsertSpec_for_query(&txo, TMP_BSON_STR(test->v), test->qt, &out, status);
304+
if (!test->expectError) {
305+
ASSERT_OK_STATUS(ret, status);
306+
ASSERT_EQUAL_BSON(TMP_BSON_STR(test->expect), &out);
307+
} else {
308+
ASSERT_FAILS_STATUS(ret, status, test->expectError);
309+
}
310+
bson_destroy(&out);
311+
mongocrypt_status_destroy(status);
312+
}
313+
}
314+
230315
void _mongocrypt_tester_install_mc_TextOpts(_mongocrypt_tester_t *tester) {
231316
INSTALL_TEST(test_mc_TextOpts_parse);
232317
INSTALL_TEST(test_mc_TextOpts_to_FLE2TextSearchInsertSpec);
318+
INSTALL_TEST(test_mc_TextOpts_to_FLE2TextSearchInsertSpec_for_query);
233319
}

test/test-mongocrypt-ctx-encrypt.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2628,6 +2628,25 @@ static void _test_encrypt_fle2_explicit(_mongocrypt_tester_t *tester) {
26282628
ee_testcase_run(&tc);
26292629
}
26302630

2631+
{
2632+
ee_testcase tc = {0};
2633+
tc.desc = "find prefix on a field with prefix+suffix";
2634+
tc.algorithm = MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR;
2635+
tc.contention_factor = OPT_I64(1);
2636+
tc.msg = TEST_BSON("{'v': 'abc'}");
2637+
tc.user_key_id = &keyABC_id;
2638+
tc.keys_to_feed[0] = keyABC;
2639+
tc.query_type = MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_STR;
2640+
tc.text_opts = TEST_BSON(RAW_STRING({
2641+
"caseSensitive" : false,
2642+
"diacriticSensitive" : false,
2643+
"prefix" : {"strMinQueryLength" : 1, "strMaxQueryLength" : 100},
2644+
"suffix" : {"strMinQueryLength" : 1, "strMaxQueryLength" : 100}
2645+
}));
2646+
tc.expect = TEST_FILE("./test/data/fle2-explicit/find-prefix.json");
2647+
ee_testcase_run(&tc);
2648+
}
2649+
26312650
_mongocrypt_buffer_cleanup(&keyABC_id);
26322651
_mongocrypt_buffer_cleanup(&key123_id);
26332652
}

0 commit comments

Comments
 (0)