item.cc 41.7 KB
Newer Older
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1
/* Copyright (C) 2000 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 22 23 24 25
   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 implementation				// gcc: Class implementation
#endif

#include "mysql_priv.h"
#include <m_ctype.h>
#include "my_dir.h"

bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
26
static void mark_as_dependent(SELECT_LEX *last, SELECT_LEX *current,
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
27 28
			      Item_ident *item);

bk@work.mysql.com's avatar
bk@work.mysql.com committed
29 30 31 32 33 34 35 36 37 38 39
/*****************************************************************************
** Item functions
*****************************************************************************/

/* Init all special items */

void item_init(void)
{
  item_user_lock_init();
}

40 41
Item::Item():
  fixed(0)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
42
{
43
  marker= 0;
44
  maybe_null=null_value=with_sum_func=unsigned_flag=0;
45
  set_charset(default_charset(), DERIVATION_COERCIBLE);
46 47 48 49 50
  name= 0;
  decimals= 0; max_length= 0;
  THD *thd= current_thd;
  next= thd->free_list;			// Put in free list
  thd->free_list= this;
51
  loop_id= 0;
52 53
  if (thd->lex.current_select->parsing_place == SELECT_LEX_NODE::SELECT_LIST)
    thd->lex.current_select->select_items++;
54 55
}

56 57 58 59 60 61
/*
  Constructor used by Item_field, Item_ref & agregate (sum) functions.
  Used for duplicating lists in processing queries with temporary
  tables
*/
Item::Item(THD *thd, Item &item):
62 63 64 65 66 67 68 69 70 71
  loop_id(0),
  str_value(item.str_value),
  name(item.name),
  max_length(item.max_length),
  marker(item.marker),
  decimals(item.decimals),
  maybe_null(item.maybe_null),
  null_value(item.null_value),
  unsigned_flag(item.unsigned_flag),
  with_sum_func(item.with_sum_func),
bar@bar.mysql.r18.ru's avatar
bar@bar.mysql.r18.ru committed
72
  fixed(item.fixed),
73
  collation(item.collation)
74
{
75 76
  next=thd->free_list;			// Put in free list
  thd->free_list= this;
77 78
}

79 80 81
// Constructor used by Item_field & Item_ref (see Item comment)
Item_ident::Item_ident(THD *thd, Item_ident &item):
  Item(thd, item),
82 83 84 85 86
  db_name(item.db_name),
  table_name(item.table_name),
  field_name(item.field_name),
  depended_from(item.depended_from)
{}
87

bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
88 89 90 91 92 93 94 95 96
bool Item_ident::remove_dependence_processor(byte * arg)
{
  DBUG_ENTER("Item_ident::remove_dependence_processor");
  if (depended_from == (st_select_lex *) arg)
    depended_from= 0;
  DBUG_RETURN(1);
}


97 98 99 100
bool Item::check_cols(uint c)
{
  if (c != 1)
  {
101
    my_error(ER_CARDINALITY_COL, MYF(0), c);
102 103 104 105 106
    return 1;
  }
  return 0;
}

monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
107 108

void Item::set_name(const char *str, uint length, CHARSET_INFO *cs)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
109 110 111
{
  if (!length)
  {
monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
112 113 114 115 116 117 118 119
    /* Empty string, used by AS or internal function like last_insert_id() */
    name= (char*) str;
    return;
  }
  while (length && !my_isgraph(cs,*str))
  {						// Fix problem with yacc
    length--;
    str++;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
120
  }
monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
121 122 123 124 125 126 127 128 129
  if (!my_charset_same(cs, system_charset_info))
  {
    uint32 res_length;
    name= sql_strmake_with_convert(str, length, cs,
				   MAX_ALIAS_NAME, system_charset_info,
				   &res_length);
  }
  else
    name=sql_strmake(str, min(length,MAX_ALIAS_NAME));
bk@work.mysql.com's avatar
bk@work.mysql.com committed
130 131
}

monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
132

133
/*
134 135 136
  This function is called when:
  - Comparing items in the WHERE clause (when doing where optimization)
  - When trying to find an ORDER BY/GROUP BY item in the SELECT part
137 138 139
*/

bool Item::eq(const Item *item, bool binary_cmp) const
bk@work.mysql.com's avatar
bk@work.mysql.com committed
140 141
{
  return type() == item->type() && name && item->name &&
142
    !my_strcasecmp(system_charset_info,name,item->name);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
143 144
}

145 146 147 148 149
bool Item_string::eq(const Item *item, bool binary_cmp) const
{
  if (type() == item->type())
  {
    if (binary_cmp)
150 151
      return !sortcmp(&str_value, &item->str_value, &my_charset_bin);
    return !sortcmp(&str_value, &item->str_value, charset());
152 153 154 155 156
  }
  return 0;
}


bk@work.mysql.com's avatar
bk@work.mysql.com committed
157 158 159 160 161 162 163 164
/*
  Get the value of the function as a TIME structure.
  As a extra convenience the time structure is reset on error!
 */

