Skip to content

Commit 06f6535

Browse files
committed
Bug#29621062: MERGE FIELD::SEND_TEXT() AND FIELD::SEND_BINARY()
The Protocol class has functions for sending values of different types to the client, one function per type. When sending values that come from an Item, the function for the corresponding type is called. When sending a value from a Field, different Protocol functions are called depending on which protocol is used. If the text protocol is used, Field::send_text() converts the value to string and calls the Protocol function that sends a string value to the client. If the binary protocol is used, Field::send_binary() calls the Protocol function for the actual type of the value, without converting it to string first. This causes inconsistencies between the text protocol and the binary protocol, and also inconsistencies within the text protocol between values that come from Items and values from Fields. This patch merges Field::send_text() and Field::send_binary() into a single function, Field::send_to_protocol(). This function behaves as the old Field::send_binary() and calls the Protocol function that corresponds to the value that is to be sent, without converting it to string first. When the text protocol is used, the value is still converted to a string, but the conversion happens in the Protocol_text class. The Protocol_text class is already capable of converting values to strings, but it is not aware of the ZEROFILL option of numeric types. A new zerofill argument was therefore added to the functions for sending numeric values. The argument is ignored by other protocols than Protocol_text, as they leave it to the clients to format the values. Protocol_text::store(float, ...) used to promote the float argument to double before converting it to string, which could make the returned value presented in higher precision than warranted (like 2.299999952316284 instead of 2.3). It is changed to format the float argument as a float, to be consistent with how it was previously handled for Fields, and with how the binary protocol handles it. Field_time_common::send_binary() has code that normalizes hours and days in the MYSQL_TIME struct. This normalization is only needed by the binary protocol (in fact, the text protocol does not expect it), and it is done redundantly in Protocol_binary::store_time(). The code is removed from Field_time_common, so that it is only performed by Protocol_binary. The Protocol_callback class has a flag which controls whether fields are sent as strings or as native types. This flag is kept, but the conversion from native types to string is moved into Protocol_callback::store_field(). Some tests results were changed, mainly because the formatting of floats resulting from Items changed in the text protocol to match floats from Fields and floats in general in the binary protocol. Some test cases which were previously disabled for the binary protocol because they gave different results on text and binary, have been enabled, as they now produce the same result with both protocols. Change-Id: I788a10eb8eb7ec2fe3d4866d0a50dd08c0ac3255
1 parent 37291ef commit 06f6535

38 files changed

+562
-538
lines changed

include/sql_string.h

