~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/subselect.cc

  • Committer: Brian Aker
  • Date: 2009-12-29 01:38:38 UTC
  • mfrom: (1251.1.1 drizzle)
  • Revision ID: brian@gaz-20091229013838-03kb2z5xbqw03ddt
Merge of Diego fix.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 <drizzled/server_includes.h>
 
26
#include "config.h"
 
27
 
 
28
#include <limits.h>
 
29
 
27
30
#include <drizzled/sql_select.h>
28
 
#include <drizzled/drizzled_error_messages.h>
 
31
#include <drizzled/error.h>
 
32
#include <drizzled/item/cache.h>
 
33
#include <drizzled/item/subselect.h>
 
34
#include <drizzled/item/cmpfunc.h>
 
35
#include <drizzled/item/ref_null_helper.h>
 
36
#include <drizzled/cached_item.h>
 
37
#include <drizzled/check_stack_overrun.h>
 
38
#include <drizzled/item/ref_null_helper.h>
 
39
#include <drizzled/item/direct_ref.h>
 
40
 
 
41
using namespace drizzled;
 
42
 
 
43
extern plugin::StorageEngine *myisam_engine;
29
44
 
30
45
inline Item * and_items(Item* cond, Item *item)
31
46
{
32
47
  return (cond? (new Item_cond_and(cond, item)) : item);
33
48
}
34
49
 
35
 
Item_subselect::Item_subselect():
36
 
  Item_result_field(), value_assigned(0), thd(0), substitution(0),
37
 
  engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
38
 
  const_item_cache(1), engine_changed(0), changed(0),
 
50
Item_subselect::Item_subselect() :
 
51
  Item_result_field(),
 
52
  value_assigned(false),
 
53
  session(NULL),
 
54
  substitution(NULL),
 
55
  unit(NULL),
 
56
  engine(NULL),
 
57
  old_engine(NULL),
 
58
  used_tables_cache(0),
 
59
  max_columns(0),
 
60
  parsing_place(NO_MATTER),
 
61
  have_to_be_excluded(false),
 
62
  const_item_cache(true),
 
63
  engine_changed(false),
 
64
  changed(false),
39
65
  is_correlated(false)
40
66
{
41
67
  with_subselect= 1;
48
74
}
49
75
 
50
76
 
51
 
void Item_subselect::init(st_select_lex *select_lex,
 
77
void Item_subselect::init(Select_Lex *select_lex,
52
78
                          select_result_interceptor *result)
53
79
{
54
80
  /*
72
98
  }
73
99
  else
74
100
  {
75
 
    SELECT_LEX *outer_select= unit->outer_select();
 
101
    Select_Lex *outer_select= unit->outer_select();
76
102
    /*
77
103
      do not take into account expression inside aggregate functions because
78
104
      they can access original table fields
86
112
      engine= new subselect_single_select_engine(select_lex, result, this);
87
113
  }
88
114
  {
89
 
    SELECT_LEX *upper= unit->outer_select();
 
115
    Select_Lex *upper= unit->outer_select();
90
116
    if (upper->parsing_place == IN_HAVING)
91
117
      upper->subquery_in_having= 1;
92
118
  }
93
119
  return;
94
120
}
95
121
 
96
 
st_select_lex *
 
122
Select_Lex *
97
123
Item_subselect::get_select_lex()
98
124
{
99
125
  return unit->first_select();
143
169
}
144
170
 
145
171
Item_subselect::trans_res
146
 
Item_subselect::select_transformer(JOIN *join __attribute__((unused)))
 
172
Item_subselect::select_transformer(JOIN *)
147
173
{
148
174
  return(RES_OK);
149
175
}
150
176
 
151
177
 
152
 
bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
 
178
bool Item_subselect::fix_fields(Session *session_param, Item **ref)
153
179
{
154
 
  char const *save_where= thd_param->where;
 
180
  char const *save_where= session_param->where;
155
181
  uint8_t uncacheable;
156
182
  bool res;
157
183
 
158
184
  assert(fixed == 0);
159
 
  engine->set_thd((thd= thd_param));
 
185
  engine->set_session((session= session_param));
160
186
 
161
 
  if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res))
 
187
  if (check_stack_overrun(session, STACK_MIN_SIZE, (unsigned char*)&res))
162
188
    return true;
163
189
 
164
190
  res= engine->prepare();
189
215
      if (have_to_be_excluded)
190
216
        engine->exclude();
191
217
      substitution= 0;
192
 
      thd->where= "checking transformed subquery";
 
218
      session->where= "checking transformed subquery";
193
219
      if (!(*ref)->fixed)
194
 
        ret= (*ref)->fix_fields(thd, ref);
195
 
      thd->where= save_where;
 
220
        ret= (*ref)->fix_fields(session, ref);
 
221
      session->where= save_where;
196
222
      return ret;
197
223
    }
198
224
    // Is it one field subselect?
205
231
  }
206
232
  else
207
233
    goto err;
208
 
  
 
234
 
209
235
  if ((uncacheable= engine->uncacheable()))
210
236
  {
211
237
    const_item_cache= 0;
215
241
  fixed= 1;
216
242
 
217
243
err:
218
 
  thd->where= save_where;
 
244
  session->where= save_where;
219
245
  return res;
220
246
}
221
247
 
222
248
 
223
249
bool Item_subselect::walk(Item_processor processor, bool walk_subquery,
224
 
                          uchar *argument)
 
250
                          unsigned char *argument)
225
251
{
226
252
 
227
253
  if (walk_subquery)
228
254
  {
229
 
    for (SELECT_LEX *lex= unit->first_select(); lex; lex= lex->next_select())
 
255
    for (Select_Lex *lex= unit->first_select(); lex; lex= lex->next_select())
230
256
    {
231
257
      List_iterator<Item> li(lex->item_list);
232
258
      Item *item;
233
 
      ORDER *order;
 
259
      order_st *order;
234
260
 
235
261
      if (lex->where && (lex->where)->walk(processor, walk_subquery, argument))
236
262
        return 1;
243
269
        if (item->walk(processor, walk_subquery, argument))
244
270
          return 1;
245
271
      }
246
 
      for (order= (ORDER*) lex->order_list.first ; order; order= order->next)
 
272
      for (order= (order_st*) lex->order_list.first ; order; order= order->next)
247
273
      {
248
274
        if ((*order->item)->walk(processor, walk_subquery, argument))
249
275
          return 1;
250
276
      }
251
 
      for (order= (ORDER*) lex->group_list.first ; order; order= order->next)
 
277
      for (order= (order_st*) lex->group_list.first ; order; order= order->next)
252
278
      {
253
279
        if ((*order->item)->walk(processor, walk_subquery, argument))
254
280
          return 1;
263
289
{
264
290
  int res;
265
291
 
266
 
  if (thd->is_error())
 
292
  if (session->is_error())
267
293
  /* Do not execute subselect in case of a fatal error */
268
294
    return 1;
269
295
 
343
369
  return const_item_cache;
344
370
}
345
371
 
346
 
Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
 
372
Item *Item_subselect::get_tmp_table_item(Session *session_arg)
347
373
{
348
374
  if (!with_sum_func && !const_item())
349
375
    return new Item_field(result_field);
350
 
  return copy_or_same(thd_arg);
 
376
  return copy_or_same(session_arg);
351
377
}
352
378
 
353
379
void Item_subselect::update_used_tables()
369
395
}
370
396
 
371
397
 
372
 
Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex)
 
398
Item_singlerow_subselect::Item_singlerow_subselect(Select_Lex *select_lex)
373
399
  :Item_subselect(), value(0)
374
400
{
375
401
  init(select_lex, new select_singlerow_subselect(this));
378
404
  return;
379
405
}
380
406
 
381
 
st_select_lex *
 
407
Select_Lex *
382
408
Item_singlerow_subselect::invalidate_and_restore_select_lex()
383
409
{
384
 
  st_select_lex *result= get_select_lex();
 
410
  Select_Lex *result= get_select_lex();
385
411
 
386
412
  assert(result);
387
413
 
388
414
  /*
389
415
    This code restore the parse tree in it's state before the execution of
390
416
    Item_singlerow_subselect::Item_singlerow_subselect(),
391
 
    and in particular decouples this object from the SELECT_LEX,
392
 
    so that the SELECT_LEX can be used with a different flavor
 
417
    and in particular decouples this object from the Select_Lex,
 
418
    so that the Select_Lex can be used with a different flavor
393
419
    or Item_subselect instead, as part of query rewriting.
394
420
  */
395
421
  unit->item= NULL;
397
423
  return(result);
398
424
}
399
425
 
400
 
Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,
 
426
Item_maxmin_subselect::Item_maxmin_subselect(Session *session_param,
401
427
                                             Item_subselect *parent,
402
 
                                             st_select_lex *select_lex,
 
428
                                             Select_Lex *select_lex,
403
429
                                             bool max_arg)
404
430
  :Item_singlerow_subselect(), was_values(true)
405
431
{
418
444
 
419
445
  /*
420
446
    this subquery always creates during preparation, so we can assign
421
 
    thd here
 
447
    session here
422
448
  */
423
 
  thd= thd_param;
 
449
  session= session_param;
424
450
 
425
451
  return;
426
452
}
473
499
  if (changed)
