[wp-trac] [WordPress Trac] #28155: mysqli flush issues
WordPress Trac
noreply at wordpress.org
Tue May 6 22:03:33 UTC 2014
#28155: mysqli flush issues
--------------------------+-----------------------------
Reporter: soulseekah | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Database | Version: 3.9
Severity: normal | Keywords:
Focuses: |
--------------------------+-----------------------------
The `flush` method in `wpdb` is not correct for mysqli usage.
First of all `is_resource` does not work with `mysqli_result` instances.
Next, I'm getting a `"Commands out of sync; you can't run this command
now"` error when using resultsets in stored procedures. This is a known
issue with MySQLi and seems to occurr when trying to initiate a new query
when the old resultset has not been freed. So obviously I was expecting
`flush` to take care of the quirk.
Here's the test procedure;
{{{
-- Test procedure for out of sync mysqli commands
DROP PROCEDURE IF EXISTS `mysqli_sync_procedure`;
DELIMITER ;;
CREATE PROCEDURE `mysqli_sync_procedure`()
BEGIN
SELECT * FROM `wp_posts` LIMIT 1;
END;;
DELIMITER ;
}}}
Next, try running the following code:
{{{
global $wpdb;
$wpdb->get_results( 'CALL mysqli_sync_procedure' );
$wpdb->get_results( 'SELECT * FROM wp_posts LIMIT 1' );
}}}
You should get a bunch of `WordPress database error: [Commands out of
sync; you can't run this command now]` from other queries being executed.
This is because stored procedures have a second resultset which contains
the status: 'OK' or 'ERR'.
`flush` doesn't work as expected, first of all because `is_resource`
returns `false` for mysqli results, checking should probably be made using
`$this->result instanceof mysqli_result` instead.
Regardless, you'll find yourself against a new error `"Couldn't fetch
mysqli_result"` when trying to free any of the results. This happens even
if you don't use the procedure, but just call `flush()` between two
queries. This may have to do with how the results are never stored or used
to begin with (`mysqli_use_result`, `mysqli_store_result`).
A primitive fix in this case would be to use `while (
$this->dbh->more_results() ) $this->dbh->next_result();`, so that all
results are fetched, leaving no results to linger about.
A better fix would be sort out the correct usage of `use`/`store` and
`free` with MySQLi. See `resultmode` in
http://ru2.php.net/manual/en/mysqli.query.php where by default you can't
even call `free` on the result, because it's always STORED vs. USED. ("If
you use MYSQLI_USE_RESULT all subsequent calls will return error Commands
out of sync unless you call mysqli_free_result()").
So, to summarize, we have three issues with mysqli:
1. `is_resource` is not the correct way to identify mysqli results
2. stored procedures are not flushed correctly because of a second query
3. `free` cannot be called on results that were fetched with
`MYSQLI_STORE_RESULT` mode
Thoughts, ideas? I'm attaching a patch that flushes mysqli results by
fetching any lingering rows.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/28155>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list