Rewrite multi-table delete of wp_options

During schema upgrade, populate_options() deletes all expired transients
and their corresponding transient timeouts.  The queries produce the
following errors:

Error running :
DELETE a, b FROM wp_options a, wp_options b
		WHERE a.option_name LIKE '\_transient\_%'
		AND a.option_name NOT LIKE '\_transient\_timeout\_%'
		AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
		AND b.option_value < 1433110465
---- converted to ----
DELETE a, b FROM wp_options a, wp_options b
		WHERE a.option_name LIKE '\_transient\_%'
		AND a.option_name NOT LIKE '\_transient\_timeout\_%'
		AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
		AND b.option_value < 1433110465
----> ERROR:  syntax error at or near "a"
LINE 1: DELETE a, b FROM wp_options a, wp_options b
               ^
---------------------
Error running :
DELETE a, b FROM wp_options a, wp_options b
			WHERE a.option_name LIKE '\_site\_transient\_%'
			AND a.option_name NOT LIKE '\_site\_transient\_timeout\_%'
			AND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) )
			AND b.option_value < 1433110465
---- converted to ----
DELETE a, b FROM wp_options a, wp_options b
			WHERE a.option_name LIKE '\_site\_transient\_%'
			AND a.option_name NOT LIKE '\_site\_transient\_timeout\_%'
			AND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) )
			AND b.option_value < 1433110465
----> ERROR:  syntax error at or near "a"
LINE 1: DELETE a, b FROM wp_options a, wp_options b
               ^
---------------------

Since PostgreSQL does not support multi-table DELETE statements,
significant rewriting must be done.  Since I could not think of a good
generic way to perform this rewriting, recognize this statement
specifically and provide an alternative version.

Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
This commit is contained in:
Kevin Locke
2015-06-03 00:42:27 -06:00
parent 3c98f08453
commit 935a99c429

View File

@@ -375,6 +375,18 @@
"(SELECT o1.option_id FROM $wpdb->options AS o1, $wpdb->options AS o2 " .
"WHERE o1.option_name = o2.option_name " .
"AND o1.option_id < o2.option_id)";
// Rewrite _transient_timeout multi-table delete query
elseif( 0 === strpos( $sql, 'DELETE a, b FROM wp_options a, wp_options b'))
{
$where = substr( $sql, strpos($sql, 'WHERE ') + 6);
$where = rtrim( $where, " \t\n\r;");
// Fix string/number comparison by adding check and cast
$where = str_replace( 'AND b.option_value', 'AND b.option_value ~ \'^[0-9]+$\' AND CAST(b.option_value AS BIGINT)', $where);
// Mirror WHERE clause to delete both sides of self-join.
$where2 = strtr( $where, array('a.' => 'b.', 'b.' => 'a.'));
$sql = 'DELETE FROM wp_options a USING wp_options b WHERE '.
'('.$where.') OR ('.$where2.');';
}
// Akismet sometimes doesn't write 'comment_ID' with 'ID' in capitals where needed ...
if( false !== strpos( $sql, $wpdb->comments))