]> granicus.if.org Git - php/commitdiff
Fix for Bug #70384 mysqli_real_query(): Unknown type 245 sent by the server
authorAndrey Hristov <andrey@php.net>
Wed, 23 Sep 2015 15:27:18 +0000 (17:27 +0200)
committerAndrey Hristov <andrey@php.net>
Wed, 23 Sep 2015 16:25:12 +0000 (18:25 +0200)
ext/mysqli/tests/bug70384.phpt [new file with mode: 0644]
ext/mysqli/tests/mysqli_get_client_stats.phpt
ext/mysqlnd/mysqlnd.c
ext/mysqlnd/mysqlnd_enum_n_def.h
ext/mysqlnd/mysqlnd_ps_codec.c
ext/mysqlnd/mysqlnd_statistics.c
ext/mysqlnd/mysqlnd_wireprotocol.c

diff --git a/ext/mysqli/tests/bug70384.phpt b/ext/mysqli/tests/bug70384.phpt
new file mode 100644 (file)
index 0000000..aa8662b
--- /dev/null
@@ -0,0 +1,62 @@
+--TEST--
+mysqli_float_handling - ensure 4 byte float is handled correctly
+--SKIPIF--
+<?php
+       require_once('skipif.inc');
+       require_once('skipifemb.inc');
+       require_once('skipifconnectfailure.inc');
+       if (@$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
+               if ($link->server_version < 50709) {
+                       die("skip MySQL 5.7.9+ needed. Found [".
+                               intval(substr($link->server_version."", -5, 1)).
+                               ".".
+                               intval(substr($link->server_version."", -4, 2)).
+                               ".".
+                               intval(substr($link->server_version."", -2, 2)).
+                               "]");
+               }
+       }
+?>
+--FILE--
+<?php
+       require('connect.inc');
+       if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
+               printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
+               die();
+       }
+
+       if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) {
+               printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+               die();
+       }
+
+       if (!mysqli_query($link, "CREATE TABLE test(jsfield JSON) ENGINE = InnoDB")) {
+               printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+               die();
+       }
+       $jsfield_data = '{"aaa": 123}';
+       // Insert via string to make sure the real floating number gets to the DB
+       if (!mysqli_query($link, "INSERT INTO test VALUES ('".$jsfield_data."')")) {
+               printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+               die();
+       }
+
+       if (!($res = mysqli_query($link, "SELECT *  FROM test"))) {
+               printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+               die();
+       }
+       $rows = $res->fetch_all();
+       if (json_encode($rows[0][0]) != json_encode($jsfield_data)) {
+               printf("[006] Data differs");
+               var_dump(json_encode($rows[0][0]) != json_encode($jsfield_data));
+               die();  
+       }
+       mysqli_close($link);
+       echo "OK";
+?>
+--CLEAN--
+<?php
+       require_once("clean_table.inc");
+?>
+--EXPECTF--
+OK
\ No newline at end of file
index a22fc58f53fe533857dd6e694aa9b62c85dad0e6..ebed88fe3ff891025ee58df89c1b638da7337546 100644 (file)
@@ -958,7 +958,7 @@ if (!mysqli_query($link, "DROP SERVER IF EXISTS myself"))
 mysqli_close($link);
 ?>
 --EXPECTF--
