Skip to content

Commit d12e2fd

Browse files
author
Tor Didriksen
committed
Bug#18486249 ASSERTION FAILED: BUF == BUFFER IN MY_DECIMAL::SANITY_CHECK
This bug was uncovered by the stricter sanity_check introduced in patch for: Bug#18335446 DECIMAL_ROUND: ASSERTION FAILED: FROM->LEN == TO->LEN The problem is that my_qsort2 sorts blobs, rather than objects. When sorting an array of decimals, it will sometimes leave objects with wrong buffer pointers. Solution: use std::sort, which is type-aware, and will copy/swap decimal objects properly.
1 parent f10e749 commit d12e2fd

File tree

5 files changed

+38
-7
lines changed

5 files changed

+38
-7
lines changed

mysql-test/r/type_newdecimal.result

+10
Original file line numberDiff line numberDiff line change
@@ -2020,3 +2020,13 @@ INSERT INTO t1 VALUES (1),(2);
20202020
UPDATE IGNORE t1 SET b = 1
20212021
WHERE b NOT IN (NULL, -3333333333333333333333);
20222022
DROP TABLE t1;
2023+
#
2024+
# Bug#18486249 ASSERTION FAILED:
2025+
# BUF == BUFFER IN MY_DECIMAL::SANITY_CHECK
2026+
#
2027+
CREATE TABLE t1(b INT, KEY(b));
2028+
INSERT INTO t1 VALUES (0);
2029+
SELECT 1 FROM t1 WHERE b NOT IN (0.1,-0.1);
2030+
1
2031+
1
2032+
DROP TABLE t1;

mysql-test/t/type_newdecimal.test

+10
Original file line numberDiff line numberDiff line change
@@ -1643,3 +1643,13 @@ UPDATE IGNORE t1 SET b = 1
16431643
WHERE b NOT IN (NULL, -3333333333333333333333);
16441644

16451645
DROP TABLE t1;
1646+
1647+
--echo #
1648+
--echo # Bug#18486249 ASSERTION FAILED:
1649+
--echo # BUF == BUFFER IN MY_DECIMAL::SANITY_CHECK
1650+
--echo #
1651+
1652+
CREATE TABLE t1(b INT, KEY(b));
1653+
INSERT INTO t1 VALUES (0);
1654+
SELECT 1 FROM t1 WHERE b NOT IN (0.1,-0.1);
1655+
DROP TABLE t1;

sql/item_cmpfunc.cc

+9-6
Original file line numberDiff line numberDiff line change
@@ -4104,12 +4104,8 @@ static int cmp_row(void *cmp_arg, cmp_item_row *a, cmp_item_row *b)
41044104

41054105
static int cmp_decimal(void *cmp_arg, my_decimal *a, my_decimal *b)
41064106
{
4107-
/*
4108-
We need call of fixing buffer pointer, because fast sort just copy
4109-
decimal buffers in memory and pointers left pointing on old buffer place
4110-
*/
4111-
a->fix_buffer_pointer();
4112-
b->fix_buffer_pointer();
4107+
a->sanity_check();
4108+
b->sanity_check();
41134109
return my_decimal_cmp(a, b);
41144110
}
41154111

@@ -4349,6 +4345,13 @@ uchar *in_decimal::get_value(Item *item)
43494345
}
43504346

43514347

4348+
void in_decimal::sort()
4349+
{
4350+
my_decimal *begin= static_cast<my_decimal*>(static_cast<void*>(base));
4351+
my_decimal *end= begin + used_count;
4352+
std::sort(begin, end);
4353+
}
4354+
43524355
cmp_item* cmp_item::get_comparator(Item_result type,
43534356
const CHARSET_INFO *cs)
43544357
{

sql/item_cmpfunc.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -1047,7 +1047,7 @@ class in_vector :public Sql_alloc
10471047
virtual ~in_vector() {}
10481048
virtual void set(uint pos,Item *item)=0;
10491049
virtual uchar *get_value(Item *item)=0;
1050-
void sort()
1050+
virtual void sort()
10511051
{
10521052
my_qsort2(base,used_count,size,compare,collation);
10531053
}
@@ -1235,6 +1235,8 @@ class in_decimal :public in_vector
12351235
}
12361236
Item_result result_type() { return DECIMAL_RESULT; }
12371237

1238+
// Our own, type-aware sort, rather than my_qsort2.
1239+
virtual void sort();
12381240
};
12391241

12401242

sql/my_decimal.h

+6
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,12 @@ int my_decimal_cmp(const my_decimal *a, const my_decimal *b)
502502
return decimal_cmp(a, b);
503503
}
504504

505+
inline
506+
bool operator<(const my_decimal &lhs, const my_decimal &rhs)
507+
{
508+
return my_decimal_cmp(&lhs, &rhs) < 0;
509+
}
510+
505511

506512
inline
507513
int my_decimal_intg(const my_decimal *a)

0 commit comments

Comments
 (0)