@@ -537,9 +537,16 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new ) {
537537 $ count = 0 ;
538538 $ replacer = new SearchReplacer ( $ old , $ new , $ this ->recurse_objects , $ this ->regex , $ this ->regex_flags , $ this ->regex_delimiter , null !== $ this ->log_handle , $ this ->regex_limit );
539539
540- $ table_sql = self ::esc_sql_ident ( $ table );
541- $ col_sql = self ::esc_sql_ident ( $ col );
542- $ where = $ this ->regex ? '' : " WHERE $ col_sql " . $ wpdb ->prepare ( ' LIKE BINARY %s ' , '% ' . self ::esc_like ( $ old ) . '% ' );
540+ $ table_sql = self ::esc_sql_ident ( $ table );
541+ $ col_sql = self ::esc_sql_ident ( $ col );
542+
543+ $ base_key_condition = '' ;
544+ $ where_key = '' ;
545+ if ( ! $ this ->regex ) {
546+ $ base_key_condition = "$ col_sql " . $ wpdb ->prepare ( ' LIKE BINARY %s ' , '% ' . self ::esc_like ( $ old ) . '% ' );
547+ $ where_key = "WHERE $ base_key_condition " ;
548+ }
549+
543550 $ escaped_primary_keys = self ::esc_sql_ident ( $ primary_keys );
544551 $ primary_keys_sql = implode ( ', ' , $ escaped_primary_keys );
545552 $ order_by_keys = array_map (
@@ -550,17 +557,12 @@ static function ( $key ) {
550557 );
551558 $ order_by_sql = 'ORDER BY ' . implode ( ', ' , $ order_by_keys );
552559 $ limit = 1000 ;
553- $ offset = 0 ;
554-
555- // Updates have to be deferred to after the chunking is completed, as
556- // the offset will otherwise not work correctly.
557- $ updates = [];
558560
559561 // 2 errors:
560562 // - WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
561563 // - WordPress.CodeAnalysis.AssignmentInCondition -- no reason to do copy-paste for a single valid assignment in while
562564 // phpcs:ignore
563- while ( $ rows = $ wpdb ->get_results ( "SELECT {$ primary_keys_sql } FROM {$ table_sql } {$ where } {$ order_by_sql } LIMIT {$ limit} OFFSET { $ offset }" ) ) {
565+ while ( $ rows = $ wpdb ->get_results ( "SELECT {$ primary_keys_sql } FROM {$ table_sql } {$ where_key } {$ order_by_sql } LIMIT {$ limit }" ) ) {
564566 foreach ( $ rows as $ keys ) {
565567 $ where_sql = '' ;
566568 foreach ( (array ) $ keys as $ k => $ v ) {
@@ -595,15 +597,22 @@ static function ( $key ) {
595597 $ update_where [ $ k ] = $ v ;
596598 }
597599
598- $ updates [] = [ $ table , array ( $ col => $ value ) , $ update_where ] ;
600+ $ wpdb -> update ( $ table , [ $ col => $ value ] , $ update_where ) ;
599601 }
600602 }
601603
602- $ offset += $ limit ;
603- }
604-
605- foreach ( $ updates as $ update ) {
606- $ wpdb ->update ( ...$ update );
604+ // Because we are ordering by primary keys from least to greatest,
605+ // we can exclude previous chunks from consideration by adding greater-than conditions
606+ // to insist the next chunk's keys must be greater than the last of this chunk's keys.
607+ $ last_keys = end ( $ rows );
608+ $ where_key_conditions = array ();
609+ if ( $ base_key_condition ) {
610+ $ where_key_conditions [] = $ base_key_condition ;
611+ }
612+ foreach ( (array ) $ last_keys as $ k => $ v ) {
613+ $ where_key_conditions [] = self ::esc_sql_ident ( $ k ) . ' > ' . self ::esc_sql_value ( $ v );
614+ }
615+ $ where_key = 'WHERE ' . implode ( 'AND ' , $ where_key_conditions );
607616 }
608617
609618 if ( $ this ->verbose && 'table ' === $ this ->format ) {
0 commit comments