WordPress.org

Make WordPress Core

Changeset 39921


Ignore:
Timestamp:
01/17/17 04:00:09 (6 months ago)
Author:
pento
Message:

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.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/upgrade.php

    r39754 r39921  
    22172217 
    22182218        // Clear the field and index arrays. 
    2219         $cfields = $indices = array(); 
     2219        $cfields = $indices = $indices_without_subparts = array(); 
    22202220 
    22212221        // Get all of the field names in the query from between the parentheses. 
     
    22902290 
    22912291                    // Parse the columns. Multiple columns are separated by a comma. 
    2292                     $index_columns = array_map( 'trim', explode( ',', $index_matches['index_columns'] ) ); 
     2292                    $index_columns = $index_columns_without_subparts = array_map( 'trim', explode( ',', $index_matches['index_columns'] ) ); 
    22932293 
    22942294                    // Normalize columns. 
    2295                     foreach ( $index_columns as &$index_column ) { 
     2295                    foreach ( $index_columns as $id => &$index_column ) { 
    22962296                        // Extract column name and number of indexed characters (sub_part). 
    22972297                        preg_match( 
     
    23202320                        $index_column = '`' . $index_column_matches['column_name'] . '`'; 
    23212321 
     2322                        // We don't need to add the subpart to $index_columns_without_subparts 
     2323                        $index_columns_without_subparts[ $id ] = $index_column; 
     2324 
    23222325                        // Append the optional sup part with the number of indexed characters. 
    23232326                        if ( isset( $index_column_matches['sub_part'] ) ) { 
     
    23282331                    // Build the normalized index definition and add it to the list of indices. 
    23292332                    $indices[] = "{$index_type} {$index_name} (" . implode( ',', $index_columns ) . ")"; 
     2333                    $indices_without_subparts[] = "{$index_type} {$index_name} (" . implode( ',', $index_columns_without_subparts ) . ")"; 
    23302334 
    23312335                    // Destroy no longer needed variables. 
    2332                     unset( $index_column, $index_column_matches, $index_matches, $index_type, $index_name, $index_columns ); 
     2336                    unset( $index_column, $index_column_matches, $index_matches, $index_type, $index_name, $index_columns, $index_columns_without_subparts ); 
    23332337 
    23342338                    break; 
     
    24472451                    // Add the field to the column list string. 
    24482452                    $index_columns .= '`' . $column_data['fieldname'] . '`'; 
    2449                     if ($column_data['subpart'] != '') { 
    2450                         $index_columns .= '('.$column_data['subpart'].')'; 
    2451                     } 
    24522453                } 
    24532454 
    2454                 // The alternative index string doesn't care about subparts 
    2455                 $alt_index_columns = preg_replace( '/\([^)]*\)/', '', $index_columns ); 
    2456  
    24572455                // Add the column list to the index create string. 
    2458                 $index_strings = array( 
    2459                     "$index_string ($index_columns)", 
    2460                     "$index_string ($alt_index_columns)", 
    2461                 ); 
    2462  
    2463                 foreach ( $index_strings as $index_string ) { 
    2464                     if ( ! ( ( $aindex = array_search( $index_string, $indices ) ) === false ) ) { 
    2465                         unset( $indices[ $aindex ] ); 
    2466                         break; 
    2467                     } 
     2456                $index_string .= " ($index_columns)"; 
     2457 
     2458                // Check if the index definition exists, ignoring subparts. 
     2459                if ( ! ( ( $aindex = array_search( $index_string, $indices_without_subparts ) ) === false ) ) { 
     2460                    // If the index already exists (even with different subparts), we don't need to create it. 
     2461                    unset( $indices_without_subparts[ $aindex ] ); 
     2462                    unset( $indices[ $aindex ] ); 
    24682463                } 
    24692464            } 
  • trunk/tests/phpunit/tests/dbdelta.php

    r38591 r39921  
    827827 
    828828    /** 
     829     * @ticket 34870 
     830     */ 
     831    function test_unchanged_key_lengths_do_not_recreate_index() { 
     832        global $wpdb; 
     833 
     834        $updates = dbDelta( 
     835            " 
     836            CREATE TABLE {$wpdb->prefix}dbdelta_test ( 
     837                id bigint(20) NOT NULL AUTO_INCREMENT, 
     838                column_1 varchar(255) NOT NULL, 
     839                column_2 text, 
     840                column_3 blob, 
     841                PRIMARY KEY  (id), 
     842                KEY key_1 (column_1(255)), 
     843                KEY compound_key (id,column_1), 
     844                FULLTEXT KEY fulltext_key (column_1) 
     845            ) ENGINE=MyISAM 
     846            ", false ); 
     847 
     848        $this->assertEmpty( $updates ); 
     849    } 
     850 
     851    /** 
     852     * @ticket 34870 
     853     */ 
     854    function test_changed_key_lengths_do_not_recreate_index() { 
     855        global $wpdb; 
     856 
     857        $updates = dbDelta( 
     858            " 
     859            CREATE TABLE {$wpdb->prefix}dbdelta_test ( 
     860                id bigint(20) NOT NULL AUTO_INCREMENT, 
     861                column_1 varchar(255) NOT NULL, 
     862                column_2 text, 
     863                column_3 blob, 
     864                PRIMARY KEY  (id), 
     865                KEY key_1 (column_1), 
     866                KEY compound_key (id,column_1), 
     867                KEY changing_key_length (column_1(20)), 
     868                FULLTEXT KEY fulltext_key (column_1) 
     869            ) ENGINE=MyISAM 
     870            " ); 
     871 
     872        $this->assertSame( array( 
     873            "Added index {$wpdb->prefix}dbdelta_test KEY `changing_key_length` (`column_1`(20))" 
     874        ), $updates ); 
     875 
     876        $updates = dbDelta( 
     877            " 
     878            CREATE TABLE {$wpdb->prefix}dbdelta_test ( 
     879                id bigint(20) NOT NULL AUTO_INCREMENT, 
     880                column_1 varchar(255) NOT NULL, 
     881                column_2 text, 
     882                column_3 blob, 
     883                PRIMARY KEY  (id), 
     884                KEY key_1 (column_1), 
     885                KEY compound_key (id,column_1), 
     886                KEY changing_key_length (column_1(50)), 
     887                FULLTEXT KEY fulltext_key (column_1) 
     888            ) ENGINE=MyISAM 
     889            " ); 
     890 
     891        $this->assertEmpty( $updates ); 
     892 
     893        $updates = dbDelta( 
     894            " 
     895            CREATE TABLE {$wpdb->prefix}dbdelta_test ( 
     896                id bigint(20) NOT NULL AUTO_INCREMENT, 
     897                column_1 varchar(255) NOT NULL, 
     898                column_2 text, 
     899                column_3 blob, 
     900                PRIMARY KEY  (id), 
     901                KEY key_1 (column_1), 
     902                KEY compound_key (id,column_1), 
     903                KEY changing_key_length (column_1(1)), 
     904                FULLTEXT KEY fulltext_key (column_1) 
     905            ) ENGINE=MyISAM 
     906            " ); 
     907 
     908        $this->assertEmpty( $updates ); 
     909 
     910        $updates = dbDelta( 
     911            " 
     912            CREATE TABLE {$wpdb->prefix}dbdelta_test ( 
     913                id bigint(20) NOT NULL AUTO_INCREMENT, 
     914                column_1 varchar(255) NOT NULL, 
     915                column_2 text, 
     916                column_3 blob, 
     917                PRIMARY KEY  (id), 
     918                KEY key_1 (column_1), 
     919                KEY compound_key (id,column_1), 
     920                KEY changing_key_length (column_1), 
     921                FULLTEXT KEY fulltext_key (column_1) 
     922            ) ENGINE=MyISAM 
     923            " ); 
     924 
     925        $this->assertEmpty( $updates ); 
     926    } 
     927 
     928    /** 
    829929     * @ticket 31679 
    830930     */ 
Note: See TracChangeset for help on using the changeset viewer.