item_subselect.cc 41 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/* Copyright (C) 2000 MySQL AB

   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.

   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.

   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 */

17
/*
18 19 20 21 22 23 24 25 26 27 28 29 30 31
   subselect Item

SUBSELECT TODO:
   - add function from mysql_select that use JOIN* as parameter to JOIN methods
     (sql_select.h/sql_select.cc)
*/

#ifdef __GNUC__
#pragma implementation				// gcc: Class implementation
#endif

#include "mysql_priv.h"
#include "sql_select.h"

unknown's avatar
unknown committed
32 33 34 35 36
inline Item * and_items(Item* cond, Item *item)
{
  return (cond? (new Item_cond_and(cond, item)) : item);
}

37
Item_subselect::Item_subselect():
unknown's avatar
unknown committed
38 39 40
  Item_result_field(), value_assigned(0), thd(0), substitution(0),
  engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
  const_item_cache(1), engine_changed(0), changed(0)
41
{
42
  reset();
43
  /*
44
    item value is NULL if select_subselect not changed this value
45 46 47 48 49
    (i.e. some rows will be found returned)
  */
  null_value= 1;
}

50

51
void Item_subselect::init(st_select_lex *select_lex,
unknown's avatar
unknown committed
52
			  select_subselect *result)
53 54 55
{

  DBUG_ENTER("Item_subselect::init");
unknown's avatar
unknown committed
56
  DBUG_PRINT("subs", ("select_lex 0x%xl", (ulong) select_lex));
unknown's avatar
unknown committed
57
  unit= select_lex->master_unit();
unknown's avatar
unknown committed
58

59 60 61 62 63 64 65
  if (unit->item)
  {
    /*
      Item can be changed in JOIN::prepare while engine in JOIN::optimize
      => we do not copy old_engine here
    */
    engine= unit->item->engine;
66
    parsing_place= unit->item->parsing_place;
67 68 69 70
    unit->item->engine= 0;
    unit->item= this;
    engine->change_item(this, result);
  }
unknown's avatar
unknown committed
71
  else
72
  {
unknown's avatar
unknown committed
73 74 75 76 77 78 79 80
    SELECT_LEX *outer_select= unit->outer_select();
    /*
      do not take into account expression inside aggregate functions because
      they can access original table fields
    */
    parsing_place= (outer_select->in_sum_expr ?
                    NO_MATTER :
                    outer_select->parsing_place);
81 82 83 84 85
    if (select_lex->next_select())
      engine= new subselect_union_engine(unit, result, this);
    else
      engine= new subselect_single_select_engine(select_lex, result, this);
  }
86 87
  {
    SELECT_LEX *upper= unit->outer_select();
88
    if (upper->parsing_place == IN_HAVING)
89 90
      upper->subquery_in_having= 1;
  }
91 92 93
  DBUG_VOID_RETURN;
}

unknown's avatar
unknown committed
94 95
void Item_subselect::cleanup()
{
unknown's avatar
unknown committed
96
  DBUG_ENTER("Item_subselect::cleanup");
unknown's avatar
unknown committed
97
  Item_result_field::cleanup();
unknown's avatar
unknown committed
98 99
  if (old_engine)
  {
100 101
    if (engine)
      engine->cleanup();
unknown's avatar
unknown committed
102 103 104
    engine= old_engine;
    old_engine= 0;
  }
105 106
  if (engine)
    engine->cleanup();
unknown's avatar
unknown committed
107 108 109 110 111 112 113 114 115 116 117
  reset();
  value_assigned= 0;
  DBUG_VOID_RETURN;
}

void Item_singlerow_subselect::cleanup()
{
  DBUG_ENTER("Item_singlerow_subselect::cleanup");
  value= 0; row= 0;
  Item_subselect::cleanup();
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
118
}
119

unknown's avatar
unknown committed
120 121
Item_subselect::~Item_subselect()
{
122
  delete engine;
unknown's avatar
unknown committed
123 124
}

125
Item_subselect::trans_res
126
Item_subselect::select_transformer(JOIN *join)
unknown's avatar
unknown committed
127 128
{
  DBUG_ENTER("Item_subselect::select_transformer");
129
  DBUG_RETURN(RES_OK);
unknown's avatar
unknown committed
130 131 132
}


133
bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
134
{
135
  DBUG_ASSERT(fixed == 0);
136
  engine->set_thd((thd= thd_param));
137

138
  char const *save_where= thd->where;
139 140 141 142 143 144
  int res;

  if (check_stack_overrun(thd, (gptr)&res))
    return 1;

  res= engine->prepare();
unknown's avatar
unknown committed
145 146 147 148

  // all transformetion is done (used by prepared statements)
  changed= 1;

149
  if (!res)
unknown's avatar
unknown committed
150
  {
151 152
    if (substitution)
    {
unknown's avatar
unknown committed
153 154
      int ret= 0;

unknown's avatar
unknown committed
155 156 157
      // did we changed top item of WHERE condition
      if (unit->outer_select()->where == (*ref))
	unit->outer_select()->where= substitution; // correct WHERE for PS
158 159
      else if (unit->outer_select()->having == (*ref))
	unit->outer_select()->having= substitution; // correct HAVING for PS
unknown's avatar
unknown committed
160

161 162 163 164 165
      (*ref)= substitution;
      substitution->name= name;
      if (have_to_be_excluded)
	engine->exclude();
      substitution= 0;
166
      thd->where= "checking transformed subquery";
167 168
      if (!(*ref)->fixed)
	ret= (*ref)->fix_fields(thd, tables, ref);
169
      thd->where= save_where;
170 171
      return ret;
    }
unknown's avatar
unknown committed
172 173
    // Is it one field subselect?
    if (engine->cols() > max_columns)
174
    {
unknown's avatar
unknown committed
175
      my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
unknown's avatar
unknown committed
176 177
      return 1;
    }
178
    fix_length_and_dec();
unknown's avatar
unknown committed
179
  }
unknown's avatar
unknown committed
180 181
  else
    return 1;
182 183
  uint8 uncacheable= engine->uncacheable();
  if (uncacheable)
unknown's avatar
unknown committed
184 185
  {
    const_item_cache= 0;
186 187
    if (uncacheable & UNCACHEABLE_RAND)
      used_tables_cache|= RAND_TABLE_BIT;
unknown's avatar
unknown committed
188
  }
189
  fixed= 1;
190
  thd->where= save_where;
191 192 193
  return res;
}

194 195
bool Item_subselect::exec()
{
196
  int res;
unknown's avatar
unknown committed
197 198 199 200 201 202 203 204 205 206
  MEM_ROOT *old_root= thd->mem_root;

  /*
    As this is execution, all objects should be allocated through the main
    mem root
  */
  thd->mem_root= &thd->main_mem_root;
  res= engine->exec();
  thd->mem_root= old_root;

207 208 209 210 211 212
  if (engine_changed)
  {
    engine_changed= 0;
    return exec();
  }
  return (res);
213 214
}

215
Item::Type Item_subselect::type() const
216 217 218 219
{
  return SUBSELECT_ITEM;
}

unknown's avatar
unknown committed
220

221 222
void Item_subselect::fix_length_and_dec()
{
223
  engine->fix_length_and_dec(0);
224
}
unknown's avatar
unknown committed
225

unknown's avatar
unknown committed
226

227
table_map Item_subselect::used_tables() const
unknown's avatar
unknown committed
228
{
229
  return (table_map) (engine->uncacheable() ? used_tables_cache : 0L);
unknown's avatar
unknown committed
230 231
}

unknown's avatar
merge  
unknown committed
232

233 234
bool Item_subselect::const_item() const
{
unknown's avatar
unknown committed
235
  return const_item_cache;
236 237
}

