Skip to content

Commit 30f904e

Browse files
committed
Merge mysql.com:/home/ram/work/b19690/b19690.5.0
into mysql.com:/home/ram/work/b19690/b19690.5.1
2 parents 46b3a3d + 0bd1c03 commit 30f904e

11 files changed

Lines changed: 175 additions & 8 deletions

File tree

mysql-test/r/type_float.result

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,77 @@ select 1e-308, 1.00000001e-300, 100000000e-300;
268268
select 10e307;
269269
10e307
270270
1e+308
271+
create table t1(a int, b double(8, 2));
272+
insert into t1 values
273+
(1, 28.50), (1, 121.85), (1, 157.23), (1, 1351.00), (1, -1965.35), (1, 81.75),
274+
(1, 217.08), (1, 7.94), (4, 96.07), (4, 6404.65), (4, -6500.72), (2, 100.00),
275+
(5, 5.00), (5, -2104.80), (5, 2033.80), (5, 0.07), (5, 65.93),
276+
(3, -4986.24), (3, 5.00), (3, 4857.34), (3, 123.74), (3, 0.16),
277+
(6, -1695.31), (6, 1003.77), (6, 499.72), (6, 191.82);
278+
explain select sum(b) s from t1 group by a;
279+
id select_type table type possible_keys key key_len ref rows Extra
280+
1 SIMPLE t1 ALL NULL NULL NULL NULL 26 Using temporary; Using filesort
281+
select sum(b) s from t1 group by a;
282+
s
283+
0.00
284+
100.00
285+
0.00
286+
-0.00
287+
-0.00
288+
0.00
289+
select sum(b) s from t1 group by a having s <> 0;
290+
s
291+
100.00
292+
select sum(b) s from t1 group by a having s <> 0 order by s;
293+
s
294+
100.00
295+
select sum(b) s from t1 group by a having s <=> 0;
296+
s
297+
0.00
298+
0.00
299+
-0.00
300+
-0.00
301+
0.00
302+
select sum(b) s from t1 group by a having s <=> 0 order by s;
303+
s
304+
-0.00
305+
-0.00
306+
0.00
307+
0.00
308+
0.00
309+
alter table t1 add key (a, b);
310+
explain select sum(b) s from t1 group by a;
311+
id select_type table type possible_keys key key_len ref rows Extra
312+
1 SIMPLE t1 index NULL a 14 NULL 26 Using index
313+
select sum(b) s from t1 group by a;
314+
s
315+
0.00
316+
100.00
317+
0.00
318+
-0.00
319+
0.00
320+
0.00
321+
select sum(b) s from t1 group by a having s <> 0;
322+
s
323+
100.00
324+
select sum(b) s from t1 group by a having s <> 0 order by s;
325+
s
326+
100.00
327+
select sum(b) s from t1 group by a having s <=> 0;
328+
s
329+
0.00
330+
0.00
331+
-0.00
332+
0.00
333+
0.00
334+
select sum(b) s from t1 group by a having s <=> 0 order by s;
335+
s
336+
-0.00
337+
0.00
338+
0.00
339+
0.00
340+
0.00
341+
drop table t1;
271342
End of 4.1 tests
272343
create table t1 (s1 float(0,2));
273344
ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 's1').

mysql-test/t/type_float.test

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,31 @@ select 1e-308, 1.00000001e-300, 100000000e-300;
187187
# check if overflows are detected correctly
188188
select 10e307;
189189

