Skip to content

Commit d0c4b6d

Browse files
committed
Implement altering column with SET DEFAULT and DROP DEFAULT
1 parent 86ba0e5 commit d0c4b6d

File tree

2 files changed

+152
-0
lines changed

2 files changed

+152
-0
lines changed

tests/WP_SQLite_Translator_Tests.php

+88
Original file line numberDiff line numberDiff line change
@@ -3056,6 +3056,94 @@ public function testSelectVariable( $variable_name ) {
30563056
$this->assertQuery( "SELECT $variable_name;" );
30573057
}
30583058

3059+
public function testAlterColumnSetAndDropDefault() {
3060+
$this->assertQuery(
3061+
'CREATE TABLE _tmp_table (
3062+
name varchar(20) NOT NULL
3063+
);'
3064+
);
3065+
$result = $this->assertQuery( 'DESCRIBE _tmp_table' );
3066+
$this->assertEquals(
3067+
array(
3068+
(object) array(
3069+
'Field' => 'name',
3070+
'Type' => 'varchar(20)',
3071+
'Null' => 'NO',
3072+
'Key' => '',
3073+
'Default' => '',
3074+
'Extra' => '',
3075+
),
3076+
),
3077+
$result
3078+
);
3079+
3080+
// SET DEFAULT
3081+
$this->assertQuery( "ALTER TABLE _tmp_table ALTER COLUMN name SET DEFAULT 'abc'" );
3082+
$result = $this->assertQuery( 'DESCRIBE _tmp_table' );
3083+
$this->assertEquals(
3084+
array(
3085+
(object) array(
3086+
'Field' => 'name',
3087+
'Type' => 'varchar(20)',
3088+
'Null' => 'NO',
3089+
'Key' => '',
3090+
'Default' => 'abc',
3091+
'Extra' => '',
3092+
),
3093+
),
3094+
$result
3095+
);
3096+
3097+
// DROP DEFAULT
3098+
$this->assertQuery( 'ALTER TABLE _tmp_table ALTER COLUMN name DROP DEFAULT' );
3099+
$result = $this->assertQuery( 'DESCRIBE _tmp_table' );
3100+
$this->assertEquals(
3101+
array(
3102+
(object) array(
3103+
'Field' => 'name',
3104+
'Type' => 'varchar(20)',
3105+
'Null' => 'NO',
3106+
'Key' => '',
3107+
'Default' => '',
3108+
'Extra' => '',
3109+
),
3110+
),
3111+
$result
3112+
);
3113+
3114+
// multiple ALTER statements, with and without the COLUMN keyword
3115+
$this->assertQuery( "ALTER TABLE _tmp_table ADD COLUMN value varchar(255) DEFAULT 'aaa'" );
3116+
$this->assertQuery(
3117+
"ALTER TABLE _tmp_table
3118+
ALTER name SET DEFAULT 'bbb',
3119+
ALTER COLUMN name DROP DEFAULT,
3120+
ALTER value DROP DEFAULT,
3121+
ALTER COLUMN name SET DEFAULT 'ccc'"
3122+
);
3123+
$result = $this->assertQuery( 'DESCRIBE _tmp_table' );
3124+
$this->assertEquals(
3125+
array(
3126+
(object) array(
3127+
'Field' => 'name',
3128+
'Type' => 'varchar(20)',
3129+
'Null' => 'NO',
3130+
'Key' => '',
3131+
'Default' => '',
3132+
'Extra' => '',
3133+
),
3134+
(object) array(
3135+
'Field' => 'value',
3136+
'Type' => 'varchar(255)',
3137+
'Null' => 'YES',
3138+
'Key' => '',
3139+
'Default' => 'aaa',
3140+
'Extra' => '',
3141+
),
3142+
),
3143+
$result
3144+
);
3145+
}
3146+
30593147
public static function mysqlVariablesToTest() {
30603148
return array(
30613149
// NOTE: This list was derived from the variables used by the UpdraftPlus plugin.

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

+64
Original file line numberDiff line numberDiff line change
@@ -3081,6 +3081,70 @@ function ( $old_name ) use ( $from_name, $new_field ) {
30813081
}
30823082
// We're done.
30833083
break;
3084+
} elseif ( 'ALTER' === $op_type ) {
3085+
$raw_from_name = 'COLUMN' === $op_subject ? $this->rewriter->skip()->token : $op_raw_subject;
3086+
$from_name = $this->normalize_column_name( $raw_from_name );
3087+
3088+
$set_or_drop_default = $this->rewriter->peek()->matches(
3089+
WP_SQLite_Token::TYPE_KEYWORD,
3090+
WP_SQLite_Token::FLAG_KEYWORD_RESERVED,
3091+
array( 'SET', 'DROP' )
3092+
) && $this->rewriter->peek_nth( 2 )->matches(
3093+
WP_SQLite_Token::TYPE_KEYWORD,
3094+
WP_SQLite_Token::FLAG_KEYWORD_RESERVED,
3095+
array( 'DEFAULT' )
3096+
);
3097+
3098+
// Handle "CHANGE <column> DROP DEFAULT" and "CHANGE <column> SET DEFAULT <value>".
3099+
if ( $set_or_drop_default ) {
3100+
$this->execute_change(
3101+
function ( $old_name, $old_column ) use ( $from_name ) {
3102+
//$old_column->consume_all();
3103+
//var_dump($old_column->get_updated_query());ob_flush();
3104+
//$old_column->replace_all([]);
3105+
if ( $from_name !== $old_name ) {
3106+
return null;
3107+
}
3108+
3109+
// 1. Drop "DEFAULT <value>" from old column definition.
3110+
do {
3111+
$is_default = $old_column->peek()->matches(
3112+
WP_SQLite_Token::TYPE_KEYWORD,
3113+
WP_SQLite_Token::FLAG_KEYWORD_RESERVED,
3114+
array( 'DEFAULT' )
3115+
);
3116+
if ( $is_default ) {
3117+
$old_column->skip(); // DEFAULT
3118+
$old_column->skip(); // value
3119+
} else {
3120+
$old_column->consume();
3121+
}
3122+
} while ( $old_column->peek() );
3123+
3124+
// 2. For SET, add new "DEFAULT <value>" to column definition.
3125+
$keyword = $this->rewriter->consume();
3126+
if ( 'SET' === $keyword->value ) {
3127+
$old_column->add( new WP_SQLite_Token( ' ', WP_SQLite_Token::TYPE_WHITESPACE ) );
3128+
$old_column->add( $this->rewriter->consume() ); // DEFAULT
3129+
$old_column->add( new WP_SQLite_Token( ' ', WP_SQLite_Token::TYPE_WHITESPACE ) );
3130+
$old_column->add( $this->rewriter->consume() ); // value
3131+
}
3132+
return $old_column->get_updated_query();
3133+
}
3134+
);
3135+
3136+
if ( ',' === $this->rewriter->peek()->value ) {
3137+
/*
3138+
* If the terminator was a comma,
3139+
* we need to continue processing the rest of the ALTER query.
3140+
*/
3141+
$this->rewriter->consume();
3142+
$comma = true;
3143+
continue;
3144+
}
3145+
// We're done.
3146+
break;
3147+
}
30843148
} elseif ( 'ADD' === $op_type && $is_index_op ) {
30853149
$key_name = $this->rewriter->consume()->value;
30863150
$sqlite_index_type = $this->mysql_index_type_to_sqlite_type( $mysql_index_type );

0 commit comments

Comments
 (0)