From 335388b048031aa62ded67854939133a21c279d5 Mon Sep 17 00:00:00 2001 From: Jan Jakes Date: Fri, 10 Jan 2025 10:10:46 +0100 Subject: [PATCH] Add support for REGEXP functions --- .../sqlite-ast/class-wp-sqlite-driver.php | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/wp-includes/sqlite-ast/class-wp-sqlite-driver.php b/wp-includes/sqlite-ast/class-wp-sqlite-driver.php index d18d92a1..bd23f349 100644 --- a/wp-includes/sqlite-ast/class-wp-sqlite-driver.php +++ b/wp-includes/sqlite-ast/class-wp-sqlite-driver.php @@ -1317,6 +1317,8 @@ private function translate( $ast ) { $token = $ast->get_child_token(); if ( WP_MySQL_Lexer::LIKE_SYMBOL === $token->id ) { return $this->translate_like( $ast ); + } elseif ( WP_MySQL_Lexer::REGEXP_SYMBOL === $token->id ) { + return $this->translate_regexp_functions( $ast ); } return $this->translate_sequence( $ast->get_children() ); case 'systemVariable': @@ -1416,6 +1418,29 @@ private function translate_like( WP_Parser_Node $node ): string { return $this->translate_sequence( $node->get_children() ); } + private function translate_regexp_functions( WP_Parser_Node $node ): string { + $tokens = $node->get_descendant_tokens(); + $is_binary = isset( $tokens[1] ) && WP_MySQL_Lexer::BINARY_SYMBOL === $tokens[1]->id; + + /* + * If the query says REGEXP BINARY, the comparison is byte-by-byte + * and letter casing matters – lowercase and uppercase letters are + * represented using different byte codes. + * + * The REGEXP function can't be easily made to accept two + * parameters, so we'll have to use a hack to get around this. + * + * If the first character of the pattern is a null byte, we'll + * remove it and make the comparison case-sensitive. This should + * be reasonably safe since PHP does not allow null bytes in + * regular expressions anyway. + */ + if ( true === $is_binary ) { + return 'REGEXP CHAR(0) || ' . $this->translate( $node->get_child_node() ); + } + return 'REGEXP ' . $this->translate( $node->get_child_node() ); + } + private function get_sqlite_create_table_statement( string $table_name, ?string $new_table_name = null ): array { // 1. Get table info. $table_info = $this->execute_sqlite_query(