bool Item::get_date(TIME *ltime,bool fuzzydate)
{
  char buff[40];
165
  String tmp(buff,sizeof(buff), &my_charset_bin),*res;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
166
  if (!(res=val_str(&tmp)) ||
167
      str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
  {
    bzero((char*) ltime,sizeof(*ltime));
    return 1;
  }
  return 0;
}

/*
  Get time of first argument.
  As a extra convenience the time structure is reset on error!
 */

bool Item::get_time(TIME *ltime)
{
  char buff[40];
183
  String tmp(buff,sizeof(buff),&my_charset_bin),*res;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
184 185 186 187 188 189 190 191 192
  if (!(res=val_str(&tmp)) ||
      str_to_time(res->ptr(),res->length(),ltime))
  {
    bzero((char*) ltime,sizeof(*ltime));
    return 1;
  }
  return 0;
}

193
CHARSET_INFO * Item::default_charset() const
194
{
195
  return current_thd->variables.collation_connection;
196 197
}

198
bool DTCollation::aggregate(DTCollation &dt)
199
{
200
  if (!my_charset_same(collation, dt.collation))
201
  {
202 203 204
    /* 
       We do allow to use binary strings (like BLOBS)
       together with character strings.
bar@bar.mysql.r18.ru's avatar
bar@bar.mysql.r18.ru committed
205 206
       Binaries have more precedance than a character
       string of the same derivation.
207
    */
208
    if (collation == &my_charset_bin)
209
    {
210 211 212 213
      if (derivation <= dt.derivation)
	; // Do nothing
      else
	set(dt);
214
    }
215
    else if (dt.collation == &my_charset_bin)
216
    {
217 218 219 220
      if (dt.derivation <= derivation)
        set(dt);
      else
       ; // Do nothing
221 222 223 224 225 226
    }
    else
    {
      set(0, DERIVATION_NONE);
      return 1; 
    }
227
  }
228
  else if (derivation < dt.derivation)
229
  {
230
    // Do nothing
231
  }
232
  else if (dt.derivation < derivation)
233
  {
234
    set(dt);
235
  }
236 237 238
  else
  { 
    if (collation == dt.collation)
239
    {
240 241 242 243 244
      // Do nothing
    }
    else 
    {
      if (derivation == DERIVATION_EXPLICIT)
245
      {
246 247
	set(0, DERIVATION_NONE);
	return 1;
248
      }
249 250 251
      CHARSET_INFO *bin= get_charset_by_csname(collation->csname, 
					       MY_CS_BINSORT,MYF(0));
      set(bin, DERIVATION_NONE);
252
    }
253 254 255 256
  }
  return 0;
}

bk@work.mysql.com's avatar
bk@work.mysql.com committed
257 258 259
Item_field::Item_field(Field *f) :Item_ident(NullS,f->table_name,f->field_name)
{
  set_field(f);
260
  set_charset(DERIVATION_IMPLICIT);
261
  fixed= 1; // This item is not needed in fix_fields
bk@work.mysql.com's avatar
bk@work.mysql.com committed
262 263
}

264 265 266
// Constructor need to process subselect with temporary tables (see Item)
Item_field::Item_field(THD *thd, Item_field &item):
  Item_ident(thd, item),
267 268
  field(item.field),
  result_field(item.result_field)
269
{ set_charset(DERIVATION_IMPLICIT); }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
270 271 272 273 274 275 276 277 278

void Item_field::set_field(Field *field_par)
{
  field=result_field=field_par;			// for easy coding with fields
  maybe_null=field->maybe_null();
  max_length=field_par->field_length;
  decimals= field->decimals();
  table_name=field_par->table_name;
  field_name=field_par->field_name;
279
  db_name=field_par->table->table_cache_key;
280
  unsigned_flag=test(field_par->flags & UNSIGNED_FLAG);
281
  set_charset(field_par->charset(), DERIVATION_IMPLICIT);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
282 283 284 285 286 287 288
}

const char *Item_ident::full_name() const
{
  char *tmp;
  if (!table_name)
    return field_name ? field_name : name ? name : "tmp_field";
289
  if (db_name && db_name[0])
bk@work.mysql.com's avatar
bk@work.mysql.com committed
290
  {
291 292
    tmp=(char*) sql_alloc((uint) strlen(db_name)+(uint) strlen(table_name)+
			  (uint) strlen(field_name)+3);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
293 294 295 296
    strxmov(tmp,db_name,".",table_name,".",field_name,NullS);
  }
  else
  {
297 298
    tmp=(char*) sql_alloc((uint) strlen(table_name)+
			  (uint) strlen(field_name)+2);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
299 300 301 302 303 304 305 306 307 308
    strxmov(tmp,table_name,".",field_name,NullS);
  }
  return tmp;
}

/* ARGSUSED */
String *Item_field::val_str(String *str)
{
  if ((null_value=field->is_null()))
    return 0;
309
  str->set_charset(str_value.charset());
bk@work.mysql.com's avatar
bk@work.mysql.com committed
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
  return field->val_str(str,&str_value);
}

double Item_field::val()
{
  if ((null_value=field->is_null()))
    return 0.0;
  return field->val_real();
}

longlong Item_field::val_int()
{
  if ((null_value=field->is_null()))
    return 0;
  return field->val_int();
}


String *Item_field::str_result(String *str)
{
  if ((null_value=result_field->is_null()))
    return 0;
332
  str->set_charset(str_value.charset());
bk@work.mysql.com's avatar
bk@work.mysql.com committed
333 334 335 336 337 338 339 340 341 342 343 344 345
  return result_field->val_str(str,&str_value);
}

bool Item_field::get_date(TIME *ltime,bool fuzzydate)
{
  if ((null_value=field->is_null()) || field->get_date(ltime,fuzzydate))
  {
    bzero((char*) ltime,sizeof(*ltime));
    return 1;
  }
  return 0;
}

346 347 348 349 350 351 352 353 354 355 356
bool Item_field::get_date_result(TIME *ltime,bool fuzzydate)
{
  if ((null_value=result_field->is_null()) ||
      result_field->get_date(ltime,fuzzydate))
  {
    bzero((char*) ltime,sizeof(*ltime));
    return 1;
  }
  return 0;
}

bk@work.mysql.com's avatar
bk@work.mysql.com committed
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
bool Item_field::get_time(TIME *ltime)
{
  if ((null_value=field->is_null()) || field->get_time(ltime))
  {
    bzero((char*) ltime,sizeof(*ltime));
    return 1;
  }
  return 0;
}

double Item_field::val_result()
{
  if ((null_value=result_field->is_null()))
    return 0.0;
  return result_field->val_real();
}

longlong Item_field::val_int_result()
{
  if ((null_value=result_field->is_null()))
    return 0;
  return result_field->val_int();
}

381

382
bool Item_field::eq(const Item *item, bool binary_cmp) const
bk@work.mysql.com's avatar
bk@work.mysql.com committed
383
{
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
  if (item->type() != FIELD_ITEM)
    return 0;
  
  Item_field *item_field= (Item_field*) item;
  if (item_field->field)
    return item_field->field == field;
  /*
    We may come here when we are trying to find a function in a GROUP BY
    clause from the select list.
    In this case the '100 % correct' way to do this would be to first
    run fix_fields() on the GROUP BY item and then retry this function, but
    I think it's better to relax the checking a bit as we will in
    most cases do the correct thing by just checking the field name.
    (In cases where we would choose wrong we would have to generate a
    ER_NON_UNIQ_ERROR).
  */
  return (!my_strcasecmp(system_charset_info, item_field->name,
			 field_name) &&
	  (!item_field->table_name ||
	   (!my_strcasecmp(table_alias_charset, item_field->table_name,
			   table_name) &&
	    (!item_field->db_name ||
	     (item_field->db_name && !my_strcasecmp(table_alias_charset,
						    item_field->db_name,
						    db_name))))));
bk@work.mysql.com's avatar
bk@work.mysql.com committed
409 410 411 412 413 414
}

table_map Item_field::used_tables() const
{
  if (field->table->const_table)
    return 0;					// const item
415
  return (depended_from ? OUTER_REF_TABLE_BIT : field->table->map);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
416 417
}

418
Item *Item_field::get_tmp_table_item(THD *thd)
419
{
420
  Item_field *new_item= new Item_field(thd, *this);
421 422 423 424
  if (new_item)
    new_item->field= new_item->result_field;
  return new_item;
}
bk@work.mysql.com's avatar
bk@work.mysql.com committed
425 426 427

String *Item_int::val_str(String *str)
{
428
  str->set(value, default_charset());
bk@work.mysql.com's avatar
bk@work.mysql.com committed
429 430 431 432 433 434 435
  return str;
}

void Item_int::print(String *str)
{
  if (!name)
  {
436
    str_value.set(value, default_charset());
bk@work.mysql.com's avatar
bk@work.mysql.com committed
437 438 439 440 441
    name=str_value.c_ptr();
  }
  str->append(name);
}

442 443
String *Item_uint::val_str(String *str)
{
444
  str->set((ulonglong) value, default_charset());
445 446 447 448 449 450 451
  return str;
}

void Item_uint::print(String *str)
{
  if (!name)
  {
452
    str_value.set((ulonglong) value, default_charset());
453 454 455 456 457
    name=str_value.c_ptr();
  }
  str->append(name);
}

bk@work.mysql.com's avatar
bk@work.mysql.com committed
458 459 460

String *Item_real::val_str(String *str)
{
461
  str->set(value,decimals,default_charset());
bk@work.mysql.com's avatar
bk@work.mysql.com committed
462 463 464 465 466 467 468 469 470 471
  return str;
}

void Item_string::print(String *str)
{
  str->append('\'');
  str->append(full_name());
  str->append('\'');
}

472 473
bool Item_null::eq(const Item *item, bool binary_cmp) const
{ return item->type() == type(); }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
474 475 476 477 478 479 480
double Item_null::val() { null_value=1; return 0.0; }
longlong Item_null::val_int() { null_value=1; return 0; }
/* ARGSUSED */
String *Item_null::val_str(String *str)
{ null_value=1; return 0;}


481 482 483 484 485 486 487 488 489 490 491 492
/* Item_param related */
void Item_param::set_null()
{ 
  maybe_null=null_value=1;    
}

void Item_param::set_int(longlong i)
{  
  int_value=(longlong)i; 
  item_type = INT_ITEM;
}

493
void Item_param::set_double(double value)
494 495 496 497 498 499
{  
  real_value=value;
  item_type = REAL_ITEM;
}


venu@myvenu.com's avatar
venu@myvenu.com committed
500
void Item_param::set_value(const char *str, uint length)
501
{  
502
  str_value.set(str,length,default_charset());
503 504 505
  item_type = STRING_ITEM;
}

506

507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525
void Item_param::set_time(TIME *tm, timestamp_type type)
{ 
  ltime.year= tm->year;
  ltime.month= tm->month;
  ltime.day= tm->day;
  
  ltime.hour= tm->hour;
  ltime.minute= tm->minute;
  ltime.second= tm->second; 

  ltime.second_part= tm->second_part;

  ltime.time_type= type;
  
  item_is_time= true;
  item_type= STRING_ITEM;
}


venu@myvenu.com's avatar
venu@myvenu.com committed
526 527 528 529
void Item_param::set_longdata(const char *str, ulong length)
{  
  str_value.append(str,length);
  long_data_supplied= 1;
530 531 532
}


venu@myvenu.com's avatar
venu@myvenu.com committed
533
int Item_param::save_in_field(Field *field, bool no_conversions)
534 535
{
  if (null_value)
536
    return (int) set_field_to_null(field);   
537 538 539 540 541
    
  field->set_notnull();
  if (item_result_type == INT_RESULT)
  {
    longlong nr=val_int();
542
    return (field->store(nr)) ? -1 : 0;
543 544 545 546
  }
  if (item_result_type == REAL_RESULT)
  {
    double nr=val();    
547
    return (field->store(nr)) ? -1 : 0; 
548 549 550 551 552
  }  
  if (item_is_time)
  {
    field->store_time(&ltime, ltime.time_type);
    return 0;
553
  }
554 555
  String *result=val_str(&str_value);
  return (field->store(result->ptr(),result->length(),field->charset())) ? -1 : 0;
556 557
}

558 559 560 561 562
bool Item_param::get_time(TIME *res)
{
  *res=ltime;
  return 0;
}
563

564 565
double Item_param::val() 
{
566
  int err;
567
  switch (item_result_type) {
568
  case STRING_RESULT:
569
    return (double) my_strntod(str_value.charset(), (char*) str_value.ptr(),
570
			       str_value.length(), (char**) 0, &err); 
571 572 573 574 575 576 577
  case INT_RESULT:
    return (double)int_value;
  default:
    return real_value;
  }
} 

578

579 580
longlong Item_param::val_int() 
{ 
581
 int err;
582
 switch (item_result_type) {
583
  case STRING_RESULT:
584 585 586
    return my_strntoll(str_value.charset(),
		       str_value.ptr(),str_value.length(),10,
		       (char**) 0,&err);
587 588 589 590 591 592 593
  case REAL_RESULT:
    return (longlong) (real_value+(real_value > 0 ? 0.5 : -0.5));
  default:
    return int_value;
  }
}

594

595 596
String *Item_param::val_str(String* str) 
{ 
597
  switch (item_result_type) {
598
  case INT_RESULT:
599
    str->set(int_value, default_charset());
600 601
    return str;
  case REAL_RESULT:
602
    str->set(real_value, 2, default_charset());
603 604 605 606 607
    return str;
  default:
    return (String*) &str_value;
  }
}
608 609 610 611 612 613 614 615 616 617 618

/*
  Return Param item values in string format, for generating the dynamic 
  query used in update/binary logs
*/

String *Item_param::query_val_str(String* str) 
{ 
  switch (item_result_type) {
  case INT_RESULT:
  case REAL_RESULT:
619
    return val_str(str);
620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662
    break;
  default:
    str->set("'", 1, default_charset());
    
    if (!item_is_time)
    {
      str->append(str_value);
      const char *from= str->ptr(); 
      uint32 length= 1;
      
      // Escape misc cases
      char *to= (char *)from, *end= (char *)to+str->length(); 
      for (to++; to != end ; length++, to++)
      {
        switch(*to) {
          case '\'':
          case '"':  
          case '\r':
          case '\n':
          case '\\': // TODO: Add remaining ..
            str->replace(length,0,"\\",1); 
            to++; end++; length++;
            break;
          default:     
            break;
        }
      }
    }
    else
    {
      char buff[25];
      
      switch (ltime.time_type)  {
        case TIMESTAMP_NONE:
          break;
        case TIMESTAMP_DATE:
          sprintf(buff, "%04d-%02d-%02d", 
                        ltime.year,ltime.month,ltime.day);
          str->append(buff, 10);
          break;
        case TIMESTAMP_FULL:
          sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d",
 	                ltime.year,ltime.month,ltime.day,
663
	                ltime.hour,ltime.minute,ltime.second);
664 665 666 667 668
          str->append(buff, 19);
          break;
        case TIMESTAMP_TIME:
        {
          sprintf(buff, "%02d:%02d:%02d",
669
	  	            ltime.hour,ltime.minute,ltime.second);
670 671 672 673 674 675 676 677 678
          str->append(buff, 8);
          break;
        }
      }
    }
    str->append("'");
  }
  return str;
}
679 680
/* End of Item_param related */

