Skip to content

Commit

Permalink
Implement altering column with SET DEFAULT and DROP DEFAULT
Browse files Browse the repository at this point in the history
  • Loading branch information
JanJakes committed Aug 15, 2024
1 parent b29518a commit c330962
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 0 deletions.
88 changes: 88 additions & 0 deletions tests/WP_SQLite_Translator_Tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -3056,6 +3056,94 @@ public function testSelectVariable( $variable_name ) {
$this->assertQuery( "SELECT $variable_name;" );
}

public function testAlterColumnSetAndDropDefault() {
$this->assertQuery(
'CREATE TABLE _tmp_table (
name varchar(20) NOT NULL
);'
);
$result = $this->assertQuery( 'DESCRIBE _tmp_table' );
$this->assertEquals(
array(
(object) array(
'Field' => 'name',
'Type' => 'varchar(20)',
'Null' => 'NO',
'Key' => '',
'Default' => '',
'Extra' => '',
),
),
$result
);

// SET DEFAULT
$this->assertQuery( "ALTER TABLE _tmp_table ALTER COLUMN name SET DEFAULT 'abc'" );
$result = $this->assertQuery( 'DESCRIBE _tmp_table' );
$this->assertEquals(
array(
(object) array(
'Field' => 'name',
'Type' => 'varchar(20)',
'Null' => 'NO',
'Key' => '',
'Default' => 'abc',
'Extra' => '',
),
),
$result
);

// DROP DEFAULT
$this->assertQuery( 'ALTER TABLE _tmp_table ALTER COLUMN name DROP DEFAULT' );
$result = $this->assertQuery( 'DESCRIBE _tmp_table' );
$this->assertEquals(
array(
(object) array(
'Field' => 'name',
'Type' => 'varchar(20)',
'Null' => 'NO',
'Key' => '',
'Default' => '',
'Extra' => '',
),
),
$result
);

// multiple ALTER statements, with and without the COLUMN keyword
$this->assertQuery( "ALTER TABLE _tmp_table ADD COLUMN value varchar(255) DEFAULT 'aaa'" );
$this->assertQuery(
"ALTER TABLE _tmp_table
ALTER name SET DEFAULT 'bbb',
ALTER COLUMN name DROP DEFAULT,
ALTER value DROP DEFAULT,
ALTER COLUMN name SET DEFAULT 'ccc'"
);
$result = $this->assertQuery( 'DESCRIBE _tmp_table' );
$this->assertEquals(
array(
(object) array(
'Field' => 'name',
'Type' => 'varchar(20)',
'Null' => 'NO',
'Key' => '',
'Default' => '',
'Extra' => '',
),
(object) array(
'Field' => 'value',
'Type' => 'varchar(255)',
'Null' => 'YES',
'Key' => '',
'Default' => 'aaa',
'Extra' => '',
),
),
$result
);
}

public static function mysqlVariablesToTest() {
return array(
// NOTE: This list was derived from the variables used by the UpdraftPlus plugin.
Expand Down
64 changes: 64 additions & 0 deletions wp-includes/sqlite/class-wp-sqlite-translator.php
Original file line number Diff line number Diff line change
Expand Up @@ -3081,6 +3081,70 @@ function ( $old_name ) use ( $from_name, $new_field ) {
}
// We're done.
break;
} elseif ( 'ALTER' === $op_type ) {
$raw_from_name = 'COLUMN' === $op_subject ? $this->rewriter->skip()->token : $op_raw_subject;
$from_name = $this->normalize_column_name( $raw_from_name );

$set_or_drop_default = $this->rewriter->peek()->matches(
WP_SQLite_Token::TYPE_KEYWORD,
WP_SQLite_Token::FLAG_KEYWORD_RESERVED,
array( 'SET', 'DROP' )
) && $this->rewriter->peek_nth( 2 )->matches(
WP_SQLite_Token::TYPE_KEYWORD,
WP_SQLite_Token::FLAG_KEYWORD_RESERVED,
array( 'DEFAULT' )
);

// Handle "CHANGE <column> DROP DEFAULT" and "CHANGE <column> SET DEFAULT <value>".
if ( $set_or_drop_default ) {
$this->execute_change(
function ( $old_name, $old_column ) use ( $from_name ) {
//$old_column->consume_all();
//var_dump($old_column->get_updated_query());ob_flush();
//$old_column->replace_all([]);
if ( $from_name !== $old_name ) {
return null;
}

// 1. Drop "DEFAULT <value>" from old column definition.
do {
$is_default = $old_column->peek()->matches(
WP_SQLite_Token::TYPE_KEYWORD,
WP_SQLite_Token::FLAG_KEYWORD_RESERVED,
array( 'DEFAULT' )
);
if ( $is_default ) {
$old_column->skip(); // DEFAULT
$old_column->skip(); // value
} else {
$old_column->consume();
}
} while ( $old_column->peek() );

// 2. For SET, add new "DEFAULT <value>" to column definition.
$keyword = $this->rewriter->consume();
if ( 'SET' === $keyword->value ) {
$old_column->add( new WP_SQLite_Token( ' ', WP_SQLite_Token::TYPE_WHITESPACE ) );
$old_column->add( $this->rewriter->consume() ); // DEFAULT
$old_column->add( new WP_SQLite_Token( ' ', WP_SQLite_Token::TYPE_WHITESPACE ) );
$old_column->add( $this->rewriter->consume() ); // value
}
return $old_column->get_updated_query();
}
);

if ( ',' === $this->rewriter->peek()->value ) {
/*
* If the terminator was a comma,
* we need to continue processing the rest of the ALTER query.
*/
$this->rewriter->consume();
$comma = true;
continue;
}
// We're done.
break;
}
} 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 );
Expand Down

0 comments on commit c330962

Please sign in to comment.