item.h 37.1 KB
Newer Older
1
/* Copyright (C) 2000-2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
2

bk@work.mysql.com's avatar
bk@work.mysql.com committed
3 4 5 6
   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
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
7

bk@work.mysql.com's avatar
bk@work.mysql.com committed
8 9 10 11
   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.
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
12

bk@work.mysql.com's avatar
bk@work.mysql.com committed
13 14 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 */


#ifdef __GNUC__
#pragma interface			/* gcc class implementation */
#endif

22
class Protocol;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
23
struct st_table_list;
24
void item_init(void);			/* Init item functions */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
25

26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

/*
   "Declared Type Collation"
   A combination of collation and its deriviation.
*/

enum Derivation
{
  DERIVATION_COERCIBLE= 3,
  DERIVATION_IMPLICIT= 2,
  DERIVATION_NONE= 1,
  DERIVATION_EXPLICIT= 0
};

class DTCollation {
public:
  CHARSET_INFO     *collation;
  enum Derivation derivation;
  
  DTCollation()
  {
    collation= &my_charset_bin;
    derivation= DERIVATION_NONE;
  }
  DTCollation(CHARSET_INFO *collation_arg, Derivation derivation_arg)
  {
    collation= collation_arg;
    derivation= derivation_arg;
  }
55
  void set(DTCollation &dt)
56
  { 
57 58
    collation= dt.collation;
    derivation= dt.derivation;
59 60 61 62 63 64 65 66 67 68
  }
  void set(CHARSET_INFO *collation_arg, Derivation derivation_arg)
  {
    collation= collation_arg;
    derivation= derivation_arg;
  }
  void set(CHARSET_INFO *collation_arg)
  { collation= collation_arg; }
  void set(Derivation derivation_arg)
  { derivation= derivation_arg; }
69 70 71
  bool aggregate(DTCollation &dt);
  bool set(DTCollation &dt1, DTCollation &dt2)
  { set(dt1); return aggregate(dt2); }
72 73 74 75 76 77 78 79 80 81 82 83 84
  const char *derivation_name() const
  {
    switch(derivation)
    {
      case DERIVATION_COERCIBLE: return "COERCIBLE";
      case DERIVATION_IMPLICIT:  return "IMPLICIT";
      case DERIVATION_EXPLICIT:  return "EXPLICIT";
      case DERIVATION_NONE:      return "NONE";
      default: return "UNKNOWN";
    }
  }
};

bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
85 86
typedef bool (Item::*Item_processor)(byte *arg);

bk@work.mysql.com's avatar
bk@work.mysql.com committed
87
class Item {
88
  Item(const Item &);			/* Prevent use of these */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
89 90
  void operator=(Item &);
public:
monty@donna.mysql.com's avatar
monty@donna.mysql.com committed
91
  static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); }
92 93
  static void *operator new(size_t size, MEM_ROOT *mem_root)
  { return (void*) alloc_root(mem_root, (uint) size); }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
94 95
  static void operator delete(void *ptr,size_t size) {} /*lint -e715 */

96 97
  enum Type {FIELD_ITEM, FUNC_ITEM, SUM_FUNC_ITEM, STRING_ITEM,
	     INT_ITEM, REAL_ITEM, NULL_ITEM, VARBIN_ITEM,
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
98
	     COPY_STR_ITEM, FIELD_AVG_ITEM, DEFAULT_VALUE_ITEM,
99 100
	     PROC_ITEM,COND_ITEM, REF_ITEM, FIELD_STD_ITEM,
	     FIELD_VARIANCE_ITEM, INSERT_VALUE_ITEM,
101
             SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER};
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
102

bk@work.mysql.com's avatar
bk@work.mysql.com committed
103
  enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
104
  
monty@mysql.com's avatar
monty@mysql.com committed
105 106 107 108 109
  /*
    str_values's main purpose is to be used to cache the value in
    save_in_field
  */
  String str_value;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
110 111 112
  my_string name;			/* Name from select */
  Item *next;
  uint32 max_length;
113
  uint name_length;                     /* Length of name */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
114 115 116
  uint8 marker,decimals;
  my_bool maybe_null;			/* If item may be null */
  my_bool null_value;			/* if item is null */
117
  my_bool unsigned_flag;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
118
  my_bool with_sum_func;
119
  my_bool fixed;                        /* If item fixed with fix_fields */
120
  DTCollation collation;
121

bk@work.mysql.com's avatar
bk@work.mysql.com committed
122 123
  // alloc & destruct is done as start of select using sql_alloc
  Item();
124 125 126 127
  /*
     Constructor used by Item_field, Item_ref & agregate (sum) functions.
     Used for duplicating lists in processing queries with temporary
     tables
128 129 130
     Also it used for Item_cond_and/Item_cond_or for creating
     top AND/OR ctructure of WHERE clause to protect it of
     optimisation changes in prepared statements
131
  */
132
  Item(THD *thd, Item *item);
133
  virtual ~Item() { name=0; }		/*lint -e1509 */
bar@bar.mysql.r18.ru's avatar
bar@bar.mysql.r18.ru committed
134
  void set_name(const char *str,uint length, CHARSET_INFO *cs);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
135
  void init_make_field(Send_field *tmp_field,enum enum_field_types type);
136 137 138 139 140 141 142
  virtual void cleanup()
  {
    DBUG_ENTER("Item::cleanup");
    DBUG_PRINT("info", ("Type: %d", (int)type()));
    fixed=0;
    DBUG_VOID_RETURN;
  }
143
  virtual void make_field(Send_field *field);
144
  virtual bool fix_fields(THD *, struct st_table_list *, Item **);
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
145
  /*
monty@mysql.com's avatar
monty@mysql.com committed
146
    should be used in case where we are sure that we do not need
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
147 148 149
    complete fix_fields() procedure.
  */
  inline void quick_fix_field() { fixed= 1; }
monty@mysql.com's avatar
monty@mysql.com committed
150
  /* Function returns 1 on overflow and -1 on fatal errors */
monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
151
  virtual int save_in_field(Field *field, bool no_conversions);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
152
  virtual void save_org_in_field(Field *field)
153
  { (void) save_in_field(field, 1); }
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
154
  virtual int save_safe_in_field(Field *field)
