diff options
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r-- | sql/item_func.cc | 402 |
1 files changed, 277 insertions, 125 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc index e0b61e856b5..5fb3efc27d5 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -405,6 +405,25 @@ Item_func::eval_not_null_tables(void *opt_arg) } +bool +Item_func::find_not_null_fields(table_map allowed) +{ + if (~allowed & used_tables()) + return false; + + Item **arg,**arg_end; + if (arg_count) + { + for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++) + { + if (!(*arg)->find_not_null_fields(allowed)) + continue; + } + } + return false; +} + + void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge) { @@ -656,16 +675,6 @@ bool Item_func::is_expensive_processor(uchar *arg) } */ -my_decimal *Item_func::val_decimal(my_decimal *decimal_value) -{ - DBUG_ASSERT(fixed); - longlong nr= val_int(); - if (null_value) - return 0; /* purecov: inspected */ - int2my_decimal(E_DEC_FATAL_ERROR, nr, unsigned_flag, decimal_value); - return decimal_value; -} - bool Item_hybrid_func::fix_attributes(Item **items, uint nitems) { @@ -1154,14 +1163,10 @@ longlong Item_func_plus::int_op() } } -#ifndef WITH_UBSAN - res= val0 + val1; -#else if (res_unsigned) res= (longlong) ((ulonglong) val0 + (ulonglong) val1); else - res= val0+val1; -#endif /* WITH_UBSAN */ + res= val0 + val1; return check_integer_overflow(res, res_unsigned); @@ -1223,7 +1228,10 @@ void Item_func_minus::fix_unsigned_flag() { if (unsigned_flag && (current_thd->variables.sql_mode & MODE_NO_UNSIGNED_SUBTRACTION)) + { unsigned_flag=0; + set_handler(Item_func_minus::type_handler()->type_handler_signed()); + } } @@ -1239,9 +1247,8 @@ bool Item_func_minus::fix_length_and_dec() if (Item_func_minus::type_handler()->Item_func_minus_fix_length_and_dec(this)) DBUG_RETURN(TRUE); DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); - if ((m_depends_on_sql_mode_no_unsigned_subtraction= unsigned_flag) && - (current_thd->variables.sql_mode & MODE_NO_UNSIGNED_SUBTRACTION)) - unsigned_flag= false; + m_depends_on_sql_mode_no_unsigned_subtraction= unsigned_flag; + fix_unsigned_flag(); DBUG_RETURN(FALSE); } @@ -1322,14 +1329,10 @@ longlong Item_func_minus::int_op() goto err; } } -#ifndef WITH_UBSAN - res= val0 - val1; -#else if (res_unsigned) res= (longlong) ((ulonglong) val0 - (ulonglong) val1); else res= val0 - val1; -#endif /* WITH_UBSAN */ return check_integer_overflow(res, res_unsigned); @@ -1757,9 +1760,9 @@ static void calc_hash_for_unique(ulong &nr1, ulong &nr2, String *str) uchar l[4]; int4store(l, str->length()); cs= str->charset(); - cs->coll->hash_sort(cs, l, sizeof(l), &nr1, &nr2); + cs->hash_sort(l, sizeof(l), &nr1, &nr2); cs= str->charset(); - cs->coll->hash_sort(cs, (uchar *)str->ptr(), str->length(), &nr1, &nr2); + cs->hash_sort((uchar *)str->ptr(), str->length(), &nr1, &nr2); } longlong Item_func_hash::val_int() @@ -1857,7 +1860,7 @@ void Item_func_neg::fix_length_and_dec_int() Ensure that result is converted to DECIMAL, as longlong can't hold the negated number */ - set_handler_by_result_type(DECIMAL_RESULT); + set_handler(&type_handler_newdecimal); DBUG_PRINT("info", ("Type changed: DECIMAL_RESULT")); } } @@ -2156,42 +2159,103 @@ double Item_func_cot::val_real() // Shift-functions, same as << and >> in C/C++ -longlong Item_func_shift_left::val_int() +class Func_handler_shift_left_int_to_ulonglong: + public Item_handled_func::Handler_ulonglong { - DBUG_ASSERT(fixed == 1); - uint shift= (uint) args[1]->val_int(); - ulonglong value= args[0]->val_int(); - if (args[0]->null_value || args[1]->null_value) +public: + Longlong_null to_longlong_null(Item_handled_func *item) const { - null_value=1; - return 0; + DBUG_ASSERT(item->is_fixed()); + return item->arguments()[0]->to_longlong_null() << + item->arguments()[1]->to_longlong_null(); } - null_value=0; - return (shift < sizeof(longlong)*8 ? (value << shift) : 0); +}; + + +class Func_handler_shift_left_decimal_to_ulonglong: + public Item_handled_func::Handler_ulonglong +{ +public: + Longlong_null to_longlong_null(Item_handled_func *item) const + { + DBUG_ASSERT(item->is_fixed()); + return VDec(item->arguments()[0]).to_xlonglong_null() << + item->arguments()[1]->to_longlong_null(); + } +}; + + +bool Item_func_shift_left::fix_length_and_dec() +{ + static Func_handler_shift_left_int_to_ulonglong ha_int_to_ull; + static Func_handler_shift_left_decimal_to_ulonglong ha_dec_to_ull; + return fix_length_and_dec_op1_std(&ha_int_to_ull, &ha_dec_to_ull); } -longlong Item_func_shift_right::val_int() + +class Func_handler_shift_right_int_to_ulonglong: + public Item_handled_func::Handler_ulonglong { - DBUG_ASSERT(fixed == 1); - uint shift= (uint) args[1]->val_int(); - ulonglong value= args[0]->val_int(); - if (args[0]->null_value || args[1]->null_value) +public: + Longlong_null to_longlong_null(Item_handled_func *item) const { - null_value=1; - return 0; + DBUG_ASSERT(item->fixed == 1); + return item->arguments()[0]->to_longlong_null() >> + item->arguments()[1]->to_longlong_null(); } - null_value=0; - return (shift < sizeof(longlong)*8 ? (value >> shift) : 0); +}; + + +class Func_handler_shift_right_decimal_to_ulonglong: + public Item_handled_func::Handler_ulonglong +{ +public: + Longlong_null to_longlong_null(Item_handled_func *item) const + { + DBUG_ASSERT(item->is_fixed()); + return VDec(item->arguments()[0]).to_xlonglong_null() >> + item->arguments()[1]->to_longlong_null(); + } +}; + + +bool Item_func_shift_right::fix_length_and_dec() +{ + static Func_handler_shift_right_int_to_ulonglong ha_int_to_ull; + static Func_handler_shift_right_decimal_to_ulonglong ha_dec_to_ull; + return fix_length_and_dec_op1_std(&ha_int_to_ull, &ha_dec_to_ull); } -longlong Item_func_bit_neg::val_int() +class Func_handler_bit_neg_int_to_ulonglong: + public Item_handled_func::Handler_ulonglong { - DBUG_ASSERT(fixed == 1); - ulonglong res= (ulonglong) args[0]->val_int(); - if ((null_value=args[0]->null_value)) - return 0; - return ~res; +public: + Longlong_null to_longlong_null(Item_handled_func *item) const + { + DBUG_ASSERT(item->is_fixed()); + return ~ item->arguments()[0]->to_longlong_null(); + } +}; + + +class Func_handler_bit_neg_decimal_to_ulonglong: + public Item_handled_func::Handler_ulonglong +{ +public: + Longlong_null to_longlong_null(Item_handled_func *item) const + { + DBUG_ASSERT(item->is_fixed()); + return ~ VDec(item->arguments()[0]).to_xlonglong_null(); + } +}; + + +bool Item_func_bit_neg::fix_length_and_dec() +{ + static Func_handler_bit_neg_int_to_ulonglong ha_int_to_ull; + static Func_handler_bit_neg_decimal_to_ulonglong ha_dec_to_ull; + return fix_length_and_dec_op1_std(&ha_int_to_ull, &ha_dec_to_ull); } @@ -2235,27 +2299,17 @@ void Item_func_int_val::fix_length_and_dec_int_or_decimal() fix_char_length(precision + sign_length); if (precision > 9) { -#if MYSQL_VERSION_ID > 100500 -#error Remove the '#else' branch and the conditional compilation if (unsigned_flag) set_handler(&type_handler_ulonglong); else set_handler(&type_handler_slonglong); -#else - set_handler(&type_handler_longlong); -#endif } else { -#if MYSQL_VERSION_ID > 100500 -#error Remove the '#else' branch and the conditional compilation if (unsigned_flag) set_handler(&type_handler_ulong); else set_handler(&type_handler_slong); -#else - set_handler(&type_handler_long); -#endif } } } @@ -3097,11 +3151,10 @@ longlong Item_func_locate::val_int() if (!b->length()) // Found empty string at start return start + 1; - if (!cmp_collation.collation->coll->instr(cmp_collation.collation, - a->ptr()+start, - (uint) (a->length()-start), - b->ptr(), b->length(), - &match, 1)) + if (!cmp_collation.collation->instr(a->ptr() + start, + (uint) (a->length() - start), + b->ptr(), b->length(), + &match, 1)) return 0; return (longlong) match.mb_len + start0 + 1; } @@ -3214,7 +3267,7 @@ longlong Item_func_ord::val_int() null_value=0; if (!res->length()) return 0; #ifdef USE_MB - if (use_mb(res->charset())) + if (res->use_mb()) { const char *str=res->ptr(); uint32 n=0, l=my_ismbchar(res->charset(),str,str+res->length()); @@ -3300,14 +3353,14 @@ longlong Item_func_find_in_set::val_int() const char *str_begin= buffer->ptr(); const char *str_end= buffer->ptr(); const char *real_end= str_end+buffer->length(); - const uchar *find_str= (const uchar *) find->ptr(); + const char *find_str= find->ptr(); uint find_str_len= find->length(); int position= 0; while (1) { int symbol_len; - if ((symbol_len= cs->cset->mb_wc(cs, &wc, (uchar*) str_end, - (uchar*) real_end)) > 0) + if ((symbol_len= cs->mb_wc(&wc, (uchar*) str_end, + (uchar*) real_end)) > 0) { const char *substr_end= str_end + symbol_len; bool is_last_item= (substr_end == real_end); @@ -3317,9 +3370,8 @@ longlong Item_func_find_in_set::val_int() position++; if (is_last_item && !is_separator) str_end= substr_end; - if (!my_strnncoll(cs, (const uchar *) str_begin, - (uint) (str_end - str_begin), - find_str, find_str_len)) + if (!cs->strnncoll(str_begin, (uint) (str_end - str_begin), + find_str, find_str_len)) return (longlong) position; else str_begin= substr_end; @@ -3337,13 +3389,39 @@ longlong Item_func_find_in_set::val_int() return 0; } -longlong Item_func_bit_count::val_int() + +class Func_handler_bit_count_int_to_slong: + public Item_handled_func::Handler_slong2 { - DBUG_ASSERT(fixed == 1); - ulonglong value= (ulonglong) args[0]->val_int(); - if ((null_value= args[0]->null_value)) - return 0; /* purecov: inspected */ - return (longlong) my_count_bits(value); +public: + Longlong_null to_longlong_null(Item_handled_func *item) const + { + DBUG_ASSERT(item->is_fixed()); + return item->arguments()[0]->to_longlong_null().bit_count(); + } +}; + + +class Func_handler_bit_count_decimal_to_slong: + public Item_handled_func::Handler_slong2 +{ +public: + Longlong_null to_longlong_null(Item_handled_func *item) const + { + DBUG_ASSERT(item->is_fixed()); + return VDec(item->arguments()[0]).to_xlonglong_null().bit_count(); + } +}; + + +bool Item_func_bit_count::fix_length_and_dec() +{ + static Func_handler_bit_count_int_to_slong ha_int_to_slong; + static Func_handler_bit_count_decimal_to_slong ha_dec_to_slong; + set_func_handler(args[0]->cmp_type() == INT_RESULT ? + (const Handler *) &ha_int_to_slong : + (const Handler *) &ha_dec_to_slong); + return m_func_handler->fix_length_and_dec(this); } @@ -3798,12 +3876,13 @@ longlong Item_master_pos_wait::val_int() THD* thd = current_thd; String *log_name = args[0]->val_str(&value); int event_count= 0; + DBUG_ENTER("Item_master_pos_wait::val_int"); null_value=0; if (thd->slave_thread || !log_name || !log_name->length()) { null_value = 1; - return 0; + DBUG_RETURN(0); } #ifdef HAVE_REPLICATION longlong pos = (ulong)args[1]->val_int(); @@ -3839,13 +3918,15 @@ longlong Item_master_pos_wait::val_int() } mi->release(); #endif - return event_count; + DBUG_PRINT("exit", ("event_count: %d null_value: %d", event_count, + (int) null_value)); + DBUG_RETURN(event_count); #ifdef HAVE_REPLICATION err: { null_value = 1; - return 0; + DBUG_RETURN(0); } #endif } @@ -3856,11 +3937,12 @@ longlong Item_master_gtid_wait::val_int() DBUG_ASSERT(fixed == 1); longlong result= 0; String *gtid_pos __attribute__((unused)) = args[0]->val_str(&value); + DBUG_ENTER("Item_master_gtid_wait::val_int"); if (args[0]->null_value) { null_value= 1; - return 0; + DBUG_RETURN(0); } null_value=0; @@ -3877,7 +3959,7 @@ longlong Item_master_gtid_wait::val_int() #else null_value= 0; #endif /* REPLICATION */ - return result; + DBUG_RETURN(result); } @@ -4156,16 +4238,17 @@ longlong Item_func_get_lock::val_int() DBUG_PRINT("enter", ("lock: %.*s", res->length(), res->ptr())); /* HASH entries are of type User_level_lock. */ if (! my_hash_inited(&thd->ull_hash) && - my_hash_init(&thd->ull_hash, &my_charset_bin, - 16 /* small hash */, 0, 0, ull_get_key, NULL, 0)) + my_hash_init(key_memory_User_level_lock, &thd->ull_hash, + &my_charset_bin, 16 /* small hash */, 0, 0, ull_get_key, + NULL, 0)) { DBUG_RETURN(0); } MDL_request ull_request; - ull_request.init(MDL_key::USER_LOCK, res->c_ptr_safe(), "", + MDL_REQUEST_INIT(&ull_request, MDL_key::USER_LOCK, res->c_ptr_safe(), "", MDL_SHARED_NO_WRITE, MDL_EXPLICIT); - MDL_key *ull_key = &ull_request.key; + MDL_key *ull_key= &ull_request.key; if ((ull= (User_level_lock*) @@ -4173,7 +4256,7 @@ longlong Item_func_get_lock::val_int() { /* Recursive lock */ ull->refs++; - null_value = 0; + null_value= 0; DBUG_PRINT("info", ("recursive lock, ref-count: %d", (int) ull->refs)); DBUG_RETURN(1); } @@ -4189,7 +4272,8 @@ longlong Item_func_get_lock::val_int() DBUG_RETURN(0); } - ull= (User_level_lock*) my_malloc(sizeof(User_level_lock), + ull= (User_level_lock*) my_malloc(key_memory_User_level_lock, + sizeof(User_level_lock), MYF(MY_WME|MY_THREAD_SPECIFIC)); if (ull == NULL) { @@ -4213,6 +4297,30 @@ longlong Item_func_get_lock::val_int() /** + Release all user level locks. + @return + - N if N-lock released + - 0 if lock wasn't held +*/ +longlong Item_func_release_all_locks::val_int() +{ + DBUG_ASSERT(fixed == 1); + THD *thd= current_thd; + ulong num_unlocked= 0; + DBUG_ENTER("Item_func_release_all_locks::val_int"); + for (size_t i= 0; i < thd->ull_hash.records; i++) + { + auto ull= (User_level_lock *) my_hash_element(&thd->ull_hash, i); + thd->mdl_context.release_lock(ull->lock); + num_unlocked+= ull->refs; + my_free(ull); + } + my_hash_free(&thd->ull_hash); + DBUG_RETURN(num_unlocked); +} + + +/** Release a user level lock. @return - 1 if lock released @@ -4412,7 +4520,7 @@ static PSI_mutex_key key_LOCK_item_func_sleep; static PSI_mutex_info item_func_sleep_mutexes[]= { - { &key_LOCK_item_func_sleep, "LOCK_user_locks", PSI_FLAG_GLOBAL} + { &key_LOCK_item_func_sleep, "LOCK_item_func_sleep", PSI_FLAG_GLOBAL} }; @@ -4533,7 +4641,7 @@ user_var_entry *get_variable(HASH *hash, LEX_CSTRING *name, size_t size=ALIGN_SIZE(sizeof(user_var_entry))+name->length+1+extra_size; if (!my_hash_inited(hash)) return 0; - if (!(entry = (user_var_entry*) my_malloc(size, + if (!(entry = (user_var_entry*) my_malloc(key_memory_user_var_entry, size, MYF(MY_WME | ME_FATAL | MY_THREAD_SPECIFIC)))) return 0; @@ -4625,8 +4733,10 @@ bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref) null_item= (args[0]->type() == NULL_ITEM); if (!m_var_entry->charset() || !null_item) m_var_entry->set_charset(args[0]->collation.derivation == DERIVATION_NUMERIC ? - default_charset() : args[0]->collation.collation); - collation.set(m_var_entry->charset(), DERIVATION_IMPLICIT); + &my_charset_numeric : args[0]->collation.collation); + collation.set(m_var_entry->charset(), + args[0]->collation.derivation == DERIVATION_NUMERIC ? + DERIVATION_NUMERIC : DERIVATION_IMPLICIT); switch (args[0]->result_type()) { case STRING_RESULT: case TIME_RESULT: @@ -4638,7 +4748,8 @@ bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref) set_handler(&type_handler_double); break; case INT_RESULT: - set_handler(Type_handler::type_handler_long_or_longlong(max_char_length())); + set_handler(Type_handler::type_handler_long_or_longlong(max_char_length(), + unsigned_flag)); break; case DECIMAL_RESULT: set_handler(&type_handler_newdecimal); @@ -4678,11 +4789,14 @@ Item_func_set_user_var::fix_length_and_dec() { maybe_null=args[0]->maybe_null; decimals=args[0]->decimals; - collation.set(DERIVATION_IMPLICIT); if (args[0]->collation.derivation == DERIVATION_NUMERIC) - fix_length_and_charset(args[0]->max_char_length(), default_charset()); + { + collation.set(DERIVATION_NUMERIC); + fix_length_and_charset(args[0]->max_char_length(), &my_charset_numeric); + } else { + collation.set(DERIVATION_IMPLICIT); fix_length_and_charset(args[0]->max_char_length(), args[0]->collation.collation); } @@ -4787,10 +4901,10 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, size_t length, char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry)); if (entry->value == pos) entry->value=0; - entry->value= (char*) my_realloc(entry->value, length, + entry->value= (char*) my_realloc(key_memory_user_var_entry_value, + entry->value, length, MYF(MY_ALLOW_ZERO_PTR | MY_WME | - ME_FATAL | - MY_THREAD_SPECIFIC)); + ME_FATAL | MY_THREAD_SPECIFIC)); if (!entry->value) return 1; } @@ -4809,6 +4923,12 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, size_t length, entry->unsigned_flag= unsigned_arg; } entry->type=type; +#ifdef USER_VAR_TRACKING +#ifndef EMBEDDED_LIBRARY + THD *thd= current_thd; + thd->session_tracker.user_variables.mark_as_changed(thd, entry); +#endif +#endif // USER_VAR_TRACKING return 0; } @@ -4898,7 +5018,7 @@ longlong user_var_entry::val_int(bool *null_value) const /** Get the value of a variable as a string. */ String *user_var_entry::val_str(bool *null_value, String *str, - uint decimals) + uint decimals) const { if ((*null_value= (value == 0))) return (String*) 0; @@ -5074,13 +5194,13 @@ Item_func_set_user_var::update() case REAL_RESULT: { res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal), - REAL_RESULT, default_charset(), 0); + REAL_RESULT, &my_charset_numeric, 0); break; } case INT_RESULT: { res= update_hash((void*) &save_result.vint, sizeof(save_result.vint), - INT_RESULT, default_charset(), unsigned_flag); + INT_RESULT, &my_charset_numeric, unsigned_flag); break; } case STRING_RESULT: @@ -5100,7 +5220,7 @@ Item_func_set_user_var::update() else res= update_hash((void*) save_result.vdec, sizeof(my_decimal), DECIMAL_RESULT, - default_charset(), 0); + &my_charset_numeric, 0); break; } case ROW_RESULT: @@ -5231,7 +5351,7 @@ void Item_func_set_user_var::make_send_field(THD *thd, Send_field *tmp_field) if (result_field) { result_field->make_send_field(tmp_field); - DBUG_ASSERT(tmp_field->table_name != 0); + DBUG_ASSERT(tmp_field->table_name.str != 0); if (Item::name.str) tmp_field->col_name= Item::name; // Use user supplied name } @@ -5539,22 +5659,31 @@ bool Item_func_get_user_var::fix_length_and_dec() { unsigned_flag= m_var_entry->unsigned_flag; max_length= (uint32)m_var_entry->length; - collation.set(m_var_entry->charset(), DERIVATION_IMPLICIT); - set_handler_by_result_type(m_var_entry->type); - switch (result_type()) { + switch (m_var_entry->type) { case REAL_RESULT: + collation.set(&my_charset_numeric, DERIVATION_NUMERIC); fix_char_length(DBL_DIG + 8); + set_handler(&type_handler_double); break; case INT_RESULT: + collation.set(&my_charset_numeric, DERIVATION_NUMERIC); fix_char_length(MAX_BIGINT_WIDTH); decimals=0; + if (unsigned_flag) + set_handler(&type_handler_ulonglong); + else + set_handler(&type_handler_slonglong); break; case STRING_RESULT: + collation.set(m_var_entry->charset(), DERIVATION_IMPLICIT); max_length= MAX_BLOB_WIDTH - 1; + set_handler(&type_handler_long_blob); break; case DECIMAL_RESULT: + collation.set(&my_charset_numeric, DERIVATION_NUMERIC); fix_char_length(DECIMAL_MAX_STR_LENGTH); decimals= DECIMAL_MAX_SCALE; + set_handler(&type_handler_newdecimal); break; case ROW_RESULT: // Keep compiler happy case TIME_RESULT: @@ -5751,7 +5880,7 @@ bool Item_func_get_system_var::fix_length_and_dec() case SHOW_SINT: case SHOW_SLONG: case SHOW_SLONGLONG: - collation.set_numeric(); + collation= DTCollation_numeric(); fix_char_length(MY_INT64_NUM_DECIMAL_DIGITS); decimals=0; break; @@ -5765,9 +5894,8 @@ bool Item_func_get_system_var::fix_length_and_dec() var_type, &component)); if (cptr) - max_length= (uint32)system_charset_info->cset->numchars(system_charset_info, - cptr, - cptr + strlen(cptr)); + max_length= (uint32) system_charset_info->numchars(cptr, + cptr + strlen(cptr)); mysql_mutex_unlock(&LOCK_global_system_variables); collation.set(system_charset_info, DERIVATION_SYSCONST); max_length*= system_charset_info->mbmaxlen; @@ -5780,9 +5908,8 @@ bool Item_func_get_system_var::fix_length_and_dec() reinterpret_cast<const LEX_STRING*>(var->value_ptr(current_thd, var_type, &component)); - max_length= (uint32)system_charset_info->cset->numchars(system_charset_info, - ls->str, - ls->str + ls->length); + max_length= (uint32) system_charset_info->numchars(ls->str, + ls->str + ls->length); mysql_mutex_unlock(&LOCK_global_system_variables); collation.set(system_charset_info, DERIVATION_SYSCONST); max_length*= system_charset_info->mbmaxlen; @@ -5791,13 +5918,13 @@ bool Item_func_get_system_var::fix_length_and_dec() break; case SHOW_BOOL: case SHOW_MY_BOOL: - collation.set_numeric(); + collation= DTCollation_numeric(); fix_char_length(1); decimals=0; break; case SHOW_DOUBLE: decimals= 6; - collation.set_numeric(); + collation= DTCollation_numeric(); fix_char_length(DBL_DIG + 6); break; default: @@ -5843,11 +5970,12 @@ const Type_handler *Item_func_get_system_var::type_handler() const case SHOW_SINT: case SHOW_SLONG: case SHOW_SLONGLONG: + return &type_handler_slonglong; case SHOW_UINT: case SHOW_ULONG: case SHOW_ULONGLONG: case SHOW_HA_ROWS: - return &type_handler_longlong; + return &type_handler_ulonglong; case SHOW_CHAR: case SHOW_CHAR_PTR: case SHOW_LEX_STRING: @@ -6014,7 +6142,7 @@ bool Item_func_match::init_search(THD *thd, bool no_order) { DBUG_ENTER("Item_func_match::init_search"); - if (!table->file->get_table()) // the handler isn't opened yet + if (!table->file->is_open()) DBUG_RETURN(0); /* Check if init_search() has been called before */ @@ -6322,14 +6450,38 @@ void Item_func_match::print(String *str, enum_query_type query_type) str->append(STRING_WITH_LEN("))")); } -longlong Item_func_bit_xor::val_int() + +class Func_handler_bit_xor_int_to_ulonglong: + public Item_handled_func::Handler_ulonglong { - DBUG_ASSERT(fixed == 1); - ulonglong arg1= (ulonglong) args[0]->val_int(); - ulonglong arg2= (ulonglong) args[1]->val_int(); - if ((null_value= (args[0]->null_value || args[1]->null_value))) - return 0; - return (longlong) (arg1 ^ arg2); +public: + Longlong_null to_longlong_null(Item_handled_func *item) const + { + DBUG_ASSERT(item->is_fixed()); + return item->arguments()[0]->to_longlong_null() ^ + item->arguments()[1]->to_longlong_null(); + } +}; + + +class Func_handler_bit_xor_dec_to_ulonglong: + public Item_handled_func::Handler_ulonglong +{ +public: + Longlong_null to_longlong_null(Item_handled_func *item) const + { + DBUG_ASSERT(item->is_fixed()); + return VDec(item->arguments()[0]).to_xlonglong_null() ^ + VDec(item->arguments()[1]).to_xlonglong_null(); + } +}; + + +bool Item_func_bit_xor::fix_length_and_dec() +{ + static const Func_handler_bit_xor_int_to_ulonglong ha_int_to_ull; + static const Func_handler_bit_xor_dec_to_ulonglong ha_dec_to_ull; + return fix_length_and_dec_op2_std(&ha_int_to_ull, &ha_dec_to_ull); } @@ -6896,7 +7048,7 @@ longlong Item_func_nextval::val_int() if (!(entry= ((SEQUENCE_LAST_VALUE*) my_hash_search(&thd->sequences, (uchar*) key, length)))) { - if (!(key= (char*) my_memdup(key, length, MYF(MY_WME))) || + if (!(key= (char*) my_memdup(PSI_INSTRUMENT_ME, key, length, MYF(MY_WME))) || !(entry= new SEQUENCE_LAST_VALUE((uchar*) key, length))) { /* EOM, error given */ |