474
500
    return(RES_OK);
475
501
 
476
 
  SELECT_LEX *select_lex= join->select_lex;
477
 
 
 
502
  Select_Lex *select_lex= join->select_lex;
 
503
 
478
504
  if (!select_lex->master_unit()->is_union() &&
479
505
      !select_lex->table_list.elements &&
480
506
      select_lex->item_list.elements == 1 &&
493
519
  {
494
520
 
495
521
    have_to_be_excluded= 1;
496
 
    if (thd->lex->describe)
 
522
    if (session->lex->describe)
497
523
    {
498
524
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
499
525
      sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
500
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
526
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
501
527
                   ER_SELECT_REDUCED, warn_buff);
502
528
    }
503
529
    substitution= select_lex->item_list.head();
506
532
      'upper' select is not really dependent => we remove this dependence
507
533
    */
508
534
    substitution->walk(&Item::remove_dependence_processor, 0,
509
 
                       (uchar *) select_lex->outer_select());
 
535
                       (unsigned char *) select_lex->outer_select());
510
536
    return(RES_REDUCE);
511
537
  }
512
538
  return(RES_OK);
513
539
}
514
540
 
515
541
 
516
 
void Item_singlerow_subselect::store(uint i, Item *item)
 
542
void Item_singlerow_subselect::store(uint32_t i, Item *item)
517
543
{
518
544
  row[i]->store(item);
519
545
}
523
549
  return engine->type();
524
550
}
525
551
 
526
 
/* 
527
 
 Don't rely on the result type to calculate field type. 
 
552
/*
 
553
 Don't rely on the result type to calculate field type.
528
554
 Ask the engine instead.
529
555
*/
530
556
enum_field_types Item_singlerow_subselect::field_type() const
540
566
  }
541
567
  else
542
568
  {
543
 
    if (!(row= (Item_cache**) sql_alloc(sizeof(Item_cache*)*max_columns)))
 
569
    if (!(row= (Item_cache**) memory::sql_alloc(sizeof(Item_cache*)*max_columns)))
544
570
      return;
545
571
    engine->fix_length_and_dec(row);
546
572
    value= *row;
555
581
    maybe_null= engine->may_be_null();
556
582
}
557
583
 
558
 
uint Item_singlerow_subselect::cols()
 
584
uint32_t Item_singlerow_subselect::cols()
559
585
{
560
586
  return engine->cols();
561
587
}
562
588
 
563
 
bool Item_singlerow_subselect::check_cols(uint c)
 
589
bool Item_singlerow_subselect::check_cols(uint32_t c)
564
590
{
565
591
  if (c != engine->cols())
566
592
  {
572
598
 
573
599
bool Item_singlerow_subselect::null_inside()
574
600
{
575
 
  for (uint i= 0; i < max_columns ; i++)
 
601
  for (uint32_t i= 0; i < max_columns ; i++)
576
602
  {
577
603
    if (row[i]->null_value)
578
604
      return 1;
660
686
}
661
687
 
662
688
 
663
 
Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex):
 
689
Item_exists_subselect::Item_exists_subselect(Select_Lex *select_lex):
664
690
  Item_subselect()
665
691
{
666
692
  bool val_bool();
680
706
}
681
707
 
682
708
 
683
 
bool Item_in_subselect::test_limit(st_select_lex_unit *unit_arg)
 
709
bool Item_in_subselect::test_limit(Select_Lex_Unit *unit_arg)
684
710
{
685
711
  if (unit_arg->fake_select_lex &&
686
712
      unit_arg->fake_select_lex->test_limit())
687
713
    return(1);
688
714
 
689
 
  SELECT_LEX *sl= unit_arg->first_select();
 
715
  Select_Lex *sl= unit_arg->first_select();
690
716
  for (; sl; sl= sl->next_select())
691
717
  {
692
718
    if (sl->test_limit())
696
722
}
697
723
 
698
724
Item_in_subselect::Item_in_subselect(Item * left_exp,
699
 
                                     st_select_lex *select_lex):
700
 
  Item_exists_subselect(), left_expr_cache(0), first_execution(true),
701
 
  optimizer(0), pushed_cond_guards(NULL), exec_method(NOT_TRANSFORMED),
702
 
  upper_item(0)
 
725
                                     Select_Lex *select_lex) :
 
726
  Item_exists_subselect(),
 
727
  left_expr(left_exp),
 
728
  left_expr_cache(NULL),
 
729
  first_execution(true),
 
730
  optimizer(NULL),
 
731
  pushed_cond_guards(NULL),
 
732
  sj_convert_priority(0),
 
733
  expr_join_nest(NULL),
 
734
  exec_method(NOT_TRANSFORMED),
 
735
  upper_item(NULL)
703
736
{
704
 
  left_expr= left_exp;
705
737
  init(select_lex, new select_exists_subselect(this));
706
738
  max_columns= UINT_MAX;
707
739
  maybe_null= 1;
714
746
 
715
747
Item_allany_subselect::Item_allany_subselect(Item * left_exp,
716
748
                                             chooser_compare_func_creator fc,
717
 
                                             st_select_lex *select_lex,
 
749
                                             Select_Lex *select_lex,
718
750
                                             bool all_arg)
719
751
  :Item_in_subselect(), func_creator(fc), all(all_arg)
720
752
{
872
904
  if (exec())
873
905
  {
874
906
    reset();
875
 
    /* 
 
907
    /*
876
908
      Must mark the IN predicate as NULL so as to make sure an enclosing NOT
877
 
      predicate will return false. See the comments in 
 
909
      predicate will return false. See the comments in
878
910
      subselect_uniquesubquery_engine::copy_ref_key for further details.
879
911
    */
880
912
    null_value= 1;
907
939
}
908
940
 
909
941
 
910
 
/* 
 
942
/*
911
943
  Rewrite a single-column IN/ALL/ANY subselect
912
944
 
913
945
  SYNOPSIS
917
949
 
918
950
  DESCRIPTION
919
951
    Rewrite a single-column subquery using rule-based approach. The subquery
920
 
    
 
952
 
921
953
       oe $cmp$ (SELECT ie FROM ... WHERE subq_where ... HAVING subq_having)
922
 
    
 
954
 
923
955
    First, try to convert the subquery to scalar-result subquery in one of
924
956
    the forms:
925
 
    
 
957
 
926
958
       - oe $cmp$ (SELECT MAX(...) )  // handled by Item_singlerow_subselect
927
959
       - oe $cmp$ <max>(SELECT ...)   // handled by Item_maxmin_subselect
928
 
   
 
960
 
929
961
    If that fails, the subquery will be handled with class Item_in_optimizer.
930
962
    There are two possibilites:
931
963
    - If the subquery execution method is materialization, then the subquery is
943
975
 
944
976
Item_subselect::trans_res
945
977
Item_in_subselect::single_value_transformer(JOIN *join,
946
 
                                            Comp_creator *func)
 
978
                                            const Comp_creator *func)
947
979
{
948
 
  SELECT_LEX *select_lex= join->select_lex;
 
980
  Select_Lex *select_lex= join->select_lex;
949
981
 
950
982
  /*
951
983
    Check that the right part of the subselect contains no more than one
1011
1043
        it.replace(item);
1012
1044
      }
1013
1045
 
1014
 
      save_allow_sum_func= thd->lex->allow_sum_func;
1015
 
      thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
 
1046
      save_allow_sum_func= session->lex->allow_sum_func;
 
1047
      session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
1016
1048
      /*
1017
1049
        Item_sum_(max|min) can't substitute other item => we can use 0 as
1018
1050
        reference, also Item_sum_(max|min) can't be fixed after creation, so
1019
1051
        we do not check item->fixed
1020
1052
      */
1021
 
      if (item->fix_fields(thd, 0))
 
1053
      if (item->fix_fields(session, 0))
1022
1054
        return(RES_ERROR);
1023
 
      thd->lex->allow_sum_func= save_allow_sum_func; 
 
1055
      session->lex->allow_sum_func= save_allow_sum_func;
1024
1056
      /* we added aggregate function => we have to change statistic */
1025
 
      count_field_types(select_lex, &join->tmp_table_param, join->all_fields, 
 
1057
      count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
1026
1058
                        0);
1027
1059
 
1028
1060
      subs= new Item_singlerow_subselect(select_lex);
1030
1062
    else
1031
1063
    {
1032
1064
      Item_maxmin_subselect *item;
1033
 
      subs= item= new Item_maxmin_subselect(thd, this, select_lex, func->l_op());
 
1065
      subs= item= new Item_maxmin_subselect(session, this, select_lex, func->l_op());
1034
1066
      if (upper_item)
1035
1067
        upper_item->set_sub_test(item);
1036
1068
    }
1042
1074
  if (!substitution)
1043
1075
  {
1044
1076
    /* We're invoked for the 1st (or the only) SELECT in the subquery UNION */
1045
 
    SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
 
1077
    Select_Lex_Unit *master_unit= select_lex->master_unit();
1046
1078
    substitution= optimizer;
1047
1079
 
1048
 
    SELECT_LEX *current= thd->lex->current_select, *up;
 
1080
    Select_Lex *current= session->lex->current_select, *up;
1049
1081
 
1050
 
    thd->lex->current_select= up= current->return_after_parsing();
 
1082
    session->lex->current_select= up= current->return_after_parsing();
1051
1083
    //optimizer never use Item **ref => we can pass 0 as parameter
1052
 
    if (!optimizer || optimizer->fix_left(thd, 0))
 
1084
    if (!optimizer || optimizer->fix_left(session, 0))
1053
1085
    {
1054
 
      thd->lex->current_select= current;
 
1086
      session->lex->current_select= current;
1055
1087
      return(RES_ERROR);
1056
1088
    }
1057
 
    thd->lex->current_select= current;
 
1089
    session->lex->current_select= current;
1058
1090
 
1059
1091
    /*
1060
1092
      As far as  Item_ref_in_optimizer do not substitute itself on fix_fields
1070
1102
 
1071
1103
  if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1072
1104
  {
1073
 
    if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool))))
 
1105
    if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool))))
1074
1106
      return(RES_ERROR);
1075
1107
    pushed_cond_guards[0]= true;
1076
1108
  }
1095
1127
 
1096
1128
  - If the subquery has aggregates, GROUP BY, or HAVING, convert to
1097
1129
 
1098
 
    SELECT ie FROM ...  HAVING subq_having AND 
 
1130
    SELECT ie FROM ...  HAVING subq_having AND
1099
1131
                               trigcond(oe $cmp$ ref_or_null_helper<ie>)
1100
 
                                   
 
1132
 
1101
1133
    the addition is wrapped into trigger only when we want to distinguish
1102
1134
    between NULL and false results.
1103
1135
 
1105
1137
    following:
1106
1138
 
1107
1139
    = If we don't need to distinguish between NULL and false subquery:
1108
 
        
 
1140
 
1109
1141
      SELECT 1 FROM ... WHERE (oe $cmp$ ie) AND subq_where
1110
1142
 
1111
1143
    = If we need to distinguish between those:
1124
1156
*/
1125
1157
 
1126
1158
Item_subselect::trans_res
1127
 
Item_in_subselect::single_value_in_to_exists_transformer(JOIN * join, Comp_creator *func)
 
1159
Item_in_subselect::single_value_in_to_exists_transformer(JOIN * join, const Comp_creator *func)
1128
1160
{
1129
 
  SELECT_LEX *select_lex= join->select_lex;
 
1161
  Select_Lex *select_lex= join->select_lex;
1130
1162
 
1131
1163
  select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1132
1164
  if (join->having || select_lex->with_sum_func ||
1142
1174
                                                      this->full_name()));
1143
1175
    if (!abort_on_null && left_expr->maybe_null)
1144
1176
    {
1145
 
      /* 
 
1177
      /*
1146
1178
        We can encounter "NULL IN (SELECT ...)". Wrap the added condition
1147
1179
        within a trig_cond.
1148
1180
      */
1149
1181
      item= new Item_func_trig_cond(item, get_cond_guard(0));
1150
1182
    }
1151
 
    
 
1183
 
1152
1184
    /*
1153
1185
      AND and comparison functions can't be changed during fix_fields()
1154
1186
      we can assign select_lex->having here, and pass 0 as last
1162
1194
      we do not check join->having->fixed, because Item_and (from and_items)
1163
1195
      or comparison function (from func->create) can't be fixed after creation
1164
1196
    */
1165
 
    tmp= join->having->fix_fields(thd, 0);
 
1197
    tmp= join->having->fix_fields(session, 0);
1166
1198
    select_lex->having_fix_field= 0;
1167
1199
    if (tmp)
1168
1200
      return(RES_ERROR);
1180
1212
                                                   (int64_t) 1,
1181
1213
                                                   MY_INT64_NUM_DECIMAL_DIGITS));
1182
1214
      select_lex->ref_pointer_array[0]= select_lex->item_list.head();
1183
 
       
 
1215
 
1184
1216
      item= func->create(expr, item);
1185
1217
      if (!abort_on_null && orig_item->maybe_null)
1186
1218
      {
1204
1236
          and_items) or comparison function (from func->create) can't be
1205
1237
          fixed after creation
1206
1238
        */
1207
 
        tmp= join->having->fix_fields(thd, 0);
 
1239
        tmp= join->having->fix_fields(session, 0);
1208
1240
        select_lex->having_fix_field= 0;
1209
1241
        if (tmp)
1210
1242
          return(RES_ERROR);
1211
1243
        item= new Item_cond_or(item,
1212
1244
                               new Item_func_isnull(orig_item));
1213
1245
      }
1214
 
      /* 
 
1246
      /*
1215
1247
        If we may encounter NULL IN (SELECT ...) and care whether subquery
1216
1248
        result is NULL or false, wrap condition in a trig_cond.
1217
1249
      */
1221
1253
          return(RES_ERROR);
1222
1254
      }
1223
1255
      /*
1224
 
        TODO: figure out why the following is done here in 
 
1256
        TODO: figure out why the following is done here in
1225
1257
        single_value_transformer but there is no corresponding action in
1226
1258
        row_value_transformer?
1227
1259
      */
1238
1270
        we do not check join->conds->fixed, because Item_and can't be fixed
1239
1271
        after creation
1240
1272
      */
1241
 
      if (join->conds->fix_fields(thd, 0))
 
1273
      if (join->conds->fix_fields(session, 0))
1242
1274
        return(RES_ERROR);
1243
1275
    }