-array(160) {
+array(161) {
   [%u|b%"bytes_sent"]=>
   %unicode|string%(1) "0"
   [%u|b%"bytes_received"]=>
@@ -1203,6 +1203,8 @@ array(160) {
   %unicode|string%(1) "0"
   [%u|b%"proto_binary_fetched_string"]=>
   %unicode|string%(1) "0"
+  [%u|b%"proto_binary_fetched_json"]=>
+  %unicode|string%(1) "0"
   [%u|b%"proto_binary_fetched_blob"]=>
   %unicode|string%(1) "0"
   [%u|b%"proto_binary_fetched_enum"]=>
index 41df2b6cae2530344adf5cca33b9fac07f0f2417..f0089862273a683290a510f2cd8a61ad1ffbb3fe 100644 (file)
@@ -2215,6 +2215,8 @@ MYSQLND_METHOD(mysqlnd_conn_data, next_result)(MYSQLND_CONN_DATA * const conn TS
 PHPAPI const char *mysqlnd_field_type_name(enum mysqlnd_field_types field_type)
 {
        switch(field_type) {
+               case FIELD_TYPE_JSON:
+                       return "json";
                case FIELD_TYPE_STRING:
                case FIELD_TYPE_VAR_STRING:
                        return "string";
index 300d7a8ced51336a4f18110aefc6acf7364c4d5c..c1ede7e65629f56df2304319c8187473889366ea 100644 (file)
@@ -233,6 +233,7 @@ typedef enum mysqlnd_field_types
        MYSQL_TYPE_NEWDATE      = 14,
        MYSQL_TYPE_VARCHAR      = 15,
        MYSQL_TYPE_BIT          = 16,
+       MYSQL_TYPE_JSON=245,
        MYSQL_TYPE_NEWDECIMAL=246,
        MYSQL_TYPE_ENUM=247,
        MYSQL_TYPE_SET=248,
@@ -274,6 +275,7 @@ typedef enum mysqlnd_server_option
 #define FIELD_TYPE_NEWDATE             MYSQL_TYPE_NEWDATE
 #define FIELD_TYPE_ENUM                        MYSQL_TYPE_ENUM
 #define FIELD_TYPE_SET                 MYSQL_TYPE_SET
+#define FIELD_TYPE_JSON                MYSQL_TYPE_JSON
 #define FIELD_TYPE_TINY_BLOB   MYSQL_TYPE_TINY_BLOB
 #define FIELD_TYPE_MEDIUM_BLOB MYSQL_TYPE_MEDIUM_BLOB
 #define FIELD_TYPE_LONG_BLOB   MYSQL_TYPE_LONG_BLOB
@@ -478,6 +480,7 @@ typedef enum mysqlnd_collected_stats
        STAT_TEXT_TYPE_FETCHED_DATETIME,
        STAT_TEXT_TYPE_FETCHED_TIMESTAMP,
        STAT_TEXT_TYPE_FETCHED_STRING,
+       STAT_TEXT_TYPE_FETCHED_JSON,
        STAT_TEXT_TYPE_FETCHED_BLOB,
        STAT_TEXT_TYPE_FETCHED_ENUM,
        STAT_TEXT_TYPE_FETCHED_SET,
index 9a70af0f36a978f422b93e5b20004b41f8a6b1db..8a331a50c6ae730fb8a8e19dd96c30291a9a64d0 100644 (file)
@@ -437,6 +437,12 @@ void _mysqlnd_init_ps_fetch_subsystem()
        mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].php_type= IS_STRING;
        mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].can_ret_as_str_in_uni  = TRUE;
 
+       mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].func        = ps_fetch_string;
+       mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].pack_len= MYSQLND_PS_SKIP_RESULT_STR;
+       mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].php_type = IS_STRING;
+       mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].is_possibly_blob = TRUE;
+       mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].can_ret_as_str_in_uni       = TRUE;
+
        mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].func   = ps_fetch_string;
        mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].pack_len= MYSQLND_PS_SKIP_RESULT_STR;
        mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].php_type = IS_STRING;
index d2fed161f944c97bb8c90a4a270e63bafa602e0d..eb73e9f434387f19fb282147230fb79fa8fb0fe8 100644 (file)
@@ -153,6 +153,7 @@ const MYSQLND_STRING mysqlnd_stats_values_names[STAT_LAST] =
        { MYSQLND_STR_W_LEN("proto_binary_fetched_datetime") },
        { MYSQLND_STR_W_LEN("proto_binary_fetched_timestamp") },
        { MYSQLND_STR_W_LEN("proto_binary_fetched_string") },
+       { MYSQLND_STR_W_LEN("proto_binary_fetched_json") },
        { MYSQLND_STR_W_LEN("proto_binary_fetched_blob") },
        { MYSQLND_STR_W_LEN("proto_binary_fetched_enum") },
        { MYSQLND_STR_W_LEN("proto_binary_fetched_set") },
index c7c0bf91907938ba4aeeb8fa27d5429b49122d7a..5901a863318a2f6b9763bc160d33da71c38eff38 100644 (file)
@@ -1656,6 +1656,7 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer,
                                        case MYSQL_TYPE_NEWDECIMAL:     statistic = STAT_TEXT_TYPE_FETCHED_DECIMAL; break;
                                        case MYSQL_TYPE_ENUM:           statistic = STAT_TEXT_TYPE_FETCHED_ENUM; break;
                                        case MYSQL_TYPE_SET:            statistic = STAT_TEXT_TYPE_FETCHED_SET; break;
+                                       case MYSQL_TYPE_JSON:           statistic = STAT_TEXT_TYPE_FETCHED_JSON; break;
                                        case MYSQL_TYPE_TINY_BLOB:      statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break;
                                        case MYSQL_TYPE_MEDIUM_BLOB:statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break;
                                        case MYSQL_TYPE_LONG_BLOB:      statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break;