~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item_func.cc

  • Committer: Monty Taylor
  • Date: 2008-10-23 00:05:28 UTC
  • Revision ID: monty@inaugust.com-20081023000528-grdvrd8c4058nutm
Moved my_handler to myisam, which is where it actually belongs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** Copyright (C) 2000-2003 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
 
 
17
/**
 
18
  @file
 
19
 
 
20
  @brief
 
21
  This file defines all numerical functions
 
22
*/
 
23
 
 
24
#include <drizzled/server_includes.h>
 
25
#include "rpl_mi.h"
 
26
#include <mysys/my_bit.h>
 
27
#include <drizzled/drizzled_error_messages.h>
 
28
 
 
29
bool check_reserved_words(LEX_STRING *name)
 
30
{
 
31
  if (!my_strcasecmp(system_charset_info, name->str, "GLOBAL") ||
 
32
      !my_strcasecmp(system_charset_info, name->str, "LOCAL") ||
 
33
      !my_strcasecmp(system_charset_info, name->str, "SESSION"))
 
34
    return true;
 
35
  return false;
 
36
}
 
37
 
 
38
 
 
39
/**
 
40
  @return
 
41
    true if item is a constant
 
42
*/
 
43
 
 
44
bool
 
45
eval_const_cond(COND *cond)
 
46
{
 
47
  return ((Item_func*) cond)->val_int() ? true : false;
 
48
}
 
49
 
 
50
 
 
51
void Item_func::fix_num_length_and_dec()
 
52
{
 
53
  uint32_t fl_length= 0;
 
54
  decimals=0;
 
55
  for (uint32_t i=0 ; i < arg_count ; i++)
 
56
  {
 
57
    set_if_bigger(decimals,args[i]->decimals);
 
58
    set_if_bigger(fl_length, args[i]->max_length);
 
59
  }
 
60
  max_length=float_length(decimals);
 
61
  if (fl_length > max_length)
 
62
  {
 
63
    decimals= NOT_FIXED_DEC;
 
64
    max_length= float_length(NOT_FIXED_DEC);
 
65
  }
 
66
}
 
67
 
 
68
/**
 
69
  Set max_length/decimals of function if function is fixed point and
 
70
  result length/precision depends on argument ones.
 
71
*/
 
72
 
 
73
void Item_func::count_decimal_length()
 
74
{
 
75
  int max_int_part= 0;
 
76
  decimals= 0;
 
77
  unsigned_flag= 1;
 
78
  for (uint32_t i=0 ; i < arg_count ; i++)
 
79
  {
 
80
    set_if_bigger(decimals, args[i]->decimals);
 
81
    set_if_bigger(max_int_part, args[i]->decimal_int_part());
 
82
    set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
 
83
  }
 
84
  int precision= cmin(max_int_part + decimals, DECIMAL_MAX_PRECISION);
 
85
  max_length= my_decimal_precision_to_length(precision, decimals,
 
86
                                             unsigned_flag);
 
87
}
 
88
 
 
89
 
 
90
/**
 
91
  Set max_length of if it is maximum length of its arguments.
 
92
*/
 
93
 
 
94
void Item_func::count_only_length()
 
95
{
 
96
  max_length= 0;
 
97
  unsigned_flag= 0;
 
98
  for (uint32_t i=0 ; i < arg_count ; i++)
 
99
  {
 
100
    set_if_bigger(max_length, args[i]->max_length);
 
101
    set_if_bigger(unsigned_flag, args[i]->unsigned_flag);
 
102
  }
 
103
}
 
104
 
 
105
 
 
106
/**
 
107
  Set max_length/decimals of function if function is floating point and
 
108
  result length/precision depends on argument ones.
 
109
*/
 
110
 
 
111
void Item_func::count_real_length()
 
112
{
 
113
  uint32_t length= 0;
 
114
  decimals= 0;
 
115
  max_length= 0;
 
116
  for (uint32_t i=0 ; i < arg_count ; i++)
 
117
  {
 
118
    if (decimals != NOT_FIXED_DEC)
 
119
    {
 
120
      set_if_bigger(decimals, args[i]->decimals);
 
121
      set_if_bigger(length, (args[i]->max_length - args[i]->decimals));
 
122
    }
 
123
    set_if_bigger(max_length, args[i]->max_length);
 
124
  }
 
125
  if (decimals != NOT_FIXED_DEC)
 
126
  {
 
127
    max_length= length;
 
128
    length+= decimals;
 
129
    if (length < max_length)  // If previous operation gave overflow
 
130
      max_length= UINT32_MAX;
 
131
    else
 
132
      max_length= length;
 
133
  }
 
134
}
 
135
 
 
136
 
 
137
 
 
138
void Item_func::signal_divide_by_null()
 
139
{
 
140
  Session *session= current_session;
 
141
  push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, ER_DIVISION_BY_ZERO, ER(ER_DIVISION_BY_ZERO));
 
142
  null_value= 1;
 
143
}
 
144
 
 
145
 
 
146
Item *Item_func::get_tmp_table_item(Session *session)
 
147
{
 
148
  if (!with_sum_func && !const_item() && functype() != SUSERVAR_FUNC)
 
149
    return new Item_field(result_field);
 
150
  return copy_or_same(session);
 
151
}
 
152
 
 
153
// Shift-functions, same as << and >> in C/C++
 
154
 
 
155
int64_t Item_func_shift_left::val_int()
 
156
{
 
157
  assert(fixed == 1);
 
158
  uint32_t shift;
 
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)
 
162
  {
 
163
    null_value=1;
 
164
    return 0;
 
165
  }
 
166
  null_value=0;
 
167
  return (shift < sizeof(int64_t)*8 ? (int64_t) res : 0L);
 
168
}
 
169
 
 
170
int64_t Item_func_shift_right::val_int()
 
171
{
 
172
  assert(fixed == 1);
 
173
  uint32_t shift;
 
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)
 
177
  {
 
178
    null_value=1;
 
179
    return 0;
 
180
  }
 
181
  null_value=0;
 
182
  return (shift < sizeof(int64_t)*8 ? (int64_t) res : 0);
 
183
}
 
184
 
 
185
 
 
186
int64_t Item_func_bit_neg::val_int()
 
187
{
 
188
  assert(fixed == 1);
 
189
  uint64_t res= (uint64_t) args[0]->val_int();
 
190
  if ((null_value=args[0]->null_value))
 
191
    return 0;
 
192
  return ~res;
 
193
}
 
194
 
 
195
 
 
196
// Conversion functions
 
197
 
 
198
void Item_func_integer::fix_length_and_dec()
 
199
{
 
200
  max_length=args[0]->max_length - args[0]->decimals+1;
 
201
  uint32_t tmp=float_length(decimals);
 
202
  set_if_smaller(max_length,tmp);
 
203
  decimals=0;
 
204
}
 
205
 
 
206
double Item_func_units::val_real()
 
207
{
 
208
  assert(fixed == 1);
 
209
  double value= args[0]->val_real();
 
210
  if ((null_value=args[0]->null_value))
 
211
    return 0;
 
212
  return value*mul+add;
 
213
}
 
214
 
 
215
 
 
216
int64_t Item_func_char_length::val_int()
 
217
{
 
218
  assert(fixed == 1);
 
219
  String *res=args[0]->val_str(&value);
 
220
  if (!res)
 
221
  {
 
222
    null_value=1;
 
223
    return 0; /* purecov: inspected */
 
224
  }
 
225
  null_value=0;
 
226
  return (int64_t) res->numchars();
 
227
}
 
228
 
 
229
 
 
230
int64_t Item_func_coercibility::val_int()
 
231
{
 
232
  assert(fixed == 1);
 
233
  null_value= 0;
 
234
  return (int64_t) args[0]->collation.derivation;
 
235
}
 
236
 
 
237
 
 
238
void Item_func_locate::fix_length_and_dec()
 
239
{
 
240
  max_length= MY_INT32_NUM_DECIMAL_DIGITS;
 
241
  agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV, 1);
 
242
}
 
243
 
 
244
 
 
245
int64_t Item_func_locate::val_int()
 
246
{
 
247
  assert(fixed == 1);
 
248
  String *a=args[0]->val_str(&value1);
 
249
  String *b=args[1]->val_str(&value2);
 
250
  if (!a || !b)
 
251
  {
 
252
    null_value=1;
 
253
    return 0; /* purecov: inspected */
 
254
  }
 
255
  null_value=0;
 
256
  /* must be int64_t to avoid truncation */
 
257
  int64_t start=  0; 
 
258
  int64_t start0= 0;
 
259
  my_match_t match;
 
260
 
 
261
  if (arg_count == 3)
 
262
  {
 
263
    start0= start= args[2]->val_int() - 1;
 
264
 
 
265
    if ((start < 0) || (start > a->length()))
 
266
      return 0;
 
267
 
 
268
    /* start is now sufficiently valid to pass to charpos function */
 
269
    start= a->charpos((int) start);
 
270
 
 
271
    if (start + b->length() > a->length())
 
272
      return 0;
 
273
  }
 
274
 
 
275
  if (!b->length())                             // Found empty string at start
 
276
    return start + 1;
 
277
  
 
278
  if (!cmp_collation.collation->coll->instr(cmp_collation.collation,
 
279
                                            a->ptr()+start,
 
280
                                            (uint) (a->length()-start),
 
281
                                            b->ptr(), b->length(),
 
282
                                            &match, 1))
 
283
    return 0;
 
284
  return (int64_t) match.mb_len + start0 + 1;
 
285
}
 
286
 
 
287
 
 
288
void Item_func_locate::print(String *str, enum_query_type query_type)
 
289
{
 
290
  str->append(STRING_WITH_LEN("locate("));
 
291
  args[1]->print(str, query_type);
 
292
  str->append(',');
 
293
  args[0]->print(str, query_type);
 
294
  if (arg_count == 3)
 
295
  {
 
296
    str->append(',');
 
297
    args[2]->print(str, query_type);
 
298
  }
 
299
  str->append(')');
 
300
}
 
301
 
 
302
 
 
303
int64_t Item_func_field::val_int()
 
304
{
 
305
  assert(fixed == 1);
 
306
 
 
307
  if (cmp_type == STRING_RESULT)
 
308
  {
 
309
    String *field;
 
310
    if (!(field= args[0]->val_str(&value)))
 
311
      return 0;
 
312
    for (uint32_t i=1 ; i < arg_count ; i++)
 
313
    {
 
314
      String *tmp_value=args[i]->val_str(&tmp);
 
315
      if (tmp_value && !sortcmp(field,tmp_value,cmp_collation.collation))
 
316
        return (int64_t) (i);
 
317
    }
 
318
  }
 
319
  else if (cmp_type == INT_RESULT)
 
320
  {
 
321
    int64_t val= args[0]->val_int();
 
322
    if (args[0]->null_value)
 
323
      return 0;
 
324
    for (uint32_t i=1; i < arg_count ; i++)
 
325
    {
 
326
      if (val == args[i]->val_int() && !args[i]->null_value)
 
327
        return (int64_t) (i);
 
328
    }
 
329
  }
 
330
  else if (cmp_type == DECIMAL_RESULT)
 
331
  {
 
332
    my_decimal dec_arg_buf, *dec_arg,
 
333
               dec_buf, *dec= args[0]->val_decimal(&dec_buf);
 
334
    if (args[0]->null_value)
 
335
      return 0;
 
336
    for (uint32_t i=1; i < arg_count; i++)
 
337
    {
 
338
      dec_arg= args[i]->val_decimal(&dec_arg_buf);
 
339
      if (!args[i]->null_value && !my_decimal_cmp(dec_arg, dec))
 
340
        return (int64_t) (i);
 
341
    }
 
342
  }
 
343
  else
 
344
  {
 
345
    double val= args[0]->val_real();
 
346
    if (args[0]->null_value)
 
347
      return 0;
 
348
    for (uint32_t i=1; i < arg_count ; i++)
 
349
    {
 
350
      if (val == args[i]->val_real() && !args[i]->null_value)
 
351
        return (int64_t) (i);
 
352
    }
 
353
  }
 
354
  return 0;
 
355
}
 
356
 
 
357
 
 
358
void Item_func_field::fix_length_and_dec()
 
359
{
 
360
  maybe_null=0; max_length=3;
 
361
  cmp_type= args[0]->result_type();
 
362
  for (uint32_t i=1; i < arg_count ; i++)
 
363
    cmp_type= item_cmp_type(cmp_type, args[i]->result_type());
 
364
  if (cmp_type == STRING_RESULT)
 
365
    agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1);
 
366
}
 
367
 
 
368
 
 
369
int64_t Item_func_ascii::val_int()
 
370
{
 
371
  assert(fixed == 1);
 
372
  String *res=args[0]->val_str(&value);
 
373
  if (!res)
 
374
  {
 
375
    null_value=1;
 
376
    return 0;
 
377
  }
 
378
  null_value=0;
 
379
  return (int64_t) (res->length() ? (unsigned char) (*res)[0] : (unsigned char) 0);
 
380
}
 
381
 
 
382
int64_t Item_func_ord::val_int()
 
383
{
 
384
  assert(fixed == 1);
 
385
  String *res=args[0]->val_str(&value);
 
386
  if (!res)
 
387
  {
 
388
    null_value=1;
 
389
    return 0;
 
390
  }
 
391
  null_value=0;
 
392
  if (!res->length()) return 0;
 
393
#ifdef USE_MB
 
394
  if (use_mb(res->charset()))
 
395
  {
 
396
    register const char *str=res->ptr();
 
397
    register uint32_t n=0, l=my_ismbchar(res->charset(),str,str+res->length());
 
398
    if (!l)
 
399
      return (int64_t)((unsigned char) *str);
 
400
    while (l--)
 
401
      n=(n<<8)|(uint32_t)((unsigned char) *str++);
 
402
    return (int64_t) n;
 
403
  }
 
404
#endif
 
405
  return (int64_t) ((unsigned char) (*res)[0]);
 
406
}
 
407
 
 
408
        /* Search after a string in a string of strings separated by ',' */
 
409
        /* Returns number of found type >= 1 or 0 if not found */
 
410
        /* This optimizes searching in enums to bit testing! */
 
411
 
 
412
void Item_func_find_in_set::fix_length_and_dec()
 
413
{
 
414
  decimals=0;
 
415
  max_length=3;                                 // 1-999
 
416
  agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV, 1);
 
417
}
 
418
 
 
419
static const char separator=',';
 
420
 
 
421
int64_t Item_func_find_in_set::val_int()
 
422
{
 
423
  assert(fixed == 1);
 
424
  if (enum_value)
 
425
  {
 
426
    uint64_t tmp=(uint64_t) args[1]->val_int();
 
427
    if (!(null_value=args[1]->null_value || args[0]->null_value))
 
428
    {
 
429
      if (tmp & enum_bit)
 
430
        return enum_value;
 
431
    }
 
432
    return 0L;
 
433
  }
 
434
 
 
435
  String *find=args[0]->val_str(&value);
 
436
  String *buffer=args[1]->val_str(&value2);
 
437
  if (!find || !buffer)
 
438
  {
 
439
    null_value=1;
 
440
    return 0; /* purecov: inspected */
 
441
  }
 
442
  null_value=0;
 
443
 
 
444
  int diff;
 
445
  if ((diff=buffer->length() - find->length()) >= 0)
 
446
  {
 
447
    my_wc_t wc;
 
448
    const CHARSET_INFO * const cs= cmp_collation.collation;
 
449
    const char *str_begin= buffer->ptr();
 
450
    const char *str_end= buffer->ptr();
 
451
    const char *real_end= str_end+buffer->length();
 
452
    const unsigned char *find_str= (const unsigned char *) find->ptr();
 
453
    uint32_t find_str_len= find->length();
 
454
    int position= 0;
 
455
    while (1)
 
456
    {
 
457
      int symbol_len;
 
458
      if ((symbol_len= cs->cset->mb_wc(cs, &wc, (unsigned char*) str_end, 
 
459
                                       (unsigned char*) real_end)) > 0)
 
460
      {
 
461
        const char *substr_end= str_end + symbol_len;
 
462
        bool is_last_item= (substr_end == real_end);
 
463
        bool is_separator= (wc == (my_wc_t) separator);
 
464
        if (is_separator || is_last_item)
 
465
        {
 
466
          position++;
 
467
          if (is_last_item && !is_separator)
 
468
            str_end= substr_end;
 
469
          if (!my_strnncoll(cs, (const unsigned char *) str_begin,
 
470
                            str_end - str_begin,
 
471
                            find_str, find_str_len))
 
472
            return (int64_t) position;
 
473
          else
 
474
            str_begin= substr_end;
 
475
        }
 
476
        str_end= substr_end;
 
477
      }
 
478
      else if (str_end - str_begin == 0 &&
 
479
               find_str_len == 0 &&
 
480
               wc == (my_wc_t) separator)
 
481
        return (int64_t) ++position;
 
482
      else
 
483
        return 0L;
 
484
    }
 
485
  }
 
486
  return 0;
 
487
}
 
488
 
 
489
int64_t Item_func_bit_count::val_int()
 
490
{
 
491
  assert(fixed == 1);
 
492
  uint64_t value= (uint64_t) args[0]->val_int();
 
493
  if ((null_value= args[0]->null_value))
 
494
    return 0; /* purecov: inspected */
 
495
  return (int64_t) my_count_bits(value);
 
496
}
 
497
 
 
498
/*
 
499
** User level locks
 
500
*/
 
501
 
 
502
pthread_mutex_t LOCK_user_locks;
 
503
static HASH hash_user_locks;
 
504
 
 
505
class User_level_lock
 
506
{
 
507
  unsigned char *key;
 
508
  size_t key_length;
 
509
 
 
510
public:
 
511
  int count;
 
512
  bool locked;
 
513
  pthread_cond_t cond;
 
514
  my_thread_id thread_id;
 
515
  void set_thread(Session *session) { thread_id= session->thread_id; }
 
516
 
 
517
  User_level_lock(const unsigned char *key_arg,uint32_t length, ulong id) 
 
518
    :key_length(length),count(1),locked(1), thread_id(id)
 
519
  {
 
520
    key= (unsigned char*) my_memdup(key_arg,length,MYF(0));
 
521
    pthread_cond_init(&cond,NULL);
 
522
    if (key)
 
523
    {
 
524
      if (my_hash_insert(&hash_user_locks,(unsigned char*) this))
 
525
      {
 
526
        free(key);
 
527
        key=0;
 
528
      }
 
529
    }
 
530
  }
 
531
  ~User_level_lock()
 
532
  {
 
533
    if (key)
 
534
    {
 
535
      hash_delete(&hash_user_locks,(unsigned char*) this);
 
536
      free(key);
 
537
    }
 
538
    pthread_cond_destroy(&cond);
 
539
  }
 
540
  inline bool initialized() { return key != 0; }
 
541
  friend void item_user_lock_release(User_level_lock *ull);
 
542
  friend unsigned char *ull_get_key(const User_level_lock *ull, size_t *length,
 
543
                            bool not_used);
 
544
};
 
545
 
 
546
unsigned char *ull_get_key(const User_level_lock *ull, size_t *length,
 
547
                   bool not_used __attribute__((unused)))
 
548
{
 
549
  *length= ull->key_length;
 
550
  return ull->key;
 
551
}
 
552
 
 
553
 
 
554
static bool item_user_lock_inited= 0;
 
555
 
 
556
void item_user_lock_init(void)
 
557
{
 
558
  pthread_mutex_init(&LOCK_user_locks,MY_MUTEX_INIT_SLOW);
 
559
  hash_init(&hash_user_locks, system_charset_info,
 
560
            16,0,0,(hash_get_key) ull_get_key,NULL,0);
 
561
  item_user_lock_inited= 1;
 
562
}
 
563
 
 
564
void item_user_lock_free(void)
 
565
{
 
566
  if (item_user_lock_inited)
 
567
  {
 
568
    item_user_lock_inited= 0;
 
569
    hash_free(&hash_user_locks);
 
570
    pthread_mutex_destroy(&LOCK_user_locks);
 
571
  }
 
572
}
 
573
 
 
574
void item_user_lock_release(User_level_lock *ull)
 
575
{
 
576
  ull->locked=0;
 
577
  ull->thread_id= 0;
 
578
  if (--ull->count)
 
579
    pthread_cond_signal(&ull->cond);
 
580
  else
 
581
    delete ull;
 
582
}
 
583
 
 
584
/**
 
585
  Wait until we are at or past the given position in the master binlog
 
586
  on the slave.
 
587
*/
 
588
 
 
589
int64_t Item_master_pos_wait::val_int()
 
590
{
 
591
  assert(fixed == 1);
 
592
  Session* session = current_session;
 
593
  String *log_name = args[0]->val_str(&value);
 
594
  int event_count= 0;
 
595
 
 
596
  null_value=0;
 
597
  if (session->slave_thread || !log_name || !log_name->length())
 
598
  {
 
599
    null_value = 1;
 
600
    return 0;
 
601
  }
 
602
  int64_t pos = (ulong)args[1]->val_int();
 
603
  int64_t timeout = (arg_count==3) ? args[2]->val_int() : 0 ;
 
604
  if ((event_count = active_mi->rli.wait_for_pos(session, log_name, pos, timeout)) == -2)
 
605
  {
 
606
    null_value = 1;
 
607
    event_count=0;
 
608
  }
 
609
  return event_count;
 
610
}
 
611
 
 
612
#ifdef EXTRA_DEBUG
 
613
void debug_sync_point(const char* lock_name, uint32_t lock_timeout)
 
614
{
 
615
}
 
616
 
 
617
#endif
 
618
 
 
619
 
 
620
int64_t Item_func_last_insert_id::val_int()
 
621
{
 
622
  Session *session= current_session;
 
623
  assert(fixed == 1);
 
624
  if (arg_count)
 
625
  {
 
626
    int64_t value= args[0]->val_int();
 
627
    null_value= args[0]->null_value;
 
628
    /*
 
629
      LAST_INSERT_ID(X) must affect the client's mysql_insert_id() as
 
630
      documented in the manual. We don't want to touch
 
631
      first_successful_insert_id_in_cur_stmt because it would make
 
632
      LAST_INSERT_ID(X) take precedence over an generated auto_increment
 
633
      value for this row.
 
634
    */
 
635
    session->arg_of_last_insert_id_function= true;
 
636
    session->first_successful_insert_id_in_prev_stmt= value;
 
637
    return value;
 
638
  }
 
639
  return session->read_first_successful_insert_id_in_prev_stmt();
 
640
}
 
641
 
 
642
 
 
643
bool Item_func_last_insert_id::fix_fields(Session *session, Item **ref)
 
644
{
 
645
  return Item_int_func::fix_fields(session, ref);
 
646
}
 
647
 
 
648
 
 
649
/* This function is just used to test speed of different functions */
 
650
 
 
651
int64_t Item_func_benchmark::val_int()
 
652
{
 
653
  assert(fixed == 1);
 
654
  char buff[MAX_FIELD_WIDTH];
 
655
  String tmp(buff,sizeof(buff), &my_charset_bin);
 
656
  my_decimal tmp_decimal;
 
657
  Session *session=current_session;
 
658
  uint64_t loop_count;
 
659
 
 
660
  loop_count= (uint64_t) args[0]->val_int();
 
661
 
 
662
  if (args[0]->null_value ||
 
663
      (!args[0]->unsigned_flag && (((int64_t) loop_count) < 0)))
 
664
  {
 
665
    if (!args[0]->null_value)
 
666
    {
 
667
      char buff[22];
 
668
      llstr(((int64_t) loop_count), buff);
 
669
      push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
670
                          ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
 
671
                          "count", buff, "benchmark");
 
672
    }
 
673
 
 
674
    null_value= 1;
 
675
    return 0;
 
676
  }
 
677
 
 
678
  null_value=0;
 
679
  for (uint64_t loop=0 ; loop < loop_count && !session->killed; loop++)
 
680
  {
 
681
    switch (args[1]->result_type()) {
 
682
    case REAL_RESULT:
 
683
      (void) args[1]->val_real();
 
684
      break;
 
685
    case INT_RESULT:
 
686
      (void) args[1]->val_int();
 
687
      break;
 
688
    case STRING_RESULT:
 
689
      (void) args[1]->val_str(&tmp);
 
690
      break;
 
691
    case DECIMAL_RESULT:
 
692
      (void) args[1]->val_decimal(&tmp_decimal);
 
693
      break;
 
694
    case ROW_RESULT:
 
695
    default:
 
696
      // This case should never be chosen
 
697
      assert(0);
 
698
      return 0;
 
699
    }
 
700
  }
 
701
  return 0;
 
702
}
 
703
 
 
704
 
 
705
void Item_func_benchmark::print(String *str, enum_query_type query_type)
 
706
{
 
707
  str->append(STRING_WITH_LEN("benchmark("));
 
708
  args[0]->print(str, query_type);
 
709
  str->append(',');
 
710
  args[1]->print(str, query_type);
 
711
  str->append(')');
 
712
}
 
713
 
 
714
#define extra_size sizeof(double)
 
715
 
 
716
static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
 
717
                                    bool create_if_not_exists)
 
718
{
 
719
  user_var_entry *entry;
 
720
 
 
721
  if (!(entry = (user_var_entry*) hash_search(hash, (unsigned char*) name.str,
 
722
                                              name.length)) &&
 
723
      create_if_not_exists)
 
724
  {
 
725
    uint32_t size=ALIGN_SIZE(sizeof(user_var_entry))+name.length+1+extra_size;
 
726
    if (!hash_inited(hash))
 
727
      return 0;
 
728
    if (!(entry = (user_var_entry*) my_malloc(size,MYF(MY_WME | ME_FATALERROR))))
 
729
      return 0;
 
730
    entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+
 
731
      extra_size;
 
732
    entry->name.length=name.length;
 
733
    entry->value=0;
 
734
    entry->length=0;
 
735
    entry->update_query_id=0;
 
736
    entry->collation.set(NULL, DERIVATION_IMPLICIT, 0);
 
737
    entry->unsigned_flag= 0;
 
738
    /*
 
739
      If we are here, we were called from a SET or a query which sets a
 
740
      variable. Imagine it is this:
 
741
      INSERT INTO t SELECT @a:=10, @a:=@a+1.
 
742
      Then when we have a Item_func_get_user_var (because of the @a+1) so we
 
743
      think we have to write the value of @a to the binlog. But before that,
 
744
      we have a Item_func_set_user_var to create @a (@a:=10), in this we mark
 
745
      the variable as "already logged" (line below) so that it won't be logged
 
746
      by Item_func_get_user_var (because that's not necessary).
 
747
    */
 
748
    entry->used_query_id=current_session->query_id;
 
749
    entry->type=STRING_RESULT;
 
750
    memcpy(entry->name.str, name.str, name.length+1);
 
751
    if (my_hash_insert(hash,(unsigned char*) entry))
 
752
    {
 
753
      free((char*) entry);
 
754
      return 0;
 
755
    }
 
756
  }
 
757
  return entry;
 
758
}
 
759
 
 
760
/*
 
761
  When a user variable is updated (in a SET command or a query like
 
762
  SELECT @a:= ).
 
763
*/
 
764
 
 
765
bool Item_func_set_user_var::fix_fields(Session *session, Item **ref)
 
766
{
 
767
  assert(fixed == 0);
 
768
  /* fix_fields will call Item_func_set_user_var::fix_length_and_dec */
 
769
  if (Item_func::fix_fields(session, ref) ||
 
770
      !(entry= get_variable(&session->user_vars, name, 1)))
 
771
    return true;
 
772
  /* 
 
773
     Remember the last query which updated it, this way a query can later know
 
774
     if this variable is a constant item in the query (it is if update_query_id
 
775
     is different from query_id).
 
776
  */
 
777
  entry->update_query_id= session->query_id;
 
778
  /*
 
779
    As it is wrong and confusing to associate any 
 
780
    character set with NULL, @a should be latin2
 
781
    after this query sequence:
 
782
 
 
783
      SET @a=_latin2'string';
 
784
      SET @a=NULL;
 
785
 
 
786
    I.e. the second query should not change the charset
 
787
    to the current default value, but should keep the 
 
788
    original value assigned during the first query.
 
789
    In order to do it, we don't copy charset
 
790
    from the argument if the argument is NULL
 
791
    and the variable has previously been initialized.
 
792
  */
 
793
  null_item= (args[0]->type() == NULL_ITEM);
 
794
  if (!entry->collation.collation || !null_item)
 
795
    entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
 
796
  collation.set(entry->collation.collation, DERIVATION_IMPLICIT);
 
797
  cached_result_type= args[0]->result_type();
 
798
  return false;
 
799
}
 
800
 
 
801
 
 
802
void
 
803
Item_func_set_user_var::fix_length_and_dec()
 
804
{
 
805
  maybe_null=args[0]->maybe_null;
 
806
  max_length=args[0]->max_length;
 
807
  decimals=args[0]->decimals;
 
808
  collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
 
809
}
 
810
 
 
811
 
 
812
/*
 
813
  Mark field in read_map
 
814
 
 
815
  NOTES
 
816
    This is used by filesort to register used fields in a a temporary
 
817
    column read set or to register used fields in a view
 
818
*/
 
819
 
 
820
bool Item_func_set_user_var::register_field_in_read_map(unsigned char *arg)
 
821
{
 
822
  if (result_field)
 
823
  {
 
824
    Table *table= (Table *) arg;
 
825
    if (result_field->table == table || !table)
 
826
      bitmap_set_bit(result_field->table->read_set, result_field->field_index);
 
827
    if (result_field->vcol_info && result_field->vcol_info->expr_item)
 
828
      return result_field->vcol_info->
 
829
               expr_item->walk(&Item::register_field_in_read_map, 1, arg);
 
830
  }
 
831
  return 0;
 
832
}
 
833
 
 
834
 
 
835
/*
 
836
  Mark field in bitmap supplied as *arg
 
837
 
 
838
*/
 
839
 
 
840
bool Item_func_set_user_var::register_field_in_bitmap(unsigned char *arg)
 
841
{
 
842
  MY_BITMAP *bitmap = (MY_BITMAP *) arg;
 
843
  assert(bitmap);
 
844
  if (result_field)
 
845
  {
 
846
    bitmap_set_bit(bitmap, result_field->field_index);
 
847
  }
 
848
  return 0;
 
849
}
 
850
 
 
851
 
 
852
/**
 
853
  Set value to user variable.
 
854
 
 
855
  @param entry          pointer to structure representing variable
 
856
  @param set_null       should we set NULL value ?
 
857
  @param ptr            pointer to buffer with new value
 
858
  @param length         length of new value
 
859
  @param type           type of new value
 
860
  @param cs             charset info for new value
 
861
  @param dv             derivation for new value
 
862
  @param unsigned_arg   indiates if a value of type INT_RESULT is unsigned
 
863
 
 
864
  @note Sets error and fatal error if allocation fails.
 
865
 
 
866
  @retval
 
867
    false   success
 
868
  @retval
 
869
    true    failure
 
870
*/
 
871
 
 
872
static bool
 
873
update_hash(user_var_entry *entry, bool set_null, void *ptr, uint32_t length,
 
874
            Item_result type, const CHARSET_INFO * const cs, Derivation dv,
 
875
            bool unsigned_arg)
 
876
{
 
877
  if (set_null)
 
878
  {
 
879
    char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
 
880
    if (entry->value && entry->value != pos)
 
881
      free(entry->value);
 
882
    entry->value= 0;
 
883
    entry->length= 0;
 
884
  }
 
885
  else
 
886
  {
 
887
    if (type == STRING_RESULT)
 
888
      length++;                                 // Store strings with end \0
 
889
    if (length <= extra_size)
 
890
    {
 
891
      /* Save value in value struct */
 
892
      char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
 
893
      if (entry->value != pos)
 
894
      {
 
895
        if (entry->value)
 
896
          free(entry->value);
 
897
        entry->value=pos;
 
898
      }
 
899
    }
 
900
    else
 
901
    {
 
902
      /* Allocate variable */
 
903
      if (entry->length != length)
 
904
      {
 
905
        char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
 
906
        if (entry->value == pos)
 
907
          entry->value=0;
 
908
        entry->value= (char*) my_realloc(entry->value, length,
 
909
                                         MYF(MY_ALLOW_ZERO_PTR | MY_WME |
 
910
                                             ME_FATALERROR));
 
911
        if (!entry->value)
 
912
          return 1;
 
913
      }
 
914
    }
 
915
    if (type == STRING_RESULT)
 
916
    {
 
917
      length--;                                 // Fix length change above
 
918
      entry->value[length]= 0;                  // Store end \0
 
919
    }
 
920
    memcpy(entry->value,ptr,length);
 
921
    if (type == DECIMAL_RESULT)
 
922
      ((my_decimal*)entry->value)->fix_buffer_pointer();
 
923
    entry->length= length;
 
924
    entry->collation.set(cs, dv);
 
925
    entry->unsigned_flag= unsigned_arg;
 
926
  }
 
927
  entry->type=type;
 
928
  return 0;
 
929
}
 
930
 
 
931
 
 
932
bool
 
933
Item_func_set_user_var::update_hash(void *ptr, uint32_t length,
 
934
                                    Item_result res_type,
 
935
                                    const CHARSET_INFO * const cs, Derivation dv,
 
936
                                    bool unsigned_arg)
 
937
{
 
938
  /*
 
939
    If we set a variable explicitely to NULL then keep the old
 
940
    result type of the variable
 
941
  */
 
942
  if ((null_value= args[0]->null_value) && null_item)
 
943
    res_type= entry->type;                      // Don't change type of item
 
944
  if (::update_hash(entry, (null_value= args[0]->null_value),
 
945
                    ptr, length, res_type, cs, dv, unsigned_arg))
 
946
  {
 
947
    null_value= 1;
 
948
    return 1;
 
949
  }
 
950
  return 0;
 
951
}
 
952
 
 
953
 
 
954
/** Get the value of a variable as a double. */
 
955
 
 
956
double user_var_entry::val_real(bool *null_value)
 
957
{
 
958
  if ((*null_value= (value == 0)))
 
959
    return 0.0;
 
960
 
 
961
  switch (type) {
 
962
  case REAL_RESULT:
 
963
    return *(double*) value;
 
964
  case INT_RESULT:
 
965
    return (double) *(int64_t*) value;
 
966
  case DECIMAL_RESULT:
 
967
  {
 
968
    double result;
 
969
    my_decimal2double(E_DEC_FATAL_ERROR, (my_decimal *)value, &result);
 
970
    return result;
 
971
  }
 
972
  case STRING_RESULT:
 
973
    return my_atof(value);                      // This is null terminated
 
974
  case ROW_RESULT:
 
975
    assert(1);                          // Impossible
 
976
    break;
 
977
  }
 
978
  return 0.0;                                   // Impossible
 
979
}
 
980
 
 
981
 
 
982
/** Get the value of a variable as an integer. */
 
983
 
 
984
int64_t user_var_entry::val_int(bool *null_value) const
 
985
{
 
986
  if ((*null_value= (value == 0)))
 
987
    return 0L;
 
988
 
 
989
  switch (type) {
 
990
  case REAL_RESULT:
 
991
    return (int64_t) *(double*) value;
 
992
  case INT_RESULT:
 
993
    return *(int64_t*) value;
 
994
  case DECIMAL_RESULT:
 
995
  {
 
996
    int64_t result;
 
997
    my_decimal2int(E_DEC_FATAL_ERROR, (my_decimal *)value, 0, &result);
 
998
    return result;
 
999
  }
 
1000
  case STRING_RESULT:
 
1001
  {
 
1002
    int error;
 
1003
    return my_strtoll10(value, (char**) 0, &error);// String is null terminated
 
1004
  }
 
1005
  case ROW_RESULT:
 
1006
    assert(1);                          // Impossible
 
1007
    break;
 
1008
  }
 
1009
  return 0L;                                    // Impossible
 
1010
}
 
1011
 
 
1012
 
 
1013
/** Get the value of a variable as a string. */
 
1014
 
 
1015
String *user_var_entry::val_str(bool *null_value, String *str,
 
1016
                                uint32_t decimals)
 
1017
{
 
1018
  if ((*null_value= (value == 0)))
 
1019
    return (String*) 0;
 
1020
 
 
1021
  switch (type) {
 
1022
  case REAL_RESULT:
 
1023
    str->set_real(*(double*) value, decimals, &my_charset_bin);
 
1024
    break;
 
1025
  case INT_RESULT:
 
1026
    if (!unsigned_flag)
 
1027
      str->set(*(int64_t*) value, &my_charset_bin);
 
1028
    else
 
1029
      str->set(*(uint64_t*) value, &my_charset_bin);
 
1030
    break;
 
1031
  case DECIMAL_RESULT:
 
1032
    my_decimal2string(E_DEC_FATAL_ERROR, (my_decimal *)value, 0, 0, 0, str);
 
1033
    break;
 
1034
  case STRING_RESULT:
 
1035
    if (str->copy(value, length, collation.collation))
 
1036
      str= 0;                                   // EOM error
 
1037
  case ROW_RESULT:
 
1038
    assert(1);                          // Impossible
 
1039
    break;
 
1040
  }
 
1041
  return(str);
 
1042
}
 
1043
 
 
1044
/** Get the value of a variable as a decimal. */
 
1045
 
 
1046
my_decimal *user_var_entry::val_decimal(bool *null_value, my_decimal *val)
 
1047
{
 
1048
  if ((*null_value= (value == 0)))
 
1049
    return 0;
 
1050
 
 
1051
  switch (type) {
 
1052
  case REAL_RESULT:
 
1053
    double2my_decimal(E_DEC_FATAL_ERROR, *(double*) value, val);
 
1054
    break;
 
1055
  case INT_RESULT:
 
1056
    int2my_decimal(E_DEC_FATAL_ERROR, *(int64_t*) value, 0, val);
 
1057
    break;
 
1058
  case DECIMAL_RESULT:
 
1059
    val= (my_decimal *)value;
 
1060
    break;
 
1061
  case STRING_RESULT:
 
1062
    str2my_decimal(E_DEC_FATAL_ERROR, value, length, collation.collation, val);
 
1063
    break;
 
1064
  case ROW_RESULT:
 
1065
    assert(1);                          // Impossible
 
1066
    break;
 
1067
  }
 
1068
  return(val);
 
1069
}
 
1070
 
 
1071
/**
 
1072
  This functions is invoked on SET \@variable or
 
1073
  \@variable:= expression.
 
1074
 
 
1075
  Evaluate (and check expression), store results.
 
1076
 
 
1077
  @note
 
1078
    For now it always return OK. All problem with value evaluating
 
1079
    will be caught by session->is_error() check in sql_set_variables().
 
1080
 
 
1081
  @retval
 
1082
    false OK.
 
1083
*/
 
1084
 
 
1085
bool
 
1086
Item_func_set_user_var::check(bool use_result_field)
 
1087
{
 
1088
  if (use_result_field && !result_field)
 
1089
    use_result_field= false;
 
1090
 
 
1091
  switch (cached_result_type) {
 
1092
  case REAL_RESULT:
 
1093
  {
 
1094
    save_result.vreal= use_result_field ? result_field->val_real() :
 
1095
                        args[0]->val_real();
 
1096
    break;
 
1097
  }
 
1098
  case INT_RESULT:
 
1099
  {
 
1100
    save_result.vint= use_result_field ? result_field->val_int() :
 
1101
                       args[0]->val_int();
 
1102
    unsigned_flag= use_result_field ? ((Field_num*)result_field)->unsigned_flag:
 
1103
                    args[0]->unsigned_flag;
 
1104
    break;
 
1105
  }
 
1106
  case STRING_RESULT:
 
1107
  {
 
1108
    save_result.vstr= use_result_field ? result_field->val_str(&value) :
 
1109
                       args[0]->val_str(&value);
 
1110
    break;
 
1111
  }
 
1112
  case DECIMAL_RESULT:
 
1113
  {
 
1114
    save_result.vdec= use_result_field ?
 
1115
                       result_field->val_decimal(&decimal_buff) :
 
1116
                       args[0]->val_decimal(&decimal_buff);
 
1117
    break;
 
1118
  }
 
1119
  case ROW_RESULT:
 
1120
  default:
 
1121
    // This case should never be chosen
 
1122
    assert(0);
 
1123
    break;
 
1124
  }
 
1125
  return(false);
 
1126
}
 
1127
 
 
1128
 
 
1129
/**
 
1130
  This functions is invoked on
 
1131
  SET \@variable or \@variable:= expression.
 
1132
 
 
1133
  @note
 
1134
    We have to store the expression as such in the variable, independent of
 
1135
    the value method used by the user
 
1136
 
 
1137
  @retval
 
1138
    0   OK
 
1139
  @retval
 
1140
    1   EOM Error
 
1141
 
 
1142
*/
 
1143
 
 
1144
bool
 
1145
Item_func_set_user_var::update()
 
1146
{
 
1147
  bool res= false;
 
1148
 
 
1149
  switch (cached_result_type) {
 
1150
  case REAL_RESULT:
 
1151
  {
 
1152
    res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal),
 
1153
                     REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
 
1154
    break;
 
1155
  }
 
1156
  case INT_RESULT:
 
1157
  {
 
1158
    res= update_hash((void*) &save_result.vint, sizeof(save_result.vint),
 
1159
                     INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT,
 
1160
                     unsigned_flag);
 
1161
    break;
 
1162
  }
 
1163
  case STRING_RESULT:
 
1164
  {
 
1165
    if (!save_result.vstr)                                      // Null value
 
1166
      res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin,
 
1167
                       DERIVATION_IMPLICIT, 0);
 
1168
    else
 
1169
      res= update_hash((void*) save_result.vstr->ptr(),
 
1170
                       save_result.vstr->length(), STRING_RESULT,
 
1171
                       save_result.vstr->charset(),
 
1172
                       DERIVATION_IMPLICIT, 0);
 
1173
    break;
 
1174
  }
 
1175
  case DECIMAL_RESULT:
 
1176
  {
 
1177
    if (!save_result.vdec)                                      // Null value
 
1178
      res= update_hash((void*) 0, 0, DECIMAL_RESULT, &my_charset_bin,
 
1179
                       DERIVATION_IMPLICIT, 0);
 
1180
    else
 
1181
      res= update_hash((void*) save_result.vdec,
 
1182
                       sizeof(my_decimal), DECIMAL_RESULT,
 
1183
                       &my_charset_bin, DERIVATION_IMPLICIT, 0);
 
1184
    break;
 
1185
  }
 
1186
  case ROW_RESULT:
 
1187
  default:
 
1188
    // This case should never be chosen
 
1189
    assert(0);
 
1190
    break;
 
1191
  }
 
1192
  return(res);
 
1193
}
 
1194
 
 
1195
 
 
1196
double Item_func_set_user_var::val_real()
 
1197
{
 
1198
  assert(fixed == 1);
 
1199
  check(0);
 
1200
  update();                                     // Store expression
 
1201
  return entry->val_real(&null_value);
 
1202
}
 
1203
 
 
1204
int64_t Item_func_set_user_var::val_int()
 
1205
{
 
1206
  assert(fixed == 1);
 
1207
  check(0);
 
1208
  update();                                     // Store expression
 
1209
  return entry->val_int(&null_value);
 
1210
}
 
1211
 
 
1212
String *Item_func_set_user_var::val_str(String *str)
 
1213
{
 
1214
  assert(fixed == 1);
 
1215
  check(0);
 
1216
  update();                                     // Store expression
 
1217
  return entry->val_str(&null_value, str, decimals);
 
1218
}
 
1219
 
 
1220
 
 
1221
my_decimal *Item_func_set_user_var::val_decimal(my_decimal *val)
 
1222
{
 
1223
  assert(fixed == 1);
 
1224
  check(0);
 
1225
  update();                                     // Store expression
 
1226
  return entry->val_decimal(&null_value, val);
 
1227
}
 
1228
 
 
1229
 
 
1230
double Item_func_set_user_var::val_result()
 
1231
{
 
1232
  assert(fixed == 1);
 
1233
  check(true);
 
1234
  update();                                     // Store expression
 
1235
  return entry->val_real(&null_value);
 
1236
}
 
1237
 
 
1238
int64_t Item_func_set_user_var::val_int_result()
 
1239
{
 
1240
  assert(fixed == 1);
 
1241
  check(true);
 
1242
  update();                                     // Store expression
 
1243
  return entry->val_int(&null_value);
 
1244
}
 
1245
 
 
1246
String *Item_func_set_user_var::str_result(String *str)
 
1247
{
 
1248
  assert(fixed == 1);
 
1249
  check(true);
 
1250
  update();                                     // Store expression
 
1251
  return entry->val_str(&null_value, str, decimals);
 
1252
}
 
1253
 
 
1254
 
 
1255
my_decimal *Item_func_set_user_var::val_decimal_result(my_decimal *val)
 
1256
{
 
1257
  assert(fixed == 1);
 
1258
  check(true);
 
1259
  update();                                     // Store expression
 
1260
  return entry->val_decimal(&null_value, val);
 
1261
}
 
1262
 
 
1263
 
 
1264
void Item_func_set_user_var::print(String *str, enum_query_type query_type)
 
1265
{
 
1266
  str->append(STRING_WITH_LEN("(@"));
 
1267
  str->append(name.str, name.length);
 
1268
  str->append(STRING_WITH_LEN(":="));
 
1269
  args[0]->print(str, query_type);
 
1270
  str->append(')');
 
1271
}
 
1272
 
 
1273
 
 
1274
void Item_func_set_user_var::print_as_stmt(String *str,
 
1275
                                           enum_query_type query_type)
 
1276
{
 
1277
  str->append(STRING_WITH_LEN("set @"));
 
1278
  str->append(name.str, name.length);
 
1279
  str->append(STRING_WITH_LEN(":="));
 
1280
  args[0]->print(str, query_type);
 
1281
  str->append(')');
 
1282
}
 
1283
 
 
1284
bool Item_func_set_user_var::send(Protocol *protocol, String *str_arg)
 
1285
{
 
1286
  if (result_field)
 
1287
  {
 
1288
    check(1);
 
1289
    update();
 
1290
    return protocol->store(result_field);
 
1291
  }
 
1292
  return Item::send(protocol, str_arg);
 
1293
}
 
1294
 
 
1295
void Item_func_set_user_var::make_field(Send_field *tmp_field)
 
1296
{
 
1297
  if (result_field)
 
1298
  {
 
1299
    result_field->make_field(tmp_field);
 
1300
    assert(tmp_field->table_name != 0);
 
1301
    if (Item::name)
 
1302
      tmp_field->col_name=Item::name;               // Use user supplied name
 
1303
  }
 
1304
  else
 
1305
    Item::make_field(tmp_field);
 
1306
}
 
1307
 
 
1308
 
 
1309
/*
 
1310
  Save the value of a user variable into a field
 
1311
 
 
1312
  SYNOPSIS
 
1313
    save_in_field()
 
1314
      field           target field to save the value to
 
1315
      no_conversion   flag indicating whether conversions are allowed
 
1316
 
 
1317
  DESCRIPTION
 
1318
    Save the function value into a field and update the user variable
 
1319
    accordingly. If a result field is defined and the target field doesn't
 
1320
    coincide with it then the value from the result field will be used as
 
1321
    the new value of the user variable.
 
1322
 
 
1323
    The reason to have this method rather than simply using the result
 
1324
    field in the val_xxx() methods is that the value from the result field
 
1325
    not always can be used when the result field is defined.
 
1326
    Let's consider the following cases:
 
1327
    1) when filling a tmp table the result field is defined but the value of it
 
1328
    is undefined because it has to be produced yet. Thus we can't use it.
 
1329
    2) on execution of an INSERT ... SELECT statement the save_in_field()
 
1330
    function will be called to fill the data in the new record. If the SELECT
 
1331
    part uses a tmp table then the result field is defined and should be
 
1332
    used in order to get the correct result.
 
1333
 
 
1334
    The difference between the SET_USER_VAR function and regular functions
 
1335
    like CONCAT is that the Item_func objects for the regular functions are
 
1336
    replaced by Item_field objects after the values of these functions have
 
1337
    been stored in a tmp table. Yet an object of the Item_field class cannot
 
1338
    be used to update a user variable.
 
1339
    Due to this we have to handle the result field in a special way here and
 
1340
    in the Item_func_set_user_var::send() function.
 
1341
 
 
1342
  RETURN VALUES
 
1343
    false       Ok
 
1344
    true        Error
 
1345
*/
 
1346
 
 
1347
int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions,
 
1348
                                          bool can_use_result_field)
 
1349
{
 
1350
  bool use_result_field= (!can_use_result_field ? 0 :
 
1351
                          (result_field && result_field != field));
 
1352
  int error;
 
1353
 
 
1354
  /* Update the value of the user variable */
 
1355
  check(use_result_field);
 
1356
  update();
 
1357
 
 
1358
  if (result_type() == STRING_RESULT ||
 
1359
      (result_type() == REAL_RESULT && field->result_type() == STRING_RESULT))
 
1360
  {
 
1361
    String *result;
 
1362
    const CHARSET_INFO * const cs= collation.collation;
 
1363
    char buff[MAX_FIELD_WIDTH];         // Alloc buffer for small columns
 
1364
    str_value.set_quick(buff, sizeof(buff), cs);
 
1365
    result= entry->val_str(&null_value, &str_value, decimals);
 
1366
 
 
1367
    if (null_value)
 
1368
    {
 
1369
      str_value.set_quick(0, 0, cs);
 
1370
      return set_field_to_null_with_conversions(field, no_conversions);
 
1371
    }
 
1372
 
 
1373
    /* NOTE: If null_value == false, "result" must be not NULL.  */
 
1374
 
 
1375
    field->set_notnull();
 
1376
    error=field->store(result->ptr(),result->length(),cs);
 
1377
    str_value.set_quick(0, 0, cs);
 
1378
  }
 
1379
  else if (result_type() == REAL_RESULT)
 
1380
  {
 
1381
    double nr= entry->val_real(&null_value);
 
1382
    if (null_value)
 
1383
      return set_field_to_null(field);
 
1384
    field->set_notnull();
 
1385
    error=field->store(nr);
 
1386
  }
 
1387
  else if (result_type() == DECIMAL_RESULT)
 
1388
  {
 
1389
    my_decimal decimal_value;
 
1390
    my_decimal *val= entry->val_decimal(&null_value, &decimal_value);
 
1391
    if (null_value)
 
1392
      return set_field_to_null(field);
 
1393
    field->set_notnull();
 
1394
    error=field->store_decimal(val);
 
1395
  }
 
1396
  else
 
1397
  {
 
1398
    int64_t nr= entry->val_int(&null_value);
 
1399
    if (null_value)
 
1400
      return set_field_to_null_with_conversions(field, no_conversions);
 
1401
    field->set_notnull();
 
1402
    error=field->store(nr, unsigned_flag);
 
1403
  }
 
1404
  return error;
 
1405
}
 
1406
 
 
1407
 
 
1408
String *
 
1409
Item_func_get_user_var::val_str(String *str)
 
1410
{
 
1411
  assert(fixed == 1);
 
1412
  if (!var_entry)
 
1413
    return((String*) 0);                        // No such variable
 
1414
  return(var_entry->val_str(&null_value, str, decimals));
 
1415
}
 
1416
 
 
1417
 
 
1418
double Item_func_get_user_var::val_real()
 
1419
{
 
1420
  assert(fixed == 1);
 
1421
  if (!var_entry)
 
1422
    return 0.0;                                 // No such variable
 
1423
  return (var_entry->val_real(&null_value));
 
1424
}
 
1425
 
 
1426
 
 
1427
my_decimal *Item_func_get_user_var::val_decimal(my_decimal *dec)
 
1428
{
 
1429
  assert(fixed == 1);
 
1430
  if (!var_entry)
 
1431
    return 0;
 
1432
  return var_entry->val_decimal(&null_value, dec);
 
1433
}
 
1434
 
 
1435
 
 
1436
int64_t Item_func_get_user_var::val_int()
 
1437
{
 
1438
  assert(fixed == 1);
 
1439
  if (!var_entry)
 
1440
    return 0L;                          // No such variable
 
1441
  return (var_entry->val_int(&null_value));
 
1442
}
 
1443
 
 
1444
 
 
1445
/**
 
1446
  Get variable by name and, if necessary, put the record of variable 
 
1447
  use into the binary log.
 
1448
 
 
1449
  When a user variable is invoked from an update query (INSERT, UPDATE etc),
 
1450
  stores this variable and its value in session->user_var_events, so that it can be
 
1451
  written to the binlog (will be written just before the query is written, see
 
1452
  log.cc).
 
1453
 
 
1454
  @param      session        Current thread
 
1455
  @param      name       Variable name
 
1456
  @param[out] out_entry  variable structure or NULL. The pointer is set
 
1457
                         regardless of whether function succeeded or not.
 
1458
 
 
1459
  @retval
 
1460
    0  OK
 
1461
  @retval
 
1462
    1  Failed to put appropriate record into binary log
 
1463
 
 
1464
*/
 
1465
 
 
1466
int get_var_with_binlog(Session *session, enum_sql_command sql_command,
 
1467
                        LEX_STRING &name, user_var_entry **out_entry)
 
1468
{
 
1469
  BINLOG_USER_VAR_EVENT *user_var_event;
 
1470
  user_var_entry *var_entry;
 
1471
  var_entry= get_variable(&session->user_vars, name, 0);
 
1472
 
 
1473
  /*
 
1474
    Any reference to user-defined variable which is done from stored
 
1475
    function or trigger affects their execution and the execution of the
 
1476
    calling statement. We must log all such variables even if they are 
 
1477
    not involved in table-updating statements.
 
1478
  */
 
1479
  if (!(opt_bin_log && is_update_query(sql_command)))
 
1480
  {
 
1481
    *out_entry= var_entry;
 
1482
    return 0;
 
1483
  }
 
1484
 
 
1485
  if (!var_entry)
 
1486
  {
 
1487
    /*
 
1488
      If the variable does not exist, it's NULL, but we want to create it so
 
1489
      that it gets into the binlog (if it didn't, the slave could be
 
1490
      influenced by a variable of the same name previously set by another
 
1491
      thread).
 
1492
      We create it like if it had been explicitly set with SET before.
 
1493
      The 'new' mimics what sql_yacc.yy does when 'SET @a=10;'.
 
1494
      sql_set_variables() is what is called from 'case SQLCOM_SET_OPTION'
 
1495
      in dispatch_command()). Instead of building a one-element list to pass to
 
1496
      sql_set_variables(), we could instead manually call check() and update();
 
1497
      this would save memory and time; but calling sql_set_variables() makes
 
1498
      one unique place to maintain (sql_set_variables()). 
 
1499
 
 
1500
      Manipulation with lex is necessary since free_underlaid_joins
 
1501
      is going to release memory belonging to the main query.
 
1502
    */
 
1503
 
 
1504
    List<set_var_base> tmp_var_list;
 
1505
    LEX *sav_lex= session->lex, lex_tmp;
 
1506
    session->lex= &lex_tmp;
 
1507
    lex_start(session);
 
1508
    tmp_var_list.push_back(new set_var_user(new Item_func_set_user_var(name,
 
1509
                                                                       new Item_null())));
 
1510
    /* Create the variable */
 
1511
    if (sql_set_variables(session, &tmp_var_list))
 
1512
    {
 
1513
      session->lex= sav_lex;
 
1514
      goto err;
 
1515
    }
 
1516
    session->lex= sav_lex;
 
1517
    if (!(var_entry= get_variable(&session->user_vars, name, 0)))
 
1518
      goto err;
 
1519
  }
 
1520
  else if (var_entry->used_query_id == session->query_id ||
 
1521
           mysql_bin_log.is_query_in_union(session, var_entry->used_query_id))
 
1522
  {
 
1523
    /* 
 
1524
       If this variable was already stored in user_var_events by this query
 
1525
       (because it's used in more than one place in the query), don't store
 
1526
       it.
 
1527
    */
 
1528
    *out_entry= var_entry;
 
1529
    return 0;
 
1530
  }
 
1531
 
 
1532
  uint32_t size;
 
1533
  /*
 
1534
    First we need to store value of var_entry, when the next situation
 
1535
    appears:
 
1536
    > set @a:=1;
 
1537
    > insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1);
 
1538
    We have to write to binlog value @a= 1.
 
1539
 
 
1540
    We allocate the user_var_event on user_var_events_alloc pool, not on
 
1541
    the this-statement-execution pool because in SPs user_var_event objects 
 
1542
    may need to be valid after current [SP] statement execution pool is
 
1543
    destroyed.
 
1544
  */
 
1545
  size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length;
 
1546
  if (!(user_var_event= (BINLOG_USER_VAR_EVENT *)
 
1547
        alloc_root(session->user_var_events_alloc, size)))
 
1548
    goto err;
 
1549
 
 
1550
  user_var_event->value= (char*) user_var_event +
 
1551
    ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT));
 
1552
  user_var_event->user_var_event= var_entry;
 
1553
  user_var_event->type= var_entry->type;
 
1554
  user_var_event->charset_number= var_entry->collation.collation->number;
 
1555
  if (!var_entry->value)
 
1556
  {
 
1557
    /* NULL value*/
 
1558
    user_var_event->length= 0;
 
1559
    user_var_event->value= 0;
 
1560
  }
 
1561
  else
 
1562
  {
 
1563
    user_var_event->length= var_entry->length;
 
1564
    memcpy(user_var_event->value, var_entry->value,
 
1565
           var_entry->length);
 
1566
  }
 
1567
  /* Mark that this variable has been used by this query */
 
1568
  var_entry->used_query_id= session->query_id;
 
1569
  if (insert_dynamic(&session->user_var_events, (unsigned char*) &user_var_event))
 
1570
    goto err;
 
1571
 
 
1572
  *out_entry= var_entry;
 
1573
  return 0;
 
1574
 
 
1575
err:
 
1576
  *out_entry= var_entry;
 
1577
  return 1;
 
1578
}
 
1579
 
 
1580
void Item_func_get_user_var::fix_length_and_dec()
 
1581
{
 
1582
  Session *session=current_session;
 
1583
  int error;
 
1584
  maybe_null=1;
 
1585
  decimals=NOT_FIXED_DEC;
 
1586
  max_length=MAX_BLOB_WIDTH;
 
1587
 
 
1588
  error= get_var_with_binlog(session, session->lex->sql_command, name, &var_entry);
 
1589
 
 
1590
  /*
 
1591
    If the variable didn't exist it has been created as a STRING-type.
 
1592
    'var_entry' is NULL only if there occured an error during the call to
 
1593
    get_var_with_binlog.
 
1594
  */
 
1595
  if (var_entry)
 
1596
  {
 
1597
    m_cached_result_type= var_entry->type;
 
1598
    unsigned_flag= var_entry->unsigned_flag;
 
1599
    max_length= var_entry->length;
 
1600
 
 
1601
    collation.set(var_entry->collation);
 
1602
    switch(m_cached_result_type) {
 
1603
    case REAL_RESULT:
 
1604
      max_length= DBL_DIG + 8;
 
1605
      break;
 
1606
    case INT_RESULT:
 
1607
      max_length= MAX_BIGINT_WIDTH;
 
1608
      decimals=0;
 
1609
      break;
 
1610
    case STRING_RESULT:
 
1611
      max_length= MAX_BLOB_WIDTH;
 
1612
      break;
 
1613
    case DECIMAL_RESULT:
 
1614
      max_length= DECIMAL_MAX_STR_LENGTH;
 
1615
      decimals= DECIMAL_MAX_SCALE;
 
1616
      break;
 
1617
    case ROW_RESULT:                            // Keep compiler happy
 
1618
    default:
 
1619
      assert(0);
 
1620
      break;
 
1621
    }
 
1622
  }
 
1623
  else
 
1624
  {
 
1625
    collation.set(&my_charset_bin, DERIVATION_IMPLICIT);
 
1626
    null_value= 1;
 
1627
    m_cached_result_type= STRING_RESULT;
 
1628
    max_length= MAX_BLOB_WIDTH;
 
1629
  }
 
1630
}
 
1631
 
 
1632
 
 
1633
bool Item_func_get_user_var::const_item() const
 
1634
{
 
1635
  return (!var_entry || current_session->query_id != var_entry->update_query_id);
 
1636
}
 
1637
 
 
1638
 
 
1639
enum Item_result Item_func_get_user_var::result_type() const
 
1640
{
 
1641
  return m_cached_result_type;
 
1642
}
 
1643
 
 
1644
 
 
1645
void Item_func_get_user_var::print(String *str,
 
1646
                                   enum_query_type query_type __attribute__((unused)))
 
1647
{
 
1648
  str->append(STRING_WITH_LEN("(@"));
 
1649
  str->append(name.str,name.length);
 
1650
  str->append(')');
 
1651
}
 
1652
 
 
1653
 
 
1654
bool Item_func_get_user_var::eq(const Item *item,
 
1655
                                bool binary_cmp __attribute__((unused))) const
 
1656
{
 
1657
  /* Assume we don't have rtti */
 
1658
  if (this == item)
 
1659
    return 1;                                   // Same item is same.
 
1660
  /* Check if other type is also a get_user_var() object */
 
1661
  if (item->type() != FUNC_ITEM ||
 
1662
      ((Item_func*) item)->functype() != functype())
 
1663
    return 0;
 
1664
  Item_func_get_user_var *other=(Item_func_get_user_var*) item;
 
1665
  return (name.length == other->name.length &&
 
1666
          !memcmp(name.str, other->name.str, name.length));
 
1667
}
 
1668
 
 
1669
 
 
1670
bool Item_user_var_as_out_param::fix_fields(Session *session, Item **ref)
 
