You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
php -r '(new PDO("mysql:host=mysql", "root", "atk4_pass_root"))->exec("ALTER USER '"'"'atk4_test_user'"'"'@'"'"'%'"'"' WITH MAX_USER_CONNECTIONS 5");'
passes, but with MariaDB:
php -r '(new PDO("mysql:host=mariadb", "root", "atk4_pass_root"))->exec("ALTER USER '"'"'atk4_test_user'"'"'@'"'"'%'"'"' WITH MAX_USER_CONNECTIONS 5");
it fails with the following error:
PDOException: SQLSTATE[HY000] [2054] Server sent charset unknown to the client. Please, report to the developers in Command line code:1
Stack trace:
#0 Command line code(1): PDO->__construct('mysql:host=mari...', 'root', 'atk4_pass_root')
#1 {main}
thrown in Command line code on line 1
With MariaDB 11.2, the PHP is working perfectly.
I am not sure if this is MariaDB or PHP error, but I would expect at least a better error message.
At least, it does not reproduce with the master php built on my ubuntu.
Did you use the php distributed with Alpine? Or did you build it yourself on Alpine?
@AirBair
Thank you! The URL you provided means that this problem is on the MariaDB side. (I was initially worried that mysqlnd might be showing spurious errors)
This is not a PHP issue, so I Close it. Thank you!
I am not sure if the issue should be closed, as any other cli client can connect to MariaDB, so maybe the php mysqli native driver needs some tweaks even if this breakage was introduced from MariaDB server side.
mnd_sprintf(&msg, 0, "Server sent charset (%d) unknown to the client. Please, report to the developers", greet_packet.charset_no);
The server sends 0 in the server default collation byte of the initial handshake packet for collations that are above 1..255 range.
But actually the connector is mainly interested in the character set, not the collation.
In MySQL-4.0 the client received the collation ID in the initial handshake packet from the server and set its own localization specific variables accordingly, to make things like strcasemp() work like on the server side.
Since MySQL-4.1 (which was released in ~2003) it works the other way around: the client sends its desired character set to the server. This collation ID in the handshake packet does not mean anything useful. It was preserved only for 4.0 client compatibility.
We are planning on working around this on the server side by downgrading the collation ID for legacy behaviour (https://jira.mariadb.org/browse/MDEV-32975). But the real fix should also be done in the PHP connector - it should not read this collation ID at all.
Reacted by Nora Dossche, Michael Voříšek, David CARLIER, James Gilliland, jadeops, Kamil Tekiela, Marcos Marcolin, Cecil Zorg and negtak
This was reported as https://jira.mariadb.org/browse/MDEV-32975 and it's marked as blocker, meaning it blocks the release, so the fix almost certainly will be in the next release of MariaDB.
As for what you can do, if you don't want to hard-code a specific charset (utf8mb3 looks rather safe), you can fail to connect, saying "buggy mariadb version please upgrade" — but please don't do that until there is a MariaDB version to upgrade to.
Regarding the charset ID specified in the handshake response, both utf8mb4_general_ci (45) and utf8mb4_unicode_ci (224) are utf8mb4, but will the behavior change?
Since character_set_client etc. are simply displayed as utf8mb4, I expect that the behavior will be the same no matter which one is specified.
@SakiTakamachi the character set between these two is the same, the difference is the collation, the way the characters are sorted and compared (ORDER BY and LIKE clauses for example). The _general_ci is faster, but less accurate for sorting. It doesn't support expansions, contractions and ignorable characters. _unicode_ci is more correct. For example, in _general_ci ß = s but in _unicode_ci ß = ss.
@LinuxJedi
Thank you. That is, when it comes to character_set_client, character_set_connection and character_set_results, there is no sorting, so am I correct in understanding that these character sets will have the same behavior?
@LinuxJedi Thank you. That is, when it comes to character_set_client, character_set_connection and character_set_results, there is no sorting, so am I correct in understanding that these character sets will have the same behavior?
Correct, and _general_ci is the oldest supported collation for that character set.
@SakiTakamachi you're right. This was discussed in https://jira.mariadb.org/browse/MDEV-32966 and the conclusion was that if a given collation is above 255, then a connector can always use a default collation instead, because default collations are below 255 and the charset is the same anyway.
Activity
SakiTakamachi commentedon Feb 21, 2024
At least, it does not reproduce with the master php built on my ubuntu.
Did you use the php distributed with Alpine? Or did you build it yourself on Alpine?
mvorisek commentedon Feb 21, 2024
Official PHP base image and mysqli and pdo_mysql installed using https://github.com/mlocati/docker-php-extension-installer.
SakiTakamachi commentedon Feb 21, 2024
Can you provide repro code without dependencies?
At least, I was not able to reproduce it using the code you provided.
AirBair commentedon Feb 21, 2024
Run into the same issue and found more context/examples here : MariaDB/mariadb-docker#560
SakiTakamachi commentedon Feb 21, 2024
@AirBair
Thank you! The URL you provided means that this problem is on the MariaDB side. (I was initially worried that mysqlnd might be showing spurious errors)
This is not a PHP issue, so I Close it. Thank you!
mvorisek commentedon Feb 21, 2024
Here is a full repro: https://github.com/atk4/data/blob/576cc2d2df48ac88ad45c5c3b5b4f8758fab0981/.github/workflows/test-unit.yml:
I am not sure if the issue should be closed, as any other cli client can connect to MariaDB, so maybe the php mysqli native driver needs some tweaks even if this breakage was introduced from MariaDB server side.
LinuxJedi commentedon Feb 21, 2024
Hi, I'm from the MariaDB Foundation.
This could actually be seen as a bug in mysqlnd because it is using behaviour that went away in MySQL 4.1, 20 years ago.
For reference:
php-src/ext/mysqlnd/mysqlnd_commands.c
Line 619 in 642e111
The server sends 0 in the server default collation byte of the initial handshake packet for collations that are above 1..255 range.
But actually the connector is mainly interested in the character set, not the collation.
In MySQL-4.0 the client received the collation ID in the initial handshake packet from the server and set its own localization specific variables accordingly, to make things like strcasemp() work like on the server side.
Since MySQL-4.1 (which was released in ~2003) it works the other way around: the client sends its desired character set to the server. This collation ID in the handshake packet does not mean anything useful. It was preserved only for 4.0 client compatibility.
We are planning on working around this on the server side by downgrading the collation ID for legacy behaviour (https://jira.mariadb.org/browse/MDEV-32975). But the real fix should also be done in the PHP connector - it should not read this collation ID at all.
ndossche commentedon Feb 21, 2024
Thanks for the clarification. This would indeed need a proper fix at PHP's side then.
21 remaining items
LinuxJedi commentedon Feb 23, 2024
My gut feeling would be that to maintain you current behaviour, of you receive a zero for the charset byte, set your charset to 0x21.
I will send a message to MariaDB engineers now and will ask them to assist.
vuvova commentedon Feb 23, 2024
This was reported as https://jira.mariadb.org/browse/MDEV-32975 and it's marked as blocker, meaning it blocks the release, so the fix almost certainly will be in the next release of MariaDB.
As for what you can do, if you don't want to hard-code a specific charset (utf8mb3 looks rather safe), you can fail to connect, saying "buggy mariadb version please upgrade" — but please don't do that until there is a MariaDB version to upgrade to.
SakiTakamachi commentedon Feb 29, 2024
@LinuxJedi
Hi. Let me ask you a question.
Regarding the charset ID specified in the handshake response, both
utf8mb4_general_ci(45) andutf8mb4_unicode_ci(224) are utf8mb4, but will the behavior change?Since
character_set_clientetc. are simply displayed asutf8mb4, I expect that the behavior will be the same no matter which one is specified.LinuxJedi commentedon Feb 29, 2024
@SakiTakamachi the character set between these two is the same, the difference is the collation, the way the characters are sorted and compared (
ORDER BYandLIKEclauses for example). The _general_ci is faster, but less accurate for sorting. It doesn't support expansions, contractions and ignorable characters. _unicode_ci is more correct. For example, in _general_ciß = sbut in _unicode_ciß = ss.SakiTakamachi commentedon Feb 29, 2024
@LinuxJedi
Thank you. That is, when it comes to
character_set_client,character_set_connectionandcharacter_set_results, there is no sorting, so am I correct in understanding that these character sets will have the same behavior?LinuxJedi commentedon Feb 29, 2024
Correct, and _general_ci is the oldest supported collation for that character set.
SakiTakamachi commentedon Feb 29, 2024
Thank you! This information is very useful in helping us come up with a default connection character set.
vuvova commentedon Feb 29, 2024
@SakiTakamachi you're right. This was discussed in https://jira.mariadb.org/browse/MDEV-32966 and the conclusion was that if a given collation is above 255, then a connector can always use a default collation instead, because default collations are below 255 and the charset is the same anyway.
And that's how https://jira.mariadb.org/browse/MDEV-32975 was fixed in MariaDB/server@1b37cb7
SakiTakamachi commentedon Feb 29, 2024
@vuvova
Thank you. The fact that we reached the same conclusion with MariaDB is very reassuring to us.
Fixed handshake response charset. (#13470)
Fixed handshake response charset. (#13470)