Skip to content

Commit f0f83a3

Browse files
author
ramil/[email protected]/ramil.myoffice.izhnet.ru
committed
Merge mysql.com:/home/ram/work/b19690/b19690.4.1
into mysql.com:/home/ram/work/b19690/b19690.5.0
2 parents 645de0c + eb415e4 commit f0f83a3

File tree

10 files changed

+172
-5
lines changed

10 files changed

+172
-5
lines changed

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
@@ -4064,7 +4064,7 @@ int Field_double::store(double nr)
40644064
else
40654065
{
40664066
double max_value;
4067-
if (dec >= NOT_FIXED_DEC)
4067+
if (not_fixed)
40684068
{
40694069
max_value= DBL_MAX;
40704070
}

sql/field.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -725,19 +725,28 @@ class Field_float :public Field_real {
725725

726726
class Field_double :public Field_real {
727727
public:
728+
my_bool not_fixed;
728729
Field_double(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
729730
uchar null_bit_arg,
730731
enum utype unireg_check_arg, const char *field_name_arg,
731732
struct st_table *table_arg,
732733
uint8 dec_arg,bool zero_arg,bool unsigned_arg)
733734
:Field_real(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
734735
unireg_check_arg, field_name_arg, table_arg,
735-
dec_arg, zero_arg, unsigned_arg)
736+
dec_arg, zero_arg, unsigned_arg),
737+
not_fixed(dec_arg >= NOT_FIXED_DEC)
736738
{}
737739
Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg,
738740
struct st_table *table_arg, uint8 dec_arg)
739-
:Field_real((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, (uint) 0,
740-
NONE, field_name_arg, table_arg, dec_arg, 0, 0)
741+
:Field_real((char*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0,
742+
NONE, field_name_arg, table_arg, dec_arg, 0, 0),
743+
not_fixed(dec_arg >= NOT_FIXED_DEC)
744+
{}
745+
Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg,
746+
struct st_table *table_arg, uint8 dec_arg, my_bool not_fixed_srg)
747+
:Field_real((char*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0,
748+
NONE, field_name_arg, table_arg, dec_arg, 0, 0),
749+
not_fixed(not_fixed_srg)
741750
{}
742751
enum_field_types type() const { return FIELD_TYPE_DOUBLE;}
743752
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
@@ -44,5 +44,11 @@ void unireg_init(ulong options)
4444
{ /* It's used by filesort... */
4545
log_10[i]= nr ; nr*= 10.0;
4646
}
47+
/* Make a tab of powers of 0.1 */
48+
for (i= 0, nr= 0.1; i < array_elements(log_01); i++)
49+
{
50+
log_01[i]= nr;
51+
nr*= 0.1;
52+
}
4753
DBUG_VOID_RETURN;
4854
}

sql/item_cmpfunc.cc

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,17 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
422422
default:
423423
DBUG_ASSERT(0);
424424
}
425+
else if (type == REAL_RESULT)
426+
{
427+
if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
428+
{
429+
precision= 5 * log_01[max((*a)->decimals, (*b)->decimals)];
430+
if (func == &Arg_comparator::compare_real)
431+
func= &Arg_comparator::compare_real_fixed;
432+
else if (func == &Arg_comparator::compare_e_real)
433+
func= &Arg_comparator::compare_e_real_fixed;
434+
}
435+
}
425436
return 0;
426437
}
427438

@@ -557,6 +568,44 @@ int Arg_comparator::compare_e_decimal()
557568
return test(my_decimal_cmp(val1, val2) == 0);
558569
}
559570

571+
572+
int Arg_comparator::compare_real_fixed()
573+
{
574+
/*
575+
Fix yet another manifestation of Bug#2338. 'Volatile' will instruct
576+
gcc to flush double values out of 80-bit Intel FPU registers before
577+
performing the comparison.
578+
*/
579+
volatile double val1, val2;
580+
val1= (*a)->val();
581+
if (!(*a)->null_value)
582+
{
583+
val2= (*b)->val();
584+
if (!(*b)->null_value)
585+
{
586+
owner->null_value= 0;
587+
if (val1 == val2 || fabs(val1 - val2) < precision)
588+
return 0;
589+
if (val1 < val2)
590+
return -1;
591+
return 1;
592+
}
593+
}
594+
owner->null_value= 1;
595+
return -1;
596+
}
597+
598+
599+
int Arg_comparator::compare_e_real_fixed()
600+
{
601+
double val1= (*a)->val();
602+
double val2= (*b)->val();
603+
if ((*a)->null_value || (*b)->null_value)
604+
return test((*a)->null_value && (*b)->null_value);
605+
return test(val1 == val2 || fabs(val1 - val2) < precision);
606+
}
607+
608+
560609
int Arg_comparator::compare_int_signed()
561610
{
562611
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/mysql_priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,6 +1211,7 @@ extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
12111211
extern char pidfile_name[FN_REFLEN], system_time_zone[30], *opt_init_file;
12121212
extern char log_error_file[FN_REFLEN], *opt_tc_log_file;
12131213
extern double log_10[32];
1214+
extern double log_01[32];
12141215
extern ulonglong log_10_int[20];
12151216
extern ulonglong keybuff_size;
12161217
extern ulonglong thd_startup_options;

sql/mysqld.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ ulong expire_logs_days = 0;
432432
ulong rpl_recovery_rank=0;
433433

434434
double log_10[32]; /* 10 potences */
435+
double log_01[32];
435436
time_t start_time;
436437

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

sql/sql_select.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8598,6 +8598,8 @@ Field* create_tmp_field_from_field(THD *thd, Field* org_field,
85988598
if (org_field->type() == MYSQL_TYPE_VAR_STRING ||
85998599
org_field->type() == MYSQL_TYPE_VARCHAR)
86008600
table->s->db_create_options|= HA_OPTION_PACK_RECORD;
8601+
else if (org_field->type() == FIELD_TYPE_DOUBLE)
8602+
((Field_double *) new_field)->not_fixed= TRUE;
86018603
}
86028604
return new_field;
86038605
}
@@ -8638,7 +8640,7 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
86388640
switch (item->result_type()) {
86398641
case REAL_RESULT:
86408642
new_field=new Field_double(item->max_length, maybe_null,
8641-
item->name, table, item->decimals);
8643+
item->name, table, item->decimals, TRUE);
86428644
break;
86438645
case INT_RESULT:
86448646
/* Select an integer type with the minimal fit precision */

0 commit comments

Comments
 (0)