#include "mysql_priv.h"#include "slave.h"#include <m_ctype.h>#include <hash.h>#include <time.h>#include <ft_global.h>#include "sp_head.h"#include "sp_rcontext.h"#include "sp.h"Include dependency graph for item_func.cc:

Go to the source code of this file.
Classes | |
| class | User_level_lock |
Defines | |
| #define | extra_size sizeof(double) |
Functions | |
| bool | check_reserved_words (LEX_STRING *name) |
| bool | eval_const_cond (COND *cond) |
| double | my_double_round (double value, int dec, bool truncate) |
| char * | ull_get_key (const User_level_lock *ull, uint *length, my_bool not_used __attribute__((unused))) |
| void | item_user_lock_init (void) |
| void | item_user_lock_free (void) |
| void | item_user_lock_release (User_level_lock *ull) |
| static user_var_entry * | get_variable (HASH *hash, LEX_STRING &name, bool create_if_not_exists) |
| static bool | update_hash (user_var_entry *entry, bool set_null, void *ptr, uint length, Item_result type, CHARSET_INFO *cs, Derivation dv, bool unsigned_arg) |
| int | get_var_with_binlog (THD *thd, enum_sql_command sql_command, LEX_STRING &name, user_var_entry **out_entry) |
| Item * | get_system_var (THD *thd, enum_var_type var_type, LEX_STRING name, LEX_STRING component) |
Variables | |
| static const char | separator = ',' |
| pthread_mutex_t | LOCK_user_locks |
| static HASH | hash_user_locks |
| static bool | item_user_lock_inited = 0 |
| #define extra_size sizeof(double) |
Definition at line 3415 of file item_func.cc.
Referenced by get_variable(), page_cur_insert_rec_write_log(), and update_hash().
| bool check_reserved_words | ( | LEX_STRING * | name | ) |
Definition at line 40 of file item_func.cc.
References FALSE, my_strcasecmp, name, system_charset_info, and TRUE.
00041 { 00042 if (!my_strcasecmp(system_charset_info, name->str, "GLOBAL") || 00043 !my_strcasecmp(system_charset_info, name->str, "LOCAL") || 00044 !my_strcasecmp(system_charset_info, name->str, "SESSION")) 00045 return TRUE; 00046 return FALSE; 00047 }
Definition at line 53 of file item_func.cc.
References cond, FALSE, and TRUE.
Referenced by remove_eq_conds().
Here is the caller graph for this function:

| Item* get_system_var | ( | THD * | thd, | |
| enum_var_type | var_type, | |||
| LEX_STRING | name, | |||
| LEX_STRING | component | |||
| ) |
Definition at line 4621 of file item_func.cc.
References base_name, ER_VARIABLE_IS_NOT_STRUCT, find_sys_var(), sys_var::is_struct(), LEX_STRING::length, MAX_SYS_VAR_LENGTH, my_error(), MYF, name, NULL, set_if_smaller, LEX_STRING::str, and UNCACHEABLE_SIDEEFFECT.
Referenced by create_select_for_variable().
04623 { 04624 sys_var *var; 04625 LEX_STRING *base_name, *component_name; 04626 04627 if (component.str) 04628 { 04629 base_name= &component; 04630 component_name= &name; 04631 } 04632 else 04633 { 04634 base_name= &name; 04635 component_name= &component; // Empty string 04636 } 04637 04638 if (!(var= find_sys_var(base_name->str, base_name->length))) 04639 return 0; 04640 if (component.str) 04641 { 04642 if (!var->is_struct()) 04643 { 04644 my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), base_name->str); 04645 return 0; 04646 } 04647 } 04648 thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT); 04649 04650 set_if_smaller(component_name->length, MAX_SYS_VAR_LENGTH); 04651 04652 return new Item_func_get_system_var(var, var_type, component_name, 04653 NULL, 0); 04654 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int get_var_with_binlog | ( | THD * | thd, | |
| enum_sql_command | sql_command, | |||
| LEX_STRING & | name, | |||
| user_var_entry ** | out_entry | |||
| ) |
Definition at line 3964 of file item_func.cc.
References ALIGN_SIZE, alloc_root(), st_user_var_events::charset_number, err, get_variable(), insert_dynamic(), MYSQL_BIN_LOG::is_query_in_union(), is_update_query(), st_user_var_events::length, lex_start(), memcpy, mysql_bin_log, name, NULL, opt_bin_log, List< T >::push_back(), sql_set_variables(), st_user_var_events::type, st_user_var_events::user_var_event, and st_user_var_events::value.
Referenced by Item_func_get_user_var::fix_length_and_dec(), and insert_params_from_vars_with_log().
03966 { 03967 BINLOG_USER_VAR_EVENT *user_var_event; 03968 user_var_entry *var_entry; 03969 var_entry= get_variable(&thd->user_vars, name, 0); 03970 03971 if (!(opt_bin_log && is_update_query(sql_command))) 03972 { 03973 *out_entry= var_entry; 03974 return 0; 03975 } 03976 03977 if (!var_entry) 03978 { 03979 /* 03980 If the variable does not exist, it's NULL, but we want to create it so 03981 that it gets into the binlog (if it didn't, the slave could be 03982 influenced by a variable of the same name previously set by another 03983 thread). 03984 We create it like if it had been explicitly set with SET before. 03985 The 'new' mimics what sql_yacc.yy does when 'SET @a=10;'. 03986 sql_set_variables() is what is called from 'case SQLCOM_SET_OPTION' 03987 in dispatch_command()). Instead of building a one-element list to pass to 03988 sql_set_variables(), we could instead manually call check() and update(); 03989 this would save memory and time; but calling sql_set_variables() makes 03990 one unique place to maintain (sql_set_variables()). 03991 03992 Manipulation with lex is necessary since free_underlaid_joins 03993 is going to release memory belonging to the main query. 03994 */ 03995 03996 List<set_var_base> tmp_var_list; 03997 LEX *sav_lex= thd->lex, lex_tmp; 03998 thd->lex= &lex_tmp; 03999 lex_start(thd, NULL, 0); 04000 tmp_var_list.push_back(new set_var_user(new Item_func_set_user_var(name, 04001 new Item_null()))); 04002 /* Create the variable */ 04003 if (sql_set_variables(thd, &tmp_var_list)) 04004 { 04005 thd->lex= sav_lex; 04006 goto err; 04007 } 04008 thd->lex= sav_lex; 04009 if (!(var_entry= get_variable(&thd->user_vars, name, 0))) 04010 goto err; 04011 } 04012 else if (var_entry->used_query_id == thd->query_id || 04013 mysql_bin_log.is_query_in_union(thd, var_entry->used_query_id)) 04014 { 04015 /* 04016 If this variable was already stored in user_var_events by this query 04017 (because it's used in more than one place in the query), don't store 04018 it. 04019 */ 04020 *out_entry= var_entry; 04021 return 0; 04022 } 04023 04024 uint size; 04025 /* 04026 First we need to store value of var_entry, when the next situation 04027 appears: 04028 > set @a:=1; 04029 > insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1); 04030 We have to write to binlog value @a= 1. 04031 04032 We allocate the user_var_event on user_var_events_alloc pool, not on 04033 the this-statement-execution pool because in SPs user_var_event objects 04034 may need to be valid after current [SP] statement execution pool is 04035 destroyed. 04036 */ 04037 size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length; 04038 if (!(user_var_event= (BINLOG_USER_VAR_EVENT *) 04039 alloc_root(thd->user_var_events_alloc, size))) 04040 goto err; 04041 04042 user_var_event->value= (char*) user_var_event + 04043 ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)); 04044 user_var_event->user_var_event= var_entry; 04045 user_var_event->type= var_entry->type; 04046 user_var_event->charset_number= var_entry->collation.collation->number; 04047 if (!var_entry->value) 04048 { 04049 /* NULL value*/ 04050 user_var_event->length= 0; 04051 user_var_event->value= 0; 04052 } 04053 else 04054 { 04055 user_var_event->length= var_entry->length; 04056 memcpy(user_var_event->value, var_entry->value, 04057 var_entry->length); 04058 } 04059 /* Mark that this variable has been used by this query */ 04060 var_entry->used_query_id= thd->query_id; 04061 if (insert_dynamic(&thd->user_var_events, (gptr) &user_var_event)) 04062 goto err; 04063 04064 *out_entry= var_entry; 04065 return 0; 04066 04067 err: 04068 *out_entry= var_entry; 04069 return 1; 04070 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static user_var_entry* get_variable | ( | HASH * | hash, | |
| LEX_STRING & | name, | |||
| bool | create_if_not_exists | |||
| ) | [static] |
Definition at line 3417 of file item_func.cc.
References ALIGN_SIZE, current_thd, DERIVATION_IMPLICIT, extra_size, hash(), hash_inited, hash_search(), memcpy, my_free, my_hash_insert(), my_malloc(), MY_WME, MYF, name, NULL, and STRING_RESULT.
Referenced by Item_user_var_as_out_param::fix_fields(), Item_func_set_user_var::fix_fields(), and get_var_with_binlog().
03419 { 03420 user_var_entry *entry; 03421 03422 if (!(entry = (user_var_entry*) hash_search(hash, (byte*) name.str, 03423 name.length)) && 03424 create_if_not_exists) 03425 { 03426 uint size=ALIGN_SIZE(sizeof(user_var_entry))+name.length+1+extra_size; 03427 if (!hash_inited(hash)) 03428 return 0; 03429 if (!(entry = (user_var_entry*) my_malloc(size,MYF(MY_WME)))) 03430 return 0; 03431 entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+ 03432 extra_size; 03433 entry->name.length=name.length; 03434 entry->value=0; 03435 entry->length=0; 03436 entry->update_query_id=0; 03437 entry->collation.set(NULL, DERIVATION_IMPLICIT); 03438 entry->unsigned_flag= 0; 03439 /* 03440 If we are here, we were called from a SET or a query which sets a 03441 variable. Imagine it is this: 03442 INSERT INTO t SELECT @a:=10, @a:=@a+1. 03443 Then when we have a Item_func_get_user_var (because of the @a+1) so we 03444 think we have to write the value of @a to the binlog. But before that, 03445 we have a Item_func_set_user_var to create @a (@a:=10), in this we mark 03446 the variable as "already logged" (line below) so that it won't be logged 03447 by Item_func_get_user_var (because that's not necessary). 03448 */ 03449 entry->used_query_id=current_thd->query_id; 03450 entry->type=STRING_RESULT; 03451 memcpy(entry->name.str, name.str, name.length+1); 03452 if (my_hash_insert(hash,(byte*) entry)) 03453 { 03454 my_free((char*) entry,MYF(0)); 03455 return 0; 03456 } 03457 } 03458 return entry; 03459 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void item_user_lock_free | ( | void | ) |
Definition at line 3025 of file item_func.cc.
References hash_free(), hash_user_locks, and pthread_mutex_destroy.
Referenced by clean_up().
03026 { 03027 if (item_user_lock_inited) 03028 { 03029 item_user_lock_inited= 0; 03030 hash_free(&hash_user_locks); 03031 pthread_mutex_destroy(&LOCK_user_locks); 03032 } 03033 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void item_user_lock_init | ( | void | ) |
Definition at line 3017 of file item_func.cc.
References hash_init, hash_user_locks, MY_MUTEX_INIT_SLOW, NULL, pthread_mutex_init, system_charset_info, and ull_get_key().
Referenced by item_init().
03018 { 03019 pthread_mutex_init(&LOCK_user_locks,MY_MUTEX_INIT_SLOW); 03020 hash_init(&hash_user_locks,system_charset_info, 03021 16,0,0,(hash_get_key) ull_get_key,NULL,0); 03022 item_user_lock_inited= 1; 03023 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void item_user_lock_release | ( | User_level_lock * | ull | ) |
Definition at line 3035 of file item_func.cc.
References User_level_lock::cond, User_level_lock::count, User_level_lock::locked, and User_level_lock::thread_id.
Referenced by Item_func_release_lock::val_int(), and Item_func_get_lock::val_int().
03036 { 03037 ull->locked=0; 03038 ull->thread_id= 0; 03039 if (--ull->count) 03040 pthread_cond_signal(&ull->cond); 03041 else 03042 delete ull; 03043 }
Here is the caller graph for this function:

| double my_double_round | ( | double | value, | |
| int | dec, | |||
| bool | truncate | |||
| ) |
Definition at line 1869 of file item_func.cc.
References abs, array_elements, log_10, and rint.
Referenced by Item_func_round::real_op(), and Item_func_format::val_str().
01870 { 01871 double tmp; 01872 uint abs_dec= abs(dec); 01873 /* 01874 tmp2 is here to avoid return the value with 80 bit precision 01875 This will fix that the test round(0.1,1) = round(0.1,1) is true 01876 */ 01877 volatile double tmp2; 01878 01879 tmp=(abs_dec < array_elements(log_10) ? 01880 log_10[abs_dec] : pow(10.0,(double) abs_dec)); 01881 01882 if (truncate) 01883 { 01884 if (value >= 0) 01885 tmp2= dec < 0 ? floor(value/tmp)*tmp : floor(value*tmp)/tmp; 01886 else 01887 tmp2= dec < 0 ? ceil(value/tmp)*tmp : ceil(value*tmp)/tmp; 01888 } 01889 else 01890 tmp2=dec < 0 ? rint(value/tmp)*tmp : rint(value*tmp)/tmp; 01891 return tmp2; 01892 }
Here is the caller graph for this function:

| char* ull_get_key | ( | const User_level_lock * | ull, | |
| uint * | length, | |||
| my_bool not_used | __attribute__((unused)) | |||
| ) |
Definition at line 3007 of file item_func.cc.
References User_level_lock::key, and User_level_lock::key_length.
Referenced by item_user_lock_init().
03009 { 03010 *length=(uint) ull->key_length; 03011 return (char*) ull->key; 03012 }
Here is the caller graph for this function:

| static bool update_hash | ( | user_var_entry * | entry, | |
| bool | set_null, | |||
| void * | ptr, | |||
| uint | length, | |||
| Item_result | type, | |||
| CHARSET_INFO * | cs, | |||
| Derivation | dv, | |||
| bool | unsigned_arg | |||
| ) | [static] |
Definition at line 3532 of file item_func.cc.
References ALIGN_SIZE, DECIMAL_RESULT, extra_size, memcpy, MY_ALLOW_ZERO_PTR, my_free, my_realloc(), MYF, pos(), and STRING_RESULT.
Referenced by Item_user_var_as_out_param::set_null_value(), and Item_user_var_as_out_param::set_value().
03535 { 03536 if (set_null) 03537 { 03538 char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry)); 03539 if (entry->value && entry->value != pos) 03540 my_free(entry->value,MYF(0)); 03541 entry->value= 0; 03542 entry->length= 0; 03543 } 03544 else 03545 { 03546 if (type == STRING_RESULT) 03547 length++; // Store strings with end \0 03548 if (length <= extra_size) 03549 { 03550 /* Save value in value struct */ 03551 char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry)); 03552 if (entry->value != pos) 03553 { 03554 if (entry->value) 03555 my_free(entry->value,MYF(0)); 03556 entry->value=pos; 03557 } 03558 } 03559 else 03560 { 03561 /* Allocate variable */ 03562 if (entry->length != length) 03563 { 03564 char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry)); 03565 if (entry->value == pos) 03566 entry->value=0; 03567 if (!(entry->value=(char*) my_realloc(entry->value, length, 03568 MYF(MY_ALLOW_ZERO_PTR)))) 03569 return 1; 03570 } 03571 } 03572 if (type == STRING_RESULT) 03573 { 03574 length--; // Fix length change above 03575 entry->value[length]= 0; // Store end \0 03576 } 03577 memcpy(entry->value,ptr,length); 03578 if (type == DECIMAL_RESULT) 03579 ((my_decimal*)entry->value)->fix_buffer_pointer(); 03580 entry->length= length; 03581 entry->collation.set(cs, dv); 03582 entry->unsigned_flag= unsigned_arg; 03583 } 03584 entry->type=type; 03585 return 0; 03586 }
Here is the call graph for this function:

Here is the caller graph for this function:

HASH hash_user_locks [static] |
Definition at line 2964 of file item_func.cc.
Referenced by item_user_lock_free(), item_user_lock_init(), User_level_lock::User_level_lock(), Item_func_is_used_lock::val_int(), Item_func_is_free_lock::val_int(), Item_func_release_lock::val_int(), Item_func_get_lock::val_int(), and User_level_lock::~User_level_lock().
bool item_user_lock_inited = 0 [static] |
Definition at line 3015 of file item_func.cc.
| pthread_mutex_t LOCK_user_locks |
Definition at line 2963 of file item_func.cc.
const char separator = ',' [static] |
Definition at line 2441 of file item_func.cc.
Referenced by BaseString::append(), BaseString::assign(), print_table_data(), Events::reconstruct_interval_expression(), BaseString::split(), and Item_func_find_in_set::val_int().
1.4.7