1244
1276
    else
1266
1298
        new_having->name= (char*)in_having_cond;
1267
1299
        select_lex->having= join->having= new_having;
1268
1300
        select_lex->having_fix_field= 1;
1269
 
        
 
1301
 
1270
1302
        /*
1271
1303
          we do not check join->having->fixed, because comparison function
1272
1304
          (from func->create) can't be fixed after creation
1273
1305
        */
1274
 
        tmp= join->having->fix_fields(thd, 0);
 
1306
        tmp= join->having->fix_fields(session, 0);
1275
1307
        select_lex->having_fix_field= 0;
1276
1308
        if (tmp)
1277
1309
          return(RES_ERROR);
1283
1315
        // fix_field of item will be done in time of substituting
1284
1316
        substitution= item;
1285
1317
        have_to_be_excluded= 1;
1286
 
        if (thd->lex->describe)
 
1318
        if (session->lex->describe)
1287
1319
        {
1288
1320
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
1289
1321
          sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
1290
 
          push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1322
          push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1291
1323
                       ER_SELECT_REDUCED, warn_buff);
1292
1324
        }
1293
1325
        return(RES_REDUCE);
1302
1334
Item_subselect::trans_res
1303
1335
Item_in_subselect::row_value_transformer(JOIN *join)
1304
1336
{
1305
 
  SELECT_LEX *select_lex= join->select_lex;
1306
 
  uint cols_num= left_expr->cols();
 
1337
  Select_Lex *select_lex= join->select_lex;
 
1338
  uint32_t cols_num= left_expr->cols();
1307
1339
 
1308
1340
  if (select_lex->item_list.elements != left_expr->cols())
1309
1341
  {
1318
1350
  if (!substitution)
1319
1351
  {
1320
1352
    //first call for this unit
1321
 
    SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
 
1353
    Select_Lex_Unit *master_unit= select_lex->master_unit();
1322
1354
    substitution= optimizer;
1323
1355
 
1324
 
    SELECT_LEX *current= thd->lex->current_select, *up;
1325
 
    thd->lex->current_select= up= current->return_after_parsing();
 
1356
    Select_Lex *current= session->lex->current_select, *up;
 
1357
    session->lex->current_select= up= current->return_after_parsing();
1326
1358
    //optimizer never use Item **ref => we can pass 0 as parameter
1327
 
    if (!optimizer || optimizer->fix_left(thd, 0))
 
1359
    if (!optimizer || optimizer->fix_left(session, 0))
1328
1360
    {
1329
 
      thd->lex->current_select= current;
 
1361
      session->lex->current_select= current;
1330
1362
      return(RES_ERROR);
1331
1363
    }
1332
1364
 
1333
1365
    // we will refer to upper level cache array => we have to save it in PS
1334
1366
    optimizer->keep_top_level_cache();
1335
1367
 
1336
 
    thd->lex->current_select= current;
 
1368
    session->lex->current_select= current;
1337
1369
    master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1338
1370
 
1339
1371
    if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1340
1372
    {
1341
 
      if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool) *
 
1373
      if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool) *
1342
1374
                                                        left_expr->cols())))
1343
1375
        return(RES_ERROR);
1344
 
      for (uint i= 0; i < cols_num; i++)
 
1376
      for (uint32_t i= 0; i < cols_num; i++)
1345
1377
        pushed_cond_guards[i]= true;
1346
1378
    }
1347
1379
  }
