Skip to content

Commit 658f32f

Browse files
authored
Fix unlimited key lengths issue (#168)
Fixes #167 I propose to fix an issue where dumping the table with keys that use multiple long fields produces SQL code that produces an error.
1 parent e1931d2 commit 658f32f

File tree

2 files changed

+72
-18
lines changed

2 files changed

+72
-18
lines changed

tests/WP_SQLite_Translator_Tests.php

+51-16
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,8 @@ public function testShowCreateTable1() {
267267
ID BIGINT PRIMARY KEY AUTO_INCREMENT NOT NULL,
268268
option_name VARCHAR(255) default '',
269269
option_value TEXT NOT NULL,
270-
UNIQUE KEY option_name (option_name),
271-
KEY composite (option_name, option_value)
270+
UNIQUE KEY option_name (option_name(100)),
271+
KEY composite (option_name(100), option_value(100))
272272
);"
273273
);
274274

@@ -283,8 +283,8 @@ public function testShowCreateTable1() {
283283
`option_name` varchar(255) DEFAULT '',
284284
`option_value` text NOT NULL DEFAULT '',
285285
PRIMARY KEY (`ID`),
286-
KEY `composite` (`option_name`, `option_value`),
287-
UNIQUE KEY `option_name` (`option_name`)
286+
KEY `composite` (`option_name`(100), `option_value`(100)),
287+
UNIQUE KEY `option_name` (`option_name`(100))
288288
);",
289289
$results[0]->{'Create Table'}
290290
);
@@ -337,8 +337,8 @@ public function testShowCreateTableQuoted() {
337337
ID BIGINT PRIMARY KEY AUTO_INCREMENT NOT NULL,
338338
option_name VARCHAR(255) default '',
339339
option_value TEXT NOT NULL,
340-
UNIQUE KEY option_name (option_name),
341-
KEY composite (option_name, option_value)
340+
UNIQUE KEY option_name (option_name(100)),
341+
KEY composite (option_name, option_value(100))
342342
);"
343343
);
344344

@@ -353,8 +353,8 @@ public function testShowCreateTableQuoted() {
353353
`option_name` varchar(255) DEFAULT '',
354354
`option_value` text NOT NULL DEFAULT '',
355355
PRIMARY KEY (`ID`),
356-
KEY `composite` (`option_name`, `option_value`),
357-
UNIQUE KEY `option_name` (`option_name`)
356+
KEY `composite` (`option_name`(100), `option_value`(100)),
357+
UNIQUE KEY `option_name` (`option_name`(100))
358358
);",
359359
$results[0]->{'Create Table'}
360360
);
@@ -418,8 +418,8 @@ public function testCreateTablseWithIdenticalIndexNames() {
418418
ID BIGINT PRIMARY KEY AUTO_INCREMENT NOT NULL,
419419
option_name VARCHAR(255) default '',
420420
option_value TEXT NOT NULL,
421-
KEY `option_name` (`option_name`),
422-
KEY `double__underscores` (`option_name`, `ID`)
421+
KEY `option_name` (`option_name`(100)),
422+
KEY `double__underscores` (`option_name`(100), `ID`)
423423
);"
424424
);
425425

@@ -428,8 +428,8 @@ public function testCreateTablseWithIdenticalIndexNames() {
428428
ID BIGINT PRIMARY KEY AUTO_INCREMENT NOT NULL,
429429
option_name VARCHAR(255) default '',
430430
option_value TEXT NOT NULL,
431-
KEY `option_name` (`option_name`),
432-
KEY `double__underscores` (`option_name`, `ID`)
431+
KEY `option_name` (`option_name`(100)),
432+
KEY `double__underscores` (`option_name`(100), `ID`)
433433
);"
434434
);
435435
}
@@ -440,8 +440,8 @@ public function testShowCreateTablePreservesDoubleUnderscoreKeyNames() {
440440
ID BIGINT PRIMARY KEY AUTO_INCREMENT NOT NULL,
441441
option_name VARCHAR(255) default '',
442442
option_value TEXT NOT NULL,
443-
KEY `option_name` (`option_name`),
444-
KEY `double__underscores` (`option_name`, `ID`)
443+
KEY `option_name` (`option_name`(100)),
444+
KEY `double__underscores` (`option_name`(100), `ID`)
445445
);"
446446
);
447447

