@@ -2184,10 +2184,11 @@ function dbDelta( $queries = '', $execute = true ) {
2184
2184
$ flds = explode ("\n" , $ qryline );
2185
2185
2186
2186
// For every field line specified in the query.
2187
- foreach ($ flds as $ fld ) {
2187
+ foreach ( $ flds as $ fld ) {
2188
+ $ fld = trim ( $ fld , " \t\n\r\0\x0B, " ); // Default trim characters, plus ','.
2188
2189
2189
2190
// Extract the field name.
2190
- preg_match (" |^([^ ]*)| " , trim ( $ fld) , $ fvals );
2191
+ preg_match ( ' |^([^ ]*)| ' , $ fld , $ fvals );
2191
2192
$ fieldname = trim ( $ fvals [1 ], '` ' );
2192
2193
$ fieldname_lowercased = strtolower ( $ fieldname );
2193
2194
@@ -2202,14 +2203,98 @@ function dbDelta( $queries = '', $execute = true ) {
2202
2203
case 'key ' :
2203
2204
case 'spatial ' :
2204
2205
$ validfield = false ;
2205
- $ indices [] = trim (trim ($ fld ), ", \n" );
2206
+
2207
+ /*
2208
+ * Normalize the index definition.
2209
+ *
2210
+ * This is done so the definition can be compared against the result of a
2211
+ * `SHOW INDEX FROM $table_name` query which returns the current table
2212
+ * index information.
2213
+ */
2214
+
2215
+ // Extract type, name and columns from the definition.
2216
+ preg_match (
2217
+ '/^ '
2218
+ . '(?P<index_type> ' // 1) Type of the index.
2219
+ . 'PRIMARY\s+KEY|(?:UNIQUE|FULLTEXT|SPATIAL)\s+(?:KEY|INDEX)|KEY|INDEX '
2220
+ . ') '
2221
+ . '\s+ ' // Followed by at least one white space character.
2222
+ . '(?: ' // Name of the index. Optional if type is PRIMARY KEY.
2223
+ . '`? ' // Name can be escaped with a backtick.
2224
+ . '(?P<index_name> ' // 2) Name of the index.
2225
+ . '(?:[0-9a-zA-Z$_-]|[\xC2-\xDF][\x80-\xBF])+ '
2226
+ . ') '
2227
+ . '`? ' // Name can be escaped with a backtick.
2228
+ . '\s+ ' // Followed by at least one white space character.
2229
+ . ')* '
2230
+ . '\( ' // Opening bracket for the columns.
2231
+ . '(?P<index_columns> '
2232
+ . '.+? ' // 3) Column names, index prefixes, and orders.
2233
+ . ') '
2234
+ . '\) ' // Closing bracket for the columns.
2235
+ . '$/im ' ,
2236
+ $ fld ,
2237
+ $ index_matches
2238
+ );
2239
+
2240
+ // Uppercase the index type and normalize space characters.
2241
+ $ index_type = strtoupper ( preg_replace ( '/\s+/ ' , ' ' , trim ( $ index_matches ['index_type ' ] ) ) );
2242
+
2243
+ // 'INDEX' is a synonym for 'KEY', standardize on 'KEY'.
2244
+ $ index_type = str_replace ( 'INDEX ' , 'KEY ' , $ index_type );
2245
+
2246
+ // Escape the index name with backticks. An index for a primary key has no name.
2247
+ $ index_name = ( 'PRIMARY KEY ' === $ index_type ) ? '' : '` ' . $ index_matches ['index_name ' ] . '` ' ;
2248
+
2249
+ // Parse the columns. Multiple columns are separated by a comma.
2250
+ $ index_columns = array_map ( 'trim ' , explode ( ', ' , $ index_matches ['index_columns ' ] ) );
2251
+
2252
+ // Normalize columns.
2253
+ foreach ( $ index_columns as &$ index_column ) {
2254
+ // Extract column name and number of indexed characters (sub_part).
2255
+ preg_match (
2256
+ '/ '
2257
+ . '`? ' // Name can be escaped with a backtick.
2258
+ . '(?P<column_name> ' // 1) Name of the column.
2259
+ . '(?:[0-9a-zA-Z$_-]|[\xC2-\xDF][\x80-\xBF])+ '
2260
+ . ') '
2261
+ . '`? ' // Name can be escaped with a backtick.
2262
+ . '(?: ' // Optional sub part.
2263
+ . '\s* ' // Optional white space character between name and opening bracket.
2264
+ . '\( ' // Opening bracket for the sub part.
2265
+ . '\s* ' // Optional white space character after opening bracket.
2266
+ . '(?P<sub_part> '
2267
+ . '\d+ ' // 2) Number of indexed characters.
2268
+ . ') '
2269
+ . '\s* ' // Optional white space character before closing bracket.
2270
+ . '\) ' // Closing bracket for the sub part.
2271
+ . ')? '
2272
+ . '/ ' ,
2273
+ $ index_column ,
2274
+ $ index_column_matches
2275
+ );
2276
+
2277
+ // Escape the column name with backticks.
2278
+ $ index_column = '` ' . $ index_column_matches ['column_name ' ] . '` ' ;
2279
+
2280
+ // Append the optional sup part with the number of indexed characters.
2281
+ if ( isset ( $ index_column_matches ['sub_part ' ] ) ) {
2282
+ $ index_column .= '( ' . $ index_column_matches ['sub_part ' ] . ') ' ;
2283
+ }
2284
+ }
2285
+
2286
+ // Build the normalized index definition and add it to the list of indices.
2287
+ $ indices [] = "{$ index_type } {$ index_name } ( " . implode ( ', ' , $ index_columns ) . ") " ;
2288
+
2289
+ // Destroy no longer needed variables.
2290
+ unset( $ index_column , $ index_column_matches , $ index_matches , $ index_type , $ index_name , $ index_columns );
2291
+
2206
2292
break ;
2207
2293
}
2208
- $ fld = trim ( $ fld );
2209
2294
2210
2295
// If it's a valid field, add it to the field array.
2211
2296
if ( $ validfield ) {
2212
- $ cfields [ $ fieldname_lowercased ] = trim ( $ fld, " , \n" ) ;
2297
+ $ cfields [ $ fieldname_lowercased ] = $ fld ;
2213
2298
}
2214
2299
}
2215
2300
@@ -2243,7 +2328,7 @@ function dbDelta( $queries = '', $execute = true ) {
2243
2328
2244
2329
if ( $ do_change ) {
2245
2330
// Add a query to change the column type.
2246
- $ cqueries [] = "ALTER TABLE {$ table } CHANGE COLUMN {$ tablefield ->Field } " . $ cfields [ $ tablefield_field_lowercased ];
2331
+ $ cqueries [] = "ALTER TABLE {$ table } CHANGE COLUMN ` {$ tablefield ->Field }` " . $ cfields [ $ tablefield_field_lowercased ];
2247
2332
$ for_update [$ table .'. ' .$ tablefield ->Field ] = "Changed type of {$ table }. {$ tablefield ->Field } from {$ tablefield ->Type } to {$ fieldtype }" ;
2248
2333
}
2249
2334
}
@@ -2253,7 +2338,7 @@ function dbDelta( $queries = '', $execute = true ) {
2253
2338
$ default_value = $ matches [1 ];
2254
2339
if ($ tablefield ->Default != $ default_value ) {
2255
2340
// Add a query to change the column's default value
2256
- $ cqueries [] = "ALTER TABLE {$ table } ALTER COLUMN {$ tablefield ->Field } SET DEFAULT ' {$ default_value }' " ;
2341
+ $ cqueries [] = "ALTER TABLE {$ table } ALTER COLUMN ` {$ tablefield ->Field }` SET DEFAULT ' {$ default_value }' " ;
2257
2342
$ for_update [$ table .'. ' .$ tablefield ->Field ] = "Changed default value of {$ table }. {$ tablefield ->Field } from {$ tablefield ->Default } to {$ default_value }" ;
2258
2343
}
2259
2344
}
@@ -2306,17 +2391,19 @@ function dbDelta( $queries = '', $execute = true ) {
2306
2391
$ index_string .= 'SPATIAL ' ;
2307
2392
}
2308
2393
$ index_string .= 'KEY ' ;
2309
- if ($ index_name != 'PRIMARY ' ) {
2310
- $ index_string .= $ index_name ;
2394
+ if ( 'PRIMARY ' !== $ index_name ) {
2395
+ $ index_string .= ' ` ' . $ index_name . ' ` ' ;
2311
2396
}
2312
2397
$ index_columns = '' ;
2313
2398
2314
2399
// For each column in the index.
2315
2400
foreach ($ index_data ['columns ' ] as $ column_data ) {
2316
- if ($ index_columns != '' ) $ index_columns .= ', ' ;
2401
+ if ( $ index_columns != '' ) {
2402
+ $ index_columns .= ', ' ;
2403
+ }
2317
2404
2318
2405
// Add the field to the column list string.
2319
- $ index_columns .= $ column_data ['fieldname ' ];
2406
+ $ index_columns .= ' ` ' . $ column_data ['fieldname ' ] . ' ` ' ;
2320
2407
if ($ column_data ['subpart ' ] != '' ) {
2321
2408
$ index_columns .= '( ' .$ column_data ['subpart ' ].') ' ;
2322
2409
}
0 commit comments