Skip to content

Commit 6469203

Browse files
authored
Implement UPDATE with mutliple tables used (single modified table only) (#238)
This PR implements support for `UPDATE` statements with multiple tables used. It only allows a single modified table, as updating multiple tables at once is likely much more complex and may require using temporary tables (e.g., in `UPDATE t1, t2 SET t1.id = t2.id, t2.id = t1.id`, we can't simply update `t1` first and `t2` after that). This is what I managed to do today—it may require adding some more tests. Resolves #233.
1 parent 50b3fcc commit 6469203

File tree

3 files changed

+391
-34
lines changed

3 files changed

+391
-34
lines changed

tests/WP_SQLite_Driver_Tests.php

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6693,4 +6693,151 @@ public function testForeignKeyOnDeleteSetDefault(): void {
66936693
$result = $this->assertQuery( 'SELECT * FROM t2' );
66946694
$this->assertEquals( array( (object) array( 'id' => '0' ) ), $result );
66956695
}
6696+
6697+
public function testUpdateWithJoinedTables(): void {
6698+
$this->assertQuery( 'CREATE TABLE t1 (id INT, comment TEXT)' );
6699+
$this->assertQuery( 'CREATE TABLE t2 (id INT, name TEXT)' );
6700+
$this->assertQuery( 'CREATE TABLE t3 (id INT, name TEXT)' );
6701+
6702+
$this->assertQuery( 'INSERT INTO t1 (id) VALUES (1), (2), (3)' );
6703+
$this->assertQuery( 'INSERT INTO t2 (id, name) VALUES (1, "update")' );
6704+
$this->assertQuery( 'INSERT INTO t2 (id, name) VALUES (2, "do-not-update")' );
6705+
$this->assertQuery( 'INSERT INTO t2 (id, name) VALUES (3, "update")' );
6706+
$this->assertQuery( 'INSERT INTO t3 (id, name) VALUES (1, "do-not-update")' );
6707+
$this->assertQuery( 'INSERT INTO t3 (id, name) VALUES (2, "update")' );
6708+
$this->assertQuery( 'INSERT INTO t3 (id, name) VALUES (3, "update")' );
6709+
6710+
// Fully qualified column reference in SET.
6711+
$this->assertQuery(
6712+
"UPDATE t1, t2
6713+
JOIN t3 ON t3.id = t1.id
6714+
SET t1.id = 0
6715+
WHERE t2.id = t1.id
6716+
AND t2.name = 'update'
6717+
AND t3.name = 'update'"
6718+
);
6719+
6720+
$result = $this->assertQuery( 'SELECT * FROM t1' );
6721+
$this->assertEquals(
6722+
array(
6723+
(object) array(
6724+
'id' => '1',
6725+
'comment' => null,
6726+
),
6727+
(object) array(
6728+
'id' => '2',
6729+
'comment' => null,
6730+
),
6731+
(object) array(
6732+
'id' => '0',
6733+
'comment' => null,
6734+
),
6735+
),
6736+
$result
6737+
);
6738+
6739+
// Unqualified column reference in SET.
6740+
$this->assertQuery( 'UPDATE t1 SET id = 3 WHERE id = 0' );
6741+
$this->assertQuery(
6742+
"UPDATE t1, t2
6743+
JOIN t3 ON t3.id = t1.id
6744+
SET comment = 'updated'
6745+
WHERE t2.id = t1.id
6746+
AND t2.name = 'update'
6747+
AND t3.name = 'update'"
6748+
);
6749+
6750+
$result = $this->assertQuery( 'SELECT * FROM t1' );
6751+
$this->assertEquals(
6752+
array(
6753+
(object) array(
6754+
'id' => '1',
6755+
'comment' => null,
6756+
),
6757+
(object) array(
6758+
'id' => '2',
6759+
'comment' => null,
6760+
),
6761+
(object) array(
6762+
'id' => '3',
6763+
'comment' => 'updated',
6764+
),
6765+
),
6766+
$result
6767+
);
6768+
}
6769+
6770+
public function testUpdateWithJoinedTablesInNonStrictMode(): void {
6771+
$this->assertQuery( "SET SESSION sql_mode = ''" );
6772+
$this->assertQuery( 'CREATE TABLE t1 (id INT, comment TEXT)' );
6773+
$this->assertQuery( 'CREATE TABLE t2 (id INT, name TEXT)' );
6774+
$this->assertQuery( 'CREATE TABLE t3 (id INT, name TEXT)' );
6775+
6776+
$this->assertQuery( 'INSERT INTO t1 (id) VALUES (1), (2), (3)' );
6777+
$this->assertQuery( 'INSERT INTO t2 (id, name) VALUES (1, "update")' );
6778+
$this->assertQuery( 'INSERT INTO t2 (id, name) VALUES (2, "do-not-update")' );
6779+
$this->assertQuery( 'INSERT INTO t2 (id, name) VALUES (3, "update")' );
6780+
$this->assertQuery( 'INSERT INTO t3 (id, name) VALUES (1, "do-not-update")' );
6781+
$this->assertQuery( 'INSERT INTO t3 (id, name) VALUES (2, "update")' );
6782+
$this->assertQuery( 'INSERT INTO t3 (id, name) VALUES (3, "update")' );
6783+
6784+
// Fully qualified column reference in SET.
6785+
$this->assertQuery(
6786+
"UPDATE t1, t2
6787+
JOIN t3 ON t3.id = t1.id
6788+
SET t1.id = 0
6789+
WHERE t2.id = t1.id
6790+
AND t2.name = 'update'
6791+
AND t3.name = 'update'"
6792+
);
6793+
6794+
$result = $this->assertQuery( 'SELECT * FROM t1' );
6795+
$this->assertEquals(
6796+
array(
6797+
(object) array(
6798+
'id' => '1',
6799+
'comment' => null,
6800+
),
6801+
(object) array(
6802+
'id' => '2',
6803+
'comment' => null,
6804+
),
6805+
(object) array(
6806+
'id' => '0',
6807+
'comment' => null,
6808+
),
6809+
),
6810+
$result
6811+
);
6812+
6813+
// Unqualified column reference in SET.
6814+
$this->assertQuery( 'UPDATE t1 SET id = 3 WHERE id = 0' );
6815+
$this->assertQuery(
6816+
"UPDATE t1, t2
6817+
JOIN t3 ON t3.id = t1.id
6818+
SET comment = 'updated'
6819+
WHERE t2.id = t1.id
6820+
AND t2.name = 'update'
6821+
AND t3.name = 'update'"
6822+
);
6823+
6824+
$result = $this->assertQuery( 'SELECT * FROM t1' );
6825+
$this->assertEquals(
6826+
array(
6827+
(object) array(
6828+
'id' => '1',
6829+
'comment' => null,
6830+
),
6831+
(object) array(
6832+
'id' => '2',
6833+
'comment' => null,
6834+
),
6835+
(object) array(
6836+
'id' => '3',
6837+
'comment' => 'updated',
6838+
),
6839+
),
6840+
$result
6841+
);
6842+
}
66966843
}

tests/WP_SQLite_Driver_Translation_Tests.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public function testUpdate(): void {
159159
);
160160

161161
$this->assertQuery(
162-
'UPDATE `t` SET `c1` = 1 , `c2` = 2',
162+
'UPDATE `t` SET `c1` = 1, `c2` = 2',
163163
'UPDATE t SET c1 = 1, c2 = 2'
164164
);
165165

0 commit comments

Comments
 (0)