@@ -455,8 +455,43 @@ public function testShowCreateTablePreservesDoubleUnderscoreKeyNames() {
455455
`option_name` varchar(255) DEFAULT \'\',
456456
`option_value` text NOT NULL DEFAULT \'\',
457457
PRIMARY KEY (`ID`),
458-
KEY `double__underscores` (`option_name`, `ID`),
459-
KEY `option_name` (`option_name`)
458+
KEY `double__underscores` (`option_name`(100), `ID`),
459+
KEY `option_name` (`option_name`(100))
460+
);',
461+
$results[0]->{'Create Table'}
462+
);
463+
}
464+
465+
public function testShowCreateTableLimitsKeyLengths() {
466+
$this->assertQuery(
467+
'CREATE TABLE _tmp__table (
468+
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
469+
`order_id` bigint(20) unsigned DEFAULT NULL,
470+
`meta_key` varchar(20) DEFAULT NULL,
471+
`meta_value` text DEFAULT NULL,
472+
`meta_data` mediumblob DEFAULT NULL,
473+
PRIMARY KEY (`id`),
474+
KEY `meta_key_value` (`meta_key`(20),`meta_value`(82)),
475+
KEY `order_id_meta_key_meta_value` (`order_id`,`meta_key`(100),`meta_value`(82)),
476+
KEY `order_id_meta_key_meta_data` (`order_id`,`meta_key`(100),`meta_data`(100))
477+
);'
478+
);
479+
480+
$this->assertQuery(
481+
'SHOW CREATE TABLE _tmp__table;'
482+
);
483+
$results = $this->engine->get_query_results();
484+
$this->assertEquals(
485+
'CREATE TABLE `_tmp__table` (
486+
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
487+
`order_id` bigint(20) unsigned DEFAULT NULL,
488+
`meta_key` varchar(20) DEFAULT NULL,
489+
`meta_value` text DEFAULT NULL,
490+
`meta_data` mediumblob DEFAULT NULL,
491+
PRIMARY KEY (`id`),
492+
KEY `order_id_meta_key_meta_data` (`order_id`, `meta_key`(20), `meta_data`(100)),
493+
KEY `order_id_meta_key_meta_value` (`order_id`, `meta_key`(20), `meta_value`(100)),
494+
KEY `meta_key_value` (`meta_key`(20), `meta_value`(100))
460495
);',
461496
$results[0]->{'Create Table'}
462497
);

wp-includes/sqlite/class-wp-sqlite-translator.php

+21-2
Original file line numberDiff line numberDiff line change
@@ -3725,7 +3725,8 @@ protected function get_column_definitions( $table_name, $columns ) {
37253725
* @return array An array of key definitions
37263726
*/
37273727
private function get_key_definitions( $table_name, $columns ) {
3728-
$key_definitions = array();
3728+
$key_length_limit = 100;
3729+
$key_definitions = array();
37293730

37303731
$pks = array();
37313732
foreach ( $columns as $column ) {
@@ -3756,7 +3757,25 @@ private function get_key_definitions( $table_name, $columns ) {
37563757
$key_definition[] = sprintf( '`%s`', $index_name );
37573758

37583759
$cols = array_map(
3759-
function ( $column ) {
3760+
function ( $column ) use ( $table_name, $key_length_limit ) {
3761+
$data_type = strtolower( $this->get_cached_mysql_data_type( $table_name, $column['name'] ) );
3762+
$data_length = $key_length_limit;
3763+
3764+
// Extract the length from the data type. Make it lower if needed. Skip 'unsigned' parts and whitespace.
3765+
if ( 1 === preg_match( '/^(\w+)\s*\(\s*(\d+)\s*\)/', $data_type, $matches ) ) {
3766+
$data_type = $matches[1]; // "varchar"
3767+
$data_length = min( $matches[2], $key_length_limit ); // "255"
3768+
}
3769+
3770+
// Set the data length to the varchar and text key lengths
3771+
// char, varchar, varbinary, tinyblob, tinytext, blob, text, mediumblob, mediumtext, longblob, longtext
3772+
if ( str_ends_with( $data_type, 'char' ) ||
3773+
str_ends_with( $data_type, 'text' ) ||
3774+
str_ends_with( $data_type, 'blob' ) ||
3775+
str_starts_with( $data_type, 'var' )
3776+
) {
3777+
return sprintf( '`%s`(%s)', $column['name'], $data_length );
3778+
}
37603779
return sprintf( '`%s`', $column['name'] );
37613780
},
37623781
$key['columns']

0 commit comments

Comments
 (0)