Skip to content

Commit 74c605c

Browse files
authored
Add support for optional COLUMN in ALTER TABLE CHANGE query (#142)
This PR addresses an issue where the ALTER TABLE CHANGE with skipped COLUMNS keyword was ignored. We supporter query ```sql -- Processed correctly ALTER TABLE _tmp_table CHANGE COLUMN name firstname varchar(50) NOT NULL default 'mark'; -- Was ignored ALTER TABLE _tmp_table CHANGE name firstname varchar(50) NOT NULL default 'mark'; ``` This PR fixes the issue by adding support for optional COLUMN in the ALTER TABLE CHANGE query
1 parent c2d9d32 commit 74c605c

File tree

2 files changed

+56
-3
lines changed

2 files changed

+56
-3
lines changed

tests/WP_SQLite_Translator_Tests.php

+51
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,57 @@ public function testAlterTableModifyColumn() {
10981098
$this->assertEquals( 2, $result[0]->ID );
10991099
}
11001100

1101+
1102+
public function testAlterTableModifyColumnWithSkippedColumnKeyword() {
1103+
$this->assertQuery(
1104+
"CREATE TABLE _tmp_table (
1105+
ID INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
1106+
name varchar(20) NOT NULL default '',
1107+
lastname varchar(20) NOT NULL default '',
1108+
KEY composite (name, lastname),
1109+
UNIQUE KEY name (name)
1110+
);"
1111+
);
1112+
// Insert a record
1113+
$result = $this->assertQuery( "INSERT INTO _tmp_table (ID, name, lastname) VALUES (1, 'Johnny', 'Appleseed');" );
1114+
$this->assertEquals( 1, $result );
1115+
1116+
// Primary key violation:
1117+
$result = $this->engine->query( "INSERT INTO _tmp_table (ID, name, lastname) VALUES (1, 'Mike', 'Pearseed');" );
1118+
$this->assertEquals( false, $result );
1119+
1120+
// Unique constraint violation:
1121+
$result = $this->engine->query( "INSERT INTO _tmp_table (ID, name, lastname) VALUES (2, 'Johnny', 'Appleseed');" );
1122+
$this->assertEquals( false, $result );
1123+
1124+
// Rename the "name" field to "firstname":
1125+
$result = $this->engine->query( "ALTER TABLE _tmp_table CHANGE name firstname varchar(50) NOT NULL default 'mark';" );
1126+
$this->assertEquals( '', $this->engine->get_error_message() );
1127+
$this->assertEquals( 1, $result );
1128+
1129+
// Confirm the original data is still there:
1130+
$result = $this->engine->query( 'SELECT * FROM _tmp_table;' );
1131+
$this->assertCount( 1, $result );
1132+
$this->assertEquals( 1, $result[0]->ID );
1133+
$this->assertEquals( 'Johnny', $result[0]->firstname );
1134+
$this->assertEquals( 'Appleseed', $result[0]->lastname );
1135+
1136+
// Confirm the primary key is intact:
1137+
$result = $this->engine->query( "INSERT INTO _tmp_table (ID, firstname, lastname) VALUES (1, 'Mike', 'Pearseed');" );
1138+
$this->assertEquals( false, $result );
1139+
1140+
// Confirm the unique key is intact:
1141+
$result = $this->engine->query( "INSERT INTO _tmp_table (ID, firstname, lastname) VALUES (2, 'Johnny', 'Appleseed');" );
1142+
$this->assertEquals( false, $result );
1143+
1144+
// Confirm the autoincrement still works:
1145+
$result = $this->engine->query( "INSERT INTO _tmp_table (firstname, lastname) VALUES ('John', 'Doe');" );
1146+
$this->assertEquals( true, $result );
1147+
$result = $this->engine->query( "SELECT * FROM _tmp_table WHERE firstname='John';" );
1148+
$this->assertCount( 1, $result );
1149+
$this->assertEquals( 2, $result[0]->ID );
1150+
}
1151+
11011152
public function testAlterTableModifyColumnWithHyphens() {
11021153
$result = $this->assertQuery(
11031154
'CREATE TABLE wptests_dbdelta_test2 (

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

+5-3
Original file line numberDiff line numberDiff line change
@@ -2916,7 +2916,8 @@ private function execute_alter() {
29162916
)
29172917
);
29182918
$op_type = strtoupper( $this->rewriter->consume()->token ?? '' );
2919-
$op_subject = strtoupper( $this->rewriter->consume()->token ?? '' );
2919+
$op_raw_subject = $this->rewriter->consume()->token ?? '';
2920+
$op_subject = strtoupper( $op_raw_subject );
29202921
$mysql_index_type = $this->normalize_mysql_index_type( $op_subject );
29212922
$is_index_op = (bool) $mysql_index_type;
29222923

@@ -2941,9 +2942,10 @@ private function execute_alter() {
29412942
);
29422943
} elseif ( 'DROP' === $op_type && 'COLUMN' === $op_subject ) {
29432944
$this->rewriter->consume_all();
2944-
} elseif ( 'CHANGE' === $op_type && 'COLUMN' === $op_subject ) {
2945+
} elseif ( 'CHANGE' === $op_type ) {
29452946
// Parse the new column definition.
2946-
$from_name = $this->normalize_column_name( $this->rewriter->skip()->token );
2947+
$raw_from_name = 'COLUMN' === $op_subject ? $this->rewriter->skip()->token : $op_raw_subject;
2948+
$from_name = $this->normalize_column_name( $raw_from_name );
29472949
$new_field = $this->parse_mysql_create_table_field();
29482950
$alter_terminator = end( $this->rewriter->output_tokens );
29492951
$this->update_data_type_cache(

0 commit comments

Comments
 (0)