unknown's avatar
unknown committed
238 239 240
Item *Item_subselect::get_tmp_table_item(THD *thd)
{
  if (!with_sum_func && !const_item())
unknown's avatar
unknown committed
241
    return new Item_field(result_field);
unknown's avatar
unknown committed
242 243
  return copy_or_same(thd);
}
unknown's avatar
merge  
unknown committed
244

245 246 247 248 249
void Item_subselect::update_used_tables()
{
  if (!engine->uncacheable())
  {
    // did all used tables become ststic?
unknown's avatar
unknown committed
250
    if (!(used_tables_cache & ~engine->upper_select_const_tables()))
251 252 253 254
      const_item_cache= 1;
  }
}

unknown's avatar
unknown committed
255 256 257 258 259 260 261 262 263

void Item_subselect::print(String *str)
{
  str->append('(');
  engine->print(str);
  str->append(')');
}


unknown's avatar
merge  
unknown committed
264
Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex)
265
  :Item_subselect(), value(0)
unknown's avatar
unknown committed
266
{
unknown's avatar
unknown committed
267
  DBUG_ENTER("Item_singlerow_subselect::Item_singlerow_subselect");
268
  init(select_lex, new select_singlerow_subselect(this));
unknown's avatar
unknown committed
269
  maybe_null= 1;
270
  max_columns= UINT_MAX;
unknown's avatar
unknown committed
271
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
272 273
}

274 275
Item_maxmin_subselect::Item_maxmin_subselect(Item_subselect *parent,
					     st_select_lex *select_lex,
unknown's avatar
unknown committed
276
					     bool max_arg)
277
  :Item_singlerow_subselect(), was_values(TRUE)
278 279
{
  DBUG_ENTER("Item_maxmin_subselect::Item_maxmin_subselect");
unknown's avatar
unknown committed
280 281
  max= max_arg;
  init(select_lex, new select_max_min_finder_subselect(this, max_arg));
282 283 284
  max_columns= 1;
  maybe_null= 1;
  max_columns= 1;
285 286 287 288 289 290 291

  /*
    Following information was collected during performing fix_fields()
    of Items belonged to subquery, which will be not repeated
  */
  used_tables_cache= parent->get_used_tables_cache();
  const_item_cache= parent->get_const_item_cache();
292

293 294 295
  DBUG_VOID_RETURN;
}

296 297
void Item_maxmin_subselect::cleanup()
{
unknown's avatar
unknown committed
298 299 300
  DBUG_ENTER("Item_maxmin_subselect::cleanup");
  Item_singlerow_subselect::cleanup();

301
  /*
unknown's avatar
unknown committed
302
    By default it is TRUE to avoid TRUE reporting by
303 304 305
    Item_func_not_all/Item_func_nop_all if this item was never called.

    Engine exec() set it to FALSE by reset_value_registration() call.
unknown's avatar
unknown committed
306 307
    select_max_min_finder_subselect::send_data() set it back to TRUE if some
    value will be found.
308 309
  */
  was_values= TRUE;
unknown's avatar
unknown committed
310
  DBUG_VOID_RETURN;
311 312 313
}


unknown's avatar
unknown committed
314 315
void Item_maxmin_subselect::print(String *str)
{
316
  str->append(max?"<max>":"<min>", 5);
unknown's avatar
unknown committed
317 318 319
  Item_singlerow_subselect::print(str);
}

320

unknown's avatar
unknown committed
321
void Item_singlerow_subselect::reset()
322
{
323 324 325
  null_value= 1;
  if (value)
    value->null_value= 1;
326 327
}

328

329
Item_subselect::trans_res
unknown's avatar
unknown committed
330
Item_singlerow_subselect::select_transformer(JOIN *join)
331
{
unknown's avatar
unknown committed
332 333
  if (changed)
    return RES_OK;
334

335
  SELECT_LEX *select_lex= join->select_lex;
336 337 338

  /* Juggle with current arena only if we're in prepared statement prepare */
  Item_arena *arena= join->thd->current_arena;
unknown's avatar
unknown committed
339

340 341
  if (!select_lex->master_unit()->first_select()->next_select() &&
      !select_lex->table_list.elements &&
unknown's avatar
unknown committed
342
      select_lex->item_list.elements == 1 &&
343
      !select_lex->item_list.head()->with_sum_func &&
unknown's avatar
unknown committed
344 345 346 347 348 349 350
      /*
	We cant change name of Item_field or Item_ref, because it will
	prevent it's correct resolving, but we should save name of
	removed item => we do not make optimization if top item of
	list is field or reference.
	TODO: solve above problem
      */
unknown's avatar
unknown committed
351
      !(select_lex->item_list.head()->type() == FIELD_ITEM ||
352 353 354 355 356 357 358
	select_lex->item_list.head()->type() == REF_ITEM) &&
      /*
        switch off this optimisation for prepare statement,
        because we do not rollback this changes
        TODO: make rollback for it, or special name resolving mode in 5.0.
      */
      !arena->is_stmt_prepare()
unknown's avatar
unknown committed
359
      )
360
  {
361

362
    have_to_be_excluded= 1;
363
    if (join->thd->lex->describe)
364 365 366
    {
      char warn_buff[MYSQL_ERRMSG_SIZE];
      sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
unknown's avatar
unknown committed
367
      push_warning(join->thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
368 369 370
		   ER_SELECT_REDUCED, warn_buff);
    }
    substitution= select_lex->item_list.head();
unknown's avatar
unknown committed
371
    /*
unknown's avatar
unknown committed
372
      as far as we moved content to upper level, field which depend of
unknown's avatar
unknown committed
373 374 375 376
      'upper' select is not really dependent => we remove this dependence
    */
    substitution->walk(&Item::remove_dependence_processor,
		       (byte *) select_lex->outer_select());
unknown's avatar
unknown committed
377 378
    /* SELECT without FROM clause can't have WHERE or HAVING clause */
    DBUG_ASSERT(join->conds == 0 && join->having == 0);
379
    return RES_REDUCE;
380
  }
381
  return RES_OK;
382

unknown's avatar
unknown committed
383 384
err:
  return RES_ERROR;
385 386
}

unknown's avatar
unknown committed
387
void Item_singlerow_subselect::store(uint i, Item *item)
unknown's avatar
unknown committed
388
{
389
  row[i]->store(item);
unknown's avatar
unknown committed
390 391
}

unknown's avatar
unknown committed
392
enum Item_result Item_singlerow_subselect::result_type() const
unknown's avatar
unknown committed
393
{
394 395 396
  return engine->type();
}

unknown's avatar
unknown committed
397
void Item_singlerow_subselect::fix_length_and_dec()
398
{
399 400 401 402 403
  if ((max_columns= engine->cols()) == 1)
  {
    engine->fix_length_and_dec(row= &value);
  }
  else
404
  {
405
    if (!(row= (Item_cache**) sql_alloc(sizeof(Item_cache*)*max_columns)))
406 407 408
      return;
    engine->fix_length_and_dec(row);
    value= *row;
409
  }
410 411 412 413 414 415 416
  /*
    If there are not tables in subquery then ability to have NULL value
    depends on SELECT list (if single row subquery have tables then it
    always can be NULL if there are not records fetched).
  */
  if (engine->no_tables())
    maybe_null= engine->may_be_null();
417 418
}

unknown's avatar
unknown committed
419
uint Item_singlerow_subselect::cols()
unknown's avatar
unknown committed
420
{
421 422 423
  return engine->cols();
}

unknown's avatar
unknown committed
424
bool Item_singlerow_subselect::check_cols(uint c)
425 426 427
{
  if (c != engine->cols())
  {
unknown's avatar
unknown committed
428
    my_error(ER_OPERAND_COLUMNS, MYF(0), c);
429 430 431 432 433
    return 1;
  }
  return 0;
}

unknown's avatar
unknown committed
434
bool Item_singlerow_subselect::null_inside()
435 436 437 438 439 440 441 442 443
{
  for (uint i= 0; i < max_columns ; i++)
  {
    if (row[i]->null_value)
      return 1;
  }
  return 0;
}