681

bk@work.mysql.com's avatar
bk@work.mysql.com committed
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698
void Item_copy_string::copy()
{
  String *res=item->val_str(&str_value);
  if (res && res != &str_value)
    str_value.copy(*res);
  null_value=item->null_value;
}

/* ARGSUSED */
String *Item_copy_string::val_str(String *str)
{
  if (null_value)
    return (String*) 0;
  return &str_value;
}

/*
699
  Functions to convert item to field (for send_fields)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
700 701 702 703
*/

/* ARGSUSED */
bool Item::fix_fields(THD *thd,
704 705
		      struct st_table_list *list,
		      Item ** ref)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
706
{
707
  fixed= 1;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
708 709 710
  return 0;
}

bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
711 712 713 714 715 716
bool Item_asterisk_remover::fix_fields(THD *thd,
				       struct st_table_list *list,
				       Item ** ref)
{
  DBUG_ENTER("Item_asterisk_remover::fix_fields");
  
717
  bool res= 1;
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
718 719 720 721
  if (item)
    if (item->type() == Item::FIELD_ITEM &&
	((Item_field*) item)->field_name[0] == '*')
    {
722
      Item_field *fitem=  (Item_field*) item;
723 724
      if (list)
	if (!list->next || fitem->db_name || fitem->table_name)
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
725
	{
726 727 728 729
	  TABLE_LIST *table= find_table_in_list(list,
						fitem->db_name,
						fitem->table_name);
	  if (table)
730
	  {
731 732 733 734
	    TABLE * tb= table->table;
	    if (find_table_in_list(table->next, fitem->db_name,
				   fitem->table_name) != 0 ||
		tb->fields == 1)
735
	    {
736 737 738 739 740 741 742 743
	      if ((item= new Item_field(tb->field[0])))
	      {
		res= 0;
		tb->field[0]->query_id= thd->query_id;
		tb->used_keys&= tb->field[0]->part_of_key;
		tb->used_fields= tb->fields;
	      }
	      else
744
		thd->fatal_error(); // can't create Item => out of memory
745 746
	    }
	    else
747
	      my_error(ER_CARDINALITY_COL, MYF(0), 1);
748 749
	  }
	  else
750
	    my_error(ER_BAD_TABLE_ERROR, MYF(0), fitem->table_name);
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
751
	}
752
	else
753
	  my_error(ER_CARDINALITY_COL, MYF(0), 1);
754
      else
755
	my_error(ER_NO_TABLES_USED, MYF(0));
756
    }   
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
757 758 759
    else
      res= item->fix_fields(thd, list, &item);
  else
760
    thd->fatal_error(); // no item given => out of memory
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
761 762 763
  DBUG_RETURN(res);
}