1671
{
 
1672
  assert(fixed == 0);
 
1673
  if (Item::fix_fields(session, ref) ||
 
1674
      !(entry= get_variable(&session->user_vars, name, 1)))
 
1675
    return true;
 
1676
  entry->type= STRING_RESULT;
 
1677
  /*
 
1678
    Let us set the same collation which is used for loading
 
1679
    of fields in LOAD DATA INFILE.
 
1680
    (Since Item_user_var_as_out_param is used only there).
 
1681
  */
 
1682
  entry->collation.set(session->variables.collation_database);
 
1683
  entry->update_query_id= session->query_id;
 
1684
  return false;
 
1685
}
 
1686
 
 
1687
 
 
1688
void Item_user_var_as_out_param::set_null_value(const CHARSET_INFO * const cs)
 
1689
{
 
1690
  ::update_hash(entry, true, 0, 0, STRING_RESULT, cs,
 
1691
                DERIVATION_IMPLICIT, 0 /* unsigned_arg */);
 
1692
}
 
1693
 
 
1694
 
 
1695
void Item_user_var_as_out_param::set_value(const char *str, uint32_t length,
 
1696
                                           const CHARSET_INFO * const cs)
 
1697
{
 
1698
  ::update_hash(entry, false, (void*)str, length, STRING_RESULT, cs,
 
1699
                DERIVATION_IMPLICIT, 0 /* unsigned_arg */);
 
1700
}
 
1701
 
 
1702
 
 
1703
double Item_user_var_as_out_param::val_real()
 
1704
{
 
1705
  assert(0);
 
1706
  return 0.0;
 
1707
}
 
1708
 
 
1709
 
 
1710
int64_t Item_user_var_as_out_param::val_int()
 
1711
{
 
1712
  assert(0);
 
1713
  return 0;
 
1714
}
 
1715
 
 
1716
 
 
1717
String* Item_user_var_as_out_param::val_str(String *str __attribute__((unused)))
 
1718
{
 
1719
  assert(0);
 
1720
  return 0;
 
1721
}
 
1722
 
 
1723
 
 
1724
my_decimal* Item_user_var_as_out_param::val_decimal(my_decimal *decimal_buffer __attribute__((unused)))
 
1725
{
 
1726
  assert(0);
 
1727
  return 0;
 
1728
}
 
1729
 
 
1730
 
 
1731
void Item_user_var_as_out_param::print(String *str,
 
1732
                                       enum_query_type query_type __attribute__((unused)))
 
1733
{
 
1734
  str->append('@');
 
1735
  str->append(name.str,name.length);
 
1736
}
 
1737
 
 
1738
 
 
1739
Item_func_get_system_var::
 
1740
Item_func_get_system_var(sys_var *var_arg, enum_var_type var_type_arg,
 
1741
                       LEX_STRING *component_arg, const char *name_arg,
 
1742
                       size_t name_len_arg)
 
1743
  :var(var_arg), var_type(var_type_arg), component(*component_arg)
 
1744
{
 
1745
  /* set_name() will allocate the name */
 
1746
  set_name(name_arg, name_len_arg, system_charset_info);
 
1747
}
 
1748
 
 
1749
 
 
1750
bool
 
1751
Item_func_get_system_var::fix_fields(Session *session, Item **ref)
 
1752
{
 
1753
  Item *item;
 
1754
 
 
1755
  /*
 
1756
    Evaluate the system variable and substitute the result (a basic constant)
 
1757
    instead of this item. If the variable can not be evaluated,
 
1758
    the error is reported in sys_var::item().
 
1759
  */
 
1760
  if (!(item= var->item(session, var_type, &component)))
 
1761
    return(1);                             // Impossible
 
1762
  item->set_name(name, 0, system_charset_info); // don't allocate a new name
 
1763
  session->change_item_tree(ref, item);
 
1764
 
 
1765
  return(0);
 
1766
}
 
1767
 
 
1768
 
 
1769
bool Item_func_get_system_var::is_written_to_binlog()
 
1770
{
 
1771
  return var->is_written_to_binlog(var_type);
 
1772
}
 
1773
 
 
1774
int64_t Item_func_bit_xor::val_int()
 
1775
{
 
1776
  assert(fixed == 1);
 
1777
  uint64_t arg1= (uint64_t) args[0]->val_int();
 
1778
  uint64_t arg2= (uint64_t) args[1]->val_int();
 
1779
  if ((null_value= (args[0]->null_value || args[1]->null_value)))
 
1780
    return 0;
 
1781
  return (int64_t) (arg1 ^ arg2);
 
1782
}
 
1783
 
 
1784
 
 
1785
/***************************************************************************
 
1786
  System variables
 
1787
****************************************************************************/
 
1788
 
 
1789
/**
 
1790
  Return value of an system variable base[.name] as a constant item.
 
1791
 
 
1792
  @param session                        Thread handler
 
1793
  @param var_type               global / session
 
1794
  @param name                   Name of base or system variable
 
1795
  @param component              Component.
 
1796
 
 
1797
  @note
 
1798
    If component.str = 0 then the variable name is in 'name'
 
1799
 
 
1800
  @return
 
1801
    - 0  : error
 
1802
    - #  : constant item
 
1803
*/
 
1804
 
 
1805
 
 
1806
Item *get_system_var(Session *session, enum_var_type var_type, LEX_STRING name,
 
1807
                     LEX_STRING component)
 
1808
{
 
1809
  sys_var *var;
 
1810
  LEX_STRING *base_name, *component_name;
 
1811
 
 
1812
  if (component.str)
 
1813
  {
 
1814
    base_name= &component;
 
1815
    component_name= &name;
 
1816
  }
 
1817
  else
 
1818
  {
 
1819
    base_name= &name;
 
1820
    component_name= &component;                 // Empty string
 
1821
  }
 
1822
 
 
1823
  if (!(var= find_sys_var(session, base_name->str, base_name->length)))
 
1824
    return 0;
 
1825
  if (component.str)
 
1826
  {
 
1827
    if (!var->is_struct())
 
1828
    {
 
1829
      my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), base_name->str);
 
1830
      return 0;
 
1831
    }
 
1832
  }
 
1833
 
 
1834
  set_if_smaller(component_name->length, MAX_SYS_VAR_LENGTH);
 
1835
 
 
1836
  return new Item_func_get_system_var(var, var_type, component_name,
 
1837
                                      NULL, 0);
 
1838
}
 
1839
 
 
1840
 
 
1841
/**
 
1842
  Check a user level lock.
 
1843
 
 
1844
  Sets null_value=true on error.
 
1845
 
 
1846
  @retval
 
1847
    1           Available
 
1848
  @retval
 
1849
    0           Already taken, or error
 
1850
*/
 
1851
 
 
1852
int64_t Item_func_is_free_lock::val_int()
 
1853
{
 
1854
  assert(fixed == 1);
 
1855
  String *res=args[0]->val_str(&value);
 
1856
  User_level_lock *ull;
 
1857
 
 
1858
  null_value=0;
 
1859
  if (!res || !res->length())
 
1860
  {
 
1861
    null_value=1;
 
1862
    return 0;
 
1863
  }
 
1864
  
 
1865
  pthread_mutex_lock(&LOCK_user_locks);
 
1866
  ull= (User_level_lock *) hash_search(&hash_user_locks, (unsigned char*) res->ptr(),
 
1867
                                       (size_t) res->length());
 
1868
  pthread_mutex_unlock(&LOCK_user_locks);
 
1869
  if (!ull || !ull->locked)
 
1870
    return 1;
 
1871
  return 0;
 
1872
}
 
1873
 
 
1874
int64_t Item_func_is_used_lock::val_int()
 
1875
{
 
1876
  assert(fixed == 1);
 
1877
  String *res=args[0]->val_str(&value);
 
1878
  User_level_lock *ull;
 
1879
 
 
1880
  null_value=1;
 
1881
  if (!res || !res->length())
 
1882
    return 0;
 
1883
  
 
1884
  pthread_mutex_lock(&LOCK_user_locks);
 
1885
  ull= (User_level_lock *) hash_search(&hash_user_locks, (unsigned char*) res->ptr(),
 
1886
                                       (size_t) res->length());
 
1887
  pthread_mutex_unlock(&LOCK_user_locks);
 
1888
  if (!ull || !ull->locked)
 
1889
    return 0;
 
1890
 
 
1891
  null_value=0;
 
1892
  return ull->thread_id;
 
1893
}
 
1894
 
 
1895
 
 
1896
int64_t Item_func_row_count::val_int()
 
1897
{
 
1898
  assert(fixed == 1);
 
1899
  Session *session= current_session;
 
1900
 
 
1901
  return session->row_count_func;
 
1902
}
 
1903
 
 
1904
int64_t Item_func_found_rows::val_int()
 
1905
{
 
1906
  assert(fixed == 1);
 
1907
  Session *session= current_session;
 
1908
 
 
1909
  return session->found_rows();
 
1910
}