unknown's avatar
unknown committed
444
void Item_singlerow_subselect::bring_value()
445
{
446
  exec();
unknown's avatar
unknown committed
447 448
}

449
double Item_singlerow_subselect::val()
unknown's avatar
unknown committed
450
{
451
  DBUG_ASSERT(fixed == 1);
452
  if (!exec() && !value->null_value)
453 454 455 456 457
  {
    null_value= 0;
    return value->val();
  }
  else
unknown's avatar
unknown committed
458
  {
459
    reset();
unknown's avatar
unknown committed
460
    return 0;
unknown's avatar
unknown committed
461
  }
unknown's avatar
unknown committed
462 463
}

464
longlong Item_singlerow_subselect::val_int()
unknown's avatar
unknown committed
465
{
466
  DBUG_ASSERT(fixed == 1);
467
  if (!exec() && !value->null_value)
468 469 470 471 472
  {
    null_value= 0;
    return value->val_int();
  }
  else
unknown's avatar
unknown committed
473
  {
474
    reset();
unknown's avatar
unknown committed
475
    return 0;
unknown's avatar
unknown committed
476
  }
unknown's avatar
unknown committed
477 478
}

479
String *Item_singlerow_subselect::val_str (String *str)
unknown's avatar
unknown committed
480
{
481
  if (!exec() && !value->null_value)
482 483 484 485 486
  {
    null_value= 0;
    return value->val_str(str);
  }
  else
unknown's avatar
unknown committed
487
  {
488
    reset();
unknown's avatar
unknown committed
489
    return 0;
unknown's avatar
unknown committed
490
  }
unknown's avatar
unknown committed
491 492
}

unknown's avatar
unknown committed
493

494
Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex):
495
  Item_subselect()
unknown's avatar
unknown committed
496
{
unknown's avatar
unknown committed
497
  DBUG_ENTER("Item_exists_subselect::Item_exists_subselect");
498
  init(select_lex, new select_exists_subselect(this));
unknown's avatar
unknown committed
499 500 501 502
  max_columns= UINT_MAX;
  null_value= 0; //can't be NULL
  maybe_null= 0; //can't be NULL
  value= 0;
unknown's avatar
unknown committed
503 504 505 506 507
  // We need only 1 row to determinate existence
  select_lex->master_unit()->global_parameters->select_limit= 1;
  DBUG_VOID_RETURN;
}

unknown's avatar
unknown committed
508 509 510

void Item_exists_subselect::print(String *str)
{
511
  str->append("exists", 6);
unknown's avatar
unknown committed
512 513 514 515
  Item_subselect::print(str);
}


516 517
bool Item_in_subselect::test_limit(SELECT_LEX_UNIT *unit)
{
unknown's avatar
unknown committed
518 519
  if (unit->fake_select_lex &&
      unit->fake_select_lex->test_limit())
520
    return(1);
unknown's avatar
unknown committed
521

522 523 524
  SELECT_LEX *sl= unit->first_select();
  for (; sl; sl= sl->next_select())
  {
unknown's avatar
unknown committed
525
    if (sl->test_limit())
526 527 528 529 530
      return(1);
  }
  return(0);
}

531
Item_in_subselect::Item_in_subselect(Item * left_exp,
unknown's avatar
unknown committed
532
				     st_select_lex *select_lex):
533
  Item_exists_subselect(), optimizer(0), transformed(0), upper_item(0)
unknown's avatar
unknown committed
534 535
{
  DBUG_ENTER("Item_in_subselect::Item_in_subselect");
unknown's avatar
unknown committed
536
  left_expr= left_exp;
537
  init(select_lex, new select_exists_subselect(this));
unknown's avatar
unknown committed
538
  max_columns= UINT_MAX;
539
  maybe_null= 1;
540
  abort_on_null= 0;
541
  reset();
unknown's avatar
unknown committed
542
  //if test_limit will fail then error will be reported to client
543
  test_limit(select_lex->master_unit());
unknown's avatar
unknown committed
544 545 546
  DBUG_VOID_RETURN;
}

547
Item_allany_subselect::Item_allany_subselect(Item * left_exp,
unknown's avatar
unknown committed
548
					     Comp_creator *fn,
unknown's avatar
unknown committed
549 550 551
					     st_select_lex *select_lex,
					     bool all_arg)
  :Item_in_subselect(), all(all_arg)
unknown's avatar
unknown committed
552 553 554
{
  DBUG_ENTER("Item_in_subselect::Item_in_subselect");
  left_expr= left_exp;
555
  func= fn;
556
  init(select_lex, new select_exists_subselect(this));
unknown's avatar
unknown committed
557
  max_columns= 1;
558
  abort_on_null= 0;
559
  reset();
unknown's avatar
unknown committed
560
  //if test_limit will fail then error will be reported to client
561
  test_limit(select_lex->master_unit());
unknown's avatar
unknown committed
562
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
563 564
}

unknown's avatar
unknown committed
565

566 567
void Item_exists_subselect::fix_length_and_dec()
{
568
   decimals= 0;
569
   max_length= 1;
unknown's avatar
unknown committed
570
   max_columns= engine->cols();
571 572
}

unknown's avatar
unknown committed
573
double Item_exists_subselect::val()
unknown's avatar
unknown committed
574
{
575
  DBUG_ASSERT(fixed == 1);
576
  if (exec())
unknown's avatar
unknown committed
577
  {
578
    reset();
unknown's avatar
unknown committed
579
    return 0;
unknown's avatar
unknown committed
580
  }
unknown's avatar
unknown committed
581 582 583
  return (double) value;
}

584
longlong Item_exists_subselect::val_int()
unknown's avatar
unknown committed
585
{
586
  DBUG_ASSERT(fixed == 1);
587
  if (exec())
unknown's avatar
unknown committed
588
  {
589
    reset();
unknown's avatar
unknown committed
590
    return 0;
unknown's avatar
unknown committed
591
  }
unknown's avatar
unknown committed
592 593 594 595 596
  return value;
}

String *Item_exists_subselect::val_str(String *str)
{
597
  DBUG_ASSERT(fixed == 1);
598
  if (exec())
unknown's avatar
unknown committed
599
  {
600 601 602
    reset();
    return 0;
  }
unknown's avatar
unknown committed
603
  str->set(value,&my_charset_bin);
604 605 606
  return str;
}

unknown's avatar
unknown committed
607

unknown's avatar
unknown committed
608
double Item_in_subselect::val()
609
{
unknown's avatar
unknown committed
610 611 612 613 614
  /*
    As far as Item_in_subselect called only from Item_in_optimizer this
    method should not be used
  */
  DBUG_ASSERT(0);
615
  DBUG_ASSERT(fixed == 1);
616
  if (exec())
617 618 619 620 621 622 623 624 625 626
  {
    reset();
    null_value= 1;
    return 0;
  }
  if (was_null && !value)
    null_value= 1;
  return (double) value;
}

unknown's avatar
unknown committed
627

628
longlong Item_in_subselect::val_int()
629
{
630
  DBUG_ASSERT(fixed == 1);
631
  if (exec())
632 633 634 635 636 637 638 639 640 641
  {
    reset();
    null_value= 1;
    return 0;
  }
  if (was_null && !value)
    null_value= 1;
  return value;
}

unknown's avatar
unknown committed
642

643 644
String *Item_in_subselect::val_str(String *str)
{
unknown's avatar
unknown committed
645 646 647 648 649
  /*
    As far as Item_in_subselect called only from Item_in_optimizer this
    method should not be used
  */
  DBUG_ASSERT(0);
650
  DBUG_ASSERT(fixed == 1);
651
  if (exec())
652 653 654 655 656 657 658 659
  {
    reset();
    null_value= 1;
    return 0;
  }
  if (was_null && !value)
  {
    null_value= 1;
unknown's avatar
unknown committed
660
    return 0;
unknown's avatar
unknown committed
661
  }
unknown's avatar
unknown committed
662
  str->set(value, &my_charset_bin);
unknown's avatar
unknown committed
663 664 665
  return str;
}

