From 6c5b66aab093d311ac8089be41d7e543cb3e1a84 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 16 Nov 2007 13:58:09 +0300 Subject: Fix for bug #32241: memory corruption due to large index map in 'Range checked for each record' The problem was in incorrectly calculated length of the buffer used to store a hexadecimal representation of an index map in select_describe(). This could result in buffer overrun and stack corruption under some circumstances. Fixed by correcting the calculation. mysql-test/r/explain.result: Added a test case for bug #32241. mysql-test/t/explain.test: Added a test case for bug #32241. sql/sql_select.cc: Corrected the buffer length calculation. Count one hex digit as 4 bits, not 8. --- sql/sql_select.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql/sql_select.cc') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 24d1639edf1..4ff80185a85 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -15282,7 +15282,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, { if (tab->use_quick == 2) { - char buf[MAX_KEY/8+1]; + /* 4 bits per 1 hex digit + terminating '\0' */ + char buf[MAX_KEY / 4 + 1]; extra.append(STRING_WITH_LEN("; Range checked for each " "record (index map: 0x")); extra.append(tab->keys.print(buf)); -- cgit v1.2.1 From 162f8bed8d81bc5bd32273833a2fc3726eba2fef Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 20 Nov 2007 16:07:24 +0200 Subject: Bug #32268: Indexed queries give bogus MIN and MAX results Loose index scan does the grouping so the temp table does not need to do it, even when sorting. Fixed by checking if the grouping is already done before doing sorting and grouping in a temp table and do only sorting. mysql-test/r/group_min_max.result: Bug #32268: test case mysql-test/t/group_min_max.test: Bug #32268: test case sql/sql_select.cc: Bug #32268: don't group in the temp table if already done --- sql/sql_select.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql/sql_select.cc') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3d3b8668a79..757bfb3a29e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10256,7 +10256,8 @@ Next_select_func setup_end_select_func(JOIN *join) /* Set up select_end */ if (table) { - if (table->group && tmp_tbl->sum_func_count) + if (table->group && tmp_tbl->sum_func_count && + !tmp_tbl->precomputed_group_by) { if (table->s->keys) { -- cgit v1.2.1 From 9ec0b73980df4577771eda5b7c4997a66498310d Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Nov 2007 02:48:01 +0300 Subject: sql_select.cc: Additional stack check for the bug#31048. sql/sql_select.cc: Additional stack check for the bug#31048. --- sql/sql_select.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sql/sql_select.cc') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3d3b8668a79..e25d0d78c87 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2332,6 +2332,11 @@ static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select, { int error; DBUG_ENTER("get_quick_record_count"); +#ifndef EMBEDDED_LIBRARY // Avoid compiler warning + char buff[STACK_BUFF_ALLOC]; +#endif + if (check_stack_overrun(thd, STACK_MIN_SIZE, buff)) + DBUG_RETURN(0); // Fatal error flag is set if (select) { select->head=table; -- cgit v1.2.1 From f3637af43ebdda58c2cbaa79406792dc6f739c08 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Nov 2007 11:40:05 +0200 Subject: Bug #30788: Inconsistent retrieval of char/varchar Index lookup does not always guarantee that we can simply remove the relevant conditions from the WHERE clause. Reasons can be e.g. conversion errors, partial indexes etc. The optimizer was removing these parts of the WHERE condition without any further checking. This leads to "false positives" when using indexes. Fixed by checking the index reference conditions (using WHERE) when using indexes with sub-queries. mysql-test/r/subselect.result: Bug #30788: - using where - test case mysql-test/r/subselect3.result: Bug #30788: using where mysql-test/t/subselect.test: Bug #30788: test case sql/item.h: Bug #30788: - Declare eq() method of Item_cache descendants : this is used in test_if_ref() - preserve the field that is being cached for type comparisions sql/sql_select.cc: Bug #30788: Don't remove the WHERE when using index lookup with subqueries. --- sql/sql_select.cc | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'sql/sql_select.cc') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7af39071561..211ac416c6d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -217,6 +217,7 @@ static void select_describe(JOIN *join, bool need_tmp_table,bool need_order, bool distinct, const char *message=NullS); static Item *remove_additional_cond(Item* conds); static void add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab); +static bool test_if_ref(Item_field *left_item,Item *right_item); /* @@ -673,9 +674,6 @@ err: without "checking NULL", remove the predicates that were pushed down into the subquery. - We can remove the equalities that will be guaranteed to be true by the - fact that subquery engine will be using index lookup. - If the subquery compares scalar values, we can remove the condition that was wrapped into trig_cond (it will be checked when needed by the subquery engine) @@ -685,6 +683,12 @@ err: and non-NULL values, we'll do a full table scan and will rely on the equalities corresponding to non-NULL parts of left tuple to filter out non-matching records. + + TODO: We can remove the equalities that will be guaranteed to be true by the + fact that subquery engine will be using index lookup. This must be done only + for cases where there are no conversion errors of significance, e.g. 257 + that is searched in a byte. But this requires homogenization of the return + codes of all Field*::store() methods. */ void JOIN::remove_subq_pushed_predicates(Item **where) @@ -692,17 +696,13 @@ void JOIN::remove_subq_pushed_predicates(Item **where) if (conds->type() == Item::FUNC_ITEM && ((Item_func *)this->conds)->functype() == Item_func::EQ_FUNC && ((Item_func *)conds)->arguments()[0]->type() == Item::REF_ITEM && - ((Item_func *)conds)->arguments()[1]->type() == Item::FIELD_ITEM) + ((Item_func *)conds)->arguments()[1]->type() == Item::FIELD_ITEM && + test_if_ref ((Item_field *)((Item_func *)conds)->arguments()[1], + ((Item_func *)conds)->arguments()[0])) { *where= 0; return; } - if (conds->type() == Item::COND_ITEM && - ((class Item_func *)this->conds)->functype() == - Item_func::COND_AND_FUNC) - { - *where= remove_additional_cond(conds); - } } @@ -1219,7 +1219,7 @@ JOIN::optimize() { if (!having) { - Item *where= 0; + Item *where= conds; if (join_tab[0].type == JT_EQ_REF && join_tab[0].ref.items[0]->name == in_left_expr_name) { @@ -11862,8 +11862,12 @@ static bool test_if_ref(Item_field *left_item,Item *right_item) Item *ref_item=part_of_refkey(field->table,field); if (ref_item && ref_item->eq(right_item,1)) { + right_item= right_item->real_item(); if (right_item->type() == Item::FIELD_ITEM) return (field->eq_def(((Item_field *) right_item)->field)); + /* remove equalities injected by IN->EXISTS transformation */ + else if (right_item->type() == Item::CACHE_ITEM) + return ((Item_cache *)right_item)->eq_def (field); if (right_item->const_item() && !(right_item->is_null())) { /* -- cgit v1.2.1 From 62b65e985444e6ab485d3a965a956e7a01222b5a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 7 Dec 2007 17:14:59 -0800 Subject: Fixed bug #32815. The index (key_part_1, key_part-2) was erroneously considered as compatible with the required ordering in the function test_test_if_order_by_key when a query with an ORDER BY clause contained a condition of the form key_part_1=const OR key_part_1 IS NULL and the order list contained only key_part_2. This happened because the value of the const_key_parts field in the KEYUSE structure was not formed correctly for the keys that could be used for ref_or_null access. This was fixed in the code of the update_ref_and_keys function. The problem could not manifest itself for MyISAM databases because the implementation of the keys_to_use_for_scanning() handler function always returns an empty bitmap for the MyISAM engine. mysql-test/r/innodb_mysql.result: Added a test case for bug #32815. mysql-test/t/innodb_mysql.test: Added a test case for bug #32815. sql/sql_select.cc: Fixed bug #32815. The index (key_part_1, key_part-2) was erroneously considered as compatible with the required ordering in the function test_test_if_order_by_key when a query with an ORDER BY clause contained a condition of the form key_part_1=const OR key_part_1 IS NULL and the order list contained only key_part_2. This happened because the value of the const_key_parts field in the KEYUSE structure was not formed correctly for the keys that could be used for ref_or_null access. This was fixed in the code of the update_ref_and_keys function. --- sql/sql_select.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/sql_select.cc') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index bcf538cdde2..d1bd018878a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3691,7 +3691,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, found_eq_constant=0; for (i=0 ; i < keyuse->elements-1 ; i++,use++) { - if (!use->used_tables) + if (!use->used_tables && use->optimize != KEY_OPTIMIZE_REF_OR_NULL) use->table->const_key_parts[use->key]|= use->keypart_map; if (use->keypart != FT_KEYPART) { -- cgit v1.2.1