149
149
return copy_or_same(session);
154
void debug_sync_point(const char* lock_name, uint32_t lock_timeout)
161
#define extra_size sizeof(double)
163
static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
164
bool create_if_not_exists)
166
user_var_entry *entry;
168
if (!(entry = (user_var_entry*) hash_search(hash, (unsigned char*) name.str,
170
create_if_not_exists)
172
uint32_t size=ALIGN_SIZE(sizeof(user_var_entry))+name.length+1+extra_size;
173
if (!hash_inited(hash))
175
if (!(entry = (user_var_entry*) my_malloc(size,MYF(MY_WME | ME_FATALERROR))))
177
entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+
179
entry->name.length=name.length;
182
entry->update_query_id=0;
183
entry->collation.set(NULL, DERIVATION_IMPLICIT, 0);
184
entry->unsigned_flag= 0;
186
If we are here, we were called from a SET or a query which sets a
187
variable. Imagine it is this:
188
INSERT INTO t SELECT @a:=10, @a:=@a+1.
189
Then when we have a Item_func_get_user_var (because of the @a+1) so we
190
think we have to write the value of @a to the binlog. But before that,
191
we have a Item_func_set_user_var to create @a (@a:=10), in this we mark
192
the variable as "already logged" (line below) so that it won't be logged
193
by Item_func_get_user_var (because that's not necessary).
195
entry->used_query_id=current_session->query_id;
196
entry->type=STRING_RESULT;
197
memcpy(entry->name.str, name.str, name.length+1);
198
if (my_hash_insert(hash,(unsigned char*) entry))
208
153
When a user variable is updated (in a SET command or a query like
856
Item_func_get_user_var::val_str(String *str)
860
return((String*) 0); // No such variable
861
return(var_entry->val_str(&null_value, str, decimals));
865
double Item_func_get_user_var::val_real()
869
return 0.0; // No such variable
870
return (var_entry->val_real(&null_value));
874
my_decimal *Item_func_get_user_var::val_decimal(my_decimal *dec)
879
return var_entry->val_decimal(&null_value, dec);
883
int64_t Item_func_get_user_var::val_int()
887
return 0L; // No such variable
888
return (var_entry->val_int(&null_value));
893
Get variable by name and, if necessary, put the record of variable
894
use into the binary log.
896
When a user variable is invoked from an update query (INSERT, UPDATE etc),
897
stores this variable and its value in session->user_var_events, so that it can be
898
written to the binlog (will be written just before the query is written, see
901
@param session Current thread
902
@param name Variable name
903
@param[out] out_entry variable structure or NULL. The pointer is set
904
regardless of whether function succeeded or not.
909
1 Failed to put appropriate record into binary log
913
int get_var_with_binlog(Session *session, enum_sql_command sql_command,
914
LEX_STRING &name, user_var_entry **out_entry)
916
BINLOG_USER_VAR_EVENT *user_var_event;
917
user_var_entry *var_entry;
918
var_entry= get_variable(&session->user_vars, name, 0);
921
Any reference to user-defined variable which is done from stored
922
function or trigger affects their execution and the execution of the
923
calling statement. We must log all such variables even if they are
924
not involved in table-updating statements.
926
if (!(opt_bin_log && is_update_query(sql_command)))
928
*out_entry= var_entry;
935
If the variable does not exist, it's NULL, but we want to create it so
936
that it gets into the binlog (if it didn't, the slave could be
937
influenced by a variable of the same name previously set by another
939
We create it like if it had been explicitly set with SET before.
940
The 'new' mimics what sql_yacc.yy does when 'SET @a=10;'.
941
sql_set_variables() is what is called from 'case SQLCOM_SET_OPTION'
942
in dispatch_command()). Instead of building a one-element list to pass to
943
sql_set_variables(), we could instead manually call check() and update();
944
this would save memory and time; but calling sql_set_variables() makes
945
one unique place to maintain (sql_set_variables()).
947
Manipulation with lex is necessary since free_underlaid_joins
948
is going to release memory belonging to the main query.
951
List<set_var_base> tmp_var_list;
952
LEX *sav_lex= session->lex, lex_tmp;
953
session->lex= &lex_tmp;
955
tmp_var_list.push_back(new set_var_user(new Item_func_set_user_var(name,
957
/* Create the variable */
958
if (sql_set_variables(session, &tmp_var_list))
960
session->lex= sav_lex;
963
session->lex= sav_lex;
964
if (!(var_entry= get_variable(&session->user_vars, name, 0)))
967
else if (var_entry->used_query_id == session->query_id ||
968
mysql_bin_log.is_query_in_union(session, var_entry->used_query_id))
971
If this variable was already stored in user_var_events by this query
972
(because it's used in more than one place in the query), don't store
975
*out_entry= var_entry;
981
First we need to store value of var_entry, when the next situation
984
> insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1);
985
We have to write to binlog value @a= 1.
987
We allocate the user_var_event on user_var_events_alloc pool, not on
988
the this-statement-execution pool because in SPs user_var_event objects
989
may need to be valid after current [SP] statement execution pool is
992
size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length;
993
if (!(user_var_event= (BINLOG_USER_VAR_EVENT *)
994
alloc_root(session->user_var_events_alloc, size)))
997
user_var_event->value= (char*) user_var_event +
998
ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT));
999
user_var_event->user_var_event= var_entry;
1000
user_var_event->type= var_entry->type;
1001
user_var_event->charset_number= var_entry->collation.collation->number;
1002
if (!var_entry->value)
1005
user_var_event->length= 0;
1006
user_var_event->value= 0;
1010
user_var_event->length= var_entry->length;
1011
memcpy(user_var_event->value, var_entry->value,
1014
/* Mark that this variable has been used by this query */
1015
var_entry->used_query_id= session->query_id;
1016
if (insert_dynamic(&session->user_var_events, (unsigned char*) &user_var_event))
1019
*out_entry= var_entry;
1023
*out_entry= var_entry;
1027
void Item_func_get_user_var::fix_length_and_dec()
1029
Session *session=current_session;
1032
decimals=NOT_FIXED_DEC;
1033
max_length=MAX_BLOB_WIDTH;
1035
error= get_var_with_binlog(session, session->lex->sql_command, name, &var_entry);
1038
If the variable didn't exist it has been created as a STRING-type.
1039
'var_entry' is NULL only if there occured an error during the call to
1040
get_var_with_binlog.
1044
m_cached_result_type= var_entry->type;
1045
unsigned_flag= var_entry->unsigned_flag;
1046
max_length= var_entry->length;
1048
collation.set(var_entry->collation);
1049
switch(m_cached_result_type) {
1051
max_length= DBL_DIG + 8;
1054
max_length= MAX_BIGINT_WIDTH;
1058
max_length= MAX_BLOB_WIDTH;
1060
case DECIMAL_RESULT:
1061
max_length= DECIMAL_MAX_STR_LENGTH;
1062
decimals= DECIMAL_MAX_SCALE;
1064
case ROW_RESULT: // Keep compiler happy
1072
collation.set(&my_charset_bin, DERIVATION_IMPLICIT);
1074
m_cached_result_type= STRING_RESULT;
1075
max_length= MAX_BLOB_WIDTH;
1080
bool Item_func_get_user_var::const_item() const
1082
return (!var_entry || current_session->query_id != var_entry->update_query_id);
1086
enum Item_result Item_func_get_user_var::result_type() const
1088
return m_cached_result_type;
1092
void Item_func_get_user_var::print(String *str,
1093
enum_query_type query_type __attribute__((unused)))
1095
str->append(STRING_WITH_LEN("(@"));
1096
str->append(name.str,name.length);
1101
bool Item_func_get_user_var::eq(const Item *item,
1102
bool binary_cmp __attribute__((unused))) const
1104
/* Assume we don't have rtti */
1106
return 1; // Same item is same.
1107
/* Check if other type is also a get_user_var() object */
1108
if (item->type() != FUNC_ITEM ||
1109
((Item_func*) item)->functype() != functype())
1111
Item_func_get_user_var *other=(Item_func_get_user_var*) item;
1112
return (name.length == other->name.length &&
1113
!memcmp(name.str, other->name.str, name.length));
1117
802
bool Item_user_var_as_out_param::fix_fields(Session *session, Item **ref)
1119
804
assert(fixed == 0);