Index: wp-includes/wp-db.php
===================================================================
--- wp-includes/wp-db.php	(revision 12583)
+++ wp-includes/wp-db.php	(working copy)
@@ -560,9 +560,12 @@
 		// If args were passed as an array (as in vsprintf), move them up
 		if ( isset($args[0]) && is_array($args[0]) )
 			$args = $args[0];
-		$query = str_replace("'%s'", '%s', $query); // in case someone mistakenly already singlequoted it
-		$query = str_replace('"%s"', '%s', $query); // doublequote unquoting
-		$query = str_replace('%s', "'%s'", $query); // quote the strings
+		// allow literal % to be entered as such
+		$query = str_replace('%', '%%', $query);
+		// leave things such as LIKE '%%stuff' or 'some %%stuff' untouched
+		// but catch mistakingly quoted strings such as '%%s'
+		$query = preg_replace("/(^|\s)(['\"]?)%%s\\2(\s|$)/", "$1'%d'$3", $query);
+		$query = preg_replace("/(^|\s)(['\"]?)%%d\\2(\s|$)/", "$1%d$3", $query);
 		array_walk($args, array(&$this, 'escape_by_ref'));
 		return @vsprintf($query, $args);
 	}
