@@ -1542,8 +1542,12 @@ private function execute_insert_or_replace_statement( WP_Parser_Node $node ): vo
15421542 $ parts [] = 'OR IGNORE ' ;
15431543 } elseif (
15441544 $ is_non_strict_mode
1545- && $ child instanceof WP_Parser_Node
1546- && ( 'insertFromConstructor ' === $ child ->rule_name || 'insertQueryExpression ' === $ child ->rule_name )
1545+ && $ is_node
1546+ && (
1547+ 'insertFromConstructor ' === $ child ->rule_name
1548+ || 'insertQueryExpression ' === $ child ->rule_name
1549+ || 'updateList ' === $ child ->rule_name
1550+ )
15471551 ) {
15481552 $ table_ref = $ node ->get_first_child_node ( 'tableRef ' );
15491553 $ table_name = $ this ->unquote_sqlite_identifier ( $ this ->translate ( $ table_ref ) );
@@ -4322,6 +4326,12 @@ private function translate_insert_or_replace_body_in_non_strict_mode(
43224326 foreach ( $ fields_node ->get_child_nodes () as $ field ) {
43234327 $ insert_list [] = $ this ->unquote_sqlite_identifier ( $ this ->translate ( $ field ) );
43244328 }
4329+ } elseif ( 'updateList ' === $ node ->rule_name ) {
4330+ // This is the "INSERT INTO ... SET c1 = v1, c2 = v2, ... " syntax.
4331+ foreach ( $ node ->get_child_nodes ( 'updateElement ' ) as $ update_element ) {
4332+ $ column_ref = $ update_element ->get_first_child_node ( 'columnRef ' );
4333+ $ insert_list [] = $ this ->unquote_sqlite_identifier ( $ this ->translate ( $ column_ref ) );
4334+ }
43254335 } else {
43264336 // When no explicit field list is provided, all columns are required.
43274337 foreach ( array_column ( $ columns , 'COLUMN_NAME ' ) as $ column_name ) {
@@ -4402,10 +4412,25 @@ function ( $column ) use ( $insert_list ) {
44024412 }
44034413 }
44044414
4405- // 6. Wrap the original insert VALUES or SELECT expression in a FROM clause.
4406- $ values = 'insertFromConstructor ' === $ node ->rule_name
4407- ? $ node ->get_first_child_node ( 'insertValues ' )
4408- : $ node ->get_first_child_node ( 'queryExpressionOrParens ' );
4415+ // 6. Wrap the original insert VALUES, SELECT, or SET list in a FROM clause.
4416+ if ( 'insertFromConstructor ' === $ node ->rule_name ) {
4417+ // VALUES (...)
4418+ $ from = $ this ->translate (
4419+ $ node ->get_first_child_node ( 'insertValues ' )
4420+ );
4421+ } elseif ( 'insertQueryExpression ' === $ node ->rule_name ) {
4422+ // SELECT ...
4423+ $ from = $ this ->translate (
4424+ $ node ->get_first_child_node ( 'queryExpressionOrParens ' )
4425+ );
4426+ } else {
4427+ // SET c1 = v1, c2 = v2, ...
4428+ $ values = array ();
4429+ foreach ( $ node ->get_child_nodes ( 'updateElement ' ) as $ update_element ) {
4430+ $ values [] = $ this ->translate ( $ update_element ->get_first_child_node ( 'expr ' ) );
4431+ }
4432+ $ from = 'VALUES ( ' . implode ( ', ' , $ values ) . ') ' ;
4433+ }
44094434
44104435 /*
44114436 * The "WHERE true" suffix is used to avoid parsing ambiguity in SQLite.
@@ -4414,7 +4439,7 @@ function ( $column ) use ( $insert_list ) {
44144439 *
44154440 * See: https://www.sqlite.org/lang_insert.html
44164441 */
4417- $ fragment .= ' FROM ( ' . $ this -> translate ( $ values ) . ') WHERE true ' ;
4442+ $ fragment .= ' FROM ( ' . $ from . ') WHERE true ' ;
44184443
44194444 return $ fragment ;
44204445 }
0 commit comments