~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/item_subselect.cc

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/**
17
17
  @file
23
23
    - add function from mysql_select that use JOIN* as parameter to JOIN
24
24
    methods (sql_select.h/sql_select.cc)
25
25
*/
26
 
#include "config.h"
27
 
 
28
 
#include <cstdio>
29
 
#include <limits.h>
30
 
 
31
 
#include <drizzled/sql_select.h>
32
 
#include <drizzled/error.h>
33
 
#include <drizzled/item/cache.h>
34
 
#include <drizzled/item/subselect.h>
35
 
#include <drizzled/item/cmpfunc.h>
36
 
#include <drizzled/item/ref_null_helper.h>
37
 
#include <drizzled/cached_item.h>
38
 
#include <drizzled/check_stack_overrun.h>
39
 
#include <drizzled/item/ref_null_helper.h>
40
 
#include <drizzled/item/direct_ref.h>
41
 
#include <drizzled/join.h>
42
 
 
43
 
namespace drizzled
44
 
{
45
 
 
46
 
extern plugin::StorageEngine *myisam_engine;
 
26
 
 
27
#ifdef USE_PRAGMA_IMPLEMENTATION
 
28
#pragma implementation                          // gcc: Class implementation
 
29
#endif
 
30
 
 
31
#include "mysql_priv.h"
 
32
#include "sql_select.h"
47
33
 
48
34
inline Item * and_items(Item* cond, Item *item)
49
35
{
50
36
  return (cond? (new Item_cond_and(cond, item)) : item);
51
37
}
52
38
 
53
 
Item_subselect::Item_subselect() :
54
 
  Item_result_field(),
55
 
  value_assigned(false),
56
 
  session(NULL),
57
 
  substitution(NULL),
58
 
  unit(NULL),
59
 
  engine(NULL),
60
 
  old_engine(NULL),
61
 
  used_tables_cache(0),
62
 
  max_columns(0),
63
 
  parsing_place(NO_MATTER),
64
 
  have_to_be_excluded(false),
65
 
  const_item_cache(true),
66
 
  engine_changed(false),
67
 
  changed(false),
68
 
  is_correlated(false)
 
39
Item_subselect::Item_subselect():
 
40
  Item_result_field(), value_assigned(0), thd(0), substitution(0),
 
41
  engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
 
42
  const_item_cache(1), engine_changed(0), changed(0),
 
43
  is_correlated(FALSE)
69
44
{
70
45
  with_subselect= 1;
71
46
  reset();
77
52
}
78
53
 
79
54
 
80
 
void Item_subselect::init(Select_Lex *select_lex,
 
55
void Item_subselect::init(st_select_lex *select_lex,
81
56
                          select_result_interceptor *result)
82
57
{
83
58
  /*
85
60
    which depends on alterations to the parse tree implemented here.
86
61
  */
87
62
 
 
63
  DBUG_ENTER("Item_subselect::init");
 
64
  DBUG_PRINT("enter", ("select_lex: 0x%lx", (long) select_lex));
88
65
  unit= select_lex->master_unit();
89
66
 
90
67
  if (unit->item)
91
68
  {
92
69
    /*
93
 
      Item can be changed in JOIN::prepare while engine in Join::optimize
 
70
      Item can be changed in JOIN::prepare while engine in JOIN::optimize
94
71
      => we do not copy old_engine here
95
72
    */
96
73
    engine= unit->item->engine;
101
78
  }
102
79
  else
103
80
  {
104
 
    Select_Lex *outer_select= unit->outer_select();
 
81
    SELECT_LEX *outer_select= unit->outer_select();
105
82
    /*
106
83
      do not take into account expression inside aggregate functions because
107
84
      they can access original table fields
115
92
      engine= new subselect_single_select_engine(select_lex, result, this);
116
93
  }
117
94
  {
118
 
    Select_Lex *upper= unit->outer_select();
 
95
    SELECT_LEX *upper= unit->outer_select();
119
96
    if (upper->parsing_place == IN_HAVING)
120
97
      upper->subquery_in_having= 1;
121
98
  }
122
 
  return;
 
99
  DBUG_VOID_RETURN;
123
100
}
124
101
 
125
 
Select_Lex *
 
102
st_select_lex *
126
103
Item_subselect::get_select_lex()
127
104
{
128
105
  return unit->first_select();
130
107
 
131
108
void Item_subselect::cleanup()
132
109
{
 
110
  DBUG_ENTER("Item_subselect::cleanup");
133
111
  Item_result_field::cleanup();
134
112
  if (old_engine)
135
113
  {
142
120
    engine->cleanup();
143
121
  reset();
144
122
  value_assigned= 0;
145
 
  return;
 
123
  DBUG_VOID_RETURN;
146
124
}
147
125
 
148
126
void Item_singlerow_subselect::cleanup()
149
127
{
 
128
  DBUG_ENTER("Item_singlerow_subselect::cleanup");
150
129
  value= 0; row= 0;
151
130
  Item_subselect::cleanup();
152
 
  return;
 
131
  DBUG_VOID_RETURN;
153
132
}
154
133
 
155
134
 
156
135
void Item_in_subselect::cleanup()
157
136
{
 
137
  DBUG_ENTER("Item_in_subselect::cleanup");
158
138
  if (left_expr_cache)
159
139
  {
160
140
    left_expr_cache->delete_elements();
161
141
    delete left_expr_cache;
162
142
    left_expr_cache= NULL;
163
143
  }
164
 
  first_execution= true;
 
144
  first_execution= TRUE;
165
145
  Item_subselect::cleanup();
166
 
  return;
 
146
  DBUG_VOID_RETURN;
167
147
}
168
148
 
169
149
Item_subselect::~Item_subselect()
172
152
}
173
153
 
174
154
Item_subselect::trans_res
175
 
Item_subselect::select_transformer(Join *)
 
155
Item_subselect::select_transformer(JOIN *join)
176
156
{
177
 
  return(RES_OK);
 
157
  DBUG_ENTER("Item_subselect::select_transformer");
 
158
  DBUG_RETURN(RES_OK);
178
159
}
179
160
 
180
161
 
181
 
bool Item_subselect::fix_fields(Session *session_param, Item **ref)
 
162
bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
182
163
{
183
 
  char const *save_where= session_param->where;
 
164
  char const *save_where= thd_param->where;
 
165
  uint8 uncacheable;
184
166
  bool res;
185
167
 
186
 
  assert(fixed == 0);
187
 
  engine->set_session((session= session_param));
 
168
  DBUG_ASSERT(fixed == 0);
 
169
  engine->set_thd((thd= thd_param));
188
170
 
189
 
  if (check_stack_overrun(session, STACK_MIN_SIZE, (unsigned char*)&res))
190
 
    return true;
 
171
  if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res))
 
172
    return TRUE;
191
173
 
192
174
  res= engine->prepare();
193
175
 
208
190
 
209
191
      // did we changed top item of WHERE condition
210
192
      if (unit->outer_select()->where == (*ref))
211
 
      {
212
 
        unit->outer_select()->where= substitution; // correct WHERE for PS
213
 
      }
 
193
        unit->outer_select()->where= substitution; // correct WHERE for PS
214
194
      else if (unit->outer_select()->having == (*ref))
215
 
      {
216
 
        unit->outer_select()->having= substitution; // correct HAVING for PS
217
 
      }
 
195
        unit->outer_select()->having= substitution; // correct HAVING for PS
218
196
 
219
197
      (*ref)= substitution;
220
198
      substitution->name= name;
221
199
      if (have_to_be_excluded)
222
 
      {
223
 
        engine->exclude();
224
 
      }
 
200
        engine->exclude();
225
201
      substitution= 0;
226
 
      session->where= "checking transformed subquery";
227
 
      if (! (*ref)->fixed)
228
 
      {
229
 
        ret= (*ref)->fix_fields(session, ref);
230
 
      }
231
 
      session->where= save_where;
 
202
      thd->where= "checking transformed subquery";
 
203
      if (!(*ref)->fixed)
 
204
        ret= (*ref)->fix_fields(thd, ref);
 
205
      thd->where= save_where;
232
206
      return ret;
233
207
    }
234
208
    // Is it one field subselect?
235
209
    if (engine->cols() > max_columns)
236
210
    {
237
211
      my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
238
 
      return true;
 
212
      return TRUE;
239
213
    }
240
214
    fix_length_and_dec();
241
215
  }
242
216
  else
243
217
    goto err;
244
 
 
245
 
  if (engine->uncacheable())
 
218
  
 
219
  if ((uncacheable= engine->uncacheable()))
246
220
  {
247
221
    const_item_cache= 0;
248
 
    if (engine->uncacheable(UNCACHEABLE_RAND))
249
 
    {
 
222
    if (uncacheable & UNCACHEABLE_RAND)
250
223
      used_tables_cache|= RAND_TABLE_BIT;
251
 
    }
252
224
  }
253
225
  fixed= 1;
254
226
 
255
227
err:
256
 
  session->where= save_where;
 
228
  thd->where= save_where;
257
229
  return res;
258
230
}
259
231
 
260
232
 
261
233
bool Item_subselect::walk(Item_processor processor, bool walk_subquery,
262
 
                          unsigned char *argument)
 
234
                          uchar *argument)
263
235
{
264
236
 
265
237
  if (walk_subquery)
266
238
  {
267
 
    for (Select_Lex *lex= unit->first_select(); lex; lex= lex->next_select())
 
239
    for (SELECT_LEX *lex= unit->first_select(); lex; lex= lex->next_select())
268
240
    {
269
241
      List_iterator<Item> li(lex->item_list);
270
242
      Item *item;
271
 
      Order *order;
 
243
      ORDER *order;
272
244
 
273
245
      if (lex->where && (lex->where)->walk(processor, walk_subquery, argument))
274
246
        return 1;
281
253
        if (item->walk(processor, walk_subquery, argument))
282
254
          return 1;
283
255
      }
284
 
      for (order= (Order*) lex->order_list.first ; order; order= order->next)
 
256
      for (order= (ORDER*) lex->order_list.first ; order; order= order->next)
285
257
      {
286
258
        if ((*order->item)->walk(processor, walk_subquery, argument))
287
259
          return 1;
288
260
      }
289
 
      for (order= (Order*) lex->group_list.first ; order; order= order->next)
 
261
      for (order= (ORDER*) lex->group_list.first ; order; order= order->next)
290
262
      {
291
263
        if ((*order->item)->walk(processor, walk_subquery, argument))
292
264
          return 1;
301
273
{
302
274
  int res;
303
275
 
304
 
  if (session->is_error())
 
276
  if (thd->is_error())
305
277
  /* Do not execute subselect in case of a fatal error */
306
278
    return 1;
307
279
 
322
294
 
323
295
bool Item_in_subselect::exec()
324
296
{
325
 
  assert(exec_method != MATERIALIZATION ||
 
297
  DBUG_ENTER("Item_in_subselect::exec");
 
298
  DBUG_ASSERT(exec_method != MATERIALIZATION ||
326
299
              (exec_method == MATERIALIZATION &&
327
300
               engine->engine_type() == subselect_engine::HASH_SJ_ENGINE));
328
301
  /*
345
318
  {
346
319
    /* Always compute IN for the first row as the cache is not valid for it. */
347
320
    if (!first_execution)
348
 
      return(false);
349
 
    first_execution= false;
 
321
      DBUG_RETURN(FALSE);
 
322
    first_execution= FALSE;
350
323
  }
351
324
 
352
325
  /*
354
327
    we don't call it, the next call to item::val_int() will return whatever
355
328
    result was computed by its previous call.
356
329
  */
357
 
  return(Item_subselect::exec());
 
330
  DBUG_RETURN(Item_subselect::exec());
358
331
}
359
332
 
360
333
 
381
354
  return const_item_cache;
382
355
}
383
356
 
384
 
Item *Item_subselect::get_tmp_table_item(Session *session_arg)
 
357
Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
385
358
{
386
359
  if (!with_sum_func && !const_item())
387
360
    return new Item_field(result_field);
388
 
  return copy_or_same(session_arg);
 
361
  return copy_or_same(thd_arg);
389
362
}
390
363
 
391
364
void Item_subselect::update_used_tables()
392
365
{
393
 
  if (! engine->uncacheable())
 
366
  if (!engine->uncacheable())
394
367
  {
395
368
    // did all used tables become static?
396
369
    if (!(used_tables_cache & ~engine->upper_select_const_tables()))
407
380
}
408
381
 
409
382
 
410
 
Item_singlerow_subselect::Item_singlerow_subselect(Select_Lex *select_lex)
 
383
Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex)
411
384
  :Item_subselect(), value(0)
412
385
{
 
386
  DBUG_ENTER("Item_singlerow_subselect::Item_singlerow_subselect");
413
387
  init(select_lex, new select_singlerow_subselect(this));
414
388
  maybe_null= 1;
415
389
  max_columns= UINT_MAX;
416
 
  return;
 
390
  DBUG_VOID_RETURN;
417
391
}
418
392
 
419
 
Select_Lex *
 
393
st_select_lex *
420
394
Item_singlerow_subselect::invalidate_and_restore_select_lex()
421
395
{
422
 
  Select_Lex *result= get_select_lex();
 
396
  DBUG_ENTER("Item_singlerow_subselect::invalidate_and_restore_select_lex");
 
397
  st_select_lex *result= get_select_lex();
423
398
 
424
 
  assert(result);
 
399
  DBUG_ASSERT(result);
425
400
 
426
401
  /*
427
402
    This code restore the parse tree in it's state before the execution of
428
403
    Item_singlerow_subselect::Item_singlerow_subselect(),
429
 
    and in particular decouples this object from the Select_Lex,
430
 
    so that the Select_Lex can be used with a different flavor
 
404
    and in particular decouples this object from the SELECT_LEX,
 
405
    so that the SELECT_LEX can be used with a different flavor
431
406
    or Item_subselect instead, as part of query rewriting.
432
407
  */
433
408
  unit->item= NULL;
434
409
 
435
 
  return(result);
 
410
  DBUG_RETURN(result);
436
411
}
437
412
 
438
 
Item_maxmin_subselect::Item_maxmin_subselect(Session *session_param,
 
413
Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,
439
414
                                             Item_subselect *parent,
440
 
                                             Select_Lex *select_lex,
 
415
                                             st_select_lex *select_lex,
441
416
                                             bool max_arg)
442
 
  :Item_singlerow_subselect(), was_values(true)
 
417
  :Item_singlerow_subselect(), was_values(TRUE)
443
418
{
 
419
  DBUG_ENTER("Item_maxmin_subselect::Item_maxmin_subselect");
444
420
  max= max_arg;
445
421
  init(select_lex, new select_max_min_finder_subselect(this, max_arg));
446
422
  max_columns= 1;
456
432
 
457
433
  /*
458
434
    this subquery always creates during preparation, so we can assign
459
 
    session here
 
435
    thd here
460
436
  */
461
 
  session= session_param;
 
437
  thd= thd_param;
462
438
 
463
 
  return;
 
439
  DBUG_VOID_RETURN;
464
440
}
465
441
 
466
442
void Item_maxmin_subselect::cleanup()
467
443
{
 
444
  DBUG_ENTER("Item_maxmin_subselect::cleanup");
468
445
  Item_singlerow_subselect::cleanup();
469
446
 
470
447
  /*
471
 
    By default it is true to avoid true reporting by
 
448
    By default it is TRUE to avoid TRUE reporting by
472
449
    Item_func_not_all/Item_func_nop_all if this item was never called.
473
450
 
474
 
    Engine exec() set it to false by reset_value_registration() call.
475
 
    select_max_min_finder_subselect::send_data() set it back to true if some
 
451
    Engine exec() set it to FALSE by reset_value_registration() call.
 
452
    select_max_min_finder_subselect::send_data() set it back to TRUE if some
476
453
    value will be found.
477
454
  */
478
 
  was_values= true;
479
 
  return;
 
455
  was_values= TRUE;
 
456
  DBUG_VOID_RETURN;
480
457
}
481
458
 
482
459
 
506
483
  Make rollback for it, or special name resolving mode in 5.0.
507
484
*/
508
485
Item_subselect::trans_res
509
 
Item_singlerow_subselect::select_transformer(Join *join)
 
486
Item_singlerow_subselect::select_transformer(JOIN *join)
510
487
{
 
488
  DBUG_ENTER("Item_singlerow_subselect::select_transformer");
511
489
  if (changed)
512
 
    return(RES_OK);
513
 
 
514
 
  Select_Lex *select_lex= join->select_lex;
515
 
 
 
490
    DBUG_RETURN(RES_OK);
 
491
 
 
492
  SELECT_LEX *select_lex= join->select_lex;
 
493
 
516
494
  if (!select_lex->master_unit()->is_union() &&
517
495
      !select_lex->table_list.elements &&
518
496
      select_lex->item_list.elements == 1 &&
531
509
  {
532
510
 
533
511
    have_to_be_excluded= 1;
534
 
    if (session->lex->describe)
 
512
    if (thd->lex->describe)
535
513
    {
536
 
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
537
 
      snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
538
 
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
514
      char warn_buff[MYSQL_ERRMSG_SIZE];
 
515
      sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
 
516
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
539
517
                   ER_SELECT_REDUCED, warn_buff);
540
518
    }
541
519
    substitution= select_lex->item_list.head();
544
522
      'upper' select is not really dependent => we remove this dependence
545
523
    */
546
524
    substitution->walk(&Item::remove_dependence_processor, 0,
547
 
                       (unsigned char *) select_lex->outer_select());
548
 
    return(RES_REDUCE);
 
525
                       (uchar *) select_lex->outer_select());
 
526
    DBUG_RETURN(RES_REDUCE);
549
527
  }
550
 
  return(RES_OK);
 
528
  DBUG_RETURN(RES_OK);
551
529
}
552
530
 
553
531
 
554
 
void Item_singlerow_subselect::store(uint32_t i, Item *item)
 
532
void Item_singlerow_subselect::store(uint i, Item *item)
555
533
{
556
534
  row[i]->store(item);
557
535
}
561
539
  return engine->type();
562
540
}
563
541
 
564
 
/*
565
 
 Don't rely on the result type to calculate field type.
 
542
/* 
 
543
 Don't rely on the result type to calculate field type. 
566
544
 Ask the engine instead.
567
545
*/
568
546
enum_field_types Item_singlerow_subselect::field_type() const
578
556
  }
