summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
authorunknown <igor@rurik.mysql.com>2006-08-22 04:14:39 -0700
committerunknown <igor@rurik.mysql.com>2006-08-22 04:14:39 -0700
commit38558705d0b1cfb97633ad688c068b3472523555 (patch)
treee3b4d6e8b698dc1be1c8782e2829f88f7228b530 /sql/opt_range.cc
parent686ca8130721d0eac86b8dcf267b5669674bbac4 (diff)
downloadmariadb-git-38558705d0b1cfb97633ad688c068b3472523555.tar.gz
Fixed bug 16201: a memory corruption causing crashes due to a too small
buffer for a MY_BITMAP temporary buffer allocated on stack in the function get_best_covering_ror_intersect(). Now the buffer of a proper size is allocated by a request from this function in mem_root. We succeeded to demonstrate the bug only on Windows with a very large database. That's why no test case is provided for in the patch. sql/opt_range.cc: Fixed bug 16201: a memory corruption causing crashes due to a too small buffer for a MY_BITMAP temporary buffer allocated on stack in the function get_best_covering_ror_intersect(). Now the buffer of a proper size is allocated by a request from this function in mem_root.
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r--sql/opt_range.cc19
1 files changed, 12 insertions, 7 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 436cc8b3d9e..9a836705bb9 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -442,6 +442,7 @@ typedef struct st_qsel_param {
uint fields_bitmap_size;
MY_BITMAP needed_fields; /* bitmask of fields needed by the query */
+ MY_BITMAP tmp_covered_fields;
key_map *needed_reg; /* ptr to SQL_SELECT::needed_reg */
@@ -1765,6 +1766,7 @@ static int fill_used_fields_bitmap(PARAM *param)
param->fields_bitmap_size= (table->s->fields/8 + 1);
uchar *tmp;
uint pk;
+ param->tmp_covered_fields.bitmap= 0;
if (!(tmp= (uchar*)alloc_root(param->mem_root,param->fields_bitmap_size)) ||
bitmap_init(&param->needed_fields, tmp, param->fields_bitmap_size*8,
FALSE))
@@ -3202,11 +3204,14 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
/*I=set of all covering indexes */
ror_scan_mark= tree->ror_scans;
- uchar buf[MAX_KEY/8+1];
- MY_BITMAP covered_fields;
- if (bitmap_init(&covered_fields, buf, nbits, FALSE))
+ MY_BITMAP *covered_fields= &param->tmp_covered_fields;
+ if (!covered_fields->bitmap)
+ covered_fields->bitmap= (uchar*)alloc_root(param->mem_root,
+ param->fields_bitmap_size);
+ if (!covered_fields->bitmap ||
+ bitmap_init(covered_fields, covered_fields->bitmap, nbits, FALSE))
DBUG_RETURN(0);
- bitmap_clear_all(&covered_fields);
+ bitmap_clear_all(covered_fields);
double total_cost= 0.0f;
ha_rows records=0;
@@ -3225,7 +3230,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
*/
for (ROR_SCAN_INFO **scan= ror_scan_mark; scan != ror_scans_end; ++scan)
{
- bitmap_subtract(&(*scan)->covered_fields, &covered_fields);
+ bitmap_subtract(&(*scan)->covered_fields, covered_fields);
(*scan)->used_fields_covered=
bitmap_bits_set(&(*scan)->covered_fields);
(*scan)->first_uncovered_field=
@@ -3247,8 +3252,8 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
if (total_cost > read_time)
DBUG_RETURN(NULL);
/* F=F-covered by first(I) */
- bitmap_union(&covered_fields, &(*ror_scan_mark)->covered_fields);
- all_covered= bitmap_is_subset(&param->needed_fields, &covered_fields);
+ bitmap_union(covered_fields, &(*ror_scan_mark)->covered_fields);
+ all_covered= bitmap_is_subset(&param->needed_fields, covered_fields);
} while ((++ror_scan_mark < ror_scans_end) && !all_covered);
if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)