From e30a0dda8f322aa8714caf6d6de6d583e51809f1 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 26 Jan 2008 21:45:35 -0800 Subject: Fixed bug #33833. Two disjuncts containing equalities of the form key=const1 and key=const2 can be merged into one if const1 is equal to const2. To check it the common collation of the constants were used rather than the collation of the field key. For example when the default collation of the constants was cases insensitive while the collation of the field was case sensitive, then two or-ed equality predicates key='b' and key='B' incorrectly were merged into one f='b'. As a result ref access was used instead of range access and wrong result sets were returned in many cases. Fixed the problem by comparing constant in the or-ed predicate with collation of the key field. mysql-test/r/range.result: Added a test case for bug #33833. mysql-test/t/range.test: Added a test case for bug #33833. sql/item.cc: Fixed bug #33833. Added the method eq_by_collation that compares two items almost as the method Item::eq, but it rather enforces a given collation for the comparison. sql/item.h: Fixed bug #33833. Added the method eq_by_collation that compares two items almost as the method Item::eq, but it rather enforces a given collation for the comparison. --- sql/sql_select.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sql/sql_select.cc') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 87935b5548f..bdea25ab99d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2887,7 +2887,9 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, } } else if (old->eq_func && new_fields->eq_func && - old->val->eq(new_fields->val, old->field->binary())) + old->val->eq_by_collation(new_fields->val, + old->field->binary(), + old->field->charset())) { old->level= and_level; -- cgit v1.2.1 From d6be1a9b957b47c2cf67590932629984c1ef5a14 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 17 Feb 2008 15:48:17 +0400 Subject: Bug #32942 now() - interval '7200' second NOT pre-calculated, causing "full table scan" Problem is not about intervals and doesn't actually cause 'full table scan'. We have an optimization for DISTINCT when we have 'DISTINCT field_from_first_join_table' we don't need to read all the rows from the JOIN-ed table if we found one conforming row. It stopped working in 5.0 as we return NESTED_LOOP_OK if we came upon that case in the evaluate_join_record() and that doesn't break the recordreading loop in sub_select(). Fixed by returning NESTED_LOOP_NO_MORE_ROWS in this case. mysql-test/r/select.result: Bug #32942 now() - interval '7200' second is NOT pre-calculated, causing "full table scan". test result mysql-test/t/select.test: Bug #32942 now() - interval '7200' second is NOT pre-calculated, causing "full table scan" test case sql/sql_select.cc: Bug #32942 now() - interval '7200' second NOT pre-calculated, causing "full table scan" return NESTED_LOOP_NO_MORE_ROWS when we don't need to read rows from this table anymore --- 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 d6cb072ce9b..60ce01c9d89 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10791,7 +10791,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, we found a row, as no new rows can be added to the result. */ if (not_used_in_distinct && found_records != join->found_records) - return NESTED_LOOP_OK; + return NESTED_LOOP_NO_MORE_ROWS; } else join_tab->read_record.file->unlock_row(); -- cgit v1.2.1 From d276cd905935d9b620cd2f4260b0920a38c35348 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 Feb 2008 15:11:11 +0400 Subject: Fixed bug #34830: mixed table and field names in Item_ref and Item_direct_ref constructor calls. Order of ref->field_name and ref->table_name arguments is of Item_ref and Item_direct_ref in the fix_inner_refs function is inverted. sql/sql_select.cc: Fixed bug #34830: mixed table and field names in Item_ref and Item_direct_ref constructor calls. Order of ref->field_name and ref->table_name arguments is of Item_ref and Item_direct_ref in the fix_inner_refs function is inverted. See definitions: Item_ref(Name_resolution_context *context_arg, Item **item, const char *table_name_arg, const char *field_name_arg, bool alias_name_used_arg= FALSE) and Item_direct_ref(Name_resolution_context *context_arg, Item **item, const char *table_name_arg, const char *field_name_arg, bool alias_name_used_arg= FALSE) --- sql/sql_select.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sql/sql_select.cc') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 38da4e26f5a..926b389f59f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -360,10 +360,10 @@ fix_inner_refs(THD *thd, List &all_fields, SELECT_LEX *select, } } new_ref= direct_ref ? - new Item_direct_ref(ref->context, item_ref, ref->field_name, - ref->table_name, ref->alias_name_used) : - new Item_ref(ref->context, item_ref, ref->field_name, - ref->table_name, ref->alias_name_used); + new Item_direct_ref(ref->context, item_ref, ref->table_name, + ref->field_name, ref->alias_name_used) : + new Item_ref(ref->context, item_ref, ref->table_name, + ref->field_name, ref->alias_name_used); if (!new_ref) return TRUE; ref->outer_ref= new_ref; -- cgit v1.2.1 From cd9f2d1c285d1bc5f5115e517da806ccb2bd1d28 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 3 Mar 2008 20:35:44 +0300 Subject: BUG#34945: "ref_or_null queries that are null_rejecting and have a null value crash mysql" - Apply Eric Bergen's patch: in join_read_always_key(), move ha_index_init() call to before the late NULLs filtering code. - Backport function comments from 6.0. mysql-test/r/null_key.result: BUG#34945: "ref_or_null queries that are null_rejecting and have a null value crash mysql" - Testcase mysql-test/t/null_key.test: BUG#34945: "ref_or_null queries that are null_rejecting and have a null value crash mysql" - Testcase sql/sql_select.cc: BUG#34945: "ref_or_null queries that are null_rejecting and have a null value crash mysql" - Apply Eric Bergen's patch: in join_read_always_key(), move ha_index_init() call to before the late NULLs filtering code. - Backport function comments from 6.0 --- sql/sql_select.cc | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'sql/sql_select.cc') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 926b389f59f..6392f7c4299 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11173,19 +11173,42 @@ join_read_key(JOIN_TAB *tab) } +/* + ref access method implementation: "read_first" function + + SYNOPSIS + join_read_always_key() + tab JOIN_TAB of the accessed table + + DESCRIPTION + This is "read_fist" function for the "ref" access method. + + The functon must leave the index initialized when it returns. + ref_or_null access implementation depends on that. + + RETURN + 0 - Ok + -1 - Row not found + 1 - Error +*/ + static int join_read_always_key(JOIN_TAB *tab) { int error; TABLE *table= tab->table; + /* Initialize the index first */ + if (!table->file->inited) + table->file->ha_index_init(tab->ref.key); + + /* Perform "Late NULLs Filtering" (see internals manual for explanations) */ for (uint i= 0 ; i < tab->ref.key_parts ; i++) { if ((tab->ref.null_rejecting & 1 << i) && tab->ref.items[i]->is_null()) return -1; - } - if (!table->file->inited) - table->file->ha_index_init(tab->ref.key); + } + if (cp_buffer_from_ref(tab->join->thd, &tab->ref)) return -1; if ((error=table->file->index_read(table->record[0], -- cgit v1.2.1