764 765 766 767
bool Item_ref_on_list_position::fix_fields(THD *thd,
					   struct st_table_list *tables,
					   Item ** reference)
{
768
  if (select_lex->item_list.elements <= pos)
769
  {
770
    ref= 0;
771 772 773
    my_error(ER_CARDINALITY_COL, MYF(0), pos);
    return 1;
  }
774 775
  ref= select_lex->ref_pointer_array + pos;
  return Item_ref_null_helper::fix_fields(thd, tables, reference);
776 777
}

778 779 780
double Item_ref_null_helper::val()
{
  double tmp= (*ref)->val_result();
781
  owner->was_null|= null_value= (*ref)->null_value;
782 783 784 785 786
  return tmp;
}
longlong Item_ref_null_helper::val_int()
{
  longlong tmp= (*ref)->val_int_result();
787
  owner->was_null|= null_value= (*ref)->null_value;
788 789 790 791 792
  return tmp;
}
String* Item_ref_null_helper::val_str(String* s)
{
  String* tmp= (*ref)->str_result(s);
793
  owner->was_null|= null_value= (*ref)->null_value;
794 795 796 797 798 799
  return tmp;
}
bool Item_ref_null_helper::get_date(TIME *ltime, bool fuzzydate)
{  
  return (owner->was_null|= null_value= (*ref)->get_date(ltime, fuzzydate));
}
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
800

bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
801 802 803 804 805 806 807 808 809 810 811

/*
  Mark item and SELECT_LEXs as dependent if it is not outer resolving

  SYNOPSIS
    mark_as_dependent()
    last - select from which current item depend
    current  - current select
    item - item which should be marked
*/

bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
812
static void mark_as_dependent(SELECT_LEX *last, SELECT_LEX *current,
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
813 814
			      Item_ident *item)
{
815 816 817
  // store pointer on SELECT_LEX from wich item is dependent
  item->depended_from= last;
  current->mark_as_dependent(last);
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
818 819 820
}


821
bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
822
{
823
  if (!field)					// If field is not checked
bk@work.mysql.com's avatar
bk@work.mysql.com committed
824
  {
825 826
    TABLE_LIST *where= 0;
    Field *tmp= (Field *)not_found_field;
827
    if ((tmp= find_field_in_tables(thd, this, tables, &where, 0)) ==
828
	not_found_field)
829 830 831 832 833 834 835 836 837 838
    {
      /*
	We can't find table field in table list of current select, 
	consequently we have to find it in outer subselect(s).
	We can't join lists of outer & current select, because of scope 
	of view rules. For example if both tables (outer & current) have 
	field 'field' it is not mistake to refer to this field without 
	mention of table name, but if we join tables in one list it will
	cause error ER_NON_UNIQ_ERROR in find_field_in_tables.
      */
839
      SELECT_LEX *last= 0;
hf@bisonxp.(none)'s avatar
hf@bisonxp.(none) committed
840 841 842
#ifdef EMBEDDED_LIBRARY
      thd->net.last_errno= 0;
#endif
843
      TABLE_LIST *table_list;
844
      Item **refer= (Item **)not_found_item;
845
      uint counter;
846
      // Prevent using outer fields in subselects, that is not supported now
847
      SELECT_LEX *cursel=(SELECT_LEX *) thd->lex.current_select;
848 849
      if (cursel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE)
	for (SELECT_LEX *sl= cursel->outer_select();
850 851
	     sl;
	     sl= sl->outer_select())
852
	{
853 854 855 856 857 858
	  table_list= (last= sl)->get_table_list();
	  if (sl->insert_select && table_list)
	  {
	    // it is primary INSERT st_select_lex => skip first table resolving
	    table_list= table_list->next;
	  }
859
	  if ((tmp= find_field_in_tables(thd, this,
860
					 table_list, &where,
861 862
					 0)) != not_found_field)
	    break;
863
	  if ((refer= find_item_in_list(this, sl->item_list, &counter, 
864
					 REPORT_EXCEPT_NOT_FOUND)) != 
865
	       (Item **) not_found_item)
866
	    break;
867 868
	  if (sl->master_unit()->first_select()->linkage ==
	      DERIVED_TABLE_TYPE)
869
	    break; // do not look over derived table
870
	}
871
      if (!tmp)
872
	return -1;
873 874 875
      else if (!refer)
	return 1;
      else if (tmp == not_found_field && refer == (Item **)not_found_item)
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
876
      {
877
	// call to return error code
878
	find_field_in_tables(thd, this, tables, &where, 1);
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
879 880
	return -1;
      }
881 882
      else if (refer != (Item **)not_found_item)
      {
883 884 885 886 887 888 889
	if (!(*refer)->fixed)
	{
	  my_error(ER_ILLEGAL_REFERENCE, MYF(0), name,
		   "forward reference in item list");
	  return -1;
	}

bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
890 891 892 893 894
	Item_ref *rf;
	*ref= rf= new Item_ref(last->ref_pointer_array + counter,
			       (char *)table_name,
			       (char *)field_name);
	if (!rf)
895
	  return 1;
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
896
	if (rf->fix_fields(thd, tables, ref) || rf->check_cols(1))
897
	  return 1;
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
898

899
	mark_as_dependent(last, cursel, rf);
900 901
	return 0;
      }
902
      else
903
      {
904
	mark_as_dependent(last, cursel, this);
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
905
	if (last->having_fix_field)
906 907 908 909 910 911 912
	{
	  Item_ref *rf;
	  *ref= rf= new Item_ref((where->db[0]?where->db:0), 
				 (char *)where->alias,
				 (char *)field_name);
	  if (!rf)
	    return 1;
913
	  return rf->fix_fields(thd, tables, ref) ||  rf->check_cols(1);
914
	}
915
      }
916
    }
917 918 919
    else if (!tmp)
      return -1;

bk@work.mysql.com's avatar
bk@work.mysql.com committed
920 921
    set_field(tmp);
  }
922 923 924 925 926 927 928 929
  else if (thd && thd->set_query_id && field->query_id != thd->query_id)
  {
    /* We only come here in unions */
    TABLE *table=field->table;
    field->query_id=thd->query_id;
    table->used_fields++;
    table->used_keys&=field->part_of_key;
  }
930
  fixed= 1;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
931 932 933 934 935 936
  return 0;
}


