@@ -410,6 +410,13 @@ class WP_PDO_MySQL_On_SQLite extends PDO {
410410 */
411411 private static $ mysql_grammar ;
412412
413+ /**
414+ * A reusable parser instance for MySQL queries.
415+ *
416+ * @var WP_MySQL_Parser|null
417+ */
418+ private $ mysql_parser = null ;
419+
413420 /**
414421 * The main database name.
415422 *
@@ -1160,11 +1167,27 @@ public function create_parser( string $query ): WP_MySQL_Parser {
11601167 );
11611168 if ( $ lexer instanceof WP_MySQL_Native_Lexer ) {
11621169 $ tokens = $ lexer ->native_token_stream ();
1163- return new WP_MySQL_Parser ( self :: $ mysql_grammar , $ tokens );
1170+ return $ this -> reset_or_create_parser ( $ tokens );
11641171 }
11651172
11661173 $ tokens = $ lexer ->remaining_tokens ();
1167- return new WP_MySQL_Parser ( self ::$ mysql_grammar , $ tokens );
1174+ return $ this ->reset_or_create_parser ( $ tokens );
1175+ }
1176+
1177+ /**
1178+ * Reset the reusable parser with new tokens or create it on first use.
1179+ *
1180+ * @param array<WP_Parser_Token>|object $tokens Parser tokens.
1181+ * @return WP_MySQL_Parser A parser initialized for the token stream.
1182+ */
1183+ private function reset_or_create_parser ( $ tokens ): WP_MySQL_Parser {
1184+ if ( null === $ this ->mysql_parser || ! method_exists ( $ this ->mysql_parser , 'reset_tokens ' ) ) {
1185+ $ this ->mysql_parser = new WP_MySQL_Parser ( self ::$ mysql_grammar , $ tokens );
1186+ } else {
1187+ $ this ->mysql_parser ->reset_tokens ( $ tokens );
1188+ }
1189+
1190+ return $ this ->mysql_parser ;
11681191 }
11691192
11701193 /**
0 commit comments