Skip to content

Commit a5ee8dd

Browse files
committed
Add support for all binary and hexadecimal literal syntaxes
1 parent f273cdc commit a5ee8dd

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

tests/WP_SQLite_Driver_Tests.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6873,4 +6873,26 @@ public function testUpdateWithJoinComplexQuery(): void {
68736873
SET claim_id = 37, last_attempt_gmt = '2025-09-03 12:23:55', last_attempt_local = '2025-09-03 12:23:55'"
68746874
);
68756875
}
6876+
6877+
public function testBinaryLiterals(): void {
6878+
$result = $this->assertQuery( 'SELECT 0b0100000101111010' );
6879+
$this->assertEquals( array( (object) array( '0b0100000101111010' => 'Az' ) ), $result );
6880+
6881+
$result = $this->assertQuery( "SELECT b'0100000101111010'" );
6882+
$this->assertEquals( array( (object) array( "b'0100000101111010'" => 'Az' ) ), $result );
6883+
6884+
$result = $this->assertQuery( "SELECT B'0100000101111010'" );
6885+
$this->assertEquals( array( (object) array( "B'0100000101111010'" => 'Az' ) ), $result );
6886+
}
6887+
6888+
public function testHexadecimalLiterals(): void {
6889+
$result = $this->assertQuery( 'SELECT 0x417a' );
6890+
$this->assertEquals( array( (object) array( '0x417a' => 'Az' ) ), $result );
6891+
6892+
$result = $this->assertQuery( "SELECT x'417a'" );
6893+
$this->assertEquals( array( (object) array( "x'417a'" => 'Az' ) ), $result );
6894+
6895+
$result = $this->assertQuery( "SELECT X'417a'" );
6896+
$this->assertEquals( array( (object) array( "X'417a'" => 'Az' ) ), $result );
6897+
}
68766898
}

tests/WP_SQLite_Driver_Translation_Tests.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,6 +1328,40 @@ public function testSerialDataTypes(): void {
13281328
);
13291329
}
13301330

1331+
public function testBinaryLiterals(): void {
1332+
// All binary literal syntaxes need to be converted to HEX strings.
1333+
$this->assertQuery(
1334+
"SELECT x'417a' AS `b'0100000101111010'`",
1335+
"SELECT b'0100000101111010'"
1336+
);
1337+
$this->assertQuery(
1338+
"SELECT x'417a' AS `B'0100000101111010'`",
1339+
"SELECT B'0100000101111010'"
1340+
);
1341+
$this->assertQuery(
1342+
"SELECT x'417a' AS `0b0100000101111010`",
1343+
'SELECT 0b0100000101111010'
1344+
);
1345+
}
1346+
1347+
public function testHexadecimalLiterals(): void {
1348+
// The x'...' and X'...' syntax should be preserved as is.
1349+
$this->assertQuery(
1350+
"SELECT x'417a'",
1351+
"SELECT x'417a'"
1352+
);
1353+
$this->assertQuery(
1354+
"SELECT X'417a'",
1355+
"SELECT X'417a'"
1356+
);
1357+
1358+
// The 0x... syntax needs to be translated to x'...'.
1359+
$this->assertQuery(
1360+
"SELECT x'417a' AS `0x417a`",
1361+
'SELECT 0x417a'
1362+
);
1363+
}
1364+
13311365
public function testSystemVariables(): void {
13321366
$this->assertQuery(
13331367
"SELECT 'ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES' AS `@@sql_mode`",

wp-includes/sqlite-ast/class-wp-sqlite-driver.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2860,6 +2860,31 @@ private function translate_token( WP_MySQL_Token $token ): ?string {
28602860
switch ( $token->id ) {
28612861
case WP_MySQL_Lexer::EOF:
28622862
return null;
2863+
case WP_MySQL_Lexer::BIN_NUMBER:
2864+
/*
2865+
* There are no binary literals in SQLite. We need to convert all
2866+
* MySQL binary string values to HEX strings in SQLite (x'...').
2867+
*/
2868+
$value = $token->get_value();
2869+
if ( '0' === $value[0] ) {
2870+
// 0b...
2871+
$value = substr( $value, 2 );
2872+
} else {
2873+
// b'...' or B'...'
2874+
$value = substr( $value, 2, -1 );
2875+
}
2876+
return sprintf( "x'%s'", base_convert( $value, 2, 16 ) );
2877+
case WP_MySQL_Lexer::HEX_NUMBER:
2878+
/*
2879+
* In MySQL, "0x" prefixed values represent binary literal values,
2880+
* while in SQLite, that would be a hexadecimal number. Therefore,
2881+
* we need to convert the 0x... syntax to x'...'.
2882+
*/
2883+
$value = $token->get_value();
2884+
if ( '0' === $value[0] && 'x' === $value[1] ) {
2885+
return sprintf( "x'%s'", substr( $value, 2 ) );
2886+
}
2887+
return $value;
28632888
case WP_MySQL_Lexer::AUTO_INCREMENT_SYMBOL:
28642889
return 'AUTOINCREMENT';
28652890
case WP_MySQL_Lexer::BINARY_SYMBOL:

0 commit comments

Comments
 (0)