void Item::init_make_field(Send_field *tmp_field,
			   enum enum_field_types field_type)
937
{  
938 939 940 941 942 943 944
  char *empty_name= (char*) "";
  tmp_field->db_name=	 	empty_name;
  tmp_field->org_table_name=	empty_name;
  tmp_field->org_col_name=	empty_name;
  tmp_field->table_name=	empty_name;
  tmp_field->col_name=		name;
  tmp_field->charsetnr= 	charset()->number;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
945 946 947 948
  tmp_field->flags=maybe_null ? 0 : NOT_NULL_FLAG;
  tmp_field->type=field_type;
  tmp_field->length=max_length;
  tmp_field->decimals=decimals;
949 950
  if (unsigned_flag)
    tmp_field->flags |= UNSIGNED_FLAG;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
951 952
}

953
void Item::make_field(Send_field *tmp_field)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
954
{
955
  init_make_field(tmp_field, field_type());
bk@work.mysql.com's avatar
bk@work.mysql.com committed
956 957
}

958
enum_field_types Item::field_type() const
bk@work.mysql.com's avatar
bk@work.mysql.com committed
959
{
960 961 962
  return ((result_type() == STRING_RESULT) ? FIELD_TYPE_VAR_STRING :
	  (result_type() == INT_RESULT) ? FIELD_TYPE_LONGLONG :
	  FIELD_TYPE_DOUBLE);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
963 964
}

965 966
/* ARGSUSED */
void Item_field::make_field(Send_field *tmp_field)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
967
{
968 969 970
  field->make_field(tmp_field);
  if (name)
    tmp_field->col_name=name;			// Use user supplied name
bk@work.mysql.com's avatar
bk@work.mysql.com committed
971 972 973 974 975 976 977 978 979 980 981 982
}

/*
** Set a field:s value from a item
*/


void Item_field::save_org_in_field(Field *to)
{
  if (field->is_null())
  {
    null_value=1;
983
    set_field_to_null_with_conversions(to, 1);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
984 985 986 987 988 989 990 991 992
  }
  else
  {
    to->set_notnull();
    field_conv(to,field);
    null_value=0;
  }
}

monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
993
int Item_field::save_in_field(Field *to, bool no_conversions)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
994 995 996 997
{
  if (result_field->is_null())
  {
    null_value=1;
998
    return set_field_to_null_with_conversions(to, no_conversions);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
999 1000 1001 1002 1003 1004 1005 1006 1007 1008
  }
  else
  {
    to->set_notnull();
    field_conv(to,result_field);
    null_value=0;
  }
  return 0;
}

1009

monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025
/*
  Store null in field

  SYNOPSIS
    save_in_field()
    field		Field where we want to store NULL

  DESCRIPTION
    This is used on INSERT.
    Allow NULL to be inserted in timestamp and auto_increment values

  RETURN VALUES
    0	 ok
    1	 Field doesn't support NULL values and can't handle 'field = NULL'
*/   

monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
1026
int Item_null::save_in_field(Field *field, bool no_conversions)
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
1027
{
1028
  return set_field_to_null_with_conversions(field, no_conversions);
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
1029 1030 1031
}


1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
/*
  Store null in field

  SYNOPSIS
    save_safe_in_field()
    field		Field where we want to store NULL

  RETURN VALUES
    0	 ok
    1	 Field doesn't support NULL values
*/   

monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
1044
int Item_null::save_safe_in_field(Field *field)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1045 1046 1047 1048 1049
{
  return set_field_to_null(field);
}


monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
1050
int Item::save_in_field(Field *field, bool no_conversions)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1051
{
1052
  int error;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1053 1054 1055 1056 1057
  if (result_type() == STRING_RESULT ||
      result_type() == REAL_RESULT &&
      field->result_type() == STRING_RESULT)
  {
    String *result;
1058
    CHARSET_INFO *cs=charset();
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1059
    char buff[MAX_FIELD_WIDTH];		// Alloc buffer for small columns
1060
    str_value.set_quick(buff,sizeof(buff),cs);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1061 1062
    result=val_str(&str_value);
    if (null_value)
1063
      return set_field_to_null_with_conversions(field, no_conversions);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1064
    field->set_notnull();
1065
    error=field->store(result->ptr(),result->length(),cs);
1066
    str_value.set_quick(0, 0, cs);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1067 1068 1069 1070 1071 1072 1073
  }
  else if (result_type() == REAL_RESULT)
  {
    double nr=val();
    if (null_value)
      return set_field_to_null(field);
    field->set_notnull();
1074
    error=field->store(nr);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1075 1076 1077 1078 1079
  }
  else
  {
    longlong nr=val_int();
    if (null_value)
1080
      return set_field_to_null_with_conversions(field, no_conversions);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1081
    field->set_notnull();
1082
    error=field->store(nr);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1083
  }
1084
  return (error) ? -1 : 0;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1085 1086
}

1087

monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
1088
int Item_string::save_in_field(Field *field, bool no_conversions)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1089 1090 1091 1092 1093 1094
{
  String *result;
  result=val_str(&str_value);
  if (null_value)
    return set_field_to_null(field);
  field->set_notnull();
1095
  return (field->store(result->ptr(),result->length(),charset())) ? -1 : 0;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1096 1097
}

monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
1098 1099

int Item_int::save_in_field(Field *field, bool no_conversions)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1100 1101 1102 1103 1104
{
  longlong nr=val_int();
  if (null_value)
    return set_field_to_null(field);
  field->set_notnull();
1105
  return (field->store(nr)) ? -1 : 0;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1106 1107
}

monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
1108 1109

int Item_real::save_in_field(Field *field, bool no_conversions)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1110 1111 1112 1113 1114
{
  double nr=val();
  if (null_value)
    return set_field_to_null(field);
  field->set_notnull();
1115
  return (field->store(nr)) ? -1 : 0;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1116 1117 1118 1119 1120 1121 1122 1123
}

/****************************************************************************
** varbinary item
** In string context this is a binary string
** In number context this is a longlong value.
****************************************************************************/

1124
inline uint char_val(char X)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1125 1126 1127 1128 1129 1130
{
  return (uint) (X >= '0' && X <= '9' ? X-'0' :
		 X >= 'A' && X <= 'Z' ? X-'A'+10 :
		 X-'a'+10);
}

1131

