Skip to content

Commit f79cd18

Browse files
committed
Fix for Bug #70384 mysqli_real_query(): Unknown type 245 sent by the server
1 parent 8317e0f commit f79cd18

File tree

7 files changed

+78
-1
lines changed

7 files changed

+78
-1
lines changed

ext/mysqli/tests/bug70384.phpt

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
--TEST--
2+
mysqli_float_handling - ensure 4 byte float is handled correctly
3+
--SKIPIF--
4+
<?php
5+
require_once('skipif.inc');
6+
require_once('skipifemb.inc');
7+
require_once('skipifconnectfailure.inc');
8+
if (@$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
9+
if ($link->server_version < 50709) {
10+
die("skip MySQL 5.7.9+ needed. Found [".
11+
intval(substr($link->server_version."", -5, 1)).
12+
".".
13+
intval(substr($link->server_version."", -4, 2)).
14+
".".
15+
intval(substr($link->server_version."", -2, 2)).
16+
"]");
17+
}
18+
}
19+
?>
20+
--FILE--
21+
<?php
22+
require('connect.inc');
23+
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
24+
printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
25+
die();
26+
}
27+
28+
if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) {
29+
printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
30+
die();
31+
}
32+
33+
if (!mysqli_query($link, "CREATE TABLE test(jsfield JSON) ENGINE = InnoDB")) {
34+
printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
35+
die();
36+
}
37+
$jsfield_data = '{"aaa": 123}';
38+
// Insert via string to make sure the real floating number gets to the DB
39+
if (!mysqli_query($link, "INSERT INTO test VALUES ('".$jsfield_data."')")) {
40+
printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
41+
die();
42+
}
43+
44+
if (!($res = mysqli_query($link, "SELECT * FROM test"))) {
45+
printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
46+
die();
47+
}
48+
$rows = $res->fetch_all();
49+
if (json_encode($rows[0][0]) != json_encode($jsfield_data)) {
50+
printf("[006] Data differs");
51+
var_dump(json_encode($rows[0][0]) != json_encode($jsfield_data));
52+
die();
53+
}
54+
mysqli_close($link);
55+
echo "OK";
56+
?>
57+
--CLEAN--
58+
<?php
59+
require_once("clean_table.inc");
60+
?>
61+
--EXPECTF--
62+
OK

