Skip to content

Commit

Permalink
Support multi-value column type modifiers for `_mysql_data_types_cach…
Browse files Browse the repository at this point in the history
…e` (#126)

Fixes: #122 

This fix will skip over tokens until it finds the closing bracket of the
type modifier `)` instead of consuming exactly 3. This should account
for data types that support more than one value as a modifier, such as:
enum, float, decimal, double.

Additionally, I've added support for enums. There are plugins that use
enum fields and it makes sense to convert those to text in SQLite.

## Testing instructions
Confirm the tests pass
  • Loading branch information
jeroenpf authored Jul 18, 2024
1 parent b74ae19 commit d24fff8
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 4 deletions.
54 changes: 54 additions & 0 deletions tests/WP_SQLite_Translator_Tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,60 @@ public function testCreateTableSpatialIndex() {
$this->assertEquals( 1, $result );
}

public function testCreateTableWithMultiValueColumnTypeModifiers() {
$result = $this->assertQuery(
"CREATE TABLE wptests_users (
ID bigint(20) unsigned NOT NULL auto_increment,
decimal_column DECIMAL(10,2) NOT NULL DEFAULT 0,
float_column FLOAT(10,2) NOT NULL DEFAULT 0,
enum_column ENUM('a', 'b', 'c') NOT NULL DEFAULT 'a',
PRIMARY KEY (ID),
)"
);
$this->assertEquals( '', $this->engine->get_error_message() );
$this->assertEquals( 1, $result );

$this->assertQuery( 'DESCRIBE wptests_users;' );
$results = $this->engine->get_query_results();
$this->assertEquals(
array(
(object) array(
'Field' => 'ID',
'Type' => 'bigint(20) unsigned',
'Null' => 'NO',
'Key' => 'PRI',
'Default' => '0',
'Extra' => '',
),
(object) array(
'Field' => 'decimal_column',
'Type' => 'decimal(10,2)',
'Null' => 'NO',
'Key' => '',
'Default' => 0,
'Extra' => '',
),
(object) array(
'Field' => 'float_column',
'Type' => 'float(10,2)',
'Null' => 'NO',
'Key' => '',
'Default' => 0,
'Extra' => '',
),
(object) array(
'Field' => 'enum_column',
'Type' => "enum('a','b','c')",
'Null' => 'NO',
'Key' => '',
'Default' => 'a',
'Extra' => '',
),
),
$results
);
}

public function testAlterTableAddColumn() {
$result = $this->assertQuery(
"CREATE TABLE _tmp_table (
Expand Down
15 changes: 11 additions & 4 deletions wp-includes/sqlite/class-wp-sqlite-translator.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class WP_SQLite_Translator {
'double' => 'real',
'decimal' => 'real',
'dec' => 'real',
'enum' => 'text',
'numeric' => 'real',
'fixed' => 'real',
'date' => 'text',
Expand Down Expand Up @@ -3556,12 +3557,18 @@ private function skip_mysql_data_type() {

$sqlite_data_type = $this->field_types_translation[ $mysql_data_type ];

// Skip the length, e.g. (10) in VARCHAR(10).
// Skip the type modifier, e.g. (20) for varchar(20) or (10,2) for decimal(10,2).
$paren_maybe = $this->rewriter->peek();
if ( $paren_maybe && '(' === $paren_maybe->token ) {
$mysql_data_type .= $this->rewriter->skip()->token;
$mysql_data_type .= $this->rewriter->skip()->token;
$mysql_data_type .= $this->rewriter->skip()->token;
$mysql_data_type .= $this->rewriter->skip()->token; // Skip '(' and add it to the data type

// Loop to capture everything until the closing parenthesis ')'
while ( $token = $this->rewriter->skip() ) {
$mysql_data_type .= $token->token;
if ( ')' === $token->token ) {
break;
}
}
}

// Skip the int keyword.
Expand Down

0 comments on commit d24fff8

Please sign in to comment.