@@ -50,6 +50,7 @@ struct mc_schema_broker_t {
5050 char * db ; // Database shared by all schemas.
5151 mc_schema_entry_t * ll ;
5252 size_t ll_len ;
53+ bool schema_mixing_is_supported ;
5354};
5455
5556mc_schema_broker_t * mc_schema_broker_new (void ) {
@@ -92,6 +93,11 @@ bool mc_schema_broker_has_multiple_requests(const mc_schema_broker_t *sb) {
9293 return sb -> ll_len > 1 ;
9394}
9495
96+ void mc_schema_broker_support_mixing_schemas (mc_schema_broker_t * sb ) {
97+ BSON_ASSERT_PARAM (sb );
98+ sb -> schema_mixing_is_supported = true;
99+ }
100+
95101void mc_schema_broker_destroy (mc_schema_broker_t * sb ) {
96102 if (!sb ) {
97103 return ;
@@ -702,6 +708,11 @@ static bool append_encryptionInformation(const mc_schema_broker_t *sb,
702708 }
703709
704710 for (mc_schema_entry_t * se = sb -> ll ; se != NULL ; se = se -> next ) {
711+ // encryptedFields is preferred over jsonSchema
712+ if (!se -> encryptedFields .set && se -> jsonSchema .set ) {
713+ continue ;
714+ }
715+
705716 BSON_ASSERT (se -> satisfied );
706717 bool loop_ok = false;
707718 char * ns = bson_strdup_printf ("%s.%s" , sb -> db , se -> coll );
@@ -917,10 +928,20 @@ static bool insert_encryptionInformation(const mc_schema_broker_t *sb,
917928 return ok ;
918929}
919930
931+ static bool any_entry_includes_encryptedFields (mc_schema_entry_t * head ) {
932+ for (mc_schema_entry_t * se = head ; se != NULL ; se = se -> next ) {
933+ if (se -> encryptedFields .set ) {
934+ return true;
935+ }
936+ }
937+
938+ return false;
939+ }
940+
920941// insert_csfleEncryptionSchemas appends schema information to a command for CSFLE.
921942// Only consumed by query analysis (mongocryptd/crypt_shared).
922943// For one JSON schema, use `jsonSchema` for backwards compatibility.
923- // For multiple JSON schemas, use `csfleEncryptionSchemas` (added in server 8.2 ).
944+ // For multiple JSON schemas, use `csfleEncryptionSchemas` (added in server 8.1 ).
924945static bool insert_csfleEncryptionSchemas (const mc_schema_broker_t * sb ,
925946 bson_t * cmd /* in/out */ ,
926947 mc_cmd_target_t cmd_target ,
@@ -965,7 +986,13 @@ static bool insert_csfleEncryptionSchemas(const mc_schema_broker_t *sb,
965986 return false;
966987 }
967988
989+ const bool skip_empty_schemas = any_entry_includes_encryptedFields (sb -> ll );
990+
968991 for (mc_schema_entry_t * se = sb -> ll ; se != NULL ; se = se -> next ) {
992+ if (se -> encryptedFields .set || (!se -> jsonSchema .set && skip_empty_schemas )) {
993+ continue ;
994+ }
995+
969996 BSON_ASSERT (se -> satisfied );
970997
971998 char * ns = bson_strdup_printf ("%s.%s" , sb -> db , se -> coll );
@@ -1033,10 +1060,15 @@ bool mc_schema_broker_add_schemas_to_cmd(const mc_schema_broker_t *sb,
10331060 }
10341061
10351062 if (has_encryptedFields && has_jsonSchema ) {
1036- // If any collection has encryptedFields, error if any collection only has a JSON Schema.
1063+ if (sb -> schema_mixing_is_supported ) {
1064+ return insert_encryptionInformation (sb , cmd_name , cmd , cmd_target , status )
1065+ && insert_csfleEncryptionSchemas (sb , cmd , cmd_target , status );
1066+ }
1067+
10371068 CLIENT_ERR ("Collection '%s' has an encryptedFields configured, but collection '%s' has a JSON schema "
1038- "configured. This is currently not supported. To ignore the JSON schema, add an empty entry for "
1039- "'%s' to AutoEncryptionOpts.encryptedFieldsMap: \"%s\": { \"fields\": [] }" ,
1069+ "configured. This is not supported on mongocryptd/crypt_shared versions below 8.2. To ignore the "
1070+ "JSON schema, add an empty entry for '%s' to AutoEncryptionOpts.encryptedFieldsMap: \"%s\": { "
1071+ "\"fields\": [] }" ,
10401072 coll_with_encryptedFields ,
10411073 coll_with_jsonSchema ,
10421074 coll_with_jsonSchema ,
0 commit comments