Skip to content
This repository was archived by the owner on Jun 2, 2025. It is now read-only.

Allow create table constraints to use data types as symbols #2

Merged
merged 9 commits into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions tests/WP_SQLite_Translator_Tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -1252,6 +1252,74 @@ public function testColumnWithOnUpdate() {
$this->assertNull( $result[0]->updated_at );
}

public function testDataTypeKeywordsAsKeyNames() {
// CREATE TABLE with a data type as a key name
$this->assertQuery(
'CREATE TABLE `_tmp_table` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`timestamp` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `timestamp` (`timestamp`),
);'
);
$results = $this->assertQuery( 'DESCRIBE _tmp_table;' );
$this->assertEquals(
array(
(object) array(
'Field' => 'id',
'Type' => 'bigint(20) unsigned',
'Null' => 'NO',
'Key' => 'PRI',
'Default' => '0',
'Extra' => '',
),
(object) array(
'Field' => 'timestamp',
'Type' => 'datetime',
'Null' => 'NO',
'Key' => '',
'Default' => null,
'Extra' => '',
),
),
$results
);
}


public function testReservedKeywordsAsFieldNames() {
// CREATE TABLE with a reserved keyword as a field name
$this->assertQuery(
'CREATE TABLE `_tmp_table` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`INDEX` timestamp,
PRIMARY KEY (`id`)
);'
);
$results = $this->assertQuery( 'DESCRIBE _tmp_table;' );
$this->assertEquals(
array(
(object) array(
'Field' => 'id',
'Type' => 'bigint(20) unsigned',
'Null' => 'NO',
'Key' => 'PRI',
'Default' => '0',
'Extra' => '',
),
(object) array(
'Field' => 'INDEX',
'Type' => 'timestamp',
'Null' => 'YES',
'Key' => '',
'Default' => null,
'Extra' => '',
),
),
$results
);
}

public function testColumnWithOnUpdateAndNoIdField() {
// CREATE TABLE with ON UPDATE
$this->assertQuery(
Expand Down
24 changes: 17 additions & 7 deletions wp-includes/sqlite/class-wp-sqlite-translator.php
Original file line number Diff line number Diff line change
Expand Up @@ -1013,15 +1013,25 @@ private function parse_create_table() {
*
* Lexer does not seem to reliably understand whether the
* first token is a field name or a reserved keyword, so
* instead we'll check whether the second non-whitespace
* token is a data type.
* alongside checking for the reserved keyword, we'll also
* check whether the second non-whitespace token is a data type.
*
* By checking for the reserved keyword, we can be sure that
* we're not parsing a constraint as a field when the
* constraint symbol matches a data type.
*/
$second_token = $this->rewriter->peek_nth( 2 );
$current_token = $this->rewriter->peek();
$second_token = $this->rewriter->peek_nth( 2 );

if ( $second_token->matches(
WP_SQLite_Token::TYPE_KEYWORD,
WP_SQLite_Token::FLAG_KEYWORD_DATA_TYPE
) ) {
if (
$second_token->matches(
WP_SQLite_Token::TYPE_KEYWORD,
WP_SQLite_Token::FLAG_KEYWORD_DATA_TYPE
) && ! $current_token->matches(
WP_SQLite_Token::TYPE_KEYWORD,
WP_SQLite_Token::FLAG_KEYWORD_RESERVED
)
) {
$result->fields[] = $this->parse_mysql_create_table_field();
} else {
$result->constraints[] = $this->parse_mysql_create_table_constraint();
Expand Down
Loading