unknown's avatar
unknown committed
666

667 668
/* Rewrite a single-column IN/ALL/ANY subselect. */

669
Item_subselect::trans_res
unknown's avatar
unknown committed
670
Item_in_subselect::single_value_transformer(JOIN *join,
unknown's avatar
unknown committed
671
					    Comp_creator *func)
unknown's avatar
unknown committed
672 673
{
  DBUG_ENTER("Item_in_subselect::single_value_transformer");
674

675
  SELECT_LEX *select_lex= join->select_lex;
unknown's avatar
unknown committed
676

677 678 679 680
  /*
    Check that the right part of the subselect contains no more than one
    column. E.g. in SELECT 1 IN (SELECT * ..) the right part is (SELECT * ...)
  */
681 682 683
  if (select_lex->item_list.elements > 1)
  {
    my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
684
    DBUG_RETURN(RES_ERROR);
685 686
  }

687 688 689 690 691 692 693 694 695 696 697
  /*
    If this is an ALL/ANY single-value subselect, try to rewrite it with
    a MIN/MAX subselect. We can do that if a possible NULL result of the
    subselect can be ignored.
    E.g. SELECT * FROM t1 WHERE b > ANY (SELECT a FROM t2) can be rewritten
    with SELECT * FROM t1 WHERE b > (SELECT MAX(a) FROM t2).
    We can't check that this optimization is safe if it's not a top-level
    item of the WHERE clause (e.g. because the WHERE clause can contain IS
    NULL/IS NOT NULL functions). If so, we rewrite ALL/ANY with NOT EXISTS
    later in this method.
  */
698
  if ((abort_on_null || (upper_item && upper_item->top_level())) &&
699
      !select_lex->master_unit()->uncacheable && !func->eqne_op())
700
  {
701 702 703
    if (substitution)
    {
      // It is second (third, ...) SELECT of UNION => All is done
704
      DBUG_RETURN(RES_OK);
705 706
    }

707 708
    Item *subs;
    if (!select_lex->group_list.elements &&
unknown's avatar
unknown committed
709
        !select_lex->having &&
710 711
	!select_lex->with_sum_func &&
	!(select_lex->next_select()))
712
    {
713
      Item_sum_hybrid *item;
unknown's avatar
unknown committed
714
      if (func->l_op())
715 716 717 718 719 720 721 722 723 724 725 726 727 728 729
      {
	/*
	  (ALL && (> || =>)) || (ANY && (< || =<))
	  for ALL condition is inverted
	*/
	item= new Item_sum_max(*select_lex->ref_pointer_array);
      }
      else
      {
	/*
	  (ALL && (< || =<)) || (ANY && (> || =>))
	  for ALL condition is inverted
	*/
	item= new Item_sum_min(*select_lex->ref_pointer_array);
      }
730 731
      if (upper_item)
        upper_item->set_sum_test(item);
732
      *select_lex->ref_pointer_array= item;
733 734 735 736 737
      {
	List_iterator<Item> it(select_lex->item_list);
	it++;
	it.replace(item);
      }
unknown's avatar
merge  
unknown committed
738

739 740 741 742 743
      /*
	Item_sum_(max|min) can't substitute other item => we can use 0 as
	reference
      */
      if (item->fix_fields(thd, join->tables_list, 0))
744
	DBUG_RETURN(RES_ERROR);
745 746
      /* we added aggregate function => we have to change statistic */
      count_field_types(&join->tmp_table_param, join->all_fields, 0);
unknown's avatar
unknown committed
747

unknown's avatar
unknown committed
748
      subs= new Item_singlerow_subselect(select_lex);
749 750 751
    }
    else
    {
752
      Item_maxmin_subselect *item;
753 754 755
      // remove LIMIT placed  by ALL/ANY subquery
      select_lex->master_unit()->global_parameters->select_limit=
	HA_POS_ERROR;
756 757 758
      subs= item= new Item_maxmin_subselect(this, select_lex, func->l_op());
      if (upper_item)
        upper_item->set_sub_test(item);
759
    }
760
    /* fix fields is already called for  left expression */
unknown's avatar
unknown committed
761
    substitution= func->create(left_expr, subs);
762
    DBUG_RETURN(RES_OK);
763 764
  }

765
  if (!substitution)
unknown's avatar
unknown committed
766
  {
767 768
    //first call for this unit
    SELECT_LEX_UNIT *unit= select_lex->master_unit();
769
    substitution= optimizer;
770

unknown's avatar
unknown committed
771
    SELECT_LEX *current= thd->lex->current_select, *up;
unknown's avatar
unknown committed
772

unknown's avatar
unknown committed
773
    thd->lex->current_select= up= current->return_after_parsing();
774
    //optimizer never use Item **ref => we can pass 0 as parameter
unknown's avatar
unknown committed
775
    if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0))
776
    {
unknown's avatar
unknown committed
777
      thd->lex->current_select= current;
778
      DBUG_RETURN(RES_ERROR);
779
    }
unknown's avatar
unknown committed
780
    thd->lex->current_select= current;
781

782 783 784 785
    /*
      As far as  Item_ref_in_optimizer do not substitude itself on fix_fields
      we can use same item for all selects.
    */
786 787 788
    expr= new Item_direct_ref((Item**)optimizer->get_cache(),
			      (char *)"<no matter>",
			      (char *)in_left_expr_name);
789

790
    unit->uncacheable|= UNCACHEABLE_DEPENDENT;
791
  }
792

793
  select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
794
  Item *item;
unknown's avatar
unknown committed
795 796

  item= (Item*) select_lex->item_list.head();
797 798 799 800 801 802 803
  /*
    Add the left part of a subselect to a WHERE or HAVING clause of
    the right part, e.g. SELECT 1 IN (SELECT a FROM t1)  =>
    SELECT Item_in_optimizer(1, SELECT a FROM t1 WHERE a=1)
    HAVING is used only if the right part contains a SUM function, a GROUP
    BY or a HAVING clause.
  */
