ID: 42548 Updated by: [EMAIL PROTECTED] Reported By: garethjo at usc dot edu Status: Assigned Bug Type: MySQLi related Operating System: Windows XP, Windows 2003 PHP Version: 5.2.4 Assigned To: georg New Comment:
See also http://dev.mysql.com/doc/refman/5.0/en/mysql-set-server-option.html Enabling multiple-statement support with MYSQL_OPTION_MULTI_STATEMENTS_ON does not have quite the same effect as enabling it by passing the CLIENT_MULTI_STATEMENTS flag to mysql_real_connect(): CLIENT_MULTI_STATEMENTS also enables CLIENT_MULTI_RESULTS. If you are using the CALL SQL statement in your programs, multiple-result support must be enabled; this means that MYSQL_OPTION_MULTI_STATEMENTS_ON by itself is insufficient to allow the use of CALL. Previous Comments: ------------------------------------------------------------------------ [2007-11-19 18:21:19] [EMAIL PROTECTED] The change to 5.2.4 was correct, previously the CLIENT_MULTI_STATEMENTS flag was actually inverted instead of reset, and as the default value for flags is 0 it was actually set, not reset, most of the time. Multiple statements are only temporarily enabled using the MYSQL_OPTION_MULTI_STATEMENTS_ON and _OFF arguments to mysql_set_server_option(). The problem here is that CLIENT_MULTI_STATEMENTS in mysql_real_connects() implicitly enables CLIENT_MULTI_RESULTS, too, but MYSQL_OPTION_MULTI_STATEMENTS_ON only enables multiple statements, *not* multiple results. So the solution is to always remove CLIENT_MULTI_STATEMENTS on connect but at the same time to always enable CLIENT_MULTI_RESULTS as this can't be modified later (patch against latest 5.2 CVS): $ cvs diff -u mysqli_api.c Index: mysqli_api.c =================================================================== RCS file: /repository/php-src/ext/mysqli/mysqli_api.c,v retrieving revision 1.118.2.22.2.18 diff -u -u -r1.118.2.22.2.18 mysqli_api.c --- mysqli_api.c 17 Oct 2007 08:19:50 -0000 1.118.2.22.2.18 +++ mysqli_api.c 19 Nov 2007 18:20:28 -0000 @@ -1438,6 +1438,8 @@ MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_INITIALIZED); + /* set some required options */ + flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */ /* remove some insecure options */ flags &= ~CLIENT_MULTI_STATEMENTS; /* don't allow multi_queries via connect parameter */ if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) { ------------------------------------------------------------------------ [2007-10-21 14:35:13] ajs at ictpro dot ch Will this bug be fixed in 5.2.5? Thanks... ------------------------------------------------------------------------ [2007-10-02 20:47:37] Al dot Smith at aeschi dot ch dot eu dot org Ok, so it turns out that this bug is amazingly easy to figure out. I just started looking at changes between 5.2.3 and 5.2.4 in ext/mysqli. It turns out that there really aren't many changes in the mysqli code, and of course one of them deals with the CLIENT_MULTI_STATEMENTS flag. Reverting this change between 5.2.3 and 5.2.4 means that 5.2.4 is once again able to do multi-queries. Goody gumdrops. diff -ur php-5.2.4-orig/ext/mysqli/mysqli_api.c php-5.2.4/ext/mysqli/mysqli_api.c --- php-5.2.4-orig/ext/mysqli/mysqli_api.c 2007-07-24 11:22:16.000000000 +0200 +++ php-5.2.4/ext/mysqli/mysqli_api.c 2007-10-02 22:43:49.000000000 +0200 @@ -1433,7 +1433,7 @@ MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_INITIALIZED); /* remove some insecure options */ - flags &= ~CLIENT_MULTI_STATEMENTS; /* don't allow multi_queries via connect parameter */ + flags ^= CLIENT_MULTI_STATEMENTS; /* don't allow multi_queries via connect parameter */ if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) { flags &= ~CLIENT_LOCAL_FILES; } ------------------------------------------------------------------------ [2007-09-12 16:42:58] garethjo at usc dot edu This is the example of the code from my initial bug report reworked to use the multi_query. It uses the same database setup script as the original script in the first bug report and produces the same error: //------------ BUG TEST START -------------------------- $mysqli = mysqli_init(); $mysqli->real_connect('localhost', 'root', 'root_pass', 'test'); if (mysqli_connect_errno()) { printf("Connect failed: %s\n", mysqli_connect_error()); exit(); } if($mysqli->multi_query ("CALL spGetProducts();")) { do { if($objResult = $mysqli->store_result()) { while($row = $objResult->fetch_assoc()) { print $row["strProductName"]." ".$row["douProductPrice"]."<br>\r\n"; } $objResult->close(); if($mysqli->more_results()) { print "------------------------<BR>"; } } else { print "no results found"; } }while ( $mysqli->next_result()); } else { print $mysqli->error; } $mysqli->close(); ?> ------------------------------------------------------------------------ [2007-09-12 08:55:24] uwendel at mysql dot com Your code snippets does not show proper usage of mysqli_multi_query(). Stored Procedures that return n result sets will return n + 1 result sets. In your case, it's two result sets to fetch and eat up before you can reuse the line. The error message from the server is exactly about that. Proper usage of mysqli_multi_query() looks like this: if (mysqli_multi_query($link, 'CALL p()')) { do { if ($res = mysqli_store_result($link)) { while ($row = mysqli_fetch_assoc($res)) var_dump($row); mysqli_free_result($res); } } while (mysqli_more_results($link) && mysqli_next_result($link)); } else { printf("Cannot call SP, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } I see you replacing mysqli_[real_]query() with mysqli_multi_query() but I do not see the more_results()/next_result() loop etc. You continue using the syntax for SPs which do not return a result set. Ulf ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/42548 -- Edit this bug report at http://bugs.php.net/?id=42548&edit=1