1132
Item_varbinary::Item_varbinary(const char *str, uint str_length)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1133 1134 1135 1136 1137 1138
{
  name=(char*) str-2;				// Lex makes this start with 0x
  max_length=(str_length+1)/2;
  char *ptr=(char*) sql_alloc(max_length+1);
  if (!ptr)
    return;
1139
  str_value.set(ptr,max_length,&my_charset_bin);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1140 1141 1142 1143 1144 1145 1146 1147 1148
  char *end=ptr+max_length;
  if (max_length*2 != str_length)
    *ptr++=char_val(*str++);			// Not even, assume 0 prefix
  while (ptr != end)
  {
    *ptr++= (char) (char_val(str[0])*16+char_val(str[1]));
    str+=2;
  }
  *ptr=0;					// Keep purify happy
1149
  set_charset(&my_charset_bin, DERIVATION_COERCIBLE);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163
}

longlong Item_varbinary::val_int()
{
  char *end=(char*) str_value.ptr()+str_value.length(),
       *ptr=end-min(str_value.length(),sizeof(longlong));

  ulonglong value=0;
  for (; ptr != end ; ptr++)
    value=(value << 8)+ (ulonglong) (uchar) *ptr;
  return (longlong) value;
}


monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
1164
int Item_varbinary::save_in_field(Field *field, bool no_conversions)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1165
{
1166
  int error;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1167 1168 1169
  field->set_notnull();
  if (field->result_type() == STRING_RESULT)
  {
1170
    error=field->store(str_value.ptr(),str_value.length(),charset());
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1171 1172 1173 1174
  }
  else
  {
    longlong nr=val_int();
1175
    error=field->store(nr);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1176
  }
1177
  return (error) ? -1 :  0;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1178 1179 1180
}


1181 1182 1183 1184 1185
/*
  Pack data in buffer for sending
*/

bool Item_null::send(Protocol *protocol, String *packet)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1186
{
1187
  return protocol->store_null();
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1188 1189 1190
}

/*
1191
  This is only called from items that is not of type item_field
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1192 1193
*/

1194
bool Item::send(Protocol *protocol, String *buffer)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1195
{
1196 1197 1198 1199 1200 1201
  bool result;
  enum_field_types type;
  LINT_INIT(result);

  switch ((type=field_type())) {
  default:
1202 1203 1204 1205 1206 1207 1208 1209 1210
  case MYSQL_TYPE_NULL:
  case MYSQL_TYPE_DECIMAL:
  case MYSQL_TYPE_ENUM:
  case MYSQL_TYPE_SET:
  case MYSQL_TYPE_TINY_BLOB:
  case MYSQL_TYPE_MEDIUM_BLOB:
  case MYSQL_TYPE_LONG_BLOB:
  case MYSQL_TYPE_BLOB:
  case MYSQL_TYPE_GEOMETRY:
1211 1212 1213 1214 1215
  case MYSQL_TYPE_STRING:
  case MYSQL_TYPE_VAR_STRING:
  {
    String *res;
    if ((res=val_str(buffer)))
1216
      result= protocol->store(res->ptr(),res->length(),res->charset());
1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234
    break;
  }
  case MYSQL_TYPE_TINY:
  {
    longlong nr;
    nr= val_int();
    if (!null_value)
      result= protocol->store_tiny(nr);
    break;
  }
  case MYSQL_TYPE_SHORT:
  {
    longlong nr;
    nr= val_int();
    if (!null_value)
      result= protocol->store_short(nr);
    break;
  }
1235
  case MYSQL_TYPE_INT24:
1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261
  case MYSQL_TYPE_LONG:
  {
    longlong nr;
    nr= val_int();
    if (!null_value)
      result= protocol->store_long(nr);
    break;
  }
  case MYSQL_TYPE_LONGLONG:
  {
    longlong nr;
    nr= val_int();
    if (!null_value)
      result= protocol->store_longlong(nr, unsigned_flag);
    break;
  }
  case MYSQL_TYPE_DOUBLE:
  {
    double nr;
    nr= val();
    if (!null_value)
      result= protocol->store(nr, decimals, buffer);
    break;
  }
  case MYSQL_TYPE_DATETIME:
  case MYSQL_TYPE_DATE:
1262
  case MYSQL_TYPE_TIMESTAMP:
1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286
  {
    TIME tm;
    get_date(&tm, 1);
    if (!null_value)
    {
      if (type == MYSQL_TYPE_DATE)
	return protocol->store_date(&tm);
      else
	result= protocol->store(&tm);
    }
    break;
  }
  case MYSQL_TYPE_TIME:
  {
    TIME tm;
    get_time(&tm);
    if (!null_value)
      result= protocol->store_time(&tm);
    break;
  }
  }
  if (null_value)
    result= protocol->store_null();
  return result;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1287 1288
}

1289 1290

bool Item_field::send(Protocol *protocol, String *buffer)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1291
{
1292
  return protocol->store(result_field);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1293 1294 1295 1296 1297 1298 1299
}

/*
  This is used for HAVING clause
  Find field in select list having the same name
 */

