@@ -1531,6 +1531,10 @@ private function execute_insert_or_replace_statement( WP_Parser_Node $node ): vo
15311531 $ table_ref = $ node ->get_first_child_node ( 'tableRef ' );
15321532 $ table_name = $ this ->unquote_sqlite_identifier ( $ this ->translate ( $ table_ref ) );
15331533 $ parts [] = $ this ->translate_insert_or_replace_body ( $ table_name , $ child );
1534+ } elseif ( $ is_node && 'insertUpdateList ' === $ child ->rule_name ) {
1535+ // Translate "ON DUPLICATE KEY UPDATE" to "ON CONFLICT DO UPDATE SET".
1536+ $ parts [] = 'ON CONFLICT DO UPDATE SET ' ;
1537+ $ parts [] = $ this ->translate_update_list ( $ table_name , $ child );
15341538 } else {
15351539 $ parts [] = $ this ->translate ( $ child );
15361540 }
@@ -1737,7 +1741,7 @@ private function execute_update_statement( WP_Parser_Node $node ): void {
17371741 }
17381742
17391743 // Translate UPDATE list, applying relevant type casting and IMPLICIT DEFAULT values.
1740- $ update_list = $ this ->translate_update_list ( $ update_target_table , $ update_list_node );
1744+ $ update_list = $ this ->translate_update_list ( $ update_target_table , $ node );
17411745
17421746 // Translate WHERE, ORDER BY, and LIMIT clauses.
17431747 if ( $ where_subquery ) {
@@ -3241,12 +3245,6 @@ private function translate( $node ): ?string {
32413245 return null ;
32423246 }
32433247 return $ this ->translate_sequence ( $ node ->get_children () );
3244- case 'insertUpdateList ' :
3245- // Translate "ON DUPLICATE KEY UPDATE" to "ON CONFLICT DO UPDATE SET".
3246- return sprintf (
3247- 'ON CONFLICT DO UPDATE SET %s ' ,
3248- $ this ->translate ( $ node ->get_first_child_node ( 'updateList ' ) )
3249- );
32503248 case 'simpleExpr ' :
32513249 return $ this ->translate_simple_expr ( $ node );
32523250 case 'predicateOperations ' :
@@ -4649,11 +4647,13 @@ function ( $column ) use ( $is_strict_mode, $insert_map ) {
46494647 * For more information about IMPLICIT DEFAULT values in MySQL, see:
46504648 * https://dev.mysql.com/doc/refman/8.4/en/data-type-defaults.html#data-type-defaults-implicit
46514649 *
4652- * @param string $table_name The name of the target table.
4653- * @param WP_Parser_Node $node The "updateList" AST node.
4654- * @return string The translated UPDATE list.
4650+ * @param string $table_name The name of the target table.
4651+ * @param WP_Parser_Node $parent_node The "updateList" AST node parent node.
4652+ * @return string The translated UPDATE list.
46554653 */
4656- private function translate_update_list ( string $ table_name , WP_Parser_Node $ node ): string {
4654+ private function translate_update_list ( string $ table_name , WP_Parser_Node $ parent_node ): string {
4655+ $ node = $ parent_node ->get_first_child_node ( 'updateList ' );
4656+
46574657 // This method is always used with the main database.
46584658 $ database = $ this ->get_saved_db_name ( $ this ->main_db_name );
46594659
@@ -4724,11 +4724,17 @@ private function translate_update_list( string $table_name, WP_Parser_Node $node
47244724 // Apply type casting.
47254725 $ value = $ this ->cast_value_for_saving ( $ data_type , $ value );
47264726
4727- // In MySQL non-STRICT mode, when a column is declared as NOT NULL,
4728- // updating to a NULL value saves an IMPLICIT DEFAULT value instead.
4729- $ implicit_default = self ::DATA_TYPE_IMPLICIT_DEFAULT_MAP [ $ data_type ] ?? null ;
4730- if ( ! $ is_strict_mode && ! $ is_nullable && null !== $ implicit_default ) {
4731- $ value = sprintf ( 'COALESCE(%s, %s) ' , $ value , $ this ->connection ->quote ( $ implicit_default ) );
4727+ /*
4728+ * In MySQL non-STRICT mode, when a column is declared as NOT NULL,
4729+ * updating to a NULL value saves an IMPLICIT DEFAULT value instead.
4730+ * This behavior does not apply to ON DUPLICATE KEY UPDATE clauses.
4731+ */
4732+ $ is_on_duplicate_key_update = 'insertUpdateList ' === $ parent_node ->rule_name ;
4733+ if ( ! $ is_strict_mode && ! $ is_nullable && ! $ is_on_duplicate_key_update ) {
4734+ $ implicit_default = self ::DATA_TYPE_IMPLICIT_DEFAULT_MAP [ $ data_type ] ?? null ;
4735+ if ( null !== $ implicit_default ) {
4736+ $ value = sprintf ( 'COALESCE(%s, %s) ' , $ value , $ this ->connection ->quote ( $ implicit_default ) );
4737+ }
47324738 }
47334739
47344740 // Compose the UPDATE list item.
0 commit comments