804 805 806
  if (join->having || select_lex->with_sum_func ||
      select_lex->group_list.elements)
  {
unknown's avatar
unknown committed
807 808 809 810 811
    item= func->create(expr,
		       new Item_ref_null_helper(this,
						select_lex->ref_pointer_array,
						(char *)"<ref>",
						this->full_name()));
812 813 814 815 816
    /*
      AND and comparison functions can't be changed during fix_fields()
      we can assign select_lex->having here, and pass 0 as last
      argument (reference) to fix_fields()
    */
unknown's avatar
unknown committed
817
    select_lex->having= join->having= and_items(join->having, item);
818
    select_lex->having_fix_field= 1;
819
    if (join->having->fix_fields(thd, join->tables_list, 0))
820
    {
821
      select_lex->having_fix_field= 0;
822
      DBUG_RETURN(RES_ERROR);
823
    }
824 825 826 827 828 829 830 831 832
    select_lex->having_fix_field= 0;
  }
  else
  {
    select_lex->item_list.empty();
    select_lex->item_list.push_back(new Item_int("Not_used",
						 (longlong) 1, 21));
    select_lex->ref_pointer_array[0]= select_lex->item_list.head();
    if (select_lex->table_list.elements)
833
    {
834
      Item *having= item, *orig_item= item;
unknown's avatar
unknown committed
835
      item= func->create(expr, item);
836
      if (!abort_on_null && orig_item->maybe_null)
unknown's avatar
unknown committed
837
      {
838
	having= new Item_is_not_null_test(this, having);
839 840 841 842 843
	/*
	  Item_is_not_null_test can't be changed during fix_fields()
	  we can assign select_lex->having here, and pass 0 as last
	  argument (reference) to fix_fields()
	*/
unknown's avatar
unknown committed
844 845 846 847
	select_lex->having=
	  join->having= (join->having ?
			 new Item_cond_and(having, join->having) :
			 having);
848
	select_lex->having_fix_field= 1;
849
	if (join->having->fix_fields(thd, join->tables_list, 0))
unknown's avatar
unknown committed
850
	{
851
	  select_lex->having_fix_field= 0;
852
	  DBUG_RETURN(RES_ERROR);
unknown's avatar
unknown committed
853
	}
854 855
	select_lex->having_fix_field= 0;
	item= new Item_cond_or(item,
856
			       new Item_func_isnull(orig_item));
857
      }
858
      item->name= (char *)in_additional_cond;
859 860 861 862 863
      /*
	AND can't be changed during fix_fields()
	we can assign select_lex->having here, and pass 0 as last
	argument (reference) to fix_fields()
      */
unknown's avatar
unknown committed
864
      select_lex->where= join->conds= and_items(join->conds, item);
865
      if (join->conds->fix_fields(thd, join->tables_list, 0))
866
	DBUG_RETURN(RES_ERROR);
867 868 869 870 871
    }
    else
    {
      if (select_lex->master_unit()->first_select()->next_select())
      {
872 873 874 875 876
	/*
	  comparison functions can't be changed during fix_fields()
	  we can assign select_lex->having here, and pass 0 as last
	  argument (reference) to fix_fields()
	*/
877 878 879 880
	select_lex->having=
	  join->having=
	  func->create(expr,
		       new Item_null_helper(this, item,
unknown's avatar
unknown committed
881 882
					    (char *)"<no matter>",
					    (char *)"<result>"));
883
	select_lex->having_fix_field= 1;
unknown's avatar
unknown committed
884
	if (join->having->fix_fields(thd, join->tables_list,
885
				     0))
886 887
	{
	  select_lex->having_fix_field= 0;
888
	  DBUG_RETURN(RES_ERROR);
unknown's avatar
unknown committed
889
	}
890 891 892 893 894
	select_lex->having_fix_field= 0;
      }
      else
      {
	// it is single select without tables => possible optimization
unknown's avatar
unknown committed
895
	item= func->create(left_expr, item);
896
        // fix_field of item will be done in time of substituting
897 898
	substitution= item;
	have_to_be_excluded= 1;
unknown's avatar
unknown committed
899
	if (thd->lex->describe)
unknown's avatar
unknown committed
900
	{
901 902
	  char warn_buff[MYSQL_ERRMSG_SIZE];
	  sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
unknown's avatar
unknown committed
903
	  push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
904
		       ER_SELECT_REDUCED, warn_buff);
unknown's avatar
unknown committed
905
	}
906
	DBUG_RETURN(RES_REDUCE);
unknown's avatar
unknown committed
907
      }
908
    }
unknown's avatar
unknown committed
909
  }
unknown's avatar
unknown committed
910

911
  DBUG_RETURN(RES_OK);
unknown's avatar
unknown committed
912
}
unknown's avatar
unknown committed
913

914

915
Item_subselect::trans_res
unknown's avatar
unknown committed
916
Item_in_subselect::row_value_transformer(JOIN *join)
unknown's avatar
unknown committed
917 918
{
  DBUG_ENTER("Item_in_subselect::row_value_transformer");
unknown's avatar
unknown committed
919

unknown's avatar
unknown committed
920
  Item *item= 0;
unknown's avatar
unknown committed
921
  SELECT_LEX *select_lex= join->select_lex;
unknown's avatar
unknown committed
922

923 924 925
  if (select_lex->item_list.elements != left_expr->cols())
  {
    my_error(ER_OPERAND_COLUMNS, MYF(0), left_expr->cols());
926
    DBUG_RETURN(RES_ERROR);
927 928
  }

929
  if (!substitution)
unknown's avatar
unknown committed
930
  {
931 932
    //first call for this unit
    SELECT_LEX_UNIT *unit= select_lex->master_unit();
933
    substitution= optimizer;
934

unknown's avatar
unknown committed
935 936
    SELECT_LEX *current= thd->lex->current_select, *up;
    thd->lex->current_select= up= current->return_after_parsing();
937
    //optimizer never use Item **ref => we can pass 0 as parameter
unknown's avatar
unknown committed
938
    if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0))
939
    {
unknown's avatar
unknown committed
940
      thd->lex->current_select= current;
941
      DBUG_RETURN(RES_ERROR);
942
    }
943 944 945 946

    // we will refer to apper level cache array => we have to save it in PS
    optimizer->keep_top_level_cache();

unknown's avatar
unknown committed
947
    thd->lex->current_select= current;
948
    unit->uncacheable|= UNCACHEABLE_DEPENDENT;
949 950
  }

951
  select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
unknown's avatar
unknown committed
952 953 954 955 956
  {
    uint n= left_expr->cols();
    List_iterator_fast<Item> li(select_lex->item_list);
    for (uint i= 0; i < n; i++)
    {
957 958 959
      DBUG_ASSERT(left_expr->fixed && select_lex->ref_pointer_array[i]->fixed);
      if (select_lex->ref_pointer_array[i]->
          check_cols(left_expr->el(i)->cols()))
960
        DBUG_RETURN(RES_ERROR);
961
      Item *func= new Item_ref_null_helper(this,
unknown's avatar
unknown committed
962 963 964 965
					   select_lex->ref_pointer_array+i,
					   (char *) "<no matter>",
					   (char *) "<list ref>");
      func=
966 967 968 969
	eq_creator.create(new Item_direct_ref((*optimizer->get_cache())->
					      addr(i),
					      (char *)"<no matter>",
					      (char *)in_left_expr_name),
unknown's avatar
unknown committed
970 971 972
			  func);
      item= and_items(item, func);
    }
973 974 975 976 977
  }
  if (join->having || select_lex->with_sum_func ||
      select_lex->group_list.first ||
      !select_lex->table_list.elements)
  {
978 979 980 981 982
    /*
      AND can't be changed during fix_fields()
      we can assign select_lex->having here, and pass 0 as last
      argument (reference) to fix_fields()
    */
unknown's avatar
unknown committed
983
    select_lex->having= join->having= and_items(join->having, item);
984
    select_lex->having_fix_field= 1;
985
    if (join->having->fix_fields(thd, join->tables_list, 0))
unknown's avatar
unknown committed
986
    {
987
      select_lex->having_fix_field= 0;
988
      DBUG_RETURN(RES_ERROR);
unknown's avatar
unknown committed
989
    }
990
    select_lex->having_fix_field= 0;
unknown's avatar
unknown committed
991
  }
992 993
  else
  {
994 995 996 997 998
    /*
      AND can't be changed during fix_fields()
      we can assign select_lex->having here, and pass 0 as last
      argument (reference) to fix_fields()
    */
unknown's avatar
unknown committed
999
    select_lex->where= join->conds= and_items(join->conds, item);
1000
    if (join->conds->fix_fields(thd, join->tables_list, 0))
1001
      DBUG_RETURN(RES_ERROR);
1002
  }
1003
  DBUG_RETURN(RES_OK);
unknown's avatar
unknown committed
1004 1005
}

1006

1007
Item_subselect::trans_res
unknown's avatar
unknown committed
1008
Item_in_subselect::select_transformer(JOIN *join)
unknown's avatar
unknown committed
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 1037 1038 1039 1040 1041 1042 1043 1044
  return select_in_like_transformer(join, &eq_creator);
}


