item_func.h 51.1 KB
Newer Older
1 2 3
#ifndef ITEM_FUNC_INCLUDED
#define ITEM_FUNC_INCLUDED

4
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
5

unknown's avatar
unknown committed
6 7
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
unknown's avatar
unknown committed
8
   the Free Software Foundation; version 2 of the License.
9

unknown's avatar
unknown committed
10 11 12 13
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
14

unknown's avatar
unknown committed
15 16 17 18 19 20 21
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */


/* Function items used by mysql */

22
#ifdef USE_PRAGMA_INTERFACE
unknown's avatar
unknown committed
23 24 25 26 27 28 29 30 31 32 33 34 35
#pragma interface			/* gcc class implementation */
#endif

#ifdef HAVE_IEEEFP_H
extern "C"				/* Bug in BSDI include file */
{
#include <ieeefp.h>
}
#endif

class Item_func :public Item_result_field
{
protected:
36
  Item **args, *tmp_arg[2];
37 38 39 40
  /*
    Allowed numbers of columns in result (usually 1, which means scalar value)
    0 means get this number from first argument
  */
unknown's avatar
unknown committed
41
  uint allowed_arg_cols;
unknown's avatar
unknown committed
42 43
public:
  uint arg_count;
44
  table_map used_tables_cache, not_null_tables_cache;
unknown's avatar
unknown committed
45 46 47
  bool const_item_cache;
  enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC,
		  GE_FUNC,GT_FUNC,FT_FUNC,
48
		  LIKE_FUNC,ISNULL_FUNC,ISNOTNULL_FUNC,
49 50
		  COND_AND_FUNC, COND_OR_FUNC, COND_XOR_FUNC,
                  BETWEEN, IN_FUNC, MULT_EQUAL_FUNC,
51
		  INTERVAL_FUNC, ISNOTNULLTEST_FUNC,
unknown's avatar
unknown committed
52 53 54 55
		  SP_EQUALS_FUNC, SP_DISJOINT_FUNC,SP_INTERSECTS_FUNC,
		  SP_TOUCHES_FUNC,SP_CROSSES_FUNC,SP_WITHIN_FUNC,
		  SP_CONTAINS_FUNC,SP_OVERLAPS_FUNC,
		  SP_STARTPOINT,SP_ENDPOINT,SP_EXTERIORRING,
56
		  SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN,
unknown's avatar
unknown committed
57 58
                  NOT_FUNC, NOT_ALL_FUNC,
                  NOW_FUNC, TRIG_COND_FUNC,
59
                  SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
60
                  EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC,
61
                  NEG_FUNC, GSYSVAR_FUNC };
62 63
  enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
                       OPTIMIZE_EQUAL };
unknown's avatar
unknown committed
64 65
  enum Type type() const { return FUNC_ITEM; }
  virtual enum Functype functype() const   { return UNKNOWN_FUNC; }
unknown's avatar
unknown committed
66 67
  Item_func(void):
    allowed_arg_cols(1), arg_count(0)
unknown's avatar
unknown committed
68
  {
69
    with_sum_func= 0;
unknown's avatar
unknown committed
70
  }
unknown's avatar
unknown committed
71 72
  Item_func(Item *a):
    allowed_arg_cols(1), arg_count(1)
unknown's avatar
unknown committed
73
  {
74
    args= tmp_arg;
75 76
    args[0]= a;
    with_sum_func= a->with_sum_func;
unknown's avatar
unknown committed
77
  }
unknown's avatar
unknown committed
78 79
  Item_func(Item *a,Item *b):
    allowed_arg_cols(1), arg_count(2)
unknown's avatar
unknown committed
80
  {
81
    args= tmp_arg;
82 83
    args[0]= a; args[1]= b;
    with_sum_func= a->with_sum_func || b->with_sum_func;
unknown's avatar
unknown committed
84
  }
unknown's avatar
unknown committed
85 86
  Item_func(Item *a,Item *b,Item *c):
    allowed_arg_cols(1)
unknown's avatar
unknown committed
87
  {
88 89
    arg_count= 0;
    if ((args= (Item**) sql_alloc(sizeof(Item*)*3)))
unknown's avatar
unknown committed
90
    {
91 92 93
      arg_count= 3;
      args[0]= a; args[1]= b; args[2]= c;
      with_sum_func= a->with_sum_func || b->with_sum_func || c->with_sum_func;
unknown's avatar
unknown committed
94 95
    }
  }
unknown's avatar
unknown committed
96 97
  Item_func(Item *a,Item *b,Item *c,Item *d):
    allowed_arg_cols(1)
unknown's avatar
unknown committed
98
  {
99 100
    arg_count= 0;
    if ((args= (Item**) sql_alloc(sizeof(Item*)*4)))
unknown's avatar
unknown committed
101
    {
102 103 104 105
      arg_count= 4;
      args[0]= a; args[1]= b; args[2]= c; args[3]= d;
      with_sum_func= a->with_sum_func || b->with_sum_func ||
	c->with_sum_func || d->with_sum_func;
unknown's avatar
unknown committed
106 107
    }
  }
unknown's avatar
unknown committed
108 109
  Item_func(Item *a,Item *b,Item *c,Item *d,Item* e):
    allowed_arg_cols(1)
unknown's avatar
unknown committed
110
  {
111 112
    arg_count= 5;
    if ((args= (Item**) sql_alloc(sizeof(Item*)*5)))
unknown's avatar
unknown committed
113
    {
114 115 116
      args[0]= a; args[1]= b; args[2]= c; args[3]= d; args[4]= e;
      with_sum_func= a->with_sum_func || b->with_sum_func ||
	c->with_sum_func || d->with_sum_func || e->with_sum_func ;
unknown's avatar
unknown committed
117 118 119
    }
  }
  Item_func(List<Item> &list);
120
  // Constructor used for Item_cond_and/or (see Item comment)
121
  Item_func(THD *thd, Item_func *item);
122
  bool fix_fields(THD *, Item **ref);
unknown's avatar
unknown committed
123
  table_map used_tables() const;
124
  table_map not_null_tables() const;
unknown's avatar
unknown committed
125
  void update_used_tables();
126
  bool eq(const Item *item, bool binary_cmp) const;
unknown's avatar
unknown committed
127 128 129 130 131
  virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; }
  virtual bool have_rev_func() const { return 0; }
  virtual Item *key_item() const { return args[0]; }
  virtual bool const_item() const { return const_item_cache; }
  inline Item **arguments() const { return args; }
132
  void set_arguments(List<Item> &list);
unknown's avatar
unknown committed
133 134
  inline uint argument_count() const { return arg_count; }
  inline void remove_arguments() { arg_count=0; }
135
  void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
136 137 138
  virtual void print(String *str, enum_query_type query_type);
  void print_op(String *str, enum_query_type query_type);
  void print_args(String *str, uint from, enum_query_type query_type);
unknown's avatar
unknown committed
139 140 141 142
  virtual void fix_num_length_and_dec();
  void count_only_length();
  void count_real_length();
  void count_decimal_length();
143
  inline bool get_arg0_date(MYSQL_TIME *ltime, uint fuzzy_date)
unknown's avatar
unknown committed
144
  {
145
    return (null_value=args[0]->get_date(ltime, fuzzy_date));
unknown's avatar
unknown committed
146
  }
147
  inline bool get_arg0_time(MYSQL_TIME *ltime)
unknown's avatar
unknown committed
148 149 150
  {
    return (null_value=args[0]->get_time(ltime));
  }
151
  bool is_null() { 
152
    update_null_value();
153 154
    return null_value; 
  }
unknown's avatar
unknown committed
155
  void signal_divide_by_null();
unknown's avatar
unknown committed
156
  friend class udf_handler;
157
  Field *tmp_table_field() { return result_field; }
158
  Field *tmp_table_field(TABLE *t_arg);
159
  Item *get_tmp_table_item(THD *thd);
unknown's avatar
unknown committed
160 161 162

  my_decimal *val_decimal(my_decimal *);

163 164
  bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems,
                        uint flags, int item_sep)
165
  {
166
    return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep);
167
  }
168 169 170
  bool agg_arg_charsets_for_string_result(DTCollation &c,
                                          Item **items, uint nitems,
                                          int item_sep= 1)
171
  {
172 173
    return agg_item_charsets_for_string_result(c, func_name(),
                                               items, nitems, item_sep);
174
  }
175 176 177
  bool agg_arg_charsets_for_comparison(DTCollation &c,
                                       Item **items, uint nitems,
                                       int item_sep= 1)
178
  {
179 180
    return agg_item_charsets_for_comparison(c, func_name(),
                                            items, nitems, item_sep);
181
  }
182 183 184 185
  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
  Item *transform(Item_transformer transformer, uchar *arg);
  Item* compile(Item_analyzer analyzer, uchar **arg_p,
                Item_transformer transformer, uchar *arg_t);
186 187
  void traverse_cond(Cond_traverser traverser,
                     void * arg, traverse_order order);
188
  bool is_expensive_processor(uchar *arg);
189
  virtual bool is_expensive() { return 0; }
190
  inline void raise_numeric_overflow(const char *type_name)