1300
bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1301
{
1302
  uint counter;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1303 1304
  if (!ref)
  {
1305
    TABLE_LIST *where= 0, *table_list;
1306
    SELECT_LEX *sl= thd->lex.current_select->outer_select();
1307 1308 1309 1310 1311
    /*
      Finding only in current select will be performed for selects that have 
      not outer one and for derived tables (which not support using outer 
      fields for now)
    */
1312
    if ((ref= find_item_in_list(this, 
1313
				*(thd->lex.current_select->get_item_list()),
1314
				&counter,
1315
				((sl && 
1316 1317
				  thd->lex.current_select->master_unit()->
				  first_select()->linkage !=
1318 1319 1320
				  DERIVED_TABLE_TYPE) ? 
				  REPORT_EXCEPT_NOT_FOUND :
				  REPORT_ALL_ERRORS))) ==
1321
	(Item **)not_found_item)
1322
    {
1323
      Field *tmp= (Field*) not_found_field;
1324
      /*
1325
	We can't find table field in table list of current select,
1326
	consequently we have to find it in outer subselect(s).
1327 1328 1329
	We can't join lists of outer & current select, because of scope
	of view rules. For example if both tables (outer & current) have
	field 'field' it is not mistake to refer to this field without
1330
	mention of table name, but if we join tables in one list it will
1331
	cause error ER_NON_UNIQ_ERROR in find_item_in_list.
1332 1333
      */
      SELECT_LEX *last=0;
1334
      for ( ; sl ; sl= sl->outer_select())
1335 1336
      {
	if ((ref= find_item_in_list(this, (last= sl)->item_list,
1337 1338
				    &counter,
				    REPORT_EXCEPT_NOT_FOUND)) !=
1339
	   (Item **)not_found_item)
1340
	  break;
1341 1342 1343 1344 1345 1346
	table_list= sl->get_table_list();
	if (sl->insert_select && table_list)
	{
	  // it is primary INSERT st_select_lex => skip first table resolving
	  table_list= table_list->next;
	}
1347
	if ((tmp= find_field_in_tables(thd, this,
1348
				       table_list, &where,
1349 1350
				       0)) != not_found_field)
	  break;
1351 1352
	if (sl->master_unit()->first_select()->linkage ==
	    DERIVED_TABLE_TYPE)
1353
	  break; // do not look over derived table
1354
      }
1355

1356
      if (!ref)
1357
	return 1;
1358 1359 1360
      else if (!tmp)
	return -1;
      else if (ref == (Item **)not_found_item && tmp == not_found_field)
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
1361 1362
      {
	// Call to report error
1363 1364
	find_item_in_list(this,
			  *(thd->lex.current_select->get_item_list()),
1365
			  &counter,
1366 1367
			  REPORT_ALL_ERRORS);
        ref= 0;
1368
	return 1;
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
1369
      }
1370 1371 1372
      else if (tmp != not_found_field)
      {
	ref= 0; // To prevent "delete *ref;" on ~Item_erf() of this item
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
1373 1374
	Item_field* fld;
	if (!((*reference)= fld= new Item_field(tmp)))
1375
	  return 1;
1376
	mark_as_dependent(last, thd->lex.current_select, fld);
1377 1378
	return 0;
      }
1379 1380
      else
      {
1381 1382 1383 1384 1385 1386
	if (!(*ref)->fixed)
	{
	  my_error(ER_ILLEGAL_REFERENCE, MYF(0), name,
		   "forward reference in item list");
	  return -1;
	}
1387
	mark_as_dependent(last, thd->lex.current_select,
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
1388 1389
			  this);
	ref= last->ref_pointer_array + counter;
1390 1391
      }
    }
1392
    else if (!ref)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1393
      return 1;
1394 1395 1396 1397 1398 1399 1400 1401
    else
    {
      if (!(*ref)->fixed)
      {
	my_error(ER_ILLEGAL_REFERENCE, MYF(0), name,
		 "forward reference in item list");
	return -1;
      }
1402
      ref= thd->lex.current_select->ref_pointer_array + counter;
1403
    }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1404
  }
1405

1406 1407 1408 1409 1410 1411 1412
  /*
    The following conditional is changed as to correctly identify 
    incorrect references in group functions or forward references 
    with sub-select's / derived tables, while it prevents this 
    check when Item_ref is created in an expression involving 
    summing function, which is to be placed in the user variable.
  */
1413
  if (((*ref)->with_sum_func && name &&
1414
       (depended_from ||
1415
	!(thd->lex.current_select->linkage != GLOBAL_OPTIONS_TYPE &&
bell@sanja.is.com.ua's avatar
bell@sanja.is.com.ua committed
1416
	  thd->lex.current_select->having_fix_field))) ||
1417 1418 1419 1420 1421 1422 1423 1424
      !(*ref)->fixed)
  {
    my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, 
	     ((*ref)->with_sum_func?
	      "reference on group function":
	      "forward reference in item list"));
    return 1;
  }
1425 1426 1427
  max_length= (*ref)->max_length;
  maybe_null= (*ref)->maybe_null;
  decimals=   (*ref)->decimals;
1428
  set_charset((*ref)->charset());
monty@mashka.mysql.fi's avatar
monty@mashka.mysql.fi committed
1429
  with_sum_func= (*ref)->with_sum_func;
1430
  fixed= 1;
1431

1432 1433
  if (ref && (*ref)->check_cols(1))
    return 1;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1434 1435 1436
  return 0;
}

1437

hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1438 1439
bool Item_default_value::eq(const Item *item, bool binary_cmp) const
{
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1440
  return item->type() == DEFAULT_VALUE_ITEM && 
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1441 1442 1443
    ((Item_default_value *)item)->arg->eq(arg, binary_cmp);
}

1444

hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1445 1446
bool Item_default_value::fix_fields(THD *thd, struct st_table_list *table_list, Item **items)
{
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1447 1448
  if (!arg)
    return false;
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1449 1450 1451
  bool res= arg->fix_fields(thd, table_list, items);
  if (res)
    return res;
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1452 1453 1454
  /* arg->type() can be only REF_ITEM or FIELD_ITEM for it defined as
   simple_ident in sql_yacc.yy
  */
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468
  if (arg->type() == REF_ITEM)
  {
    Item_ref *ref= (Item_ref *)arg;
    if (ref->ref[0]->type() != FIELD_ITEM)
    {
      return 1;
    }
    arg= ref->ref[0];
  }
  Item_field *field_arg= (Item_field *)arg;
  Field *def_field= (Field*) sql_alloc(field_arg->field->size_of());
  if (!def_field)
    return 1;
  memcpy(def_field, field_arg->field, field_arg->field->size_of());
1469 1470
  def_field->move_field(def_field->table->default_values -
                        def_field->table->record[0]);
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1471 1472 1473 1474
  set_field(def_field);
  return 0;
}

hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1475 1476
void Item_default_value::print(String *str)
{
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1477 1478 1479
  if (!arg)
  {
    str->append("DEFAULT");
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1480
    return;
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1481 1482
  }
  str->append("DEFAULT(");
hf@deer.mysql.r18.ru's avatar
SCRUM  
hf@deer.mysql.r18.ru committed
1483 1484 1485
  arg->print(str);
  str->append(')');
}
1486

1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527
bool Item_insert_value::eq(const Item *item, bool binary_cmp) const
{
  return item->type() == INSERT_VALUE_ITEM &&
    ((Item_default_value *)item)->arg->eq(arg, binary_cmp);
}


bool Item_insert_value::fix_fields(THD *thd, struct st_table_list *table_list, Item **items)
{
  bool res= arg->fix_fields(thd, table_list, items);
  if (res)
    return res;
  /*
    arg->type() can be only REF_ITEM or FIELD_ITEM as arg is
    a simple_ident in sql_yacc.yy
  */
  if (arg->type() == REF_ITEM)
  {
    Item_ref *ref= (Item_ref *)arg;
    if (ref->ref[0]->type() != FIELD_ITEM)
    {
      return 1;
    }
    arg= ref->ref[0];
  }
  Item_field *field_arg= (Item_field *)arg;
  if (field_arg->field->table->insert_values)
  {
    Field *def_field= (Field*) sql_alloc(field_arg->field->size_of());
    if (!def_field)
      return 1;
    memcpy(def_field, field_arg->field, field_arg->field->size_of());
    def_field->move_field(def_field->table->insert_values -
                          def_field->table->record[0]);
    set_field(def_field);
  }
  else
  {
    Field *field=field_arg->field;
    /* charset doesn't matter here, it's to avoid sigsegv only */
    set_field(new Field_null(0,0,Field::NONE,field->field_name,field->table,
1528
          &my_charset_bin));
1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539
  }
  return 0;
}

void Item_insert_value::print(String *str)
{
  str->append("VALUE(");
  arg->print(str);
  str->append(')');
}

bk@work.mysql.com's avatar
bk@work.mysql.com committed
1540
/*
1541 1542
  If item is a const function, calculate it and return a const item
  The original item is freed if not returned
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1543 1544 1545 1546 1547 1548 1549 1550
*/

Item_result item_cmp_type(Item_result a,Item_result b)
{
  if (a == STRING_RESULT && b == STRING_RESULT)
    return STRING_RESULT;
  else if (a == INT_RESULT && b == INT_RESULT)
    return INT_RESULT;
1551 1552
  else if (a == ROW_RESULT || b == ROW_RESULT)
    return ROW_RESULT;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568
  else
    return REAL_RESULT;
}