/*
  Prepare IN/ALL/ANY/SOME subquery transformation and call appropriate
  transformation function

  SYNOPSIS
    Item_in_subselect::select_in_like_transformer()
    join    JOIN object of transforming subquery
    func    creator of condition function of subquery

  DESCRIPTION
    To decide which transformation procedure (scalar or row) applicable here
    we have to call fix_fields() for left expression to be able to call
    cols() method on it. Also this method make arena management for
    underlying transformation methods.

  RETURN
    RES_OK      OK
    RES_REDUCE  OK, and current subquery was reduced during transformation
    RES_ERROR   Error
*/

Item_subselect::trans_res
Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
{
  Item_arena *arena, backup;
  SELECT_LEX *current= thd->lex->current_select, *up;
  const char *save_where= thd->where;
  Item_subselect::trans_res res= RES_ERROR;
  bool result;

  DBUG_ENTER("Item_in_subselect::select_in_like_transformer");
unknown's avatar
unknown committed
1045

1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078
  if (changed)
  {
    DBUG_RETURN(RES_OK);
  }

  thd->where= "IN/ALL/ANY subquery";

  /*
    In some optimisation cases we will not need this Item_in_optimizer
    object, but we can't know it here, but here we need address correct
    reference on left expresion.
  */
  if (!optimizer)
  {
    arena= thd->change_arena_if_needed(&backup);
    result= (!(optimizer= new Item_in_optimizer(left_expr, this)));
    if (arena)
      thd->restore_backup_item_arena(arena, &backup);
    if (result)
      goto err;
  }

  thd->lex->current_select= up= current->return_after_parsing();
  result= (!left_expr->fixed &&
           left_expr->fix_fields(thd, up->get_table_list(),
                                 optimizer->arguments()));
  /* fix_fields can change reference to left_expr, we need reassign it */
  left_expr= optimizer->arguments()[0];

  thd->lex->current_select= current;
  if (result)
    goto err;

unknown's avatar
unknown committed
1079
  transformed= 1;
1080 1081 1082 1083 1084 1085 1086 1087
  arena= thd->change_arena_if_needed(&backup);
  /*
    Both transformers call fix_fields() only for Items created inside them,
    and all that items do not make permanent changes in current item arena
    which allow to us call them with changed arena (if we do not know nature
    of Item, we have to call fix_fields() for it only with original arena to
    avoid memory leack)
  */
unknown's avatar
unknown committed
1088
  if (left_expr->cols() == 1)
1089 1090 1091 1092 1093 1094
    res= single_value_transformer(join, func);
  else
  {
    /* we do not support row operation for ALL/ANY/SOME */
    if (func != &eq_creator)
    {
unknown's avatar
unknown committed
1095 1096
      if (arena)
        thd->restore_backup_item_arena(arena, &backup);
1097 1098 1099 1100 1101 1102 1103 1104 1105 1106
      my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
      DBUG_RETURN(RES_ERROR);
    }
    res= row_value_transformer(join);
  }
  if (arena)
    thd->restore_backup_item_arena(arena, &backup);
err:
  thd->where= save_where;
  DBUG_RETURN(res);
unknown's avatar
unknown committed
1107 1108
}

1109

unknown's avatar
unknown committed
1110 1111 1112
void Item_in_subselect::print(String *str)
{
  if (transformed)
1113
    str->append("<exists>", 8);
unknown's avatar
unknown committed
1114 1115 1116
  else
  {
    left_expr->print(str);
1117
    str->append(" in ", 4);
unknown's avatar
unknown committed
1118 1119 1120 1121 1122
  }
  Item_subselect::print(str);
}


1123
Item_subselect::trans_res
unknown's avatar
unknown committed
1124
Item_allany_subselect::select_transformer(JOIN *join)
unknown's avatar
unknown committed
1125
{
unknown's avatar
unknown committed
1126
  transformed= 1;
1127 1128
  if (upper_item)
    upper_item->show= 1;
1129
  return select_in_like_transformer(join, func);
unknown's avatar
unknown committed
1130 1131
}

unknown's avatar
unknown committed
1132 1133 1134 1135

void Item_allany_subselect::print(String *str)
{
  if (transformed)
1136
    str->append("<exists>", 8);
unknown's avatar
unknown committed
1137 1138 1139 1140
  else
  {
    left_expr->print(str);
    str->append(' ');
unknown's avatar
unknown committed
1141 1142
    str->append(func->symbol(all));
    str->append(all ? " all " : " any ", 5);
unknown's avatar
unknown committed
1143 1144 1145 1146 1147
  }
  Item_subselect::print(str);
}


1148
subselect_single_select_engine::
1149 1150 1151 1152 1153
subselect_single_select_engine(st_select_lex *select,
			       select_subselect *result,
			       Item_subselect *item)
  :subselect_engine(item, result),
   prepared(0), optimized(0), executed(0), join(0)
unknown's avatar
unknown committed
1154 1155 1156 1157 1158 1159 1160
{
  select_lex= select;
  SELECT_LEX_UNIT *unit= select_lex->master_unit();
  unit->offset_limit_cnt= unit->global_parameters->offset_limit;
  unit->select_limit_cnt= unit->global_parameters->select_limit+
    unit->global_parameters ->offset_limit;
  if (unit->select_limit_cnt < unit->global_parameters->select_limit)
1161
    unit->select_limit_cnt= HA_POS_ERROR;	// no limit
unknown's avatar
unknown committed
1162 1163
  if (unit->select_limit_cnt == HA_POS_ERROR)
    select_lex->options&= ~OPTION_FOUND_ROWS;
unknown's avatar
unknown committed
1164
  unit->item= item;
unknown's avatar
unknown committed
1165 1166 1167
  this->select_lex= select_lex;
}

unknown's avatar
unknown committed
1168

unknown's avatar
unknown committed
1169 1170
void subselect_single_select_engine::cleanup()
{
unknown's avatar
unknown committed
1171 1172
  DBUG_ENTER("subselect_single_select_engine::cleanup");
  prepared= optimized= executed= 0;
1173
  join= 0;
1174
  result->cleanup();
unknown's avatar
unknown committed
1175 1176 1177 1178 1179 1180 1181 1182
  DBUG_VOID_RETURN;
}


void subselect_union_engine::cleanup()
{
  DBUG_ENTER("subselect_union_engine::cleanup");
  unit->reinit_exec_mechanism();
1183
  result->cleanup();
unknown's avatar
unknown committed
1184
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
1185
}
1186

unknown's avatar
unknown committed
1187 1188 1189 1190

void subselect_uniquesubquery_engine::cleanup()
{
  DBUG_ENTER("subselect_uniquesubquery_engine::cleanup");
1191 1192 1193 1194
  /*
    subselect_uniquesubquery_engine have not 'result' assigbed, so we do not
    cleanup() it
  */
unknown's avatar
unknown committed
1195 1196 1197 1198
  DBUG_VOID_RETURN;
}


1199
subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
1200 1201 1202
					       select_subselect *result_arg,
					       Item_subselect *item_arg)
  :subselect_engine(item_arg, result_arg)
unknown's avatar
unknown committed
1203 1204
{
  unit= u;
1205
  if (!result_arg)				//out of memory
1206
    current_thd->fatal_error();
1207
  unit->item= item_arg;
unknown's avatar
unknown committed
1208 1209
}

1210