1379
1411
Item_subselect::trans_res
1380
1412
Item_in_subselect::row_value_in_to_exists_transformer(JOIN * join)
1381
1413
{
1382
 
  SELECT_LEX *select_lex= join->select_lex;
 
1414
  Select_Lex *select_lex= join->select_lex;
1383
1415
  Item *having_item= 0;
1384
 
  uint cols_num= left_expr->cols();
 
1416
  uint32_t cols_num= left_expr->cols();
1385
1417
  bool is_having_used= (join->having || select_lex->with_sum_func ||
1386
1418
                        select_lex->group_list.first ||
1387
1419
                        !select_lex->table_list.elements);
1403
1435
      TODO: say here explicitly if the order of AND parts matters or not.
1404
1436
    */
1405
1437
    Item *item_having_part2= 0;
1406
 
    for (uint i= 0; i < cols_num; i++)
 
1438
    for (uint32_t i= 0; i < cols_num; i++)
1407
1439
    {
1408
1440
      assert((left_expr->fixed && select_lex->ref_pointer_array[i]->fixed) ||
1409
1441
                  (select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
1439
1471
          return(RES_ERROR);
1440
1472
      }
1441
1473
      having_item= and_items(having_item, col_item);
1442
 
      
1443
 
      Item *item_nnull_test= 
 
1474
 
 
1475
      Item *item_nnull_test=
1444
1476
         new Item_is_not_null_test(this,
1445
1477
                                   new Item_ref(&select_lex->context,
1446
1478
                                                select_lex->
1449
1481
                                                (char *)"<list ref>"));
1450
1482
      if (!abort_on_null && left_expr->element_index(i)->maybe_null)
1451
1483
      {
1452
 
        if (!(item_nnull_test= 
 
1484
        if (!(item_nnull_test=
1453
1485
              new Item_func_trig_cond(item_nnull_test, get_cond_guard(i))))
1454
1486
          return(RES_ERROR);
1455
1487
      }
1479
1511
                               (l3 = v3)
1480
1512
    */
1481
1513
    Item *where_item= 0;
1482
 
    for (uint i= 0; i < cols_num; i++)
 
1514
    for (uint32_t i= 0; i < cols_num; i++)
1483
1515
    {
1484
1516
      Item *item, *item_isnull;
1485
1517
      assert((left_expr->fixed && select_lex->ref_pointer_array[i]->fixed) ||
1508
1540
        Item *having_col_item=
1509
1541
          new Item_is_not_null_test(this,
1510
1542
                                    new
1511
 
                                    Item_ref(&select_lex->context, 
 
1543
                                    Item_ref(&select_lex->context,
1512
1544
                                             select_lex->ref_pointer_array + i,
1513
1545
                                             (char *)"<no matter>",
1514
1546
                                             (char *)"<list ref>"));
1515
 
        
1516
 
        
 
1547
 
 
1548
 
1517
1549
        item_isnull= new
1518
1550
          Item_func_isnull(new
1519
1551
                           Item_direct_ref(&select_lex->context,
1523
1555
                                           (char *)"<list ref>")
1524
1556
                          );
1525
1557
        item= new Item_cond_or(item, item_isnull);
1526
 
        /* 
 
1558
        /*
1527
1559
          TODO: why we create the above for cases where the right part
1528
1560
                cant be NULL?
1529
1561
        */
1531
1563
        {
1532
1564
          if (!(item= new Item_func_trig_cond(item, get_cond_guard(i))))
1533
1565
            return(RES_ERROR);
1534
 
          if (!(having_col_item= 
 
1566
          if (!(having_col_item=
1535
1567
                  new Item_func_trig_cond(having_col_item, get_cond_guard(i))))
1536
1568
            return(RES_ERROR);
1537
1569
        }
1546
1578
    */
1547
1579
    select_lex->where= join->conds= and_items(join->conds, where_item);
1548
1580
    select_lex->where->top_level_item();
1549
 
    if (join->conds->fix_fields(thd, 0))
 
1581
    if (join->conds->fix_fields(session, 0))
1550
1582
      return(RES_ERROR);
1551
1583
  }
1552
1584
  if (having_item)
1562
1594
      argument (reference) to fix_fields()
1563
1595
    */
1564
1596
    select_lex->having_fix_field= 1;
1565
 
    res= join->having->fix_fields(thd, 0);
 
1597
    res= join->having->fix_fields(session, 0);
1566
1598
    select_lex->having_fix_field= 0;
1567
1599
    if (res)
1568
1600
    {
1577
1609
Item_subselect::trans_res
1578
1610
Item_in_subselect::select_transformer(JOIN *join)
1579
1611
{
1580
 
  return select_in_like_transformer(join, &eq_creator);
 
1612
  return select_in_like_transformer(join, Eq_creator::instance());
1581
1613
}
1582
1614
 
1583
1615
 
1603
1635
*/
1604
1636
 
1605
1637
Item_subselect::trans_res
1606
 
Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
 
1638
Item_in_subselect::select_in_like_transformer(JOIN *join, const Comp_creator *func)
1607
1639
{
1608
 
  SELECT_LEX *current= thd->lex->current_select, *up;
1609
 
  const char *save_where= thd->where;
 
1640
  Select_Lex *current= session->lex->current_select, *up;
 
1641
  const char *save_where= session->where;
1610
1642
  Item_subselect::trans_res res= RES_ERROR;
1611
1643
  bool result;
1612
1644
 
1613
1645
  {
1614
1646
    /*
1615
1647
      IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
1616
 
      ORDER BY clause becomes meaningless thus we drop it here.
 
1648
      order_st BY clause becomes meaningless thus we drop it here.
1617
1649
    */
1618
 
    SELECT_LEX *sl= current->master_unit()->first_select();
 
1650
    Select_Lex *sl= current->master_unit()->first_select();
1619
1651
    for (; sl; sl= sl->next_select())
1620
1652
    {
1621
1653
      if (sl->join)
1626
1658
  if (changed)
1627
1659
    return(RES_OK);
1628
1660
 
1629
 
  thd->where= "IN/ALL/ANY subquery";
 
1661
  session->where= "IN/ALL/ANY subquery";
1630
1662
 
1631
1663
  /*
1632
1664
    In some optimisation cases we will not need this Item_in_optimizer
1640
1672
      goto err;
1641
1673
  }
1642
1674
 
1643
 
  thd->lex->current_select= up= current->return_after_parsing();
 
1675
  session->lex->current_select= up= current->return_after_parsing();
1644
1676
  result= (!left_expr->fixed &&
1645
 
           left_expr->fix_fields(thd, optimizer->arguments()));
 
1677
           left_expr->fix_fields(session, optimizer->arguments()));
1646
1678
  /* fix_fields can change reference to left_expr, we need reassign it */
1647
1679
  left_expr= optimizer->arguments()[0];
1648
1680
 
1649
 
  thd->lex->current_select= current;
 
1681
  session->lex->current_select= current;
1650
1682
  if (result)
1651
1683
    goto err;
1652
1684
 
1669
1701
  else
1670
1702
  {
1671
1703
    /* we do not support row operation for ALL/ANY/SOME */
1672
 
    if (func != &eq_creator)
 
1704
    if (func != Eq_creator::instance())
1673
1705
    {
1674
1706
      my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
1675
1707
      return(RES_ERROR);
1677
1709
    res= row_value_transformer(join);
1678
1710
  }
1679
1711
err:
1680
 
  thd->where= save_where;
 
1712
  session->where= save_where;
1681
1713
  return(res);
1682
1714
}
1683
1715
 
1695
1727
}
1696
1728
 
1697
1729
 
1698
 
bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
 
1730
bool Item_in_subselect::fix_fields(Session *session_arg, Item **ref)
1699
1731
{
1700
1732
  bool result = 0;
1701
1733
 
1702
1734
  if (exec_method == SEMI_JOIN)
1703
1735
    return !( (*ref)= new Item_int(1));
1704
1736
 
1705
 
  return result || Item_subselect::fix_fields(thd_arg, ref);
 
1737
  return result || Item_subselect::fix_fields(session_arg, ref);
1706
1738
}
1707
1739
 
1708
1740
 
1738
1770
  if (engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE)
1739
1771
  {
1740
1772
    /* Create/initialize objects in permanent memory. */
1741
 
    subselect_single_select_engine *old_engine;
1742
 
 
1743
 
    old_engine= (subselect_single_select_engine*) engine;
1744
 
 
1745
 
    if (!(new_engine= new subselect_hash_sj_engine(thd, this,
1746
 
                                                   old_engine)) ||
 
1773
    subselect_single_select_engine *old_engine_ptr;
 
1774
 
 
1775
    old_engine_ptr= static_cast<subselect_single_select_engine *>(engine);
 
1776
 
 
1777
    if (!(new_engine= new subselect_hash_sj_engine(session, this,
 
1778
                                                   old_engine_ptr)) ||
1747
1779
        new_engine->init_permanent(unit->get_unit_column_types()))
1748
1780
    {
1749
 
      Item_subselect::trans_res trans_res;
 
1781
      Item_subselect::trans_res new_trans_res;
1750
1782
      /*
1751
1783
        If for some reason we cannot use materialization for this IN predicate,
1752
1784
        delete all materialization-related objects, and apply the IN=>EXISTS
1756
1788
      new_engine= NULL;
1757
1789
      exec_method= NOT_TRANSFORMED;
1758
1790
      if (left_expr->cols() == 1)
1759
 
        trans_res= single_value_in_to_exists_transformer(old_engine->join,
1760
 
                                                         &eq_creator);
 
1791
        new_trans_res= single_value_in_to_exists_transformer(
 
1792
                           old_engine_ptr->join,
 
1793
                           Eq_creator::instance());
1761
1794
      else
1762
 
        trans_res= row_value_in_to_exists_transformer(old_engine->join);
1763
 
      res= (trans_res != Item_subselect::RES_OK);
 
1795
        new_trans_res= row_value_in_to_exists_transformer(old_engine_ptr->join);
 
1796
      res= (new_trans_res != Item_subselect::RES_OK);
1764
1797
    }
1765
1798
    if (new_engine)
1766
1799
      engine= new_engine;
1768
1801
  else
1769
1802
  {
1770
1803
    assert(engine->engine_type() == subselect_engine::HASH_SJ_ENGINE);
1771
 
    new_engine= (subselect_hash_sj_engine*) engine;
 
1804
    new_engine= static_cast<subselect_hash_sj_engine *>(engine);
1772
1805
  }
1773
1806
 
1774
1807
  /* Initilizations done in runtime memory, repeated for each execution. */
1805
1838
 
1806
1839
bool Item_in_subselect::init_left_expr_cache()
1807
1840
{
1808
 
  JOIN *outer_join;
1809
 
  Next_select_func end_select;
1810
 
  bool use_result_field= false;
 
1841
  JOIN *outer_join= NULL;
1811
1842
 
1812
1843
  outer_join= unit->outer_select()->join;
1813
 
  if (!outer_join || !outer_join->tables)
 
1844
  if (! outer_join || ! outer_join->tables || ! outer_join->join_tab)
1814
1845
    return true;
1815
 
  /*
1816
 
    If we use end_[send | write]_group to handle complete rows of the outer
1817
 
    query, make the cache of the left IN operand use Item_field::result_field
1818
 
    instead of Item_field::field.  We need this because normally
1819
 
    Cached_item_field uses Item::field to fetch field data, while
1820
 
    copy_ref_key() that copies the left IN operand into a lookup key uses
1821
 
    Item::result_field. In the case end_[send | write]_group result_field is
1822
 
    one row behind field.
1823
 
  */
1824
 
  end_select= outer_join->join_tab[outer_join->tables-1].next_select;
1825
 
  if (end_select == end_send_group || end_select == end_write_group)
1826
 
    use_result_field= true;
1827
1846
 
1828
1847
  if (!(left_expr_cache= new List<Cached_item>))
1829
1848
    return true;
1830
1849
 
1831
 
  for (uint i= 0; i < left_expr->cols(); i++)
 
1850
  for (uint32_t i= 0; i < left_expr->cols(); i++)
1832
1851
  {
1833
 
    Cached_item *cur_item_cache= new_Cached_item(thd,
1834
 
                                                 left_expr->element_index(i),
1835
 
                                                 use_result_field);
 
1852
    Cached_item *cur_item_cache= new_Cached_item(session, left_expr->element_index(i));
1836
1853
    if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
1837
1854
      return true;
1838
1855
  }
1853
1870
  @retval false otherwise
1854
1871
*/
1855
1872
 
1856
 
bool Item_in_subselect::is_expensive_processor(uchar *arg __attribute__((unused)))
 
1873
bool Item_in_subselect::is_expensive_processor(unsigned char *)
1857
1874
{
1858
1875
  return exec_method == MATERIALIZATION;
1859
1876
}
1884
1901
}
1885
1902
 
1886
1903
 
1887
 
void subselect_engine::set_thd(THD *thd_arg)
 
1904
void subselect_engine::set_session(Session *session_arg)
1888
1905
{
1889
 
  thd= thd_arg;
 
1906
  session= session_arg;
1890
1907
  if (result)
1891
 
    result->set_thd(thd_arg);
 
1908
    result->set_session(session_arg);
1892
1909
}
1893
1910
 
1894
1911
 
1895
1912
subselect_single_select_engine::
1896
 
subselect_single_select_engine(st_select_lex *select,
 
1913
subselect_single_select_engine(Select_Lex *select,
1897
1914
                               select_result_interceptor *result_arg,
1898
1915
                               Item_subselect *item_arg)
1899
1916
  :subselect_engine(item_arg, result_arg),
1951
1968
void subselect_uniquesubquery_engine::cleanup()
1952
1969
{
1953
1970
  /* Tell handler we don't need the index anymore */
1954
 
  if (tab->table->file->inited)
1955
 
    tab->table->file->ha_index_end();
 
1971
  if (tab->table->cursor->inited)
 
1972
    tab->table->cursor->ha_index_end();
1956
1973
  return;
1957
1974
}
1958
1975
 
1959
1976
 
1960
 
subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
 
1977
subselect_union_engine::subselect_union_engine(Select_Lex_Unit *u,
1961
1978
                                               select_result_interceptor *result_arg,
1962
1979
                                               Item_subselect *item_arg)
1963
1980
  :subselect_engine(item_arg, result_arg)
1997
2014
{
1998
2015
  if (prepared)
1999
2016
    return 0;
2000
 
  join= new JOIN(thd, select_lex->item_list,
 
2017
  join= new JOIN(session, select_lex->item_list,
2001
2018
                 select_lex->options | SELECT_NO_UNLOCK, result);
2002
2019
  if (!join || !result)
2003
2020
    return 1; /* Fatal error is set already. */
2004
2021
  prepared= 1;
2005
 
  SELECT_LEX *save_select= thd->lex->current_select;
2006
 
  thd->lex->current_select= select_lex;
 
2022
  Select_Lex *save_select= session->lex->current_select;
 
2023
  session->lex->current_select= select_lex;
2007
2024
  if (join->prepare(&select_lex->ref_pointer_array,
2008
 
                    (TABLE_LIST*) select_lex->table_list.first,
 
2025
                    (TableList*) select_lex->table_list.first,
2009
2026
                    select_lex->with_wild,
2010
2027
                    select_lex->where,
2011
2028
                    select_lex->order_list.elements +
2012
2029
                    select_lex->group_list.elements,
2013
 
                    (ORDER*) select_lex->order_list.first,
2014
 
                    (ORDER*) select_lex->group_list.first,
 
2030
                    (order_st*) select_lex->order_list.first,
 
2031
                    (order_st*) select_lex->group_list.first,
2015
2032
                    select_lex->having,
2016
 
                    (ORDER*) 0, select_lex,
2017
 
                    select_lex->master_unit()))
 
2033
                    select_lex, select_lex->master_unit()))
2018
2034
    return 1;
2019
 
  thd->lex->current_select= save_select;
 
2035
  session->lex->current_select= save_select;
2020
2036
  return 0;
2021
2037
}
2022
2038
 
2023
2039
int subselect_union_engine::prepare()
2024
2040
{
2025
 
  return unit->prepare(thd, result, SELECT_NO_UNLOCK);
 
2041
  return unit->prepare(session, result, (uint32_t)SELECT_NO_UNLOCK);
2026
2042
}
2027
2043
 
2028
2044
int subselect_uniquesubquery_engine::prepare()
2049
2065
*/
2050
2066
 
2051
2067
bool subselect_single_select_engine::no_rows()
2052
 
 
2068
{
2053
2069
  return !item->assigned();
2054
2070
}
2055
2071
 
2056
2072
 
2057
 
/* 
2058
 
 makes storage for the output values for the subquery and calcuates 
 
2073
/*
 
2074
 makes storage for the output values for the subquery and calcuates
2059
2075
 their data and column types and their nullability.
2060
 
*/ 
 
2076
*/
2061
2077
void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
2062
2078
{
2063
2079
  Item *sel_item;
2064
2080
  List_iterator_fast<Item> li(item_list);
2065
2081
  res_type= STRING_RESULT;
2066
2082
  res_field_type= DRIZZLE_TYPE_VARCHAR;
2067
 
  for (uint i= 0; (sel_item= li++); i++)
 
2083
  for (uint32_t i= 0; (sel_item= li++); i++)
2068
2084
  {
2069
2085
    item->max_length= sel_item->max_length;
2070
2086
    res_type= sel_item->result_type();
2106
2122
  }
2107
2123
}
2108
2124
 
2109
 
void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row __attribute__((unused)))
 
2125
void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **)
2110
2126
{
2111
2127
  //this never should be called
2112
2128
  assert(0);
2113
2129
}
2114
2130
 
2115
 
int  init_read_record_seq(JOIN_TAB *tab);
2116
 
int join_read_always_key_or_null(JOIN_TAB *tab);
 
2131
int  init_read_record_seq(JoinTable *tab);
 
2132
int join_read_always_key_or_null(JoinTable *tab);
2117
2133
int join_read_next_same_or_null(READ_RECORD *info);
2118
2134
 
2119
2135
int subselect_single_select_engine::exec()
2120
2136
{
2121
 
  char const *save_where= thd->where;
2122
 
  SELECT_LEX *save_select= thd->lex->current_select;
2123
 
  thd->lex->current_select= select_lex;
 
2137
  char const *save_where= session->where;
 
2138
  Select_Lex *save_select= session->lex->current_select;
 
2139
  session->lex->current_select= select_lex;
2124
2140
  if (!join->optimized)
2125
2141
  {
2126
 
    SELECT_LEX_UNIT *unit= select_lex->master_unit();
 
2142
    Select_Lex_Unit *unit= select_lex->master_unit();
2127
2143
 
2128
2144
    unit->set_limit(unit->global_parameters);
2129
 
    if (join->flatten_subqueries())
2130
 
    {
2131
 
      thd->is_fatal_error= true;
2132
 
      return(1);
2133
 
    }
2134
2145
    if (join->optimize())
2135
2146
    {
2136
 
      thd->where= save_where;
 
2147
      session->where= save_where;
2137
2148
      executed= 1;
2138
 
      thd->lex->current_select= save_select;
 
2149
      session->lex->current_select= save_select;
2139
2150
      return(join->error ? join->error : 1);
2140
2151
    }
2141
 
    if (!select_lex->uncacheable && thd->lex->describe && 
2142
 
        !(join->select_options & SELECT_DESCRIBE) && 
 
2152
    if (!select_lex->uncacheable && session->lex->describe &&
 
2153
        !(join->select_options & SELECT_DESCRIBE) &&
2143
2154
        join->need_tmp && item->const_item())
2144
2155
    {
2145
2156
      /*
2151
2162
      select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
2152
2163
      select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
2153
2164
      if (join->init_save_join_tab())
2154
 
        return(1);                        /* purecov: inspected */
 
2165
        return(1);
2155
2166
    }
2156
2167
    if (item->engine_changed)
2157
2168
    {
2164
2175
  {
2165
2176
    if (join->reinit())
2166
2177
    {
2167
 
      thd->where= save_where;
2168
 
      thd->lex->current_select= save_select;
 
2178
      session->where= save_where;
 
2179
      session->lex->current_select= save_select;
2169
2180
      return(1);
2170
2181
    }
2171
2182
    item->reset();
2174
2185
  if (!executed)
2175
2186
  {
2176
2187
    item->reset_value_registration();
2177
 
    JOIN_TAB *changed_tabs[MAX_TABLES];
2178
 
    JOIN_TAB **last_changed_tab= changed_tabs;
 
2188
    JoinTable *changed_tabs[MAX_TABLES];
 
2189
    JoinTable **last_changed_tab= changed_tabs;
2179
2190
    if (item->have_guarded_conds())
2180
2191
    {
2181
2192
      /*
2184
2195
        pushed down into the subquery. Those optimizations are ref[_or_null]
2185
2196
        acceses. Change them to be full table scans.
2186
2197
      */
2187
 
      for (uint i=join->const_tables ; i < join->tables ; i++)
 
2198
      for (uint32_t i=join->const_tables ; i < join->tables ; i++)
2188
2199
      {
2189
 
        JOIN_TAB *tab=join->join_tab+i;
 
2200
        JoinTable *tab=join->join_tab+i;
2190
2201
        if (tab && tab->keyuse)
2191
2202
        {
2192
 
          for (uint i= 0; i < tab->ref.key_parts; i++)
 
2203
          for (uint32_t key_part= 0;
 
2204
               key_part < tab->ref.key_parts;
 
2205
               key_part++)
2193
2206
          {
2194
 
            bool *cond_guard= tab->ref.cond_guards[i];
 
2207
            bool *cond_guard= tab->ref.cond_guards[key_part];
2195
2208
            if (cond_guard && !*cond_guard)
2196
2209
            {
2197
2210
              /* Change the access method to full table scan */
2199
2212
              tab->save_read_record= tab->read_record.read_record;
2200
2213
              tab->read_first_record= init_read_record_seq;
2201
2214
              tab->read_record.record= tab->table->record[0];
2202
 
              tab->read_record.thd= join->thd;
2203
 
              tab->read_record.ref_length= tab->table->file->ref_length;
 
2215
              tab->read_record.session= join->session;
 
2216
              tab->read_record.ref_length= tab->table->cursor->ref_length;
2204
2217
              *(last_changed_tab++)= tab;
2205
2218
              break;
2206
2219
            }
2208
2221
        }
2209
2222
      }
2210
2223
    }
2211
 
    
 
2224
 
2212
2225
    join->exec();
2213
2226
 
2214
2227
    /* Enable the optimizations back */
2215
 
    for (JOIN_TAB **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
 
2228
    for (JoinTable **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
2216
2229
    {
2217
 
      JOIN_TAB *tab= *ptab;
 
2230
      JoinTable *tab= *ptab;
2218
2231
      tab->read_record.record= 0;
2219
2232
      tab->read_record.ref_length= 0;
2220
 
      tab->read_first_record= tab->save_read_first_record; 
 
2233
      tab->read_first_record= tab->save_read_first_record;
2221
2234
      tab->read_record.read_record= tab->save_read_record;
2222
2235
    }
2223
2236
    executed= 1;
2224
 
    thd->where= save_where;
2225
 
    thd->lex->current_select= save_select;
2226
 
    return(join->error||thd->is_fatal_error);
 
2237
    session->where= save_where;
 
2238
    session->lex->current_select= save_select;
 
2239
    return(join->error||session->is_fatal_error);
2227
2240
  }
2228
 
  thd->where= save_where;
2229
 
  thd->lex->current_select= save_select;
 
2241
  session->where= save_where;
 
2242
  session->lex->current_select= save_select;
2230
2243
  return(0);
2231
2244
}
2232
2245
 
2233
2246
int subselect_union_engine::exec()
2234
2247
{
2235
 
  char const *save_where= thd->where;
 
2248
  char const *save_where= session->where;
2236
2249
  int res= unit->exec();
2237
 
  thd->where= save_where;
 
2250
  session->where= save_where;
2238
2251
  return res;
2239
2252
}
2240
2253
 
2241
2254
 
2242
2255
/*
2243
2256
  Search for at least one row satisfying select condition
2244
 
 
 
2257
 
2245
2258
  SYNOPSIS
2246
2259
    subselect_uniquesubquery_engine::scan_table()
2247
2260
 
2248
2261
  DESCRIPTION
2249
2262
    Scan the table using sequential access until we find at least one row
2250
2263
    satisfying select condition.
2251
 
    
 
2264
 
2252
2265
    The caller must set this->empty_result_set=false before calling this
2253
2266
    function. This function will set it to true if it finds a matching row.
2254
2267
 
2260
2273
int subselect_uniquesubquery_engine::scan_table()
2261
2274
{
2262
2275
  int error;
2263
 
  TABLE *table= tab->table;
2264
 
 
2265
 
  if (table->file->inited)
2266
 
    table->file->ha_index_end();
2267
 
 
2268
 
  table->file->ha_rnd_init(1);
2269
 
  table->file->extra_opt(HA_EXTRA_CACHE,
2270
 
                         current_thd->variables.read_buff_size);
 
2276
  Table *table= tab->table;
 
2277
 
 
2278
  if (table->cursor->inited)
 
2279
    table->cursor->ha_index_end();
 
2280
 
 
2281
  table->cursor->ha_rnd_init(1);
 
2282
  table->cursor->extra_opt(HA_EXTRA_CACHE,
 
2283
                         current_session->variables.read_buff_size);
2271
2284
  table->null_row= 0;
2272
2285
  for (;;)
2273
2286
  {
2274
 
    error=table->file->rnd_next(table->record[0]);
 
2287
    error=table->cursor->rnd_next(table->record[0]);
2275
2288
    if (error && error != HA_ERR_END_OF_FILE)
2276
2289
    {
2277
 
      error= report_error(table, error);
 
2290
      error= table->report_error(error);
2278
2291
      break;
2279
2292
    }
2280
2293
    /* No more rows */
2288
2301
    }
2289
2302
  }
2290
2303
 
2291
 
  table->file->ha_rnd_end();
 
2304
  table->cursor->ha_rnd_end();
2292
2305
  return(error != 0);
2293
2306
}
2294
2307
 
2337
2350
 
2338
2351
bool subselect_uniquesubquery_engine::copy_ref_key()
2339
2352
{
2340
 
  for (store_key **copy= tab->ref.key_copy ; *copy ; copy++)
 
2353
  for (StoredKey **copy= tab->ref.key_copy ; *copy ; copy++)
2341
2354
  {
2342
 
    enum store_key::store_key_result store_res;
 
2355
    enum StoredKey::store_key_result store_res;
2343
2356
    store_res= (*copy)->copy();
2344
2357
    tab->ref.key_err= store_res;
2345
2358
 
2368
2381
    }
2369
2382
 
2370
2383
    /*
2371
 
      Check if the error is equal to STORE_KEY_FATAL. This is not expressed 
2372
 
      using the store_key::store_key_result enum because ref.key_err is a 
2373
 
      boolean and we want to detect both true and STORE_KEY_FATAL from the 
2374
 
      space of the union of the values of [true, false] and 
2375
 
      store_key::store_key_result.  
 
2384
      Check if the error is equal to STORE_KEY_FATAL. This is not expressed
 
2385
      using the StoredKey::store_key_result enum because ref.key_err is a
 
2386
      boolean and we want to detect both true and STORE_KEY_FATAL from the
 
2387
      space of the union of the values of [true, false] and
 
2388
      StoredKey::store_key_result.
2376
2389
      TODO: fix the variable an return types.
2377
2390
    */
2378
 
    if (store_res == store_key::STORE_KEY_FATAL)
 
2391
    if (store_res == StoredKey::STORE_KEY_FATAL)
2379
2392
    {
2380
2393
      /*
2381
2394
       Error converting the left IN operand to the column type of the right
2382
 
       IN operand. 
 
2395
       IN operand.
2383
2396
      */
2384
2397
      tab->table->status= STATUS_NOT_FOUND;
2385
2398
      break;
2400
2413
    If some part of the lookup key is NULL, then we're evaluating
2401
2414
      NULL IN (SELECT ... )
2402
2415
    This is a special case, we don't need to search for NULL in the table,
2403
 
    instead, the result value is 
 
2416
    instead, the result value is
2404
2417
      - NULL  if select produces empty row set
2405
2418
      - false otherwise.
2406
2419
 
2407
2420
    In some cases (IN subselect is a top level item, i.e. abort_on_null==true)
2408
2421
    the caller doesn't distinguish between NULL and false result and we just
2409
 
    return false. 
2410
 
    Otherwise we make a full table scan to see if there is at least one 
 
2422
    return false.
 
2423
    Otherwise we make a full table scan to see if there is at least one
2411
2424
    matching row.
2412
 
    
 
2425
 
2413
2426
    The result of this function (info about whether a row was found) is
2414
2427
    stored in this->empty_result_set.
2415
2428
  NOTE
2416
 
    
 
2429
 
2417
2430
  RETURN
2418
2431
    false - ok
2419
2432
    true  - an error occured while scanning
2422
2435
int subselect_uniquesubquery_engine::exec()
2423
2436
{
2424
2437
  int error;
2425
 
  TABLE *table= tab->table;
 
2438
  Table *table= tab->table;
2426
2439
  empty_result_set= true;
2427
2440
  table->status= 0;
2428
 
 
 
2441
 
2429
2442
  /* TODO: change to use of 'full_scan' here? */
2430
2443
  if (copy_ref_key())
2431
2444
    return(1);
2432
2445
  if (table->status)
2433
2446
  {
2434
 
    /* 
2435
 
      We know that there will be no rows even if we scan. 
 
2447
    /*
 
2448
      We know that there will be no rows even if we scan.
2436
2449
      Can be set in copy_ref_key.
2437
2450
    */
2438
2451
    ((Item_in_subselect *) item)->value= 0;
2441
2454
 
2442
2455
  if (null_keypart)
2443
2456
    return(scan_table());
2444
 
 
2445
 
  if (!table->file->inited)
2446
 
    table->file->ha_index_init(tab->ref.key, 0);
2447
 
  error= table->file->index_read_map(table->record[0],
 
2457
 
 
2458
  if (!table->cursor->inited)
 
2459
    table->cursor->ha_index_init(tab->ref.key, 0);
 
2460
  error= table->cursor->index_read_map(table->record[0],
2448
2461
                                     tab->ref.key_buff,
2449
2462
                                     make_prev_keypart_map(tab->ref.key_parts),
2450
2463
                                     HA_READ_KEY_EXACT);
2451
2464
  if (error &&
2452
2465
      error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
2453
 
    error= report_error(table, error);
 
2466
    error= table->report_error(error);
2454
2467
  else
2455
2468
  {
2456
2469
    error= 0;
2473
2486
 
2474
2487
  SYNOPSIS
2475
2488
    subselect_indexsubquery_engine:exec()
2476
 
      full_scan 
 
2489
      full_scan
2477
2490
 
2478
2491
  DESCRIPTION
2479
2492
    The engine is used to resolve subqueries in form
2480
2493
 
2481
 
      oe IN (SELECT key FROM tbl WHERE subq_where) 
 
2494
      oe IN (SELECT key FROM tbl WHERE subq_where)
2482
2495
 
2483
 
    The value of the predicate is calculated as follows: 
 
2496
    The value of the predicate is calculated as follows:
2484
2497
    1. If oe IS NULL, this is a special case, do a full table scan on
2485
 
       table tbl and search for row that satisfies subq_where. If such 
 
2498
       table tbl and search for row that satisfies subq_where. If such
2486
2499
       row is found, return NULL, otherwise return false.
2487
2500
    2. Make an index lookup via key=oe, search for a row that satisfies
2488
2501
       subq_where. If found, return true.
2489
 
    3. If check_null==true, make another lookup via key=NULL, search for a 
 
2502
    3. If check_null==true, make another lookup via key=NULL, search for a
2490
2503
       row that satisfies subq_where. If found, return NULL, otherwise
2491
2504
       return false.
2492
2505
 
2493
2506
  TODO
2494
2507
    The step #1 can be optimized further when the index has several key
2495
2508
    parts. Consider a subquery:
2496
 
    
 
2509
 
2497
2510
      (oe1, oe2) IN (SELECT keypart1, keypart2 FROM tbl WHERE subq_where)
2498
2511
 
2499
2512
    and suppose we need to evaluate it for {oe1, oe2}=={const1, NULL}.
2503
2516
      SELECT keypart1, keypart2 FROM tbl WHERE subq_where            (1)
2504
2517
 
2505
2518
    and checking if it has produced any matching rows, evaluate
2506
 
    
 
2519
 
2507
2520
      SELECT keypart2 FROM tbl WHERE subq_where AND keypart1=const1  (2)
2508
2521
 
2509
 
    If this query produces a row, the result is NULL (as we're evaluating 
 
2522
    If this query produces a row, the result is NULL (as we're evaluating
2510
2523
    "(const1, NULL) IN { (const1, X), ... }", which has a value of UNKNOWN,
2511
2524
    i.e. NULL).  If the query produces no rows, the result is false.
2512
2525
 
2524
2537
{
2525
2538
  int error;
2526
2539
  bool null_finding= 0;
2527
 
  TABLE *table= tab->table;
 
2540
  Table *table= tab->table;
2528
2541
 
2529
2542
  ((Item_in_subselect *) item)->value= 0;
2530
2543
  empty_result_set= true;
2544
2557
 
2545
2558
  if (table->status)
2546
2559
  {
2547
 
    /* 
2548
 
      We know that there will be no rows even if we scan. 
 
2560
    /*
 
2561
      We know that there will be no rows even if we scan.
2549
2562
      Can be set in copy_ref_key.
2550
2563
    */
2551
2564
    ((Item_in_subselect *) item)->value= 0;
2555
2568
  if (null_keypart)
2556
2569
    return(scan_table());
2557
2570
 
2558
 
  if (!table->file->inited)
2559
 
    table->file->ha_index_init(tab->ref.key, 1);
2560
 
  error= table->file->index_read_map(table->record[0],
 
2571
  if (!table->cursor->inited)
 
2572
    table->cursor->ha_index_init(tab->ref.key, 1);
 
2573
  error= table->cursor->index_read_map(table->record[0],
2561
2574
                                     tab->ref.key_buff,
2562
2575
                                     make_prev_keypart_map(tab->ref.key_parts),
2563
2576
                                     HA_READ_KEY_EXACT);
2564
2577
  if (error &&
2565
2578
      error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
2566
 
    error= report_error(table, error);
 
2579
    error= table->report_error(error);
2567
2580
  else
2568
2581
  {
2569
2582
    for (;;)
2581
2594
            ((Item_in_subselect *) item)->value= 1;
2582
2595
          break;
2583
2596
        }
2584
 
        error= table->file->index_next_same(table->record[0],
 
2597
        error= table->cursor->index_next_same(table->record[0],
2585
2598
                                            tab->ref.key_buff,
2586
2599
                                            tab->ref.key_length);
2587
2600
        if (error && error != HA_ERR_END_OF_FILE)
2588
2601
        {
2589
 
          error= report_error(table, error);
 
2602
          error= table->report_error(error);
2590
2603
          break;
2591
2604
        }
2592
2605
      }
2606
2619
}
2607
2620
 
2608
2621
 
2609
 
uint subselect_single_select_engine::cols()
 
2622
uint32_t subselect_single_select_engine::cols()
2610
2623
{
2611
2624
  return select_lex->item_list.elements;
2612
2625
}
2613
2626
 
2614
2627
 
2615
 
uint subselect_union_engine::cols()
 
2628
uint32_t subselect_union_engine::cols()
2616
2629
{
2617
2630
  return unit->types.elements;
2618
2631
}
2648
2661
}
2649
2662
 
2650
2663
 
2651
 
table_map subselect_engine::calc_const_tables(TABLE_LIST *table)
 
2664
table_map subselect_engine::calc_const_tables(TableList *table)
2652
2665
{
2653
2666
  table_map map= 0;
2654
2667
  for (; table; table= table->next_leaf)
2655
2668
  {
2656
 
    TABLE *tbl= table->table;
 
2669
    Table *tbl= table->table;
2657
2670
    if (tbl && tbl->const_table)
2658
2671
      map|= tbl->map;
2659
2672
  }
2663
2676
 
2664
2677
table_map subselect_single_select_engine::upper_select_const_tables()
2665
2678
{
2666
 
  return calc_const_tables((TABLE_LIST *) select_lex->outer_select()->
 
2679
  return calc_const_tables((TableList *) select_lex->outer_select()->
2667
2680
                           leaf_tables);
2668
2681
}
2669
2682
 
2670
2683
 
2671
2684
table_map subselect_union_engine::upper_select_const_tables()
2672
2685
{
2673
 
  return calc_const_tables((TABLE_LIST *) unit->outer_select()->leaf_tables);
 
2686
  return calc_const_tables((TableList *) unit->outer_select()->leaf_tables);
2674
2687
}
2675
2688
 
2676
2689
 
2677
2690
void subselect_single_select_engine::print(String *str,
2678
2691
                                           enum_query_type query_type)
2679
2692
{
2680
 
  select_lex->print(thd, str, query_type);
 
2693
  select_lex->print(session, str, query_type);
2681
2694
}
2682
2695
 
2683
2696
 
2724
2737
{
2725
2738
  KEY *key_info= tab->table->key_info + tab->ref.key;
2726
2739
  str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2727
 
  for (uint i= 0; i < key_info->key_parts; i++)
 
2740
  for (uint32_t i= 0; i < key_info->key_parts; i++)
2728
2741
    tab->ref.items[i]->print(str);
2729
2742
  str->append(STRING_WITH_LEN(" in "));
2730
2743
  str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2819
2832
    true  error
2820
2833
*/
2821
2834
 
2822
 
bool subselect_uniquesubquery_engine::change_result(Item_subselect *si __attribute__((unused)),
2823
 
                                                    select_result_interceptor *res __attribute__((unused)))
 
2835
bool subselect_uniquesubquery_engine::change_result(Item_subselect *,
 
2836
                                                    select_result_interceptor *)
2824
2837
{
2825
2838
  assert(0);
2826
2839
  return true;
2867
2880
*/
2868
2881
bool subselect_union_engine::no_tables()
2869
2882
{
2870
 
  for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
 
2883
  for (Select_Lex *sl= unit->first_select(); sl; sl= sl->next_select())
2871
2884
  {
2872
2885
    if (sl->table_list.elements)
2873
2886
      return false;
2906
2919
    temporary table has one hash index on all its columns.
2907
2920
  - Create a new result sink that sends the result stream of the subquery to
2908
2921
    the temporary table,
2909
 
  - Create and initialize a new JOIN_TAB, and TABLE_REF objects to perform
 
2922
  - Create and initialize a new JoinTable, and TABLE_REF objects to perform
2910
2923
    lookups into the indexed temporary table.
2911
2924
 
2912
2925
  @notice:
2922
2935
  /* The result sink where we will materialize the subquery result. */
2923
2936
  select_union  *tmp_result_sink;
2924
2937
  /* The table into which the subquery is materialized. */
2925
 
  TABLE         *tmp_table;
 
2938
  Table         *tmp_table;
2926
2939
  KEY           *tmp_key; /* The only index on the temporary table. */
2927
 
  uint          tmp_key_parts; /* Number of keyparts in tmp_key. */
 
2940
  uint32_t          tmp_key_parts; /* Number of keyparts in tmp_key. */
2928
2941
  Item_in_subselect *item_in= (Item_in_subselect *) item;
2929
2942
 
2930
2943
  /* 1. Create/initialize materialization related objects. */
2937
2950
  if (!(tmp_result_sink= new select_union))
2938
2951
    return(true);
2939
2952
  if (tmp_result_sink->create_result_table(
2940
 
                         thd, tmp_columns, true,
2941
 
                         thd->options | TMP_TABLE_ALL_COLUMNS,
 
2953
                         session, tmp_columns, true,
 
2954
                         session->options | TMP_TABLE_ALL_COLUMNS,
2942
2955
                         "materialized subselect", true))
2943
2956
    return(true);
2944
2957
 
2955
2968
  */
2956
2969
  if (tmp_table->s->keys == 0)
2957
2970
  {
2958
 
    assert(tmp_table->s->db_type() == myisam_hton);
 
2971
    assert(tmp_table->s->db_type() == myisam_engine);
2959
2972
    assert(
2960
2973
      tmp_table->s->uniques ||
2961
 
      tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
2962
 
      tmp_table->key_info->key_parts > tmp_table->file->max_key_parts());
2963
 
    free_tmp_table(thd, tmp_table);
 
2974
      tmp_table->key_info->key_length >= tmp_table->cursor->getEngine()->max_key_length() ||
 
2975
      tmp_table->key_info->key_parts > tmp_table->cursor->getEngine()->max_key_parts());
 
2976
    tmp_table->free_tmp_table(session);
2964
2977
    delete result;
2965
2978
    result= NULL;
2966
2979
    return(true);
2977
2990
  /* 2. Create/initialize execution related objects. */
2978
2991
 
2979
2992
  /*
2980
 
    Create and initialize the JOIN_TAB that represents an index lookup
 
2993
    Create and initialize the JoinTable that represents an index lookup
2981
2994
    plan operator into the materialized subquery result. Notice that:
2982
 
    - this JOIN_TAB has no corresponding JOIN (and doesn't need one), and
 
2995
    - this JoinTable has no corresponding JOIN (and doesn't need one), and
2983
2996
    - here we initialize only those members that are used by
2984
2997
      subselect_uniquesubquery_engine, so these objects are incomplete.
2985
 
  */ 
2986
 
  if (!(tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
 
2998
  */
 
2999
  if (!(tab= (JoinTable*) session->alloc(sizeof(JoinTable))))
2987
3000
    return(true);
2988
3001
  tab->table= tmp_table;
2989
3002
  tab->ref.key= 0; /* The only temp table index. */
2990
3003
  tab->ref.key_length= tmp_key->key_length;
2991
3004
  if (!(tab->ref.key_buff=
2992
 
        (uchar*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
 
3005
        (unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
2993
3006
      !(tab->ref.key_copy=
2994
 
        (store_key**) thd->alloc((sizeof(store_key*) *
 
3007
        (StoredKey**) session->alloc((sizeof(StoredKey*) *
2995
3008
                                  (tmp_key_parts + 1)))) ||
2996
3009
      !(tab->ref.items=
2997
 
        (Item**) thd->alloc(sizeof(Item*) * tmp_key_parts)))
 
3010
        (Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
2998
3011
    return(true);
2999
3012
 
3000
3013
  KEY_PART_INFO *cur_key_part= tmp_key->key_part;
3001
 
  store_key **ref_key= tab->ref.key_copy;
3002
 
  uchar *cur_ref_buff= tab->ref.key_buff;
3003
 
  
3004
 
  for (uint i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
 
3014
  StoredKey **ref_key= tab->ref.key_copy;
 
3015
  unsigned char *cur_ref_buff= tab->ref.key_buff;
 
3016
 
 
3017
  for (uint32_t i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3005
3018
  {
3006
3019
    tab->ref.items[i]= item_in->left_expr->element_index(i);
3007
3020
    int null_count= test(cur_key_part->field->real_maybe_null());
3008
 
    *ref_key= new store_key_item(thd, cur_key_part->field,
 
3021
    *ref_key= new store_key_item(session, cur_key_part->field,
3009
3022
                                 /* TODO:
3010
3023
                                    the NULL byte is taken into account in
3011
3024
                                    cur_key_part->store_length, so instead of
3051
3064
{
3052
3065
  delete result;
3053
3066
  if (tab)
3054
 
    free_tmp_table(thd, tab->table);
 
3067
    tab->table->free_tmp_table(session);
3055
3068
}
3056
3069
 
3057
3070
 
3093
3106
  if (!is_materialized)
3094
3107
  {
3095
3108
    int res= 0;
3096
 
    SELECT_LEX *save_select= thd->lex->current_select;
3097
 
    thd->lex->current_select= materialize_engine->select_lex;
 
3109
    Select_Lex *save_select= session->lex->current_select;
 
3110
    session->lex->current_select= materialize_engine->select_lex;
3098
3111
    if ((res= materialize_join->optimize()))
3099
3112
      goto err;
3100
3113
    materialize_join->exec();
3101
 
    if ((res= test(materialize_join->error || thd->is_fatal_error)))
 
3114
    if ((res= test(materialize_join->error || session->is_fatal_error)))
3102
3115
      goto err;
3103
3116
 
3104
3117
    /*
3117
3130
      statistics, then we test if the temporary table for the query result is
3118
3131
      empty.
3119
3132
    */
3120
 
    tab->table->file->info(HA_STATUS_VARIABLE);
3121
 
    if (!tab->table->file->stats.records)
 
3133
    tab->table->cursor->info(HA_STATUS_VARIABLE);
 
3134
    if (!tab->table->cursor->stats.records)
3122
3135
    {
3123
3136
      empty_result_set= true;
3124
3137
      item_in->value= false;
3131
3144
      tmp_param= NULL;
3132
3145
 
3133
3146
err:
3134
 
    thd->lex->current_select= save_select;
 
3147
    session->lex->current_select= save_select;
3135
3148
    if (res)
3136
3149
      return(res);
3137
3150
  }