@@ -673,6 +673,17 @@ bool phongo_execute_bulk_write(mongoc_client_t *client, const char *namespace, p
673673 return false;
674674 }
675675
676+ /* If a write concern was not specified, libmongoc will use the client's
677+ * write concern; however, we should still fetch it for the write result.
678+ * Additionally, we need to check if an unacknowledged write concern would
679+ * conflict with an explicit session. */
680+ write_concern = zwriteConcern ? Z_WRITECONCERN_OBJ_P (zwriteConcern )-> write_concern : mongoc_client_get_write_concern (client );
681+
682+ if (zsession && !mongoc_write_concern_is_acknowledged (write_concern )) {
683+ phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC , "Cannot combine \"session\" option with an unacknowledged write concern" );
684+ return false;
685+ }
686+
676687 mongoc_bulk_operation_set_database (bulk , bulk_write -> database );
677688 mongoc_bulk_operation_set_collection (bulk , bulk_write -> collection );
678689 mongoc_bulk_operation_set_client (bulk , client );
@@ -682,13 +693,8 @@ bool phongo_execute_bulk_write(mongoc_client_t *client, const char *namespace, p
682693 mongoc_bulk_operation_set_client_session (bulk , Z_SESSION_OBJ_P (zsession )-> client_session );
683694 }
684695
685- /* If a write concern was not specified, libmongoc will use the client's
686- * write concern; however, we should still fetch it for the write result. */
687- write_concern = phongo_write_concern_from_zval (zwriteConcern TSRMLS_CC );
688- if (write_concern ) {
689- mongoc_bulk_operation_set_write_concern (bulk , write_concern );
690- } else {
691- write_concern = mongoc_client_get_write_concern (client );
696+ if (zwriteConcern ) {
697+ mongoc_bulk_operation_set_write_concern (bulk , Z_WRITECONCERN_OBJ_P (zwriteConcern )-> write_concern );
692698 }
693699
694700 success = mongoc_bulk_operation_execute (bulk , & reply , & error );
@@ -862,6 +868,7 @@ bool phongo_execute_command(mongoc_client_t *client, php_phongo_command_type_t t
862868 bool result = false;
863869 bool free_reply = false;
864870 bool free_zsession = false;
871+ bool is_unacknowledged_write_concern = false;
865872
866873 command = Z_COMMAND_OBJ_P (zcommand );
867874
@@ -880,9 +887,33 @@ bool phongo_execute_command(mongoc_client_t *client, php_phongo_command_type_t t
880887 goto cleanup ;
881888 }
882889
883- /* If an explicit session was not provided, attempt to create an implicit
884- * client session (ignoring any errors). */
885- if (!zsession ) {
890+ if (type & PHONGO_OPTION_WRITE_CONCERN ) {
891+ zval * zwriteConcern = NULL ;
892+
893+ if (!phongo_parse_write_concern (options , & opts , & zwriteConcern TSRMLS_CC )) {
894+ /* Exception should already have been thrown */
895+ goto cleanup ;
896+ }
897+
898+ /* Determine if the explicit or inherited write concern is
899+ * unacknowledged so that we can ensure it does not conflict with an
900+ * explicit or implicit session. */
901+ if (zwriteConcern ) {
902+ is_unacknowledged_write_concern = !mongoc_write_concern_is_acknowledged (Z_WRITECONCERN_OBJ_P (zwriteConcern )-> write_concern );
903+ } else if (type != PHONGO_COMMAND_RAW ) {
904+ is_unacknowledged_write_concern = !mongoc_write_concern_is_acknowledged (mongoc_client_get_write_concern (client ));
905+ }
906+ }
907+
908+ if (zsession && is_unacknowledged_write_concern ) {
909+ phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC , "Cannot combine \"session\" option with an unacknowledged write concern" );
910+ goto cleanup ;
911+ }
912+
913+ /* If an explicit session was not provided and the effective write concern
914+ * is not unacknowledged, attempt to create an implicit client session
915+ * (ignoring any errors). */
916+ if (!zsession && !is_unacknowledged_write_concern ) {
886917 zsession = phongo_create_implicit_session (client TSRMLS_CC );
887918
888919 if (zsession ) {
@@ -895,11 +926,6 @@ bool phongo_execute_command(mongoc_client_t *client, php_phongo_command_type_t t
895926 }
896927 }
897928
898- if ((type & PHONGO_OPTION_WRITE_CONCERN ) && !phongo_parse_write_concern (options , & opts , NULL TSRMLS_CC )) {
899- /* Exception should already have been thrown */
900- goto cleanup ;
901- }
902-
903929 if (!BSON_APPEND_INT32 (& opts , "serverId" , server_id )) {
904930 phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC , "Error appending \"serverId\" option" );
905931 goto cleanup ;
0 commit comments