item_func.h 47.6 KB
Newer Older
unknown's avatar
unknown committed
1
/* Copyright (C) 2000-2006 MySQL AB
2

unknown's avatar
unknown committed
3 4
   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
5
   the Free Software Foundation; version 2 of the License.
6

unknown's avatar
unknown committed
7 8 9 10
   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.
11

unknown's avatar
unknown committed
12 13 14 15 16 17 18
   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 */

19
#ifdef USE_PRAGMA_INTERFACE
unknown's avatar
unknown committed
20 21 22 23 24 25 26 27 28 29 30 31 32
#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:
33
  Item **args, *tmp_arg[2];
34 35 36 37
  /*
    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
38
  uint allowed_arg_cols;
unknown's avatar
unknown committed
39 40
public:
  uint arg_count;
41
  table_map used_tables_cache, not_null_tables_cache;
unknown's avatar
unknown committed
42 43 44
  bool const_item_cache;
  enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC,
		  GE_FUNC,GT_FUNC,FT_FUNC,
45
		  LIKE_FUNC,ISNULL_FUNC,ISNOTNULL_FUNC,
46 47
		  COND_AND_FUNC, COND_OR_FUNC, COND_XOR_FUNC,
                  BETWEEN, IN_FUNC, MULT_EQUAL_FUNC,
48
		  INTERVAL_FUNC, ISNOTNULLTEST_FUNC,
unknown's avatar
unknown committed
49 50 51 52
		  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,
53
		  SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN,
unknown's avatar
unknown committed
54 55
                  NOT_FUNC, NOT_ALL_FUNC,
                  NOW_FUNC, TRIG_COND_FUNC,
56
                  SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
57
                  EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC,
58
                  NEG_FUNC, GSYSVAR_FUNC };
59 60
  enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
                       OPTIMIZE_EQUAL };
unknown's avatar
unknown committed
61 62
  enum Type type() const { return FUNC_ITEM; }
  virtual enum Functype functype() const   { return UNKNOWN_FUNC; }
unknown's avatar
unknown committed
63 64
  Item_func(void):
    allowed_arg_cols(1), arg_count(0)
unknown's avatar
unknown committed
65
  {
66
    with_sum_func= 0;
unknown's avatar
unknown committed
67
  }
unknown's avatar
unknown committed
68 69
  Item_func(Item *a):
    allowed_arg_cols(1), arg_count(1)
unknown's avatar
unknown committed
70
  {
71
    args= tmp_arg;
72 73
    args[0]= a;
    with_sum_func= a->with_sum_func;
unknown's avatar
unknown committed
74
  }
unknown's avatar
unknown committed
75 76
  Item_func(Item *a,Item *b):
    allowed_arg_cols(1), arg_count(2)
unknown's avatar
unknown committed
77
  {
78
    args= tmp_arg;
79 80
    args[0]= a; args[1]= b;
    with_sum_func= a->with_sum_func || b->with_sum_func;
unknown's avatar
unknown committed
81
  }
unknown's avatar
unknown committed
82 83
  Item_func(Item *a,Item *b,Item *c):
    allowed_arg_cols(1)
unknown's avatar
unknown committed
84
  {
85 86
    arg_count= 0;
    if ((args= (Item**) sql_alloc(sizeof(Item*)*3)))
unknown's avatar
unknown committed
87
    {
88 89 90
      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
91 92
    }
  }
unknown's avatar
unknown committed
93 94
  Item_func(Item *a,Item *b,Item *c,Item *d):
    allowed_arg_cols(1)
unknown's avatar
unknown committed
95
  {
96 97
    arg_count= 0;
    if ((args= (Item**) sql_alloc(sizeof(Item*)*4)))
unknown's avatar
unknown committed
98
    {
99 100 101 102
      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
103 104
    }
  }
unknown's avatar
unknown committed
105 106
  Item_func(Item *a,Item *b,Item *c,Item *d,Item* e):
    allowed_arg_cols(1)
unknown's avatar
unknown committed
107
  {
108 109
    arg_count= 5;
    if ((args= (Item**) sql_alloc(sizeof(Item*)*5)))
unknown's avatar
unknown committed
110
    {
111 112 113
      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
114 115 116
    }
  }
  Item_func(List<Item> &list);
117
  // Constructor used for Item_cond_and/or (see Item comment)
118
  Item_func(THD *thd, Item_func *item);
119
  bool fix_fields(THD *, Item **ref);
unknown's avatar
unknown committed
120
  table_map used_tables() const;
121
  table_map not_null_tables() const;
unknown's avatar
unknown committed
122
  void update_used_tables();
123
  bool eq(const Item *item, bool binary_cmp) const;
unknown's avatar
unknown committed
124 125 126
  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]; }
127 128 129 130 131 132 133 134 135 136 137
  /*
    This method is used for debug purposes to print the name of an
    item to the debug log. The second use of this method is as
    a helper function of print(), where it is applicable.
    To suit both goals it should return a meaningful,
    distinguishable and sintactically correct string.  This method
    should not be used for runtime type identification, use enum
    {Sum}Functype and Item_func::functype()/Item_sum::sum_func()
    instead.
  */
  virtual const char *func_name() const= 0;
unknown's avatar
unknown committed
138 139
  virtual bool const_item() const { return const_item_cache; }
  inline Item **arguments() const { return args; }
140
  void set_arguments(List<Item> &list);
unknown's avatar
unknown committed
141 142
  inline uint argument_count() const { return arg_count; }
  inline void remove_arguments() { arg_count=0; }
143
  void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
144 145 146
  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
147 148 149 150
  virtual void fix_num_length_and_dec();
  void count_only_length();
  void count_real_length();
  void count_decimal_length();
151
  inline bool get_arg0_date(MYSQL_TIME *ltime, uint fuzzy_date)
unknown's avatar
unknown committed
152
  {
153
    return (null_value=args[0]->get_date(ltime, fuzzy_date));
unknown's avatar
unknown committed
154
  }
155
  inline bool get_arg0_time(MYSQL_TIME *ltime)
unknown's avatar
unknown committed
156 157 158
  {
    return (null_value=args[0]->get_time(ltime));
  }
159
  bool is_null() { 
160
    update_null_value();
161 162
    return null_value; 
  }
unknown's avatar
unknown committed
163
  void signal_divide_by_null();
unknown's avatar
unknown committed
164
  friend class udf_handler;
165
  Field *tmp_table_field() { return result_field; }
166
  Field *tmp_table_field(TABLE *t_arg);
167
  Item *get_tmp_table_item(THD *thd);
unknown's avatar
unknown committed
168 169 170

  my_decimal *val_decimal(my_decimal *);