579
557
  else
580
558
  {
581
 
    if (!(row= (Item_cache**) memory::sql_alloc(sizeof(Item_cache*)*max_columns)))
 
559
    if (!(row= (Item_cache**) sql_alloc(sizeof(Item_cache*)*max_columns)))
582
560
      return;
583
561
    engine->fix_length_and_dec(row);
584
562
    value= *row;
593
571
    maybe_null= engine->may_be_null();
594
572
}
595
573
 
596
 
uint32_t Item_singlerow_subselect::cols()
 
574
uint Item_singlerow_subselect::cols()
597
575
{
598
576
  return engine->cols();
599
577
}
600
578
 
601
 
bool Item_singlerow_subselect::check_cols(uint32_t c)
 
579
bool Item_singlerow_subselect::check_cols(uint c)
602
580
{
603
581
  if (c != engine->cols())
604
582
  {
610
588
 
611
589
bool Item_singlerow_subselect::null_inside()
612
590
{
613
 
  for (uint32_t i= 0; i < max_columns ; i++)
 
591
  for (uint i= 0; i < max_columns ; i++)
614
592
  {
615
593
    if (row[i]->null_value)
616
594
      return 1;
625
603
 
626
604
double Item_singlerow_subselect::val_real()
627
605
{
628
 
  assert(fixed == 1);
 
606
  DBUG_ASSERT(fixed == 1);
629
607
  if (!exec() && !value->null_value)
630
608
  {
631
609
    null_value= 0;
638
616
  }
639
617
}
640
618
 
641
 
int64_t Item_singlerow_subselect::val_int()
 
619
longlong Item_singlerow_subselect::val_int()
642
620
{
643
 
  assert(fixed == 1);
 
621
  DBUG_ASSERT(fixed == 1);
644
622
  if (!exec() && !value->null_value)
645
623
  {
646
624
    null_value= 0;
698
676
}
699
677
 
700
678
 
701
 
Item_exists_subselect::Item_exists_subselect(Select_Lex *select_lex):
 
679
Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex):
702
680
  Item_subselect()
703
681
{
 
682
  DBUG_ENTER("Item_exists_subselect::Item_exists_subselect");
704
683
  bool val_bool();
705
684
  init(select_lex, new select_exists_subselect(this));
706
685
  max_columns= UINT_MAX;
707
686
  null_value= 0; //can't be NULL
708
687
  maybe_null= 0; //can't be NULL
709
688
  value= 0;
710
 
  return;
 
689
  DBUG_VOID_RETURN;
711
690
}
712
691
 
713
692
 
718
697
}
719
698
 
720
699
 
721
 
bool Item_in_subselect::test_limit(Select_Lex_Unit *unit_arg)
 
700
bool Item_in_subselect::test_limit(st_select_lex_unit *unit_arg)
722
701
{
723
702
  if (unit_arg->fake_select_lex &&
724
703
      unit_arg->fake_select_lex->test_limit())
725
704
    return(1);
726
705
 
727
 
  Select_Lex *sl= unit_arg->first_select();
 
706
  SELECT_LEX *sl= unit_arg->first_select();
728
707
  for (; sl; sl= sl->next_select())
729
708
  {
730
709
    if (sl->test_limit())
734
713
}
735
714
 
736
715
Item_in_subselect::Item_in_subselect(Item * left_exp,
737
 
                                     Select_Lex *select_lex) :
738
 
  Item_exists_subselect(),
739
 
  left_expr(left_exp),
740
 
  left_expr_cache(NULL),
741
 
  first_execution(true),
742
 
  optimizer(NULL),
743
 
  pushed_cond_guards(NULL),
744
 
  sj_convert_priority(0),
745
 
  expr_join_nest(NULL),
746
 
  exec_method(NOT_TRANSFORMED),
747
 
  upper_item(NULL)
 
716
                                     st_select_lex *select_lex):
 
717
  Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
 
718
  optimizer(0), pushed_cond_guards(NULL), exec_method(NOT_TRANSFORMED),
 
719
  upper_item(0)
748
720
{
 
721
  DBUG_ENTER("Item_in_subselect::Item_in_subselect");
 
722
  left_expr= left_exp;
749
723
  init(select_lex, new select_exists_subselect(this));
750
724
  max_columns= UINT_MAX;
751
725
  maybe_null= 1;
753
727
  reset();
754
728
  //if test_limit will fail then error will be reported to client
755
729
  test_limit(select_lex->master_unit());
756
 
  return;
 
730
  DBUG_VOID_RETURN;
757
731
}
758
732
 
759
733
Item_allany_subselect::Item_allany_subselect(Item * left_exp,
760
734
                                             chooser_compare_func_creator fc,
761
 
                                             Select_Lex *select_lex,
 
735
                                             st_select_lex *select_lex,
762
736
                                             bool all_arg)
763
737
  :Item_in_subselect(), func_creator(fc), all(all_arg)
764
738
{
 
739
  DBUG_ENTER("Item_allany_subselect::Item_allany_subselect");
765
740
  left_expr= left_exp;
766
741
  func= func_creator(all_arg);
767
742
  init(select_lex, new select_exists_subselect(this));
770
745
  reset();
771
746
  //if test_limit will fail then error will be reported to client
772
747
  test_limit(select_lex->master_unit());
773
 
  return;
 
748
  DBUG_VOID_RETURN;
774
749
}
775
750
 
776
751
 
780
755
   max_length= 1;
781
756
   max_columns= engine->cols();
782
757
  /* We need only 1 row to determine existence */
783
 
  unit->global_parameters->select_limit= new Item_int((int32_t) 1);
 
758
  unit->global_parameters->select_limit= new Item_int((int32) 1);
784
759
}
785
760
 
786
761
double Item_exists_subselect::val_real()
787
762
{
788
 
  assert(fixed == 1);
 
763
  DBUG_ASSERT(fixed == 1);
789
764
  if (exec())
790
765
  {
791
766
    reset();
794
769
  return (double) value;
795
770
}
796
771
 
797
 
int64_t Item_exists_subselect::val_int()
 
772
longlong Item_exists_subselect::val_int()
798
773
{
799
 
  assert(fixed == 1);
 
774
  DBUG_ASSERT(fixed == 1);
800
775
  if (exec())
801
776
  {
802
777
    reset();
807
782
 
808
783
String *Item_exists_subselect::val_str(String *str)
809
784
{
810
 
  assert(fixed == 1);
 
785
  DBUG_ASSERT(fixed == 1);
811
786
  if (exec())
812
787
  {
813
788
    reset();
814
789
    return 0;
815
790
  }
816
 
  str->set((uint64_t)value,&my_charset_bin);
 
791
  str->set((ulonglong)value,&my_charset_bin);
817
792
  return str;
818
793
}
819
794
 
820
795
 
821
796
my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
822
797
{
823
 
  assert(fixed == 1);
 
798
  DBUG_ASSERT(fixed == 1);
824
799
  if (exec())
825
800
  {
826
801
    reset();
833
808
 
834
809
bool Item_exists_subselect::val_bool()
835
810
{
836
 
  assert(fixed == 1);
 
811
  DBUG_ASSERT(fixed == 1);
837
812
  if (exec())
838
813
  {
839
814
    reset();
849
824
    As far as Item_in_subselect called only from Item_in_optimizer this
850
825
    method should not be used
851
826
  */
852
 
  assert(0);
853
 
  assert(fixed == 1);
 
827
  DBUG_ASSERT(0);
 
828
  DBUG_ASSERT(fixed == 1);
854
829
  null_value= 0;
855
830
  if (exec())
856
831
  {
864
839
}
865
840
 
866
841
 
867
 
int64_t Item_in_subselect::val_int()
 
842
longlong Item_in_subselect::val_int()
868
843
{
869
844
  /*
870
845
    As far as Item_in_subselect called only from Item_in_optimizer this
871
846
    method should not be used
872
847
  */
873
 
  assert(fixed == 1);
 
848
  DBUG_ASSERT(0);
 
849
  DBUG_ASSERT(fixed == 1);
874
850
  null_value= 0;
875
851
  if (exec())
876
852
  {
890
866
    As far as Item_in_subselect called only from Item_in_optimizer this
891
867
    method should not be used
892
868
  */
893
 
  assert(0);
894
 
  assert(fixed == 1);
 
869
  DBUG_ASSERT(0);
 
870
  DBUG_ASSERT(fixed == 1);
895
871
  null_value= 0;
896
872
  if (exec())
897
873
  {
904
880
    null_value= 1;
905
881
    return 0;
906
882
  }
907
 
  str->set((uint64_t)value, &my_charset_bin);
 
883
  str->set((ulonglong)value, &my_charset_bin);
908
884
  return str;
909
885
}
910
886
 
911
887
 
912
888
bool Item_in_subselect::val_bool()
913
889
{
914
 
  assert(fixed == 1);
 
890
  DBUG_ASSERT(fixed == 1);
915
891
  null_value= 0;
916
892
  if (exec())
917
893
  {
918
894
    reset();
919
 
    /*
 
895
    /* 
920
896
      Must mark the IN predicate as NULL so as to make sure an enclosing NOT
921
 
      predicate will return false. See the comments in
 
897
      predicate will return FALSE. See the comments in 
922
898
      subselect_uniquesubquery_engine::copy_ref_key for further details.
923
899
    */
924
900
    null_value= 1;
935
911
    As far as Item_in_subselect called only from Item_in_optimizer this
936
912
    method should not be used
937
913
  */
938
 
  assert(0);
 
914
  DBUG_ASSERT(0);
939
915
  null_value= 0;
940
 
  assert(fixed == 1);
 
916
  DBUG_ASSERT(fixed == 1);
941
917
  if (exec())
942
918
  {
943
919
    reset();
951
927
}
952
928
 
953
929
 
954
 
/*
 
930
/* 
955
931
  Rewrite a single-column IN/ALL/ANY subselect
956
932
 
957
933
  SYNOPSIS
961
937
 
962
938
  DESCRIPTION
963
939
    Rewrite a single-column subquery using rule-based approach. The subquery
964
 
 
 
940
    
965
941
       oe $cmp$ (SELECT ie FROM ... WHERE subq_where ... HAVING subq_having)
966
 
 
 
942
    
967
943
    First, try to convert the subquery to scalar-result subquery in one of
968
944
    the forms:
969
 
 
 
945
    
970
946
       - oe $cmp$ (SELECT MAX(...) )  // handled by Item_singlerow_subselect
971
947
       - oe $cmp$ <max>(SELECT ...)   // handled by Item_maxmin_subselect
972
 
 
 
948
   
973
949
    If that fails, the subquery will be handled with class Item_in_optimizer.
974
950
    There are two possibilites:
975
951
    - If the subquery execution method is materialization, then the subquery is
986
962
*/
987
963
 
988
964
Item_subselect::trans_res
989
 
Item_in_subselect::single_value_transformer(Join *join,
990
 
                                            const Comp_creator *func)
 
965
Item_in_subselect::single_value_transformer(JOIN *join,
 
966
                                            Comp_creator *func)
991
967
{
992
 
  Select_Lex *select_lex= join->select_lex;
 
968
  SELECT_LEX *select_lex= join->select_lex;
 
969
  DBUG_ENTER("Item_in_subselect::single_value_transformer");
993
970
 
994
971
  /*
995
972
    Check that the right part of the subselect contains no more than one
998
975
  if (select_lex->item_list.elements > 1)
999
976
  {
1000
977
    my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
1001
 
    return(RES_ERROR);
 
978
    DBUG_RETURN(RES_ERROR);
1002
979
  }
1003
980
 
1004
981
  /*
1013
990
    later in this method.
1014
991
  */
1015
992
  if ((abort_on_null || (upper_item && upper_item->top_level())) &&
1016
 
      select_lex->master_unit()->uncacheable.none() && !func->eqne_op())
 
993
      !select_lex->master_unit()->uncacheable && !func->eqne_op())
1017
994
  {
1018
995
    if (substitution)
1019
996
    {
1020
997
      // It is second (third, ...) SELECT of UNION => All is done
1021
 
      return(RES_OK);
 
998
      DBUG_RETURN(RES_OK);
1022
999
    }
1023
1000
 
1024
1001
    Item *subs;
1055
1032
        it.replace(item);
1056
1033
      }
1057
1034
 
1058
 
      save_allow_sum_func= session->lex->allow_sum_func;
1059
 
      session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
 
1035
      save_allow_sum_func= thd->lex->allow_sum_func;
 
1036
      thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
1060
1037
      /*
1061
1038
        Item_sum_(max|min) can't substitute other item => we can use 0 as
1062
1039
        reference, also Item_sum_(max|min) can't be fixed after creation, so
1063
1040
        we do not check item->fixed
1064
1041
      */
1065
 
      if (item->fix_fields(session, 0))
1066
 
        return(RES_ERROR);
1067
 
      session->lex->allow_sum_func= save_allow_sum_func;
 
1042
      if (item->fix_fields(thd, 0))
 
1043
        DBUG_RETURN(RES_ERROR);
 
1044
      thd->lex->allow_sum_func= save_allow_sum_func; 
1068
1045
      /* we added aggregate function => we have to change statistic */
1069
 
      count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
 
1046
      count_field_types(select_lex, &join->tmp_table_param, join->all_fields, 
1070
1047
                        0);
1071
1048
 
1072
1049
      subs= new Item_singlerow_subselect(select_lex);
1074
1051
    else
1075
1052
    {
1076
1053
      Item_maxmin_subselect *item;
1077
 
      subs= item= new Item_maxmin_subselect(session, this, select_lex, func->l_op());
 
1054
      subs= item= new Item_maxmin_subselect(thd, this, select_lex, func->l_op());
1078
1055
      if (upper_item)
1079
1056
        upper_item->set_sub_test(item);
1080
1057
    }
1081
1058
    /* fix fields is already called for  left expression */
1082
1059
    substitution= func->create(left_expr, subs);
1083
 
    return(RES_OK);
 
1060
    DBUG_RETURN(RES_OK);
1084
1061
  }
1085
1062
 
1086
1063
  if (!substitution)
1087
1064
  {
1088
1065
    /* We're invoked for the 1st (or the only) SELECT in the subquery UNION */
1089
 
    Select_Lex_Unit *master_unit= select_lex->master_unit();
 
1066
    SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
1090
1067
    substitution= optimizer;
1091
1068
 
1092
 
    Select_Lex *current= session->lex->current_select, *up;
 
1069
    SELECT_LEX *current= thd->lex->current_select, *up;
1093
1070
 
1094
 
    session->lex->current_select= up= current->return_after_parsing();
 
1071
    thd->lex->current_select= up= current->return_after_parsing();
1095
1072
    //optimizer never use Item **ref => we can pass 0 as parameter
1096
 
    if (!optimizer || optimizer->fix_left(session, 0))
 
1073
    if (!optimizer || optimizer->fix_left(thd, 0))
1097
1074
    {
1098
 
      session->lex->current_select= current;
1099
 
      return(RES_ERROR);
 
1075
      thd->lex->current_select= current;
 
1076
      DBUG_RETURN(RES_ERROR);
1100
1077
    }
1101
 
    session->lex->current_select= current;
 
1078
    thd->lex->current_select= current;
1102
1079
 
1103
1080
    /*
1104
1081
      As far as  Item_ref_in_optimizer do not substitute itself on fix_fields
1109
1086
                              (char *)"<no matter>",
1110
1087
                              (char *)in_left_expr_name);
1111
1088
 
1112
 
    master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1089
    master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1113
1090
  }
1114
1091
 
1115
1092
  if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1116
1093
  {
1117
 
    if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool))))
1118
 
      return(RES_ERROR);
1119
 
    pushed_cond_guards[0]= true;
 
1094
    if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool))))
 
1095
      DBUG_RETURN(RES_ERROR);
 
1096
    pushed_cond_guards[0]= TRUE;
1120
1097
  }
1121
1098
 
1122
1099
  /*
1124
1101
    perform the IN -> EXISTS transformation.
1125
1102
  */
1126
1103
  if (exec_method == MATERIALIZATION)
1127
 
    return(RES_OK);
 
1104
    DBUG_RETURN(RES_OK);
1128
1105
 
1129
1106
  /* Perform the IN=>EXISTS transformation. */
1130
 
  return(single_value_in_to_exists_transformer(join, func));
 
1107
  DBUG_RETURN(single_value_in_to_exists_transformer(join, func));
1131
1108
}
1132
1109
 
1133
1110
 
1139
1116
 
1140
1117
  - If the subquery has aggregates, GROUP BY, or HAVING, convert to
1141
1118
 
1142
 
    SELECT ie FROM ...  HAVING subq_having AND
 
1119
    SELECT ie FROM ...  HAVING subq_having AND 
1143
1120
                               trigcond(oe $cmp$ ref_or_null_helper<ie>)
1144
 
 
 
1121
                                   
1145
1122
    the addition is wrapped into trigger only when we want to distinguish
1146
 
    between NULL and false results.
 
1123
    between NULL and FALSE results.
1147
1124
 
1148
1125
  - Otherwise (no aggregates/GROUP BY/HAVING) convert it to one of the
1149
1126
    following:
1150
1127
 
1151
 
    = If we don't need to distinguish between NULL and false subquery:
1152
 
 
 
1128
    = If we don't need to distinguish between NULL and FALSE subquery:
 
1129
        
1153
1130
      SELECT 1 FROM ... WHERE (oe $cmp$ ie) AND subq_where
1154
1131
 
1155
1132
    = If we need to distinguish between those:
1168
1145
*/
1169
1146
 
1170
1147
Item_subselect::trans_res
1171
 
Item_in_subselect::single_value_in_to_exists_transformer(Join * join, const Comp_creator *func)
 
1148
Item_in_subselect::single_value_in_to_exists_transformer(JOIN * join, Comp_creator *func)
1172
1149
{
1173
 
  Select_Lex *select_lex= join->select_lex;
 
1150
  SELECT_LEX *select_lex= join->select_lex;
 
1151
  DBUG_ENTER("Item_in_subselect::single_value_in_to_exists_transformer");
1174
1152
 
1175
 
  select_lex->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1153
  select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1176
1154
  if (join->having || select_lex->with_sum_func ||
1177
1155
      select_lex->group_list.elements)
1178
1156
  {
1186
1164
                                                      this->full_name()));
1187
1165
    if (!abort_on_null && left_expr->maybe_null)
1188
1166
    {
1189
 
      /*
 
1167
      /* 
1190
1168
        We can encounter "NULL IN (SELECT ...)". Wrap the added condition
1191
1169
        within a trig_cond.
1192
1170
      */
1193
1171
      item= new Item_func_trig_cond(item, get_cond_guard(0));
1194
1172
    }
1195
 
 
 
1173
    
1196
1174
    /*
1197
1175
      AND and comparison functions can't be changed during fix_fields()
1198
1176
      we can assign select_lex->having here, and pass 0 as last
1206
1184
      we do not check join->having->fixed, because Item_and (from and_items)
1207
1185
      or comparison function (from func->create) can't be fixed after creation
1208
1186
    */
1209
 
    tmp= join->having->fix_fields(session, 0);
 
1187
    tmp= join->having->fix_fields(thd, 0);
1210
1188
    select_lex->having_fix_field= 0;
1211
1189
    if (tmp)
1212
 
      return(RES_ERROR);
 
1190
      DBUG_RETURN(RES_ERROR);
1213
1191
  }
1214
1192
  else
1215
1193
  {
1221
1199
      Item *having= item, *orig_item= item;
1222
1200
      select_lex->item_list.empty();
1223
1201
      select_lex->item_list.push_back(new Item_int("Not_used",
1224
 
                                                   (int64_t) 1,
 
1202
                                                   (longlong) 1,
1225
1203
                                                   MY_INT64_NUM_DECIMAL_DIGITS));
1226
1204
      select_lex->ref_pointer_array[0]= select_lex->item_list.head();
1227
 
 
 
1205
       
1228
1206
      item= func->create(expr, item);
1229
1207
      if (!abort_on_null && orig_item->maybe_null)
1230
1208
      {
1233
1211
        {
1234
1212
          if (!(having= new Item_func_trig_cond(having,
1235
1213
                                                get_cond_guard(0))))
1236
 
            return(RES_ERROR);
 
1214
            DBUG_RETURN(RES_ERROR);
1237
1215
        }
1238
1216
        /*
1239
1217
          Item_is_not_null_test can't be changed during fix_fields()
1248
1226
          and_items) or comparison function (from func->create) can't be
1249
1227
          fixed after creation
1250
1228
        */
1251
 
        tmp= join->having->fix_fields(session, 0);
 
1229
        tmp= join->having->fix_fields(thd, 0);
1252
1230
        select_lex->having_fix_field= 0;
1253
1231
        if (tmp)
1254
 
          return(RES_ERROR);
 
1232
          DBUG_RETURN(RES_ERROR);
1255
1233
        item= new Item_cond_or(item,
1256
1234
                               new Item_func_isnull(orig_item));
1257
1235
      }
1258
 
      /*
 
1236
      /* 
1259
1237
        If we may encounter NULL IN (SELECT ...) and care whether subquery
1260
 
        result is NULL or false, wrap condition in a trig_cond.
 
1238
        result is NULL or FALSE, wrap condition in a trig_cond.
1261
1239
      */
1262
1240
      if (!abort_on_null && left_expr->maybe_null)
1263
1241
      {
1264
1242
        if (!(item= new Item_func_trig_cond(item, get_cond_guard(0))))
1265
 
          return(RES_ERROR);
 
1243
          DBUG_RETURN(RES_ERROR);
1266
1244
      }
1267
1245
      /*
1268
 
        TODO: figure out why the following is done here in
 
1246
        TODO: figure out why the following is done here in 
1269
1247
        single_value_transformer but there is no corresponding action in
1270
1248
        row_value_transformer?
1271
1249
      */
1282
1260
        we do not check join->conds->fixed, because Item_and can't be fixed
1283
1261
        after creation
1284
1262
      */
1285
 
      if (join->conds->fix_fields(session, 0))
1286
 
        return(RES_ERROR);
 
1263
      if (join->conds->fix_fields(thd, 0))
 
1264
        DBUG_RETURN(RES_ERROR);
1287
1265
    }
1288
1266
    else
1289
1267
    {
1305
1283
        {
1306
1284
          if (!(new_having= new Item_func_trig_cond(new_having,
1307
1285
                                                    get_cond_guard(0))))
1308
 
            return(RES_ERROR);
 
1286
            DBUG_RETURN(RES_ERROR);
1309
1287
        }
1310
1288
        new_having->name= (char*)in_having_cond;
1311
1289
        select_lex->having= join->having= new_having;
1312
1290
        select_lex->having_fix_field= 1;
1313
 
 
 
1291
        
1314
1292
        /*
1315
1293
          we do not check join->having->fixed, because comparison function
1316
1294
          (from func->create) can't be fixed after creation
1317
1295
        */
1318
 
        tmp= join->having->fix_fields(session, 0);
 
1296
        tmp= join->having->fix_fields(thd, 0);
1319
1297
        select_lex->having_fix_field= 0;
1320
1298
        if (tmp)
1321
 
          return(RES_ERROR);
 
1299
          DBUG_RETURN(RES_ERROR);
1322
1300
      }
1323
1301
      else
1324
1302
      {
1327
1305
        // fix_field of item will be done in time of substituting
1328
1306
        substitution= item;
1329
1307
        have_to_be_excluded= 1;
1330
 
        if (session->lex->describe)
 
1308
        if (thd->lex->describe)
1331
1309
        {
1332
 
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
1333
 
          snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
1334
 
          push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1310
          char warn_buff[MYSQL_ERRMSG_SIZE];
 
1311
          sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
 
1312
          push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1335
1313
                       ER_SELECT_REDUCED, warn_buff);
1336
1314
        }
1337
 
        return(RES_REDUCE);
 
1315
        DBUG_RETURN(RES_REDUCE);
1338
1316
      }
1339
1317
    }
1340
1318
  }
1341
1319
 
1342
 
  return(RES_OK);
 
1320
  DBUG_RETURN(RES_OK);
1343
1321
}
1344
1322
 
1345
1323
 
1346
1324
Item_subselect::trans_res
1347
 
Item_in_subselect::row_value_transformer(Join *join)
 
1325
Item_in_subselect::row_value_transformer(JOIN *join)
1348
1326
{
1349
 
  Select_Lex *select_lex= join->select_lex;
1350
 
  uint32_t cols_num= left_expr->cols();
 
1327
  SELECT_LEX *select_lex= join->select_lex;
 
1328
  uint cols_num= left_expr->cols();
 
1329
 
 
1330
  DBUG_ENTER("Item_in_subselect::row_value_transformer");
1351
1331
 
1352
1332
  if (select_lex->item_list.elements != left_expr->cols())
1353
1333
  {
1354
1334
    my_error(ER_OPERAND_COLUMNS, MYF(0), left_expr->cols());
1355
 
    return(RES_ERROR);
 
1335
    DBUG_RETURN(RES_ERROR);
1356
1336
  }
1357
1337
 
1358
1338
  /*
1362
1342
  if (!substitution)
1363
1343
  {
1364
1344
    //first call for this unit
1365
 
    Select_Lex_Unit *master_unit= select_lex->master_unit();
 
1345
    SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
1366
1346
    substitution= optimizer;
1367
1347
 
1368
 
    Select_Lex *current= session->lex->current_select, *up;
1369
 
    session->lex->current_select= up= current->return_after_parsing();
 
1348
    SELECT_LEX *current= thd->lex->current_select, *up;
 
1349
    thd->lex->current_select= up= current->return_after_parsing();
1370
1350
    //optimizer never use Item **ref => we can pass 0 as parameter
1371
 
    if (!optimizer || optimizer->fix_left(session, 0))
 
1351
    if (!optimizer || optimizer->fix_left(thd, 0))
1372
1352
    {
1373
 
      session->lex->current_select= current;
1374
 
      return(RES_ERROR);
 
1353
      thd->lex->current_select= current;
 
1354
      DBUG_RETURN(RES_ERROR);
1375
1355
    }
1376
1356
 
1377
1357
    // we will refer to upper level cache array => we have to save it in PS
1378
1358
    optimizer->keep_top_level_cache();
1379
1359
 
1380
 
    session->lex->current_select= current;
1381
 
    master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1360
    thd->lex->current_select= current;
 
1361
    master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1382
1362
 
1383
1363
    if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1384
1364
    {
1385
 
      if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool) *
 
1365
      if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool) *
1386
1366
                                                        left_expr->cols())))
1387
 
        return(RES_ERROR);
1388
 
      for (uint32_t i= 0; i < cols_num; i++)
1389
 
        pushed_cond_guards[i]= true;
 
1367
        DBUG_RETURN(RES_ERROR);
 
1368
      for (uint i= 0; i < cols_num; i++)
 
1369
        pushed_cond_guards[i]= TRUE;
1390
1370
    }
1391
1371
  }
1392
1372
 
1395
1375
    perform the IN -> EXISTS transformation.
1396
1376
  */
1397
1377
  if (exec_method == MATERIALIZATION)
1398
 
    return(RES_OK);
 
1378
    DBUG_RETURN(RES_OK);
1399
1379
 
1400
1380
  /* Perform the IN=>EXISTS transformation. */
1401
 
  return(row_value_in_to_exists_transformer(join));
 
1381
  DBUG_RETURN(row_value_in_to_exists_transformer(join));
1402
1382
}
1403
1383
 
1404
1384
 
1421
1401
*/
1422
1402
 
1423
1403
Item_subselect::trans_res
1424
 
Item_in_subselect::row_value_in_to_exists_transformer(Join * join)
 
1404
Item_in_subselect::row_value_in_to_exists_transformer(JOIN * join)
1425
1405
{
1426
 
  Select_Lex *select_lex= join->select_lex;
 
1406
  SELECT_LEX *select_lex= join->select_lex;
1427
1407
  Item *having_item= 0;
1428
 
  uint32_t cols_num= left_expr->cols();
 
1408
  uint cols_num= left_expr->cols();
1429
1409
  bool is_having_used= (join->having || select_lex->with_sum_func ||
1430
1410
                        select_lex->group_list.first ||
1431
1411
                        !select_lex->table_list.elements);
1432
1412
 
1433
 
  select_lex->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1413
  DBUG_ENTER("Item_in_subselect::row_value_in_to_exists_transformer");
 
1414
 
 
1415
  select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1434
1416
  if (is_having_used)
1435
1417
  {
1436
1418
    /*
1447
1429
      TODO: say here explicitly if the order of AND parts matters or not.
1448
1430
    */
1449
1431
    Item *item_having_part2= 0;
1450
 
    for (uint32_t i= 0; i < cols_num; i++)
 
1432
    for (uint i= 0; i < cols_num; i++)
1451
1433
    {
1452
 
      assert((left_expr->fixed && select_lex->ref_pointer_array[i]->fixed) ||
 
1434
      DBUG_ASSERT(left_expr->fixed &&
 
1435
                  select_lex->ref_pointer_array[i]->fixed ||
1453
1436
                  (select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
1454
1437
                   ((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
1455
1438
                    Item_ref::OUTER_REF));
1456
1439
      if (select_lex->ref_pointer_array[i]->
1457
1440
          check_cols(left_expr->element_index(i)->cols()))
1458
 
        return(RES_ERROR);
 
1441
        DBUG_RETURN(RES_ERROR);
1459
1442
      Item *item_eq=
1460
1443
        new Item_func_eq(new
1461
1444
                         Item_ref(&select_lex->context,
1480
1463
      if (!abort_on_null && left_expr->element_index(i)->maybe_null)
1481
1464
      {
1482
1465
        if (!(col_item= new Item_func_trig_cond(col_item, get_cond_guard(i))))
1483
 
          return(RES_ERROR);
 
1466
          DBUG_RETURN(RES_ERROR);
1484
1467
      }
1485
1468
      having_item= and_items(having_item, col_item);
1486
 
 
1487
 
      Item *item_nnull_test=
 
1469
      
 
1470
      Item *item_nnull_test= 
1488
1471
         new Item_is_not_null_test(this,
1489
1472
                                   new Item_ref(&select_lex->context,
1490
1473
                                                select_lex->
1493
1476
                                                (char *)"<list ref>"));
1494
1477
      if (!abort_on_null && left_expr->element_index(i)->maybe_null)
1495
1478
      {
1496
 
        if (!(item_nnull_test=
 
1479
        if (!(item_nnull_test= 
1497
1480
              new Item_func_trig_cond(item_nnull_test, get_cond_guard(i))))
1498
 
          return(RES_ERROR);
 
1481
          DBUG_RETURN(RES_ERROR);
1499
1482
      }
1500
1483
      item_having_part2= and_items(item_having_part2, item_nnull_test);
1501
1484
      item_having_part2->top_level_item();
1523
1506
                               (l3 = v3)
1524
1507
    */
1525
1508
    Item *where_item= 0;
1526
 
    for (uint32_t i= 0; i < cols_num; i++)
 
1509
    for (uint i= 0; i < cols_num; i++)
1527
1510
    {
1528
1511
      Item *item, *item_isnull;
1529
 
      assert((left_expr->fixed && select_lex->ref_pointer_array[i]->fixed) ||
 
1512
      DBUG_ASSERT(left_expr->fixed &&
 
1513
                  select_lex->ref_pointer_array[i]->fixed ||
1530
1514
                  (select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
1531
1515
                   ((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
1532
1516
                    Item_ref::OUTER_REF));
1533
1517
      if (select_lex->ref_pointer_array[i]->
1534
1518
          check_cols(left_expr->element_index(i)->cols()))
1535
 
        return(RES_ERROR);
 
1519
        DBUG_RETURN(RES_ERROR);
1536
1520
      item=
1537
1521
        new Item_func_eq(new
1538
1522
                         Item_direct_ref(&select_lex->context,
1552
1536
        Item *having_col_item=
1553
1537
          new Item_is_not_null_test(this,
1554
1538
                                    new
1555
 
                                    Item_ref(&select_lex->context,
 
1539
                                    Item_ref(&select_lex->context, 
1556
1540
                                             select_lex->ref_pointer_array + i,
1557
1541
                                             (char *)"<no matter>",
1558
1542
                                             (char *)"<list ref>"));
1559
 
 
1560
 
 
 
1543
        
 
1544
        
1561
1545
        item_isnull= new
1562
1546
          Item_func_isnull(new
1563
1547
                           Item_direct_ref(&select_lex->context,
1567
1551
                                           (char *)"<list ref>")
1568
1552
                          );
1569
1553
        item= new Item_cond_or(item, item_isnull);
1570
 
        /*
 
1554
        /* 
1571
1555
          TODO: why we create the above for cases where the right part
1572
1556
                cant be NULL?
1573
1557
        */
1574
1558
        if (left_expr->element_index(i)->maybe_null)
1575
1559
        {
1576
1560
          if (!(item= new Item_func_trig_cond(item, get_cond_guard(i))))
1577
 
            return(RES_ERROR);
1578
 
          if (!(having_col_item=
 
1561
            DBUG_RETURN(RES_ERROR);
 
1562
          if (!(having_col_item= 
1579
1563
                  new Item_func_trig_cond(having_col_item, get_cond_guard(i))))
1580
 
            return(RES_ERROR);
 
1564
            DBUG_RETURN(RES_ERROR);
1581
1565
        }
1582
1566
        having_item= and_items(having_item, having_col_item);
1583
1567
      }
1590
1574
    */
1591
1575
    select_lex->where= join->conds= and_items(join->conds, where_item);
1592
1576
    select_lex->where->top_level_item();
1593
 
    if (join->conds->fix_fields(session, 0))
1594
 
      return(RES_ERROR);
 
1577
    if (join->conds->fix_fields(thd, 0))
 
1578
      DBUG_RETURN(RES_ERROR);
1595
1579
  }
1596
1580
  if (having_item)
1597
1581
  {
1606
1590
      argument (reference) to fix_fields()
1607
1591
    */
1608
1592
    select_lex->having_fix_field= 1;
1609
 
    res= join->having->fix_fields(session, 0);
 
1593
    res= join->having->fix_fields(thd, 0);
1610
1594
    select_lex->having_fix_field= 0;
1611
1595
    if (res)
1612
1596
    {
1613
 
      return(RES_ERROR);
 
1597
      DBUG_RETURN(RES_ERROR);
1614
1598
    }
1615
1599
  }
1616
1600
 
1617
 
  return(RES_OK);
 
1601
  DBUG_RETURN(RES_OK);
1618
1602
}
1619
1603
 
1620
1604
 
1621
1605
Item_subselect::trans_res
1622
 
Item_in_subselect::select_transformer(Join *join)
 
1606
Item_in_subselect::select_transformer(JOIN *join)
1623
1607
{
1624
 
  return select_in_like_transformer(join, Eq_creator::instance());
 
1608
  return select_in_like_transformer(join, &eq_creator);
1625
1609
}
1626
1610
 
1627
1611
 
1647
1631
*/
1648
1632
 
1649
1633
Item_subselect::trans_res
1650
 
Item_in_subselect::select_in_like_transformer(Join *join, const Comp_creator *func)
 
1634
Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
1651
1635
{
1652
 
  Select_Lex *current= session->lex->current_select, *up;
1653
 
  const char *save_where= session->where;
 
1636
  SELECT_LEX *current= thd->lex->current_select, *up;
 
1637
  const char *save_where= thd->where;
1654
1638
  Item_subselect::trans_res res= RES_ERROR;
1655
1639
  bool result;
1656
1640
 
 
1641
  DBUG_ENTER("Item_in_subselect::select_in_like_transformer");
 
1642
 
1657
1643
  {
1658
1644
    /*
1659
1645
      IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
1660
1646
      ORDER BY clause becomes meaningless thus we drop it here.
1661
1647
    */
1662
 
    Select_Lex *sl= current->master_unit()->first_select();
 
1648
    SELECT_LEX *sl= current->master_unit()->first_select();
1663
1649
    for (; sl; sl= sl->next_select())
1664
1650
    {
1665
1651
      if (sl->join)
1668
1654
  }
1669
1655
 
1670
1656
  if (changed)
1671
 
    return(RES_OK);
 
1657
    DBUG_RETURN(RES_OK);
1672
1658
 
1673
 
  session->where= "IN/ALL/ANY subquery";
 
1659
  thd->where= "IN/ALL/ANY subquery";
1674
1660
 
1675
1661
  /*
1676
1662
    In some optimisation cases we will not need this Item_in_optimizer
1684
1670
      goto err;
1685
1671
  }
1686
1672
 
1687
 
  session->lex->current_select= up= current->return_after_parsing();
 
1673
  thd->lex->current_select= up= current->return_after_parsing();
1688
1674
  result= (!left_expr->fixed &&
1689
 
           left_expr->fix_fields(session, optimizer->arguments()));
 
1675
           left_expr->fix_fields(thd, optimizer->arguments()));
1690
1676
  /* fix_fields can change reference to left_expr, we need reassign it */
1691
1677
  left_expr= optimizer->arguments()[0];
1692
1678
 
1693
 
  session->lex->current_select= current;
 
1679
  thd->lex->current_select= current;
1694
1680
  if (result)
1695
1681
    goto err;
1696
1682
 
1713
1699
  else
1714
1700
  {
1715
1701
    /* we do not support row operation for ALL/ANY/SOME */
1716
 
    if (func != Eq_creator::instance())
 
1702
    if (func != &eq_creator)
1717
1703
    {
1718
1704
      my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
1719
 
      return(RES_ERROR);
 
1705
      DBUG_RETURN(RES_ERROR);
1720
1706
    }
1721
1707
    res= row_value_transformer(join);
1722
1708
  }
1723
1709
err:
1724
 
  session->where= save_where;
1725
 
  return(res);
 
1710
  thd->where= save_where;
 
1711
  DBUG_RETURN(res);
1726
1712
}
1727
1713
 
1728
1714
 
1739
1725
}
1740
1726
 
1741
1727
 
1742
 
bool Item_in_subselect::fix_fields(Session *session_arg, Item **ref)
 
1728
bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
1743
1729
{
1744
1730
  bool result = 0;
1745
1731
 
1746
1732
  if (exec_method == SEMI_JOIN)
1747
1733
    return !( (*ref)= new Item_int(1));
1748
1734
 
1749
 
  return result || Item_subselect::fix_fields(session_arg, ref);
 
1735
  if (thd_arg->lex->view_prepare_mode && left_expr && !left_expr->fixed)
 
1736
    result = left_expr->fix_fields(thd_arg, &left_expr);
 
1737
 
 
1738
  return result || Item_subselect::fix_fields(thd_arg, ref);
1750
1739
}
1751
1740
 
1752
1741
 
1770
1759
    execution.
1771
1760
 
1772
1761
  @returns
1773
 
    @retval true  memory allocation error occurred
1774
 
    @retval false an execution method was chosen successfully
 
1762
    @retval TRUE  memory allocation error occurred
 
1763
    @retval FALSE an execution method was chosen successfully
1775
1764
*/
1776
1765
 
1777
1766
bool Item_in_subselect::setup_engine()
1778
1767
{
1779
1768
  subselect_hash_sj_engine *new_engine= NULL;
1780
 
  bool res= false;
 
1769
  bool res= FALSE;
 
1770
 
 
1771
  DBUG_ENTER("Item_in_subselect::setup_engine");
1781
1772
 
1782
1773
  if (engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE)
1783
1774
  {
1784
1775
    /* Create/initialize objects in permanent memory. */
1785
 
    subselect_single_select_engine *old_engine_ptr;
1786
 
 
1787
 
    old_engine_ptr= static_cast<subselect_single_select_engine *>(engine);
1788
 
 
1789
 
    if (!(new_engine= new subselect_hash_sj_engine(session, this,
1790
 
                                                   old_engine_ptr)) ||
 
1776
    subselect_single_select_engine *old_engine;
 
1777
 
 
1778
    old_engine= (subselect_single_select_engine*) engine;
 
1779
 
 
1780
    if (!(new_engine= new subselect_hash_sj_engine(thd, this,
 
1781
                                                   old_engine)) ||
1791
1782
        new_engine->init_permanent(unit->get_unit_column_types()))
1792
1783
    {
1793
 
      Item_subselect::trans_res new_trans_res;
 
1784
      Item_subselect::trans_res trans_res;
1794
1785
      /*
1795
1786
        If for some reason we cannot use materialization for this IN predicate,
1796
1787
        delete all materialization-related objects, and apply the IN=>EXISTS
1800
1791
      new_engine= NULL;
1801
1792
      exec_method= NOT_TRANSFORMED;
1802
1793
      if (left_expr->cols() == 1)
1803
 
        new_trans_res= single_value_in_to_exists_transformer(
1804
 
                           old_engine_ptr->join,
1805
 
                           Eq_creator::instance());
 
1794
        trans_res= single_value_in_to_exists_transformer(old_engine->join,
 
1795
                                                         &eq_creator);
1806
1796
      else
1807
 
        new_trans_res= row_value_in_to_exists_transformer(old_engine_ptr->join);
1808
 
      res= (new_trans_res != Item_subselect::RES_OK);
 
1797
        trans_res= row_value_in_to_exists_transformer(old_engine->join);
 
1798
      res= (trans_res != Item_subselect::RES_OK);
1809
1799
    }
1810
1800
    if (new_engine)
1811
1801
      engine= new_engine;
1812
1802
  }
1813
1803
  else
1814
1804
  {
1815
 
    assert(engine->engine_type() == subselect_engine::HASH_SJ_ENGINE);
1816
 
    new_engine= static_cast<subselect_hash_sj_engine *>(engine);
 
1805
    DBUG_ASSERT(engine->engine_type() == subselect_engine::HASH_SJ_ENGINE);
 
1806
    new_engine= (subselect_hash_sj_engine*) engine;
1817
1807
  }
1818
1808
 
1819
1809
  /* Initilizations done in runtime memory, repeated for each execution. */
1829
1819
    */
1830
1820
    unit->global_parameters->select_limit= NULL;
1831
1821
    if ((res= new_engine->init_runtime()))
1832
 
      return(res);
 
1822
      DBUG_RETURN(res);
1833
1823
  }
1834
1824
 
1835
 
  return(res);
 
1825
  DBUG_RETURN(res);
1836
1826
}
1837
1827
 
1838
1828
 
1843
1833
  but it takes a different kind of collection of items, and the
1844
1834
  list we push to is dynamically allocated.
1845
1835
 
1846
 
  @retval true  if a memory allocation error occurred or the cache is
 
1836
  @retval TRUE  if a memory allocation error occurred or the cache is
1847
1837
                not applicable to the current query
1848
 
  @retval false if success
 
1838
  @retval FALSE if success
1849
1839
*/
1850
1840
 
1851
1841
bool Item_in_subselect::init_left_expr_cache()
1852
1842
{
1853
 
  Join *outer_join= NULL;
 
1843
  JOIN *outer_join;
 
1844
  Next_select_func end_select;
 
1845
  bool use_result_field= FALSE;
1854
1846
 
1855
1847
  outer_join= unit->outer_select()->join;
1856
 
  if (! outer_join || ! outer_join->tables || ! outer_join->join_tab)
1857
 
    return true;
 
1848
  if (!outer_join || !outer_join->tables)
 
1849
    return TRUE;
 
1850
  /*
 
1851
    If we use end_[send | write]_group to handle complete rows of the outer
 
1852
    query, make the cache of the left IN operand use Item_field::result_field
 
1853
    instead of Item_field::field.  We need this because normally
 
1854
    Cached_item_field uses Item::field to fetch field data, while
 
1855
    copy_ref_key() that copies the left IN operand into a lookup key uses
 
1856
    Item::result_field. In the case end_[send | write]_group result_field is
 
1857
    one row behind field.
 
1858
  */
 
1859
  end_select= outer_join->join_tab[outer_join->tables-1].next_select;
 
1860
  if (end_select == end_send_group || end_select == end_write_group)
 
1861
    use_result_field= TRUE;
1858
1862
 
1859
1863
  if (!(left_expr_cache= new List<Cached_item>))
1860
 
    return true;
 
1864
    return TRUE;
1861
1865
 
1862
 
  for (uint32_t i= 0; i < left_expr->cols(); i++)
 
1866
  for (uint i= 0; i < left_expr->cols(); i++)
1863
1867
  {
1864
 
    Cached_item *cur_item_cache= new_Cached_item(session, left_expr->element_index(i));
 
1868
    Cached_item *cur_item_cache= new_Cached_item(thd,
 
1869
                                                 left_expr->element_index(i),
 
1870
                                                 use_result_field);
1865
1871
    if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
1866
 
      return true;
 
1872
      return TRUE;
1867
1873
  }
1868
 
  return false;
 
1874
  return FALSE;
1869
1875
}
1870
1876
 
1871
1877
 
1878
1884
    make_cond_for_table() in such a way that it is unchanged when we use
1879
1885
    the IN=>EXISTS transformation to compute IN.
1880
1886
 
1881
 
  @retval true  if the predicate is expensive
1882
 
  @retval false otherwise
 
1887
  @retval TRUE  if the predicate is expensive
 
1888
  @retval FALSE otherwise
1883
1889
*/
1884
1890
 
1885
 
bool Item_in_subselect::is_expensive_processor(unsigned char *)
 
1891
bool Item_in_subselect::is_expensive_processor(uchar *arg)
1886
1892
{
1887
1893
  return exec_method == MATERIALIZATION;
1888
1894
}
1889
1895
 
1890
1896
 
1891
1897
Item_subselect::trans_res
1892
 
Item_allany_subselect::select_transformer(Join *join)
 
1898
Item_allany_subselect::select_transformer(JOIN *join)
1893
1899
{
 
1900
  DBUG_ENTER("Item_allany_subselect::select_transformer");
1894
1901
  exec_method= IN_TO_EXISTS;
1895
1902
  if (upper_item)
1896
1903
    upper_item->show= 1;
1897
 
  return(select_in_like_transformer(join, func));
 
1904
  DBUG_RETURN(select_in_like_transformer(join, func));
1898
1905
}
1899
1906
 
1900
1907
 
1913
1920
}
1914
1921
 
1915
1922
 
1916
 
void subselect_engine::set_session(Session *session_arg)
 
1923
void subselect_engine::set_thd(THD *thd_arg)
1917
1924
{
1918
 
  session= session_arg;
 
1925
  thd= thd_arg;
1919
1926
  if (result)
1920
 
    result->set_session(session_arg);
 
1927
    result->set_thd(thd_arg);
1921
1928
}
1922
1929
 
1923
1930
 
1924
1931
subselect_single_select_engine::
1925
 
subselect_single_select_engine(Select_Lex *select,
 
1932
subselect_single_select_engine(st_select_lex *select,
1926
1933
                               select_result_interceptor *result_arg,
1927
1934
                               Item_subselect *item_arg)
1928
1935
  :subselect_engine(item_arg, result_arg),
1934
1941
 
1935
1942
void subselect_single_select_engine::cleanup()
1936
1943
{
 
1944
  DBUG_ENTER("subselect_single_select_engine::cleanup");
1937
1945
  prepared= executed= 0;
1938
1946
  join= 0;
1939
1947
  result->cleanup();
1940
 
  return;
 
1948
  DBUG_VOID_RETURN;
1941
1949
}
1942
1950
 
1943
1951
 
1944
1952
void subselect_union_engine::cleanup()
1945
1953
{
 
1954
  DBUG_ENTER("subselect_union_engine::cleanup");
1946
1955
  unit->reinit_exec_mechanism();
1947
1956
  result->cleanup();
1948
 
  return;
 
1957
  DBUG_VOID_RETURN;
1949
1958
}
1950
1959
 
1951
1960
 
1966
1975
    return value is undefined if last execution ended in an error.
1967
1976
 
1968
1977
  RETURN
1969
 
    true  - Last subselect execution has produced no rows
1970
 
    false - Otherwise
 
1978
    TRUE  - Last subselect execution has produced no rows
 
1979
    FALSE - Otherwise
1971
1980
*/
1972
1981
 
1973
1982
bool subselect_union_engine::no_rows()
1979
1988
 
1980
1989
void subselect_uniquesubquery_engine::cleanup()
1981
1990
{
 
1991
  DBUG_ENTER("subselect_uniquesubquery_engine::cleanup");
1982
1992
  /* Tell handler we don't need the index anymore */
1983
 
  if (tab->table->cursor->inited)
1984
 
    tab->table->cursor->endIndexScan();
1985
 
  return;
 
1993
  if (tab->table->file->inited)
 
1994
    tab->table->file->ha_index_end();
 
1995
  DBUG_VOID_RETURN;
1986
1996
}
1987
1997
 
1988
1998
 
1989
 
subselect_union_engine::subselect_union_engine(Select_Lex_Unit *u,
 
1999
subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
1990
2000
                                               select_result_interceptor *result_arg,
1991
2001
                                               Item_subselect *item_arg)
1992
2002
  :subselect_engine(item_arg, result_arg)
2026
2036
{
2027
2037
  if (prepared)
2028
2038
    return 0;
2029
 
  join= new Join(session, select_lex->item_list,
 
2039
  join= new JOIN(thd, select_lex->item_list,
2030
2040
                 select_lex->options | SELECT_NO_UNLOCK, result);
2031
2041
  if (!join || !result)
2032
2042
    return 1; /* Fatal error is set already. */
2033
2043
  prepared= 1;
2034
 
  Select_Lex *save_select= session->lex->current_select;
2035
 
  session->lex->current_select= select_lex;
 
2044
  SELECT_LEX *save_select= thd->lex->current_select;
 
2045
  thd->lex->current_select= select_lex;
2036
2046
  if (join->prepare(&select_lex->ref_pointer_array,
2037
 
                    (TableList*) select_lex->table_list.first,
 
2047
                    (TABLE_LIST*) select_lex->table_list.first,
2038
2048
                    select_lex->with_wild,
2039
2049
                    select_lex->where,
2040
2050
                    select_lex->order_list.elements +
2041
2051
                    select_lex->group_list.elements,
2042
 
                    (Order*) select_lex->order_list.first,
2043
 
                    (Order*) select_lex->group_list.first,
 
2052
                    (ORDER*) select_lex->order_list.first,
 
2053
                    (ORDER*) select_lex->group_list.first,
2044
2054
                    select_lex->having,
2045
 
                    select_lex, select_lex->master_unit()))
 
2055
                    (ORDER*) 0, select_lex,
 
2056
                    select_lex->master_unit()))
2046
2057
    return 1;
2047
 
  session->lex->current_select= save_select;
 
2058
  thd->lex->current_select= save_select;
2048
2059
  return 0;
2049
2060
}
2050
2061
 
2051
2062
int subselect_union_engine::prepare()
2052
2063
{
2053
 
  return unit->prepare(session, result, (uint32_t)SELECT_NO_UNLOCK);
 
2064
  return unit->prepare(thd, result, SELECT_NO_UNLOCK);
2054
2065
}
2055
2066
 
2056
2067
int subselect_uniquesubquery_engine::prepare()
2057
2068
{
2058
2069
  /* Should never be called. */
2059
 
  assert(false);
 
2070
  DBUG_ASSERT(FALSE);
2060
2071
  return 1;
2061
2072
}
2062
2073
 
2072
2083
    return value is undefined if last execution ended in an error.
2073
2084
 
2074
2085
  RETURN
2075
 
    true  - Last subselect execution has produced no rows
2076
 
    false - Otherwise
 
2086
    TRUE  - Last subselect execution has produced no rows
 
2087
    FALSE - Otherwise
2077
2088
*/
2078
2089
 
2079
2090
bool subselect_single_select_engine::no_rows()
2080
 
{
 
2091
2081
2092
  return !item->assigned();
2082
2093
}
2083
2094
 
2084
2095
 
2085
 
/*
2086
 
 makes storage for the output values for the subquery and calcuates
 
2096
/* 
 
2097
 makes storage for the output values for the subquery and calcuates 
2087
2098
 their data and column types and their nullability.
2088
 
*/
 
2099
*/ 
2089
2100
void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
2090
2101
{
2091
2102
  Item *sel_item;
2092
2103
  List_iterator_fast<Item> li(item_list);
2093
2104
  res_type= STRING_RESULT;
2094
 
  res_field_type= DRIZZLE_TYPE_VARCHAR;
2095
 
  for (uint32_t i= 0; (sel_item= li++); i++)
 
2105
  res_field_type= MYSQL_TYPE_VAR_STRING;
 
2106
  for (uint i= 0; (sel_item= li++); i++)
2096
2107
  {
2097
2108
    item->max_length= sel_item->max_length;
2098
2109
    res_type= sel_item->result_type();
2110
2121
 
2111
2122
void subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
2112
2123
{
2113
 
  assert(row || select_lex->item_list.elements==1);
 
2124
  DBUG_ASSERT(row || select_lex->item_list.elements==1);
2114
2125
  set_row(select_lex->item_list, row);
2115
2126
  item->collation.set(row[0]->collation);
2116
2127
  if (cols() != 1)
2119
2130
 
2120
2131
void subselect_union_engine::fix_length_and_dec(Item_cache **row)
2121
2132
{
2122
 
  assert(row || unit->first_select()->item_list.elements==1);
 
2133
  DBUG_ASSERT(row || unit->first_select()->item_list.elements==1);
2123
2134
 
2124
2135
  if (unit->first_select()->item_list.elements == 1)
2125
2136
  {
2134
2145
  }
2135
2146
}
2136
2147
 
2137
 
void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **)
 
2148
void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row)
2138
2149
{
2139
2150
  //this never should be called
2140
 
  assert(0);
 
2151
  DBUG_ASSERT(0);
2141
2152
}
2142
2153
 
2143
 
int  init_read_record_seq(JoinTable *tab);
2144
 
int join_read_always_key_or_null(JoinTable *tab);
2145
 
int join_read_next_same_or_null(ReadRecord *info);
 
2154
int  init_read_record_seq(JOIN_TAB *tab);
 
2155
int join_read_always_key_or_null(JOIN_TAB *tab);
 
2156
int join_read_next_same_or_null(READ_RECORD *info);
2146
2157
 
2147
2158
int subselect_single_select_engine::exec()
2148
2159
{
2149
 
  char const *save_where= session->where;
2150
 
  Select_Lex *save_select= session->lex->current_select;
2151
 
  session->lex->current_select= select_lex;
 
2160
  DBUG_ENTER("subselect_single_select_engine::exec");
 
2161
  char const *save_where= thd->where;
 
2162
  SELECT_LEX *save_select= thd->lex->current_select;
 
2163
  thd->lex->current_select= select_lex;
2152
2164
  if (!join->optimized)
2153
2165
  {
2154
 
    Select_Lex_Unit *unit= select_lex->master_unit();
 
2166
    SELECT_LEX_UNIT *unit= select_lex->master_unit();
2155
2167
 
2156
2168
    unit->set_limit(unit->global_parameters);
 
2169
    if (join->flatten_subqueries())
 
2170
    {
 
2171
      thd->is_fatal_error= TRUE;
 
2172
      DBUG_RETURN(1);
 
2173
    }
2157
2174
    if (join->optimize())
2158
2175
    {
2159
 
      session->where= save_where;
 
2176
      thd->where= save_where;
2160
2177
      executed= 1;
2161
 
      session->lex->current_select= save_select;
2162
 
      return(join->error ? join->error : 1);
 
2178
      thd->lex->current_select= save_select;
 
2179
      DBUG_RETURN(join->error ? join->error : 1);
2163
2180
    }
2164
 
    if (select_lex->uncacheable.none() && session->lex->describe &&
2165
 
        !(join->select_options & SELECT_DESCRIBE) &&
 
2181
    if (!select_lex->uncacheable && thd->lex->describe && 
 
2182
        !(join->select_options & SELECT_DESCRIBE) && 
2166
2183
        join->need_tmp && item->const_item())
2167
2184
    {
2168
2185
      /*
2171
2188
        called by EXPLAIN and we need to preserve the initial query structure
2172
2189
        so we can display it.
2173
2190
       */
2174
 
      select_lex->uncacheable.set(UNCACHEABLE_EXPLAIN);
2175
 
      select_lex->master_unit()->uncacheable.set(UNCACHEABLE_EXPLAIN);
 
2191
      select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
 
2192
      select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
2176
2193
      if (join->init_save_join_tab())
2177
 
        return(1);
 
2194
        DBUG_RETURN(1);                        /* purecov: inspected */
2178
2195
    }
2179
2196
    if (item->engine_changed)
2180
2197
    {
2181
 
      return(1);
 
2198
      DBUG_RETURN(1);
2182
2199
    }
2183
2200
  }
2184
 
  if (select_lex->uncacheable.any() &&
2185
 
      ! select_lex->uncacheable.test(UNCACHEABLE_EXPLAIN) &&
2186
 
      executed)
 
2201
  if (select_lex->uncacheable &&
 
2202
      select_lex->uncacheable != UNCACHEABLE_EXPLAIN
 
2203
      && executed)
2187
2204
  {
2188
2205
    if (join->reinit())
2189
2206
    {
2190
 
      session->where= save_where;
2191
 
      session->lex->current_select= save_select;
2192
 
      return 1;
 
2207
      thd->where= save_where;
 
2208
      thd->lex->current_select= save_select;
 
2209
      DBUG_RETURN(1);
2193
2210
    }
2194
2211
    item->reset();
2195
2212
    item->assigned((executed= 0));
2197
2214
  if (!executed)
2198
2215
  {
2199
2216
    item->reset_value_registration();
2200
 
    JoinTable *changed_tabs[MAX_TABLES];
2201
 
    JoinTable **last_changed_tab= changed_tabs;
 
2217
    JOIN_TAB *changed_tabs[MAX_TABLES];
 
2218
    JOIN_TAB **last_changed_tab= changed_tabs;
2202
2219
    if (item->have_guarded_conds())
2203
2220
    {
2204
2221
      /*
2207
2224
        pushed down into the subquery. Those optimizations are ref[_or_null]
2208
2225
        acceses. Change them to be full table scans.
2209
2226
      */
2210
 
      for (uint32_t i=join->const_tables ; i < join->tables ; i++)
 
2227
      for (uint i=join->const_tables ; i < join->tables ; i++)
2211
2228
      {
2212
 
        JoinTable *tab=join->join_tab+i;
 
2229
        JOIN_TAB *tab=join->join_tab+i;
2213
2230
        if (tab && tab->keyuse)
2214
2231
        {
2215
 
          for (uint32_t key_part= 0;
2216
 
               key_part < tab->ref.key_parts;
2217
 
               key_part++)
 
2232
          for (uint i= 0; i < tab->ref.key_parts; i++)
2218
2233
          {
2219
 
            bool *cond_guard= tab->ref.cond_guards[key_part];
 
2234
            bool *cond_guard= tab->ref.cond_guards[i];
2220
2235
            if (cond_guard && !*cond_guard)
2221
2236
            {
2222
2237
              /* Change the access method to full table scan */
2224
2239
              tab->save_read_record= tab->read_record.read_record;
2225
2240
              tab->read_first_record= init_read_record_seq;
2226
2241
              tab->read_record.record= tab->table->record[0];
2227
 
              tab->read_record.session= join->session;
2228
 
              tab->read_record.ref_length= tab->table->cursor->ref_length;
 
2242
              tab->read_record.thd= join->thd;
 
2243
              tab->read_record.ref_length= tab->table->file->ref_length;
2229
2244
              *(last_changed_tab++)= tab;
2230
2245
              break;
2231
2246
            }
2233
2248
        }
2234
2249
      }
2235
2250
    }
2236
 
 
 
2251
    
2237
2252
    join->exec();
2238
2253
 
2239
2254
    /* Enable the optimizations back */
2240
 
    for (JoinTable **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
 
2255
    for (JOIN_TAB **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
2241
2256
    {
2242
 
      JoinTable *tab= *ptab;
 
2257
      JOIN_TAB *tab= *ptab;
2243
2258
      tab->read_record.record= 0;
2244
2259
      tab->read_record.ref_length= 0;
2245
 
      tab->read_first_record= tab->save_read_first_record;
 
2260
      tab->read_first_record= tab->save_read_first_record; 
2246
2261
      tab->read_record.read_record= tab->save_read_record;
2247
2262
    }
2248
2263
    executed= 1;
2249
 
    session->where= save_where;
2250
 
    session->lex->current_select= save_select;
2251
 
    return(join->error||session->is_fatal_error);
 
2264
    thd->where= save_where;
 
2265
    thd->lex->current_select= save_select;
 
2266
    DBUG_RETURN(join->error||thd->is_fatal_error);
2252
2267
  }
2253
 
  session->where= save_where;
2254
 
  session->lex->current_select= save_select;
2255
 
  return(0);
 
2268
  thd->where= save_where;
 
2269
  thd->lex->current_select= save_select;
 
2270
  DBUG_RETURN(0);
2256
2271
}
2257
2272
 
2258
2273
int subselect_union_engine::exec()
2259
2274
{
2260
 
  char const *save_where= session->where;
 
2275
  char const *save_where= thd->where;
2261
2276
  int res= unit->exec();
2262
 
  session->where= save_where;
 
2277
  thd->where= save_where;
2263
2278
  return res;
2264
2279
}
2265
2280
 
2266
2281
 
2267
2282
/*
2268
2283
  Search for at least one row satisfying select condition
2269
 
 
 
2284
 
2270
2285
  SYNOPSIS
2271
2286
    subselect_uniquesubquery_engine::scan_table()
2272
2287
 
2273
2288
  DESCRIPTION
2274
2289
    Scan the table using sequential access until we find at least one row
2275
2290
    satisfying select condition.
2276
 
 
2277
 
    The caller must set this->empty_result_set=false before calling this
2278
 
    function. This function will set it to true if it finds a matching row.
 
2291
    
 
2292
    The caller must set this->empty_result_set=FALSE before calling this
 
2293
    function. This function will set it to TRUE if it finds a matching row.
2279
2294
 
2280
2295
  RETURN
2281
 
    false - OK
2282
 
    true  - Error
 
2296
    FALSE - OK
 
2297
    TRUE  - Error
2283
2298
*/
2284
2299
 
2285
2300
int subselect_uniquesubquery_engine::scan_table()
2286
2301
{
2287
2302
  int error;
2288
 
  Table *table= tab->table;
2289
 
 
2290
 
  if (table->cursor->inited)
2291
 
    table->cursor->endIndexScan();
2292
 
 
2293
 
  table->cursor->startTableScan(1);
2294
 
  table->cursor->extra_opt(HA_EXTRA_CACHE,
2295
 
                           current_session->variables.read_buff_size);
 
2303
  TABLE *table= tab->table;
 
2304
  DBUG_ENTER("subselect_uniquesubquery_engine::scan_table");
 
2305
 
 
2306
  if (table->file->inited)
 
2307
    table->file->ha_index_end();
 
2308
 
 
2309
  table->file->ha_rnd_init(1);
 
2310
  table->file->extra_opt(HA_EXTRA_CACHE,
 
2311
                         current_thd->variables.read_buff_size);
2296
2312
  table->null_row= 0;
2297
2313
  for (;;)
2298
2314
  {
2299
 
    error=table->cursor->rnd_next(table->record[0]);
 
2315
    error=table->file->rnd_next(table->record[0]);
2300
2316
    if (error && error != HA_ERR_END_OF_FILE)
2301
2317
    {
2302
 
      error= table->report_error(error);
 
2318
      error= report_error(table, error);
2303
2319
      break;
2304
2320
    }
2305
2321
    /* No more rows */
2308
2324
 
2309
2325
    if (!cond || cond->val_int())
2310
2326
    {
2311
 
      empty_result_set= false;
 
2327
      empty_result_set= FALSE;
2312
2328
      break;
2313
2329
    }
2314
2330
  }
2315
2331
 
2316
 
  table->cursor->endTableScan();
2317
 
  return(error != 0);
 
2332
  table->file->ha_rnd_end();
 
2333
  DBUG_RETURN(error != 0);
2318
2334
}
2319
2335
 
2320
2336
 
2328
2344
    Copy ref key and check for null parts in it.
2329
2345
    Depending on the nullability and conversion problems this function
2330
2346
    recognizes and processes the following states :
2331
 
      1. Partial match on top level. This means IN has a value of false
 
2347
      1. Partial match on top level. This means IN has a value of FALSE
2332
2348
         regardless of the data in the subquery table.
2333
2349
         Detected by finding a NULL in the left IN operand of a top level
2334
2350
         expression.
2335
 
         We may actually skip reading the subquery, so return true to skip
 
2351
         We may actually skip reading the subquery, so return TRUE to skip
2336
2352
         the table scan in subselect_uniquesubquery_engine::exec and make
2337
 
         the value of the IN predicate a NULL (that is equal to false on
 
2353
         the value of the IN predicate a NULL (that is equal to FALSE on
2338
2354
         top level).
2339
2355
      2. No exact match when IN is nested inside another predicate.
2340
2356
         Detected by finding a NULL in the left IN operand when IN is not
2341
2357
         a top level predicate.
2342
2358
         We cannot have an exact match. But we must proceed further with a
2343
2359
         table scan to find out if it's a partial match (and IN has a value
2344
 
         of NULL) or no match (and IN has a value of false).
2345
 
         So we return false to continue with the scan and see if there are
 
2360
         of NULL) or no match (and IN has a value of FALSE).
 
2361
         So we return FALSE to continue with the scan and see if there are
2346
2362
         any record that would constitute a partial match (as we cannot
2347
2363
         determine that from the index).
2348
2364
      3. Error converting the left IN operand to the column type of the
2349
2365
         right IN operand. This counts as no match (and IN has the value of
2350
 
         false). We mark the subquery table cursor as having no more rows
 
2366
         FALSE). We mark the subquery table cursor as having no more rows
2351
2367
         (to ensure that the processing that follows will not find a match)
2352
 
         and return false, so IN is not treated as returning NULL.
 
2368
         and return FALSE, so IN is not treated as returning NULL.
2353
2369
 
2354
2370
 
2355
2371
  RETURN
2356
 
    false - The value of the IN predicate is not known. Proceed to find the
 
2372
    FALSE - The value of the IN predicate is not known. Proceed to find the
2357
2373
            value of the IN predicate using the determined values of
2358
2374
            null_keypart and table->status.
2359
 
    true  - IN predicate has a value of NULL. Stop the processing right there
 
2375
    TRUE  - IN predicate has a value of NULL. Stop the processing right there
2360
2376
            and return NULL to the outer predicates.
2361
2377
*/
2362
2378
 
2363
2379
bool subselect_uniquesubquery_engine::copy_ref_key()
2364
2380
{
2365
 
  for (StoredKey **copy= tab->ref.key_copy ; *copy ; copy++)
 
2381
  DBUG_ENTER("subselect_uniquesubquery_engine::copy_ref_key");
 
2382
 
 
2383
  for (store_key **copy= tab->ref.key_copy ; *copy ; copy++)
2366
2384
  {
2367
 
    StoredKey::store_key_result store_res= (*copy)->copy();
 
2385
    enum store_key::store_key_result store_res;
 
2386
    store_res= (*copy)->copy();
2368
2387
    tab->ref.key_err= store_res;
2369
2388
 
2370
2389
    /*
2382
2401
      if (top_level)
2383
2402
      {
2384
2403
        /* Partial match on top level */
2385
 
        return(1);
 
2404
        DBUG_RETURN(1);
2386
2405
      }
2387
2406
      else
2388
2407
      {
2392
2411
    }
2393
2412
 
2394
2413
    /*
2395
 
      Check if the error is equal to STORE_KEY_FATAL. This is not expressed
2396
 
      using the StoredKey::store_key_result enum because ref.key_err is a
2397
 
      boolean and we want to detect both true and STORE_KEY_FATAL from the
2398
 
      space of the union of the values of [true, false] and
2399
 
      StoredKey::store_key_result.
 
2414
      Check if the error is equal to STORE_KEY_FATAL. This is not expressed 
 
2415
      using the store_key::store_key_result enum because ref.key_err is a 
 
2416
      boolean and we want to detect both TRUE and STORE_KEY_FATAL from the 
 
2417
      space of the union of the values of [TRUE, FALSE] and 
 
2418
      store_key::store_key_result.  
2400
2419
      TODO: fix the variable an return types.
2401
2420
    */
2402
 
    if (store_res == StoredKey::STORE_KEY_FATAL)
 
2421
    if (store_res == store_key::STORE_KEY_FATAL)
2403
2422
    {
2404
2423
      /*
2405
2424
       Error converting the left IN operand to the column type of the right
2406
 
       IN operand.
 
2425
       IN operand. 
2407
2426
      */
2408
2427
      tab->table->status= STATUS_NOT_FOUND;
2409
2428
      break;
2410
2429
    }
2411
2430
  }
2412
 
  return(0);
 
2431
  DBUG_RETURN(0);
2413
2432
}
2414
2433
 
2415
2434
 
2424
2443
    If some part of the lookup key is NULL, then we're evaluating
2425
2444
      NULL IN (SELECT ... )
2426
2445
    This is a special case, we don't need to search for NULL in the table,
2427
 
    instead, the result value is
 
2446
    instead, the result value is 
2428
2447
      - NULL  if select produces empty row set
2429
 
      - false otherwise.
 
2448
      - FALSE otherwise.
2430
2449
 
2431
 
    In some cases (IN subselect is a top level item, i.e. abort_on_null==true)
2432
 
    the caller doesn't distinguish between NULL and false result and we just
2433
 
    return false.
2434
 
    Otherwise we make a full table scan to see if there is at least one
 
2450
    In some cases (IN subselect is a top level item, i.e. abort_on_null==TRUE)
 
2451
    the caller doesn't distinguish between NULL and FALSE result and we just
 
2452
    return FALSE. 
 
2453
    Otherwise we make a full table scan to see if there is at least one 
2435
2454
    matching row.
2436
 
 
 
2455
    
2437
2456
    The result of this function (info about whether a row was found) is
2438
2457
    stored in this->empty_result_set.
2439
2458
  NOTE
2440
 
 
 
2459
    
2441
2460
  RETURN
2442
 
    false - ok
2443
 
    true  - an error occured while scanning
 
2461
    FALSE - ok
 
2462
    TRUE  - an error occured while scanning
2444
2463
*/
2445
2464
 
2446
2465
int subselect_uniquesubquery_engine::exec()
2447
2466
{
 
2467
  DBUG_ENTER("subselect_uniquesubquery_engine::exec");
2448
2468
  int error;
2449
 
  Table *table= tab->table;
2450
 
  empty_result_set= true;
 
2469
  TABLE *table= tab->table;
 
2470
  empty_result_set= TRUE;
2451
2471
  table->status= 0;
2452
 
 
 
2472
 
2453
2473
  /* TODO: change to use of 'full_scan' here? */
2454
2474
  if (copy_ref_key())
2455
 
    return(1);
 
2475
    DBUG_RETURN(1);
2456
2476
  if (table->status)
2457
2477
  {
2458
 
    /*
2459
 
      We know that there will be no rows even if we scan.
 
2478
    /* 
 
2479
      We know that there will be no rows even if we scan. 
2460
2480
      Can be set in copy_ref_key.
2461
2481
    */
2462
2482
    ((Item_in_subselect *) item)->value= 0;
2463
 
    return(0);
 
2483
    DBUG_RETURN(0);
2464
2484
  }
2465
2485
 
2466
2486
  if (null_keypart)
2467
 
    return(scan_table());
2468
 
 
2469
 
  if (!table->cursor->inited)
2470
 
    table->cursor->startIndexScan(tab->ref.key, 0);
2471
 
  error= table->cursor->index_read_map(table->record[0],
 
2487
    DBUG_RETURN(scan_table());
 
2488
 
 
2489
  if (!table->file->inited)
 
2490
    table->file->ha_index_init(tab->ref.key, 0);
 
2491
  error= table->file->index_read_map(table->record[0],
2472
2492
                                     tab->ref.key_buff,
2473
2493
                                     make_prev_keypart_map(tab->ref.key_parts),
2474
2494
                                     HA_READ_KEY_EXACT);
 
2495
  DBUG_PRINT("info", ("lookup result: %i", error));
2475
2496
  if (error &&
2476
2497
      error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
2477
 
    error= table->report_error(error);
 
2498
    error= report_error(table, error);
2478
2499
  else
2479
2500
  {
2480
2501
    error= 0;
2482
2503
    if (!table->status && (!cond || cond->val_int()))
2483
2504
    {
2484
2505
      ((Item_in_subselect *) item)->value= 1;
2485
 
      empty_result_set= false;
 
2506
      empty_result_set= FALSE;
2486
2507
    }
2487
2508
    else
2488
2509
      ((Item_in_subselect *) item)->value= 0;
2489
2510
  }
2490
2511
 
2491
 
  return(error != 0);
 
2512
  DBUG_RETURN(error != 0);
2492
2513
}
2493
2514
 
2494
2515
 
2497
2518
 
2498
2519
  SYNOPSIS
2499
2520
    subselect_indexsubquery_engine:exec()
2500
 
      full_scan
 
2521
      full_scan 
2501
2522
 
2502
2523
  DESCRIPTION
2503
2524
    The engine is used to resolve subqueries in form
2504
2525
 
2505
 
      oe IN (SELECT key FROM tbl WHERE subq_where)
 
2526
      oe IN (SELECT key FROM tbl WHERE subq_where) 
2506
2527
 
2507
 
    The value of the predicate is calculated as follows:
 
2528
    The value of the predicate is calculated as follows: 
2508
2529
    1. If oe IS NULL, this is a special case, do a full table scan on
2509
 
       table tbl and search for row that satisfies subq_where. If such
2510
 
       row is found, return NULL, otherwise return false.
 
2530
       table tbl and search for row that satisfies subq_where. If such 
 
2531
       row is found, return NULL, otherwise return FALSE.
2511
2532
    2. Make an index lookup via key=oe, search for a row that satisfies
2512
 
       subq_where. If found, return true.
2513
 
    3. If check_null==true, make another lookup via key=NULL, search for a
 
2533
       subq_where. If found, return TRUE.
 
2534
    3. If check_null==TRUE, make another lookup via key=NULL, search for a 
2514
2535
       row that satisfies subq_where. If found, return NULL, otherwise
2515
 
       return false.
 
2536
       return FALSE.
2516
2537
 
2517
2538
  TODO
2518
2539
    The step #1 can be optimized further when the index has several key
2519
2540
    parts. Consider a subquery:
2520
 
 
 
2541
    
2521
2542
      (oe1, oe2) IN (SELECT keypart1, keypart2 FROM tbl WHERE subq_where)
2522
2543
 
2523
2544
    and suppose we need to evaluate it for {oe1, oe2}=={const1, NULL}.
2527
2548
      SELECT keypart1, keypart2 FROM tbl WHERE subq_where            (1)
2528
2549
 
2529
2550
    and checking if it has produced any matching rows, evaluate
2530
 
 
 
2551
    
2531
2552
      SELECT keypart2 FROM tbl WHERE subq_where AND keypart1=const1  (2)
2532
2553
 
2533
 
    If this query produces a row, the result is NULL (as we're evaluating
 
2554
    If this query produces a row, the result is NULL (as we're evaluating 
2534
2555
    "(const1, NULL) IN { (const1, X), ... }", which has a value of UNKNOWN,
2535
 
    i.e. NULL).  If the query produces no rows, the result is false.
 
2556
    i.e. NULL).  If the query produces no rows, the result is FALSE.
2536
2557
 
2537
2558
    We currently evaluate (1) by doing a full table scan. (2) can be
2538
2559
    evaluated by doing a "ref" scan on "keypart1=const1", which can be much
2546
2567
 
2547
2568
int subselect_indexsubquery_engine::exec()
2548
2569
{
 
2570
  DBUG_ENTER("subselect_indexsubquery_engine::exec");
2549
2571
  int error;
2550
2572
  bool null_finding= 0;
2551
 
  Table *table= tab->table;
 
2573
  TABLE *table= tab->table;
2552
2574
 
2553
2575
  ((Item_in_subselect *) item)->value= 0;
2554
 
  empty_result_set= true;
 
2576
  empty_result_set= TRUE;
2555
2577
  null_keypart= 0;
2556
2578
  table->status= 0;
2557
2579
 
2564
2586
 
2565
2587
  /* Copy the ref key and check for nulls... */
2566
2588
  if (copy_ref_key())
2567
 
    return(1);
 
2589
    DBUG_RETURN(1);
2568
2590
 
2569
2591
  if (table->status)
2570
2592
  {
2571
 
    /*
2572
 
      We know that there will be no rows even if we scan.
 
2593
    /* 
 
2594
      We know that there will be no rows even if we scan. 
2573
2595
      Can be set in copy_ref_key.
2574
2596
    */
2575
2597
    ((Item_in_subselect *) item)->value= 0;
2576
 
    return(0);
 
2598
    DBUG_RETURN(0);
2577
2599
  }
2578
2600
 
2579
2601
  if (null_keypart)
2580
 
    return(scan_table());
 
2602
    DBUG_RETURN(scan_table());
2581
2603
 
2582
 
  if (!table->cursor->inited)
2583
 
    table->cursor->startIndexScan(tab->ref.key, 1);
2584
 
  error= table->cursor->index_read_map(table->record[0],
 
2604
  if (!table->file->inited)
 
2605
    table->file->ha_index_init(tab->ref.key, 1);
 
2606
  error= table->file->index_read_map(table->record[0],
2585
2607
                                     tab->ref.key_buff,
2586
2608
                                     make_prev_keypart_map(tab->ref.key_parts),
2587
2609
                                     HA_READ_KEY_EXACT);
2588
2610
  if (error &&
2589
2611
      error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
2590
 
    error= table->report_error(error);
 
2612
    error= report_error(table, error);
2591
2613
  else
2592
2614
  {
2593
2615
    for (;;)
2598
2620
      {
2599
2621
        if ((!cond || cond->val_int()) && (!having || having->val_int()))
2600
2622
        {
2601
 
          empty_result_set= false;
 
2623
          empty_result_set= FALSE;
2602
2624
          if (null_finding)
2603
2625
            ((Item_in_subselect *) item)->was_null= 1;
2604
2626
          else
2605
2627
            ((Item_in_subselect *) item)->value= 1;
2606
2628
          break;
2607
2629
        }
2608
 
        error= table->cursor->index_next_same(table->record[0],
 
2630
        error= table->file->index_next_same(table->record[0],
2609
2631
                                            tab->ref.key_buff,
2610
2632
                                            tab->ref.key_length);
2611
2633
        if (error && error != HA_ERR_END_OF_FILE)
2612
2634
        {
2613
 
          error= table->report_error(error);
 
2635
          error= report_error(table, error);
2614
2636
          break;
2615
2637
        }
2616
2638
      }
2626
2648
      }
2627
2649
    }
2628
2650
  }
2629
 
  return(error != 0);
 
2651
  DBUG_RETURN(error != 0);
2630
2652
}
2631
2653
 
2632
2654
 
2633
 
uint32_t subselect_single_select_engine::cols()
 
2655
uint subselect_single_select_engine::cols()
2634
2656
{
2635
2657
  return select_lex->item_list.elements;
2636
2658
}
2637
2659
 
2638
2660
 
2639
 
uint32_t subselect_union_engine::cols()
 
2661
uint subselect_union_engine::cols()
2640
2662
{
2641
2663
  return unit->types.elements;
2642
2664
}
2643
2665
 
2644
2666
 
2645
 
bool subselect_single_select_engine::uncacheable()
2646
 
{
2647
 
  return select_lex->uncacheable.any();
2648
 
}
2649
 
 
2650
 
 
2651
 
bool subselect_single_select_engine::uncacheable(uint32_t bit_pos)
2652
 
{
2653
 
  return select_lex->uncacheable.test(bit_pos);
2654
 
}
2655
 
 
2656
 
 
2657
 
bool subselect_union_engine::uncacheable()
2658
 
{
2659
 
  return unit->uncacheable.any();
2660
 
}
2661
 
 
2662
 
 
2663
 
bool subselect_union_engine::uncacheable(uint32_t bit_pos)
2664
 
{
2665
 
  return unit->uncacheable.test(bit_pos);
 
2667
uint8 subselect_single_select_engine::uncacheable()
 
2668
{
 
2669
  return select_lex->uncacheable;
 
2670
}
 
2671
 
 
2672
 
 
2673
uint8 subselect_union_engine::uncacheable()
 
2674
{
 
2675
  return unit->uncacheable;
2666
2676
}
2667
2677
 
2668
2678
 
2680
2690
void subselect_uniquesubquery_engine::exclude()
2681
2691
{
2682
2692
  //this never should be called
2683
 
  assert(0);
 
2693
  DBUG_ASSERT(0);
2684
2694
}
2685
2695
 
2686
2696
 
2687
 
table_map subselect_engine::calc_const_tables(TableList *table)
 
2697
table_map subselect_engine::calc_const_tables(TABLE_LIST *table)
2688
2698
{
2689
2699
  table_map map= 0;
2690
2700
  for (; table; table= table->next_leaf)
2691
2701
  {
2692
 
    Table *tbl= table->table;
 
2702
    TABLE *tbl= table->table;
2693
2703
    if (tbl && tbl->const_table)
2694
2704
      map|= tbl->map;
2695
2705
  }
2699
2709
 
2700
2710
table_map subselect_single_select_engine::upper_select_const_tables()
2701
2711
{
2702
 
  return calc_const_tables((TableList *) select_lex->outer_select()->
 
2712
  return calc_const_tables((TABLE_LIST *) select_lex->outer_select()->
2703
2713
                           leaf_tables);
2704
2714
}
2705
2715
 
2706
2716
 
2707
2717
table_map subselect_union_engine::upper_select_const_tables()
2708
2718
{
2709
 
  return calc_const_tables((TableList *) unit->outer_select()->leaf_tables);
 
2719
  return calc_const_tables((TABLE_LIST *) unit->outer_select()->leaf_tables);
2710
2720
}
2711
2721
 
2712
2722
 
2713
2723
void subselect_single_select_engine::print(String *str,
2714
2724
                                           enum_query_type query_type)
2715
2725
{
2716
 
  select_lex->print(session, str, query_type);
 
2726
  select_lex->print(thd, str, query_type);
2717
2727
}
2718
2728
 
2719
2729
 
2726
2736
void subselect_uniquesubquery_engine::print(String *str,
2727
2737
                                            enum_query_type query_type)
2728
2738
{
2729
 
  char *table_name= const_cast<char *>(tab->table->getShare()->getTableName());
 
2739
  char *table_name= tab->table->s->table_name.str;
2730
2740
  str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2731
2741
  tab->ref.items[0]->print(str, query_type);
2732
2742
  str->append(STRING_WITH_LEN(" in "));
2733
 
  if (tab->table->getShare()->isTemporaryCategory())
 
2743
  if (tab->table->s->table_category == TABLE_CATEGORY_TEMPORARY)
2734
2744
  {
2735
2745
    /*
2736
2746
      Temporary tables' names change across runs, so they can't be used for
2739
2749
    str->append(STRING_WITH_LEN("<temporary table>"));
2740
2750
  }
2741
2751
  else
2742
 
    str->append(table_name, tab->table->getShare()->getTableNameSize());
2743
 
  KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
 
2752
    str->append(table_name, tab->table->s->table_name.length);
 
2753
  KEY *key_info= tab->table->key_info+ tab->ref.key;
2744
2754
  str->append(STRING_WITH_LEN(" on "));
2745
2755
  str->append(key_info->name);
2746
2756
  if (cond)
2760
2770
{
2761
2771
  KEY *key_info= tab->table->key_info + tab->ref.key;
2762
2772
  str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2763
 
  for (uint32_t i= 0; i < key_info->key_parts; i++)
 
2773
  for (uint i= 0; i < key_info->key_parts; i++)
2764
2774
    tab->ref.items[i]->print(str);
2765
2775
  str->append(STRING_WITH_LEN(" in "));
2766
 
  str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
 
2776
  str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2767
2777
  str->append(STRING_WITH_LEN(" on "));
2768
2778
  str->append(key_info->name);
2769
2779
  if (cond)
2781
2791
  str->append(STRING_WITH_LEN("<index_lookup>("));
2782
2792
  tab->ref.items[0]->print(str, query_type);
2783
2793
  str->append(STRING_WITH_LEN(" in "));
2784
 
  str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
2785
 
  KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
 
2794
  str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
 
2795
  KEY *key_info= tab->table->key_info+ tab->ref.key;
2786
2796
  str->append(STRING_WITH_LEN(" on "));
2787
2797
  str->append(key_info->name);
2788
2798
  if (check_null)
2807
2817
  @param res            new select_result object
2808
2818
 
2809
2819
  @retval
2810
 
    false OK
 
2820
    FALSE OK
2811
2821
  @retval
2812
 
    true  error
 
2822
    TRUE  error
2813
2823
*/
2814
2824
 
2815
2825
bool subselect_single_select_engine::change_result(Item_subselect *si,
2828
2838
  @param res            new select_result object
2829
2839
 
2830
2840
  @retval
2831
 
    false OK
 
2841
    FALSE OK
2832
2842
  @retval
2833
 
    true  error
 
2843
    TRUE  error
2834
2844
*/
2835
2845
 
2836
2846
bool subselect_union_engine::change_result(Item_subselect *si,
2850
2860
  @param res            new select_result object
2851
2861
 
2852
2862
  @retval
2853
 
    false OK
 
2863
    FALSE OK
2854
2864
  @retval
2855
 
    true  error
 
2865
    TRUE  error
2856
2866
*/
2857
2867
 
2858
 
bool subselect_uniquesubquery_engine::change_result(Item_subselect *,
2859
 
                                                    select_result_interceptor *)
 
2868
bool subselect_uniquesubquery_engine::change_result(Item_subselect *si,
 
2869
                                                    select_result_interceptor *res)
2860
2870
{
2861
 
  assert(0);
2862
 
  return true;
 
2871
  DBUG_ASSERT(0);
 
2872
  return TRUE;
2863
2873
}
2864
2874
 
2865
2875
 
2867
2877
  Report about presence of tables in subquery.
2868
2878
 
2869
2879
  @retval
2870
 
    true  there are not tables used in subquery
 
2880
    TRUE  there are not tables used in subquery
2871
2881
  @retval
2872
 
    false there are some tables in subquery
 
2882
    FALSE there are some tables in subquery
2873
2883
*/
2874
2884
bool subselect_single_select_engine::no_tables()
2875
2885
{
2884
2894
    subselect_single_select_engine::may_be_null()
2885
2895
 
2886
2896
  RETURN
2887
 
    false  can guarantee that the subquery never return NULL
2888
 
    true   otherwise
 
2897
    FALSE  can guarantee that the subquery never return NULL
 
2898
    TRUE   otherwise
2889
2899
*/
2890
2900
bool subselect_single_select_engine::may_be_null()
2891
2901
{
2897
2907
  Report about presence of tables in subquery.
2898
2908
 
2899
2909
  @retval
2900
 
    true  there are not tables used in subquery
 
2910
    TRUE  there are not tables used in subquery
2901
2911
  @retval
2902
 
    false there are some tables in subquery
 
2912
    FALSE there are some tables in subquery
2903
2913
*/
2904
2914
bool subselect_union_engine::no_tables()
2905
2915
{
2906
 
  for (Select_Lex *sl= unit->first_select(); sl; sl= sl->next_select())
 
2916
  for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
2907
2917
  {
2908
2918
    if (sl->table_list.elements)
2909
 
      return false;
 
2919
      return FALSE;
2910
2920
  }
2911
 
  return true;
 
2921
  return TRUE;
2912
2922
}
2913
2923
 
2914
2924
 
2916
2926
  Report about presence of tables in subquery.
2917
2927
 
2918
2928
  @retval
2919
 
    true  there are not tables used in subquery
 
2929
    TRUE  there are not tables used in subquery
2920
2930
  @retval
2921
 
    false there are some tables in subquery
 
2931
    FALSE there are some tables in subquery
2922
2932
*/
2923
2933
 
2924
2934
bool subselect_uniquesubquery_engine::no_tables()
2942
2952
    temporary table has one hash index on all its columns.
2943
2953
  - Create a new result sink that sends the result stream of the subquery to
2944
2954
    the temporary table,
2945
 
  - Create and initialize a new JoinTable, and TABLE_REF objects to perform
 
2955
  - Create and initialize a new JOIN_TAB, and TABLE_REF objects to perform
2946
2956
    lookups into the indexed temporary table.
2947
2957
 
2948
2958
  @notice:
2949
2959
    Currently Item_subselect::init() already chooses and creates at parse
2950
2960
    time an engine with a corresponding JOIN to execute the subquery.
2951
2961
 
2952
 
  @retval true  if error
2953
 
  @retval false otherwise
 
2962
  @retval TRUE  if error
 
2963
  @retval FALSE otherwise
2954
2964
*/
2955
2965
 
2956
2966
bool subselect_hash_sj_engine::init_permanent(List<Item> *tmp_columns)
2958
2968
  /* The result sink where we will materialize the subquery result. */
2959
2969
  select_union  *tmp_result_sink;
2960
2970
  /* The table into which the subquery is materialized. */
2961
 
  Table         *tmp_table;
2962
 
  KeyInfo           *tmp_key; /* The only index on the temporary table. */
2963
 
  uint32_t          tmp_key_parts; /* Number of keyparts in tmp_key. */
 
2971
  TABLE         *tmp_table;
 
2972
  KEY           *tmp_key; /* The only index on the temporary table. */
 
2973
  uint          tmp_key_parts; /* Number of keyparts in tmp_key. */
2964
2974
  Item_in_subselect *item_in= (Item_in_subselect *) item;
2965
2975
 
 
2976
  DBUG_ENTER("subselect_hash_sj_engine::init_permanent");
 
2977
 
2966
2978
  /* 1. Create/initialize materialization related objects. */
2967
2979
 
2968
2980
  /*
2971
2983
    managed (created/filled/etc) internally by the interceptor.
2972
2984
  */
2973
2985
  if (!(tmp_result_sink= new select_union))
2974
 
    return(true);
2975
 
 
 
2986
    DBUG_RETURN(TRUE);
2976
2987
  if (tmp_result_sink->create_result_table(
2977
 
                         session, tmp_columns, true,
2978
 
                         session->options | TMP_TABLE_ALL_COLUMNS,
2979
 
                         "materialized subselect"))
2980
 
    return(true);
 
2988
                         thd, tmp_columns, TRUE,
 
2989
                         thd->options | TMP_TABLE_ALL_COLUMNS,
 
2990
                         "materialized subselect", TRUE))
 
2991
    DBUG_RETURN(TRUE);
2981
2992
 
2982
2993
  tmp_table= tmp_result_sink->table;
2983
2994
  tmp_key= tmp_table->key_info;
2990
3001
     table since it will not be used, and tell the caller we failed to
2991
3002
     initialize the engine.
2992
3003
  */
2993
 
  if (tmp_table->getShare()->sizeKeys() == 0)
 
3004
  if (tmp_table->s->keys == 0)
2994
3005
  {
2995
 
    assert(tmp_table->getShare()->db_type() == myisam_engine);
2996
 
    assert(
2997
 
      tmp_table->getShare()->uniques ||
2998
 
      tmp_table->key_info->key_length >= tmp_table->cursor->getEngine()->max_key_length() ||
2999
 
      tmp_table->key_info->key_parts > tmp_table->cursor->getEngine()->max_key_parts());
3000
 
    tmp_table= NULL;
 
3006
    DBUG_ASSERT(tmp_table->s->db_type() == myisam_hton);
 
3007
    DBUG_ASSERT(
 
3008
      tmp_table->s->uniques ||
 
3009
      tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
 
3010
      tmp_table->key_info->key_parts > tmp_table->file->max_key_parts());
 
3011
    free_tmp_table(thd, tmp_table);
3001
3012
    delete result;
3002
3013
    result= NULL;
3003
 
    return(true);
 
3014
    DBUG_RETURN(TRUE);
3004
3015
  }
3005
3016
  result= tmp_result_sink;
3006
3017
 
3008
3019
    Make sure there is only one index on the temp table, and it doesn't have
3009
3020
    the extra key part created when s->uniques > 0.
3010
3021
  */
3011
 
  assert(tmp_table->getShare()->sizeKeys() == 1 && tmp_columns->elements == tmp_key_parts);
 
3022
  DBUG_ASSERT(tmp_table->s->keys == 1 && tmp_columns->elements == tmp_key_parts);
3012
3023
 
3013
3024
 
3014
3025
  /* 2. Create/initialize execution related objects. */
3015
3026
 
3016
3027
  /*
3017
 
    Create and initialize the JoinTable that represents an index lookup
 
3028
    Create and initialize the JOIN_TAB that represents an index lookup
3018
3029
    plan operator into the materialized subquery result. Notice that:
3019
 
    - this JoinTable has no corresponding JOIN (and doesn't need one), and
 
3030
    - this JOIN_TAB has no corresponding JOIN (and doesn't need one), and
3020
3031
    - here we initialize only those members that are used by
3021
3032
      subselect_uniquesubquery_engine, so these objects are incomplete.
3022
 
  */
3023
 
  if (!(tab= (JoinTable*) session->alloc(sizeof(JoinTable))))
3024
 
    return(true);
 
3033
  */ 
 
3034
  if (!(tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
 
3035
    DBUG_RETURN(TRUE);
3025
3036
  tab->table= tmp_table;
3026
3037
  tab->ref.key= 0; /* The only temp table index. */
3027
3038
  tab->ref.key_length= tmp_key->key_length;
3028
3039
  if (!(tab->ref.key_buff=
3029
 
        (unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
 
3040
        (uchar*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3030
3041
      !(tab->ref.key_copy=
3031
 
        (StoredKey**) session->alloc((sizeof(StoredKey*) *
 
3042
        (store_key**) thd->alloc((sizeof(store_key*) *
3032
3043
                                  (tmp_key_parts + 1)))) ||
3033
3044
      !(tab->ref.items=
3034
 
        (Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
3035
 
    return(true);
3036
 
 
3037
 
  KeyPartInfo *cur_key_part= tmp_key->key_part;
3038
 
  StoredKey **ref_key= tab->ref.key_copy;
3039
 
  unsigned char *cur_ref_buff= tab->ref.key_buff;
3040
 
 
3041
 
  for (uint32_t i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
 
3045
        (Item**) thd->alloc(sizeof(Item*) * tmp_key_parts)))
 
3046
    DBUG_RETURN(TRUE);
 
3047
 
 
3048
  KEY_PART_INFO *cur_key_part= tmp_key->key_part;
 
3049
  store_key **ref_key= tab->ref.key_copy;
 
3050
  uchar *cur_ref_buff= tab->ref.key_buff;
 
3051
  
 
3052
  for (uint i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3042
3053
  {
3043
3054
    tab->ref.items[i]= item_in->left_expr->element_index(i);
3044
3055
    int null_count= test(cur_key_part->field->real_maybe_null());
3045
 
    *ref_key= new store_key_item(session, cur_key_part->field,
 
3056
    *ref_key= new store_key_item(thd, cur_key_part->field,
3046
3057
                                 /* TODO:
3047
3058
                                    the NULL byte is taken into account in
3048
3059
                                    cur_key_part->store_length, so instead of
3058
3069
  tab->ref.key_err= 1;
3059
3070
  tab->ref.key_parts= tmp_key_parts;
3060
3071
 
3061
 
  return(false);
 
3072
  DBUG_RETURN(FALSE);
3062
3073
}
3063
3074
 
3064
3075
 
3066
3077
  Initialize members of the engine that need to be re-initilized at each
3067
3078
  execution.
3068
3079
 
3069
 
  @retval true  if a memory allocation error occurred
3070
 
  @retval false if success
 
3080
  @retval TRUE  if a memory allocation error occurred
 
3081
  @retval FALSE if success
3071
3082
*/
3072
3083
 
3073
3084
bool subselect_hash_sj_engine::init_runtime()
3080
3091
  /* Let our engine reuse this query plan for materialization. */
3081
3092
  materialize_join= materialize_engine->join;
3082
3093
  materialize_join->change_result(result);
3083
 
  return false;
 
3094
  return FALSE;
3084
3095
}
3085
3096
 
3086
3097
 
3088
3099
{
3089
3100
  delete result;
3090
3101
  if (tab)
3091
 
  {
3092
 
    tab->table= NULL;
3093
 
  }
 
3102
    free_tmp_table(thd, tab->table);
3094
3103
}
3095
3104
 
3096
3105
 
3098
3107
  Cleanup performed after each PS execution.
3099
3108
 
3100
3109
  @detail
3101
 
  Called in the end of Join::prepare for PS from Item_subselect::cleanup.
 
3110
  Called in the end of JOIN::prepare for PS from Item_subselect::cleanup.
3102
3111
*/
3103
3112
 
3104
3113
void subselect_hash_sj_engine::cleanup()
3105
3114
{
3106
 
  is_materialized= false;
 
3115
  is_materialized= FALSE;
3107
3116
  result->cleanup(); /* Resets the temp table as well. */
3108
3117
  materialize_engine->cleanup();
3109
3118
  subselect_uniquesubquery_engine::cleanup();
3117
3126
  If needed materialize the subquery into a temporary table, then
3118
3127
  copmpute the predicate via a lookup into this table.
3119
3128
 
3120
 
  @retval true  if error
3121
 
  @retval false otherwise
 
3129
  @retval TRUE  if error
 
3130
  @retval FALSE otherwise
3122
3131
*/
3123
3132
 
3124
3133
int subselect_hash_sj_engine::exec()
3125
3134
{
3126
3135
  Item_in_subselect *item_in= (Item_in_subselect *) item;
3127
3136
 
 
3137
  DBUG_ENTER("subselect_hash_sj_engine::exec");
 
3138
 
3128
3139
  /*
3129
3140
    Optimize and materialize the subquery during the first execution of
3130
3141
    the subquery predicate.
3132
3143
  if (!is_materialized)
3133
3144
  {
3134
3145
    int res= 0;
3135
 
    Select_Lex *save_select= session->lex->current_select;
3136
 
    session->lex->current_select= materialize_engine->select_lex;
 
3146
    SELECT_LEX *save_select= thd->lex->current_select;
 
3147
    thd->lex->current_select= materialize_engine->select_lex;
3137
3148
    if ((res= materialize_join->optimize()))
3138
3149
      goto err;
3139
3150
    materialize_join->exec();
3140
 
    if ((res= test(materialize_join->error || session->is_fatal_error)))
 
3151
    if ((res= test(materialize_join->error || thd->is_fatal_error)))
3141
3152
      goto err;
3142
3153
 
3143
3154
    /*
3144
3155
      TODO:
3145
3156
      - Unlock all subquery tables as we don't need them. To implement this
3146
 
        we need to add new functionality to Join::join_free that can unlock
 
3157
        we need to add new functionality to JOIN::join_free that can unlock
3147
3158
        all tables in a subquery (and all its subqueries).
3148
3159
      - The temp table used for grouping in the subquery can be freed
3149
3160
        immediately after materialization (yet it's done together with
3150
3161
        unlocking).
3151
3162
     */
3152
 
    is_materialized= true;
 
3163
    is_materialized= TRUE;
3153
3164
    /*
3154
3165
      If the subquery returned no rows, the temporary table is empty, so we know
3155
 
      directly that the result of IN is false. We first update the table
 
3166
      directly that the result of IN is FALSE. We first update the table
3156
3167
      statistics, then we test if the temporary table for the query result is
3157
3168
      empty.
3158
3169
    */
3159
 
    tab->table->cursor->info(HA_STATUS_VARIABLE);
3160
 
    if (!tab->table->cursor->stats.records)
 
3170
    tab->table->file->info(HA_STATUS_VARIABLE);
 
3171
    if (!tab->table->file->stats.records)
3161
3172
    {
3162
 
      empty_result_set= true;
3163
 
      item_in->value= false;
3164
 
      /* TODO: check we need this: item_in->null_value= false; */
3165
 
      return(false);
 
3173
      empty_result_set= TRUE;
 
3174
      item_in->value= FALSE;
 
3175
      /* TODO: check we need this: item_in->null_value= FALSE; */
 
3176
      DBUG_RETURN(FALSE);
3166
3177
    }
3167
3178
    /* Set tmp_param only if its usable, i.e. tmp_param->copy_field != NULL. */
3168
3179
    tmp_param= &(item_in->unit->outer_select()->join->tmp_table_param);
3170
3181
      tmp_param= NULL;
3171
3182
 
3172
3183
err:
3173
 
    session->lex->current_select= save_select;
 
3184
    thd->lex->current_select= save_select;
3174
3185
    if (res)
3175
 
      return(res);
 
3186
      DBUG_RETURN(res);
3176
3187
  }
3177
3188
 
3178
3189
  /*
3179
3190
    Lookup the left IN operand in the hash index of the materialized subquery.
3180
3191
  */
3181
 
  return(subselect_uniquesubquery_engine::exec());
 
3192
  DBUG_RETURN(subselect_uniquesubquery_engine::exec());
3182
3193
}
3183
3194
 
3184
3195
 
3198
3209
           "<the access method for lookups is not yet created>"
3199
3210
         ));
3200
3211
}
3201
 
 
3202
 
} /* namespace drizzled */