190+
#
191+
# Bug #19690: ORDER BY eliminates rows from the result
192+
#
193+
create table t1(a int, b double(8, 2));
194+
insert into t1 values
195+
(1, 28.50), (1, 121.85), (1, 157.23), (1, 1351.00), (1, -1965.35), (1, 81.75),
196+
(1, 217.08), (1, 7.94), (4, 96.07), (4, 6404.65), (4, -6500.72), (2, 100.00),
197+
(5, 5.00), (5, -2104.80), (5, 2033.80), (5, 0.07), (5, 65.93),
198+
(3, -4986.24), (3, 5.00), (3, 4857.34), (3, 123.74), (3, 0.16),
199+
(6, -1695.31), (6, 1003.77), (6, 499.72), (6, 191.82);
200+
explain select sum(b) s from t1 group by a;
201+
select sum(b) s from t1 group by a;
202+
select sum(b) s from t1 group by a having s <> 0;
203+
select sum(b) s from t1 group by a having s <> 0 order by s;
204+
select sum(b) s from t1 group by a having s <=> 0;
205+
select sum(b) s from t1 group by a having s <=> 0 order by s;
206+
alter table t1 add key (a, b);
207+
explain select sum(b) s from t1 group by a;
208+
select sum(b) s from t1 group by a;
209+
select sum(b) s from t1 group by a having s <> 0;
210+
select sum(b) s from t1 group by a having s <> 0 order by s;
211+
select sum(b) s from t1 group by a having s <=> 0;
212+
select sum(b) s from t1 group by a having s <=> 0 order by s;
213+
drop table t1;
214+
190215
--echo End of 4.1 tests
191216

192217
#

sql/field.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4163,7 +4163,7 @@ int Field_double::store(double nr)
41634163
else
41644164
{
41654165
double max_value;
4166-
if (dec >= NOT_FIXED_DEC)
4166+
if (not_fixed)
41674167
{
41684168
max_value= DBL_MAX;
41694169
}

sql/field.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -789,18 +789,27 @@ class Field_float :public Field_real {
789789

790790
class Field_double :public Field_real {
791791
public:
792+
my_bool not_fixed;
792793
Field_double(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
793794
uchar null_bit_arg,
794795
enum utype unireg_check_arg, const char *field_name_arg,
795796
uint8 dec_arg,bool zero_arg,bool unsigned_arg)
796797
:Field_real(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
797798
unireg_check_arg, field_name_arg,
798-
dec_arg, zero_arg, unsigned_arg)
799+
dec_arg, zero_arg, unsigned_arg),
800+
not_fixed(dec_arg >= NOT_FIXED_DEC)
799801
{}
800802
Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg,
801803
uint8 dec_arg)
802-
:Field_real((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, (uint) 0,
803-
NONE, field_name_arg, dec_arg, 0, 0)
804+
:Field_real((char*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0,
805+
NONE, field_name_arg, dec_arg, 0, 0),
806+
not_fixed(dec_arg >= NOT_FIXED_DEC)
807+
{}
808+
Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg,
809+
uint8 dec_arg, my_bool not_fixed_srg)
810+
:Field_real((char*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0,
811+
NONE, field_name_arg, dec_arg, 0, 0),
812+
not_fixed(not_fixed_srg)
804813
{}
805814
enum_field_types type() const { return MYSQL_TYPE_DOUBLE;}
806815
enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; }

sql/init.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,11 @@ void unireg_init(ulong options)
4545
{ /* It's used by filesort... */
4646
log_10[i]= nr ; nr*= 10.0;
4747
}
48+
/* Make a tab of powers of 0.1 */
49+
for (i= 0, nr= 0.1; i < array_elements(log_01); i++)
50+
{
51+
log_01[i]= nr;
52+
nr*= 0.1;
53+
}
4854
DBUG_VOID_RETURN;
4955
}

sql/item_cmpfunc.cc

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,19 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
470470
break;
471471
}
472472
case DECIMAL_RESULT:
473+
break;
473474
case REAL_RESULT:
475+
{
476+
if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
477+
{
478+
precision= 5 * log_01[max((*a)->decimals, (*b)->decimals)];
479+
if (func == &Arg_comparator::compare_real)
480+
func= &Arg_comparator::compare_real_fixed;
481+
else if (func == &Arg_comparator::compare_e_real)
482+
func= &Arg_comparator::compare_e_real_fixed;
483+
}
474484
break;
485+
}
475486
default:
476487
DBUG_ASSERT(0);
477488
}
@@ -610,6 +621,44 @@ int Arg_comparator::compare_e_decimal()
610621
return test(my_decimal_cmp(val1, val2) == 0);
611622
}
612623

