Skip to content

Commit 2561000

Browse files
Allow ALTER TABLE to operate on columns without COLUMN keyword (#145)
This PR adds support for the following valid ALTER TABLE syntax: ```sql ALTER TABLE <table-name> ADD <column-name> <data-type>; ``` and ```sql ALTER TABLE <table-name> DROP <column-name>; ``` Prior to this PR, these queries do not work and result in error conditions. For reference, here is the documented SQLite syntax for ALTER TABLE queries: https://www.sqlite.org/syntax/alter-table-stmt.html It shows that the COLUMN keyword is optional, and I've successfully tested syntax without the COLUMN keyword in both MySQL and SQLite. Reported by @JanJakes
1 parent ac23456 commit 2561000

File tree

2 files changed

+92
-4
lines changed

2 files changed

+92
-4
lines changed

tests/WP_SQLite_Translator_Tests.php

+85-1
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,7 @@ enum_column ENUM('a', 'b', 'c') NOT NULL DEFAULT 'a',
871871
);
872872
}
873873

874-
public function testAlterTableAddColumn() {
874+
public function testAlterTableAddAndDropColumn() {
875875
$result = $this->assertQuery(
876876
"CREATE TABLE _tmp_table (
877877
name varchar(20) NOT NULL default ''
@@ -905,6 +905,90 @@ public function testAlterTableAddColumn() {
905905
),
906906
$results
907907
);
908+
909+
$result = $this->assertQuery( 'ALTER TABLE _tmp_table ADD `column2` int;' );
910+
$this->assertEquals( '', $this->engine->get_error_message() );
911+
$this->assertEquals( 1, $result );
912+
913+
$this->assertQuery( 'DESCRIBE _tmp_table;' );
914+
$results = $this->engine->get_query_results();
915+
$this->assertEquals(
916+
array(
917+
(object) array(
918+
'Field' => 'name',
919+
'Type' => 'varchar(20)',
920+
'Null' => 'NO',
921+
'Key' => '',
922+
'Default' => '',
923+
'Extra' => '',
924+
),
925+
(object) array(
926+
'Field' => 'column',
927+
'Type' => 'int',
928+
'Null' => 'YES',
929+
'Key' => '',
930+
'Default' => null,
931+
'Extra' => '',
932+
),
933+
(object) array(
934+
'Field' => 'column2',
935+
'Type' => 'int',
936+
'Null' => 'YES',
937+
'Key' => '',
938+
'Default' => null,
939+
'Extra' => '',
940+
),
941+
),
942+
$results
943+
);
944+
945+
$result = $this->assertQuery( 'ALTER TABLE _tmp_table DROP COLUMN `column`;' );
946+
$this->assertEquals( '', $this->engine->get_error_message() );
947+
$this->assertEquals( 1, $result );
948+
949+
$this->assertQuery( 'DESCRIBE _tmp_table;' );
950+
$results = $this->engine->get_query_results();
951+
$this->assertEquals(
952+
array(
953+
(object) array(
954+
'Field' => 'name',
955+
'Type' => 'varchar(20)',
956+
'Null' => 'NO',
957+
'Key' => '',
958+
'Default' => '',
959+
'Extra' => '',
960+
),
961+
(object) array(
962+
'Field' => 'column2',
963+
'Type' => 'int',
964+
'Null' => 'YES',
965+
'Key' => '',
966+
'Default' => null,
967+
'Extra' => '',
968+
),
969+
),
970+
$results
971+
);
972+
973+
$result = $this->assertQuery( 'ALTER TABLE _tmp_table DROP `column2`;' );
974+
$this->assertEquals( '', $this->engine->get_error_message() );
975+
$this->assertEquals( 1, $result );
976+
977+
$this->assertQuery( 'DESCRIBE _tmp_table;' );
978+
$results = $this->engine->get_query_results();
979+
$this->assertEquals(
980+
array(
981+
(object) array(
982+
'Field' => 'name',
983+
'Type' => 'varchar(20)',
984+
'Null' => 'NO',
985+
'Key' => '',
986+
'Default' => '',
987+
'Extra' => '',
988+
),
989+
),
990+
$results
991+
);
908992
}
909993

910994
public function testAlterTableAddNotNullVarcharColumn() {

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

+7-3
Original file line numberDiff line numberDiff line change
@@ -2921,8 +2921,12 @@ private function execute_alter() {
29212921
$mysql_index_type = $this->normalize_mysql_index_type( $op_subject );
29222922
$is_index_op = (bool) $mysql_index_type;
29232923

2924-
if ( 'ADD' === $op_type && 'COLUMN' === $op_subject ) {
2925-
$column_name = $this->rewriter->consume()->value;
2924+
if ( 'ADD' === $op_type && ! $is_index_op ) {
2925+
if ( 'COLUMN' === $op_subject ) {
2926+
$column_name = $this->rewriter->consume()->value;
2927+
} else {
2928+
$column_name = $op_subject;
2929+
}
29262930

29272931
$skip_mysql_data_type_parts = $this->skip_mysql_data_type();
29282932
$sqlite_data_type = $skip_mysql_data_type_parts[0];
@@ -2940,7 +2944,7 @@ private function execute_alter() {
29402944
$column_name,
29412945
$mysql_data_type
29422946
);
2943-
} elseif ( 'DROP' === $op_type && 'COLUMN' === $op_subject ) {
2947+
} elseif ( 'DROP' === $op_type && ! $is_index_op ) {
29442948
$this->rewriter->consume_all();
29452949
} elseif ( 'CHANGE' === $op_type ) {
29462950
// Parse the new column definition.

0 commit comments

Comments
 (0)