dbDelta: Ignore index subparts when checking for duplicate indices.

If index lengths change in table definitions, we don't recreate the index - instead, we throw a database error, as `dbDelta()` tries to create a new index with the same name.

It's better to leave the index as is, MySQL doesn't have an efficient process for resizing indices, and dropping/creating is a slow process which we don't want to trigger automatically.

Fixes #34870.


Built from https://develop.svn.wordpress.org/trunk@39921


git-svn-id: http://core.svn.wordpress.org/trunk@39858 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Gary Pendergast 2017-01-17 04:01:42 +00:00
parent 3c1ce66767
commit 096b09d941
2 changed files with 15 additions and 20 deletions

View File

@ -2216,7 +2216,7 @@ function dbDelta( $queries = '', $execute = true ) {
continue; continue;
// Clear the field and index arrays. // Clear the field and index arrays.
$cfields = $indices = array(); $cfields = $indices = $indices_without_subparts = array();
// Get all of the field names in the query from between the parentheses. // Get all of the field names in the query from between the parentheses.
preg_match("|\((.*)\)|ms", $qry, $match2); preg_match("|\((.*)\)|ms", $qry, $match2);
@ -2289,10 +2289,10 @@ function dbDelta( $queries = '', $execute = true ) {
$index_name = ( 'PRIMARY KEY' === $index_type ) ? '' : '`' . strtolower( $index_matches['index_name'] ) . '`'; $index_name = ( 'PRIMARY KEY' === $index_type ) ? '' : '`' . strtolower( $index_matches['index_name'] ) . '`';
// Parse the columns. Multiple columns are separated by a comma. // Parse the columns. Multiple columns are separated by a comma.
$index_columns = array_map( 'trim', explode( ',', $index_matches['index_columns'] ) ); $index_columns = $index_columns_without_subparts = array_map( 'trim', explode( ',', $index_matches['index_columns'] ) );
// Normalize columns. // Normalize columns.
foreach ( $index_columns as &$index_column ) { foreach ( $index_columns as $id => &$index_column ) {
// Extract column name and number of indexed characters (sub_part). // Extract column name and number of indexed characters (sub_part).
preg_match( preg_match(
'/' '/'
@ -2319,6 +2319,9 @@ function dbDelta( $queries = '', $execute = true ) {
// Escape the column name with backticks. // Escape the column name with backticks.
$index_column = '`' . $index_column_matches['column_name'] . '`'; $index_column = '`' . $index_column_matches['column_name'] . '`';
// We don't need to add the subpart to $index_columns_without_subparts
$index_columns_without_subparts[ $id ] = $index_column;
// Append the optional sup part with the number of indexed characters. // Append the optional sup part with the number of indexed characters.
if ( isset( $index_column_matches['sub_part'] ) ) { if ( isset( $index_column_matches['sub_part'] ) ) {
$index_column .= '(' . $index_column_matches['sub_part'] . ')'; $index_column .= '(' . $index_column_matches['sub_part'] . ')';
@ -2327,9 +2330,10 @@ function dbDelta( $queries = '', $execute = true ) {
// Build the normalized index definition and add it to the list of indices. // Build the normalized index definition and add it to the list of indices.
$indices[] = "{$index_type} {$index_name} (" . implode( ',', $index_columns ) . ")"; $indices[] = "{$index_type} {$index_name} (" . implode( ',', $index_columns ) . ")";
$indices_without_subparts[] = "{$index_type} {$index_name} (" . implode( ',', $index_columns_without_subparts ) . ")";
// Destroy no longer needed variables. // Destroy no longer needed variables.
unset( $index_column, $index_column_matches, $index_matches, $index_type, $index_name, $index_columns ); unset( $index_column, $index_column_matches, $index_matches, $index_type, $index_name, $index_columns, $index_columns_without_subparts );
break; break;
} }
@ -2446,25 +2450,16 @@ function dbDelta( $queries = '', $execute = true ) {
// Add the field to the column list string. // Add the field to the column list string.
$index_columns .= '`' . $column_data['fieldname'] . '`'; $index_columns .= '`' . $column_data['fieldname'] . '`';
if ($column_data['subpart'] != '') {
$index_columns .= '('.$column_data['subpart'].')';
}
} }
// The alternative index string doesn't care about subparts
$alt_index_columns = preg_replace( '/\([^)]*\)/', '', $index_columns );
// Add the column list to the index create string. // Add the column list to the index create string.
$index_strings = array( $index_string .= " ($index_columns)";
"$index_string ($index_columns)",
"$index_string ($alt_index_columns)",
);
foreach ( $index_strings as $index_string ) { // Check if the index definition exists, ignoring subparts.
if ( ! ( ( $aindex = array_search( $index_string, $indices ) ) === false ) ) { if ( ! ( ( $aindex = array_search( $index_string, $indices_without_subparts ) ) === false ) ) {
unset( $indices[ $aindex ] ); // If the index already exists (even with different subparts), we don't need to create it.
break; unset( $indices_without_subparts[ $aindex ] );
} unset( $indices[ $aindex ] );
} }
} }
} }

View File

@ -4,7 +4,7 @@
* *
* @global string $wp_version * @global string $wp_version
*/ */
$wp_version = '4.8-alpha-39920'; $wp_version = '4.8-alpha-39921';
/** /**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.