Skip to content

Commit ca02b66

Browse files
committed
Implement INSERT INTO ... SET ... syntax
1 parent 581d361 commit ca02b66

2 files changed

Lines changed: 55 additions & 1 deletion

File tree

tests/WP_SQLite_Driver_Tests.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9439,4 +9439,40 @@ public function testCastExpression(): void {
94399439
$result
94409440
);
94419441
}
9442+
9443+
public function testInsertIntoSetSyntax(): void {
9444+
$this->assertQuery(
9445+
'CREATE TABLE t (
9446+
id INT PRIMARY KEY AUTO_INCREMENT,
9447+
name VARCHAR(255) NOT NULL,
9448+
value TEXT
9449+
)'
9450+
);
9451+
9452+
$this->assertQuery( "INSERT INTO t SET name = 'one'" );
9453+
$this->assertQuery( "INSERT INTO t SET name = 'two', value = 'two-value'" );
9454+
$this->assertQuery( "INSERT INTO t SET value = 'three-value', name = 'three'" );
9455+
9456+
$result = $this->assertQuery( 'SELECT * FROM t' );
9457+
$this->assertEquals(
9458+
array(
9459+
(object) array(
9460+
'id' => '1',
9461+
'name' => 'one',
9462+
'value' => null,
9463+
),
9464+
(object) array(
9465+
'id' => '2',
9466+
'name' => 'two',
9467+
'value' => 'two-value',
9468+
),
9469+
(object) array(
9470+
'id' => '3',
9471+
'name' => 'three',
9472+
'value' => 'three-value',
9473+
),
9474+
),
9475+
$result
9476+
);
9477+
}
94429478
}

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1529,7 +1529,15 @@ private function execute_insert_or_replace_statement( WP_Parser_Node $node ): vo
15291529

15301530
$parts = array();
15311531
foreach ( $node->get_children() as $child ) {
1532-
if ( $child instanceof WP_MySQL_Token && WP_MySQL_Lexer::IGNORE_SYMBOL === $child->id ) {
1532+
$is_token = $child instanceof WP_MySQL_Token;
1533+
$is_node = $child instanceof WP_Parser_Node;
1534+
1535+
// Skip the SET keyword in "INSERT INTO ... SET ..." syntax.
1536+
if ( $is_token && WP_MySQL_Lexer::SET_SYMBOL === $child->id ) {
1537+
continue;
1538+
}
1539+
1540+
if ( $is_token && WP_MySQL_Lexer::IGNORE_SYMBOL === $child->id ) {
15331541
// Translate "UPDATE IGNORE" to "UPDATE OR IGNORE".
15341542
$parts[] = 'OR IGNORE';
15351543
} elseif (
@@ -1540,6 +1548,16 @@ private function execute_insert_or_replace_statement( WP_Parser_Node $node ): vo
15401548
$table_ref = $node->get_first_child_node( 'tableRef' );
15411549
$table_name = $this->unquote_sqlite_identifier( $this->translate( $table_ref ) );
15421550
$parts[] = $this->translate_insert_or_replace_body_in_non_strict_mode( $table_name, $child );
1551+
} elseif ( $is_node && 'updateList' === $child->rule_name ) {
1552+
// Convert "SET c1 = v1, c2 = v2, ... to "(c1, c2, ...) VALUES (v1, v2, ...)".
1553+
$columns = array();
1554+
$values = array();
1555+
foreach ( $child->get_child_nodes( 'updateElement' ) as $update_element ) {
1556+
$column_ref = $update_element->get_first_child_node( 'columnRef' );
1557+
$columns[] = $this->translate( $column_ref );
1558+
$values[] = $this->translate( $update_element->get_first_child_node( 'expr' ) );
1559+
}
1560+
$parts[] = '(' . implode( ', ', $columns ) . ') VALUES (' . implode( ', ', $values ) . ')';
15431561
} else {
15441562
$parts[] = $this->translate( $child );
15451563
}

0 commit comments

Comments
 (0)