Skip to content

Commit b5a9fba

Browse files
authored
Merge pull request #2 from Automattic/update/support-type-names-as-key-names
Allow create table constraints to use data types as symbols
2 parents 271163b + fada3e6 commit b5a9fba

2 files changed

Lines changed: 85 additions & 7 deletions

File tree

tests/WP_SQLite_Translator_Tests.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,6 +1252,74 @@ public function testColumnWithOnUpdate() {
12521252
$this->assertNull( $result[0]->updated_at );
12531253
}
12541254

1255+
public function testDataTypeKeywordsAsKeyNames() {
1256+
// CREATE TABLE with a data type as a key name
1257+
$this->assertQuery(
1258+
'CREATE TABLE `_tmp_table` (
1259+
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
1260+
`timestamp` datetime NOT NULL,
1261+
PRIMARY KEY (`id`),
1262+
KEY `timestamp` (`timestamp`),
1263+
);'
1264+
);
1265+
$results = $this->assertQuery( 'DESCRIBE _tmp_table;' );
1266+
$this->assertEquals(
1267+
array(
1268+
(object) array(
1269+
'Field' => 'id',
1270+
'Type' => 'bigint(20) unsigned',
1271+
'Null' => 'NO',
1272+
'Key' => 'PRI',
1273+
'Default' => '0',
1274+
'Extra' => '',
1275+
),
1276+
(object) array(
1277+
'Field' => 'timestamp',
1278+
'Type' => 'datetime',
1279+
'Null' => 'NO',
1280+
'Key' => '',
1281+
'Default' => null,
1282+
'Extra' => '',
1283+
),
1284+
),
1285+
$results
1286+
);
1287+
}
1288+
1289+
1290+
public function testReservedKeywordsAsFieldNames() {
1291+
// CREATE TABLE with a reserved keyword as a field name
1292+
$this->assertQuery(
1293+
'CREATE TABLE `_tmp_table` (
1294+
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
1295+
`INDEX` timestamp,
1296+
PRIMARY KEY (`id`)
1297+
);'
1298+
);
1299+
$results = $this->assertQuery( 'DESCRIBE _tmp_table;' );
1300+
$this->assertEquals(
1301+
array(
1302+
(object) array(
1303+
'Field' => 'id',
1304+
'Type' => 'bigint(20) unsigned',
1305+
'Null' => 'NO',
1306+
'Key' => 'PRI',
1307+
'Default' => '0',
1308+
'Extra' => '',
1309+
),
1310+
(object) array(
1311+
'Field' => 'INDEX',
1312+
'Type' => 'timestamp',
1313+
'Null' => 'YES',
1314+
'Key' => '',
1315+
'Default' => null,
1316+
'Extra' => '',
1317+
),
1318+
),
1319+
$results
1320+
);
1321+
}
1322+
12551323
public function testColumnWithOnUpdateAndNoIdField() {
12561324
// CREATE TABLE with ON UPDATE
12571325
$this->assertQuery(

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

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,15 +1013,25 @@ private function parse_create_table() {
10131013
*
10141014
* Lexer does not seem to reliably understand whether the
10151015
* first token is a field name or a reserved keyword, so
1016-
* instead we'll check whether the second non-whitespace
1017-
* token is a data type.
1016+
* alongside checking for the reserved keyword, we'll also
1017+
* check whether the second non-whitespace token is a data type.
1018+
*
1019+
* By checking for the reserved keyword, we can be sure that
1020+
* we're not parsing a constraint as a field when the
1021+
* constraint symbol matches a data type.
10181022
*/
1019-
$second_token = $this->rewriter->peek_nth( 2 );
1023+
$current_token = $this->rewriter->peek();
1024+
$second_token = $this->rewriter->peek_nth( 2 );
10201025

1021-
if ( $second_token->matches(
1022-
WP_SQLite_Token::TYPE_KEYWORD,
1023-
WP_SQLite_Token::FLAG_KEYWORD_DATA_TYPE
1024-
) ) {
1026+
if (
1027+
$second_token->matches(
1028+
WP_SQLite_Token::TYPE_KEYWORD,
1029+
WP_SQLite_Token::FLAG_KEYWORD_DATA_TYPE
1030+
) && ! $current_token->matches(
1031+
WP_SQLite_Token::TYPE_KEYWORD,
1032+
WP_SQLite_Token::FLAG_KEYWORD_RESERVED
1033+
)
1034+
) {
10251035
$result->fields[] = $this->parse_mysql_create_table_field();
10261036
} else {
10271037
$result->constraints[] = $this->parse_mysql_create_table_constraint();

0 commit comments

Comments
 (0)