diff --git a/tests/WP_SQLite_Translator_Tests.php b/tests/WP_SQLite_Translator_Tests.php index 353b5b12..82ed6ecf 100644 --- a/tests/WP_SQLite_Translator_Tests.php +++ b/tests/WP_SQLite_Translator_Tests.php @@ -283,8 +283,8 @@ public function testShowCreateTable1() { `option_name` varchar(255) DEFAULT '', `option_value` text NOT NULL DEFAULT '', PRIMARY KEY (`ID`), - KEY `_tmp_table__composite` (`option_name`, `option_value`), - UNIQUE KEY `_tmp_table__option_name` (`option_name`) + KEY `composite` (`option_name`, `option_value`), + UNIQUE KEY `option_name` (`option_name`) );", $results[0]->{'Create Table'} ); @@ -312,8 +312,8 @@ public function testShowCreateTableQuoted() { `option_name` varchar(255) DEFAULT '', `option_value` text NOT NULL DEFAULT '', PRIMARY KEY (`ID`), - KEY `_tmp_table__composite` (`option_name`, `option_value`), - UNIQUE KEY `_tmp_table__option_name` (`option_name`) + KEY `composite` (`option_name`, `option_value`), + UNIQUE KEY `option_name` (`option_name`) );", $results[0]->{'Create Table'} ); @@ -365,12 +365,32 @@ public function testShowCreateTableWithAlterAndCreateIndex() { `option_name` smallint NOT NULL DEFAULT 14, `option_value` text NOT NULL DEFAULT \'\', PRIMARY KEY (`ID`), - KEY `_tmp_table__option_name` (`option_name`) + KEY `option_name` (`option_name`) );', $results[0]->{'Create Table'} ); } + public function testCreateTablseWithIdenticalIndexNames() { + $this->assertQuery( + "CREATE TABLE _tmp_table_a ( + ID BIGINT PRIMARY KEY AUTO_INCREMENT NOT NULL, + option_name VARCHAR(255) default '', + option_value TEXT NOT NULL, + KEY `option_name` (`option_name`) + );" + ); + + $this->assertQuery( + "CREATE TABLE _tmp_table_b ( + ID BIGINT PRIMARY KEY AUTO_INCREMENT NOT NULL, + option_name VARCHAR(255) default '', + option_value TEXT NOT NULL, + KEY `option_name` (`option_name`) + );" + ); + } + public function testShowCreateTableWithPrimaryKeyColumnsReverseOrdered() { $this->assertQuery( 'CREATE TABLE `_tmp_table` ( diff --git a/wp-includes/sqlite/class-wp-sqlite-translator.php b/wp-includes/sqlite/class-wp-sqlite-translator.php index 573c4691..12decc6e 100644 --- a/wp-includes/sqlite/class-wp-sqlite-translator.php +++ b/wp-includes/sqlite/class-wp-sqlite-translator.php @@ -898,8 +898,7 @@ private function execute_create_table() { if ( 'UNIQUE INDEX' === $index_type ) { $unique = 'UNIQUE '; } - $index_name = "{$table->name}__{$constraint->name}"; - + $index_name = $this->generate_index_name( $table->name, $constraint->name ); $this->execute_sqlite_query( "CREATE $unique INDEX \"$index_name\" ON \"{$table->name}\" (\"" . implode( '", "', $constraint->columns ) . '")' ); @@ -3081,7 +3080,7 @@ private function execute_alter() { } elseif ( 'ADD' === $op_type && $is_index_op ) { $key_name = $this->rewriter->consume()->value; $sqlite_index_type = $this->mysql_index_type_to_sqlite_type( $mysql_index_type ); - $sqlite_index_name = "{$this->table_name}__$key_name"; + $sqlite_index_name = $this->generate_index_name( $this->table_name, $key_name ); $this->rewriter->replace_all( array( new WP_SQLite_Token( 'CREATE', WP_SQLite_Token::TYPE_KEYWORD, WP_SQLite_Token::FLAG_KEYWORD_RESERVED ), @@ -3565,7 +3564,12 @@ private function get_key_definitions( $table_name, $columns ) { $key_definition[] = 'KEY'; - $key_definition[] = sprintf( '`%s`', $key['index']['name'] ); + // Remove the prefix from the index name if there is any. We use __ as a separator. + $index_name = strstr( $key['index']['name'], '__' ) + ? explode( '__', $key['index']['name'] )[1] + : $key['index']['name']; + + $key_definition[] = sprintf( '`%s`', $index_name ); $cols = array_map( function ( $column ) { @@ -4188,4 +4192,18 @@ public function rollback() { do_action( 'sqlite_transaction_query_executed', 'ROLLBACK', (bool) $this->last_exec_returned, $this->transaction_level ); return $this->last_exec_returned; } + + /** + * Create an index name consisting of table name and original index name. + * This is to avoid duplicate index names in SQLite. + * + * @param $table + * @param $original_index_name + * + * @return string + */ + private function generate_index_name( $table, $original_index_name ) { + // Strip the occurrences of 2 or more consecutive underscores to allow easier splitting on __ later. + return preg_replace( '/_{2,}/', '_', $table ) . '__' . $original_index_name; + } }