+21
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,29 @@ class String {
322322
bool set(ulonglong num, const CHARSET_INFO *cs) {
323323
return set_int((longlong)num, true, cs);
324324
}
325+
326+
/**
327+
Sets the contents of this string to the string representation of the given
328+
double value.
329+
330+
@param num the double value
331+
@param decimals the number of decimals
332+
@param cs the character set of the string
333+
@return false on success, true on error
334+
*/
325335
bool set_real(double num, uint decimals, const CHARSET_INFO *cs);
326336

337+
/**
338+
Sets the contents of this string to the string representation of the given
339+
float value.
340+
341+
@param num the float value
342+
@param decimals the number of decimals
343+
@param cs the character set of the string
344+
@return false on success, true on error
345+
*/
346+
bool set_float(float num, uint decimals, const CHARSET_INFO *cs);
347+
327348
/*
328349
PMG 2004.11.12
329350
This is a method that works the same as perl's "chop". It simply

mysql-test/include/select.inc

-2
Original file line numberDiff line numberDiff line change
@@ -2335,7 +2335,6 @@ DROP TABLE IF EXISTS t1,t2;
23352335
#
23362336
# Bug #20954 "avg(keyval) retuns 0.38 but max(keyval) returns an empty set"
23372337
#
2338-
--disable_ps_protocol
23392338
CREATE TABLE t1 (key1 float default NULL, UNIQUE KEY key1 (key1));
23402339
CREATE TABLE t2 (key2 float default NULL, UNIQUE KEY key2 (key2));
23412340
INSERT INTO t1 VALUES (0.3762),(0.3845),(0.6158),(0.7941);
@@ -2360,7 +2359,6 @@ select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
23602359
select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
23612360

23622361
DROP TABLE t1,t2;
2363-
--enable_ps_protocol
23642362

23652363
#
23662364
# Bug #18759 "Incorrect string to numeric conversion"

mysql-test/r/cast.result

+5-5
Original file line numberDiff line numberDiff line change
@@ -606,10 +606,10 @@ CAST(1/3 AS DOUBLE) as double_col,
606606
CAST(1/3 AS DOUBLE PRECISION) as double_prec_col,
607607
CAST(1/3 AS REAL) as real_col;
608608
float_col double_col double_prec_col real_col
609-
0.3333333432674408 0.333333333 0.333333333 0.333333333
609+
0.333333 0.333333333 0.333333333 0.333333333
610610
SELECT CAST(1/3 AS FLOAT(10)), CAST(1/3 AS FLOAT(53));
611611
CAST(1/3 AS FLOAT(10)) CAST(1/3 AS FLOAT(53))
612-
0.3333333432674408 0.333333333
612+
0.333333 0.333333333
613613
SELECT CAST(1/3 AS FLOAT(-1));
614614
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1))' at line 1
615615
SELECT CAST(1/3 AS FLOAT(54));
@@ -639,15 +639,15 @@ CAST(TIME'23:59:59' AS FLOAT) CAST(TIME'23:59:59' AS DOUBLE)
639639
SELECT CAST(TIME'23:59:59.123456' AS FLOAT),
640640
CAST(TIME'23:59:59.123456' AS DOUBLE);
641641
CAST(TIME'23:59:59.123456' AS FLOAT) CAST(TIME'23:59:59.123456' AS DOUBLE)
642-
235959.125 235959.123456
642+
235959 235959.123456
643643
SELECT CAST(TIMESTAMP'2000-01-01 23:59:59' AS FLOAT),
644644
CAST(TIMESTAMP'2000-01-01 23:59:59' AS DOUBLE);
645645
CAST(TIMESTAMP'2000-01-01 23:59:59' AS FLOAT) CAST(TIMESTAMP'2000-01-01 23:59:59' AS DOUBLE)
646-
20000100319232 20000101235959
646+
20000100000000 20000101235959
647647
SELECT CAST(TIMESTAMP'2000-01-01 23:59:59.123456' AS FLOAT),
648648
CAST(TIMESTAMP'2000-01-01 23:59:59.123456' AS DOUBLE);
649649
CAST(TIMESTAMP'2000-01-01 23:59:59.123456' AS FLOAT) CAST(TIMESTAMP'2000-01-01 23:59:59.123456' AS DOUBLE)
650-
20000100319232 20000101235959.125
650+
20000100000000 20000101235959.125
651651
CREATE TABLE t1 as SELECT CAST(1/3 AS FLOAT) as float_col,
652652
CAST(1/3 AS DOUBLE) as double_col,
653653
CAST(CAST(999.00009 AS DECIMAL(7,4)) AS DOUBLE) as d2;

mysql-test/r/mysqltest.result

+2-2
Original file line numberDiff line numberDiff line change
@@ -648,13 +648,13 @@ Warnings:
648648
Warning 3719 'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous.
649649
mysqltest: The test didn't produce any output
650650
Failing multi statement query
651-
mysqltest: At line 3: Query 'create table t1 (a int primary key);
651+
mysqltest: At line 2: Query 'create table t1 (a int primary key);
652652
insert into t1 values (1);
653653
select 'select-me';
654654
insertz 'error query'' failed.
655655
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'insertz 'error query'' at line 1
656656
drop table t1;
657-
mysqltest: At line 3: Query 'create table t1 (a int primary key);
657+
mysqltest: At line 2: Query 'create table t1 (a int primary key);
658658
insert into t1 values (1);
659659
select 'select-me';
660660
insertz 'error query'' failed.

mysql-test/r/select_all.result

+7-7
Original file line numberDiff line numberDiff line change
@@ -2910,26 +2910,26 @@ Warnings:
29102910
Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
29112911
select max(key1) from t1 where key1 <= 0.6158;
29122912
max(key1)
2913-
0.6158000230789185
2913+
0.6158
29142914
select max(key2) from t2 where key2 <= 1.6158;
29152915
max(key2)
2916-
1.6158000230789185
2916+
1.6158
29172917
select min(key1) from t1 where key1 >= 0.3762;
29182918
min(key1)
2919-
0.37619999051094055
2919+
0.3762
29202920
select min(key2) from t2 where key2 >= 1.3762;
29212921
min(key2)
2922-
1.3761999607086182
2922+
1.3762
29232923
select max(key1), min(key2) from t1, t2
29242924
where key1 <= 0.6158 and key2 >= 1.3762;
29252925
max(key1) min(key2)
2926-
0.6158000230789185 1.3761999607086182
2926+
0.6158 1.3762
29272927
select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
29282928
max(key1)
2929-
0.6158000230789185
2929+
0.6158
29302930
select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
29312931
min(key1)
2932-
0.37619999051094055
2932+
0.3762
29332933
DROP TABLE t1,t2;
29342934
CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL);
29352935
INSERT INTO t1 VALUES (10);

mysql-test/r/select_all_bka.result

+7-7
Original file line numberDiff line numberDiff line change
@@ -2911,26 +2911,26 @@ Warnings:
29112911
Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
29122912
select max(key1) from t1 where key1 <= 0.6158;
29132913
max(key1)
2914-
0.6158000230789185
2914+
0.6158
29152915
select max(key2) from t2 where key2 <= 1.6158;
29162916
max(key2)
2917-
1.6158000230789185
2917+
1.6158
29182918
select min(key1) from t1 where key1 >= 0.3762;
29192919
min(key1)
2920-
0.37619999051094055
2920+
0.3762
29212921
select min(key2) from t2 where key2 >= 1.3762;
29222922
min(key2)
2923-
1.3761999607086182
2923+
1.3762
29242924
select max(key1), min(key2) from t1, t2
29252925
where key1 <= 0.6158 and key2 >= 1.3762;
29262926
max(key1) min(key2)
2927-
0.6158000230789185 1.3761999607086182
2927+
0.6158 1.3762
29282928
select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
29292929
max(key1)
2930-
0.6158000230789185
2930+
0.6158
29312931
select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
29322932
min(key1)
2933-
0.37619999051094055
2933+
0.3762
29342934
DROP TABLE t1,t2;
29352935
CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL);
29362936
INSERT INTO t1 VALUES (10);

mysql-test/r/select_all_bka_nixbnl.result

+7-7
Original file line numberDiff line numberDiff line change
@@ -2911,26 +2911,26 @@ Warnings:
29112911
Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
29122912
select max(key1) from t1 where key1 <= 0.6158;
29132913
max(key1)
2914-
0.6158000230789185
2914+
0.6158
29152915
select max(key2) from t2 where key2 <= 1.6158;
29162916
max(key2)
2917-
1.6158000230789185
2917+
1.6158
29182918
select min(key1) from t1 where key1 >= 0.3762;
29192919
min(key1)
2920-
0.37619999051094055
2920+
0.3762
29212921
select min(key2) from t2 where key2 >= 1.3762;
29222922
min(key2)
2923-
1.3761999607086182
2923+
1.3762
29242924
select max(key1), min(key2) from t1, t2
29252925
where key1 <= 0.6158 and key2 >= 1.3762;
29262926
max(key1) min(key2)
2927-
0.6158000230789185 1.3761999607086182
2927+
0.6158 1.3762
29282928
select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
29292929
max(key1)
2930-
0.6158000230789185
2930+
0.6158
29312931
select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
29322932
min(key1)
2933-
0.37619999051094055
2933+
0.3762
29342934
DROP TABLE t1,t2;
29352935
CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL);
29362936
INSERT INTO t1 VALUES (10);

mysql-test/r/select_icp_mrr.result

+7-7
Original file line numberDiff line numberDiff line change
@@ -2910,26 +2910,26 @@ Warnings:
29102910
Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
29112911
select max(key1) from t1 where key1 <= 0.6158;
29122912
max(key1)
2913-
0.6158000230789185
2913+
0.6158
29142914
select max(key2) from t2 where key2 <= 1.6158;
29152915
max(key2)
2916-
1.6158000230789185
2916+
1.6158
29172917
select min(key1) from t1 where key1 >= 0.3762;
29182918
min(key1)
2919-
0.37619999051094055
2919+
0.3762
29202920
select min(key2) from t2 where key2 >= 1.3762;
29212921
min(key2)
2922-
1.3761999607086182
2922+
1.3762
29232923
select max(key1), min(key2) from t1, t2
29242924
where key1 <= 0.6158 and key2 >= 1.3762;
29252925
max(key1) min(key2)
2926-
0.6158000230789185 1.3761999607086182
2926+
0.6158 1.3762
29272927
select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
29282928
max(key1)
2929-
0.6158000230789185
2929+
0.6158
29302930
select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
29312931
min(key1)
2932-
0.37619999051094055
2932+
0.3762
29332933
DROP TABLE t1,t2;
29342934
CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL);
29352935
INSERT INTO t1 VALUES (10);

mysql-test/r/select_icp_mrr_bka.result

+7-7
Original file line numberDiff line numberDiff line change
@@ -2911,26 +2911,26 @@ Warnings:
29112911
Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
29122912
select max(key1) from t1 where key1 <= 0.6158;
29132913
max(key1)
2914-
0.6158000230789185
2914+
0.6158
29152915
select max(key2) from t2 where key2 <= 1.6158;
29162916
max(key2)
2917-
1.6158000230789185
2917+
1.6158
29182918
select min(key1) from t1 where key1 >= 0.3762;
29192919
min(key1)
2920-
0.37619999051094055
2920+
0.3762
29212921
select min(key2) from t2 where key2 >= 1.3762;
29222922
min(key2)
2923-
1.3761999607086182
2923+
1.3762
29242924
select max(key1), min(key2) from t1, t2
29252925
where key1 <= 0.6158 and key2 >= 1.3762;
29262926
max(key1) min(key2)
2927-
0.6158000230789185 1.3761999607086182
2927+
0.6158 1.3762
29282928
select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
29292929
max(key1)
2930-
0.6158000230789185
2930+
0.6158
29312931
select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
29322932
min(key1)
2933-
0.37619999051094055
2933+
0.3762
29342934
DROP TABLE t1,t2;
29352935
CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL);
29362936
INSERT INTO t1 VALUES (10);

mysql-test/r/select_icp_mrr_bka_nixbnl.result

+7-7
Original file line numberDiff line numberDiff line change
@@ -2911,26 +2911,26 @@ Warnings:
29112911
Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
29122912
select max(key1) from t1 where key1 <= 0.6158;
29132913
max(key1)
2914-
0.6158000230789185
2914+
0.6158
29152915
select max(key2) from t2 where key2 <= 1.6158;
29162916
max(key2)
2917-
1.6158000230789185
2917+
1.6158
29182918
select min(key1) from t1 where key1 >= 0.3762;
29192919
min(key1)
2920-
0.37619999051094055
2920+
0.3762
29212921
select min(key2) from t2 where key2 >= 1.3762;
29222922
min(key2)
2923-
1.3761999607086182
2923+
1.3762
29242924
select max(key1), min(key2) from t1, t2
29252925
where key1 <= 0.6158 and key2 >= 1.3762;
29262926
max(key1) min(key2)
2927-
0.6158000230789185 1.3761999607086182
2927+
0.6158 1.3762
29282928
select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
29292929
max(key1)
2930-
0.6158000230789185
2930+
0.6158
29312931
select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
29322932
min(key1)
2933-
0.37619999051094055
2933+
0.3762
29342934
DROP TABLE t1,t2;
29352935
CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL);
29362936
INSERT INTO t1 VALUES (10);

mysql-test/r/select_none.result

+7-7
Original file line numberDiff line numberDiff line change
@@ -2909,26 +2909,26 @@ Warnings:
29092909
Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
29102910
select max(key1) from t1 where key1 <= 0.6158;
29112911
max(key1)
2912-
0.6158000230789185
2912+
0.6158
29132913
select max(key2) from t2 where key2 <= 1.6158;
29142914
max(key2)
2915-
1.6158000230789185
2915+
1.6158
29162916
select min(key1) from t1 where key1 >= 0.3762;
29172917
min(key1)
2918-
0.37619999051094055
2918+
0.3762
29192919
select min(key2) from t2 where key2 >= 1.3762;
29202920
min(key2)
2921-
1.3761999607086182
2921+
1.3762
29222922
select max(key1), min(key2) from t1, t2
29232923
where key1 <= 0.6158 and key2 >= 1.3762;
29242924
max(key1) min(key2)
2925-
0.6158000230789185 1.3761999607086182
2925+
0.6158 1.3762
29262926
select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
29272927
max(key1)
2928-
0.6158000230789185
2928+
0.6158
29292929
select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
29302930
min(key1)
2931-
0.37619999051094055
2931+
0.3762
29322932
DROP TABLE t1,t2;
29332933
CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL);
29342934
INSERT INTO t1 VALUES (10);

mysql-test/r/select_none_bka.result

+7-7
Original file line numberDiff line numberDiff line change
@@ -2910,26 +2910,26 @@ Warnings:
29102910
Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
29112911
select max(key1) from t1 where key1 <= 0.6158;
29122912
max(key1)
2913-
0.6158000230789185
2913+
0.6158
29142914
select max(key2) from t2 where key2 <= 1.6158;
29152915
max(key2)
2916-
1.6158000230789185
2916+
1.6158
29172917
select min(key1) from t1 where key1 >= 0.3762;
29182918
min(key1)
2919-
0.37619999051094055
2919+
0.3762
29202920
select min(key2) from t2 where key2 >= 1.3762;
29212921
min(key2)
2922-
1.3761999607086182
2922+
1.3762
29232923
select max(key1), min(key2) from t1, t2
29242924
where key1 <= 0.6158 and key2 >= 1.3762;
29252925
max(key1) min(key2)
2926-
0.6158000230789185 1.3761999607086182
2926+
0.6158 1.3762
29272927
select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
29282928
max(key1)
2929-
0.6158000230789185
2929+
0.6158
29302930
select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
29312931
min(key1)
2932-
0.37619999051094055
2932+
0.3762
29332933
DROP TABLE t1,t2;
29342934
CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL);
29352935
INSERT INTO t1 VALUES (10);

mysql-test/r/select_none_bka_nixbnl.result

+7-7
Original file line numberDiff line numberDiff line change
@@ -2910,26 +2910,26 @@ Warnings:
29102910
Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
29112911
select max(key1) from t1 where key1 <= 0.6158;
29122912
max(key1)
2913-
0.6158000230789185
2913+
0.6158
29142914
select max(key2) from t2 where key2 <= 1.6158;
29152915
max(key2)
2916-
1.6158000230789185
2916+
1.6158
29172917
select min(key1) from t1 where key1 >= 0.3762;
29182918
min(key1)
2919-
0.37619999051094055
2919+
0.3762
29202920
select min(key2) from t2 where key2 >= 1.3762;
29212921
min(key2)
2922-
1.3761999607086182
2922+
1.3762
29232923
select max(key1), min(key2) from t1, t2
29242924
where key1 <= 0.6158 and key2 >= 1.3762;
29252925
max(key1) min(key2)
2926-
0.6158000230789185 1.3761999607086182
2926+
0.6158 1.3762
29272927
select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
29282928
max(key1)
2929-
0.6158000230789185
2929+
0.6158
29302930
select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
29312931
min(key1)
2932-
0.37619999051094055
2932+
0.3762
29332933
DROP TABLE t1,t2;
29342934
CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL);
29352935
INSERT INTO t1 VALUES (10);

0 commit comments

Comments
 (0)