diff options
author | Georgi Kodinov <Georgi.Kodinov@Oracle.com> | 2010-11-26 14:51:48 +0200 |
---|---|---|
committer | Georgi Kodinov <Georgi.Kodinov@Oracle.com> | 2010-11-26 14:51:48 +0200 |
commit | c5987223db0158389602e57c25c13368aad80b34 (patch) | |
tree | c48ad0e6cae3c6805e0e56810c191edf4210919f /sql | |
parent | 7074a99580ea7b89aef387838205778401d002c3 (diff) | |
parent | dce374bb663c0450546a6836cea763e8c3eca8dd (diff) | |
download | mariadb-git-c5987223db0158389602e57c25c13368aad80b34.tar.gz |
merge
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_partition.cc | 10 | ||||
-rw-r--r-- | sql/item_func.cc | 26 | ||||
-rw-r--r-- | sql/item_func.h | 2 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 43 | ||||
-rw-r--r-- | sql/item_subselect.cc | 15 | ||||
-rw-r--r-- | sql/item_sum.cc | 6 | ||||
-rw-r--r-- | sql/sql_select.cc | 14 |
7 files changed, 97 insertions, 19 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 607f4ce2143..7bcbd241541 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4299,8 +4299,12 @@ int ha_partition::index_read_idx_map(uchar *buf, uint index, get_partition_set(table, buf, index, &m_start_key, &m_part_spec); - /* How can it be more than one partition with the current use? */ - DBUG_ASSERT(m_part_spec.start_part == m_part_spec.end_part); + /* + We have either found exactly 1 partition + (in which case start_part == end_part) + or no matching partitions (start_part > end_part) + */ + DBUG_ASSERT(m_part_spec.start_part >= m_part_spec.end_part); for (part= m_part_spec.start_part; part <= m_part_spec.end_part; part++) { @@ -4535,6 +4539,7 @@ int ha_partition::partition_scan_set_up(uchar * buf, bool idx_read_flag) key not found. */ DBUG_PRINT("info", ("scan with no partition to scan")); + table->status= STATUS_NOT_FOUND; DBUG_RETURN(HA_ERR_END_OF_FILE); } if (m_part_spec.start_part == m_part_spec.end_part) @@ -4559,6 +4564,7 @@ int ha_partition::partition_scan_set_up(uchar * buf, bool idx_read_flag) if (start_part == MY_BIT_NONE) { DBUG_PRINT("info", ("scan with no partition to scan")); + table->status= STATUS_NOT_FOUND; DBUG_RETURN(HA_ERR_END_OF_FILE); } if (start_part > m_part_spec.start_part) diff --git a/sql/item_func.cc b/sql/item_func.cc index 22af67fea3a..b542969cfb0 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1363,9 +1363,13 @@ longlong Item_func_int_div::val_int() signal_divide_by_null(); return 0; } - return (unsigned_flag ? - (ulonglong) value / (ulonglong) val2 : - value / val2); + + if (unsigned_flag) + return ((ulonglong) value / (ulonglong) val2); + else if (value == LONGLONG_MIN && val2 == -1) + return LONGLONG_MIN; + else + return value / val2; } @@ -1399,9 +1403,9 @@ longlong Item_func_mod::int_op() if (args[0]->unsigned_flag) result= args[1]->unsigned_flag ? ((ulonglong) value) % ((ulonglong) val2) : ((ulonglong) value) % val2; - else - result= args[1]->unsigned_flag ? - value % ((ulonglong) val2) : value % val2; + else result= args[1]->unsigned_flag ? + value % ((ulonglong) val2) : + (val2 == -1) ? 0 : value % val2; return result; } @@ -5304,7 +5308,17 @@ void Item_func_match::init_search(bool no_order) /* Check if init_search() has been called before */ if (ft_handler) + { + /* + We should reset ft_handler as it is cleaned up + on destruction of FT_SELECT object + (necessary in case of re-execution of subquery). + TODO: FT_SELECT should not clean up ft_handler. + */ + if (join_key) + table->file->ft_handler= ft_handler; DBUG_VOID_RETURN; + } if (key == NO_SUCH_KEY) { diff --git a/sql/item_func.h b/sql/item_func.h index 256348eee08..26a7e033692 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1531,7 +1531,7 @@ public: join_key(0), ft_handler(0), table(0), master(0), concat_ws(0) { } void cleanup() { - DBUG_ENTER("Item_func_match"); + DBUG_ENTER("Item_func_match::cleanup"); Item_real_func::cleanup(); if (!master && ft_handler) ft_handler->please->close_search(ft_handler); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 5d56b0a621a..8fda281bd9e 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1013,6 +1013,20 @@ String *Item_func_insert::val_str(String *str) if ((length < 0) || (length > res->length())) length= res->length(); + /* + There is one exception not handled (intentionaly) by the character set + aggregation code. If one string is strong side and is binary, and + another one is weak side and is a multi-byte character string, + then we need to operate on the second string in terms on bytes when + calling ::numchars() and ::charpos(), rather than in terms of characters. + Lets substitute its character set to binary. + */ + if (collation.collation == &my_charset_bin) + { + res->set_charset(&my_charset_bin); + res2->set_charset(&my_charset_bin); + } + /* start and length are now sufficiently valid to pass to charpos function */ start= res->charpos((int) start); length= res->charpos((int) length, (uint32) start); @@ -2514,6 +2528,20 @@ String *Item_func_rpad::val_str(String *str) /* Set here so that rest of code sees out-of-bound value as such. */ if ((ulonglong) count > INT_MAX32) count= INT_MAX32; + /* + There is one exception not handled (intentionaly) by the character set + aggregation code. If one string is strong side and is binary, and + another one is weak side and is a multi-byte character string, + then we need to operate on the second string in terms on bytes when + calling ::numchars() and ::charpos(), rather than in terms of characters. + Lets substitute its character set to binary. + */ + if (collation.collation == &my_charset_bin) + { + res->set_charset(&my_charset_bin); + rpad->set_charset(&my_charset_bin); + } + if (count <= (res_char_length= res->numchars())) { // String to pad is big enough res->length(res->charpos((int) count)); // Shorten result if longer @@ -2616,6 +2644,20 @@ String *Item_func_lpad::val_str(String *str) if ((ulonglong) count > INT_MAX32) count= INT_MAX32; + /* + There is one exception not handled (intentionaly) by the character set + aggregation code. If one string is strong side and is binary, and + another one is weak side and is a multi-byte character string, + then we need to operate on the second string in terms on bytes when + calling ::numchars() and ::charpos(), rather than in terms of characters. + Lets substitute its character set to binary. + */ + if (collation.collation == &my_charset_bin) + { + res->set_charset(&my_charset_bin); + pad->set_charset(&my_charset_bin); + } + res_char_length= res->numchars(); if (count <= res_char_length) @@ -3093,6 +3135,7 @@ String* Item_func_inet_ntoa::val_str(String* str) if ((null_value= (args[0]->null_value || n > (ulonglong) LL(4294967295)))) return 0; // Null value + str->set_charset(collation.collation); str->length(0); int4store(buf,n); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 1ed36ce7656..d521ad0b4e8 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1906,21 +1906,26 @@ int subselect_single_select_engine::exec() DBUG_RETURN(join->error ? join->error : 1); } if (!select_lex->uncacheable && thd->lex->describe && - !(join->select_options & SELECT_DESCRIBE) && - join->need_tmp) + !(join->select_options & SELECT_DESCRIBE)) { item->update_used_tables(); if (item->const_item()) { /* + It's necessary to keep original JOIN table because + create_sort_index() function may overwrite original + JOIN_TAB::type and wrong optimization method can be + selected on re-execution. + */ + select_lex->uncacheable|= UNCACHEABLE_EXPLAIN; + select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN; + /* Force join->join_tmp creation, because this subquery will be replaced by a simple select from the materialization temp table by optimize() called by EXPLAIN and we need to preserve the initial query structure so we can display it. */ - select_lex->uncacheable|= UNCACHEABLE_EXPLAIN; - select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN; - if (join->init_save_join_tab()) + if (join->need_tmp && join->init_save_join_tab()) DBUG_RETURN(1); /* purecov: inspected */ } } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index ae9e46e2abf..65f8222d38b 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3401,8 +3401,6 @@ String* Item_func_group_concat::val_str(String* str) void Item_func_group_concat::print(String *str, enum_query_type query_type) { - /* orig_args is not filled with valid values until fix_fields() */ - Item **pargs= fixed ? orig_args : args; str->append(STRING_WITH_LEN("group_concat(")); if (distinct) str->append(STRING_WITH_LEN("distinct ")); @@ -3410,7 +3408,7 @@ void Item_func_group_concat::print(String *str, enum_query_type query_type) { if (i) str->append(','); - pargs[i]->print(str, query_type); + orig_args[i]->print(str, query_type); } if (arg_count_order) { @@ -3419,7 +3417,7 @@ void Item_func_group_concat::print(String *str, enum_query_type query_type) { if (i) str->append(','); - pargs[i + arg_count_field]->print(str, query_type); + orig_args[i + arg_count_field]->print(str, query_type); if (order[i]->asc) str->append(STRING_WITH_LEN(" ASC")); else diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 748071986b1..c17cb946fa3 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1713,6 +1713,9 @@ JOIN::reinit() func->clear(); } + if (!(select_options & SELECT_DESCRIBE)) + init_ftfuncs(thd, select_lex, test(order)); + DBUG_RETURN(0); } @@ -2487,6 +2490,13 @@ mysql_select(THD *thd, Item ***rref_pointer_array, { DBUG_RETURN(TRUE); } + /* + Original join tabs might be overwritten at first + subselect execution. So we need to restore them. + */ + Item_subselect *subselect= select_lex->master_unit()->item; + if (subselect && subselect->is_uncacheable() && join->reinit()) + DBUG_RETURN(TRUE); } else { @@ -13206,6 +13216,8 @@ static bool list_contains_unique_index(TABLE *table, bool (*find_func) (Field *, void *), void *data) { + if (table->pos_in_table_list->outer_join) + return 0; for (uint keynr= 0; keynr < table->s->keys; keynr++) { if (keynr == table->s->primary_key || @@ -13219,7 +13231,7 @@ list_contains_unique_index(TABLE *table, key_part < key_part_end; key_part++) { - if (key_part->field->maybe_null() || + if (key_part->field->real_maybe_null() || !find_func(key_part->field, data)) break; } |