Item *resolve_const_item(Item *item,Item *comp_item)
{
  if (item->basic_const_item())
    return item;				// Can't be better
  Item_result res_type=item_cmp_type(comp_item->result_type(),
				     item->result_type());
  char *name=item->name;			// Alloced by sql_alloc

  if (res_type == STRING_RESULT)
  {
    char buff[MAX_FIELD_WIDTH];
1569
    String tmp(buff,sizeof(buff),&my_charset_bin),*result;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582
    result=item->val_str(&tmp);
    if (item->null_value)
    {
#ifdef DELETE_ITEMS
      delete item;
#endif
      return new Item_null(name);
    }
    uint length=result->length();
    char *tmp_str=sql_strmake(result->ptr(),length);
#ifdef DELETE_ITEMS
    delete item;
#endif
1583
    return new Item_string(name,tmp_str,length,result->charset());
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623
  }
  if (res_type == INT_RESULT)
  {
    longlong result=item->val_int();
    uint length=item->max_length;
    bool null_value=item->null_value;
#ifdef DELETE_ITEMS
    delete item;
#endif
    return (null_value ? (Item*) new Item_null(name) :
	    (Item*) new Item_int(name,result,length));
  }
  else
  {						// It must REAL_RESULT
    double result=item->val();
    uint length=item->max_length,decimals=item->decimals;
    bool null_value=item->null_value;
#ifdef DELETE_ITEMS
    delete item;
#endif
    return (null_value ? (Item*) new Item_null(name) :
	    (Item*) new Item_real(name,result,decimals,length));
  }
}

/*
  Return true if the value stored in the field is equal to the const item
  We need to use this on the range optimizer because in some cases
  we can't store the value in the field without some precision/character loss.
*/

bool field_is_equal_to_item(Field *field,Item *item)
{

  Item_result res_type=item_cmp_type(field->result_type(),
				     item->result_type());
  if (res_type == STRING_RESULT)
  {
    char item_buff[MAX_FIELD_WIDTH];
    char field_buff[MAX_FIELD_WIDTH];
1624 1625
    String item_tmp(item_buff,sizeof(item_buff),&my_charset_bin),*item_result;
    String field_tmp(field_buff,sizeof(field_buff),&my_charset_bin);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1626 1627 1628 1629
    item_result=item->val_str(&item_tmp);
    if (item->null_value)
      return 1;					// This must be true
    field->val_str(&field_tmp,&field_tmp);
1630
    return !sortcmp(&field_tmp,item_result,&my_charset_bin);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1631 1632 1633 1634 1635 1636 1637 1638 1639
  }
  if (res_type == INT_RESULT)
    return 1;					// Both where of type int
  double result=item->val();
  if (item->null_value)
    return 1;
  return result == field->val_real();
}

1640 1641 1642 1643 1644 1645 1646 1647 1648 1649
Item_cache* Item_cache::get_cache(Item_result type)
{
  switch (type)
  {
  case INT_RESULT:
    return new Item_cache_int();
  case REAL_RESULT:
    return new Item_cache_real();
  case STRING_RESULT:
    return new Item_cache_str();
1650 1651
  case ROW_RESULT:
    return new Item_cache_row();
1652 1653 1654 1655 1656 1657 1658 1659 1660
  default:
    // should never be in real life
    DBUG_ASSERT(0);
    return 0;
  }
}

void Item_cache_str::store(Item *item)
{
1661 1662
  value_buff.set(buffer, sizeof(buffer), item->charset());
  value= item->str_result(&value_buff);
1663 1664
  if ((null_value= item->null_value))
    value= 0;
1665
  else if (value != &value_buff)
1666 1667 1668 1669 1670 1671 1672 1673 1674
  {
    /*
      We copy string value to avoid changing value if 'item' is table field
      in queries like following (where t1.c is varchar):
      select a, 
             (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a'),
             (select c from t1 where a=t2.a)
        from t2;
    */
1675 1676
    value_buff.copy(*value);
    value= &value_buff;
1677
  }
1678
  set_charset(&item->collation);
1679 1680 1681
}
double Item_cache_str::val()
{ 
1682
  int err;
1683
  if (value)
1684
    return my_strntod(value->charset(), (char*) value->ptr(),
1685
		      value->length(), (char**) 0, &err);
1686 1687 1688 1689 1690
  else
    return (double)0;
}
longlong Item_cache_str::val_int()
{
1691
  int err;
1692 1693
  if (value)
    return my_strntoll(value->charset(), value->ptr(),
1694
		       value->length(), 10, (char**) 0, &err);
1695 1696 1697
  else
    return (longlong)0;
}
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1698

1699 1700
bool Item_cache_row::allocate(uint num)
{
1701
  item_count= num;
1702
  THD *thd= current_thd;
1703 1704
  return (!(values= 
	    (Item_cache **) thd->calloc(sizeof(Item_cache *)*item_count)));
1705 1706 1707 1708 1709 1710
}

bool Item_cache_row::setup(Item * item)
{
  if (!values && allocate(item->cols()))
    return 1;
1711
  for (uint i= 0; i < item_count; i++)
1712
  {
1713
    Item *el= item->el(i);
1714 1715
    Item_cache *tmp;
    if (!(tmp= values[i]= Item_cache::get_cache(el->result_type())))
1716
      return 1;
1717
    tmp->setup(el);
1718 1719 1720 1721 1722 1723 1724 1725
  }
  return 0;
}

void Item_cache_row::store(Item * item)
{
  null_value= 0;
  item->bring_value();
1726
  for (uint i= 0; i < item_count; i++)
1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743
  {
    values[i]->store(item->el(i));
    null_value|= values[i]->null_value;
  }
}

void Item_cache_row::illegal_method_call(const char *method)
{
  DBUG_ENTER("Item_cache_row::illegal_method_call");
  DBUG_PRINT("error", ("!!! %s method was called for row item", method));
  DBUG_ASSERT(0);
  my_error(ER_CARDINALITY_COL, MYF(0), 1);
  DBUG_VOID_RETURN;
}

bool Item_cache_row::check_cols(uint c)
{
1744
  if (c != item_count)
1745 1746 1747 1748 1749 1750 1751 1752 1753
  {
    my_error(ER_CARDINALITY_COL, MYF(0), c);
    return 1;
  }
  return 0;
}

bool Item_cache_row::null_inside()
{
1754
  for (uint i= 0; i < item_count; i++)
1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772
  {
    if (values[i]->cols() > 1)
    {
      if (values[i]->null_inside())
	return 1;
    }
    else
    {
      values[i]->val_int();
      if (values[i]->null_value)
	return 1;
    }
  }
  return 0;
}

void Item_cache_row::bring_value()
{
1773
  for (uint i= 0; i < item_count; i++)
1774 1775 1776
    values[i]->bring_value();
  return;
}
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1777 1778 1779 1780 1781 1782 1783 1784

/*****************************************************************************
** Instantiate templates
*****************************************************************************/

#ifdef __GNUC__
template class List<Item>;
template class List_iterator<Item>;
monty@tik.mysql.fi's avatar
monty@tik.mysql.fi committed
1785
template class List_iterator_fast<Item>;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
1786 1787
template class List<List_item>;
#endif