155
  { return save_in_field(field, 1); }
156
  virtual bool send(Protocol *protocol, String *str);
157
  virtual bool eq(const Item *, bool binary_cmp) const;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
158
  virtual Item_result result_type () const { return REAL_RESULT; }
159
  virtual enum_field_types field_type() const;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
160
  virtual enum Type type() const =0;
161
  /* valXXX methods must return NULL or 0 or 0.0 if null_value is set. */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
162 163 164
  virtual double val()=0;
  virtual longlong val_int()=0;
  virtual String *val_str(String*)=0;
165
  virtual Field *get_tmp_table_field() { return 0; }
166
  virtual Field *tmp_table_field(TABLE *t_arg) { return 0; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
167 168 169 170
  virtual const char *full_name() const { return name ? name : "???"; }
  virtual double  val_result() { return val(); }
  virtual longlong val_int_result() { return val_int(); }
  virtual String *str_result(String* tmp) { return val_str(tmp); }
171
  /* bit map of tables used by item */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
172
  virtual table_map used_tables() const { return (table_map) 0L; }
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
  /*
    Return table map of tables that can't be NULL tables (tables that are
    used in a context where if they would contain a NULL row generated
    by a LEFT or RIGHT join, the item would not be true).
    This expression is used on WHERE item to determinate if a LEFT JOIN can be
    converted to a normal join.
    Generally this function should return used_tables() if the function
    would return null if any of the arguments are null
    As this is only used in the beginning of optimization, the value don't
    have to be updated in update_used_tables()
  */
  virtual table_map not_null_tables() const { return used_tables(); }
  /*
    Returns true if this is a simple constant item like an integer, not
    a constant expression
  */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
189 190 191 192 193
  virtual bool basic_const_item() const { return 0; }
  virtual Item *new_item() { return 0; }	/* Only for const items */
  virtual cond_result eq_cmp_result() const { return COND_OK; }
  inline uint float_length(uint decimals_par) const
  { return decimals != NOT_FIXED_DEC ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;}
194 195 196 197
  /* 
    Returns true if this is constant (during query execution, i.e. its value
    will not change until next fix_fields) and its value is known.
  */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
198
  virtual bool const_item() const { return used_tables() == 0; }
199 200 201 202 203 204
  /* 
    Returns true if this is constant but its value may be not known yet.
    (Can be used for parameters of prep. stmts or of stored procedures.)
  */
  virtual bool const_during_execution() const 
  { return (used_tables() & ~PARAM_TABLE_BIT) == 0; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
205
  virtual void print(String *str_arg) { str_arg->append(full_name()); }
206
  void print_item_w_name(String *);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
207
  virtual void update_used_tables() {}
208
  virtual void split_sum_func(Item **ref_pointer_array, List<Item> &fields) {}
209
  virtual bool get_date(TIME *ltime,uint fuzzydate);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
210
  virtual bool get_time(TIME *ltime);
211
  virtual bool get_date_result(TIME *ltime,uint fuzzydate)
212
  { return get_date(ltime,fuzzydate); }
213
  virtual bool is_null() { return 0; }
214
  virtual void top_level_item() {}
monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
215 216 217
  virtual void set_result_field(Field *field) {}
  virtual bool is_result_field() { return 0; }
  virtual void save_in_result_field(bool no_conversions) {}
218
  virtual void no_rows_in_result() {}
219
  virtual Item *copy_or_same(THD *thd) { return this; }
220
  virtual Item *copy_andor_structure(THD *thd) { return this; }
221
  virtual Item *real_item() { return this; }
222
  virtual Item *get_tmp_table_item(THD *thd) { return copy_or_same(thd); }
223

224
  CHARSET_INFO *default_charset() const;
225
  virtual CHARSET_INFO *compare_collation() { return NULL; }
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
226 227 228 229 230 231 232

  virtual bool walk(Item_processor processor, byte *arg)
  {
    return (this->*processor)(arg);
  }

  virtual bool remove_dependence_processor(byte * arg) { return 0; }
233
  virtual bool remove_fixed(byte * arg) { fixed= 0; return 0; }
234
  
235 236
  virtual Item *this_item() { return this; } /* For SPs mostly. */
  virtual Item *this_const_item() const { return const_cast<Item*>(this); } /* For SPs mostly. */
237 238 239 240

  // Row emulation
  virtual uint cols() { return 1; }
  virtual Item* el(uint i) { return this; }
241
  virtual Item** addr(uint i) { return 0; }
242
  virtual bool check_cols(uint c);
243
  // It is not row => null inside is impossible
244 245 246
  virtual bool null_inside() { return 0; }
  // used in row subselects to get value of elements
  virtual void bring_value() {}
247 248

  Field *tmp_table_field_from_field_type(TABLE *table);
249 250
  
  /* Used in sql_select.cc:eliminate_not_funcs() */
251
  virtual Item *neg_transformer(THD *thd) { return NULL; }
252 253 254 255
  void delete_self()
  {
    cleanup();
    delete this;
pem@mysql.comhem.se's avatar
pem@mysql.comhem.se committed
256
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
257 258 259
};


260 261 262 263 264 265
// A local SP variable (incl. parameters), used in runtime
class Item_splocal : public Item
{
private:
  
  uint m_offset;
266
  LEX_STRING m_name;
267 268 269

public:

270 271
  Item_splocal(LEX_STRING name, uint offset)
    : m_offset(offset), m_name(name)
272 273 274
  {
    Item::maybe_null= TRUE;
  }
275 276 277 278 279 280 281 282 283 284 285

  Item *this_item();
  Item *this_const_item() const;

  inline uint get_offset()
  {
    return m_offset;
  }

  // Abstract methods inherited from Item. Just defer the call to
  // the item in the frame
286
  enum Type type() const;
287 288 289

  inline double val()
  {
290 291 292 293
    Item *it= this_item();
    double ret= it->val();
    Item::null_value= it->null_value;
    return ret;
294 295 296 297
  }

  inline longlong val_int()
  {
298 299 300 301
    Item *it= this_item();
    longlong ret= it->val_int();
    Item::null_value= it->null_value;
    return ret;
302 303 304 305
  }

  inline String *val_str(String *sp)
  {
306 307 308 309 310 311 312 313 314 315 316 317
    Item *it= this_item();
    String *ret= it->val_str(sp);
    Item::null_value= it->null_value;
    return ret;
  }

  inline bool is_null()
  {
    Item *it= this_item();
    bool ret= it->is_null();
    Item::null_value= it->null_value;
    return ret;
318 319 320 321
  }

  inline void make_field(Send_field *field)
  {
322 323 324 325
    Item *it= this_item();

    it->set_name(m_name.str, m_name.length, system_charset_info);
    it->make_field(field);
326 327
  }

328 329 330 331 332 333 334
  inline Item_result result_type() const
  {
    return this_const_item()->result_type();
  }

  inline bool const_item() const
  {
335
    return TRUE;
336 337
  }

338 339 340 341
  inline int save_in_field(Field *field, bool no_conversions)
  {
    return this_item()->save_in_field(field, no_conversions);
  }
342 343 344

  inline void print(String *str)
  {
345
    str->reserve(m_name.length+8);
346
    str->append(m_name.str, m_name.length);
347 348
    str->append('@');
    str->qs_append(m_offset);
349
  }
350 351 352 353 354

  inline bool send(Protocol *protocol, String *str)
  {
    return this_item()->send(protocol, str);
  }
355 356 357
};


358 359 360
class Item_num: public Item
{
public:
monty@mysql.com's avatar
monty@mysql.com committed
361
  virtual Item_num *neg()= 0;
362 363
};

364
#define NO_CACHED_FIELD_INDEX ((uint)(-1))
365

366
class st_select_lex;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
367 368
class Item_ident :public Item
{
369 370 371 372 373 374 375 376 377
  /* 
    We have to store initial values of db_name, table_name and field_name
    to be able to restore them during cleanup() because they can be 
    updated during fix_fields() to values from Field object and life-time 
    of those is shorter than life-time of Item_field.
  */
  const char *orig_db_name;
  const char *orig_table_name;
  const char *orig_field_name;
378
  Item **changed_during_fix_field;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
379 380 381 382
public:
  const char *db_name;
  const char *table_name;
  const char *field_name;
383 384
  /* 
    Cached value of index for this field in table->field array, used by prep. 
385 386 387 388 389 390 391 392
    stmts for speeding up their re-execution. Holds NO_CACHED_FIELD_INDEX 
    if index value is not known.
  */
  uint cached_field_index;
  /*
    Cached pointer to table which contains this field, used for the same reason
    by prep. stmt. too in case then we have not-fully qualified field.
    0 - means no cached value.
393
  */
394
  TABLE_LIST *cached_table;
395
  st_select_lex *depended_from;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
396
  Item_ident(const char *db_name_par,const char *table_name_par,
397
	     const char *field_name_par);
pem@mysql.com's avatar
pem@mysql.com committed
398
  Item_ident(THD *thd, Item_ident *item);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
399
  const char *full_name() const;
400 401 402
  void cleanup();
  void register_item_tree_changing(Item **ref)
    { changed_during_fix_field= ref; }
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
403
  bool remove_dependence_processor(byte * arg);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
404 405
};

406

bk@work.mysql.com's avatar
bk@work.mysql.com committed
407 408 409 410 411
class Item_field :public Item_ident
{
  void set_field(Field *field);
public:
  Field *field,*result_field;
412 413 414
#ifndef DBUG_OFF
  bool double_fix;
#endif
bk@work.mysql.com's avatar
bk@work.mysql.com committed
415 416 417

  Item_field(const char *db_par,const char *table_name_par,
	     const char *field_name_par)
418 419 420 421 422
    :Item_ident(db_par,table_name_par,field_name_par),
     field(0), result_field(0)
#ifndef DBUG_OFF
    ,double_fix(0)
#endif
423
  { collation.set(DERIVATION_IMPLICIT); }
424
  // Constructor need to process subselect with temporary tables (see Item)
425
  Item_field(THD *thd, Item_field *item);
426 427 428 429 430
  /*
    Constructor used inside setup_wild(), ensures that field and table
    names will live as long as Item_field (important in prep. stmt.)
  */
  Item_field(THD *thd, Field *field);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
431 432
  Item_field(Field *field);
  enum Type type() const { return FIELD_ITEM; }
433
  bool eq(const Item *item, bool binary_cmp) const;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
434 435 436 437 438 439
  double val();
  longlong val_int();
  String *val_str(String*);
  double val_result();
  longlong val_int_result();
  String *str_result(String* tmp);
440
  bool send(Protocol *protocol, String *str_arg);
441
  bool fix_fields(THD *, struct st_table_list *, Item **);
442
  void make_field(Send_field *tmp_field);
monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
443
  int save_in_field(Field *field,bool no_conversions);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
444 445 446 447 448 449
  void save_org_in_field(Field *field);
  table_map used_tables() const;
  enum Item_result result_type () const
  {
    return field->result_type();
  }
450
  enum_field_types field_type() const
451 452 453
  {
    return field->type();
  }
454
  Field *get_tmp_table_field() { return result_field; }
455
  Field *tmp_table_field(TABLE *t_arg) { return result_field; }
456 457
  bool get_date(TIME *ltime,uint fuzzydate);
  bool get_date_result(TIME *ltime,uint fuzzydate);
458
  bool get_time(TIME *ltime);
459
  bool is_null() { return field->is_null(); }
460
  Item *get_tmp_table_item(THD *thd);
hf@deer.(none)'s avatar
hf@deer.(none) committed
461
  void cleanup();
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
462
  friend class Item_default_value;
463
  friend class Item_insert_value;
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
464
  friend class st_select_lex_unit;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
465 466 467 468 469 470
};

class Item_null :public Item
{
public:
  Item_null(char *name_par=0)
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
471 472 473 474 475 476
  {
    maybe_null= null_value= TRUE;
    max_length= 0;
    name= name_par ? name_par : (char*) "NULL";
    fixed= 1;
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
477
  enum Type type() const { return NULL_ITEM; }
478
  bool eq(const Item *item, bool binary_cmp) const;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
479 480 481
  double val();
  longlong val_int();
  String *val_str(String *str);
monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
482
  int save_in_field(Field *field, bool no_conversions);
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
483
  int save_safe_in_field(Field *field);
hf@deer.mysql.r18.ru's avatar
hf@deer.mysql.r18.ru committed
484
  bool send(Protocol *protocol, String *str);
485 486
  enum Item_result result_type () const { return STRING_RESULT; }
  enum_field_types field_type() const   { return MYSQL_TYPE_NULL; }
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
487 488
  // to prevent drop fixed flag (no need parent cleanup call)
  void cleanup() {}
bk@work.mysql.com's avatar
bk@work.mysql.com committed
489 490
  bool basic_const_item() const { return 1; }
  Item *new_item() { return new Item_null(name); }
491
  bool is_null() { return 1; }
492
  void print(String *str) { str->append("NULL", 4); }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
493 494
};

495 496 497
class Item_param :public Item
{
public:    
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528
  enum enum_item_param_state
  {
    NO_VALUE, NULL_VALUE, INT_VALUE, REAL_VALUE,
    STRING_VALUE, TIME_VALUE, LONG_DATA_VALUE
  } state;

  union
  {
    longlong integer;                           
    double   real;                              
    /*
      Character sets conversion info for string values.
      Character sets of client and connection defined at bind time are used
      for all conversions, even if one of them is later changed (i.e.
      between subsequent calls to mysql_stmt_execute).
    */
    struct CONVERSION_INFO
    {
      CHARSET_INFO *character_set_client;
      /*
        This points at character set of connection if conversion
        to it is required (i. e. if placeholder typecode is not BLOB).
        Otherwise it's equal to character_set_client (to simplify 
        check in convert_str_value()).
      */
      CHARSET_INFO *final_character_set_of_str_value;
    } cs_info;
    TIME     time;
  } value;

  /* Cached values for virtual methods to save us one switch.  */
529 530
  enum Item_result item_result_type;
  enum Type item_type;
531 532 533 534
  /*         
    Offset of placeholder inside statement text. Used to create
    no-placeholders version of this statement for the binary log.
  */         
535
  uint pos_in_query;
536

537 538 539
  Item_param(uint pos_in_query_arg);

  enum Item_result result_type () const { return item_result_type; }
540
  enum Type type() const { return item_type; }
541 542
  enum_field_types field_type() const { return MYSQL_TYPE_STRING; }

543 544 545
  double val();
  longlong val_int();
  String *val_str(String*);
546
  bool get_time(TIME *tm);
venu@myvenu.com's avatar
venu@myvenu.com committed
547
  int  save_in_field(Field *field, bool no_conversions);
548

549
  void set_null();
550
  void set_int(longlong i, uint32 max_length_arg);
551
  void set_double(double i);
552 553 554
  bool set_str(const char *str, ulong length);
  bool set_longdata(const char *str, ulong length);
  void set_time(TIME *tm, timestamp_type type, uint32 max_length_arg);
555
  void reset();
556 557 558 559 560 561 562 563
  /*
    Assign placeholder value from bind data.
    Note, that 'len' has different semantics in embedded library (as we
    don't need to check that packet is not broken there). See
    sql_prepare.cc for details.
  */
  void (*set_param_func)(Item_param *param, uchar **pos, ulong len);

564 565 566 567
  const String *query_val_str(String *str) const;

  bool convert_str_value(THD *thd);
  
568
  Item *new_item() { return new Item_param(pos_in_query); }
569 570 571 572 573 574
  /* 
    If value for parameter was not set we treat it as non-const 
    so noone will use parameters value in fix_fields still 
    parameter is constant during execution.
  */
  virtual table_map used_tables() const
575
  { return state != NO_VALUE ? (table_map)0 : PARAM_TABLE_BIT; }
576
  void print(String *str) { str->append('?'); }
577
};
bk@work.mysql.com's avatar
bk@work.mysql.com committed
578

579
class Item_int :public Item_num
bk@work.mysql.com's avatar
bk@work.mysql.com committed
580 581
{
public:
582
  longlong value;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
583
  Item_int(int32 i,uint length=11) :value((longlong) i)
584
    { max_length=length; fixed= 1; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
585 586
#ifdef HAVE_LONG_LONG
  Item_int(longlong i,uint length=21) :value(i)
587
    { max_length=length; fixed= 1;}
bk@work.mysql.com's avatar
bk@work.mysql.com committed
588 589
#endif
  Item_int(const char *str_arg,longlong i,uint length) :value(i)
590
    { max_length=length; name=(char*) str_arg; fixed= 1; }
monty@mysql.com's avatar
monty@mysql.com committed
591
  Item_int(const char *str_arg, uint length=64);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
592
  enum Type type() const { return INT_ITEM; }
593 594
  enum Item_result result_type () const { return INT_RESULT; }
  enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
595 596
  longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
  double val() { DBUG_ASSERT(fixed == 1); return (double) value; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
597
  String *val_str(String*);
monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
598
  int save_in_field(Field *field, bool no_conversions);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
599 600
  bool basic_const_item() const { return 1; }
  Item *new_item() { return new Item_int(name,value,max_length); }
601
  // to prevent drop fixed flag (no need parent cleanup call)
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
602
  void cleanup() {}
bk@work.mysql.com's avatar
bk@work.mysql.com committed
603
  void print(String *str);
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
604
  Item_num *neg() { value= -value; return this; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
605 606 607
};


608 609 610
class Item_uint :public Item_int
{
public:
monty@mysql.com's avatar
monty@mysql.com committed
611
  Item_uint(const char *str_arg, uint length);
612
  Item_uint(uint32 i) :Item_int((longlong) i, 10) 
ram@gw.mysql.r18.ru's avatar
ram@gw.mysql.r18.ru committed
613
    { unsigned_flag= 1; }
614 615
  double val()
    { DBUG_ASSERT(fixed == 1); return ulonglong2double((ulonglong)value); }
616 617
  String *val_str(String*);
  Item *new_item() { return new Item_uint(name,max_length); }
monty@mysql.com's avatar
monty@mysql.com committed
618
  int save_in_field(Field *field, bool no_conversions);
619
  void print(String *str);
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
620
  Item_num *neg ();
621 622 623
};


624
class Item_real :public Item_num
bk@work.mysql.com's avatar
bk@work.mysql.com committed
625 626
{
public:
627
  double value;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
628
  // Item_real() :value(0) {}
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
629
  Item_real(const char *str_arg, uint length) :value(my_atof(str_arg))
bk@work.mysql.com's avatar
bk@work.mysql.com committed
630 631
  {
    name=(char*) str_arg;
632
    decimals=(uint8) nr_of_decimals(str_arg);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
633
    max_length=length;
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
634
    fixed= 1;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
635 636 637 638 639
  }
  Item_real(const char *str,double val_arg,uint decimal_par,uint length)
    :value(val_arg)
  {
    name=(char*) str;
640
    decimals=(uint8) decimal_par;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
641
    max_length=length;
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
642
    fixed= 1;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
643
  }
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
644
  Item_real(double value_par) :value(value_par) { fixed= 1; }
monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
645
  int save_in_field(Field *field, bool no_conversions);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
646
  enum Type type() const { return REAL_ITEM; }
647
  enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
648 649 650 651 652 653
  double val() { DBUG_ASSERT(fixed == 1); return value; }
  longlong val_int()
  {
    DBUG_ASSERT(fixed == 1);
    return (longlong) (value+(value > 0 ? 0.5 : -0.5));
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
654 655
  String *val_str(String*);
  bool basic_const_item() const { return 1; }
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
656 657
  // to prevent drop fixed flag (no need parent cleanup call)
  void cleanup() {}
bk@work.mysql.com's avatar
bk@work.mysql.com committed
658
  Item *new_item() { return new Item_real(name,value,decimals,max_length); }
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
659
  Item_num *neg() { value= -value; return this; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675
};


class Item_float :public Item_real
{
public:
  Item_float(const char *str,uint length) :Item_real(str,length)
  {
    decimals=NOT_FIXED_DEC;
    max_length=DBL_DIG+8;
  }
};

class Item_string :public Item
{
public:
bar@bar.mysql.r18.ru's avatar
bar@bar.mysql.r18.ru committed
676
  Item_string(const char *str,uint length,
677
  	      CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
678
  {
679
    collation.set(cs, dv);
680
    str_value.set_or_copy_aligned(str,length,cs);
681 682 683 684 685 686 687
    /*
      We have to have a different max_length than 'length' here to
      ensure that we get the right length if we do use the item
      to create a new table. In this case max_length must be the maximum
      number of chars for a string of this type because we in create_field::
      divide the max_length with mbmaxlen).
    */
688
    max_length= str_value.numchars()*cs->mbmaxlen;
bar@bar.mysql.r18.ru's avatar
bar@bar.mysql.r18.ru committed
689
    set_name(str, length, cs);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
690
    decimals=NOT_FIXED_DEC;
691 692
    // it is constant => can be used without fix_fields (and frequently used)
    fixed= 1;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
693
  }
694
  Item_string(const char *name_par, const char *str, uint length,
695
	      CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
696
  {
697
    collation.set(cs, dv);
698
    str_value.set_or_copy_aligned(str,length,cs);
699
    max_length= str_value.numchars()*cs->mbmaxlen;
bar@bar.mysql.r18.ru's avatar
bar@bar.mysql.r18.ru committed
700
    set_name(name_par,0,cs);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
701
    decimals=NOT_FIXED_DEC;
702 703
    // it is constant => can be used without fix_fields (and frequently used)
    fixed= 1;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
704 705
  }
  enum Type type() const { return STRING_ITEM; }
706
  double val()
707 708
  {
    DBUG_ASSERT(fixed == 1);
709
    int err;
710
    return my_strntod(str_value.charset(), (char*) str_value.ptr(),
711
		      str_value.length(), (char**) 0, &err);
712 713 714
  }
  longlong val_int()
  {
715
    DBUG_ASSERT(fixed == 1);
716
    int err;
717
    return my_strntoll(str_value.charset(), str_value.ptr(),
718
		       str_value.length(), 10, (char**) 0, &err);
719
  }
720 721 722 723 724
  String *val_str(String*)
  {
    DBUG_ASSERT(fixed == 1);
    return (String*) &str_value;
  }
monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
725
  int save_in_field(Field *field, bool no_conversions);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
726
  enum Item_result result_type () const { return STRING_RESULT; }
727
  enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
728
  bool basic_const_item() const { return 1; }
729
  bool eq(const Item *item, bool binary_cmp) const;
730 731
  Item *new_item() 
  {
732 733
    return new Item_string(name, str_value.ptr(), 
    			   str_value.length(), &my_charset_bin);
734
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
735
  String *const_string() { return &str_value; }
736
  inline void append(char *str, uint length) { str_value.append(str, length); }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
737
  void print(String *str);
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
738 739
  // to prevent drop fixed flag (no need parent cleanup call)
  void cleanup() {}
bk@work.mysql.com's avatar
bk@work.mysql.com committed
740 741 742 743 744 745 746
};

/* for show tables */

class Item_datetime :public Item_string
{
public:
bar@bar.mysql.r18.ru's avatar
bar@bar.mysql.r18.ru committed
747 748
  Item_datetime(const char *item_name): Item_string(item_name,"",0,
  						    &my_charset_bin)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
749
  { max_length=19;}
750
  enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
751 752 753 754 755
};

class Item_empty_string :public Item_string
{
public:
bar@bar.mysql.r18.ru's avatar
bar@bar.mysql.r18.ru committed
756 757
  Item_empty_string(const char *header,uint length) :Item_string("",0,
  							&my_charset_bin)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
758
    { name=(char*) header; max_length=length;}
759
  void make_field(Send_field *field);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
760 761
};

762 763 764 765 766 767 768 769 770 771 772 773 774 775
class Item_return_int :public Item_int
{
  enum_field_types int_field_type;
public:
  Item_return_int(const char *name, uint length,
		  enum_field_types field_type_arg)
    :Item_int(name, 0, length), int_field_type(field_type_arg)
  {
    unsigned_flag=1;
  }
  enum_field_types field_type() const { return int_field_type; }
};


bk@work.mysql.com's avatar
bk@work.mysql.com committed
776 777 778
class Item_varbinary :public Item
{
public:
779
  Item_varbinary(const char *str,uint str_length);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
780
  enum Type type() const { return VARBIN_ITEM; }
781 782
  double val()
    { DBUG_ASSERT(fixed == 1); return (double) Item_varbinary::val_int(); }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
783
  longlong val_int();
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
784
  bool basic_const_item() const { return 1; }
785
  String *val_str(String*) { DBUG_ASSERT(fixed == 1); return &str_value; }
monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
786
  int save_in_field(Field *field, bool no_conversions);
787
  enum Item_result result_type () const { return STRING_RESULT; }
788
  enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
789 790
  // to prevent drop fixed flag (no need parent cleanup call)
  void cleanup() {}
bk@work.mysql.com's avatar
bk@work.mysql.com committed
791 792 793 794 795 796 797 798
};


class Item_result_field :public Item	/* Item with result field */
{
public:
  Field *result_field;				/* Save result here */
  Item_result_field() :result_field(0) {}
799
  // Constructor used for Item_sum/Item_cond_and/or (see Item comment)
800 801
  Item_result_field(THD *thd, Item_result_field *item):
    Item(thd, item), result_field(item->result_field)
802
  {}
bk@work.mysql.com's avatar
bk@work.mysql.com committed
803
  ~Item_result_field() {}			/* Required with gcc 2.95 */
804
  Field *get_tmp_table_field() { return result_field; }
805
  Field *tmp_table_field(TABLE *t_arg) { return result_field; }
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
806
  table_map used_tables() const { return 1; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
807
  virtual void fix_length_and_dec()=0;
monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
808 809 810 811 812 813
  void set_result_field(Field *field) { result_field= field; }
  bool is_result_field() { return 1; }
  void save_in_result_field(bool no_conversions)
  {
    save_in_field(result_field, no_conversions);
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
814 815 816 817 818 819
};


class Item_ref :public Item_ident
{
public:
hf@deer.(none)'s avatar
hf@deer.(none) committed
820
  Field *result_field;			 /* Save result here */
serg@serg.mysql.com's avatar
serg@serg.mysql.com committed
821
  Item **ref;
hf@deer.(none)'s avatar
hf@deer.(none) committed
822 823 824 825 826 827 828 829 830 831
  Item **hook_ptr;                       /* These two to restore  */
  Item *orig_item;                       /* things in 'cleanup()' */
  Item_ref(Item **hook, Item *original,const char *db_par,
	   const char *table_name_par, const char *field_name_par)
    :Item_ident(db_par,table_name_par,field_name_par),ref(0), hook_ptr(hook),
    orig_item(original) {}
  Item_ref(Item **item, Item **hook, 
	   const char *table_name_par, const char *field_name_par)
    :Item_ident(NullS,table_name_par,field_name_par),
    ref(item), hook_ptr(hook), orig_item(hook ? *hook:0) {}
832
  // Constructor need to process subselect with temporary tables (see Item)
833 834
  Item_ref(THD *thd, Item_ref *item, Item **hook)
    :Item_ident(thd, item), ref(item->ref), 
hf@deer.(none)'s avatar
hf@deer.(none) committed
835
    hook_ptr(hook), orig_item(hook ? *hook : 0) {}
bk@work.mysql.com's avatar
bk@work.mysql.com committed
836
  enum Type type() const		{ return REF_ITEM; }
837
  bool eq(const Item *item, bool binary_cmp) const
838
  { return ref && (*ref)->eq(item, binary_cmp); }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
839 840 841
  double val()
  {
    double tmp=(*ref)->val_result();
842
    null_value=(*ref)->null_value;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
843 844 845 846 847
    return tmp;
  }
  longlong val_int()
  {
    longlong tmp=(*ref)->val_int_result();
848
    null_value=(*ref)->null_value;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
849 850 851 852 853
    return tmp;
  }
  String *val_str(String* tmp)
  {
    tmp=(*ref)->str_result(tmp);
854
    null_value=(*ref)->null_value;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
855 856
    return tmp;
  }
857 858 859
  bool is_null()
  {
    (void) (*ref)->val_int_result();
860
    return (*ref)->null_value;
861
  }
862
  bool get_date(TIME *ltime,uint fuzzydate)
863 864
  {
    return (null_value=(*ref)->get_date_result(ltime,fuzzydate));
bk@work.mysql.com's avatar
bk@work.mysql.com committed
865
  }
866
  bool send(Protocol *prot, String *tmp){ return (*ref)->send(prot, tmp); }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
867
  void make_field(Send_field *field)	{ (*ref)->make_field(field); }
868
  bool fix_fields(THD *, struct st_table_list *, Item **);
monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
869
  int save_in_field(Field *field, bool no_conversions)
870
  { return (*ref)->save_in_field(field, no_conversions); }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
871 872
  void save_org_in_field(Field *field)	{ (*ref)->save_org_in_field(field); }
  enum Item_result result_type () const { return (*ref)->result_type(); }
873
  enum_field_types field_type() const   { return (*ref)->field_type(); }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
874
  table_map used_tables() const		{ return (*ref)->used_tables(); }
875
  void set_result_field(Field *field)	{ result_field= field; }
monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
876 877 878 879 880
  bool is_result_field() { return 1; }
  void save_in_result_field(bool no_conversions)
  {
    (*ref)->save_in_field(result_field, no_conversions);
  }
881
  Item *real_item() { return *ref; }
882
  void print(String *str);
hf@deer.(none)'s avatar
hf@deer.(none) committed
883
  void cleanup();
bk@work.mysql.com's avatar
bk@work.mysql.com committed
884 885
};

886 887 888 889 890 891 892
class Item_in_subselect;
class Item_ref_null_helper: public Item_ref
{
protected:
  Item_in_subselect* owner;
public:
  Item_ref_null_helper(Item_in_subselect* master, Item **item,
893
		       const char *table_name_par, const char *field_name_par):
hf@deer.(none)'s avatar
hf@deer.(none) committed
894
    Item_ref(item, NULL, table_name_par, field_name_par), owner(master) {}
895 896 897
  double val();
  longlong val_int();
  String* val_str(String* s);
898
  bool get_date(TIME *ltime, uint fuzzydate);
899
  void print(String *str);
900 901
};

902 903 904 905 906 907 908 909 910
class Item_null_helper :public Item_ref_null_helper
{
  Item *store;
public:
  Item_null_helper(Item_in_subselect* master, Item *item,
		   const char *table_name_par, const char *field_name_par)
    :Item_ref_null_helper(master, &store, table_name_par, field_name_par),
     store(item)
    {}
911
  void print(String *str);
912
};
913

914 915 916 917 918 919 920 921 922 923 924 925
/*
  The following class is used to optimize comparing of date columns
  We need to save the original item, to be able to set the field to the
  original value in 'opt_range'.
*/

class Item_int_with_ref :public Item_int
{
  Item *ref;
public:
  Item_int_with_ref(longlong i, Item *ref_arg) :Item_int(i), ref(ref_arg)
  {}
monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
926
  int save_in_field(Field *field, bool no_conversions)
927
  {
928
    return ref->save_in_field(field, no_conversions);
929 930 931 932
  }
};


933
#include "gstream.h"
934
#include "spatial.h"
bk@work.mysql.com's avatar
bk@work.mysql.com committed
935 936
#include "item_sum.h"
#include "item_func.h"
937
#include "item_row.h"
bk@work.mysql.com's avatar
bk@work.mysql.com committed
938 939
#include "item_cmpfunc.h"
#include "item_strfunc.h"
940
#include "item_geofunc.h"
bk@work.mysql.com's avatar
bk@work.mysql.com committed
941 942
#include "item_timefunc.h"
#include "item_uniq.h"
943
#include "item_subselect.h"
bk@work.mysql.com's avatar
bk@work.mysql.com committed
944 945 946

class Item_copy_string :public Item
{
947
  enum enum_field_types cached_field_type;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
948 949 950 951 952 953 954 955
public:
  Item *item;
  Item_copy_string(Item *i) :item(i)
  {
    null_value=maybe_null=item->maybe_null;
    decimals=item->decimals;
    max_length=item->max_length;
    name=item->name;
956
    cached_field_type= item->field_type();
bk@work.mysql.com's avatar
bk@work.mysql.com committed
957 958 959
  }
  enum Type type() const { return COPY_STR_ITEM; }
  enum Item_result result_type () const { return STRING_RESULT; }
960
  enum_field_types field_type() const { return cached_field_type; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
961
  double val()
962
  {
963
    int err;
964 965
    return (null_value ? 0.0 :
	    my_strntod(str_value.charset(), (char*) str_value.ptr(),
966
		       str_value.length(),NULL,&err));
967
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
968
  longlong val_int()
969 970 971 972
  { 
    int err;
    return null_value ? LL(0) : my_strntoll(str_value.charset(),str_value.ptr(),str_value.length(),10, (char**) 0,&err); 
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
973 974 975
  String *val_str(String*);
  void make_field(Send_field *field) { item->make_field(field); }
  void copy();
monty@mysql.com's avatar
monty@mysql.com committed
976
  int save_in_field(Field *field, bool no_conversions);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
977 978
  table_map used_tables() const { return (table_map) 1L; }
  bool const_item() const { return 0; }
979
  bool is_null() { return null_value; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036
};


class Item_buff :public Sql_alloc
{
public:
  my_bool null_value;
  Item_buff() :null_value(0) {}
  virtual bool cmp(void)=0;
  virtual ~Item_buff(); /*line -e1509 */
};

class Item_str_buff :public Item_buff
{
  Item *item;
  String value,tmp_value;
public:
  Item_str_buff(Item *arg) :item(arg),value(arg->max_length) {}
  bool cmp(void);
  ~Item_str_buff();				// Deallocate String:s
};


class Item_real_buff :public Item_buff
{
  Item *item;
  double value;
public:
  Item_real_buff(Item *item_par) :item(item_par),value(0.0) {}
  bool cmp(void);
};

class Item_int_buff :public Item_buff
{
  Item *item;
  longlong value;
public:
  Item_int_buff(Item *item_par) :item(item_par),value(0) {}
  bool cmp(void);
};


class Item_field_buff :public Item_buff
{
  char *buff;
  Field *field;
  uint length;

public:
  Item_field_buff(Item_field *item)
  {
    field=item->field;
    buff= (char*) sql_calloc(length=field->pack_length());
  }
  bool cmp(void);
};

hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1037 1038 1039 1040
class Item_default_value : public Item_field
{
public:
  Item *arg;
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1041 1042
  Item_default_value() :
    Item_field((const char *)NULL, (const char *)NULL, (const char *)NULL), arg(NULL) {}
1043
  Item_default_value(Item *a) :
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1044
    Item_field((const char *)NULL, (const char *)NULL, (const char *)NULL), arg(a) {}
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1045
  enum Type type() const { return DEFAULT_VALUE_ITEM; }
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1046 1047
  bool eq(const Item *item, bool binary_cmp) const;
  bool fix_fields(THD *, struct st_table_list *, Item **);
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1048
  void print(String *str);
1049
  int save_in_field(Field *field_arg, bool no_conversions)
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1050 1051 1052
  {
    if (!arg)
    {
1053
      field_arg->set_default();
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1054 1055
      return 0;
    }
1056
    return Item_field::save_in_field(field_arg, no_conversions);
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1057
  }
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1058
  table_map used_tables() const { return (table_map)0L; }
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
1059 1060 1061 1062 1063 1064
  
  bool walk(Item_processor processor, byte *args)
  {
    return arg->walk(processor, args) ||
      (this->*processor)(args);
  }
hf@deer.mysql.r18.ru's avatar
hf@deer.mysql.r18.ru committed
1065
};
hf@deer.mysql.r18.ru's avatar
hf@deer.mysql.r18.ru committed
1066

1067 1068 1069 1070 1071 1072 1073 1074 1075
class Item_insert_value : public Item_field
{
public:
  Item *arg;
  Item_insert_value(Item *a) :
    Item_field((const char *)NULL, (const char *)NULL, (const char *)NULL), arg(a) {}
  bool eq(const Item *item, bool binary_cmp) const;
  bool fix_fields(THD *, struct st_table_list *, Item **);
  void print(String *str);
1076
  int save_in_field(Field *field_arg, bool no_conversions)
1077
  {
1078
    return Item_field::save_in_field(field_arg, no_conversions);
1079 1080
  }
  table_map used_tables() const { return (table_map)0L; }
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
1081 1082 1083 1084 1085 1086

  bool walk(Item_processor processor, byte *args)
  {
    return arg->walk(processor, args) ||
	    (this->*processor)(args);
  }
1087 1088
};

1089 1090
class Item_cache: public Item
{
1091 1092
protected:
  Item *example;
1093
  table_map used_table_map;
1094
public:
1095
  Item_cache(): example(0), used_table_map(0) {fixed= 1; null_value= 1;}
1096 1097 1098

  void set_used_tables(table_map map) { used_table_map= map; }

bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
1099
  virtual bool allocate(uint i) { return 0; }
1100
  virtual bool setup(Item *item)
1101
  {
1102 1103 1104 1105 1106 1107
    example= item;
    max_length= item->max_length;
    decimals= item->decimals;
    collation.set(item->collation);
    return 0;
  };
1108 1109
  virtual void store(Item *)= 0;
  enum Type type() const { return CACHE_ITEM; }
1110
  static Item_cache* get_cache(Item_result type);
1111
  table_map used_tables() const { return used_table_map; }
1112
  virtual void keep_array() {}
1113
  // to prevent drop fixed flag (no need parent cleanup call)
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
1114
  void cleanup() {}
1115
  void print(String *str);
1116 1117 1118 1119 1120 1121
};

class Item_cache_int: public Item_cache
{
  longlong value;
public:
1122
  Item_cache_int(): Item_cache() {}
1123
  
1124
  void store(Item *item);
1125 1126 1127 1128 1129 1130 1131 1132
  double val() { DBUG_ASSERT(fixed == 1); return (double) value; }
  longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
  String* val_str(String *str)
  {
    DBUG_ASSERT(fixed == 1);
    str->set(value, default_charset());
    return str;
  }
1133 1134 1135 1136 1137 1138 1139
  enum Item_result result_type() const { return INT_RESULT; }
};

class Item_cache_real: public Item_cache
{
  double value;
public:
1140
  Item_cache_real(): Item_cache() {}
1141

1142
  void store(Item *item);
1143 1144 1145 1146 1147 1148
  double val() { DBUG_ASSERT(fixed == 1); return value; }
  longlong val_int()
  {
    DBUG_ASSERT(fixed == 1);
    return (longlong) (value+(value > 0 ? 0.5 : -0.5));
  }
1149 1150
  String* val_str(String *str)
  {
1151
    str->set(value, decimals, default_charset());
1152 1153 1154 1155 1156 1157 1158 1159
    return str;
  }
  enum Item_result result_type() const { return REAL_RESULT; }
};

class Item_cache_str: public Item_cache
{
  char buffer[80];
1160
  String *value, value_buff;
1161
public:
1162
  Item_cache_str(): Item_cache() { }
1163
  
1164 1165 1166
  void store(Item *item);
  double val();
  longlong val_int();
1167
  String* val_str(String *) { DBUG_ASSERT(fixed == 1); return value; }
1168 1169 1170 1171
  enum Item_result result_type() const { return STRING_RESULT; }
  CHARSET_INFO *charset() const { return value->charset(); };
};

1172 1173 1174
class Item_cache_row: public Item_cache
{
  Item_cache  **values;
1175
  uint item_count;
1176
  bool save_array;
1177
public:
1178 1179
  Item_cache_row()
    :Item_cache(), values(0), item_count(2), save_array(0) {}
1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213
  
  /*
    'allocate' used only in row transformer, to preallocate space for row 
    cache.
  */
  bool allocate(uint num);
  /*
    'setup' is needed only by row => it not called by simple row subselect
    (only by IN subselect (in subselect optimizer))
  */
  bool setup(Item *item);
  void store(Item *item);
  void illegal_method_call(const char *);
  void make_field(Send_field *)
  {
    illegal_method_call((const char*)"make_field");
  };
  double val()
  {
    illegal_method_call((const char*)"val");
    return 0;
  };
  longlong val_int()
  {
    illegal_method_call((const char*)"val_int");
    return 0;
  };
  String *val_str(String *)
  {
    illegal_method_call((const char*)"val_str");
    return 0;
  };
  enum Item_result result_type() const { return ROW_RESULT; }
  
1214
  uint cols() { return item_count; }
1215 1216 1217 1218 1219
  Item* el(uint i) { return values[i]; }
  Item** addr(uint i) { return (Item **) (values + i); }
  bool check_cols(uint c);
  bool null_inside();
  void bring_value();
1220
  void keep_array() { save_array= 1; }
hf@deer.(none)'s avatar
hf@deer.(none) committed
1221 1222
  void cleanup()
  {
1223
    DBUG_ENTER("Item_cache_row::cleanup");
hf@deer.(none)'s avatar
hf@deer.(none) committed
1224
    Item_cache::cleanup();
1225 1226 1227 1228
    if (save_array)
      bzero(values, item_count*sizeof(Item**));
    else
      values= 0;
1229
    DBUG_VOID_RETURN;
hf@deer.(none)'s avatar
hf@deer.(none) committed
1230
  }
1231 1232
};

1233 1234 1235 1236 1237 1238 1239 1240

/*
  Used to store type. name, length of Item for UNIONS & derived table
*/
class Item_type_holder: public Item
{
protected:
  Item_result item_type;
1241
  Item_result orig_type;
1242 1243 1244 1245 1246 1247 1248 1249 1250
  Field *field_example;
public:
  Item_type_holder(THD*, Item*);

  Item_result result_type () const { return item_type; }
  enum Type type() const { return TYPE_HOLDER; }
  double val();
  longlong val_int();
  String *val_str(String*);
1251
  bool join_types(THD *thd, Item *);
1252
  Field *example() { return field_example; }
1253 1254
  void cleanup()
  {
1255
    DBUG_ENTER("Item_type_holder::cleanup");
1256 1257
    Item::cleanup();
    item_type= orig_type;
1258
    DBUG_VOID_RETURN;
1259
  }
1260 1261 1262
};


bk@work.mysql.com's avatar
bk@work.mysql.com committed
1263 1264 1265 1266
extern Item_buff *new_Item_buff(Item *item);
extern Item_result item_cmp_type(Item_result a,Item_result b);
extern Item *resolve_const_item(Item *item,Item *cmp_item);
extern bool field_is_equal_to_item(Field *field,Item *item);