150
149
return copy_or_same(session);
153
// Shift-functions, same as << and >> in C/C++
155
int64_t Item_func_shift_left::val_int()
159
uint64_t res= ((uint64_t) args[0]->val_int() <<
160
(shift=(uint) args[1]->val_int()));
161
if (args[0]->null_value || args[1]->null_value)
167
return (shift < sizeof(int64_t)*8 ? (int64_t) res : 0L);
170
int64_t Item_func_shift_right::val_int()
174
uint64_t res= (uint64_t) args[0]->val_int() >>
175
(shift=(uint) args[1]->val_int());
176
if (args[0]->null_value || args[1]->null_value)
182
return (shift < sizeof(int64_t)*8 ? (int64_t) res : 0);
185
// Conversion functions
187
void Item_func_integer::fix_length_and_dec()
189
max_length=args[0]->max_length - args[0]->decimals+1;
190
uint32_t tmp=float_length(decimals);
191
set_if_smaller(max_length,tmp);
195
int64_t Item_func_field::val_int()
199
if (cmp_type == STRING_RESULT)
202
if (!(field= args[0]->val_str(&value)))
204
for (uint32_t i=1 ; i < arg_count ; i++)
206
String *tmp_value=args[i]->val_str(&tmp);
207
if (tmp_value && !sortcmp(field,tmp_value,cmp_collation.collation))
208
return (int64_t) (i);
211
else if (cmp_type == INT_RESULT)
213
int64_t val= args[0]->val_int();
214
if (args[0]->null_value)
216
for (uint32_t i=1; i < arg_count ; i++)
218
if (val == args[i]->val_int() && !args[i]->null_value)
219
return (int64_t) (i);
222
else if (cmp_type == DECIMAL_RESULT)
224
my_decimal dec_arg_buf, *dec_arg,
225
dec_buf, *dec= args[0]->val_decimal(&dec_buf);
226
if (args[0]->null_value)
228
for (uint32_t i=1; i < arg_count; i++)
230
dec_arg= args[i]->val_decimal(&dec_arg_buf);
231
if (!args[i]->null_value && !my_decimal_cmp(dec_arg, dec))
232
return (int64_t) (i);
237
double val= args[0]->val_real();
238
if (args[0]->null_value)
240
for (uint32_t i=1; i < arg_count ; i++)
242
if (val == args[i]->val_real() && !args[i]->null_value)
243
return (int64_t) (i);
250
void Item_func_field::fix_length_and_dec()
252
maybe_null=0; max_length=3;
253
cmp_type= args[0]->result_type();
254
for (uint32_t i=1; i < arg_count ; i++)
255
cmp_type= item_cmp_type(cmp_type, args[i]->result_type());
256
if (cmp_type == STRING_RESULT)
257
agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1);
261
int64_t Item_func_ord::val_int()
264
String *res=args[0]->val_str(&value);
271
if (!res->length()) return 0;
273
if (use_mb(res->charset()))
275
register const char *str=res->ptr();
276
register uint32_t n=0, l=my_ismbchar(res->charset(),str,str+res->length());
278
return (int64_t)((unsigned char) *str);
280
n=(n<<8)|(uint32_t)((unsigned char) *str++);
284
return (int64_t) ((unsigned char) (*res)[0]);
291
pthread_mutex_t LOCK_user_locks;
292
static HASH hash_user_locks;
294
class User_level_lock
303
my_thread_id thread_id;
304
void set_thread(Session *session) { thread_id= session->thread_id; }
306
User_level_lock(const unsigned char *key_arg,uint32_t length, ulong id)
307
:key_length(length),count(1),locked(1), thread_id(id)
309
key= (unsigned char*) my_memdup(key_arg,length,MYF(0));
310
pthread_cond_init(&cond,NULL);
313
if (my_hash_insert(&hash_user_locks,(unsigned char*) this))
324
hash_delete(&hash_user_locks,(unsigned char*) this);
327
pthread_cond_destroy(&cond);
329
inline bool initialized() { return key != 0; }
330
friend void item_user_lock_release(User_level_lock *ull);
331
friend unsigned char *ull_get_key(const User_level_lock *ull, size_t *length,
335
unsigned char *ull_get_key(const User_level_lock *ull, size_t *length,
336
bool not_used __attribute__((unused)))
338
*length= ull->key_length;
343
static bool item_user_lock_inited= 0;
345
void item_user_lock_init(void)
347
pthread_mutex_init(&LOCK_user_locks,MY_MUTEX_INIT_SLOW);
348
hash_init(&hash_user_locks, system_charset_info,
349
16,0,0,(hash_get_key) ull_get_key,NULL,0);
350
item_user_lock_inited= 1;
353
void item_user_lock_free(void)
355
if (item_user_lock_inited)
357
item_user_lock_inited= 0;
358
hash_free(&hash_user_locks);
359
pthread_mutex_destroy(&LOCK_user_locks);
363
void item_user_lock_release(User_level_lock *ull)
368
pthread_cond_signal(&ull->cond);
374
Wait until we are at or past the given position in the master binlog
378
int64_t Item_master_pos_wait::val_int()
381
Session* session = current_session;
382
String *log_name = args[0]->val_str(&value);
386
if (session->slave_thread || !log_name || !log_name->length())
391
int64_t pos = (ulong)args[1]->val_int();
392
int64_t timeout = (arg_count==3) ? args[2]->val_int() : 0 ;
393
if ((event_count = active_mi->rli.wait_for_pos(session, log_name, pos, timeout)) == -2)
402
void debug_sync_point(const char* lock_name, uint32_t lock_timeout)
408
#define extra_size sizeof(double)
410
static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
411
bool create_if_not_exists)
413
user_var_entry *entry;
415
if (!(entry = (user_var_entry*) hash_search(hash, (unsigned char*) name.str,
417
create_if_not_exists)
419
uint32_t size=ALIGN_SIZE(sizeof(user_var_entry))+name.length+1+extra_size;
420
if (!hash_inited(hash))
422
if (!(entry = (user_var_entry*) my_malloc(size,MYF(MY_WME | ME_FATALERROR))))
424
entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+
426
entry->name.length=name.length;
429
entry->update_query_id=0;
430
entry->collation.set(NULL, DERIVATION_IMPLICIT, 0);
431
entry->unsigned_flag= 0;
433
If we are here, we were called from a SET or a query which sets a
434
variable. Imagine it is this:
435
INSERT INTO t SELECT @a:=10, @a:=@a+1.
436
Then when we have a Item_func_get_user_var (because of the @a+1) so we
437
think we have to write the value of @a to the binlog. But before that,
438
we have a Item_func_set_user_var to create @a (@a:=10), in this we mark
439
the variable as "already logged" (line below) so that it won't be logged
440
by Item_func_get_user_var (because that's not necessary).
442
entry->used_query_id=current_session->query_id;
443
entry->type=STRING_RESULT;
444
memcpy(entry->name.str, name.str, name.length+1);
445
if (my_hash_insert(hash,(unsigned char*) entry))
455
153
When a user variable is updated (in a SET command or a query like
1103
Item_func_get_user_var::val_str(String *str)
1107
return((String*) 0); // No such variable
1108
return(var_entry->val_str(&null_value, str, decimals));
1112
double Item_func_get_user_var::val_real()
1116
return 0.0; // No such variable
1117
return (var_entry->val_real(&null_value));
1121
my_decimal *Item_func_get_user_var::val_decimal(my_decimal *dec)
1126
return var_entry->val_decimal(&null_value, dec);
1130
int64_t Item_func_get_user_var::val_int()
1134
return 0L; // No such variable
1135
return (var_entry->val_int(&null_value));
1140
Get variable by name and, if necessary, put the record of variable
1141
use into the binary log.
1143
When a user variable is invoked from an update query (INSERT, UPDATE etc),
1144
stores this variable and its value in session->user_var_events, so that it can be
1145
written to the binlog (will be written just before the query is written, see
1148
@param session Current thread
1149
@param name Variable name
1150
@param[out] out_entry variable structure or NULL. The pointer is set
1151
regardless of whether function succeeded or not.
1156
1 Failed to put appropriate record into binary log
1160
int get_var_with_binlog(Session *session, enum_sql_command sql_command,
1161
LEX_STRING &name, user_var_entry **out_entry)
1163
BINLOG_USER_VAR_EVENT *user_var_event;
1164
user_var_entry *var_entry;
1165
var_entry= get_variable(&session->user_vars, name, 0);
1168
Any reference to user-defined variable which is done from stored
1169
function or trigger affects their execution and the execution of the
1170
calling statement. We must log all such variables even if they are
1171
not involved in table-updating statements.
1173
if (!(opt_bin_log && is_update_query(sql_command)))
1175
*out_entry= var_entry;
1182
If the variable does not exist, it's NULL, but we want to create it so
1183
that it gets into the binlog (if it didn't, the slave could be
1184
influenced by a variable of the same name previously set by another
1186
We create it like if it had been explicitly set with SET before.
1187
The 'new' mimics what sql_yacc.yy does when 'SET @a=10;'.
1188
sql_set_variables() is what is called from 'case SQLCOM_SET_OPTION'
1189
in dispatch_command()). Instead of building a one-element list to pass to
1190
sql_set_variables(), we could instead manually call check() and update();
1191
this would save memory and time; but calling sql_set_variables() makes
1192
one unique place to maintain (sql_set_variables()).
1194
Manipulation with lex is necessary since free_underlaid_joins
1195
is going to release memory belonging to the main query.
1198
List<set_var_base> tmp_var_list;
1199
LEX *sav_lex= session->lex, lex_tmp;
1200
session->lex= &lex_tmp;
1202
tmp_var_list.push_back(new set_var_user(new Item_func_set_user_var(name,
1204
/* Create the variable */
1205
if (sql_set_variables(session, &tmp_var_list))
1207
session->lex= sav_lex;
1210
session->lex= sav_lex;
1211
if (!(var_entry= get_variable(&session->user_vars, name, 0)))
1214
else if (var_entry->used_query_id == session->query_id ||
1215
mysql_bin_log.is_query_in_union(session, var_entry->used_query_id))
1218
If this variable was already stored in user_var_events by this query
1219
(because it's used in more than one place in the query), don't store
1222
*out_entry= var_entry;
1228
First we need to store value of var_entry, when the next situation
1231
> insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1);
1232
We have to write to binlog value @a= 1.
1234
We allocate the user_var_event on user_var_events_alloc pool, not on
1235
the this-statement-execution pool because in SPs user_var_event objects
1236
may need to be valid after current [SP] statement execution pool is
1239
size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length;
1240
if (!(user_var_event= (BINLOG_USER_VAR_EVENT *)
1241
alloc_root(session->user_var_events_alloc, size)))
1244
user_var_event->value= (char*) user_var_event +
1245
ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT));
1246
user_var_event->user_var_event= var_entry;
1247
user_var_event->type= var_entry->type;
1248
user_var_event->charset_number= var_entry->collation.collation->number;
1249
if (!var_entry->value)
1252
user_var_event->length= 0;
1253
user_var_event->value= 0;
1257
user_var_event->length= var_entry->length;
1258
memcpy(user_var_event->value, var_entry->value,
1261
/* Mark that this variable has been used by this query */
1262
var_entry->used_query_id= session->query_id;
1263
if (insert_dynamic(&session->user_var_events, (unsigned char*) &user_var_event))
1266
*out_entry= var_entry;
1270
*out_entry= var_entry;
1274
void Item_func_get_user_var::fix_length_and_dec()
1276
Session *session=current_session;
1279
decimals=NOT_FIXED_DEC;
1280
max_length=MAX_BLOB_WIDTH;
1282
error= get_var_with_binlog(session, session->lex->sql_command, name, &var_entry);
1285
If the variable didn't exist it has been created as a STRING-type.
1286
'var_entry' is NULL only if there occured an error during the call to
1287
get_var_with_binlog.
1291
m_cached_result_type= var_entry->type;
1292
unsigned_flag= var_entry->unsigned_flag;
1293
max_length= var_entry->length;
1295
collation.set(var_entry->collation);
1296
switch(m_cached_result_type) {
1298
max_length= DBL_DIG + 8;
1301
max_length= MAX_BIGINT_WIDTH;
1305
max_length= MAX_BLOB_WIDTH;
1307
case DECIMAL_RESULT:
1308
max_length= DECIMAL_MAX_STR_LENGTH;
1309
decimals= DECIMAL_MAX_SCALE;
1311
case ROW_RESULT: // Keep compiler happy
1319
collation.set(&my_charset_bin, DERIVATION_IMPLICIT);
1321
m_cached_result_type= STRING_RESULT;
1322
max_length= MAX_BLOB_WIDTH;
1327
bool Item_func_get_user_var::const_item() const
1329
return (!var_entry || current_session->query_id != var_entry->update_query_id);
1333
enum Item_result Item_func_get_user_var::result_type() const
1335
return m_cached_result_type;
1339
void Item_func_get_user_var::print(String *str,
1340
enum_query_type query_type __attribute__((unused)))
1342
str->append(STRING_WITH_LEN("(@"));
1343
str->append(name.str,name.length);
1348
bool Item_func_get_user_var::eq(const Item *item,
1349
bool binary_cmp __attribute__((unused))) const
1351
/* Assume we don't have rtti */
1353
return 1; // Same item is same.
1354
/* Check if other type is also a get_user_var() object */
1355
if (item->type() != FUNC_ITEM ||
1356
((Item_func*) item)->functype() != functype())
1358
Item_func_get_user_var *other=(Item_func_get_user_var*) item;
1359
return (name.length == other->name.length &&
1360
!memcmp(name.str, other->name.str, name.length));
1364
802
bool Item_user_var_as_out_param::fix_fields(Session *session, Item **ref)
1366
804
assert(fixed == 0);