Skip to content

Conversation

JanJakes
Copy link
Member

Add support for all binary and hexadecimal literal syntaxes. The differences are:

  1. In MySQL, 0x… is a binary literal, while in SQLite it’s a numeric one.
  2. In MySQL, 0b..., b'...', and B'...' syntaxes can be used to represent binary literals. SQLite only supports HEX literals (x'...').

This PR implements the following conversions:

  1. Convert 0x... to x'...'.
  2. Convert 0b..., b'...', and B'...' to x'...' with binary to hexadecimal conversion.

@JanJakes JanJakes requested a review from adamziel September 17, 2025 07:28
// 0b...
$value = substr( $value, 2 );
} else {
// b'...' or B'...'
Copy link
Collaborator

@adamziel adamziel Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also account for X'01', x'01', _binary X'01', and _binary x'01'? Or are these fine because we can just preserve them as they are and we won't see them in this else?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adamziel X'01' and x'01' will be HEX literals and processed in the case below (HEX_NUMBER). So they should never appear under the WP_MySQL_Lexer::BIN_NUMBER token. These are valid in SQLite, so that case leaves them as is (only 0x... is translated).

For _binary x'01', I think the cast syntax will fail in SQLite at the moment, but behavior-wise, it should be fine, as both x'41' and _binary x'41' represent the same binary bytes — with SELECT, you get A as a result in both cases.

@adamziel adamziel merged commit d70701a into develop Sep 17, 2025
14 checks passed
@adamziel adamziel deleted the bin-hex-literals branch September 17, 2025 10:18
@f1-outsourcing
Copy link

@JanJakes is there some install manual?? Nothing seems to work.

#247

JanJakes added a commit that referenced this pull request Oct 2, 2025
…tation (#255)

This fixes the following error:
```bash
SQLSTATE[HY000]: General error: 1 unrecognized token: "x'1'"
```

For queries like the following:
```sql
SELECT 0b1;
SELECT 0b01;
SELECT 0b001;
...
```

SQLite doesn't have binary string literals, so [we need to convert them
to HEX string
literals](#245).
However, HEX string literals in SQLite must be aligned to full bytes
(their length needs to be even) — `x'01'` is valid, while `x'1'` is
invalid.

In MySQL, binary strings don't require such alignment, and `0b1` is
valid (and `SELECT 0b1 = 0b01` returns `true`).

Additionally, the `base_convert()` function used in the [original
implementation](#245)
doesn't preserve existing leading `0` padding.

To solve both of these issues, this PR implements the following:
1. Count how many full bytes the original binary string requires.
2. Make sure the resulting HEX string has that number of bytes, using
leading `0` padding.

For HEX strings, this fix is not needed, as those require to be
byte-aligned also in MySQL, so throwing an error for `x'1'` is actually
correct.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants