~drizzle-trunk/drizzle/development

492.3.2 by Lee
code clean up to moving functions into drizzled/functions directory - Item_num_op and Item_numhybrid
1
/** Copyright (C) 2000-2003 MySQL AB
1 by brian
clean slate
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
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
24
#include <drizzled/server_includes.h>
212.5.28 by Monty Taylor
Moved my_bit and my_list
25
#include <mysys/my_bit.h>
520.6.7 by Monty Taylor
Moved a bunch of crap out of common_includes.
26
#include <drizzled/slave.h>
549 by Monty Taylor
Took gettext.h out of header files.
27
#include <drizzled/error.h>
1 by brian
clean slate
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"))
56 by brian
Next pass of true/false update.
34
    return true;
35
  return false;
1 by brian
clean slate
36
}
37
38
39
/**
40
  @return
56 by brian
Next pass of true/false update.
41
    true if item is a constant
1 by brian
clean slate
42
*/
43
44
bool
45
eval_const_cond(COND *cond)
46
{
56 by brian
Next pass of true/false update.
47
  return ((Item_func*) cond)->val_int() ? true : false;
1 by brian
clean slate
48
}
49
50
51
void Item_func::fix_num_length_and_dec()
52
{
482 by Brian Aker
Remove uint.
53
  uint32_t fl_length= 0;
1 by brian
clean slate
54
  decimals=0;
482 by Brian Aker
Remove uint.
55
  for (uint32_t i=0 ; i < arg_count ; i++)
1 by brian
clean slate
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;
482 by Brian Aker
Remove uint.
78
  for (uint32_t i=0 ; i < arg_count ; i++)
1 by brian
clean slate
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
  }
398.1.4 by Monty Taylor
Renamed max/min.
84
  int precision= cmin(max_int_part + decimals, DECIMAL_MAX_PRECISION);
1 by brian
clean slate
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;
482 by Brian Aker
Remove uint.
98
  for (uint32_t i=0 ; i < arg_count ; i++)
1 by brian
clean slate
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
{
205 by Brian Aker
uint32 -> uin32_t
113
  uint32_t length= 0;
1 by brian
clean slate
114
  decimals= 0;
115
  max_length= 0;
482 by Brian Aker
Remove uint.
116
  for (uint32_t i=0 ; i < arg_count ; i++)
1 by brian
clean slate
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
163 by Brian Aker
Merge Monty's code.
130
      max_length= UINT32_MAX;
1 by brian
clean slate
131
    else
132
      max_length= length;
133
  }
134
}
135
136
137
138
void Item_func::signal_divide_by_null()
139
{
520.1.22 by Brian Aker
Second pass of thd cleanup
140
  Session *session= current_session;
141
  push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, ER_DIVISION_BY_ZERO, ER(ER_DIVISION_BY_ZERO));
1 by brian
clean slate
142
  null_value= 1;
