@@ -1317,6 +1317,8 @@ private function translate( $ast ) {
13171317 $ token = $ ast ->get_child_token ();
13181318 if ( WP_MySQL_Lexer::LIKE_SYMBOL === $ token ->id ) {
13191319 return $ this ->translate_like ( $ ast );
1320+ } elseif ( WP_MySQL_Lexer::REGEXP_SYMBOL === $ token ->id ) {
1321+ return $ this ->translate_regexp_functions ( $ ast );
13201322 }
13211323 return $ this ->translate_sequence ( $ ast ->get_children () );
13221324 case 'systemVariable ' :
@@ -1416,6 +1418,29 @@ private function translate_like( WP_Parser_Node $node ): string {
14161418 return $ this ->translate_sequence ( $ node ->get_children () );
14171419 }
14181420
1421+ private function translate_regexp_functions ( WP_Parser_Node $ node ): string {
1422+ $ tokens = $ node ->get_descendant_tokens ();
1423+ $ is_binary = isset ( $ tokens [1 ] ) && WP_MySQL_Lexer::BINARY_SYMBOL === $ tokens [1 ]->id ;
1424+
1425+ /*
1426+ * If the query says REGEXP BINARY, the comparison is byte-by-byte
1427+ * and letter casing matters – lowercase and uppercase letters are
1428+ * represented using different byte codes.
1429+ *
1430+ * The REGEXP function can't be easily made to accept two
1431+ * parameters, so we'll have to use a hack to get around this.
1432+ *
1433+ * If the first character of the pattern is a null byte, we'll
1434+ * remove it and make the comparison case-sensitive. This should
1435+ * be reasonably safe since PHP does not allow null bytes in
1436+ * regular expressions anyway.
1437+ */
1438+ if ( true === $ is_binary ) {
1439+ return 'REGEXP CHAR(0) || ' . $ this ->translate ( $ node ->get_child_node () );
1440+ }
1441+ return 'REGEXP ' . $ this ->translate ( $ node ->get_child_node () );
1442+ }
1443+
14191444 private function get_sqlite_create_table_statement ( string $ table_name , ?string $ new_table_name = null ): array {
14201445 // 1. Get table info.
14211446 $ table_info = $ this ->execute_sqlite_query (
0 commit comments