summaryrefslogtreecommitdiff
path: root/sql/item_func.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r--sql/item_func.cc402
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 */