143
}
144
145
520.1.22 by Brian Aker
Second pass of thd cleanup
146
Item *Item_func::get_tmp_table_item(Session *session)
1 by brian
clean slate
147
{
148
  if (!with_sum_func && !const_item() && functype() != SUSERVAR_FUNC)
149
    return new Item_field(result_field);
520.1.22 by Brian Aker
Second pass of thd cleanup
150
  return copy_or_same(session);
1 by brian
clean slate
151
}
152
153
/*
154
  When a user variable is updated (in a SET command or a query like
155
  SELECT @a:= ).
156
*/
157
520.1.22 by Brian Aker
Second pass of thd cleanup
158
bool Item_func_set_user_var::fix_fields(Session *session, Item **ref)
1 by brian
clean slate
159
{
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
160
  assert(fixed == 0);
1 by brian
clean slate
161
  /* fix_fields will call Item_func_set_user_var::fix_length_and_dec */
520.1.22 by Brian Aker
Second pass of thd cleanup
162
  if (Item_func::fix_fields(session, ref) ||
163
      !(entry= get_variable(&session->user_vars, name, 1)))
56 by brian
Next pass of true/false update.
164
    return true;
1 by brian
clean slate
165
  /* 
166
     Remember the last query which updated it, this way a query can later know
167
     if this variable is a constant item in the query (it is if update_query_id
168
     is different from query_id).
169
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
170
  entry->update_query_id= session->query_id;
1 by brian
clean slate
171
  /*
172
    As it is wrong and confusing to associate any 
173
    character set with NULL, @a should be latin2
174
    after this query sequence:
175
176
      SET @a=_latin2'string';
177
      SET @a=NULL;
178
179
    I.e. the second query should not change the charset
180
    to the current default value, but should keep the 
181
    original value assigned during the first query.
182
    In order to do it, we don't copy charset
183
    from the argument if the argument is NULL
184
    and the variable has previously been initialized.
185
  */
186
  null_item= (args[0]->type() == NULL_ITEM);
187
  if (!entry->collation.collation || !null_item)
188
    entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
189
  collation.set(entry->collation.collation, DERIVATION_IMPLICIT);
190
  cached_result_type= args[0]->result_type();
56 by brian
Next pass of true/false update.
191
  return false;
1 by brian
clean slate
192
}
193
194
195
void
196
Item_func_set_user_var::fix_length_and_dec()
197
{
198
  maybe_null=args[0]->maybe_null;
199
  max_length=args[0]->max_length;
200
  decimals=args[0]->decimals;
201
  collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
202
}
203
204
205
/*
206
  Mark field in read_map
207
208
  NOTES
209
    This is used by filesort to register used fields in a a temporary
210
    column read set or to register used fields in a view
211
*/
212
481 by Brian Aker
Remove all of uchar.
213
bool Item_func_set_user_var::register_field_in_read_map(unsigned char *arg)
1 by brian
clean slate
214
{
215
  if (result_field)
216
  {
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
217
    Table *table= (Table *) arg;
1 by brian
clean slate
218
    if (result_field->table == table || !table)
219
      bitmap_set_bit(result_field->table->read_set, result_field->field_index);
383.7.1 by Andrey Zhakov
Initial submit of code and tests
220
    if (result_field->vcol_info && result_field->vcol_info->expr_item)
221
      return result_field->vcol_info->
222
               expr_item->walk(&Item::register_field_in_read_map, 1, arg);
223
  }
224
  return 0;
225
}
226
227
228
/*
229
  Mark field in bitmap supplied as *arg
230
231
*/
232
481.3.1 by Monty Taylor
Merged vcol stuff.
233
bool Item_func_set_user_var::register_field_in_bitmap(unsigned char *arg)
383.7.1 by Andrey Zhakov
Initial submit of code and tests
234
{
235
  MY_BITMAP *bitmap = (MY_BITMAP *) arg;
236
  assert(bitmap);
237
  if (result_field)
238
  {
239
    bitmap_set_bit(bitmap, result_field->field_index);
1 by brian
clean slate
240
  }
241
  return 0;
242
}
243
244
245
/**
246
  Set value to user variable.
247
248
  @param entry          pointer to structure representing variable
249
  @param set_null       should we set NULL value ?
250
  @param ptr            pointer to buffer with new value
251
  @param length         length of new value
252
  @param type           type of new value
253
  @param cs             charset info for new value
254
  @param dv             derivation for new value
255
  @param unsigned_arg   indiates if a value of type INT_RESULT is unsigned
256
257
  @note Sets error and fatal error if allocation fails.
258
259
  @retval
260
    false   success
261
  @retval
262
    true    failure
263
*/
264
492.3.32 by Lee
more changes to move functions from item_func.cc/h to the functions directory
265
#define extra_size sizeof(double)
266
1 by brian
clean slate
267
static bool
482 by Brian Aker
Remove uint.
268
update_hash(user_var_entry *entry, bool set_null, void *ptr, uint32_t length,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
269
            Item_result type, const CHARSET_INFO * const cs, Derivation dv,
1 by brian
clean slate
270
            bool unsigned_arg)
271
{
272
  if (set_null)
273
  {
274
    char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
275
    if (entry->value && entry->value != pos)
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
276
      free(entry->value);
1 by brian
clean slate
277
    entry->value= 0;
278
    entry->length= 0;
279
  }
280
  else
281
  {
282
    if (type == STRING_RESULT)
283
      length++;					// Store strings with end \0
284
    if (length <= extra_size)
285
    {
286
      /* Save value in value struct */
287
      char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
288
      if (entry->value != pos)
289
      {
290
	if (entry->value)
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
291
	  free(entry->value);
1 by brian
clean slate
292
	entry->value=pos;
293
      }
294
    }
295
    else
296
    {
297
      /* Allocate variable */
298
      if (entry->length != length)
299
      {
300
	char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
301
	if (entry->value == pos)
302
	  entry->value=0;
303
        entry->value= (char*) my_realloc(entry->value, length,
304
                                         MYF(MY_ALLOW_ZERO_PTR | MY_WME |
305
                                             ME_FATALERROR));
306
        if (!entry->value)
307
	  return 1;
308
      }
309
    }
310
    if (type == STRING_RESULT)
311
    {
312
      length--;					// Fix length change above
313
      entry->value[length]= 0;			// Store end \0
314
    }
315
    memcpy(entry->value,ptr,length);
316
    if (type == DECIMAL_RESULT)
317
      ((my_decimal*)entry->value)->fix_buffer_pointer();
318
    entry->length= length;
319
    entry->collation.set(cs, dv);
320
    entry->unsigned_flag= unsigned_arg;
321
  }
322
  entry->type=type;
323
  return 0;
324
}
325
326
327
bool
482 by Brian Aker
Remove uint.
328
Item_func_set_user_var::update_hash(void *ptr, uint32_t length,
1 by brian
clean slate
329
                                    Item_result res_type,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
330
                                    const CHARSET_INFO * const cs, Derivation dv,
1 by brian
clean slate
331
                                    bool unsigned_arg)
332
{
333
  /*
334
    If we set a variable explicitely to NULL then keep the old
335
    result type of the variable
336
  */
337
  if ((null_value= args[0]->null_value) && null_item)
338
    res_type= entry->type;                      // Don't change type of item
339
  if (::update_hash(entry, (null_value= args[0]->null_value),
340
                    ptr, length, res_type, cs, dv, unsigned_arg))
341
  {
342
    null_value= 1;
343
    return 1;
344
  }
345
  return 0;
346
}
347
348
349
/** Get the value of a variable as a double. */
350
275 by Brian Aker
Full removal of my_bool from central server.
351
double user_var_entry::val_real(bool *null_value)
1 by brian
clean slate
352
{
353
  if ((*null_value= (value == 0)))
354
    return 0.0;
355
356
  switch (type) {
357
  case REAL_RESULT:
358
    return *(double*) value;
359
  case INT_RESULT:
152 by Brian Aker
longlong replacement
360
    return (double) *(int64_t*) value;
1 by brian
clean slate
361
  case DECIMAL_RESULT:
362
  {
363
    double result;
364
    my_decimal2double(E_DEC_FATAL_ERROR, (my_decimal *)value, &result);
365
    return result;
366
  }
367
  case STRING_RESULT:
368
    return my_atof(value);                      // This is null terminated
369
  case ROW_RESULT:
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
370
    assert(1);				// Impossible
1 by brian
clean slate
371
    break;
372
  }
373
  return 0.0;					// Impossible
374
}
375
376
377
/** Get the value of a variable as an integer. */
378
275 by Brian Aker
Full removal of my_bool from central server.
379
int64_t user_var_entry::val_int(bool *null_value) const
1 by brian
clean slate
380
{
381
  if ((*null_value= (value == 0)))
398.1.8 by Monty Taylor
Enabled -Wlong-long.
382
    return 0L;
1 by brian
clean slate
383
384
  switch (type) {
385
  case REAL_RESULT:
152 by Brian Aker
longlong replacement
386
    return (int64_t) *(double*) value;
1 by brian
clean slate
387
  case INT_RESULT:
152 by Brian Aker
longlong replacement
388
    return *(int64_t*) value;
1 by brian
clean slate
389
  case DECIMAL_RESULT:
390
  {
152 by Brian Aker
longlong replacement
391
    int64_t result;
1 by brian
clean slate
392
    my_decimal2int(E_DEC_FATAL_ERROR, (my_decimal *)value, 0, &result);
393
    return result;
394
  }
395
  case STRING_RESULT:
396
  {
397
    int error;
398
    return my_strtoll10(value, (char**) 0, &error);// String is null terminated
399
  }
400
  case ROW_RESULT:
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
401
    assert(1);				// Impossible
1 by brian
clean slate
402
    break;
403
  }
398.1.8 by Monty Taylor
Enabled -Wlong-long.
404
  return 0L;					// Impossible
1 by brian
clean slate
405
}
406
407
408
/** Get the value of a variable as a string. */
409
275 by Brian Aker
Full removal of my_bool from central server.
410
String *user_var_entry::val_str(bool *null_value, String *str,
482 by Brian Aker
Remove uint.
411
				uint32_t decimals)
1 by brian
clean slate
412
{
413
  if ((*null_value= (value == 0)))
414
    return (String*) 0;
415
416
  switch (type) {
417
  case REAL_RESULT:
418
    str->set_real(*(double*) value, decimals, &my_charset_bin);
419
    break;
420
  case INT_RESULT:
421
    if (!unsigned_flag)
152 by Brian Aker
longlong replacement
422
      str->set(*(int64_t*) value, &my_charset_bin);
1 by brian
clean slate
423
    else
151 by Brian Aker
Ulonglong to uint64_t
424
      str->set(*(uint64_t*) value, &my_charset_bin);
1 by brian
clean slate
425
    break;
426
  case DECIMAL_RESULT:
427
    my_decimal2string(E_DEC_FATAL_ERROR, (my_decimal *)value, 0, 0, 0, str);
428
    break;
429
  case STRING_RESULT:
430
    if (str->copy(value, length, collation.collation))
431
      str= 0;					// EOM error
432
  case ROW_RESULT:
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
433
    assert(1);				// Impossible
1 by brian
clean slate
434
    break;
435
  }
436
  return(str);
437
}
438
439
/** Get the value of a variable as a decimal. */
440
275 by Brian Aker
Full removal of my_bool from central server.
441
my_decimal *user_var_entry::val_decimal(bool *null_value, my_decimal *val)
1 by brian
clean slate
442
{
443
  if ((*null_value= (value == 0)))
444
    return 0;
445
446
  switch (type) {
447
  case REAL_RESULT:
448
    double2my_decimal(E_DEC_FATAL_ERROR, *(double*) value, val);
449
    break;
450
  case INT_RESULT:
152 by Brian Aker
longlong replacement
451
    int2my_decimal(E_DEC_FATAL_ERROR, *(int64_t*) value, 0, val);
1 by brian
clean slate
452
    break;
453
  case DECIMAL_RESULT:
454
    val= (my_decimal *)value;
455
    break;
456
  case STRING_RESULT:
457
    str2my_decimal(E_DEC_FATAL_ERROR, value, length, collation.collation, val);
458
    break;
459
  case ROW_RESULT:
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
460
    assert(1);				// Impossible
1 by brian
clean slate
461
    break;
462
  }
463
  return(val);
464
}
465
466
/**
467
  This functions is invoked on SET \@variable or
468
  \@variable:= expression.
469
470
  Evaluate (and check expression), store results.
471
472
  @note
473
    For now it always return OK. All problem with value evaluating
520.1.22 by Brian Aker
Second pass of thd cleanup
474
    will be caught by session->is_error() check in sql_set_variables().
1 by brian
clean slate
475
476
  @retval
56 by brian
Next pass of true/false update.
477
    false OK.
1 by brian
clean slate
478
*/
479
480
bool
481
Item_func_set_user_var::check(bool use_result_field)
482
{
483
  if (use_result_field && !result_field)
56 by brian
Next pass of true/false update.
484
    use_result_field= false;
1 by brian
clean slate
485
486
  switch (cached_result_type) {
487
  case REAL_RESULT:
488
  {
489
    save_result.vreal= use_result_field ? result_field->val_real() :
490
                        args[0]->val_real();
491
    break;
492
  }
493
  case INT_RESULT:
494
  {
495
    save_result.vint= use_result_field ? result_field->val_int() :
496
                       args[0]->val_int();
497
    unsigned_flag= use_result_field ? ((Field_num*)result_field)->unsigned_flag:
498
                    args[0]->unsigned_flag;
499
    break;
500
  }
501
  case STRING_RESULT:
502
  {
503
    save_result.vstr= use_result_field ? result_field->val_str(&value) :
504
                       args[0]->val_str(&value);
505
    break;
506
  }
507
  case DECIMAL_RESULT:
508
  {
509
    save_result.vdec= use_result_field ?
510
                       result_field->val_decimal(&decimal_buff) :
511
                       args[0]->val_decimal(&decimal_buff);
512
    break;
513
  }
514
  case ROW_RESULT:
515
  default:
516
    // This case should never be chosen
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
517
    assert(0);
1 by brian
clean slate
518
    break;
519
  }
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
520
  return(false);
1 by brian
clean slate
521
}
522
523
524
/**
525
  This functions is invoked on
526
  SET \@variable or \@variable:= expression.
527
528
  @note
529
    We have to store the expression as such in the variable, independent of
530
    the value method used by the user
531
532
  @retval
533
    0	OK
534
  @retval
535
    1	EOM Error
536
537
*/
538
539
bool
540
Item_func_set_user_var::update()
541
{
542
  bool res= false;
543
544
  switch (cached_result_type) {
545
  case REAL_RESULT:
546
  {
547
    res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal),
548
		     REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
549
    break;
550
  }
551
  case INT_RESULT:
552
  {
553
    res= update_hash((void*) &save_result.vint, sizeof(save_result.vint),
554
                     INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT,
555
                     unsigned_flag);
556
    break;
557
  }
558
  case STRING_RESULT:
559
  {
560
    if (!save_result.vstr)					// Null value
561
      res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin,
562
		       DERIVATION_IMPLICIT, 0);
563
    else
564
      res= update_hash((void*) save_result.vstr->ptr(),
565
		       save_result.vstr->length(), STRING_RESULT,
566
		       save_result.vstr->charset(),
567
		       DERIVATION_IMPLICIT, 0);
568
    break;
569
  }
570
  case DECIMAL_RESULT:
571
  {
572
    if (!save_result.vdec)					// Null value
573
      res= update_hash((void*) 0, 0, DECIMAL_RESULT, &my_charset_bin,
574
                       DERIVATION_IMPLICIT, 0);
575
    else
576
      res= update_hash((void*) save_result.vdec,
577
                       sizeof(my_decimal), DECIMAL_RESULT,
578
                       &my_charset_bin, DERIVATION_IMPLICIT, 0);
579
    break;
580
  }
581
  case ROW_RESULT:
582
  default:
583
    // This case should never be chosen
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
584
    assert(0);
1 by brian
clean slate
585
    break;
586
  }
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
587
  return(res);
1 by brian
clean slate
588
}
589
590
591
double Item_func_set_user_var::val_real()
592
{
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
593
  assert(fixed == 1);
1 by brian
clean slate
594
  check(0);
595
  update();					// Store expression
596
  return entry->val_real(&null_value);
597
}
598
152 by Brian Aker
longlong replacement
599
int64_t Item_func_set_user_var::val_int()
1 by brian
clean slate
600
{
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
601
  assert(fixed == 1);
1 by brian
clean slate
602
  check(0);
603
  update();					// Store expression
604
  return entry->val_int(&null_value);
605
}
606
607
String *Item_func_set_user_var::val_str(String *str)
608
{
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
609
  assert(fixed == 1);
1 by brian
clean slate
610
  check(0);
611
  update();					// Store expression
612
  return entry->val_str(&null_value, str, decimals);
613
}
614
615
616
my_decimal *Item_func_set_user_var::val_decimal(my_decimal *val)
617
{
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
618
  assert(fixed == 1);
1 by brian
clean slate
619
  check(0);
620
  update();					// Store expression
621
  return entry->val_decimal(&null_value, val);
622
}
623
624
625
double Item_func_set_user_var::val_result()
626
{
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
627
  assert(fixed == 1);
56 by brian
Next pass of true/false update.
628
  check(true);
1 by brian
clean slate
629
  update();					// Store expression
630
  return entry->val_real(&null_value);
631
}
632
152 by Brian Aker
longlong replacement
633
int64_t Item_func_set_user_var::val_int_result()
1 by brian
clean slate
634
{
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
635
  assert(fixed == 1);
56 by brian
Next pass of true/false update.
636
  check(true);
1 by brian
clean slate
637
  update();					// Store expression
638
  return entry->val_int(&null_value);
639
}
640
641
String *Item_func_set_user_var::str_result(String *str)
642
{
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
643
  assert(fixed == 1);
56 by brian
Next pass of true/false update.
644
  check(true);
1 by brian
clean slate
645
  update();					// Store expression
646
  return entry->val_str(&null_value, str, decimals);
647
}
648
649
650
my_decimal *Item_func_set_user_var::val_decimal_result(my_decimal *val)
651
{
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
652
  assert(fixed == 1);
56 by brian
Next pass of true/false update.
653
  check(true);
1 by brian
clean slate
654
  update();					// Store expression
655
  return entry->val_decimal(&null_value, val);
656
}
657
658
659
void Item_func_set_user_var::print(String *str, enum_query_type query_type)
660
{
661
  str->append(STRING_WITH_LEN("(@"));
662
  str->append(name.str, name.length);
663
  str->append(STRING_WITH_LEN(":="));
664
  args[0]->print(str, query_type);
665
  str->append(')');
666
}
667
668
669
void Item_func_set_user_var::print_as_stmt(String *str,
670
                                           enum_query_type query_type)
671
{
672
  str->append(STRING_WITH_LEN("set @"));
673
  str->append(name.str, name.length);
674
  str->append(STRING_WITH_LEN(":="));
675
  args[0]->print(str, query_type);
676
  str->append(')');
677
}
678
679
bool Item_func_set_user_var::send(Protocol *protocol, String *str_arg)
680
{
681
  if (result_field)
682
  {
683
    check(1);
684
    update();
685
    return protocol->store(result_field);
686
  }
687
  return Item::send(protocol, str_arg);
688
}
689
690
void Item_func_set_user_var::make_field(Send_field *tmp_field)
691
{
692
  if (result_field)
693
  {
694
    result_field->make_field(tmp_field);
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
695
    assert(tmp_field->table_name != 0);
1 by brian
clean slate
696
    if (Item::name)
697
      tmp_field->col_name=Item::name;               // Use user supplied name
698
  }
699
  else
700
    Item::make_field(tmp_field);
701
}
702
703
704
/*
705
  Save the value of a user variable into a field
706
707
  SYNOPSIS
708
    save_in_field()
709
      field           target field to save the value to
710
      no_conversion   flag indicating whether conversions are allowed
711
712
  DESCRIPTION
713
    Save the function value into a field and update the user variable
714
    accordingly. If a result field is defined and the target field doesn't
715
    coincide with it then the value from the result field will be used as
716
    the new value of the user variable.
717
718
    The reason to have this method rather than simply using the result
719
    field in the val_xxx() methods is that the value from the result field
720
    not always can be used when the result field is defined.
721
    Let's consider the following cases:
722
    1) when filling a tmp table the result field is defined but the value of it
723
    is undefined because it has to be produced yet. Thus we can't use it.
724
    2) on execution of an INSERT ... SELECT statement the save_in_field()
725
    function will be called to fill the data in the new record. If the SELECT
726
    part uses a tmp table then the result field is defined and should be
727
    used in order to get the correct result.
728
729
    The difference between the SET_USER_VAR function and regular functions
730
    like CONCAT is that the Item_func objects for the regular functions are
731
    replaced by Item_field objects after the values of these functions have
732
    been stored in a tmp table. Yet an object of the Item_field class cannot
733
    be used to update a user variable.
734
    Due to this we have to handle the result field in a special way here and
735
    in the Item_func_set_user_var::send() function.
736
737
  RETURN VALUES
56 by brian
Next pass of true/false update.
738
    false       Ok
739
    true        Error
1 by brian
clean slate
740
*/
741
742
int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions,
743
                                          bool can_use_result_field)
744
{
745
  bool use_result_field= (!can_use_result_field ? 0 :
746
                          (result_field && result_field != field));
747
  int error;
748
749
  /* Update the value of the user variable */
750
  check(use_result_field);
751
  update();
752
753
  if (result_type() == STRING_RESULT ||
754
      (result_type() == REAL_RESULT && field->result_type() == STRING_RESULT))
755
  {
756
    String *result;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
757
    const CHARSET_INFO * const cs= collation.collation;
1 by brian
clean slate
758
    char buff[MAX_FIELD_WIDTH];		// Alloc buffer for small columns
759
    str_value.set_quick(buff, sizeof(buff), cs);
760
    result= entry->val_str(&null_value, &str_value, decimals);
761
762
    if (null_value)
763
    {
764
      str_value.set_quick(0, 0, cs);
765
      return set_field_to_null_with_conversions(field, no_conversions);
766
    }
767
56 by brian
Next pass of true/false update.
768
    /* NOTE: If null_value == false, "result" must be not NULL.  */
1 by brian
clean slate
769
770
    field->set_notnull();
771
    error=field->store(result->ptr(),result->length(),cs);
772
    str_value.set_quick(0, 0, cs);
773
  }
774
  else if (result_type() == REAL_RESULT)
775
  {
776
    double nr= entry->val_real(&null_value);
777
    if (null_value)
778
      return set_field_to_null(field);
779
    field->set_notnull();
780
    error=field->store(nr);
781
  }
782
  else if (result_type() == DECIMAL_RESULT)
783
  {
784
    my_decimal decimal_value;
785
    my_decimal *val= entry->val_decimal(&null_value, &decimal_value);
786
    if (null_value)
787
      return set_field_to_null(field);
788
    field->set_notnull();
789
    error=field->store_decimal(val);
790
  }
791
  else
792
  {
152 by Brian Aker
longlong replacement
793
    int64_t nr= entry->val_int(&null_value);
1 by brian
clean slate
794
    if (null_value)
795
      return set_field_to_null_with_conversions(field, no_conversions);
796
    field->set_notnull();
797
    error=field->store(nr, unsigned_flag);
798
  }
799
  return error;
800
}
801
802
520.1.22 by Brian Aker
Second pass of thd cleanup
803
bool Item_user_var_as_out_param::fix_fields(Session *session, Item **ref)
1 by brian
clean slate
804
{
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
805
  assert(fixed == 0);
520.1.22 by Brian Aker
Second pass of thd cleanup
806
  if (Item::fix_fields(session, ref) ||
807
      !(entry= get_variable(&session->user_vars, name, 1)))
56 by brian
Next pass of true/false update.
808
    return true;
1 by brian
clean slate
809
  entry->type= STRING_RESULT;
810
  /*
811
    Let us set the same collation which is used for loading
812
    of fields in LOAD DATA INFILE.
813
    (Since Item_user_var_as_out_param is used only there).
814
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
815
  entry->collation.set(session->variables.collation_database);
816
  entry->update_query_id= session->query_id;
56 by brian
Next pass of true/false update.
817
  return false;
1 by brian
clean slate
818
}
819
820
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
821
void Item_user_var_as_out_param::set_null_value(const CHARSET_INFO * const cs)
1 by brian
clean slate
822
{
56 by brian
Next pass of true/false update.
823
  ::update_hash(entry, true, 0, 0, STRING_RESULT, cs,
1 by brian
clean slate
824
                DERIVATION_IMPLICIT, 0 /* unsigned_arg */);
825
}
826
827
482 by Brian Aker
Remove uint.
828
void Item_user_var_as_out_param::set_value(const char *str, uint32_t length,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
829
                                           const CHARSET_INFO * const cs)
1 by brian
clean slate
830
{
56 by brian
Next pass of true/false update.
831
  ::update_hash(entry, false, (void*)str, length, STRING_RESULT, cs,
1 by brian
clean slate
832
                DERIVATION_IMPLICIT, 0 /* unsigned_arg */);
833
}
834
835
836
double Item_user_var_as_out_param::val_real()
837
{
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
838
  assert(0);
1 by brian
clean slate
839
  return 0.0;
840
}
841
842
152 by Brian Aker
longlong replacement
843
int64_t Item_user_var_as_out_param::val_int()
1 by brian
clean slate
844
{
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
845
  assert(0);
1 by brian
clean slate
846
  return 0;
847
}
848
849
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
850
String* Item_user_var_as_out_param::val_str(String *str __attribute__((unused)))
77.1.15 by Monty Taylor
Bunch of warning cleanups.
851
{
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
852
  assert(0);
77.1.15 by Monty Taylor
Bunch of warning cleanups.
853
  return 0;
854
}
855
856
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
857
my_decimal* Item_user_var_as_out_param::val_decimal(my_decimal *decimal_buffer __attribute__((unused)))
77.1.15 by Monty Taylor
Bunch of warning cleanups.
858
{
51.1.20 by Jay Pipes
Removed/replaced DBUG symbols and fixed TRUE/FALSEs
859
  assert(0);
77.1.15 by Monty Taylor
Bunch of warning cleanups.
860
  return 0;
861
}
862
863
864
void Item_user_var_as_out_param::print(String *str,
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
865
                                       enum_query_type query_type __attribute__((unused)))
1 by brian
clean slate
866
{
867
  str->append('@');
868
  str->append(name.str,name.length);
869
}
870
871
/***************************************************************************
872
  System variables
873
****************************************************************************/
874
875
/**
876
  Return value of an system variable base[.name] as a constant item.
877
520.1.22 by Brian Aker
Second pass of thd cleanup
878
  @param session			Thread handler
1 by brian
clean slate
879
  @param var_type		global / session
880
  @param name		        Name of base or system variable
881
  @param component		Component.
882
883
  @note
884
    If component.str = 0 then the variable name is in 'name'
885
886
  @return
887
    - 0  : error
888
    - #  : constant item
889
*/