624+
625+
int Arg_comparator::compare_real_fixed()
626+
{
627+
/*
628+
Fix yet another manifestation of Bug#2338. 'Volatile' will instruct
629+
gcc to flush double values out of 80-bit Intel FPU registers before
630+
performing the comparison.
631+
*/
632+
volatile double val1, val2;
633+
val1= (*a)->val_real();
634+
if (!(*a)->null_value)
635+
{
636+
val2= (*b)->val_real();
637+
if (!(*b)->null_value)
638+
{
639+
owner->null_value= 0;
640+
if (val1 == val2 || fabs(val1 - val2) < precision)
641+
return 0;
642+
if (val1 < val2)
643+
return -1;
644+
return 1;
645+
}
646+
}
647+
owner->null_value= 1;
648+
return -1;
649+
}
650+
651+
652+
int Arg_comparator::compare_e_real_fixed()
653+
{
654+
double val1= (*a)->val_real();
655+
double val2= (*b)->val_real();
656+
if ((*a)->null_value || (*b)->null_value)
657+
return test((*a)->null_value && (*b)->null_value);
658+
return test(val1 == val2 || fabs(val1 - val2) < precision);
659+
}
660+
661+
613662
int Arg_comparator::compare_int_signed()
614663
{
615664
longlong val1= (*a)->val_int();

sql/item_cmpfunc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class Arg_comparator: public Sql_alloc
3434
arg_cmp_func func;
3535
Item_bool_func2 *owner;
3636
Arg_comparator *comparators; // used only for compare_row()
37+
double precision;
3738

3839
public:
3940
DTCollation cmp_collation;
@@ -80,6 +81,8 @@ class Arg_comparator: public Sql_alloc
8081
int compare_e_int(); // compare args[0] & args[1]
8182
int compare_e_int_diff_signedness();
8283
int compare_e_row(); // compare args[0] & args[1]
84+
int compare_real_fixed();
85+
int compare_e_real_fixed();
8386

8487
static arg_cmp_func comparator_matrix [5][2];
8588

sql/item_sum.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table,
400400
Field *field;
401401
switch (result_type()) {
402402
case REAL_RESULT:
403-
field= new Field_double(max_length, maybe_null, name, decimals);
403+
field= new Field_double(max_length, maybe_null, name, decimals, TRUE);
404404
break;
405405
case INT_RESULT:
406406
field= new Field_longlong(max_length, maybe_null, name, unsigned_flag);
@@ -1135,7 +1135,7 @@ Field *Item_sum_avg::create_tmp_field(bool group, TABLE *table,
11351135
field= new Field_new_decimal(max_length, maybe_null, name,
11361136
decimals, unsigned_flag);
11371137
else
1138-
field= new Field_double(max_length, maybe_null, name, decimals);
1138+
field= new Field_double(max_length, maybe_null, name, decimals, TRUE);
11391139
if (field)
11401140
field->init(table);
11411141
return field;
@@ -1334,7 +1334,7 @@ Field *Item_sum_variance::create_tmp_field(bool group, TABLE *table,
13341334
field= new Field_string(sizeof(double)*2 + sizeof(longlong), 0, name, &my_charset_bin);
13351335
}
13361336
else
1337-
field= new Field_double(max_length, maybe_null, name, decimals);
1337+
field= new Field_double(max_length, maybe_null, name, decimals, TRUE);
13381338

13391339
if (field != NULL)
13401340
field->init(table);

sql/mysql_priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1543,6 +1543,7 @@ extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
15431543
extern char pidfile_name[FN_REFLEN], system_time_zone[30], *opt_init_file;
15441544
extern char log_error_file[FN_REFLEN], *opt_tc_log_file;
15451545
extern double log_10[32];
1546+
extern double log_01[32];
15461547
extern ulonglong log_10_int[20];
15471548
extern ulonglong keybuff_size;
15481549
extern ulonglong thd_startup_options;

sql/mysqld.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ ulong rpl_recovery_rank=0;
502502
const char *log_output_str= "TABLE";
503503

504504
double log_10[32]; /* 10 potences */
505+
double log_01[32];
505506
time_t start_time;
506507

507508
char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];

0 commit comments

Comments
 (0)