unknown's avatar
unknown committed
1211 1212
int subselect_single_select_engine::prepare()
{
unknown's avatar
unknown committed
1213 1214
  if (prepared)
    return 0;
1215 1216
  join= new JOIN(thd, select_lex->item_list,
		 select_lex->options | SELECT_NO_UNLOCK, result);
1217 1218
  if (!join || !result)
  {
1219
    thd->fatal_error();				//out of memory
1220 1221
    return 1;
  }
unknown's avatar
unknown committed
1222
  prepared= 1;
1223 1224
  SELECT_LEX *save_select= thd->lex->current_select;
  thd->lex->current_select= select_lex;
unknown's avatar
unknown committed
1225 1226 1227
  if (join->prepare(&select_lex->ref_pointer_array,
		    (TABLE_LIST*) select_lex->table_list.first,
		    select_lex->with_wild,
unknown's avatar
unknown committed
1228
		    select_lex->where,
unknown's avatar
unknown committed
1229 1230
		    select_lex->order_list.elements +
		    select_lex->group_list.elements,
unknown's avatar
unknown committed
1231 1232 1233
		    (ORDER*) select_lex->order_list.first,
		    (ORDER*) select_lex->group_list.first,
		    select_lex->having,
1234
		    (ORDER*) 0, select_lex,
1235
		    select_lex->master_unit()))
unknown's avatar
unknown committed
1236
    return 1;
1237
  thd->lex->current_select= save_select;
unknown's avatar
unknown committed
1238 1239 1240 1241 1242
  return 0;
}

int subselect_union_engine::prepare()
{
1243
  return unit->prepare(thd, result, SELECT_NO_UNLOCK, "");
unknown's avatar
unknown committed
1244 1245
}

1246
int subselect_uniquesubquery_engine::prepare()
1247 1248 1249 1250 1251 1252
{
  //this never should be called
  DBUG_ASSERT(0);
  return 1;
}

1253
static Item_result set_row(List<Item> &item_list, Item *item,
unknown's avatar
unknown committed
1254
			   Item_cache **row, bool *maybe_null)
1255
{
1256 1257
  Item_result res_type= STRING_RESULT;
  Item *sel_item;
1258
  List_iterator_fast<Item> li(item_list);
1259 1260 1261 1262 1263
  for (uint i= 0; (sel_item= li++); i++)
  {
    item->max_length= sel_item->max_length;
    res_type= sel_item->result_type();
    item->decimals= sel_item->decimals;
unknown's avatar
unknown committed
1264
    *maybe_null= sel_item->maybe_null;
1265 1266 1267
    if (!(row[i]= Item_cache::get_cache(res_type)))
      return STRING_RESULT; // we should return something
    row[i]->setup(sel_item);
1268
  }
1269
  if (item_list.elements > 1)
1270 1271
    res_type= ROW_RESULT;
  return res_type;
1272 1273
}

1274
void subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
1275
{
1276
  DBUG_ASSERT(row || select_lex->item_list.elements==1);
1277
  res_type= set_row(select_lex->item_list, item, row, &maybe_null);
1278
  item->collation.set(row[0]->collation);
unknown's avatar
unknown committed
1279 1280
  if (cols() != 1)
    maybe_null= 0;
1281 1282 1283 1284 1285 1286 1287
}

void subselect_union_engine::fix_length_and_dec(Item_cache **row)
{
  DBUG_ASSERT(row || unit->first_select()->item_list.elements==1);

  if (unit->first_select()->item_list.elements == 1)
1288
  {
1289
    res_type= set_row(unit->types, item, row, &maybe_null);
1290 1291
    item->collation.set(row[0]->collation);
  }
1292 1293
  else
  {
unknown's avatar
unknown committed
1294
    bool fake= 0;
1295
    res_type= set_row(unit->types, item, row, &fake);
1296 1297
  }
}
unknown's avatar
unknown committed
1298

1299
void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row)
1300 1301 1302 1303 1304
{
  //this never should be called
  DBUG_ASSERT(0);
}

unknown's avatar
unknown committed
1305 1306 1307
int subselect_single_select_engine::exec()
{
  DBUG_ENTER("subselect_single_select_engine::exec");
1308
  char const *save_where= join->thd->where;
1309 1310
  SELECT_LEX *save_select= join->thd->lex->current_select;
  join->thd->lex->current_select= select_lex;
unknown's avatar
unknown committed
1311 1312 1313 1314 1315
  if (!optimized)
  {
    optimized=1;
    if (join->optimize())
    {
1316
      join->thd->where= save_where;
unknown's avatar
unknown committed
1317
      executed= 1;
1318
      join->thd->lex->current_select= save_select;
unknown's avatar
unknown committed
1319
      DBUG_RETURN(join->error ? join->error : 1);
unknown's avatar
unknown committed
1320
    }
1321 1322 1323 1324
    if (item->engine_changed)
    {
      DBUG_RETURN(1);
    }
unknown's avatar
unknown committed
1325
  }
1326
  if (select_lex->uncacheable && executed)
unknown's avatar
unknown committed
1327 1328
  {
    if (join->reinit())
1329 1330
    {
      join->thd->where= save_where;
1331
      join->thd->lex->current_select= save_select;
unknown's avatar
unknown committed
1332
      DBUG_RETURN(1);
1333
    }
1334
    item->reset();
unknown's avatar
unknown committed
1335 1336 1337 1338
    item->assigned((executed= 0));
  }
  if (!executed)
  {
1339
    item->reset_value_registration();
unknown's avatar
unknown committed
1340 1341
    join->exec();
    executed= 1;
1342
    join->thd->where= save_where;
1343
    join->thd->lex->current_select= save_select;
1344
    DBUG_RETURN(join->error||thd->is_fatal_error);
unknown's avatar
unknown committed
1345
  }
1346
  join->thd->where= save_where;
1347
  join->thd->lex->current_select= save_select;
unknown's avatar
unknown committed
1348 1349 1350 1351 1352
  DBUG_RETURN(0);
}

int subselect_union_engine::exec()
{
1353 1354 1355 1356
  char const *save_where= unit->thd->where;
  int res= unit->exec();
  unit->thd->where= save_where;
  return res;
unknown's avatar
unknown committed
1357 1358
}

1359

