diff --git a/packages/mysql-on-sqlite/src/sqlite/class-wp-mysql-on-sqlite.php b/packages/mysql-on-sqlite/src/sqlite/class-wp-mysql-on-sqlite.php index bef1bedeb..42c9cb7ea 100644 --- a/packages/mysql-on-sqlite/src/sqlite/class-wp-mysql-on-sqlite.php +++ b/packages/mysql-on-sqlite/src/sqlite/class-wp-mysql-on-sqlite.php @@ -4579,8 +4579,9 @@ private function translate_token( WP_MySQL_Token $token ): ?string { $value = substr( $value, 2, -1 ); } - // Convert the binary string to HEX. - $hex = base_convert( $value, 2, 16 ); + // Convert the binary string to HEX. An empty value stays empty, + // as "base_convert()" would return "0" for it. + $hex = '' === $value ? '' : base_convert( $value, 2, 16 ); /* * The "base_convert()" function doesn't add or preserve padding. diff --git a/packages/mysql-on-sqlite/tests/WP_MySQL_On_SQLite_Tests.php b/packages/mysql-on-sqlite/tests/WP_MySQL_On_SQLite_Tests.php index 4f87a3a6f..7e6047064 100644 --- a/packages/mysql-on-sqlite/tests/WP_MySQL_On_SQLite_Tests.php +++ b/packages/mysql-on-sqlite/tests/WP_MySQL_On_SQLite_Tests.php @@ -11997,6 +11997,48 @@ public static function oddLengthQuotedHexadecimalLiterals(): array { ); } + public function testEmptyBitLiteral(): void { + // An empty bit-value literal is an empty binary string, like an empty + // hex literal, and not the one-byte value "x'0'". See #612. + $this->assertEquals( + $this->assertQuery( "SELECT x'' AS v" ), + $this->assertQuery( "SELECT b'' AS v" ) + ); + $this->assertEquals( + array( (object) array( 'length' => '0' ) ), + $this->assertQuery( "SELECT LENGTH(b'') AS length" ) + ); + + $this->assertQuery( 'CREATE TABLE t (id INT PRIMARY KEY, data BLOB)' ); + $this->assertQuery( "INSERT INTO t (id, data) VALUES (1, b'')" ); + $this->assertEquals( + array( + (object) array( + 'id' => '1', + 'data' => '', + ), + ), + $this->assertQuery( 'SELECT id, HEX(data) AS data FROM t' ) + ); + } + + public function testEmptyBitLiteralComparesLikeEmptyHexLiteral(): void { + // Hex and bit literals translate to blob literals, and a blob never + // equals a text value in SQLite. MySQL compares the empty binary + // string equal to the empty text string, a difference tracked for + // hex literals in #575. The empty bit literal behaves like the empty + // hex literal, in both directions. + $this->assertEquals( + $this->assertQuery( "SELECT x'' = '' AS v" ), + $this->assertQuery( "SELECT b'' = '' AS v" ) + ); + + $this->assertEquals( + array( (object) array( 'v' => '1' ) ), + $this->assertQuery( "SELECT b'' = x'' AS v" ) + ); + } + public function testColumnInfo(): void { $this->assertQuery( 'CREATE TABLE t (