Make WordPress Core

Ticket #10404: 10404.patch_caseinsensitive_and_noindexname_compare

File 10404.patch_caseinsensitive_and_noindexname_compare, 5.5 KB (added by charlestonsw, 11 years ago)

Case insensitive index AND simple index with NO NAME patch (see comments for details)

Line 
1Index: upgrade.php
2===================================================================
3--- upgrade.php (revision 26316)
4+++ upgrade.php (working copy)
5@@ -1501,15 +1501,21 @@
6 }
7 
8 /**
9- * {@internal Missing Short Description}}
10+ * Create or update database tables based on analyis of SQL queries provided.
11  *
12- * {@internal Missing Long Description}}
13+ * Adding indices to tables should be in the form:
14+ * KEY <keyname> (<field list>)
15  *
16+ * Key name should be provided for all key types but is REQUIRED for compound keys such as KEY mycompoundkey (id,flda).
17+ *
18+ * Failure to create table indices with the proper syntax can produce duplicate keys which degrades performance during
19+ * record inserts and updates for the affected table.
20+ *
21  * @since 1.5.0
22  *
23- * @param unknown_type $queries
24- * @param unknown_type $execute
25- * @return unknown
26+ * @param string[] $queries single string or array of strings representing SQL queries
27+ * @param boolean $execute
28+ * @return string[]
29  */
30 function dbDelta( $queries = '', $execute = true ) {
31        global $wpdb;
32@@ -1577,7 +1583,11 @@
33                        preg_match("|^([^ ]*)|", trim($fld), $fvals);
34                        $fieldname = trim( $fvals[1], '`' );
35 
36-                       // Verify the found field name
37+                       // Verify the found field name,
38+            //
39+            // Field names do NOT have index commands on the query line.
40+            // Put those lines into the indices array for later inspection.
41+            //
42                        $validfield = true;
43                        switch (strtolower($fieldname)) {
44                        case '':
45@@ -1587,7 +1597,7 @@
46                        case 'unique':
47                        case 'key':
48                                $validfield = false;
49-                               $indices[] = trim(trim($fld), ", \n");
50+                               $indices[] = strtoupper(trim(trim($fld), ", \n"));
51                                break;
52                        }
53                        $fld = trim($fld);
54@@ -1655,20 +1665,38 @@
55                        }
56 
57                        // For each actual index in the index array
58+            // Build a create string to compare to the query
59+            //
60                        foreach ($index_ary as $index_name => $index_data) {
61-                               // Build a create string to compare to the query
62+                       
63+                // Initialize the string
64                                $index_string = '';
65+
66+                // Special Operator: PRIMARY
67+                //
68                                if ($index_name == 'PRIMARY') {
69                                        $index_string .= 'PRIMARY ';
70+
71+                // Special Operator UNIQUE
72+                //
73                                } else if($index_data['unique']) {
74                                        $index_string .= 'UNIQUE ';
75                                }
76+
77+                // All indices utilize the KEY operator
78+                //
79                                $index_string .= 'KEY ';
80+
81+                // Add the index name for all index types EXCEPT the PRIMARY index
82+                //
83                                if ($index_name != 'PRIMARY') {
84                                        $index_string .= $index_name;
85                                }
86+
87+                               // For each column in the index
88+                // Build the column definition (the part inside the parens)
89+                //
90                                $index_columns = '';
91-                               // For each column in the index
92                                foreach ($index_data['columns'] as $column_data) {
93                                        if ($index_columns != '') $index_columns .= ',';
94                                        // Add the field to the column list string
95@@ -1677,17 +1705,47 @@
96                                                $index_columns .= '('.$column_data['subpart'].')';
97                                        }
98                                }
99+
100                                // Add the column list to the index create string
101                                $index_string .= ' ('.$index_columns.')';
102-                               if (!(($aindex = array_search($index_string, $indices)) === false)) {
103+
104+                // Now go look to see if the index string we just built from the table meta data
105+                // matches any of the index build strings the user specified in the create table SQL
106+                // and REMOVE any that match from the "indices to be created" stack
107+                //
108+                // Start with the WP3.7.1 (and earlier) index string with the index name specified
109+                // KEY id (id)
110+                //
111+                               if (!(($aindex = array_search(strtoupper($index_string), $indices)) === false)) {
112                                        unset($indices[$aindex]);
113-                                       //echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">{$table}:<br />Found index:".$index_string."</pre>\n";
114-                               }
115-                               //else echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">{$table}:<br /><b>Did not find index:</b>".$index_string."<br />".print_r($indices, true)."</pre>\n";
116+
117+                // Check for a version where the optional index name was not specified (default to single column name)
118+                // KEY (id)
119+                //
120+                // Convert the string we are trying to match from KEY <fldname> (<fldname>) to KEY (<fldname>)
121+                //
122+                // Make sure the pattern matches KEY <something> (<something>) and
123+                // that the first <something> is identical to the second <something>
124+                //
125+                // If it does, strip out the first <something>\s+, then re-check for an index match.
126+                //
127+                               } else {
128+                    if (
129+                        ( preg_match('/(KEY\s+)(\w+)\s+(\((\w+)\))/',$index_string,$regex_matches) === 1 ) &&
130+                        ( $regex_matches[2] === $regex_matches[4] )
131+                        ) {
132+                        $index_string = $regex_matches[1].$regex_matches[3];
133+                        if (!(($aindex = array_search(strtoupper($index_string), $indices)) === false)) {
134+                            unset($indices[$aindex]);
135+                        }
136+                    }
137+                }
138+
139                        }
140                }
141 
142-               // For every remaining index specified for the table
143+        // Add the indices to the table.
144+        //
145                foreach ( (array) $indices as $index ) {
146                        // Push a query line into $cqueries that adds the index to that table
147                        $cqueries[] = "ALTER TABLE {$table} ADD $index";