]> granicus.if.org Git - php/commitdiff
Fix #78179: mysqli/mysqlnd transaction extensions
authorDaniel Black <daniel@mariadb.org>
Tue, 21 Jul 2020 06:23:14 +0000 (16:23 +1000)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 18 Sep 2020 13:29:44 +0000 (15:29 +0200)
MariaDB versioning created a mess with regarding testing
features based on version. We sidestep the problem here
by assuming the extensions are present, and if a syntax
error occurs with a SQL mode TRANS_START_READ_WRITE |
TRANS_START_READ_ONLY enabled, then output the same
warning as before.

ext/mysqli/mysqli_nonapi.c
ext/mysqlnd/mysqlnd_connection.c

index 3d0240183a8ddb0b547cfa8900523b632892afd8..b0b554d85c4ae673e808ebfec6b319caa065cee1 100644 (file)
@@ -1086,45 +1086,43 @@ extern char * mysqli_escape_string_for_tx_name_in_comment(const char * const nam
 static int mysqli_begin_transaction_libmysql(MYSQL * conn, const unsigned int mode, const char * const name)
 {
        int ret;
-       zend_bool err = FALSE;
        smart_str tmp_str = {0};
+       char * name_esc;
+       char * query;
+       unsigned int query_len;
        if (mode & TRANS_START_WITH_CONSISTENT_SNAPSHOT) {
                if (tmp_str.s) {
                        smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
                }
                smart_str_appendl(&tmp_str, "WITH CONSISTENT SNAPSHOT", sizeof("WITH CONSISTENT SNAPSHOT") - 1);
        }
-       if (mode & (TRANS_START_READ_WRITE | TRANS_START_READ_ONLY)) {
-               if (mysql_get_server_version(conn) < 50605L) {
-                       php_error_docref(NULL, E_WARNING, "This server version doesn't support 'READ WRITE' and 'READ ONLY'. Minimum 5.6.5 is required");
-                       err = TRUE;
-               } else if (mode & TRANS_START_READ_WRITE) {
-                       if (tmp_str.s) {
-                               smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
-                       }
-                       smart_str_appendl(&tmp_str, "READ WRITE", sizeof("READ WRITE") - 1);
-               } else if (mode & TRANS_START_READ_ONLY) {
-                       if (tmp_str.s) {
-                               smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
-                       }
-                       smart_str_appendl(&tmp_str, "READ ONLY", sizeof("READ ONLY") - 1);
+       if (mode & TRANS_START_READ_WRITE) {
+               if (tmp_str.s) {
+                       smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
                }
+               smart_str_appendl(&tmp_str, "READ WRITE", sizeof("READ WRITE") - 1);
+       } else if (mode & TRANS_START_READ_ONLY) {
+               if (tmp_str.s) {
+                       smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
+               }
+               smart_str_appendl(&tmp_str, "READ ONLY", sizeof("READ ONLY") - 1);
        }
        smart_str_0(&tmp_str);
 
-       if (err == FALSE){
-               char * name_esc = mysqli_escape_string_for_tx_name_in_comment(name);
-               char * query;
-               unsigned int query_len = spprintf(&query, 0, "START TRANSACTION%s %s",
-                                                                                 name_esc? name_esc:"", tmp_str.s? ZSTR_VAL(tmp_str.s):"");
+       name_esc = mysqli_escape_string_for_tx_name_in_comment(name);
+       query_len = spprintf(&query, 0, "START TRANSACTION%s %s",
+                                                name_esc? name_esc:"", tmp_str.s? ZSTR_VAL(tmp_str.s):"");
 
-               smart_str_free(&tmp_str);
-               if (name_esc) {
-                       efree(name_esc);
-               }
+       smart_str_free(&tmp_str);
+       if (name_esc) {
+               efree(name_esc);
+       }
+
+       ret = mysql_real_query(conn, query, query_len);
+       efree(query);
 
-               ret = mysql_real_query(conn, query, query_len);
-               efree(query);
+       if (ret && mode & (TRANS_START_READ_WRITE | TRANS_START_READ_ONLY) && mysql_errno(conn) == 1064) {
+               php_error_docref(NULL, E_WARNING, "This server version doesn't support 'READ WRITE' and 'READ ONLY'. Minimum 5.6.5 is required");
        }
        return ret;
 }
index dba65c0954c9362773c9a37f34136ac39ff30d94..2cd86dcf665d537b8d28125f429b60a59c0e520d 100644 (file)
@@ -2131,23 +2131,16 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_begin)(MYSQLND_CONN_DATA * conn, const unsi
                                }
                                smart_str_appendl(&tmp_str, "WITH CONSISTENT SNAPSHOT", sizeof("WITH CONSISTENT SNAPSHOT") - 1);
                        }
-                       if (mode & (TRANS_START_READ_WRITE | TRANS_START_READ_ONLY)) {
-                               zend_ulong server_version = conn->m->get_server_version(conn);
-                               if (server_version < 50605L) {
-                                       php_error_docref(NULL, E_WARNING, "This server version doesn't support 'READ WRITE' and 'READ ONLY'. Minimum 5.6.5 is required");
-                                       smart_str_free(&tmp_str);
-                                       break;
-                               } else if (mode & TRANS_START_READ_WRITE) {
-                                       if (tmp_str.s && ZSTR_LEN(tmp_str.s)) {
-                                               smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
-                                       }
-                                       smart_str_appendl(&tmp_str, "READ WRITE", sizeof("READ WRITE") - 1);
-                               } else if (mode & TRANS_START_READ_ONLY) {
-                                       if (tmp_str.s && ZSTR_LEN(tmp_str.s)) {
-                                               smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
-                                       }
-                                       smart_str_appendl(&tmp_str, "READ ONLY", sizeof("READ ONLY") - 1);
+                       if (mode & TRANS_START_READ_WRITE) {
+                               if (tmp_str.s && ZSTR_LEN(tmp_str.s)) {
+                                       smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
                                }
+                               smart_str_appendl(&tmp_str, "READ WRITE", sizeof("READ WRITE") - 1);
+                       } else if (mode & TRANS_START_READ_ONLY) {
+                               if (tmp_str.s && ZSTR_LEN(tmp_str.s)) {
+                                       smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
+                               }
+                               smart_str_appendl(&tmp_str, "READ ONLY", sizeof("READ ONLY") - 1);
                        }
                        smart_str_0(&tmp_str);
 
@@ -2166,6 +2159,11 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_begin)(MYSQLND_CONN_DATA * conn, const unsi
                                }
                                ret = conn->m->query(conn, query, query_len);
                                mnd_sprintf_free(query);
+                               if (ret && mode & (TRANS_START_READ_WRITE | TRANS_START_READ_ONLY) &&
+                                       mysqlnd_stmt_errno(conn) == 1064) {
+                                       php_error_docref(NULL, E_WARNING, "This server version doesn't support 'READ WRITE' and 'READ ONLY'. Minimum 5.6.5 is required");
+                                       break;
+                               }
                        }
                } while (0);
                conn->m->local_tx_end(conn, this_func, ret);