Rework SHOW COLUMNS/INDEX/TABLE support

Wordpress 4 makes use of SHOW COLUMNS and SHOW TABLES in addition to
SHOW INDEX, both with and without the FULL modifier.  Implement support
for these statements using queries against INFORMATION_SCHEMA.

Some of these queries use lower-case versions of these statements,
such as "show tables like 'wp_flag_pictures'", so we make sure to
recognize both the upper- and lower-case versions.

This is based, in part, on the work of raptorz in the support forum at
https://wordpress.org/support/topic/upgrade-to-wp421-fail?replies=3#post-6886123

Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
This commit is contained in:
Kevin Locke
2015-06-03 01:03:54 -06:00
parent f97491346b
commit 6aea521bf2
2 changed files with 50 additions and 7 deletions

View File

@ -411,7 +411,7 @@
$sql = "SET NAMES 'utf8'";
}
// Load up upgrade and install functions as required
$begin = substr( $sql, 0, 3);
$begin = strtoupper( substr( $sql, 0, 3));
$search = array( 'SHO', 'ALT', 'DES', 'CRE', 'DRO');
if( in_array($begin, $search))
{

View File

@ -38,13 +38,40 @@
{
global $wpdb;
// SHOW INDEX emulation
if( 0 === strpos( $sql, 'SHOW INDEX'))
// Emulate SHOW commands
if( 0 === strpos( $sql, 'SHOW') || 0 === strpos( $sql, 'show'))
{
$logto = 'SHOWINDEX';
$pattern = '/SHOW INDEX FROM\s+(\w+)/';
preg_match( $pattern, $sql, $matches);
$table = $matches[1];
// SHOW COLUMNS emulation
if( preg_match('/SHOW\s+(FULL\s+)?COLUMNS\s+(?:FROM\s+|IN\s+)`?(\w+)`?(?:\s+LIKE\s+(.+)|\s+WHERE\s+(.+))?/i', $sql, $matches))
{
$logto = 'SHOWCOLUMN';
$full = $matches[1];
$table = $matches[2];
$like = $matches[3];
$where = $matches[4];
// Wrap as sub-query to emulate WHERE behavior
$sql = ($where ? 'SELECT * FROM (' : '').
'SELECT column_name as "Field",
data_type as "Type",'.($full ? '
NULL as "Collation",' : '').'
is_nullable as "Null",
\'\' as "Key",
column_default as "Default",
\'\' as "Extra"'.($full ? ',
\'select,insert,update,references\' as "Privileges",
\'\' as "Comment"' : '').'
FROM information_schema.columns
WHERE table_name = \''.$table.'\''.($like ? '
AND column_name LIKE '.$like : '').($where ? ') AS columns
WHERE '.$where : '').';';
}
// SHOW INDEX emulation
elseif( 0 === strpos( $sql, 'SHOW INDEX'))
{
$logto = 'SHOWINDEX';
$pattern = '/SHOW INDEX FROM\s+(\w+)/';
preg_match( $pattern, $sql, $matches);
$table = $matches[1];
$sql = 'SELECT bc.relname AS "Table",
CASE WHEN i.indisunique THEN \'0\' ELSE \'1\' END AS "Non_unique",
CASE WHEN i.indisprimary THEN \'PRIMARY\' WHEN bc.relname LIKE \'%usermeta\' AND ic.relname = \'umeta_key\'
@ -58,6 +85,22 @@ WHERE bc.oid = i.indrelid
AND a.attrelid = bc.oid
AND bc.relname = \''.$table.'\'
ORDER BY a.attname;';
}
// SHOW TABLES emulation
elseif( preg_match('/SHOW\s+(FULL\s+)?TABLES\s+(?:LIKE\s+(.+)|WHERE\s+(.+))?/i', $sql, $matches))
{
$logto = 'SHOWTABLES';
$full = $matches[1];
$like = $matches[2];
$where = $matches[3];
// Wrap as sub-query to emulate WHERE behavior
$sql = ($where ? 'SELECT * FROM (' : '').
'SELECT table_name as "Tables_in_'.$wpdb->dbname.'"'.($full ? ',
table_type AS "Table_type"' : '').'
FROM information_schema.tables'.($like ? '
WHERE table_name LIKE '.$like : '').($where ? ') AS tables
WHERE '.$where : '').';';
}
}
// Table alteration
elseif( 0 === strpos( $sql, 'ALTER TABLE'))