Skip to content

Commit 11e8548

Browse files
authored
Support INSERT without INTO keyword (#354)
## Summary MySQL supports omitting the `INTO` keyword in `INSERT` statements (e.g., `INSERT t (id) VALUES (1)`), but SQLite requires it. This adds the missing `INTO` keyword during query translation. This is a simpler alternative to #343, focusing only on the `INTO` keyword injection. It also adds tests covering `INSERT` without `INTO` across multiple syntaxes: `VALUES`, `SET`, `SELECT`, and their `IGNORE` variants. Closes #343. Thanks @wp-fuse for reporting this! ## Test plan - [x] `INSERT t (id, name) VALUES (1, 'a')` — VALUES syntax without INTO. - [x] `INSERT IGNORE t (id, name) VALUES (1, 'a')` — IGNORE without INTO. - [x] `INSERT t SET id = 2, name = 'b'` — SET syntax without INTO. - [x] `INSERT IGNORE t SET id = 2, name = 'b'` — IGNORE + SET without INTO. - [x] `INSERT t (id, name) SELECT 3, 'c'` — SELECT syntax without INTO. - [x] `INSERT IGNORE t (id, name) SELECT 3, 'c'` — IGNORE + SELECT without INTO.
1 parent e88f9e7 commit 11e8548

2 files changed

Lines changed: 33 additions & 0 deletions

File tree

packages/mysql-on-sqlite/src/sqlite/class-wp-pdo-mysql-on-sqlite.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,6 +1835,11 @@ private function execute_insert_or_replace_statement( WP_Parser_Node $node ): vo
18351835
$is_node = $child instanceof WP_Parser_Node;
18361836

18371837
if ( $child instanceof WP_Parser_Node && 'tableRef' === $child->rule_name ) {
1838+
// MySQL supports INSERT without the INTO keyword; SQLite requires it.
1839+
if ( ! $node->has_child_token( WP_MySQL_Lexer::INTO_SYMBOL ) ) {
1840+
$parts[] = 'INTO';
1841+
}
1842+
18381843
$database = $this->get_database_name( $child );
18391844
if ( 'information_schema' === strtolower( $database ) ) {
18401845
throw $this->new_access_denied_to_information_schema_exception();

packages/mysql-on-sqlite/tests/WP_SQLite_Driver_Tests.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9986,6 +9986,34 @@ public function testCastExpression(): void {
99869986
);
99879987
}
99889988

9989+
public function testInsertWithoutInto(): void {
9990+
$this->assertQuery( 'CREATE TABLE t (id INT PRIMARY KEY, name VARCHAR(255))' );
9991+
9992+
// INSERT ... VALUES
9993+
$this->assertQuery( "INSERT t (id, name) VALUES (1, 'a')" );
9994+
9995+
// INSERT IGNORE
9996+
$this->assertQuery( "INSERT IGNORE t (id, name) VALUES (1, 'a')" );
9997+
9998+
// INSERT ... SET
9999+
$this->assertQuery( "INSERT t SET id = 2, name = 'b'" );
10000+
10001+
// INSERT IGNORE ... SET
10002+
$this->assertQuery( "INSERT IGNORE t SET id = 2, name = 'b'" );
10003+
10004+
// INSERT ... SELECT
10005+
$this->assertQuery( "INSERT t (id, name) SELECT 3, 'c'" );
10006+
10007+
// INSERT IGNORE ... SELECT
10008+
$this->assertQuery( "INSERT IGNORE t (id, name) SELECT 3, 'c'" );
10009+
10010+
$res = $this->assertQuery( 'SELECT * FROM t ORDER BY id' );
10011+
$this->assertCount( 3, $res );
10012+
$this->assertEquals( 'a', $res[0]->name );
10013+
$this->assertEquals( 'b', $res[1]->name );
10014+
$this->assertEquals( 'c', $res[2]->name );
10015+
}
10016+
998910017
public function testInsertIntoSetSyntax(): void {
999010018
$this->assertQuery(
999110019
'CREATE TABLE t (

0 commit comments

Comments
 (0)