Skip to content

Commit 0f5b5be

Browse files
committed
Add support for MySQL savepoints
1 parent ac62e18 commit 0f5b5be

2 files changed

Lines changed: 54 additions & 2 deletions

File tree

tests/WP_SQLite_Driver_Tests.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6294,4 +6294,38 @@ public function testLockTemporaryTables(): void {
62946294
$this->assertQuery( 'LOCK TABLES t1 READ, t2 READ, t3 WRITE' );
62956295
$this->assertQuery( 'UNLOCK TABLES' );
62966296
}
6297+
6298+
public function testTransactionSavepoints(): void {
6299+
$this->assertQuery( 'CREATE TABLE t (id INT)' );
6300+
6301+
$this->assertQuery( 'BEGIN' );
6302+
$this->assertQuery( 'INSERT INTO t (id) VALUES (1)' );
6303+
$result = $this->assertQuery( 'SELECT * FROM t' );
6304+
$this->assertSame( array( '1' ), (array) array_column( $result, 'id' ) );
6305+
6306+
$this->assertQuery( 'SAVEPOINT sp1' );
6307+
$this->assertQuery( 'INSERT INTO t (id) VALUES (2)' );
6308+
$result = $this->assertQuery( 'SELECT * FROM t' );
6309+
$this->assertSame( array( '1', '2' ), (array) array_column( $result, 'id' ) );
6310+
6311+
$this->assertQuery( 'SAVEPOINT sp2' );
6312+
$this->assertQuery( 'INSERT INTO t (id) VALUES (3)' );
6313+
$result = $this->assertQuery( 'SELECT * FROM t' );
6314+
$this->assertSame( array( '1', '2', '3' ), (array) array_column( $result, 'id' ) );
6315+
6316+
$this->assertQuery( 'ROLLBACK TO SAVEPOINT sp1' );
6317+
$result = $this->assertQuery( 'SELECT * FROM t' );
6318+
$this->assertSame( array( '1' ), (array) array_column( $result, 'id' ) );
6319+
6320+
$this->assertQuery( 'RELEASE SAVEPOINT sp1' );
6321+
$this->assertQuery( 'ROLLBACK' );
6322+
$result = $this->assertQuery( 'SELECT * FROM t' );
6323+
$this->assertSame( array(), (array) array_column( $result, 'id' ) );
6324+
}
6325+
6326+
public function testRollbackNonExistentTransactionSavepoint(): void {
6327+
$this->expectException( 'WP_SQLite_Driver_Exception' );
6328+
$this->expectExceptionMessage( 'no such savepoint: sp1' );
6329+
$this->assertQuery( 'ROLLBACK TO SAVEPOINT sp1' );
6330+
}
62976331
}

wp-includes/sqlite-ast/class-wp-sqlite-driver.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,9 +1033,27 @@ private function execute_transaction_or_locking_statement( WP_Parser_Node $node
10331033

10341034
// Unknown statement. Fall through to the default case.
10351035
case 'savepointStatement':
1036-
// ROLLBACK.
1036+
$savepoint_name = $this->translate( $subnode->get_first_child_node( 'identifier' ) );
1037+
1038+
// ROLLBACK/ROLLBACK TO SAVEPOINT <identifier>.
10371039
if ( WP_MySQL_Lexer::ROLLBACK_SYMBOL === $token->id ) {
1038-
$this->rollback();
1040+
if ( null === $savepoint_name ) {
1041+
$this->rollback();
1042+
} else {
1043+
$this->execute_sqlite_query( sprintf( 'ROLLBACK TO SAVEPOINT %s', $savepoint_name ) );
1044+
}
1045+
break;
1046+
}
1047+
1048+
// SAVEPOINT.
1049+
if ( WP_MySQL_Lexer::SAVEPOINT_SYMBOL === $token->id ) {
1050+
$this->execute_sqlite_query( sprintf( 'SAVEPOINT %s', $savepoint_name ) );
1051+
break;
1052+
}
1053+
1054+
// RELEASE SAVEPOINT.
1055+
if ( WP_MySQL_Lexer::RELEASE_SYMBOL === $token->id ) {
1056+
$this->execute_sqlite_query( sprintf( 'RELEASE SAVEPOINT %s', $savepoint_name ) );
10391057
break;
10401058
}
10411059

0 commit comments

Comments
 (0)