Skip to content

Commit

Permalink
Support CREATE TABLE unique keys with no key name (#130)
Browse files Browse the repository at this point in the history
In a table like
```sql
CREATE TABLE `test` (
	`id` INT,
	`name` VARCHAR(255),
	`other` VARCHAR(255),
	PRIMARY KEY (id),
	UNIQUE KEY (name)
)
```

the internal name for the unique key would be `(` because typically a
key would be defined with
```
UNIQUE KEY `name` (name)
```

Usually this wrong key name is not a problem unless a `INSERT .. ON
DUPLICATE KEY` statement is used where the resulting `ON CONFLICT(
"keyname" )` would be transformed to `ON CONFLICT( "" )` which then
fails.

To fix this, this now derives a key name in case it is omitted..

cc @costasovo
  • Loading branch information
akirk authored Jul 18, 2024
1 parent d24fff8 commit d074dec
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
17 changes: 17 additions & 0 deletions tests/WP_SQLite_Query_Tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,23 @@ public function testOnDuplicateKey() {
ON DUPLICATE KEY UPDATE `text` = "test1"'
);
}
public function testOnDuplicateKeyWithUnnamedKeys() {
$this->assertQuery(
'CREATE TABLE `test` (
`id` INT,
`name` VARCHAR(255),
`other` VARCHAR(255),
PRIMARY KEY (id),
UNIQUE KEY (name)
);'
);
// The order is deliberate to test that the query works with the keys in any order.
$this->assertQuery(
'INSERT INTO test (`name`, other)
VALUES ("name", "test")
ON DUPLICATE KEY UPDATE `other` = values(other)'
);
}

public function testShowColumns() {

Expand Down
8 changes: 7 additions & 1 deletion wp-includes/sqlite/class-wp-sqlite-translator.php
Original file line number Diff line number Diff line change
Expand Up @@ -1186,7 +1186,9 @@ private function parse_mysql_create_table_constraint() {
$result->value = $this->normalize_mysql_index_type( $constraint->value );
if ( $result->value ) {
$this->rewriter->skip(); // Constraint type.
if ( 'PRIMARY' !== $result->value ) {

$name = $this->rewriter->peek();
if ( '(' !== $name->token && 'PRIMARY' !== $result->value ) {
$result->name = $this->rewriter->skip()->value;
}

Expand All @@ -1202,6 +1204,10 @@ private function parse_mysql_create_table_constraint() {
}
$this->rewriter->skip(); // `,` or `)`
} while ( $this->rewriter->depth > $constraint_depth );

if ( empty( $result->name ) ) {
$result->name = implode( '_', $result->columns );
}
}

do {
Expand Down

0 comments on commit d074dec

Please sign in to comment.