1360
int subselect_uniquesubquery_engine::exec()
1361
{
1362
  DBUG_ENTER("subselect_uniquesubquery_engine::exec");
1363 1364
  int error;
  TABLE *table= tab->table;
1365
  for (store_key **copy=tab->ref.key_copy ; *copy ; copy++)
1366
  {
1367 1368 1369 1370 1371
    if (tab->ref.key_err= (*copy)->copy())
    {
      table->status= STATUS_NOT_FOUND;
      DBUG_RETURN(1);
    }
1372
  }
1373 1374 1375 1376 1377 1378

  if (!table->file->inited)
    table->file->ha_index_init(tab->ref.key);
  error= table->file->index_read(table->record[0],
                                 tab->ref.key_buff,
                                 tab->ref.key_length,HA_READ_KEY_EXACT);
1379 1380
  if (error &&
      error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
1381
    error= report_error(table, error);
1382 1383
  else
  {
1384 1385 1386 1387 1388
    error= 0;
    table->null_row= 0;
    ((Item_in_subselect *) item)->value= (!table->status &&
                                          (!cond || cond->val_int()) ? 1 :
                                          0);
1389
  }
1390

1391
  DBUG_RETURN(error != 0);
1392 1393
}

1394 1395

subselect_uniquesubquery_engine::~subselect_uniquesubquery_engine()
1396
{
1397
  /* Tell handler we don't need the index anymore */
unknown's avatar
unknown committed
1398
  tab->table->file->ha_index_end();
1399 1400
}

1401

1402
int subselect_indexsubquery_engine::exec()
1403
{
1404
  DBUG_ENTER("subselect_indexsubselect_engine::exec");
1405
  int error;
1406
  bool null_finding= 0;
1407
  TABLE *table= tab->table;
1408

1409
  ((Item_in_subselect *) item)->value= 0;
1410

1411 1412
  if (check_null)
  {
1413
    /* We need to check for NULL if there wasn't a matching value */
1414
    *tab->ref.null_ref_key= 0;			// Search first for not null
1415 1416 1417
    ((Item_in_subselect *) item)->was_null= 0;
  }

1418
  for (store_key **copy=tab->ref.key_copy ; *copy ; copy++)
1419
  {
1420 1421 1422 1423 1424
    if (tab->ref.key_err= (*copy)->copy())
    {
      table->status= STATUS_NOT_FOUND;
      DBUG_RETURN(1);
    }
1425
  }
1426 1427 1428 1429 1430 1431

  if (!table->file->inited)
    table->file->ha_index_init(tab->ref.key);
  error= table->file->index_read(table->record[0],
                                 tab->ref.key_buff,
                                 tab->ref.key_length,HA_READ_KEY_EXACT);
1432 1433
  if (error &&
      error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
1434
    error= report_error(table, error);
1435 1436
  else
  {
1437
    for (;;)
1438
    {
1439 1440 1441
      error= 0;
      table->null_row= 0;
      if (!table->status)
1442
      {
1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468
        if (!cond || cond->val_int())
        {
          if (null_finding)
            ((Item_in_subselect *) item)->was_null= 1;
          else
            ((Item_in_subselect *) item)->value= 1;
          break;
        }
        error= table->file->index_next_same(table->record[0],
                                            tab->ref.key_buff,
                                            tab->ref.key_length);
        if (error && error != HA_ERR_END_OF_FILE)
        {
          error= report_error(table, error);
          break;
        }
      }
      else
      {
        if (!check_null || null_finding)
          break;			/* We don't need to check nulls */
        *tab->ref.null_ref_key= 1;
        null_finding= 1;
        /* Check if there exists a row with a null value in the index */
        if ((error= (safe_index_read(tab) == 1)))
          break;
1469
      }
1470 1471
    }
  }
1472
  DBUG_RETURN(error != 0);
1473 1474
}

1475

unknown's avatar
unknown committed
1476 1477
uint subselect_single_select_engine::cols()
{
1478 1479
  DBUG_ASSERT(select_lex->join); // should be called after fix_fields()
  return select_lex->join->fields_list.elements;
unknown's avatar
unknown committed
1480 1481
}

unknown's avatar
unknown committed
1482

unknown's avatar
unknown committed
1483 1484
uint subselect_union_engine::cols()
{
1485 1486
  DBUG_ASSERT(unit->is_prepared());  // should be called after fix_fields()
  return unit->types.elements;
unknown's avatar
unknown committed
1487 1488
}

unknown's avatar
unknown committed
1489

1490
uint8 subselect_single_select_engine::uncacheable()
1491 1492 1493 1494
{
  return select_lex->uncacheable;
}

unknown's avatar
unknown committed
1495

1496
uint8 subselect_union_engine::uncacheable()
1497 1498 1499 1500
{
  return unit->uncacheable;
}

unknown's avatar
unknown committed
1501

unknown's avatar
unknown committed
1502 1503 1504 1505 1506 1507 1508 1509 1510
void subselect_single_select_engine::exclude()
{
  select_lex->master_unit()->exclude_level();
}

void subselect_union_engine::exclude()
{
  unit->exclude_level();
}
1511

unknown's avatar
unknown committed
1512

1513
void subselect_uniquesubquery_engine::exclude()
1514 1515 1516 1517
{
  //this never should be called
  DBUG_ASSERT(0);
}
1518 1519 1520 1521 1522


table_map subselect_engine::calc_const_tables(TABLE_LIST *table)
{
  table_map map= 0;
1523
  for (; table; table= table->next)
1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538
  {
    TABLE *tbl= table->table;
    if (tbl && tbl->const_table)
      map|= tbl->map;
  }
  return map;
}


table_map subselect_single_select_engine::upper_select_const_tables()
{
  return calc_const_tables((TABLE_LIST *) select_lex->outer_select()->
			   table_list.first);
}

unknown's avatar
merge  
unknown committed
1539

1540 1541 1542 1543 1544
table_map subselect_union_engine::upper_select_const_tables()
{
  return calc_const_tables((TABLE_LIST *) unit->outer_select()->
			   table_list.first);
}
unknown's avatar
merge  
unknown committed
1545 1546


unknown's avatar
unknown committed
1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560
void subselect_single_select_engine::print(String *str)
{
  select_lex->print(thd, str);
}


void subselect_union_engine::print(String *str)
{
  unit->print(str);
}


void subselect_uniquesubquery_engine::print(String *str)
{
1561
  str->append("<primary_index_lookup>(", 23);
unknown's avatar
unknown committed
1562
  tab->ref.items[0]->print(str);
1563
  str->append(" in ", 4);
unknown's avatar
unknown committed
1564
  str->append(tab->table->real_name);
unknown's avatar
unknown committed
1565
  KEY *key_info= tab->table->key_info+ tab->ref.key;
1566
  str->append(" on ", 4);
unknown's avatar
unknown committed
1567
  str->append(key_info->name);
unknown's avatar
unknown committed
1568 1569
  if (cond)
  {
1570
    str->append(" where ", 7);
unknown's avatar
unknown committed
1571 1572 1573 1574 1575 1576 1577 1578
    cond->print(str);
  }
  str->append(')');
}


void subselect_indexsubquery_engine::print(String *str)
{
1579
  str->append("<index_lookup>(", 15);
unknown's avatar
unknown committed
1580
  tab->ref.items[0]->print(str);
1581
  str->append(" in ", 4);
unknown's avatar
unknown committed
1582
  str->append(tab->table->real_name);
unknown's avatar
unknown committed
1583
  KEY *key_info= tab->table->key_info+ tab->ref.key;
1584
  str->append(" on ", 4);
unknown's avatar
unknown committed
1585
  str->append(key_info->name);
unknown's avatar
unknown committed
1586
  if (check_null)
1587
    str->append(" chicking NULL", 14);
unknown's avatar
unknown committed
1588 1589
    if (cond)
  {
1590
    str->append(" where ", 7);
unknown's avatar
unknown committed
1591 1592 1593 1594
    cond->print(str);
  }
  str->append(')');
}
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 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658

/*
  change select_result object of engine

  SINOPSYS
    subselect_single_select_engine::change_result()
    si		new subselect Item
    res		new select_result object

  RETURN
    0  OK
    -1 error
*/

int subselect_single_select_engine::change_item(Item_subselect *si,
						select_subselect *res)
{
  item= si;
  result= res;
  return select_lex->join->change_result(result);
}


/*
  change select_result object of engine

  SINOPSYS
    subselect_single_select_engine::change_result()
    si		new subselect Item
    res		new select_result object

  RETURN
    0  OK
    -1 error
*/

int subselect_union_engine::change_item(Item_subselect *si,
					select_subselect *res)
{
  item= si;
  int rc= unit->change_result(res, result);
  result= res;
  return rc;
}


/*
  change select_result emulation, never should be called

  SINOPSYS
    subselect_single_select_engine::change_result()
    si		new subselect Item
    res		new select_result object

  RETURN
    -1 error
*/

int subselect_uniquesubquery_engine::change_item(Item_subselect *si,
						 select_subselect *res)
{
  DBUG_ASSERT(0);
  return -1;
}
1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713


/*
  Report about presence of tables in subquery

  SINOPSYS
    subselect_single_select_engine::no_tables()

  RETURN
    TRUE  there are not tables used in subquery
    FALSE there are some tables in subquery
*/
bool subselect_single_select_engine::no_tables()
{
  return(select_lex->table_list.elements == 0);
}


/*
  Report about presence of tables in subquery

  SINOPSYS
    subselect_union_engine::no_tables()

  RETURN
    TRUE  there are not tables used in subquery
    FALSE there are some tables in subquery
*/
bool subselect_union_engine::no_tables()
{
  for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
  {
    if (sl->table_list.elements)
      return FALSE;
  }
  return TRUE;
}


/*
  Report about presence of tables in subquery

  SINOPSYS
    subselect_uniquesubquery_engine::no_tables()

  RETURN
    TRUE  there are not tables used in subquery
    FALSE there are some tables in subquery
*/

bool subselect_uniquesubquery_engine::no_tables()
{
  /* returning value is correct, but this method should never be called */
  return 0;
}