ext/mysqli/tests/mysqli_get_client_stats.phpt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,7 @@ if (!mysqli_query($link, "DROP SERVER IF EXISTS myself"))
958958
mysqli_close($link);
959959
?>
960960
--EXPECTF--
961-
array(160) {
961+
array(161) {
962962
[%u|b%"bytes_sent"]=>
963963
%unicode|string%(1) "0"
964964
[%u|b%"bytes_received"]=>
@@ -1203,6 +1203,8 @@ array(160) {
12031203
%unicode|string%(1) "0"
12041204
[%u|b%"proto_binary_fetched_string"]=>
12051205
%unicode|string%(1) "0"
1206+
[%u|b%"proto_binary_fetched_json"]=>
1207+
%unicode|string%(1) "0"
12061208
[%u|b%"proto_binary_fetched_blob"]=>
12071209
%unicode|string%(1) "0"
12081210
[%u|b%"proto_binary_fetched_enum"]=>

ext/mysqlnd/mysqlnd.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2215,6 +2215,8 @@ MYSQLND_METHOD(mysqlnd_conn_data, next_result)(MYSQLND_CONN_DATA * const conn TS
22152215
PHPAPI const char *mysqlnd_field_type_name(enum mysqlnd_field_types field_type)
22162216
{
22172217
switch(field_type) {
2218+
case FIELD_TYPE_JSON:
2219+
return "json";
22182220
case FIELD_TYPE_STRING:
22192221
case FIELD_TYPE_VAR_STRING:
22202222
return "string";

ext/mysqlnd/mysqlnd_enum_n_def.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ typedef enum mysqlnd_field_types
233233
MYSQL_TYPE_NEWDATE = 14,
234234
MYSQL_TYPE_VARCHAR = 15,
235235
MYSQL_TYPE_BIT = 16,
236+
MYSQL_TYPE_JSON=245,
236237
MYSQL_TYPE_NEWDECIMAL=246,
237238
MYSQL_TYPE_ENUM=247,
238239
MYSQL_TYPE_SET=248,
@@ -274,6 +275,7 @@ typedef enum mysqlnd_server_option
274275
#define FIELD_TYPE_NEWDATE MYSQL_TYPE_NEWDATE
275276
#define FIELD_TYPE_ENUM MYSQL_TYPE_ENUM
276277
#define FIELD_TYPE_SET MYSQL_TYPE_SET
278+
#define FIELD_TYPE_JSON MYSQL_TYPE_JSON
277279
#define FIELD_TYPE_TINY_BLOB MYSQL_TYPE_TINY_BLOB
278280
#define FIELD_TYPE_MEDIUM_BLOB MYSQL_TYPE_MEDIUM_BLOB
279281
#define FIELD_TYPE_LONG_BLOB MYSQL_TYPE_LONG_BLOB
@@ -478,6 +480,7 @@ typedef enum mysqlnd_collected_stats
478480
STAT_TEXT_TYPE_FETCHED_DATETIME,
479481
STAT_TEXT_TYPE_FETCHED_TIMESTAMP,
480482
STAT_TEXT_TYPE_FETCHED_STRING,
483+
STAT_TEXT_TYPE_FETCHED_JSON,
481484
STAT_TEXT_TYPE_FETCHED_BLOB,
482485
STAT_TEXT_TYPE_FETCHED_ENUM,
483486
STAT_TEXT_TYPE_FETCHED_SET,

ext/mysqlnd/mysqlnd_ps_codec.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,12 @@ void _mysqlnd_init_ps_fetch_subsystem()
437437
mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].php_type= IS_STRING;
438438
mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].can_ret_as_str_in_uni = TRUE;
439439

440+
mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].func = ps_fetch_string;
441+
mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].pack_len= MYSQLND_PS_SKIP_RESULT_STR;
442+
mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].php_type = IS_STRING;
443+
mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].is_possibly_blob = TRUE;
444+
mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].can_ret_as_str_in_uni = TRUE;
445+
440446
mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].func = ps_fetch_string;
441447
mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].pack_len= MYSQLND_PS_SKIP_RESULT_STR;
442448
mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].php_type = IS_STRING;

ext/mysqlnd/mysqlnd_statistics.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ const MYSQLND_STRING mysqlnd_stats_values_names[STAT_LAST] =
153153
{ MYSQLND_STR_W_LEN("proto_binary_fetched_datetime") },
154154
{ MYSQLND_STR_W_LEN("proto_binary_fetched_timestamp") },
155155
{ MYSQLND_STR_W_LEN("proto_binary_fetched_string") },
156+
{ MYSQLND_STR_W_LEN("proto_binary_fetched_json") },
156157
{ MYSQLND_STR_W_LEN("proto_binary_fetched_blob") },
157158
{ MYSQLND_STR_W_LEN("proto_binary_fetched_enum") },
158159
{ MYSQLND_STR_W_LEN("proto_binary_fetched_set") },

ext/mysqlnd/mysqlnd_wireprotocol.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,6 +1656,7 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer,
16561656
case MYSQL_TYPE_NEWDECIMAL: statistic = STAT_TEXT_TYPE_FETCHED_DECIMAL; break;
16571657
case MYSQL_TYPE_ENUM: statistic = STAT_TEXT_TYPE_FETCHED_ENUM; break;
16581658
case MYSQL_TYPE_SET: statistic = STAT_TEXT_TYPE_FETCHED_SET; break;
1659+
case MYSQL_TYPE_JSON: statistic = STAT_TEXT_TYPE_FETCHED_JSON; break;
16591660
case MYSQL_TYPE_TINY_BLOB: statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break;
16601661
case MYSQL_TYPE_MEDIUM_BLOB:statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break;
16611662
case MYSQL_TYPE_LONG_BLOB: statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break;

0 commit comments

Comments
 (0)