191
  {
192 193 194 195 196 197 198 199 200
    char buf[256];
    String str(buf, sizeof(buf), system_charset_info);
    str.length(0);
    print(&str, QT_ORDINARY);
    my_error(ER_DATA_OUT_OF_RANGE, MYF(0), type_name, str.c_ptr_safe());
  }
  inline double raise_float_overflow()
  {
    raise_numeric_overflow("DOUBLE");
201 202
    return 0.0;
  }
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
  inline longlong raise_integer_overflow()
  {
    raise_numeric_overflow(unsigned_flag ? "BIGINT UNSIGNED": "BIGINT");
    return 0;
  }
  inline int raise_decimal_overflow()
  {
    raise_numeric_overflow("DECIMAL");
    return E_DEC_OVERFLOW;
  }
  /**
     Throw an error if the input double number is not finite, i.e. is either
     +/-INF or NAN.
  */
  inline double check_float_overflow(double value)
  {
    return isfinite(value) ? value : raise_float_overflow();
  }
  /**
    Throw an error if the input BIGINT value represented by the
    (longlong value, bool unsigned flag) pair cannot be returned by the
    function, i.e. is not compatible with this Item's unsigned_flag.
  */
  inline longlong check_integer_overflow(longlong value, bool val_unsigned)
  {
    if ((unsigned_flag && !val_unsigned && value < 0) ||
        (!unsigned_flag && val_unsigned && (ulonglong) value > LONGLONG_MAX))
      return raise_integer_overflow();
    return value;
  }
  /**
     Throw an error if the error code of a DECIMAL operation is E_DEC_OVERFLOW.
  */
  inline int check_decimal_overflow(int error)
  {
    return (error == E_DEC_OVERFLOW) ? raise_decimal_overflow() : error;
  }
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
  bool has_timestamp_args()
  {
    DBUG_ASSERT(fixed == TRUE);
    for (uint i= 0; i < arg_count; i++)
    {
      if (args[i]->type() == Item::FIELD_ITEM &&
          args[i]->field_type() == MYSQL_TYPE_TIMESTAMP)
        return TRUE;
    }
    return FALSE;
  }
  /*
    We assume the result of any function that has a TIMESTAMP argument to be
    timezone-dependent, since a TIMESTAMP value in both numeric and string
    contexts is interpreted according to the current timezone.
    The only exception is UNIX_TIMESTAMP() which returns the internal
    representation of a TIMESTAMP argument verbatim, and thus does not depend on
    the timezone.
   */
  virtual bool is_timezone_dependent_processor(uchar *bool_arg)
  {
    return has_timestamp_args();
  }
263 264 265 266 267

  virtual bool find_function_processor (uchar *arg)
  {
    return functype() == *(Functype *) arg;
  }
unknown's avatar
unknown committed
268 269 270 271 272 273
};


class Item_real_func :public Item_func
{
public:
274 275 276 277
  Item_real_func() :Item_func() { collation.set_numeric(); }
  Item_real_func(Item *a) :Item_func(a) { collation.set_numeric(); }
  Item_real_func(Item *a,Item *b) :Item_func(a,b) { collation.set_numeric(); }
  Item_real_func(List<Item> &list) :Item_func(list) { collation.set_numeric(); }
unknown's avatar
unknown committed
278
  String *val_str(String*str);
279
  my_decimal *val_decimal(my_decimal *decimal_value);
280
  longlong val_int()
281
    { DBUG_ASSERT(fixed == 1); return (longlong) rint(val_real()); }
unknown's avatar
unknown committed
282
  enum Item_result result_type () const { return REAL_RESULT; }
unknown's avatar
unknown committed
283 284
  void fix_length_and_dec()
  { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); }
unknown's avatar
unknown committed
285 286
};

287

unknown's avatar
unknown committed
288
class Item_func_numhybrid: public Item_func
unknown's avatar
unknown committed
289
{
unknown's avatar
unknown committed
290
protected:
unknown's avatar
unknown committed
291 292
  Item_result hybrid_type;
public:
unknown's avatar
unknown committed
293
  Item_func_numhybrid(Item *a) :Item_func(a), hybrid_type(REAL_RESULT)
294
  { collation.set_numeric(); }
unknown's avatar
unknown committed
295
  Item_func_numhybrid(Item *a,Item *b)
unknown's avatar
unknown committed
296
    :Item_func(a,b), hybrid_type(REAL_RESULT)
297
  { collation.set_numeric(); }
unknown's avatar
unknown committed
298
  Item_func_numhybrid(List<Item> &list)
unknown's avatar
unknown committed
299
    :Item_func(list), hybrid_type(REAL_RESULT)
300
  { collation.set_numeric(); }
unknown's avatar
unknown committed
301

unknown's avatar
unknown committed
302
  enum Item_result result_type () const { return hybrid_type; }
unknown's avatar
unknown committed
303 304 305 306 307 308 309 310 311
  void fix_length_and_dec();
  void fix_num_length_and_dec();
  virtual void find_num_type()= 0; /* To be called from fix_length_and_dec */

  double val_real();
  longlong val_int();
  my_decimal *val_decimal(my_decimal *);
  String *val_str(String*str);

312 313 314 315 316 317
  /**
     @brief Performs the operation that this functions implements when the
     result type is INT.

     @return The result of the operation.
  */
unknown's avatar
unknown committed
318
  virtual longlong int_op()= 0;
319 320 321 322 323 324 325

  /**
     @brief Performs the operation that this functions implements when the
     result type is REAL.

     @return The result of the operation.
  */
unknown's avatar
unknown committed
326
  virtual double real_op()= 0;
327 328 329 330 331 332 333 334 335 336 337

  /**
     @brief Performs the operation that this functions implements when the
     result type is DECIMAL.

     @param A pointer where the DECIMAL value will be allocated.
     @return 
       - 0 If the result is NULL
       - The same pointer it was given, with the area initialized to the
         result of the operation.
  */
unknown's avatar
unknown committed
338
  virtual my_decimal *decimal_op(my_decimal *)= 0;
339 340 341 342 343 344 345

  /**
     @brief Performs the operation that this functions implements when the
     result type is a string type.

     @return The result of the operation.
  */
unknown's avatar
unknown committed
346
  virtual String *str_op(String *)= 0;
347
  bool is_null() { update_null_value(); return null_value; }
unknown's avatar
unknown committed
348 349
};

unknown's avatar
unknown committed
350 351 352 353 354 355
/* function where type of result detected by first argument */
class Item_func_num1: public Item_func_numhybrid
{
public:
  Item_func_num1(Item *a) :Item_func_numhybrid(a) {}
  Item_func_num1(Item *a, Item *b) :Item_func_numhybrid(a, b) {}
unknown's avatar
unknown committed
356

unknown's avatar
unknown committed
357 358
  void fix_num_length_and_dec();
  void find_num_type();
unknown's avatar
unknown committed
359
  String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
unknown's avatar
unknown committed
360
};
unknown's avatar
unknown committed
361

unknown's avatar
unknown committed
362 363 364

/* Base class for operations like '+', '-', '*' */
class Item_num_op :public Item_func_numhybrid
unknown's avatar
unknown committed
365 366
{
 public:
unknown's avatar
unknown committed
367 368
  Item_num_op(Item *a,Item *b) :Item_func_numhybrid(a, b) {}
  virtual void result_precision()= 0;
369 370 371 372 373 374

  virtual inline void print(String *str, enum_query_type query_type)
  {
    print_op(str, query_type);
  }

unknown's avatar
unknown committed
375
  void find_num_type();
unknown's avatar
unknown committed
376
  String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
unknown's avatar
unknown committed
377 378 379 380 381 382
};


class Item_int_func :public Item_func
{
public:
383 384 385 386 387 388
  Item_int_func() :Item_func()
  { collation.set_numeric(); fix_char_length(21); }
  Item_int_func(Item *a) :Item_func(a)
  { collation.set_numeric(); fix_char_length(21); }
  Item_int_func(Item *a,Item *b) :Item_func(a,b)
  { collation.set_numeric(); fix_char_length(21); }
unknown's avatar
unknown committed
389
  Item_int_func(Item *a,Item *b,Item *c) :Item_func(a,b,c)
390 391 392 393 394
  { collation.set_numeric(); fix_char_length(21); }
  Item_int_func(List<Item> &list) :Item_func(list)
  { collation.set_numeric(); fix_char_length(21); }
  Item_int_func(THD *thd, Item_int_func *item) :Item_func(thd, item)
  { collation.set_numeric(); }
395
  double val_real();
unknown's avatar
unknown committed
396 397
  String *val_str(String*str);
  enum Item_result result_type () const { return INT_RESULT; }
unknown's avatar
unknown committed
398
  void fix_length_and_dec() {}
unknown's avatar
unknown committed
399 400
};

401

402 403 404 405 406
class Item_func_connection_id :public Item_int_func
{
  longlong value;

public:
407
  Item_func_connection_id() {}
408 409 410 411 412 413 414
  const char *func_name() const { return "connection_id"; }
  void fix_length_and_dec();
  bool fix_fields(THD *thd, Item **ref);
  longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
};


415 416 417 418
class Item_func_signed :public Item_int_func
{
public:
  Item_func_signed(Item *a) :Item_int_func(a) {}
419
  const char *func_name() const { return "cast_as_signed"; }
420 421
  longlong val_int();
  longlong val_int_from_str(int *error);
422
  void fix_length_and_dec()
423
  { fix_char_length(args[0]->max_char_length()); unsigned_flag=0; }
424
  virtual void print(String *str, enum_query_type query_type);
unknown's avatar
unknown committed
425
  uint decimal_precision() const { return args[0]->decimal_precision(); }
426 427
};

428

unknown's avatar
unknown committed
429
class Item_func_unsigned :public Item_func_signed
430 431
{
public:
unknown's avatar
unknown committed
432
  Item_func_unsigned(Item *a) :Item_func_signed(a) {}
433
  const char *func_name() const { return "cast_as_unsigned"; }
434
  void fix_length_and_dec()
435
  {
436 437
    fix_char_length(min(args[0]->max_char_length(),
                        DECIMAL_MAX_PRECISION + 2));
438 439
    unsigned_flag=1;
  }
440
  longlong val_int();
441
  virtual void print(String *str, enum_query_type query_type);
442 443 444
};


unknown's avatar
unknown committed
445
class Item_decimal_typecast :public Item_func
unknown's avatar
unknown committed
446
{
unknown's avatar
unknown committed
447
  my_decimal decimal_value;
unknown's avatar
unknown committed
448
public:
unknown's avatar
unknown committed
449 450 451
  Item_decimal_typecast(Item *a, int len, int dec) :Item_func(a)
  {
    decimals= dec;
452 453 454
    collation.set_numeric();
    fix_char_length(my_decimal_precision_to_length_no_truncation(len, dec,
                                                                 unsigned_flag));
unknown's avatar
unknown committed
455 456
  }
  String *val_str(String *str);
457
  double val_real();
unknown's avatar
unknown committed
458
  longlong val_int();
unknown's avatar
unknown committed
459 460
  my_decimal *val_decimal(my_decimal*);
  enum Item_result result_type () const { return DECIMAL_RESULT; }
unknown's avatar
unknown committed
461
  enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
unknown's avatar
unknown committed
462
  void fix_length_and_dec() {};
463
  const char *func_name() const { return "decimal_typecast"; }
464
  virtual void print(String *str, enum_query_type query_type);
unknown's avatar
unknown committed
465 466 467 468 469 470 471 472
};


class Item_func_additive_op :public Item_num_op
{
public:
  Item_func_additive_op(Item *a,Item *b) :Item_num_op(a,b) {}
  void result_precision();
473
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
unknown's avatar
unknown committed
474 475 476 477 478 479 480 481 482 483 484
};


class Item_func_plus :public Item_func_additive_op
{
public:
  Item_func_plus(Item *a,Item *b) :Item_func_additive_op(a,b) {}
  const char *func_name() const { return "+"; }
  longlong int_op();
  double real_op();
  my_decimal *decimal_op(my_decimal *);
unknown's avatar
unknown committed
485 486
};

unknown's avatar
unknown committed
487
class Item_func_minus :public Item_func_additive_op
unknown's avatar
unknown committed
488 489
{
public:
unknown's avatar
unknown committed
490
  Item_func_minus(Item *a,Item *b) :Item_func_additive_op(a,b) {}
unknown's avatar
unknown committed
491
  const char *func_name() const { return "-"; }
unknown's avatar
unknown committed
492 493 494
  longlong int_op();
  double real_op();
  my_decimal *decimal_op(my_decimal *);
495
  void fix_length_and_dec();
unknown's avatar
unknown committed
496 497
};

498

unknown's avatar
unknown committed
499 500 501 502 503
class Item_func_mul :public Item_num_op
{
public:
  Item_func_mul(Item *a,Item *b) :Item_num_op(a,b) {}
  const char *func_name() const { return "*"; }
unknown's avatar
unknown committed
504 505 506 507
  longlong int_op();
  double real_op();
  my_decimal *decimal_op(my_decimal *);
  void result_precision();
508
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
unknown's avatar
unknown committed
509 510 511 512 513 514
};


class Item_func_div :public Item_num_op
{
public:
unknown's avatar
unknown committed
515
  uint prec_increment;
unknown's avatar
unknown committed
516
  Item_func_div(Item *a,Item *b) :Item_num_op(a,b) {}
517
  longlong int_op() { DBUG_ASSERT(0); return 0; }
unknown's avatar
unknown committed
518 519
  double real_op();
  my_decimal *decimal_op(my_decimal *);
unknown's avatar
unknown committed
520 521
  const char *func_name() const { return "/"; }
  void fix_length_and_dec();
unknown's avatar
unknown committed
522
  void result_precision();
unknown's avatar
unknown committed
523 524 525
};


526
class Item_func_int_div :public Item_int_func
527 528
{
public:
529
  Item_func_int_div(Item *a,Item *b) :Item_int_func(a,b)
unknown's avatar
unknown committed
530
  {}
531 532 533
  longlong val_int();
  const char *func_name() const { return "DIV"; }
  void fix_length_and_dec();
534 535 536 537 538 539

  virtual inline void print(String *str, enum_query_type query_type)
  {
    print_op(str, query_type);
  }

540
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
541 542 543
};


unknown's avatar
unknown committed
544 545 546 547
class Item_func_mod :public Item_num_op
{
public:
  Item_func_mod(Item *a,Item *b) :Item_num_op(a,b) {}
unknown's avatar
unknown committed
548 549 550
  longlong int_op();
  double real_op();
  my_decimal *decimal_op(my_decimal *);
unknown's avatar
unknown committed
551
  const char *func_name() const { return "%"; }
unknown's avatar
unknown committed
552
  void result_precision();
unknown's avatar
unknown committed
553
  void fix_length_and_dec();
554
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
unknown's avatar
unknown committed
555 556 557
};


558
class Item_func_neg :public Item_func_num1
unknown's avatar
unknown committed
559 560
{
public:
561
  Item_func_neg(Item *a) :Item_func_num1(a) {}
unknown's avatar
unknown committed
562 563 564
  double real_op();
  longlong int_op();
  my_decimal *decimal_op(my_decimal *);
unknown's avatar
unknown committed
565
  const char *func_name() const { return "-"; }
566
  enum Functype functype() const   { return NEG_FUNC; }
567
  void fix_length_and_dec();
unknown's avatar
unknown committed
568
  void fix_num_length_and_dec();
unknown's avatar
unknown committed
569
  uint decimal_precision() const { return args[0]->decimal_precision(); }
unknown's avatar
unknown committed
570
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
unknown's avatar
unknown committed
571 572 573
};


unknown's avatar
unknown committed
574
class Item_func_abs :public Item_func_num1
unknown's avatar
unknown committed
575 576
{
public:
unknown's avatar
unknown committed
577 578 579 580
  Item_func_abs(Item *a) :Item_func_num1(a) {}
  double real_op();
  longlong int_op();
  my_decimal *decimal_op(my_decimal *);
unknown's avatar
unknown committed
581 582
  const char *func_name() const { return "abs"; }
  void fix_length_and_dec();
unknown's avatar
unknown committed
583
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
unknown's avatar
unknown committed
584 585
};

unknown's avatar
unknown committed
586
// A class to handle logarithmic and trigonometric functions
unknown's avatar
unknown committed
587 588 589 590 591 592 593 594

class Item_dec_func :public Item_real_func
{
 public:
  Item_dec_func(Item *a) :Item_real_func(a) {}
  Item_dec_func(Item *a,Item *b) :Item_real_func(a,b) {}
  void fix_length_and_dec()
  {
595
    decimals=NOT_FIXED_DEC; max_length=float_length(decimals);
unknown's avatar
unknown committed
596 597 598 599 600 601 602 603
    maybe_null=1;
  }
};

class Item_func_exp :public Item_dec_func
{
public:
  Item_func_exp(Item *a) :Item_dec_func(a) {}
604
  double val_real();
unknown's avatar
unknown committed
605 606 607
  const char *func_name() const { return "exp"; }
};

608 609 610 611 612

class Item_func_ln :public Item_dec_func
{
public:
  Item_func_ln(Item *a) :Item_dec_func(a) {}
613
  double val_real();
614 615 616 617
  const char *func_name() const { return "ln"; }
};


unknown's avatar
unknown committed
618 619 620 621
class Item_func_log :public Item_dec_func
{
public:
  Item_func_log(Item *a) :Item_dec_func(a) {}
622
  Item_func_log(Item *a,Item *b) :Item_dec_func(a,b) {}
623
  double val_real();
unknown's avatar
unknown committed
624 625 626 627
  const char *func_name() const { return "log"; }
};


628 629 630 631
class Item_func_log2 :public Item_dec_func
{
public:
  Item_func_log2(Item *a) :Item_dec_func(a) {}
632
  double val_real();
633 634 635 636
  const char *func_name() const { return "log2"; }
};


unknown's avatar
unknown committed
637 638 639 640
class Item_func_log10 :public Item_dec_func
{
public:
  Item_func_log10(Item *a) :Item_dec_func(a) {}
641
  double val_real();
unknown's avatar
unknown committed
642 643 644 645 646 647 648 649
  const char *func_name() const { return "log10"; }
};


class Item_func_sqrt :public Item_dec_func
{
public:
  Item_func_sqrt(Item *a) :Item_dec_func(a) {}
650
  double val_real();
unknown's avatar
unknown committed
651 652 653 654 655 656 657 658
  const char *func_name() const { return "sqrt"; }
};


class Item_func_pow :public Item_dec_func
{
public:
  Item_func_pow(Item *a,Item *b) :Item_dec_func(a,b) {}
659
  double val_real();
unknown's avatar
unknown committed
660 661 662 663 664 665
  const char *func_name() const { return "pow"; }
};


class Item_func_acos :public Item_dec_func
{
666
public:
unknown's avatar
unknown committed
667
  Item_func_acos(Item *a) :Item_dec_func(a) {}
668
  double val_real();
unknown's avatar
unknown committed
669 670 671 672 673
  const char *func_name() const { return "acos"; }
};

class Item_func_asin :public Item_dec_func
{
674
public:
unknown's avatar
unknown committed
675
  Item_func_asin(Item *a) :Item_dec_func(a) {}
676
  double val_real();
unknown's avatar
unknown committed
677 678 679 680 681
  const char *func_name() const { return "asin"; }
};

class Item_func_atan :public Item_dec_func
{
682
public:
unknown's avatar
unknown committed
683 684
  Item_func_atan(Item *a) :Item_dec_func(a) {}
  Item_func_atan(Item *a,Item *b) :Item_dec_func(a,b) {}
685
  double val_real();
unknown's avatar
unknown committed
686 687 688 689 690
  const char *func_name() const { return "atan"; }
};

class Item_func_cos :public Item_dec_func
{
691
public:
unknown's avatar
unknown committed
692
  Item_func_cos(Item *a) :Item_dec_func(a) {}
693
  double val_real();
unknown's avatar
unknown committed
694 695 696 697 698
  const char *func_name() const { return "cos"; }
};

class Item_func_sin :public Item_dec_func
{
699
public:
unknown's avatar
unknown committed
700
  Item_func_sin(Item *a) :Item_dec_func(a) {}
701
  double val_real();
unknown's avatar
unknown committed
702 703 704 705 706
  const char *func_name() const { return "sin"; }
};

class Item_func_tan :public Item_dec_func
{
707
public:
unknown's avatar
unknown committed
708
  Item_func_tan(Item *a) :Item_dec_func(a) {}
709
  double val_real();
unknown's avatar
unknown committed
710 711 712
  const char *func_name() const { return "tan"; }
};

713 714 715 716 717 718 719 720
class Item_func_cot :public Item_dec_func
{
public:
  Item_func_cot(Item *a) :Item_dec_func(a) {}
  double val_real();
  const char *func_name() const { return "cot"; }
};

unknown's avatar
unknown committed
721 722 723 724 725 726 727 728
class Item_func_integer :public Item_int_func
{
public:
  inline Item_func_integer(Item *a) :Item_int_func(a) {}
  void fix_length_and_dec();
};


unknown's avatar
unknown committed
729 730 731 732 733 734 735 736 737 738
class Item_func_int_val :public Item_func_num1
{
public:
  Item_func_int_val(Item *a) :Item_func_num1(a) {}
  void fix_num_length_and_dec();
  void find_num_type();
};


class Item_func_ceiling :public Item_func_int_val
unknown's avatar
unknown committed
739 740
{
public:
unknown's avatar
unknown committed
741
  Item_func_ceiling(Item *a) :Item_func_int_val(a) {}
unknown's avatar
unknown committed
742
  const char *func_name() const { return "ceiling"; }
unknown's avatar
unknown committed
743 744 745
  longlong int_op();
  double real_op();
  my_decimal *decimal_op(my_decimal *);
unknown's avatar
unknown committed
746
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
unknown's avatar
unknown committed
747 748
};

unknown's avatar
unknown committed
749 750

class Item_func_floor :public Item_func_int_val
unknown's avatar
unknown committed
751 752
{
public:
unknown's avatar
unknown committed
753
  Item_func_floor(Item *a) :Item_func_int_val(a) {}
unknown's avatar
unknown committed
754
  const char *func_name() const { return "floor"; }
unknown's avatar
unknown committed
755 756 757
  longlong int_op();
  double real_op();
  my_decimal *decimal_op(my_decimal *);
unknown's avatar
unknown committed
758
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
unknown's avatar
unknown committed
759 760 761 762
};

/* This handles round and truncate */

unknown's avatar
unknown committed
763
class Item_func_round :public Item_func_num1
unknown's avatar
unknown committed
764 765 766
{
  bool truncate;
public:
unknown's avatar
unknown committed
767 768
  Item_func_round(Item *a, Item *b, bool trunc_arg)
    :Item_func_num1(a,b), truncate(trunc_arg) {}
unknown's avatar
unknown committed
769
  const char *func_name() const { return truncate ? "truncate" : "round"; }
unknown's avatar
unknown committed
770 771 772
  double real_op();
  longlong int_op();
  my_decimal *decimal_op(my_decimal *);
unknown's avatar
unknown committed
773
  void fix_length_and_dec();
unknown's avatar
unknown committed
774 775 776 777 778
};


class Item_func_rand :public Item_real_func
{
779
  struct rand_struct *rand;
780
  bool first_eval; // TRUE if val_real() is called 1st time
unknown's avatar
unknown committed
781
public:
782
  Item_func_rand(Item *a) :Item_real_func(a), rand(0), first_eval(TRUE) {}
783
  Item_func_rand()	  :Item_real_func() {}
784
  double val_real();
unknown's avatar
unknown committed
785 786
  const char *func_name() const { return "rand"; }
  bool const_item() const { return 0; }
unknown's avatar
unknown committed
787
  void update_used_tables();
788
  bool fix_fields(THD *thd, Item **ref);
789
  void cleanup() { first_eval= TRUE; Item_real_func::cleanup(); }
790 791
private:
  void seed_random (Item * val);  
unknown's avatar
unknown committed
792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807
};


class Item_func_sign :public Item_int_func
{
public:
  Item_func_sign(Item *a) :Item_int_func(a) {}
  const char *func_name() const { return "sign"; }
  longlong val_int();
};


class Item_func_units :public Item_real_func
{
  char *name;
  double mul,add;
808
public:
unknown's avatar
unknown committed
809 810
  Item_func_units(char *name_arg,Item *a,double mul_arg,double add_arg)
    :Item_real_func(a),name(name_arg),mul(mul_arg),add(add_arg) {}
811
  double val_real();
unknown's avatar
unknown committed
812
  const char *func_name() const { return name; }
unknown's avatar
unknown committed
813 814
  void fix_length_and_dec()
  { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); }
unknown's avatar
unknown committed
815 816 817 818 819 820 821 822
};


class Item_func_min_max :public Item_func
{
  Item_result cmp_type;
  String tmp_value;
  int cmp_sign;
823 824 825 826 827
  /* TRUE <=> arguments should be compared in the DATETIME context. */
  bool compare_as_dates;
  /* An item used for issuing warnings while string to DATETIME conversion. */
  Item *datetime_item;
  THD *thd;
828 829
protected:
  enum_field_types cached_field_type;
unknown's avatar
unknown committed
830 831
public:
  Item_func_min_max(List<Item> &list,int cmp_sign_arg) :Item_func(list),
832 833
    cmp_type(INT_RESULT), cmp_sign(cmp_sign_arg), compare_as_dates(FALSE),
    datetime_item(0) {}
834
  double val_real();
unknown's avatar
unknown committed
835 836
  longlong val_int();
  String *val_str(String *);
unknown's avatar
unknown committed
837
  my_decimal *val_decimal(my_decimal *);
unknown's avatar
unknown committed
838 839
  void fix_length_and_dec();
  enum Item_result result_type () const { return cmp_type; }
840
  bool result_as_longlong() { return compare_as_dates; };
841
  uint cmp_datetimes(ulonglong *value);
842
  enum_field_types field_type() const { return cached_field_type; }
unknown's avatar
unknown committed
843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858
};

class Item_func_min :public Item_func_min_max
{
public:
  Item_func_min(List<Item> &list) :Item_func_min_max(list,1) {}
  const char *func_name() const { return "least"; }
};

class Item_func_max :public Item_func_min_max
{
public:
  Item_func_max(List<Item> &list) :Item_func_min_max(list,-1) {}
  const char *func_name() const { return "greatest"; }
};

unknown's avatar
unknown committed
859

860 861 862 863 864 865 866 867 868
/* 
  Objects of this class are used for ROLLUP queries to wrap up 
  each constant item referred to in GROUP BY list. 
*/

class Item_func_rollup_const :public Item_func
{
public:
  Item_func_rollup_const(Item *a) :Item_func(a)
unknown's avatar
unknown committed
869 870 871 872 873
  {
    name= a->name;
    name_length= a->name_length;
  }
  double val_real() { return args[0]->val_real(); }
874 875
  longlong val_int() { return args[0]->val_int(); }
  String *val_str(String *str) { return args[0]->val_str(str); }
unknown's avatar
unknown committed
876
  my_decimal *val_decimal(my_decimal *dec) { return args[0]->val_decimal(dec); }
877 878 879 880 881 882 883 884
  const char *func_name() const { return "rollup_const"; }
  bool const_item() const { return 0; }
  Item_result result_type() const { return args[0]->result_type(); }
  void fix_length_and_dec()
  {
    collation= args[0]->collation;
    max_length= args[0]->max_length;
    decimals=args[0]->decimals; 
885
    /* The item could be a NULL constant. */
886
    null_value= args[0]->is_null();
887 888 889 890
  }
};


unknown's avatar
unknown committed
891 892 893 894 895 896 897 898 899 900
class Item_func_length :public Item_int_func
{
  String value;
public:
  Item_func_length(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "length"; }
  void fix_length_and_dec() { max_length=10; }
};

unknown's avatar
unknown committed
901 902 903 904
class Item_func_bit_length :public Item_func_length
{
public:
  Item_func_bit_length(Item *a) :Item_func_length(a) {}
905 906
  longlong val_int()
    { DBUG_ASSERT(fixed == 1); return Item_func_length::val_int()*8; }
unknown's avatar
unknown committed
907 908 909
  const char *func_name() const { return "bit_length"; }
};

unknown's avatar
unknown committed
910 911 912 913 914 915 916 917 918 919
class Item_func_char_length :public Item_int_func
{
  String value;
public:
  Item_func_char_length(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "char_length"; }
  void fix_length_and_dec() { max_length=10; }
};

unknown's avatar
unknown committed
920 921 922 923 924 925
class Item_func_coercibility :public Item_int_func
{
public:
  Item_func_coercibility(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "coercibility"; }
926 927
  void fix_length_and_dec() { max_length=10; maybe_null= 0; }
  table_map not_null_tables() const { return 0; }
unknown's avatar
unknown committed
928 929
};

unknown's avatar
unknown committed
930 931 932
class Item_func_locate :public Item_int_func
{
  String value1,value2;
933
  DTCollation cmp_collation;
unknown's avatar
unknown committed
934 935 936 937 938
public:
  Item_func_locate(Item *a,Item *b) :Item_int_func(a,b) {}
  Item_func_locate(Item *a,Item *b,Item *c) :Item_int_func(a,b,c) {}
  const char *func_name() const { return "locate"; }
  longlong val_int();
939
  void fix_length_and_dec();
940
  virtual void print(String *str, enum_query_type query_type);
unknown's avatar
unknown committed
941 942 943 944 945 946
};


class Item_func_field :public Item_int_func
{
  String value,tmp;
947 948
  Item_result cmp_type;
  DTCollation cmp_collation;
unknown's avatar
unknown committed
949
public:
950
  Item_func_field(List<Item> &list) :Item_int_func(list) {}
unknown's avatar
unknown committed
951 952
  longlong val_int();
  const char *func_name() const { return "field"; }
953
  void fix_length_and_dec();
unknown's avatar
unknown committed
954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980
};


class Item_func_ascii :public Item_int_func
{
  String value;
public:
  Item_func_ascii(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "ascii"; }
  void fix_length_and_dec() { max_length=3; }
};

class Item_func_ord :public Item_int_func
{
  String value;
public:
  Item_func_ord(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "ord"; }
};

class Item_func_find_in_set :public Item_int_func
{
  String value,value2;
  uint enum_value;
  ulonglong enum_bit;
981
  DTCollation cmp_collation;
unknown's avatar
unknown committed
982 983 984 985 986 987 988
public:
  Item_func_find_in_set(Item *a,Item *b) :Item_int_func(a,b),enum_value(0) {}
  longlong val_int();
  const char *func_name() const { return "find_in_set"; }
  void fix_length_and_dec();
};

989
/* Base class for all bit functions: '~', '|', '^', '&', '>>', '<<' */
unknown's avatar
unknown committed
990

991
class Item_func_bit: public Item_int_func
unknown's avatar
unknown committed
992 993
{
public:
994 995 996
  Item_func_bit(Item *a, Item *b) :Item_int_func(a, b) {}
  Item_func_bit(Item *a) :Item_int_func(a) {}
  void fix_length_and_dec() { unsigned_flag= 1; }
997 998 999 1000 1001

  virtual inline void print(String *str, enum_query_type query_type)
  {
    print_op(str, query_type);
  }
1002 1003 1004 1005 1006 1007
};

class Item_func_bit_or :public Item_func_bit
{
public:
  Item_func_bit_or(Item *a, Item *b) :Item_func_bit(a, b) {}
unknown's avatar
unknown committed
1008 1009 1010 1011
  longlong val_int();
  const char *func_name() const { return "|"; }
};

1012
class Item_func_bit_and :public Item_func_bit
unknown's avatar
unknown committed
1013 1014
{
public:
1015
  Item_func_bit_and(Item *a, Item *b) :Item_func_bit(a, b) {}
unknown's avatar
unknown committed
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025
  longlong val_int();
  const char *func_name() const { return "&"; }
};

class Item_func_bit_count :public Item_int_func
{
public:
  Item_func_bit_count(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "bit_count"; }
unknown's avatar
unknown committed
1026
  void fix_length_and_dec() { max_length=2; }
unknown's avatar
unknown committed
1027 1028
};

1029
class Item_func_shift_left :public Item_func_bit
unknown's avatar
unknown committed
1030 1031
{
public:
1032
  Item_func_shift_left(Item *a, Item *b) :Item_func_bit(a, b) {}
unknown's avatar
unknown committed
1033 1034 1035 1036
  longlong val_int();
  const char *func_name() const { return "<<"; }
};

1037
class Item_func_shift_right :public Item_func_bit
unknown's avatar
unknown committed
1038 1039
{
public:
1040
  Item_func_shift_right(Item *a, Item *b) :Item_func_bit(a, b) {}
unknown's avatar
unknown committed
1041 1042 1043 1044
  longlong val_int();
  const char *func_name() const { return ">>"; }
};

1045
class Item_func_bit_neg :public Item_func_bit
unknown's avatar
unknown committed
1046 1047
{
public:
1048
  Item_func_bit_neg(Item *a) :Item_func_bit(a) {}
unknown's avatar
unknown committed
1049 1050
  longlong val_int();
  const char *func_name() const { return "~"; }
1051 1052 1053 1054 1055

  virtual inline void print(String *str, enum_query_type query_type)
  {
    Item_func::print(str, query_type);
  }
unknown's avatar
unknown committed
1056 1057
};

unknown's avatar
unknown committed
1058

1059
class Item_func_last_insert_id :public Item_int_func
unknown's avatar
unknown committed
1060 1061
{
public:
1062 1063
  Item_func_last_insert_id() :Item_int_func() {}
  Item_func_last_insert_id(Item *a) :Item_int_func(a) {}
unknown's avatar
unknown committed
1064 1065
  longlong val_int();
  const char *func_name() const { return "last_insert_id"; }
unknown's avatar
unknown committed
1066 1067 1068 1069 1070
  void fix_length_and_dec()
  {
    if (arg_count)
      max_length= args[0]->max_length;
  }
1071
  bool fix_fields(THD *thd, Item **ref);
unknown's avatar
unknown committed
1072 1073
};

1074

unknown's avatar
unknown committed
1075 1076
class Item_func_benchmark :public Item_int_func
{
1077
public:
1078 1079
  Item_func_benchmark(Item *count_expr, Item *expr)
    :Item_int_func(count_expr, expr)
unknown's avatar
unknown committed
1080 1081 1082
  {}
  longlong val_int();
  const char *func_name() const { return "benchmark"; }
unknown's avatar
unknown committed
1083
  void fix_length_and_dec() { max_length=1; maybe_null=0; }
1084
  virtual void print(String *str, enum_query_type query_type);
unknown's avatar
unknown committed
1085 1086 1087
};


1088 1089 1090 1091
class Item_func_sleep :public Item_int_func
{
public:
  Item_func_sleep(Item *a) :Item_int_func(a) {}
1092
  bool const_item() const { return 0; }
1093
  const char *func_name() const { return "sleep"; }
1094 1095 1096 1097 1098
  void update_used_tables()
  {
    Item_int_func::update_used_tables();
    used_tables_cache|= RAND_TABLE_BIT;
  }
1099 1100 1101 1102 1103
  longlong val_int();
};



unknown's avatar
unknown committed
1104 1105 1106 1107
#ifdef HAVE_DLOPEN

class Item_udf_func :public Item_func
{
1108
protected:
unknown's avatar
unknown committed
1109 1110 1111
  udf_handler udf;

public:
1112 1113
  Item_udf_func(udf_func *udf_arg)
    :Item_func(), udf(udf_arg) {}
unknown's avatar
unknown committed
1114 1115 1116
  Item_udf_func(udf_func *udf_arg, List<Item> &list)
    :Item_func(list), udf(udf_arg) {}
  const char *func_name() const { return udf.name(); }
1117
  enum Functype functype() const   { return UDF_FUNC; }
1118
  bool fix_fields(THD *thd, Item **ref)
unknown's avatar
unknown committed
1119
  {
1120
    DBUG_ASSERT(fixed == 0);
1121
    bool res= udf.fix_fields(thd, this, arg_count, args);
unknown's avatar
unknown committed
1122 1123
    used_tables_cache= udf.used_tables_cache;
    const_item_cache= udf.const_item_cache;
1124
    fixed= 1;
unknown's avatar
unknown committed
1125 1126
    return res;
  }
1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176
  void update_used_tables() 
  {
    /*
      TODO: Make a member in UDF_INIT and return if a UDF is deterministic or
      not.
      Currently UDF_INIT has a member (const_item) that is an in/out 
      parameter to the init() call.
      The code in udf_handler::fix_fields also duplicates the arguments 
      handling code in Item_func::fix_fields().
      
      The lack of information if a UDF is deterministic makes writing
      a correct update_used_tables() for UDFs impossible.
      One solution to this would be :
       - Add a is_deterministic member of UDF_INIT
       - (optionally) deprecate the const_item member of UDF_INIT
       - Take away the duplicate code from udf_handler::fix_fields() and
         make Item_udf_func call Item_func::fix_fields() to process its 
         arguments as for any other function.
       - Store the deterministic flag returned by <udf>_init into the 
       udf_handler. 
       - Don't implement Item_udf_func::fix_fields, implement
       Item_udf_func::fix_length_and_dec() instead (similar to non-UDF
       functions).
       - Override Item_func::update_used_tables to call 
       Item_func::update_used_tables() and add a RAND_TABLE_BIT to the 
       result of Item_func::update_used_tables() if the UDF is 
       non-deterministic.
       - (optionally) rename RAND_TABLE_BIT to NONDETERMINISTIC_BIT to
       better describe its usage.
       
      The above would require a change of the UDF API.
      Until that change is done here's how the current code works:
      We call Item_func::update_used_tables() only when we know that
      the function depends on real non-const tables and is deterministic.
      This can be done only because we know that the optimizer will
      call update_used_tables() only when there's possibly a new const
      table. So update_used_tables() can only make a Item_func more
      constant than it is currently.
      That's why we don't need to do anything if a function is guaranteed
      to return non-constant (it's non-deterministic) or is already a
      const.
    */  
    if ((used_tables_cache & ~PSEUDO_TABLE_BITS) && 
        !(used_tables_cache & RAND_TABLE_BIT))
    {
      Item_func::update_used_tables();
      if (!const_item_cache && !used_tables_cache)
        used_tables_cache= RAND_TABLE_BIT;
    }
  }
1177
  void cleanup();
unknown's avatar
unknown committed
1178
  Item_result result_type () const { return udf.result_type(); }
1179
  table_map not_null_tables() const { return 0; }
1180
  bool is_expensive() { return 1; }
1181
  virtual void print(String *str, enum_query_type query_type);
unknown's avatar
unknown committed
1182 1183 1184 1185 1186 1187
};


class Item_func_udf_float :public Item_udf_func
{
 public:
1188 1189 1190 1191 1192
  Item_func_udf_float(udf_func *udf_arg)
    :Item_udf_func(udf_arg) {}
  Item_func_udf_float(udf_func *udf_arg,
                      List<Item> &list)
    :Item_udf_func(udf_arg, list) {}
1193
  longlong val_int()
1194 1195
  {
    DBUG_ASSERT(fixed == 1);
1196
    return (longlong) rint(Item_func_udf_float::val_real());
1197
  }
unknown's avatar
unknown committed
1198 1199 1200 1201 1202 1203 1204 1205
  my_decimal *val_decimal(my_decimal *dec_buf)
  {
    double res=val_real();
    if (null_value)
      return NULL;
    double2my_decimal(E_DEC_FATAL_ERROR, res, dec_buf);
    return dec_buf;
  }
1206
  double val_real();
unknown's avatar
unknown committed
1207 1208 1209 1210 1211 1212 1213 1214
  String *val_str(String *str);
  void fix_length_and_dec() { fix_num_length_and_dec(); }
};


class Item_func_udf_int :public Item_udf_func
{
public:
1215 1216 1217 1218 1219
  Item_func_udf_int(udf_func *udf_arg)
    :Item_udf_func(udf_arg) {}
  Item_func_udf_int(udf_func *udf_arg,
                    List<Item> &list)
    :Item_udf_func(udf_arg, list) {}
unknown's avatar
unknown committed
1220
  longlong val_int();
1221
  double val_real() { return (double) Item_func_udf_int::val_int(); }
unknown's avatar
unknown committed
1222 1223
  String *val_str(String *str);
  enum Item_result result_type () const { return INT_RESULT; }
unknown's avatar
unknown committed
1224 1225 1226 1227 1228 1229 1230
  void fix_length_and_dec() { decimals= 0; max_length= 21; }
};


class Item_func_udf_decimal :public Item_udf_func
{
public:
1231 1232
  Item_func_udf_decimal(udf_func *udf_arg)
    :Item_udf_func(udf_arg) {}
unknown's avatar
unknown committed
1233
  Item_func_udf_decimal(udf_func *udf_arg, List<Item> &list)
1234
    :Item_udf_func(udf_arg, list) {}
unknown's avatar
unknown committed
1235 1236 1237 1238 1239 1240
  longlong val_int();
  double val_real();
  my_decimal *val_decimal(my_decimal *);
  String *val_str(String *str);
  enum Item_result result_type () const { return DECIMAL_RESULT; }
  void fix_length_and_dec();
unknown's avatar
unknown committed
1241 1242 1243 1244 1245 1246
};


class Item_func_udf_str :public Item_udf_func
{
public:
1247 1248
  Item_func_udf_str(udf_func *udf_arg)
    :Item_udf_func(udf_arg) {}
unknown's avatar
unknown committed
1249
  Item_func_udf_str(udf_func *udf_arg, List<Item> &list)
1250
    :Item_udf_func(udf_arg, list) {}
unknown's avatar
unknown committed
1251
  String *val_str(String *);
1252
  double val_real()
unknown's avatar
unknown committed
1253
  {
unknown's avatar
unknown committed
1254 1255 1256 1257 1258 1259
    int err_not_used;
    char *end_not_used;
    String *res;
    res= val_str(&str_value);
    return res ? my_strntod(res->charset(),(char*) res->ptr(), 
                            res->length(), &end_not_used, &err_not_used) : 0.0;
unknown's avatar
unknown committed
1260 1261 1262
  }
  longlong val_int()
  {
unknown's avatar
unknown committed
1263
    int err_not_used;
unknown's avatar
unknown committed
1264
    String *res;  res=val_str(&str_value);
unknown's avatar
unknown committed
1265 1266
    return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,
                             (char**) 0, &err_not_used) : (longlong) 0;
unknown's avatar
unknown committed
1267
  }
unknown's avatar
unknown committed
1268 1269 1270 1271 1272 1273 1274 1275
  my_decimal *val_decimal(my_decimal *dec_buf)
  {
    String *res=val_str(&str_value);
    if (!res)
      return NULL;
    string2my_decimal(E_DEC_FATAL_ERROR, res, dec_buf);
    return dec_buf;
  }
unknown's avatar
unknown committed
1276 1277 1278 1279 1280 1281 1282 1283 1284
  enum Item_result result_type () const { return STRING_RESULT; }
  void fix_length_and_dec();
};

#else /* Dummy functions to get sql_yacc.cc compiled */

class Item_func_udf_float :public Item_real_func
{
 public:
1285 1286 1287 1288
  Item_func_udf_float(udf_func *udf_arg)
    :Item_real_func() {}
  Item_func_udf_float(udf_func *udf_arg, List<Item> &list)
    :Item_real_func(list) {}
1289
  double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; }
unknown's avatar
unknown committed
1290 1291 1292 1293 1294 1295
};


class Item_func_udf_int :public Item_int_func
{
public:
1296 1297 1298 1299
  Item_func_udf_int(udf_func *udf_arg)
    :Item_int_func() {}
  Item_func_udf_int(udf_func *udf_arg, List<Item> &list)
    :Item_int_func(list) {}
1300
  longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; }
unknown's avatar
unknown committed
1301 1302 1303
};


unknown's avatar
unknown committed
1304 1305 1306
class Item_func_udf_decimal :public Item_int_func
{
public:
1307 1308 1309 1310
  Item_func_udf_decimal(udf_func *udf_arg)
    :Item_int_func() {}
  Item_func_udf_decimal(udf_func *udf_arg, List<Item> &list)
    :Item_int_func(list) {}
unknown's avatar
unknown committed
1311 1312 1313 1314
  my_decimal *val_decimal(my_decimal *) { DBUG_ASSERT(fixed == 1); return 0; }
};


unknown's avatar
unknown committed
1315 1316 1317
class Item_func_udf_str :public Item_func
{
public:
1318 1319 1320 1321
  Item_func_udf_str(udf_func *udf_arg)
    :Item_func() {}
  Item_func_udf_str(udf_func *udf_arg, List<Item> &list)
    :Item_func(list) {}
1322 1323
  String *val_str(String *)
    { DBUG_ASSERT(fixed == 1); null_value=1; return 0; }
1324
  double val_real() { DBUG_ASSERT(fixed == 1); null_value= 1; return 0.0; }
1325
  longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; }
unknown's avatar
unknown committed
1326 1327 1328 1329 1330 1331 1332 1333 1334 1335
  enum Item_result result_type () const { return STRING_RESULT; }
  void fix_length_and_dec() { maybe_null=1; max_length=0; }
};

#endif /* HAVE_DLOPEN */

/*
** User level locks
*/

1336
class User_level_lock;
unknown's avatar
unknown committed
1337
void item_user_lock_init(void);
1338
void item_user_lock_release(User_level_lock *ull);
unknown's avatar
unknown committed
1339 1340 1341 1342 1343 1344 1345 1346 1347
void item_user_lock_free(void);

class Item_func_get_lock :public Item_int_func
{
  String value;
 public:
  Item_func_get_lock(Item *a,Item *b) :Item_int_func(a,b) {}
  longlong val_int();
  const char *func_name() const { return "get_lock"; }
unknown's avatar
unknown committed
1348
  void fix_length_and_dec() { max_length=1; maybe_null=1;}
unknown's avatar
unknown committed
1349 1350 1351 1352 1353
};

class Item_func_release_lock :public Item_int_func
{
  String value;
1354
public:
unknown's avatar
unknown committed
1355 1356 1357
  Item_func_release_lock(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "release_lock"; }
unknown's avatar
unknown committed
1358
  void fix_length_and_dec() { max_length=1; maybe_null=1;}
unknown's avatar
unknown committed
1359 1360
};

unknown's avatar
unknown committed
1361 1362 1363 1364 1365
/* replication functions */

class Item_master_pos_wait :public Item_int_func
{
  String value;
1366
public:
unknown's avatar
unknown committed
1367
  Item_master_pos_wait(Item *a,Item *b) :Item_int_func(a,b) {}
1368
  Item_master_pos_wait(Item *a,Item *b,Item *c) :Item_int_func(a,b,c) {}
unknown's avatar
unknown committed
1369 1370
  longlong val_int();
  const char *func_name() const { return "master_pos_wait"; }
1371
  void fix_length_and_dec() { max_length=21; maybe_null=1;}
unknown's avatar
unknown committed
1372 1373
};

unknown's avatar
unknown committed
1374

unknown's avatar
unknown committed
1375
/* Handling of user definable variables */
unknown's avatar
unknown committed
1376 1377 1378 1379 1380 1381 1382

class user_var_entry;

class Item_func_set_user_var :public Item_func
{
  enum Item_result cached_result_type;
  user_var_entry *entry;
1383
  /*
1384
    The entry_thread_id variable is used:
1385 1386 1387
    1) to skip unnecessary updates of the entry field (see above);
    2) to reset the entry field that was initialized in the other thread
       (for example, an item tree of a trigger that updates user variables
1388
       may be shared between several connections, and the entry_thread_id field
1389 1390 1391 1392
       prevents updates of one connection user variables from a concurrent
       connection calling the same trigger that initially updated some
       user variable it the first connection context).
  */
1393
  my_thread_id entry_thread_id;
1394 1395
  char buffer[MAX_FIELD_WIDTH];
  String value;
unknown's avatar
unknown committed
1396
  my_decimal decimal_buff;
1397
  bool null_item;
1398 1399 1400 1401 1402
  union
  {
    longlong vint;
    double vreal;
    String *vstr;
unknown's avatar
unknown committed
1403
    my_decimal *vdec;
1404
  } save_result;
unknown's avatar
unknown committed
1405 1406

public:
1407
  LEX_STRING name; // keep it public
1408
  Item_func_set_user_var(LEX_STRING a,Item *b)
1409
    :Item_func(b), cached_result_type(INT_RESULT),
1410
     entry(NULL), entry_thread_id(0), name(a)
1411
  {}
1412
  enum Functype functype() const { return SUSERVAR_FUNC; }
1413
  double val_real();
unknown's avatar
unknown committed
1414 1415
  longlong val_int();
  String *val_str(String *str);
unknown's avatar
unknown committed
1416
  my_decimal *val_decimal(my_decimal *);
unknown's avatar
unknown committed
1417
  double val_result();
1418
  longlong val_int_result();
Georgi Kodinov's avatar
merge  
Georgi Kodinov committed
1419
  bool val_bool_result();
unknown's avatar
unknown committed
1420
  String *str_result(String *str);
1421
  my_decimal *val_decimal_result(my_decimal *);
1422
  bool is_null_result();
1423
  bool update_hash(void *ptr, uint length, enum Item_result type,
unknown's avatar
unknown committed
1424
  		   CHARSET_INFO *cs, Derivation dv, bool unsigned_arg);
1425
  bool send(Protocol *protocol, String *str_arg);
unknown's avatar
unknown committed
1426
  void make_field(Send_field *tmp_field);
1427
  bool check(bool use_result_field);
1428
  void save_item_result(Item *item);
unknown's avatar
unknown committed
1429 1430
  bool update();
  enum Item_result result_type () const { return cached_result_type; }
1431
  bool fix_fields(THD *thd, Item **ref);
unknown's avatar
unknown committed
1432
  void fix_length_and_dec();
1433 1434
  virtual void print(String *str, enum_query_type query_type);
  void print_as_stmt(String *str, enum_query_type query_type);
unknown's avatar
unknown committed
1435
  const char *func_name() const { return "set_user_var"; }
1436 1437 1438 1439 1440 1441 1442
  int save_in_field(Field *field, bool no_conversions,
                    bool can_use_result_field);
  int save_in_field(Field *field, bool no_conversions)
  {
    return save_in_field(field, no_conversions, 1);
  }
  void save_org_in_field(Field *field) { (void)save_in_field(field, 1, 0); }
unknown's avatar
unknown committed
1443
  bool register_field_in_read_map(uchar *arg);
1444
  bool set_entry(THD *thd, bool create_if_not_exists);
1445
  void cleanup();
unknown's avatar
unknown committed
1446 1447 1448
};


1449 1450
class Item_func_get_user_var :public Item_func,
                              private Settable_routine_parameter
unknown's avatar
unknown committed
1451
{
1452
  user_var_entry *var_entry;
1453
  Item_result m_cached_result_type;
unknown's avatar
unknown committed
1454 1455

public:
1456
  LEX_STRING name; // keep it public
1457
  Item_func_get_user_var(LEX_STRING a):
unknown's avatar
unknown committed
1458
    Item_func(), m_cached_result_type(STRING_RESULT), name(a) {}
1459 1460
  enum Functype functype() const { return GUSERVAR_FUNC; }
  LEX_STRING get_name() { return name; }
1461
  double val_real();
unknown's avatar
unknown committed
1462
  longlong val_int();
unknown's avatar
unknown committed
1463
  my_decimal *val_decimal(my_decimal*);
unknown's avatar
unknown committed
1464 1465
  String *val_str(String* str);
  void fix_length_and_dec();
1466
  virtual void print(String *str, enum_query_type query_type);
unknown's avatar
unknown committed
1467
  enum Item_result result_type() const;
1468 1469 1470 1471
  /*
    We must always return variables as strings to guard against selects of type
    select @t1:=1,@t1,@t:="hello",@t from foo where (@t1:= t2.b)
  */
unknown's avatar
unknown committed
1472
  const char *func_name() const { return "get_user_var"; }
1473
  bool const_item() const;
1474
  table_map used_tables() const
1475
  { return const_item() ? 0 : RAND_TABLE_BIT; }
1476
  bool eq(const Item *item, bool binary_cmp) const;
1477
private:
1478
  bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
1479 1480 1481 1482 1483 1484

public:
  Settable_routine_parameter *get_settable_routine_parameter()
  {
    return this;
  }
1485
};
unknown's avatar
unknown committed
1486

unknown's avatar
unknown committed
1487

unknown's avatar
unknown committed
1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501
/*
  This item represents user variable used as out parameter (e.g in LOAD DATA),
  and it is supposed to be used only for this purprose. So it is simplified
  a lot. Actually you should never obtain its value.

  The only two reasons for this thing being an Item is possibility to store it
  in List<Item> and desire to place this code somewhere near other functions
  working with user variables.
*/
class Item_user_var_as_out_param :public Item
{
  LEX_STRING name;
  user_var_entry *entry;
public:
1502 1503
  Item_user_var_as_out_param(LEX_STRING a) : name(a)
  { set_name(a.str, 0, system_charset_info); }
unknown's avatar
unknown committed
1504 1505 1506 1507 1508 1509 1510
  /* We should return something different from FIELD_ITEM here */
  enum Type type() const { return STRING_ITEM;}
  double val_real();
  longlong val_int();
  String *val_str(String *str);
  my_decimal *val_decimal(my_decimal *decimal_buffer);
  /* fix_fields() binds variable name with its entry structure */
1511
  bool fix_fields(THD *thd, Item **ref);
1512
  virtual void print(String *str, enum_query_type query_type);
unknown's avatar
unknown committed
1513 1514 1515 1516 1517
  void set_null_value(CHARSET_INFO* cs);
  void set_value(const char *str, uint length, CHARSET_INFO* cs);
};


1518 1519
/* A system variable */

1520 1521 1522 1523
#define GET_SYS_VAR_CACHE_LONG     1
#define GET_SYS_VAR_CACHE_DOUBLE   2
#define GET_SYS_VAR_CACHE_STRING   4

1524 1525 1526
class Item_func_get_system_var :public Item_func
{
  sys_var *var;
Georgi Kodinov's avatar
Georgi Kodinov committed
1527
  enum_var_type var_type, orig_var_type;
1528
  LEX_STRING component;
1529 1530 1531 1532 1533 1534 1535
  longlong cached_llval;
  double cached_dval;
  String cached_strval;
  my_bool cached_null_value;
  query_id_t used_query_id;
  uchar cache_present;

1536 1537 1538 1539
public:
  Item_func_get_system_var(sys_var *var_arg, enum_var_type var_type_arg,
                           LEX_STRING *component_arg, const char *name_arg,
                           size_t name_len_arg);
1540
  enum Functype functype() const { return GSYSVAR_FUNC; }
1541
  void update_null_value();
1542 1543 1544 1545 1546 1547 1548 1549 1550
  void fix_length_and_dec();
  void print(String *str, enum_query_type query_type);
  bool const_item() const { return true; }
  table_map used_tables() const { return 0; }
  enum Item_result result_type() const;
  enum_field_types field_type() const;
  double val_real();
  longlong val_int();
  String* val_str(String*);
unknown's avatar
unknown committed
1551 1552
  /* TODO: fix to support views */
  const char *func_name() const { return "get_system_var"; }
1553 1554 1555 1556 1557 1558 1559 1560 1561
  /**
    Indicates whether this system variable is written to the binlog or not.

    Variables are written to the binlog as part of "status_vars" in
    Query_log_event, as an Intvar_log_event, or a Rand_log_event.

    @return true if the variable is written to the binlog, false otherwise.
  */
  bool is_written_to_binlog();
1562
  bool eq(const Item *item, bool binary_cmp) const;
Georgi Kodinov's avatar
Georgi Kodinov committed
1563 1564

  void cleanup();
1565 1566 1567
};


unknown's avatar
unknown committed
1568 1569 1570
class Item_func_inet_aton : public Item_int_func
{
public:
1571 1572 1573 1574
  Item_func_inet_aton(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "inet_aton"; }
  void fix_length_and_dec() { decimals= 0; max_length= 21; maybe_null= 1; unsigned_flag= 1;}
unknown's avatar
unknown committed
1575 1576 1577
};


1578
/* for fulltext search */
1579
#include <ft_global.h>
unknown's avatar
unknown committed
1580 1581 1582 1583

class Item_func_match :public Item_real_func
{
public:
1584
  uint key, flags;
unknown's avatar
unknown committed
1585
  bool join_key;
1586 1587 1588 1589
  DTCollation cmp_collation;
  FT_INFO *ft_handler;
  TABLE *table;
  Item_func_match *master;   // for master-slave optimization
1590 1591
  Item *concat_ws;           // Item_func_concat_ws
  String value;              // value of concat_ws
1592
  String search_value;       // key_item()'s value converted to cmp_collation
unknown's avatar
unknown committed
1593

unknown's avatar
unknown committed
1594
  Item_func_match(List<Item> &a, uint b): Item_real_func(a), key(0), flags(b),
1595
       join_key(0), ft_handler(0), table(0), master(0), concat_ws(0) { }
unknown's avatar
unknown committed
1596
  void cleanup()
1597
  {
1598
    DBUG_ENTER("Item_func_match::cleanup");
1599
    Item_real_func::cleanup();
1600
    if (!master && ft_handler)
unknown's avatar
unknown committed
1601
      ft_handler->please->close_search(ft_handler);
1602
    ft_handler= 0;
1603
    concat_ws= 0;
1604
    table= 0;           // required by Item_func_match::eq()
unknown's avatar
unknown committed
1605
    DBUG_VOID_RETURN;
1606
  }
unknown's avatar
unknown committed
1607
  enum Functype functype() const { return FT_FUNC; }
1608
  const char *func_name() const { return "match"; }
unknown's avatar
unknown committed
1609
  void update_used_tables() {}
1610
  table_map not_null_tables() const { return 0; }
1611
  bool fix_fields(THD *thd, Item **ref);
1612
  bool eq(const Item *, bool binary_cmp) const;
1613
  /* The following should be safe, even if we compare doubles */
1614 1615
  longlong val_int() { DBUG_ASSERT(fixed == 1); return val_real() != 0.0; }
  double val_real();
1616
  virtual void print(String *str, enum_query_type query_type);
1617 1618

  bool fix_index();
1619
  void init_search(bool no_order);
1620
};
unknown's avatar
unknown committed
1621

unknown's avatar
unknown committed
1622

1623
class Item_func_bit_xor : public Item_func_bit
unknown's avatar
unknown committed
1624 1625
{
public:
1626
  Item_func_bit_xor(Item *a, Item *b) :Item_func_bit(a, b) {}
unknown's avatar
unknown committed
1627 1628 1629 1630
  longlong val_int();
  const char *func_name() const { return "^"; }
};

1631
class Item_func_is_free_lock :public Item_int_func
unknown's avatar
unknown committed
1632 1633 1634
{
  String value;
public:
1635
  Item_func_is_free_lock(Item *a) :Item_int_func(a) {}
unknown's avatar
unknown committed
1636
  longlong val_int();
1637
  const char *func_name() const { return "is_free_lock"; }
unknown's avatar
unknown committed
1638
  void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
unknown's avatar
unknown committed
1639 1640
};

unknown's avatar
SCRUM  
unknown committed
1641 1642 1643 1644 1645 1646 1647 1648 1649 1650
class Item_func_is_used_lock :public Item_int_func
{
  String value;
public:
  Item_func_is_used_lock(Item *a) :Item_int_func(a) {}
  longlong val_int();
  const char *func_name() const { return "is_used_lock"; }
  void fix_length_and_dec() { decimals=0; max_length=10; maybe_null=1;}
};

unknown's avatar
unknown committed
1651 1652
/* For type casts */

1653
enum Cast_target
unknown's avatar
unknown committed
1654 1655
{
  ITEM_CAST_BINARY, ITEM_CAST_SIGNED_INT, ITEM_CAST_UNSIGNED_INT,
unknown's avatar
unknown committed
1656 1657
  ITEM_CAST_DATE, ITEM_CAST_TIME, ITEM_CAST_DATETIME, ITEM_CAST_CHAR,
  ITEM_CAST_DECIMAL
unknown's avatar
unknown committed
1658
};
1659 1660


1661 1662 1663 1664 1665 1666 1667 1668 1669 1670
class Item_func_row_count :public Item_int_func
{
public:
  Item_func_row_count() :Item_int_func() {}
  longlong val_int();
  const char *func_name() const { return "row_count"; }
  void fix_length_and_dec() { decimals= 0; maybe_null=0; }
};


1671 1672 1673 1674 1675 1676 1677
/*
 *
 * Stored FUNCTIONs
 *
 */

class sp_head;
1678
class sp_name;
1679
struct st_sp_security_context;
1680 1681 1682 1683

class Item_func_sp :public Item_func
{
private:
1684
  Name_resolution_context *context;
1685
  sp_name *m_name;
1686
  mutable sp_head *m_sp;
unknown's avatar
unknown committed
1687
  TABLE *dummy_table;
1688
  uchar result_buf[64];
1689 1690 1691 1692
  /*
     The result field of the concrete stored function.
  */
  Field *sp_result_field;
1693

1694 1695 1696
  bool execute();
  bool execute_impl(THD *thd);
  bool init_result_field(THD *thd);
1697
  
1698 1699
public:

1700
  Item_func_sp(Name_resolution_context *context_arg, sp_name *name);
1701

1702 1703
  Item_func_sp(Name_resolution_context *context_arg,
               sp_name *name, List<Item> &list);
1704 1705 1706 1707

  virtual ~Item_func_sp()
  {}

unknown's avatar
unknown committed
1708
  void update_used_tables();
1709

1710
  void cleanup();
1711

1712
  const char *func_name() const;
1713

1714 1715
  enum enum_field_types field_type() const;

unknown's avatar
unknown committed
1716 1717 1718 1719
  Field *tmp_table_field(TABLE *t_arg);

  void make_field(Send_field *tmp_field);

1720 1721 1722 1723
  Item_result result_type() const;

  longlong val_int()
  {
1724
    if (execute())
unknown's avatar
unknown committed
1725
      return (longlong) 0;
1726
    return sp_result_field->val_int();
1727 1728
  }

1729
  double val_real()
1730
  {
1731
    if (execute())
1732
      return 0.0;
1733
    return sp_result_field->val_real();
1734 1735
  }

unknown's avatar
unknown committed
1736 1737
  my_decimal *val_decimal(my_decimal *dec_buf)
  {
1738
    if (execute())
unknown's avatar
unknown committed
1739
      return NULL;
1740
    return sp_result_field->val_decimal(dec_buf);
unknown's avatar
unknown committed
1741 1742
  }

1743 1744
  String *val_str(String *str)
  {
1745 1746 1747 1748
    String buf;
    char buff[20];
    buf.set(buff, 20, str->charset());
    buf.length(0);
1749
    if (execute())
1750
      return NULL;
1751 1752 1753 1754 1755 1756
    /*
      result_field will set buf pointing to internal buffer
      of the resul_field. Due to this it will change any time
      when SP is executed. In order to prevent occasional
      corruption of returned value, we make here a copy.
    */
1757
    sp_result_field->val_str(&buf);
1758 1759
    str->copy(buf);
    return str;
1760 1761
  }

1762
  virtual bool change_context_processor(uchar *cntx)
1763 1764
    { context= (Name_resolution_context *)cntx; return FALSE; }

1765
  bool sp_check_access(THD * thd);
1766
  virtual enum Functype functype() const { return FUNC_SP; }
1767

1768
  bool fix_fields(THD *thd, Item **ref);
1769
  void fix_length_and_dec(void);
1770
  bool is_expensive() { return 1; }
1771 1772 1773 1774 1775

  inline Field *get_sp_result_field()
  {
    return sp_result_field;
  }
1776
};
unknown's avatar
unknown committed
1777 1778


1779 1780 1781 1782 1783 1784 1785 1786
class Item_func_found_rows :public Item_int_func
{
public:
  Item_func_found_rows() :Item_int_func() {}
  longlong val_int();
  const char *func_name() const { return "found_rows"; }
  void fix_length_and_dec() { decimals= 0; maybe_null=0; }
};
1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798


void uuid_short_init();

class Item_func_uuid_short :public Item_int_func
{
public:
  Item_func_uuid_short() :Item_int_func() {}
  const char *func_name() const { return "uuid_short"; }
  longlong val_int();
  void fix_length_and_dec()
  { max_length= 21; unsigned_flag=1; }
1799
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
1800 1801
};

1802 1803 1804 1805 1806 1807 1808 1809 1810 1811
Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
                     LEX_STRING component);
extern bool check_reserved_words(LEX_STRING *name);
extern enum_field_types agg_field_type(Item **items, uint nitems);
double my_double_round(double value, longlong dec, bool dec_unsigned,
                       bool truncate);
bool eval_const_cond(COND *cond);

extern bool volatile  mqh_used;

1812
#endif /* ITEM_FUNC_INCLUDED */