Skip to content

Commit 7f869ca

Browse files
committed
Ultra-Robust PR 2: Support INSERT without INTO with correct table_name capture
1 parent 783790c commit 7f869ca

1 file changed

Lines changed: 46 additions & 8 deletions

File tree

wp-includes/sqlite-ast/class-wp-pdo-mysql-on-sqlite.php

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,36 +1830,67 @@ private function execute_select_statement( WP_Parser_Node $node ): void {
18301830
private function execute_insert_or_replace_statement( WP_Parser_Node $node ): void {
18311831
$parts = array();
18321832
$on_conflict_update_list = null;
1833+
$seen_into = false;
1834+
$last_modifier_index = -1;
1835+
$is_insert = false;
1836+
1837+
$table_ref = $node->get_first_child_node( 'tableRef' );
1838+
$table_name = $this->unquote_sqlite_identifier( $this->translate( $table_ref ) );
1839+
18331840
foreach ( $node->get_children() as $child ) {
18341841
$is_token = $child instanceof WP_MySQL_Token;
18351842
$is_node = $child instanceof WP_Parser_Node;
18361843

1837-
if ( $child instanceof WP_Parser_Node && 'tableRef' === $child->rule_name ) {
1844+
if ( $is_node && 'tableRef' === $child->rule_name ) {
18381845
$database = $this->get_database_name( $child );
18391846
if ( 'information_schema' === strtolower( $database ) ) {
18401847
throw $this->new_access_denied_to_information_schema_exception();
18411848
}
18421849
}
18431850

1851+
if ( $is_node && in_array( $child->rule_name, array( 'insertLockOption', 'delayedOption' ), true ) ) {
1852+
// SQLite doesn't support these priority modifiers; skip them.
1853+
continue;
1854+
}
1855+
18441856
// Skip the SET keyword in "INSERT INTO ... SET ..." syntax.
18451857
if ( $is_token && WP_MySQL_Lexer::SET_SYMBOL === $child->id ) {
18461858
continue;
18471859
}
18481860

1861+
if ( $is_token && ( WP_MySQL_Lexer::INSERT_SYMBOL === $child->id || WP_MySQL_Lexer::REPLACE_SYMBOL === $child->id ) ) {
1862+
$is_insert = WP_MySQL_Lexer::INSERT_SYMBOL === $child->id;
1863+
$parts[] = $this->translate( $child );
1864+
$last_modifier_index = count( $parts ) - 1;
1865+
continue;
1866+
}
1867+
18491868
if ( $is_token && WP_MySQL_Lexer::IGNORE_SYMBOL === $child->id ) {
1850-
// Translate "UPDATE IGNORE" to "UPDATE OR IGNORE".
1851-
$parts[] = 'OR IGNORE';
1852-
} elseif (
1869+
// Translate MySQL "INSERT IGNORE" to SQLite "INSERT OR IGNORE".
1870+
$parts[] = $is_insert ? 'OR IGNORE' : 'IGNORE';
1871+
$last_modifier_index = count( $parts ) - 1;
1872+
continue;
1873+
}
1874+
1875+
if ( $is_token && WP_MySQL_Lexer::INTO_SYMBOL === $child->id ) {
1876+
$seen_into = true;
1877+
$part = $this->translate( $child );
1878+
if ( null !== $part ) {
1879+
$parts[] = $part;
1880+
$last_modifier_index = count( $parts ) - 1;
1881+
}
1882+
continue;
1883+
}
1884+
1885+
if (
18531886
$is_node
18541887
&& (
18551888
'insertFromConstructor' === $child->rule_name
18561889
|| 'insertQueryExpression' === $child->rule_name
18571890
|| 'updateList' === $child->rule_name
18581891
)
18591892
) {
1860-
$table_ref = $node->get_first_child_node( 'tableRef' );
1861-
$table_name = $this->unquote_sqlite_identifier( $this->translate( $table_ref ) );
1862-
$parts[] = $this->translate_insert_or_replace_body( $table_name, $child );
1893+
$parts[] = $this->translate_insert_or_replace_body( $table_name, $child );
18631894
} elseif ( $is_node && 'insertUpdateList' === $child->rule_name ) {
18641895
/*
18651896
* Translate "ON DUPLICATE KEY UPDATE" to "ON CONFLICT DO UPDATE SET".
@@ -1878,10 +1909,17 @@ private function execute_insert_or_replace_statement( WP_Parser_Node $node ): vo
18781909
$parts[] = $this->translate_update_list( $table_name, $child );
18791910
}
18801911
} else {
1881-
$parts[] = $this->translate( $child );
1912+
$part = $this->translate( $child );
1913+
if ( null !== $part ) {
1914+
$parts[] = $part;
1915+
}
18821916
}
18831917
}
18841918

1919+
if ( ! $seen_into && -1 !== $last_modifier_index ) {
1920+
array_splice( $parts, $last_modifier_index + 1, 0, array( 'INTO' ) );
1921+
}
1922+
18851923
$query = implode( ' ', $parts );
18861924

18871925
/*

0 commit comments

Comments
 (0)