Repository navigation
[possible degradation] UTF-8 string is now printed in 0x hex form in some cases. #1511
Description
Activity
Hi!
Yes, this is intentional. In #1483, we fixed a bug in which some binary values displayed as text, and other binary values displayed as hex literals, depending on whether the values could be interpreted as UTF-8.
Your expression, simplified as
SELECT AES_DECRYPT(UNHEX(HEX(AES_ENCRYPT('foo@example.com', 'my_secret_key'))),'my_secret_key') AS foo; ┌──────────────────────────────────┐ │ foo │ ├──────────────────────────────────┤ │ 0x666f6f406578616d706c652e636f6d │ └──────────────────────────────────┘
is indeed binary! We can check this using
CHARSET()SELECT CHARSET(AES_DECRYPT(UNHEX(HEX(AES_ENCRYPT('foo@example.com', 'my_secret_key'))),'my_secret_key')) AS foo; ┌────────┐ │ foo │ ├────────┤ │ binary │ └────────┘
The docs for
AES_DECRYPT():explain that
AES_DECRYPT()decrypts the encrypted stringcrypt_strusing the key stringkey_str, and returns the original (binary) string in hexadecimal format. (To obtain the string as plaintext, cast the result to CHAR. Alternatively, start the mysql client with--skip-binary-as-hexto cause all binary values to be displayed as text.)So, using the documented recommendation works:
SELECT CAST(AES_DECRYPT(UNHEX(HEX(AES_ENCRYPT('foo@example.com', 'my_secret_key'))),'my_secret_key') AS CHAR) AS foo; ┌─────────────────┐ │ foo │ ├─────────────────┤ │ foo@example.com │ └─────────────────┘
Though I personally would be more explicit with
CONVERT … USING:SELECT CONVERT(AES_DECRYPT(UNHEX(HEX(AES_ENCRYPT('foo@example.com', 'my_secret_key'))),'my_secret_key') USING utf8mb4) AS foo; ┌─────────────────┐ │ foo │ ├─────────────────┤ │ foo@example.com │ └─────────────────┘
Finally, the display of the original value as a hex literal is consistent with the vendor client.
However, mycli could consider an option like
--skip-binary-as-hexwhich restored the previous behavior, so long as it was not the default.Reacted by ynnReacted by ynn@rolandwalker
Thank you very much for the detailed explanation.
I simply learned many things from your response.
Finally, the display of the original value as a hex literal is consistent with the vendor client.
I confirmed this after reading the documentation you quoted and that of
--skip-binary-as-hex:# interactive session without `--skip-binary-as-hex` $ mysql mysql> SELECT AES_DECRYPT(UNHEX(HEX(AES_ENCRYPT('foo@example.com', 'my_secret_key'))),'my_secret_key') AS foo; +----------------------------------+ | foo | +----------------------------------+ | 0x666F6F406578616D706C652E636F6D | +----------------------------------+
# interactive session with `--skip-binary-as-hex` $ mysql --skip-binary-as-hex mysql> SELECT AES_DECRYPT(UNHEX(HEX(AES_ENCRYPT('foo@example.com', 'my_secret_key'))),'my_secret_key') AS foo; +-----------------+ | foo | +-----------------+ | foo@example.com | +-----------------+
# non-interactive session $ echo "SELECT AES_DECRYPT(UNHEX(HEX(AES_ENCRYPT('foo@example.com', 'my_secret_key'))),'my_secret_key') AS foo;" | mysql foo foo@example.com
However, mycli could consider an option like --skip-binary-as-hex which restored the previous behavior, so long as it was not the default.
Thank you!
I do want this because I have many existing SQL statements which use
AES_DECRYPT()withoutCAST()orCONVERT(); rewriting all of them would be time-consuming.binary_displayoption added in https://github.com/dbcli/mycli/releases/tag/v1.50.0 !Reacted by ynnReacted by ynnReacted by ynn
How to Reproduce
Expected:
I'm 100% sure I used to get this result until recently:
Actual:
Possible Cause?
The changelog of 1.48.0 (2026/01/27) says
Use 0x-style hex literals for binaries in SQL output formats.
Render binary values more consistently as hex literals.
Are these related?