171
  bool agg_arg_collations(DTCollation &c, Item **items, uint nitems,
172
                          uint flags)
173
  {
174
    return agg_item_collations(c, func_name(), items, nitems, flags, 1);
175
  }
176 177
  bool agg_arg_collations_for_comparison(DTCollation &c,
                                         Item **items, uint nitems,
178
                                         uint flags)
179 180 181 182
  {
    return agg_item_collations_for_comparison(c, func_name(),
                                              items, nitems, flags);
  }
unknown's avatar
unknown committed
183
  bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems,
184
                        uint flags, int item_sep)
185
  {
186
    return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep);
187
  }
188 189 190 191
  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);
192 193
  void traverse_cond(Cond_traverser traverser,
                     void * arg, traverse_order order);
194
  bool is_expensive_processor(uchar *arg);
195
  virtual bool is_expensive() { return 0; }
196 197 198 199 200 201 202
  inline double fix_result(double value)
  {
    if (isfinite(value))
      return value;
    null_value=1;
    return 0.0;
  }
unknown's avatar
unknown committed
203 204 205 206 207 208 209 210 211 212 213
};


class Item_real_func :public Item_func
{
public:
  Item_real_func() :Item_func() {}
  Item_real_func(Item *a) :Item_func(a) {}
  Item_real_func(Item *a,Item *b) :Item_func(a,b) {}
  Item_real_func(List<Item> &list) :Item_func(list) {}
  String *val_str(String*str);
214
  my_decimal *val_decimal(my_decimal *decimal_value);
215
  longlong val_int()
216
    { DBUG_ASSERT(fixed == 1); return (longlong) rint(val_real()); }
unknown's avatar
unknown committed
217
  enum Item_result result_type () const { return REAL_RESULT; }
unknown's avatar
unknown committed
218 219
  void fix_length_and_dec()
  { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); }
unknown's avatar
unknown committed
220 221
};

222

unknown's avatar
unknown committed
223
class Item_func_numhybrid: public Item_func
unknown's avatar
unknown committed
224
{
unknown's avatar
unknown committed
225
protected:
unknown's avatar
unknown committed
226 227
  Item_result hybrid_type;
public:
unknown's avatar
unknown committed
228
  Item_func_numhybrid(Item *a) :Item_func(a), hybrid_type(REAL_RESULT)
unknown's avatar
unknown committed
229 230
  {}
  Item_func_numhybrid(Item *a,Item *b)
unknown's avatar
unknown committed
231
    :Item_func(a,b), hybrid_type(REAL_RESULT)
unknown's avatar
unknown committed
232
  {}
unknown's avatar
unknown committed
233
  Item_func_numhybrid(List<Item> &list)
unknown's avatar
unknown committed
234
    :Item_func(list), hybrid_type(REAL_RESULT)
unknown's avatar
unknown committed
235
  {}
unknown's avatar
unknown committed
236

unknown's avatar
unknown committed
237
  enum Item_result result_type () const { return hybrid_type; }
unknown's avatar
unknown committed
238 239 240 241 242 243 244 245 246
  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);

247 248 249 250 251 252
  /**
     @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
253
  virtual longlong int_op()= 0;
254 255 256 257 258 259 260

  /**
     @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
261
  virtual double real_op()= 0;
262 263 264 265 266 267 268 269 270 271 272

  /**
     @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
273
  virtual my_decimal *decimal_op(my_decimal *)= 0;
274 275 276 277 278 279 280

  /**
     @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
281
  virtual String *str_op(String *)= 0;
282
  bool is_null() { update_null_value(); return null_value; }
unknown's avatar
unknown committed
283 284
};

unknown's avatar
unknown committed
285 286 287 288 289 290
/* 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
291

unknown's avatar
unknown committed
292 293
  void fix_num_length_and_dec();
  void find_num_type();
unknown's avatar
unknown committed
294
  String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
unknown's avatar
unknown committed
295
};
unknown's avatar
unknown committed
296

unknown's avatar
unknown committed
297 298 299

/* Base class for operations like '+', '-', '*' */
class Item_num_op :public Item_func_numhybrid
unknown's avatar
unknown committed
300 301
{
 public:
unknown's avatar
unknown committed
302 303
  Item_num_op(Item *a,Item *b) :Item_func_numhybrid(a, b) {}
  virtual void result_precision()= 0;
304 305 306 307 308 309

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

unknown's avatar
unknown committed
310
  void find_num_type();
unknown's avatar
unknown committed
311
  String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
unknown's avatar
unknown committed
312 313 314 315 316 317
};


class Item_int_func :public Item_func
{
public:
unknown's avatar
unknown committed
318 319 320 321 322 323
  Item_int_func() :Item_func() { max_length= 21; }
  Item_int_func(Item *a) :Item_func(a) { max_length= 21; }
  Item_int_func(Item *a,Item *b) :Item_func(a,b) { max_length= 21; }
  Item_int_func(Item *a,Item *b,Item *c) :Item_func(a,b,c)
  { max_length= 21; }
  Item_int_func(List<Item> &list) :Item_func(list) { max_length= 21; }
324
  Item_int_func(THD *thd, Item_int_func *item) :Item_func(thd, item) {}
325
  double val_real();
unknown's avatar
unknown committed
326 327
  String *val_str(String*str);
  enum Item_result result_type () const { return INT_RESULT; }
unknown's avatar
unknown committed
328
  void fix_length_and_dec() {}
unknown's avatar
unknown committed
329 330
};

331

332 333 334 335 336
class Item_func_connection_id :public Item_int_func
{
  longlong value;

public:
337
  Item_func_connection_id() {}
338 339 340 341 342 343 344
  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; }
};


345 346 347 348
class Item_func_signed :public Item_int_func
{
public:
  Item_func_signed(Item *a) :Item_int_func(a) {}
349
  const char *func_name() const { return "cast_as_signed"; }
350 351
  longlong val_int();
  longlong val_int_from_str(int *error);
352
  void fix_length_and_dec()
unknown's avatar
unknown committed
353
  { max_length=args[0]->max_length; unsigned_flag=0; }
354
  virtual void print(String *str, enum_query_type query_type);
unknown's avatar
unknown committed
355
  uint decimal_precision() const { return args[0]->decimal_precision(); }
356 357
};

358

unknown's avatar
unknown committed
359
class Item_func_unsigned :public Item_func_signed
360 361
{
public:
unknown's avatar
unknown committed
362
  Item_func_unsigned(Item *a) :Item_func_signed(a) {}
363
  const char *func_name() const { return "cast_as_unsigned"; }
364
  void fix_length_and_dec()
unknown's avatar
unknown committed
365
  { max_length=args[0]->max_length; unsigned_flag=1; }
366
  longlong val_int();
367
  virtual void print(String *str, enum_query_type query_type);
368 369 370
};


unknown's avatar
unknown committed
371
class Item_decimal_typecast :public Item_func
unknown's avatar
unknown committed
372
{
unknown's avatar
unknown committed
373
  my_decimal decimal_value;
unknown's avatar
unknown committed
374
public:
unknown's avatar
unknown committed
375 376 377
  Item_decimal_typecast(Item *a, int len, int dec) :Item_func(a)
  {
    decimals= dec;
378
    max_length= my_decimal_precision_to_length(len, dec, unsigned_flag);
unknown's avatar
unknown committed
379 380
  }
  String *val_str(String *str);
381
  double val_real();
unknown's avatar
unknown committed
382
  longlong val_int();
unknown's avatar
unknown committed
383 384
  my_decimal *val_decimal(my_decimal*);
  enum Item_result result_type () const { return DECIMAL_RESULT; }
unknown's avatar
unknown committed
385
  enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
unknown's avatar
unknown committed
386
  void fix_length_and_dec() {};
387
  const char *func_name() const { return "decimal_typecast"; }
388
  virtual void print(String *str, enum_query_type query_type);
unknown's avatar
unknown committed
389 390 391 392 393 394 395 396
};


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();
397
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
unknown's avatar
unknown committed
398 399 400 401 402 403 404 405 406 407 408
};


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
409 410
};

unknown's avatar
unknown committed
411
class Item_func_minus :public Item_func_additive_op
unknown's avatar
unknown committed
412 413
{
public:
unknown's avatar
unknown committed
414
  Item_func_minus(Item *a,Item *b) :Item_func_additive_op(a,b) {}
unknown's avatar
unknown committed
415
  const char *func_name() const { return "-"; }
unknown's avatar
unknown committed
416 417 418
  longlong int_op();
  double real_op();
  my_decimal *decimal_op(my_decimal *);
419
  void fix_length_and_dec();
unknown's avatar
unknown committed
420 421
};

422

unknown's avatar
unknown committed
423 424 425 426 427
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
428 429 430 431
  longlong int_op();
  double real_op();
  my_decimal *decimal_op(my_decimal *);
  void result_precision();
432
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
unknown's avatar
unknown committed
433 434 435 436 437 438
};


class Item_func_div :public Item_num_op
{
public:
unknown's avatar
unknown committed
439
  uint prec_increment;
unknown's avatar
unknown committed
440
  Item_func_div(Item *a,Item *b) :Item_num_op(a,b) {}
441
  longlong int_op() { DBUG_ASSERT(0); return 0; }
unknown's avatar
unknown committed
442 443
  double real_op();
  my_decimal *decimal_op(my_decimal *);
unknown's avatar
unknown committed
444 445
  const char *func_name() const { return "/"; }
  void fix_length_and_dec();
unknown's avatar
unknown committed
446
  void result_precision();
unknown's avatar
unknown committed
447 448 449
};


450
class Item_func_int_div :public Item_int_func
451 452
{
public:
453
  Item_func_int_div(Item *a,Item *b) :Item_int_func(a,b)
unknown's avatar
unknown committed
454
  {}
455 456 457
  longlong val_int();
  const char *func_name() const { return "DIV"; }
  void fix_length_and_dec();
458 459 460 461 462 463

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

464
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
465 466 467
};


unknown's avatar
unknown committed
468 469 470 471
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
472 473 474
  longlong int_op();
  double real_op();
  my_decimal *decimal_op(my_decimal *);
unknown's avatar
unknown committed
475
  const char *func_name() const { return "%"; }
unknown's avatar
unknown committed
476
  void result_precision();
unknown's avatar
unknown committed
477
  void fix_length_and_dec();
478
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
unknown's avatar
unknown committed
479 480 481
};


482
class Item_func_neg :public Item_func_num1
unknown's avatar
unknown committed
483 484
{
public:
485
  Item_func_neg(Item *a) :Item_func_num1(a) {}
unknown's avatar
unknown committed
486 487 488
  double real_op();
  longlong int_op();
  my_decimal *decimal_op(my_decimal *);
unknown's avatar
unknown committed
489
  const char *func_name() const { return "-"; }
490
  enum Functype functype() const   { return NEG_FUNC; }
491
  void fix_length_and_dec();
unknown's avatar
unknown committed
492
  void fix_num_length_and_dec();
unknown's avatar
unknown committed
493
  uint decimal_precision() const { return args[0]->decimal_precision(); }
unknown's avatar
unknown committed
494
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
unknown's avatar
unknown committed
495 496 497
};


unknown's avatar
unknown committed
498
class Item_func_abs :public Item_func_num1
unknown's avatar
unknown committed
499 500
{
public:
unknown's avatar
unknown committed
501 502 503 504
  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
505 506
  const char *func_name() const { return "abs"; }
  void fix_length_and_dec();
unknown's avatar
unknown committed
507
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
unknown's avatar
unknown committed
508 509
};

unknown's avatar
unknown committed
510
// A class to handle logarithmic and trigonometric functions
unknown's avatar
unknown committed
511 512 513 514 515 516 517 518

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()
  {
519
    decimals=NOT_FIXED_DEC; max_length=float_length(decimals);
unknown's avatar
unknown committed
520 521 522 523 524 525 526 527
    maybe_null=1;
  }
};

class Item_func_exp :public Item_dec_func
{
public:
  Item_func_exp(Item *a) :Item_dec_func(a) {}
528
  double val_real();
unknown's avatar
unknown committed
529 530 531
  const char *func_name() const { return "exp"; }
};

532 533 534 535 536

class Item_func_ln :public Item_dec_func
{
public:
  Item_func_ln(Item *a) :Item_dec_func(a) {}
537
  double val_real();
538 539 540 541
  const char *func_name() const { return "ln"; }
};


unknown's avatar
unknown committed
542 543 544 545
class Item_func_log :public Item_dec_func
{
public:
  Item_func_log(Item *a) :Item_dec_func(a) {}
546
  Item_func_log(Item *a,Item *b) :Item_dec_func(a,b) {}
547
  double val_real();
unknown's avatar
unknown committed
548 549 550 551
  const char *func_name() const { return "log"; }
};


552 553 554 555
class Item_func_log2 :public Item_dec_func
{
public:
  Item_func_log2(Item *a) :Item_dec_func(a) {}
556
  double val_real();
557 558 559 560
  const char *func_name() const { return "log2"; }
};


unknown's avatar
unknown committed
561 562 563 564
class Item_func_log10 :public Item_dec_func
{
public:
  Item_func_log10(Item *a) :Item_dec_func(a) {}
565
  double val_real();
unknown's avatar
unknown committed
566 567 568 569 570 571 572 573
  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) {}
574
  double val_real();
unknown's avatar
unknown committed
575 576 577 578 579 580 581 582
  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) {}
583
  double val_real();
unknown's avatar
unknown committed
584 585 586 587 588 589
  const char *func_name() const { return "pow"; }
};


class Item_func_acos :public Item_dec_func
{
590
public:
unknown's avatar
unknown committed
591
  Item_func_acos(Item *a) :Item_dec_func(a) {}
592
  double val_real();
unknown's avatar
unknown committed
593 594 595 596 597
  const char *func_name() const { return "acos"; }
};

class Item_func_asin :public Item_dec_func
{
598
public:
unknown's avatar
unknown committed
599
  Item_func_asin(Item *a) :Item_dec_func(a) {}
600
  double val_real();
unknown's avatar
unknown committed
601 602 603 604 605
  const char *func_name() const { return "asin"; }
};

class Item_func_atan :public Item_dec_func
{
606
public:
unknown's avatar
unknown committed
607 608
  Item_func_atan(Item *a) :Item_dec_func(a) {}
  Item_func_atan(Item *a,Item *b) :Item_dec_func(a,b) {}
609
  double val_real();
unknown's avatar
unknown committed
610 611 612 613 614
  const char *func_name() const { return "atan"; }
};

class Item_func_cos :public Item_dec_func
{
615
public:
unknown's avatar
unknown committed
616
  Item_func_cos(Item *a) :Item_dec_func(a) {}
617
  double val_real();
unknown's avatar
unknown committed
618 619 620 621 622
  const char *func_name() const { return "cos"; }
};

class Item_func_sin :public Item_dec_func
{
623
public:
unknown's avatar
unknown committed
624
  Item_func_sin(Item *a) :Item_dec_func(a) {}
625
  double val_real();
unknown's avatar
unknown committed
626 627 628 629 630
  const char *func_name() const { return "sin"; }
};

class Item_func_tan :public Item_dec_func
{
631
public:
unknown's avatar
unknown committed
632
  Item_func_tan(Item *a) :Item_dec_func(a) {}
633
  double val_real();
unknown's avatar
unknown committed
634 635 636 637 638 639 640 641 642 643 644
  const char *func_name() const { return "tan"; }
};

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
645 646 647 648 649 650 651 652 653 654
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
655 656
{
public:
unknown's avatar
unknown committed
657
  Item_func_ceiling(Item *a) :Item_func_int_val(a) {}
unknown's avatar
unknown committed
658
  const char *func_name() const { return "ceiling"; }
unknown's avatar
unknown committed
659 660 661
  longlong int_op();
  double real_op();
  my_decimal *decimal_op(my_decimal *);
unknown's avatar
unknown committed
662
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
unknown's avatar
unknown committed
663 664
};

unknown's avatar
unknown committed
665 666

class Item_func_floor :public Item_func_int_val
unknown's avatar
unknown committed
667 668
{
public:
unknown's avatar
unknown committed
669
  Item_func_floor(Item *a) :Item_func_int_val(a) {}
unknown's avatar
unknown committed
670
  const char *func_name() const { return "floor"; }
unknown's avatar
unknown committed
671 672 673
  longlong int_op();
  double real_op();
  my_decimal *decimal_op(my_decimal *);
unknown's avatar
unknown committed
674
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
unknown's avatar
unknown committed
675 676 677 678
};

/* This handles round and truncate */

unknown's avatar
unknown committed
679
class Item_func_round :public Item_func_num1
unknown's avatar
unknown committed
680 681 682
{
  bool truncate;
public:
unknown's avatar
unknown committed
683 684
  Item_func_round(Item *a, Item *b, bool trunc_arg)
    :Item_func_num1(a,b), truncate(trunc_arg) {}
unknown's avatar
unknown committed
685
  const char *func_name() const { return truncate ? "truncate" : "round"; }
unknown's avatar
unknown committed
686 687 688
  double real_op();
  longlong int_op();
  my_decimal *decimal_op(my_decimal *);
unknown's avatar
unknown committed
689
  void fix_length_and_dec();
unknown's avatar
unknown committed
690 691 692 693 694
};


class Item_func_rand :public Item_real_func
{
695
  struct rand_struct *rand;
unknown's avatar
unknown committed
696
public:
697 698
  Item_func_rand(Item *a) :Item_real_func(a), rand(0) {}
  Item_func_rand()	  :Item_real_func() {}
699
  double val_real();
unknown's avatar
unknown committed
700 701
  const char *func_name() const { return "rand"; }
  bool const_item() const { return 0; }
unknown's avatar
unknown committed
702
  void update_used_tables();
703
  bool fix_fields(THD *thd, Item **ref);
704 705
private:
  void seed_random (Item * val);  
unknown's avatar
unknown committed
706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721
};


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;
722
public:
unknown's avatar
unknown committed
723 724
  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) {}
725
  double val_real();
unknown's avatar
unknown committed
726
  const char *func_name() const { return name; }
unknown's avatar
unknown committed
727 728
  void fix_length_and_dec()
  { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); }
unknown's avatar
unknown committed
729 730 731 732 733 734 735 736
};


class Item_func_min_max :public Item_func
{
  Item_result cmp_type;
  String tmp_value;
  int cmp_sign;
737 738 739 740 741
  /* 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;
742 743
protected:
  enum_field_types cached_field_type;
unknown's avatar
unknown committed
744 745
public:
  Item_func_min_max(List<Item> &list,int cmp_sign_arg) :Item_func(list),
746 747
    cmp_type(INT_RESULT), cmp_sign(cmp_sign_arg), compare_as_dates(FALSE),
    datetime_item(0) {}
748
  double val_real();
unknown's avatar
unknown committed
749 750
  longlong val_int();
  String *val_str(String *);
unknown's avatar
unknown committed
751
  my_decimal *val_decimal(my_decimal *);
unknown's avatar
unknown committed
752 753
  void fix_length_and_dec();
  enum Item_result result_type () const { return cmp_type; }
754
  bool result_as_longlong() { return compare_as_dates; };
755
  uint cmp_datetimes(ulonglong *value);
756
  enum_field_types field_type() const { return cached_field_type; }
unknown's avatar
unknown committed
757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772
};

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
773

774 775 776 777 778 779 780 781 782
/* 
  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
783 784 785 786 787
  {
    name= a->name;
    name_length= a->name_length;
  }
  double val_real() { return args[0]->val_real(); }
788 789
  longlong val_int() { return args[0]->val_int(); }
  String *val_str(String *str) { return args[0]->val_str(str); }
unknown's avatar
unknown committed
790
  my_decimal *val_decimal(my_decimal *dec) { return args[0]->val_decimal(dec); }
791 792 793 794 795 796 797 798
  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; 
799
    /* The item could be a NULL constant. */
800
    null_value= args[0]->is_null();
801 802 803 804
  }
};


unknown's avatar
unknown committed
805 806 807 808 809 810 811 812 813 814
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
815 816 817 818
class Item_func_bit_length :public Item_func_length
{
public:
  Item_func_bit_length(Item *a) :Item_func_length(a) {}
819 820
  longlong val_int()
    { DBUG_ASSERT(fixed == 1); return Item_func_length::val_int()*8; }
unknown's avatar
unknown committed
821 822 823
  const char *func_name() const { return "bit_length"; }
};

unknown's avatar
unknown committed
824 825 826 827 828 829 830 831 832 833
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
834 835 836 837 838 839
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"; }
840 841
  void fix_length_and_dec() { max_length=10; maybe_null= 0; }
  table_map not_null_tables() const { return 0; }
unknown's avatar
unknown committed
842 843
};

unknown's avatar
unknown committed
844 845 846
class Item_func_locate :public Item_int_func
{
  String value1,value2;
847
  DTCollation cmp_collation;
unknown's avatar
unknown committed
848 849 850 851 852
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();
853
  void fix_length_and_dec();
854
  virtual void print(String *str, enum_query_type query_type);
unknown's avatar
unknown committed
855 856 857 858 859 860
};


class Item_func_field :public Item_int_func
{
  String value,tmp;
861 862
  Item_result cmp_type;
  DTCollation cmp_collation;
unknown's avatar
unknown committed
863
public:
864
  Item_func_field(List<Item> &list) :Item_int_func(list) {}
unknown's avatar
unknown committed
865 866
  longlong val_int();
  const char *func_name() const { return "field"; }
867
  void fix_length_and_dec();
unknown's avatar
unknown committed
868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894
};


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;
895
  DTCollation cmp_collation;
unknown's avatar
unknown committed
896 897 898 899 900 901 902
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();
};

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

905
class Item_func_bit: public Item_int_func
unknown's avatar
unknown committed
906 907
{
public:
908 909 910
  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; }
911 912 913 914 915

  virtual inline void print(String *str, enum_query_type query_type)
  {
    print_op(str, query_type);
  }
916 917 918 919 920 921
};

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
922 923 924 925
  longlong val_int();
  const char *func_name() const { return "|"; }
};

926
class Item_func_bit_and :public Item_func_bit
unknown's avatar
unknown committed
927 928
{
public:
929
  Item_func_bit_and(Item *a, Item *b) :Item_func_bit(a, b) {}
unknown's avatar
unknown committed
930 931 932 933 934 935 936 937 938 939
  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
940
  void fix_length_and_dec() { max_length=2; }
unknown's avatar
unknown committed
941 942
};

943
class Item_func_shift_left :public Item_func_bit
unknown's avatar
unknown committed
944 945
{
public:
946
  Item_func_shift_left(Item *a, Item *b) :Item_func_bit(a, b) {}
unknown's avatar
unknown committed
947 948 949 950
  longlong val_int();
  const char *func_name() const { return "<<"; }
};

951
class Item_func_shift_right :public Item_func_bit
unknown's avatar
unknown committed
952 953
{
public:
954
  Item_func_shift_right(Item *a, Item *b) :Item_func_bit(a, b) {}
unknown's avatar
unknown committed
955 956 957 958
  longlong val_int();
  const char *func_name() const { return ">>"; }
};

959
class Item_func_bit_neg :public Item_func_bit
unknown's avatar
unknown committed
960 961
{
public:
962
  Item_func_bit_neg(Item *a) :Item_func_bit(a) {}
unknown's avatar
unknown committed
963 964
  longlong val_int();
  const char *func_name() const { return "~"; }
965 966 967 968 969

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

unknown's avatar
unknown committed
972

973
class Item_func_last_insert_id :public Item_int_func
unknown's avatar
unknown committed
974 975
{
public:
976 977
  Item_func_last_insert_id() :Item_int_func() {}
  Item_func_last_insert_id(Item *a) :Item_int_func(a) {}
unknown's avatar
unknown committed
978 979
  longlong val_int();
  const char *func_name() const { return "last_insert_id"; }
unknown's avatar
unknown committed
980 981 982 983 984
  void fix_length_and_dec()
  {
    if (arg_count)
      max_length= args[0]->max_length;
  }
985
  bool fix_fields(THD *thd, Item **ref);
unknown's avatar
unknown committed
986 987
};

988

unknown's avatar
unknown committed
989 990
class Item_func_benchmark :public Item_int_func
{
991
public:
992 993
  Item_func_benchmark(Item *count_expr, Item *expr)
    :Item_int_func(count_expr, expr)
unknown's avatar
unknown committed
994 995 996
  {}
  longlong val_int();
  const char *func_name() const { return "benchmark"; }
unknown's avatar
unknown committed
997
  void fix_length_and_dec() { max_length=1; maybe_null=0; }
998
  virtual void print(String *str, enum_query_type query_type);
unknown's avatar
unknown committed
999 1000 1001
};


1002 1003 1004 1005
class Item_func_sleep :public Item_int_func
{
public:
  Item_func_sleep(Item *a) :Item_int_func(a) {}
1006
  bool const_item() const { return 0; }
1007
  const char *func_name() const { return "sleep"; }
1008 1009 1010 1011 1012
  void update_used_tables()
  {
    Item_int_func::update_used_tables();
    used_tables_cache|= RAND_TABLE_BIT;
  }
1013 1014 1015 1016 1017
  longlong val_int();
};



unknown's avatar
unknown committed
1018 1019 1020 1021
#ifdef HAVE_DLOPEN

class Item_udf_func :public Item_func
{
1022
protected:
unknown's avatar
unknown committed
1023 1024 1025
  udf_handler udf;

public:
1026 1027
  Item_udf_func(udf_func *udf_arg)
    :Item_func(), udf(udf_arg) {}
unknown's avatar
unknown committed
1028 1029 1030
  Item_udf_func(udf_func *udf_arg, List<Item> &list)
    :Item_func(list), udf(udf_arg) {}
  const char *func_name() const { return udf.name(); }
1031
  enum Functype functype() const   { return UDF_FUNC; }
1032
  bool fix_fields(THD *thd, Item **ref)
unknown's avatar
unknown committed
1033
  {
1034
    DBUG_ASSERT(fixed == 0);
1035
    bool res= udf.fix_fields(thd, this, arg_count, args);
unknown's avatar
unknown committed
1036 1037
    used_tables_cache= udf.used_tables_cache;
    const_item_cache= udf.const_item_cache;
1038
    fixed= 1;
unknown's avatar
unknown committed
1039 1040
    return res;
  }
1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
  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;
    }
  }
1091
  void cleanup();
unknown's avatar
unknown committed
1092
  Item_result result_type () const { return udf.result_type(); }
1093
  table_map not_null_tables() const { return 0; }
1094
  bool is_expensive() { return 1; }
1095
  virtual void print(String *str, enum_query_type query_type);
unknown's avatar
unknown committed
1096 1097 1098 1099 1100 1101
};


class Item_func_udf_float :public Item_udf_func
{
 public:
1102 1103 1104 1105 1106
  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) {}
1107
  longlong val_int()
1108 1109
  {
    DBUG_ASSERT(fixed == 1);
1110
    return (longlong) rint(Item_func_udf_float::val_real());
1111
  }
unknown's avatar
unknown committed
1112 1113 1114 1115 1116 1117 1118 1119
  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;
  }
1120
  double val_real();
unknown's avatar
unknown committed
1121 1122 1123 1124 1125 1126 1127 1128
  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:
1129 1130 1131 1132 1133
  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
1134
  longlong val_int();
1135
  double val_real() { return (double) Item_func_udf_int::val_int(); }
unknown's avatar
unknown committed
1136 1137
  String *val_str(String *str);
  enum Item_result result_type () const { return INT_RESULT; }
unknown's avatar
unknown committed
1138 1139 1140 1141 1142 1143 1144
  void fix_length_and_dec() { decimals= 0; max_length= 21; }
};


class Item_func_udf_decimal :public Item_udf_func
{
public:
1145 1146
  Item_func_udf_decimal(udf_func *udf_arg)
    :Item_udf_func(udf_arg) {}
unknown's avatar
unknown committed
1147
  Item_func_udf_decimal(udf_func *udf_arg, List<Item> &list)
1148
    :Item_udf_func(udf_arg, list) {}
unknown's avatar
unknown committed
1149 1150 1151 1152 1153 1154
  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
1155 1156 1157 1158 1159 1160
};


class Item_func_udf_str :public Item_udf_func
{
public:
1161 1162
  Item_func_udf_str(udf_func *udf_arg)
    :Item_udf_func(udf_arg) {}
unknown's avatar
unknown committed
1163
  Item_func_udf_str(udf_func *udf_arg, List<Item> &list)
1164
    :Item_udf_func(udf_arg, list) {}
unknown's avatar
unknown committed
1165
  String *val_str(String *);
1166
  double val_real()
unknown's avatar
unknown committed
1167
  {
unknown's avatar
unknown committed
1168 1169 1170 1171 1172 1173
    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
1174 1175 1176
  }
  longlong val_int()
  {
unknown's avatar
unknown committed
1177
    int err_not_used;
unknown's avatar
unknown committed
1178
    String *res;  res=val_str(&str_value);
unknown's avatar
unknown committed
1179 1180
    return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,
                             (char**) 0, &err_not_used) : (longlong) 0;
unknown's avatar
unknown committed
1181
  }
unknown's avatar
unknown committed
1182 1183 1184 1185 1186 1187 1188 1189
  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
1190 1191 1192 1193 1194 1195 1196 1197 1198
  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:
1199 1200 1201 1202
  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) {}
1203
  double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; }
unknown's avatar
unknown committed
1204 1205 1206 1207 1208 1209
};


class Item_func_udf_int :public Item_int_func
{
public:
1210 1211 1212 1213
  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) {}
1214
  longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; }
unknown's avatar
unknown committed
1215 1216 1217
};


unknown's avatar
unknown committed
1218 1219 1220
class Item_func_udf_decimal :public Item_int_func
{
public:
1221 1222 1223 1224
  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
1225 1226 1227 1228
  my_decimal *val_decimal(my_decimal *) { DBUG_ASSERT(fixed == 1); return 0; }
};


unknown's avatar
unknown committed
1229 1230 1231
class Item_func_udf_str :public Item_func
{
public:
1232 1233 1234 1235
  Item_func_udf_str(udf_func *udf_arg)
    :Item_func() {}
  Item_func_udf_str(udf_func *udf_arg, List<Item> &list)
    :Item_func(list) {}
1236 1237
  String *val_str(String *)
    { DBUG_ASSERT(fixed == 1); null_value=1; return 0; }
1238
  double val_real() { DBUG_ASSERT(fixed == 1); null_value= 1; return 0.0; }
1239
  longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; }
unknown's avatar
unknown committed
1240 1241 1242 1243 1244 1245 1246 1247 1248 1249
  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
*/

1250
class User_level_lock;
unknown's avatar
unknown committed
1251
void item_user_lock_init(void);
1252
void item_user_lock_release(User_level_lock *ull);
unknown's avatar
unknown committed
1253 1254 1255 1256 1257 1258 1259 1260 1261
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
1262
  void fix_length_and_dec() { max_length=1; maybe_null=1;}
unknown's avatar
unknown committed
1263 1264 1265 1266 1267
};

class Item_func_release_lock :public Item_int_func
{
  String value;
1268
public:
unknown's avatar
unknown committed
1269 1270 1271
  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
1272
  void fix_length_and_dec() { max_length=1; maybe_null=1;}
unknown's avatar
unknown committed
1273 1274
};

unknown's avatar
unknown committed
1275 1276 1277 1278 1279
/* replication functions */

class Item_master_pos_wait :public Item_int_func
{
  String value;
1280
public:
unknown's avatar
unknown committed
1281
  Item_master_pos_wait(Item *a,Item *b) :Item_int_func(a,b) {}
1282
  Item_master_pos_wait(Item *a,Item *b,Item *c) :Item_int_func(a,b,c) {}
unknown's avatar
unknown committed
1283 1284
  longlong val_int();
  const char *func_name() const { return "master_pos_wait"; }
1285
  void fix_length_and_dec() { max_length=21; maybe_null=1;}
unknown's avatar
unknown committed
1286 1287
};

unknown's avatar
unknown committed
1288

unknown's avatar
unknown committed
1289
/* Handling of user definable variables */
unknown's avatar
unknown committed
1290 1291 1292 1293 1294 1295 1296

class user_var_entry;

class Item_func_set_user_var :public Item_func
{
  enum Item_result cached_result_type;
  user_var_entry *entry;
1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307
  /*
    The entry_thd variable is used:
    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
       may be shared between several connections, and the entry_thd field
       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).
  */
  THD *entry_thd;
1308 1309
  char buffer[MAX_FIELD_WIDTH];
  String value;
unknown's avatar
unknown committed
1310
  my_decimal decimal_buff;
1311
  bool null_item;
1312 1313 1314 1315 1316
  union
  {
    longlong vint;
    double vreal;
    String *vstr;
unknown's avatar
unknown committed
1317
    my_decimal *vdec;
1318
  } save_result;
unknown's avatar
unknown committed
1319 1320

public:
1321
  LEX_STRING name; // keep it public
1322
  Item_func_set_user_var(LEX_STRING a,Item *b)
1323 1324
    :Item_func(b), cached_result_type(INT_RESULT),
     entry(NULL), entry_thd(NULL), name(a)
1325
  {}
1326
  enum Functype functype() const { return SUSERVAR_FUNC; }
1327
  double val_real();
unknown's avatar
unknown committed
1328 1329
  longlong val_int();
  String *val_str(String *str);
unknown's avatar
unknown committed
1330
  my_decimal *val_decimal(my_decimal *);
unknown's avatar
unknown committed
1331
  double val_result();
1332
  longlong val_int_result();
unknown's avatar
unknown committed
1333
  String *str_result(String *str);
1334
  my_decimal *val_decimal_result(my_decimal *);
1335
  bool update_hash(void *ptr, uint length, enum Item_result type,
unknown's avatar
unknown committed
1336
  		   CHARSET_INFO *cs, Derivation dv, bool unsigned_arg);
1337
  bool send(Protocol *protocol, String *str_arg);
unknown's avatar
unknown committed
1338
  void make_field(Send_field *tmp_field);
1339
  bool check(bool use_result_field);
unknown's avatar
unknown committed
1340 1341
  bool update();
  enum Item_result result_type () const { return cached_result_type; }
1342
  bool fix_fields(THD *thd, Item **ref);
unknown's avatar
unknown committed
1343
  void fix_length_and_dec();
1344 1345
  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
1346
  const char *func_name() const { return "set_user_var"; }
1347 1348 1349 1350 1351 1352 1353
  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
1354
  bool register_field_in_read_map(uchar *arg);
1355
  bool set_entry(THD *thd, bool create_if_not_exists);
unknown's avatar
unknown committed
1356 1357 1358
};


1359 1360
class Item_func_get_user_var :public Item_func,
                              private Settable_routine_parameter
unknown's avatar
unknown committed
1361
{
1362
  user_var_entry *var_entry;
1363
  Item_result m_cached_result_type;
unknown's avatar
unknown committed
1364 1365

public:
1366
  LEX_STRING name; // keep it public
1367
  Item_func_get_user_var(LEX_STRING a):
unknown's avatar
unknown committed
1368
    Item_func(), m_cached_result_type(STRING_RESULT), name(a) {}
1369 1370
  enum Functype functype() const { return GUSERVAR_FUNC; }
  LEX_STRING get_name() { return name; }
1371
  double val_real();
unknown's avatar
unknown committed
1372
  longlong val_int();
unknown's avatar
unknown committed
1373
  my_decimal *val_decimal(my_decimal*);
unknown's avatar
unknown committed
1374 1375
  String *val_str(String* str);
  void fix_length_and_dec();
1376
  virtual void print(String *str, enum_query_type query_type);
unknown's avatar
unknown committed
1377
  enum Item_result result_type() const;
1378 1379 1380 1381
  /*
    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
1382
  const char *func_name() const { return "get_user_var"; }
1383
  bool const_item() const;
1384
  table_map used_tables() const
1385
  { return const_item() ? 0 : RAND_TABLE_BIT; }
1386
  bool eq(const Item *item, bool binary_cmp) const;
1387
private:
1388
  bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
1389 1390 1391 1392 1393 1394

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

unknown's avatar
unknown committed
1397

unknown's avatar
unknown committed
1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419
/*
  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:
  Item_user_var_as_out_param(LEX_STRING a) : name(a) {}
  /* 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 */
1420
  bool fix_fields(THD *thd, Item **ref);
1421
  virtual void print(String *str, enum_query_type query_type);
unknown's avatar
unknown committed
1422 1423 1424 1425 1426
  void set_null_value(CHARSET_INFO* cs);
  void set_value(const char *str, uint length, CHARSET_INFO* cs);
};


1427 1428
/* A system variable */

1429 1430 1431 1432
#define GET_SYS_VAR_CACHE_LONG     1
#define GET_SYS_VAR_CACHE_DOUBLE   2
#define GET_SYS_VAR_CACHE_STRING   4

1433 1434 1435
class Item_func_get_system_var :public Item_func
{
  sys_var *var;
Georgi Kodinov's avatar
Georgi Kodinov committed
1436
  enum_var_type var_type, orig_var_type;
1437
  LEX_STRING component;
1438 1439 1440 1441 1442 1443 1444
  longlong cached_llval;
  double cached_dval;
  String cached_strval;
  my_bool cached_null_value;
  query_id_t used_query_id;
  uchar cache_present;

1445 1446 1447 1448
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);
1449 1450 1451 1452 1453 1454 1455 1456 1457 1458
  enum Functype functype() const { return GSYSVAR_FUNC; }
  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
1459 1460
  /* TODO: fix to support views */
  const char *func_name() const { return "get_system_var"; }
1461 1462 1463 1464 1465 1466 1467 1468 1469
  /**
    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();
1470
  bool eq(const Item *item, bool binary_cmp) const;
Georgi Kodinov's avatar
Georgi Kodinov committed
1471 1472

  void cleanup();
1473 1474 1475
};


unknown's avatar
unknown committed
1476 1477 1478
class Item_func_inet_aton : public Item_int_func
{
public:
1479 1480 1481 1482
  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
1483 1484 1485
};


1486
/* for fulltext search */
1487
#include <ft_global.h>
unknown's avatar
unknown committed
1488 1489 1490 1491

class Item_func_match :public Item_real_func
{
public:
1492
  uint key, flags;
unknown's avatar
unknown committed
1493
  bool join_key;
1494 1495 1496 1497
  DTCollation cmp_collation;
  FT_INFO *ft_handler;
  TABLE *table;
  Item_func_match *master;   // for master-slave optimization
1498 1499
  Item *concat_ws;           // Item_func_concat_ws
  String value;              // value of concat_ws
1500
  String search_value;       // key_item()'s value converted to cmp_collation
unknown's avatar
unknown committed
1501

unknown's avatar
unknown committed
1502
  Item_func_match(List<Item> &a, uint b): Item_real_func(a), key(0), flags(b),
1503
       join_key(0), ft_handler(0), table(0), master(0), concat_ws(0) { }
unknown's avatar
unknown committed
1504
  void cleanup()
1505
  {
unknown's avatar
unknown committed
1506
    DBUG_ENTER("Item_func_match");
1507
    Item_real_func::cleanup();
1508
    if (!master && ft_handler)
unknown's avatar
unknown committed
1509
      ft_handler->please->close_search(ft_handler);
1510
    ft_handler= 0;
1511
    concat_ws= 0;
unknown's avatar
unknown committed
1512
    DBUG_VOID_RETURN;
1513
  }
unknown's avatar
unknown committed
1514
  enum Functype functype() const { return FT_FUNC; }
1515
  const char *func_name() const { return "match"; }
unknown's avatar
unknown committed
1516
  void update_used_tables() {}
1517
  table_map not_null_tables() const { return 0; }
1518
  bool fix_fields(THD *thd, Item **ref);
1519
  bool eq(const Item *, bool binary_cmp) const;
1520
  /* The following should be safe, even if we compare doubles */
1521 1522
  longlong val_int() { DBUG_ASSERT(fixed == 1); return val_real() != 0.0; }
  double val_real();
1523
  virtual void print(String *str, enum_query_type query_type);
1524 1525

  bool fix_index();
1526
  void init_search(bool no_order);
1527
};
unknown's avatar
unknown committed
1528

unknown's avatar
unknown committed
1529

1530
class Item_func_bit_xor : public Item_func_bit
unknown's avatar
unknown committed
1531 1532
{
public:
1533
  Item_func_bit_xor(Item *a, Item *b) :Item_func_bit(a, b) {}
unknown's avatar
unknown committed
1534 1535 1536 1537
  longlong val_int();
  const char *func_name() const { return "^"; }
};

1538
class Item_func_is_free_lock :public Item_int_func
unknown's avatar
unknown committed
1539 1540 1541
{
  String value;
public:
1542
  Item_func_is_free_lock(Item *a) :Item_int_func(a) {}
unknown's avatar
unknown committed
1543
  longlong val_int();
1544
  const char *func_name() const { return "is_free_lock"; }
unknown's avatar
unknown committed
1545
  void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
unknown's avatar
unknown committed
1546 1547
};

unknown's avatar
SCRUM  
unknown committed
1548 1549 1550 1551 1552 1553 1554 1555 1556 1557
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
1558 1559
/* For type casts */

1560
enum Cast_target
unknown's avatar
unknown committed
1561 1562
{
  ITEM_CAST_BINARY, ITEM_CAST_SIGNED_INT, ITEM_CAST_UNSIGNED_INT,
unknown's avatar
unknown committed
1563 1564
  ITEM_CAST_DATE, ITEM_CAST_TIME, ITEM_CAST_DATETIME, ITEM_CAST_CHAR,
  ITEM_CAST_DECIMAL
unknown's avatar
unknown committed
1565
};
1566 1567


1568 1569 1570 1571 1572 1573 1574 1575 1576 1577
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; }
};


1578 1579 1580 1581 1582 1583 1584
/*
 *
 * Stored FUNCTIONs
 *
 */

class sp_head;
1585
class sp_name;
1586
struct st_sp_security_context;
1587 1588 1589 1590

class Item_func_sp :public Item_func
{
private:
1591
  Name_resolution_context *context;
1592
  sp_name *m_name;
1593
  mutable sp_head *m_sp;
unknown's avatar
unknown committed
1594
  TABLE *dummy_table;
1595
  uchar result_buf[64];
1596 1597 1598 1599
  /*
     The result field of the concrete stored function.
  */
  Field *sp_result_field;
1600

1601 1602 1603
  bool execute();
  bool execute_impl(THD *thd);
  bool init_result_field(THD *thd);
1604
  
1605 1606
public:

1607
  Item_func_sp(Name_resolution_context *context_arg, sp_name *name);
1608

1609 1610
  Item_func_sp(Name_resolution_context *context_arg,
               sp_name *name, List<Item> &list);
1611 1612 1613 1614

  virtual ~Item_func_sp()
  {}

unknown's avatar
unknown committed
1615
  void update_used_tables();
1616

1617
  void cleanup();
1618

1619
  const char *func_name() const;
1620

1621 1622
  enum enum_field_types field_type() const;

unknown's avatar
unknown committed
1623 1624 1625 1626
  Field *tmp_table_field(TABLE *t_arg);

  void make_field(Send_field *tmp_field);

1627 1628 1629 1630
  Item_result result_type() const;

  longlong val_int()
  {
1631
    if (execute())
unknown's avatar
unknown committed
1632
      return (longlong) 0;
1633
    return sp_result_field->val_int();
1634 1635
  }

1636
  double val_real()
1637
  {
1638
    if (execute())
1639
      return 0.0;
1640
    return sp_result_field->val_real();
1641 1642
  }

unknown's avatar
unknown committed
1643 1644
  my_decimal *val_decimal(my_decimal *dec_buf)
  {
1645
    if (execute())
unknown's avatar
unknown committed
1646
      return NULL;
1647
    return sp_result_field->val_decimal(dec_buf);
unknown's avatar
unknown committed
1648 1649
  }

1650 1651
  String *val_str(String *str)
  {
1652 1653 1654 1655
    String buf;
    char buff[20];
    buf.set(buff, 20, str->charset());
    buf.length(0);
1656
    if (execute())
1657
      return NULL;
1658 1659 1660 1661 1662 1663
    /*
      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.
    */
1664
    sp_result_field->val_str(&buf);
1665 1666
    str->copy(buf);
    return str;
1667 1668
  }

1669
  virtual bool change_context_processor(uchar *cntx)
1670 1671
    { context= (Name_resolution_context *)cntx; return FALSE; }

1672
  bool sp_check_access(THD * thd);
1673
  virtual enum Functype functype() const { return FUNC_SP; }
1674

1675
  bool fix_fields(THD *thd, Item **ref);
1676
  void fix_length_and_dec(void);
1677
  bool is_expensive() { return 1; }
1678 1679 1680 1681 1682

  inline Field *get_sp_result_field()
  {
    return sp_result_field;
  }
1683
};
unknown's avatar
unknown committed
1684 1685


1686 1687 1688 1689 1690 1691 1692 1693
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; }
};
1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705


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; }
1706
  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
1707 1708
};