~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item_subselect.cc

  • Committer: Brian Aker
  • Date: 2008-10-12 01:59:02 UTC
  • Revision ID: brian@tangent.org-20081012015902-prhy6wsimdqr28om
Dead code around unsigned (first pass)

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
 
 
 
26
#include <drizzled/server_includes.h>
31
27
#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;
 
28
#include <drizzled/drizzled_error_messages.h>
47
29
 
48
30
inline Item * and_items(Item* cond, Item *item)
49
31
{
50
32
  return (cond? (new Item_cond_and(cond, item)) : item);
51
33
}
52
34
 
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),
 
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),
68
39
  is_correlated(false)
69
40
{
70
41
  with_subselect= 1;
77
48
}
78
49
 
79
50
 
80
 
void Item_subselect::init(Select_Lex *select_lex,
 
51
void Item_subselect::init(st_select_lex *select_lex,
81
52
                          select_result_interceptor *result)
82
53
{
83
54
  /*
90
61
  if (unit->item)
91
62
  {
92
63
    /*
93
 
      Item can be changed in JOIN::prepare while engine in Join::optimize
 
64
      Item can be changed in JOIN::prepare while engine in JOIN::optimize
94
65
      => we do not copy old_engine here
95
66
    */
96
67
    engine= unit->item->engine;
101
72
  }
102
73
  else
103
74
  {
104
 
    Select_Lex *outer_select= unit->outer_select();
 
75
    SELECT_LEX *outer_select= unit->outer_select();
105
76
    /*
106
77
      do not take into account expression inside aggregate functions because
107
78
      they can access original table fields
115
86
      engine= new subselect_single_select_engine(select_lex, result, this);
116
87
  }
117
88
  {
118
 
    Select_Lex *upper= unit->outer_select();
 
89
    SELECT_LEX *upper= unit->outer_select();
119
90
    if (upper->parsing_place == IN_HAVING)
120
91
      upper->subquery_in_having= 1;
121
92
  }
122
93
  return;
123
94
}
124
95
 
125
 
Select_Lex *
 
96
st_select_lex *
126
97
Item_subselect::get_select_lex()
127
98
{
128
99
  return unit->first_select();
172
143
}
173
144
 
174
145
Item_subselect::trans_res
175
 
Item_subselect::select_transformer(Join *)
 
146
Item_subselect::select_transformer(JOIN *join __attribute__((unused)))
176
147
{
177
148
  return(RES_OK);
178
149
}
179
150
 
180
151
 
181
 
bool Item_subselect::fix_fields(Session *session_param, Item **ref)
 
152
bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
182
153
{
183
 
  char const *save_where= session_param->where;
 
154
  char const *save_where= thd_param->where;
 
155
  uint8_t uncacheable;
184
156
  bool res;
185
157
 
186
158
  assert(fixed == 0);
187
 
  engine->set_session((session= session_param));
 
159
  engine->set_thd((thd= thd_param));
188
160
 
189
 
  if (check_stack_overrun(session, STACK_MIN_SIZE, (unsigned char*)&res))
 
161
  if (check_stack_overrun(thd, STACK_MIN_SIZE, (unsigned char*)&res))
190
162
    return true;
191
163
 
192
164
  res= engine->prepare();
208
180
 
209
181
      // did we changed top item of WHERE condition
210
182
      if (unit->outer_select()->where == (*ref))
211
 
      {
212
 
        unit->outer_select()->where= substitution; // correct WHERE for PS
213
 
      }
 
183
        unit->outer_select()->where= substitution; // correct WHERE for PS
214
184
      else if (unit->outer_select()->having == (*ref))
215
 
      {
216
 
        unit->outer_select()->having= substitution; // correct HAVING for PS
217
 
      }
 
185
        unit->outer_select()->having= substitution; // correct HAVING for PS
218
186
 
219
187
      (*ref)= substitution;
220
188
      substitution->name= name;
221
189
      if (have_to_be_excluded)
222
 
      {
223
 
        engine->exclude();
224
 
      }
 
190
        engine->exclude();
225
191
      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;
 
192
      thd->where= "checking transformed subquery";
 
193
      if (!(*ref)->fixed)
 
194
        ret= (*ref)->fix_fields(thd, ref);
 
195
      thd->where= save_where;
232
196
      return ret;
233
197
    }
234
198
    // Is it one field subselect?
241
205
  }
242
206
  else
243
207
    goto err;
244
 
 
245
 
  if (engine->uncacheable())
 
208
  
 
209
  if ((uncacheable= engine->uncacheable()))
246
210
  {
247
211
    const_item_cache= 0;
248
 
    if (engine->uncacheable(UNCACHEABLE_RAND))
249
 
    {
 
212
    if (uncacheable & UNCACHEABLE_RAND)
250
213
      used_tables_cache|= RAND_TABLE_BIT;
251
 
    }
252
214
  }
253
215
  fixed= 1;
254
216
 
255
217
err:
256
 
  session->where= save_where;
 
218
  thd->where= save_where;
257
219
  return res;
258
220
}
259
221
 
264
226
 
265
227
  if (walk_subquery)
266
228
  {
267
 
    for (Select_Lex *lex= unit->first_select(); lex; lex= lex->next_select())
 
229
    for (SELECT_LEX *lex= unit->first_select(); lex; lex= lex->next_select())
268
230
    {
269
231
      List_iterator<Item> li(lex->item_list);
270
232
      Item *item;
271
 
      Order *order;
 
233
      order_st *order;
272
234
 
273
235
      if (lex->where && (lex->where)->walk(processor, walk_subquery, argument))
274
236
        return 1;
281
243
        if (item->walk(processor, walk_subquery, argument))
282
244
          return 1;
283
245
      }
284
 
      for (order= (Order*) lex->order_list.first ; order; order= order->next)
 
246
      for (order= (order_st*) lex->order_list.first ; order; order= order->next)
285
247
      {
286
248
        if ((*order->item)->walk(processor, walk_subquery, argument))
287
249
          return 1;
288
250
      }
289
 
      for (order= (Order*) lex->group_list.first ; order; order= order->next)
 
251
      for (order= (order_st*) lex->group_list.first ; order; order= order->next)
290
252
      {
291
253
        if ((*order->item)->walk(processor, walk_subquery, argument))
292
254
          return 1;
301
263
{
302
264
  int res;
303
265
 
304
 
  if (session->is_error())
 
266
  if (thd->is_error())
305
267
  /* Do not execute subselect in case of a fatal error */
306
268
    return 1;
307
269
 
381
343
  return const_item_cache;
382
344
}
383
345
 
384
 
Item *Item_subselect::get_tmp_table_item(Session *session_arg)
 
346
Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
385
347
{
386
348
  if (!with_sum_func && !const_item())
387
349
    return new Item_field(result_field);
388
 
  return copy_or_same(session_arg);
 
350
  return copy_or_same(thd_arg);
389
351
}
390
352
 
391
353
void Item_subselect::update_used_tables()
392
354
{
393
 
  if (! engine->uncacheable())
 
355
  if (!engine->uncacheable())
394
356
  {
395
357
    // did all used tables become static?
396
358
    if (!(used_tables_cache & ~engine->upper_select_const_tables()))
407
369
}
408
370
 
409
371
 
410
 
Item_singlerow_subselect::Item_singlerow_subselect(Select_Lex *select_lex)
 
372
Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex)
411
373
  :Item_subselect(), value(0)
412
374
{
413
375
  init(select_lex, new select_singlerow_subselect(this));
416
378
  return;
417
379
}
418
380
 
419
 
Select_Lex *
 
381
st_select_lex *
420
382
Item_singlerow_subselect::invalidate_and_restore_select_lex()
421
383
{
422
 
  Select_Lex *result= get_select_lex();
 
384
  st_select_lex *result= get_select_lex();
423
385
 
424
386
  assert(result);
425
387
 
426
388
  /*
427
389
    This code restore the parse tree in it's state before the execution of
428
390
    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
 
391
    and in particular decouples this object from the SELECT_LEX,
 
392
    so that the SELECT_LEX can be used with a different flavor
431
393
    or Item_subselect instead, as part of query rewriting.
432
394
  */
433
395
  unit->item= NULL;
435
397
  return(result);
436
398
}
437
399
 
438
 
Item_maxmin_subselect::Item_maxmin_subselect(Session *session_param,
 
400
Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,
439
401
                                             Item_subselect *parent,
440
 
                                             Select_Lex *select_lex,
 
402
                                             st_select_lex *select_lex,
441
403
                                             bool max_arg)
442
404
  :Item_singlerow_subselect(), was_values(true)
443
405
{
456
418
 
457
419
  /*
458
420
    this subquery always creates during preparation, so we can assign
459
 
    session here
 
421
    thd here
460
422
  */
461
 
  session= session_param;
 
423
  thd= thd_param;
462
424
 
463
425
  return;
464
426
}
506
468
  Make rollback for it, or special name resolving mode in 5.0.
507
469
*/
508
470
Item_subselect::trans_res
509
 
Item_singlerow_subselect::select_transformer(Join *join)
 
471
Item_singlerow_subselect::select_transformer(JOIN *join)
510
472
{
511
473
  if (changed)
512
474
    return(RES_OK);
513
475
 
514
 
  Select_Lex *select_lex= join->select_lex;
515
 
 
 
476
  SELECT_LEX *select_lex= join->select_lex;
 
477
 
516
478
  if (!select_lex->master_unit()->is_union() &&
517
479
      !select_lex->table_list.elements &&
518
480
      select_lex->item_list.elements == 1 &&
531
493
  {
532
494
 
533
495
    have_to_be_excluded= 1;
534
 
    if (session->lex->describe)
 
496
    if (thd->lex->describe)
535
497
    {
536
498
      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,
 
499
      sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
 
500
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
539
501
                   ER_SELECT_REDUCED, warn_buff);
540
502
    }
541
503
    substitution= select_lex->item_list.head();
561
523
  return engine->type();
562
524
}
563
525
 
564
 
/*
565
 
 Don't rely on the result type to calculate field type.
 
526
/* 
 
527
 Don't rely on the result type to calculate field type. 
566
528
 Ask the engine instead.
567
529
*/
568
530
enum_field_types Item_singlerow_subselect::field_type() const
578
540
  }
579
541
  else
580
542
  {
581
 
    if (!(row= (Item_cache**) memory::sql_alloc(sizeof(Item_cache*)*max_columns)))
 
543
    if (!(row= (Item_cache**) sql_alloc(sizeof(Item_cache*)*max_columns)))
582
544
      return;
583
545
    engine->fix_length_and_dec(row);
584
546
    value= *row;
698
660
}
699
661
 
700
662
 
701
 
Item_exists_subselect::Item_exists_subselect(Select_Lex *select_lex):
 
663
Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex):
702
664
  Item_subselect()
703
665
{
704
666
  bool val_bool();
718
680
}
719
681
 
720
682
 
721
 
bool Item_in_subselect::test_limit(Select_Lex_Unit *unit_arg)
 
683
bool Item_in_subselect::test_limit(st_select_lex_unit *unit_arg)
722
684
{
723
685
  if (unit_arg->fake_select_lex &&
724
686
      unit_arg->fake_select_lex->test_limit())
725
687
    return(1);
726
688
 
727
 
  Select_Lex *sl= unit_arg->first_select();
 
689
  SELECT_LEX *sl= unit_arg->first_select();
728
690
  for (; sl; sl= sl->next_select())
729
691
  {
730
692
    if (sl->test_limit())
734
696
}
735
697
 
736
698
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)
 
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)
748
703
{
 
704
  left_expr= left_exp;
749
705
  init(select_lex, new select_exists_subselect(this));
750
706
  max_columns= UINT_MAX;
751
707
  maybe_null= 1;
758
714
 
759
715
Item_allany_subselect::Item_allany_subselect(Item * left_exp,
760
716
                                             chooser_compare_func_creator fc,
761
 
                                             Select_Lex *select_lex,
 
717
                                             st_select_lex *select_lex,
762
718
                                             bool all_arg)
763
719
  :Item_in_subselect(), func_creator(fc), all(all_arg)
764
720
{
916
872
  if (exec())
917
873
  {
918
874
    reset();
919
 
    /*
 
875
    /* 
920
876
      Must mark the IN predicate as NULL so as to make sure an enclosing NOT
921
 
      predicate will return false. See the comments in
 
877
      predicate will return false. See the comments in 
922
878
      subselect_uniquesubquery_engine::copy_ref_key for further details.
923
879
    */
924
880
    null_value= 1;
951
907
}
952
908
 
953
909
 
954
 
/*
 
910
/* 
955
911
  Rewrite a single-column IN/ALL/ANY subselect
956
912
 
957
913
  SYNOPSIS
961
917
 
962
918
  DESCRIPTION
963
919
    Rewrite a single-column subquery using rule-based approach. The subquery
964
 
 
 
920
    
965
921
       oe $cmp$ (SELECT ie FROM ... WHERE subq_where ... HAVING subq_having)
966
 
 
 
922
    
967
923
    First, try to convert the subquery to scalar-result subquery in one of
968
924
    the forms:
969
 
 
 
925
    
970
926
       - oe $cmp$ (SELECT MAX(...) )  // handled by Item_singlerow_subselect
971
927
       - oe $cmp$ <max>(SELECT ...)   // handled by Item_maxmin_subselect
972
 
 
 
928
   
973
929
    If that fails, the subquery will be handled with class Item_in_optimizer.
974
930
    There are two possibilites:
975
931
    - If the subquery execution method is materialization, then the subquery is
986
942
*/
987
943
 
988
944
Item_subselect::trans_res
989
 
Item_in_subselect::single_value_transformer(Join *join,
990
 
                                            const Comp_creator *func)
 
945
Item_in_subselect::single_value_transformer(JOIN *join,
 
946
                                            Comp_creator *func)
991
947
{
992
 
  Select_Lex *select_lex= join->select_lex;
 
948
  SELECT_LEX *select_lex= join->select_lex;
993
949
 
994
950
  /*
995
951
    Check that the right part of the subselect contains no more than one
1013
969
    later in this method.
1014
970
  */
1015
971
  if ((abort_on_null || (upper_item && upper_item->top_level())) &&
1016
 
      select_lex->master_unit()->uncacheable.none() && !func->eqne_op())
 
972
      !select_lex->master_unit()->uncacheable && !func->eqne_op())
1017
973
  {
1018
974
    if (substitution)
1019
975
    {
1055
1011
        it.replace(item);
1056
1012
      }
1057
1013
 
1058
 
      save_allow_sum_func= session->lex->allow_sum_func;
1059
 
      session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
 
1014
      save_allow_sum_func= thd->lex->allow_sum_func;
 
1015
      thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
1060
1016
      /*
1061
1017
        Item_sum_(max|min) can't substitute other item => we can use 0 as
1062
1018
        reference, also Item_sum_(max|min) can't be fixed after creation, so
1063
1019
        we do not check item->fixed
1064
1020
      */
1065
 
      if (item->fix_fields(session, 0))
 
1021
      if (item->fix_fields(thd, 0))
1066
1022
        return(RES_ERROR);
1067
 
      session->lex->allow_sum_func= save_allow_sum_func;
 
1023
      thd->lex->allow_sum_func= save_allow_sum_func; 
1068
1024
      /* we added aggregate function => we have to change statistic */
1069
 
      count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
 
1025
      count_field_types(select_lex, &join->tmp_table_param, join->all_fields, 
1070
1026
                        0);
1071
1027
 
1072
1028
      subs= new Item_singlerow_subselect(select_lex);
1074
1030
    else
1075
1031
    {
1076
1032
      Item_maxmin_subselect *item;
1077
 
      subs= item= new Item_maxmin_subselect(session, this, select_lex, func->l_op());
 
1033
      subs= item= new Item_maxmin_subselect(thd, this, select_lex, func->l_op());
1078
1034
      if (upper_item)
1079
1035
        upper_item->set_sub_test(item);
1080
1036
    }
1086
1042
  if (!substitution)
1087
1043
  {
1088
1044
    /* We're invoked for the 1st (or the only) SELECT in the subquery UNION */
1089
 
    Select_Lex_Unit *master_unit= select_lex->master_unit();
 
1045
    SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
1090
1046
    substitution= optimizer;
1091
1047
 
1092
 
    Select_Lex *current= session->lex->current_select, *up;
 
1048
    SELECT_LEX *current= thd->lex->current_select, *up;
1093
1049
 
1094
 
    session->lex->current_select= up= current->return_after_parsing();
 
1050
    thd->lex->current_select= up= current->return_after_parsing();
1095
1051
    //optimizer never use Item **ref => we can pass 0 as parameter
1096
 
    if (!optimizer || optimizer->fix_left(session, 0))
 
1052
    if (!optimizer || optimizer->fix_left(thd, 0))
1097
1053
    {
1098
 
      session->lex->current_select= current;
 
1054
      thd->lex->current_select= current;
1099
1055
      return(RES_ERROR);
1100
1056
    }
1101
 
    session->lex->current_select= current;
 
1057
    thd->lex->current_select= current;
1102
1058
 
1103
1059
    /*
1104
1060
      As far as  Item_ref_in_optimizer do not substitute itself on fix_fields
1109
1065
                              (char *)"<no matter>",
1110
1066
                              (char *)in_left_expr_name);
1111
1067
 
1112
 
    master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1068
    master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1113
1069
  }
1114
1070
 
1115
1071
  if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1116
1072
  {
1117
 
    if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool))))
 
1073
    if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool))))
1118
1074
      return(RES_ERROR);
1119
1075
    pushed_cond_guards[0]= true;
1120
1076
  }
1139
1095
 
1140
1096
  - If the subquery has aggregates, GROUP BY, or HAVING, convert to
1141
1097
 
1142
 
    SELECT ie FROM ...  HAVING subq_having AND
 
1098
    SELECT ie FROM ...  HAVING subq_having AND 
1143
1099
                               trigcond(oe $cmp$ ref_or_null_helper<ie>)
1144
 
 
 
1100
                                   
1145
1101
    the addition is wrapped into trigger only when we want to distinguish
1146
1102
    between NULL and false results.
1147
1103
 
1149
1105
    following:
1150
1106
 
1151
1107
    = If we don't need to distinguish between NULL and false subquery:
1152
 
 
 
1108
        
1153
1109
      SELECT 1 FROM ... WHERE (oe $cmp$ ie) AND subq_where
1154
1110
 
1155
1111
    = If we need to distinguish between those:
1168
1124
*/
1169
1125
 
1170
1126
Item_subselect::trans_res
1171
 
Item_in_subselect::single_value_in_to_exists_transformer(Join * join, const Comp_creator *func)
 
1127
Item_in_subselect::single_value_in_to_exists_transformer(JOIN * join, Comp_creator *func)
1172
1128
{
1173
 
  Select_Lex *select_lex= join->select_lex;
 
1129
  SELECT_LEX *select_lex= join->select_lex;
1174
1130
 
1175
 
  select_lex->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1131
  select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1176
1132
  if (join->having || select_lex->with_sum_func ||
1177
1133
      select_lex->group_list.elements)
1178
1134
  {
1186
1142
                                                      this->full_name()));
1187
1143
    if (!abort_on_null && left_expr->maybe_null)
1188
1144
    {
1189
 
      /*
 
1145
      /* 
1190
1146
        We can encounter "NULL IN (SELECT ...)". Wrap the added condition
1191
1147
        within a trig_cond.
1192
1148
      */
1193
1149
      item= new Item_func_trig_cond(item, get_cond_guard(0));
1194
1150
    }
1195
 
 
 
1151
    
1196
1152
    /*
1197
1153
      AND and comparison functions can't be changed during fix_fields()
1198
1154
      we can assign select_lex->having here, and pass 0 as last
1206
1162
      we do not check join->having->fixed, because Item_and (from and_items)
1207
1163
      or comparison function (from func->create) can't be fixed after creation
1208
1164
    */
1209
 
    tmp= join->having->fix_fields(session, 0);
 
1165
    tmp= join->having->fix_fields(thd, 0);
1210
1166
    select_lex->having_fix_field= 0;
1211
1167
    if (tmp)
1212
1168
      return(RES_ERROR);
1224
1180
                                                   (int64_t) 1,
1225
1181
                                                   MY_INT64_NUM_DECIMAL_DIGITS));
1226
1182
      select_lex->ref_pointer_array[0]= select_lex->item_list.head();
1227
 
 
 
1183
       
1228
1184
      item= func->create(expr, item);
1229
1185
      if (!abort_on_null && orig_item->maybe_null)
1230
1186
      {
1248
1204
          and_items) or comparison function (from func->create) can't be
1249
1205
          fixed after creation
1250
1206
        */
1251
 
        tmp= join->having->fix_fields(session, 0);
 
1207
        tmp= join->having->fix_fields(thd, 0);
1252
1208
        select_lex->having_fix_field= 0;
1253
1209
        if (tmp)
1254
1210
          return(RES_ERROR);
1255
1211
        item= new Item_cond_or(item,
1256
1212
                               new Item_func_isnull(orig_item));
1257
1213
      }
1258
 
      /*
 
1214
      /* 
1259
1215
        If we may encounter NULL IN (SELECT ...) and care whether subquery
1260
1216
        result is NULL or false, wrap condition in a trig_cond.
1261
1217
      */
1265
1221
          return(RES_ERROR);
1266
1222
      }
1267
1223
      /*
1268
 
        TODO: figure out why the following is done here in
 
1224
        TODO: figure out why the following is done here in 
1269
1225
        single_value_transformer but there is no corresponding action in
1270
1226
        row_value_transformer?
1271
1227
      */
1282
1238
        we do not check join->conds->fixed, because Item_and can't be fixed
1283
1239
        after creation
1284
1240
      */
1285
 
      if (join->conds->fix_fields(session, 0))
 
1241
      if (join->conds->fix_fields(thd, 0))
1286
1242
        return(RES_ERROR);
1287
1243
    }
1288
1244
    else
1310
1266
        new_having->name= (char*)in_having_cond;
1311
1267
        select_lex->having= join->having= new_having;
1312
1268
        select_lex->having_fix_field= 1;
1313
 
 
 
1269
        
1314
1270
        /*
1315
1271
          we do not check join->having->fixed, because comparison function
1316
1272
          (from func->create) can't be fixed after creation
1317
1273
        */
1318
 
        tmp= join->having->fix_fields(session, 0);
 
1274
        tmp= join->having->fix_fields(thd, 0);
1319
1275
        select_lex->having_fix_field= 0;
1320
1276
        if (tmp)
1321
1277
          return(RES_ERROR);
1327
1283
        // fix_field of item will be done in time of substituting
1328
1284
        substitution= item;
1329
1285
        have_to_be_excluded= 1;
1330
 
        if (session->lex->describe)
 
1286
        if (thd->lex->describe)
1331
1287
        {
1332
1288
          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,
 
1289
          sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
 
1290
          push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1335
1291
                       ER_SELECT_REDUCED, warn_buff);
1336
1292
        }
1337
1293
        return(RES_REDUCE);
1344
1300
 
1345
1301
 
1346
1302
Item_subselect::trans_res
1347
 
Item_in_subselect::row_value_transformer(Join *join)
 
1303
Item_in_subselect::row_value_transformer(JOIN *join)
1348
1304
{
1349
 
  Select_Lex *select_lex= join->select_lex;
 
1305
  SELECT_LEX *select_lex= join->select_lex;
1350
1306
  uint32_t cols_num= left_expr->cols();
1351
1307
 
1352
1308
  if (select_lex->item_list.elements != left_expr->cols())
1362
1318
  if (!substitution)
1363
1319
  {
1364
1320
    //first call for this unit
1365
 
    Select_Lex_Unit *master_unit= select_lex->master_unit();
 
1321
    SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
1366
1322
    substitution= optimizer;
1367
1323
 
1368
 
    Select_Lex *current= session->lex->current_select, *up;
1369
 
    session->lex->current_select= up= current->return_after_parsing();
 
1324
    SELECT_LEX *current= thd->lex->current_select, *up;
 
1325
    thd->lex->current_select= up= current->return_after_parsing();
1370
1326
    //optimizer never use Item **ref => we can pass 0 as parameter
1371
 
    if (!optimizer || optimizer->fix_left(session, 0))
 
1327
    if (!optimizer || optimizer->fix_left(thd, 0))
1372
1328
    {
1373
 
      session->lex->current_select= current;
 
1329
      thd->lex->current_select= current;
1374
1330
      return(RES_ERROR);
1375
1331
    }
1376
1332
 
1377
1333
    // we will refer to upper level cache array => we have to save it in PS
1378
1334
    optimizer->keep_top_level_cache();
1379
1335
 
1380
 
    session->lex->current_select= current;
1381
 
    master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1336
    thd->lex->current_select= current;
 
1337
    master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1382
1338
 
1383
1339
    if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1384
1340
    {
1385
 
      if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool) *
 
1341
      if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool) *
1386
1342
                                                        left_expr->cols())))
1387
1343
        return(RES_ERROR);
1388
1344
      for (uint32_t i= 0; i < cols_num; i++)
1421
1377
*/
1422
1378
 
1423
1379
Item_subselect::trans_res
1424
 
Item_in_subselect::row_value_in_to_exists_transformer(Join * join)
 
1380
Item_in_subselect::row_value_in_to_exists_transformer(JOIN * join)
1425
1381
{
1426
 
  Select_Lex *select_lex= join->select_lex;
 
1382
  SELECT_LEX *select_lex= join->select_lex;
1427
1383
  Item *having_item= 0;
1428
1384
  uint32_t cols_num= left_expr->cols();
1429
1385
  bool is_having_used= (join->having || select_lex->with_sum_func ||
1430
1386
                        select_lex->group_list.first ||
1431
1387
                        !select_lex->table_list.elements);
1432
1388
 
1433
 
  select_lex->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1389
  select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1434
1390
  if (is_having_used)
1435
1391
  {
1436
1392
    /*
1483
1439
          return(RES_ERROR);
1484
1440
      }
1485
1441
      having_item= and_items(having_item, col_item);
1486
 
 
1487
 
      Item *item_nnull_test=
 
1442
      
 
1443
      Item *item_nnull_test= 
1488
1444
         new Item_is_not_null_test(this,
1489
1445
                                   new Item_ref(&select_lex->context,
1490
1446
                                                select_lex->
1493
1449
                                                (char *)"<list ref>"));
1494
1450
      if (!abort_on_null && left_expr->element_index(i)->maybe_null)
1495
1451
      {
1496
 
        if (!(item_nnull_test=
 
1452
        if (!(item_nnull_test= 
1497
1453
              new Item_func_trig_cond(item_nnull_test, get_cond_guard(i))))
1498
1454
          return(RES_ERROR);
1499
1455
      }
1552
1508
        Item *having_col_item=
1553
1509
          new Item_is_not_null_test(this,
1554
1510
                                    new
1555
 
                                    Item_ref(&select_lex->context,
 
1511
                                    Item_ref(&select_lex->context, 
1556
1512
                                             select_lex->ref_pointer_array + i,
1557
1513
                                             (char *)"<no matter>",
1558
1514
                                             (char *)"<list ref>"));
1559
 
 
1560
 
 
 
1515
        
 
1516
        
1561
1517
        item_isnull= new
1562
1518
          Item_func_isnull(new
1563
1519
                           Item_direct_ref(&select_lex->context,
1567
1523
                                           (char *)"<list ref>")
1568
1524
                          );
1569
1525
        item= new Item_cond_or(item, item_isnull);
1570
 
        /*
 
1526
        /* 
1571
1527
          TODO: why we create the above for cases where the right part
1572
1528
                cant be NULL?
1573
1529
        */
1575
1531
        {
1576
1532
          if (!(item= new Item_func_trig_cond(item, get_cond_guard(i))))
1577
1533
            return(RES_ERROR);
1578
 
          if (!(having_col_item=
 
1534
          if (!(having_col_item= 
1579
1535
                  new Item_func_trig_cond(having_col_item, get_cond_guard(i))))
1580
1536
            return(RES_ERROR);
1581
1537
        }
1590
1546
    */
1591
1547
    select_lex->where= join->conds= and_items(join->conds, where_item);
1592
1548
    select_lex->where->top_level_item();
1593
 
    if (join->conds->fix_fields(session, 0))
 
1549
    if (join->conds->fix_fields(thd, 0))
1594
1550
      return(RES_ERROR);
1595
1551
  }
1596
1552
  if (having_item)
1606
1562
      argument (reference) to fix_fields()
1607
1563
    */
1608
1564
    select_lex->having_fix_field= 1;
1609
 
    res= join->having->fix_fields(session, 0);
 
1565
    res= join->having->fix_fields(thd, 0);
1610
1566
    select_lex->having_fix_field= 0;
1611
1567
    if (res)
1612
1568
    {
1619
1575
 
1620
1576
 
1621
1577
Item_subselect::trans_res
1622
 
Item_in_subselect::select_transformer(Join *join)
 
1578
Item_in_subselect::select_transformer(JOIN *join)
1623
1579
{
1624
 
  return select_in_like_transformer(join, Eq_creator::instance());
 
1580
  return select_in_like_transformer(join, &eq_creator);
1625
1581
}
1626
1582
 
1627
1583
 
1647
1603
*/
1648
1604
 
1649
1605
Item_subselect::trans_res
1650
 
Item_in_subselect::select_in_like_transformer(Join *join, const Comp_creator *func)
 
1606
Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
1651
1607
{
1652
 
  Select_Lex *current= session->lex->current_select, *up;
1653
 
  const char *save_where= session->where;
 
1608
  SELECT_LEX *current= thd->lex->current_select, *up;
 
1609
  const char *save_where= thd->where;
1654
1610
  Item_subselect::trans_res res= RES_ERROR;
1655
1611
  bool result;
1656
1612
 
1657
1613
  {
1658
1614
    /*
1659
1615
      IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
1660
 
      ORDER BY clause becomes meaningless thus we drop it here.
 
1616
      order_st BY clause becomes meaningless thus we drop it here.
1661
1617
    */
1662
 
    Select_Lex *sl= current->master_unit()->first_select();
 
1618
    SELECT_LEX *sl= current->master_unit()->first_select();
1663
1619
    for (; sl; sl= sl->next_select())
1664
1620
    {
1665
1621
      if (sl->join)
1670
1626
  if (changed)
1671
1627
    return(RES_OK);
1672
1628
 
1673
 
  session->where= "IN/ALL/ANY subquery";
 
1629
  thd->where= "IN/ALL/ANY subquery";
1674
1630
 
1675
1631
  /*
1676
1632
    In some optimisation cases we will not need this Item_in_optimizer
1684
1640
      goto err;
1685
1641
  }
1686
1642
 
1687
 
  session->lex->current_select= up= current->return_after_parsing();
 
1643
  thd->lex->current_select= up= current->return_after_parsing();
1688
1644
  result= (!left_expr->fixed &&
1689
 
           left_expr->fix_fields(session, optimizer->arguments()));
 
1645
           left_expr->fix_fields(thd, optimizer->arguments()));
1690
1646
  /* fix_fields can change reference to left_expr, we need reassign it */
1691
1647
  left_expr= optimizer->arguments()[0];
1692
1648
 
1693
 
  session->lex->current_select= current;
 
1649
  thd->lex->current_select= current;
1694
1650
  if (result)
1695
1651
    goto err;
1696
1652
 
1713
1669
  else
1714
1670
  {
1715
1671
    /* we do not support row operation for ALL/ANY/SOME */
1716
 
    if (func != Eq_creator::instance())
 
1672
    if (func != &eq_creator)
1717
1673
    {
1718
1674
      my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
1719
1675
      return(RES_ERROR);
1721
1677
    res= row_value_transformer(join);
1722
1678
  }
1723
1679
err:
1724
 
  session->where= save_where;
 
1680
  thd->where= save_where;
1725
1681
  return(res);
1726
1682
}
1727
1683
 
1739
1695
}
1740
1696
 
1741
1697
 
1742
 
bool Item_in_subselect::fix_fields(Session *session_arg, Item **ref)
 
1698
bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
1743
1699
{
1744
1700
  bool result = 0;
1745
1701
 
1746
1702
  if (exec_method == SEMI_JOIN)
1747
1703
    return !( (*ref)= new Item_int(1));
1748
1704
 
1749
 
  return result || Item_subselect::fix_fields(session_arg, ref);
 
1705
  return result || Item_subselect::fix_fields(thd_arg, ref);
1750
1706
}
1751
1707
 
1752
1708
 
1782
1738
  if (engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE)
1783
1739
  {
1784
1740
    /* 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)) ||
 
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)) ||
1791
1747
        new_engine->init_permanent(unit->get_unit_column_types()))
1792
1748
    {
1793
 
      Item_subselect::trans_res new_trans_res;
 
1749
      Item_subselect::trans_res trans_res;
1794
1750
      /*
1795
1751
        If for some reason we cannot use materialization for this IN predicate,
1796
1752
        delete all materialization-related objects, and apply the IN=>EXISTS
1800
1756
      new_engine= NULL;
1801
1757
      exec_method= NOT_TRANSFORMED;
1802
1758
      if (left_expr->cols() == 1)
1803
 
        new_trans_res= single_value_in_to_exists_transformer(
1804
 
                           old_engine_ptr->join,
1805
 
                           Eq_creator::instance());
 
1759
        trans_res= single_value_in_to_exists_transformer(old_engine->join,
 
1760
                                                         &eq_creator);
1806
1761
      else
1807
 
        new_trans_res= row_value_in_to_exists_transformer(old_engine_ptr->join);
1808
 
      res= (new_trans_res != Item_subselect::RES_OK);
 
1762
        trans_res= row_value_in_to_exists_transformer(old_engine->join);
 
1763
      res= (trans_res != Item_subselect::RES_OK);
1809
1764
    }
1810
1765
    if (new_engine)
1811
1766
      engine= new_engine;
1813
1768
  else
1814
1769
  {
1815
1770
    assert(engine->engine_type() == subselect_engine::HASH_SJ_ENGINE);
1816
 
    new_engine= static_cast<subselect_hash_sj_engine *>(engine);
 
1771
    new_engine= (subselect_hash_sj_engine*) engine;
1817
1772
  }
1818
1773
 
1819
1774
  /* Initilizations done in runtime memory, repeated for each execution. */
1850
1805
 
1851
1806
bool Item_in_subselect::init_left_expr_cache()
1852
1807
{
1853
 
  Join *outer_join= NULL;
 
1808
  JOIN *outer_join;
 
1809
  Next_select_func end_select;
 
1810
  bool use_result_field= false;
1854
1811
 
1855
1812
  outer_join= unit->outer_select()->join;
1856
 
  if (! outer_join || ! outer_join->tables || ! outer_join->join_tab)
 
1813
  if (!outer_join || !outer_join->tables)
1857
1814
    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;
1858
1827
 
1859
1828
  if (!(left_expr_cache= new List<Cached_item>))
1860
1829
    return true;
1861
1830
 
1862
1831
  for (uint32_t i= 0; i < left_expr->cols(); i++)
1863
1832
  {
1864
 
    Cached_item *cur_item_cache= new_Cached_item(session, left_expr->element_index(i));
 
1833
    Cached_item *cur_item_cache= new_Cached_item(thd,
 
1834
                                                 left_expr->element_index(i),
 
1835
                                                 use_result_field);
1865
1836
    if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
1866
1837
      return true;
1867
1838
  }
1882
1853
  @retval false otherwise
1883
1854
*/
1884
1855
 
1885
 
bool Item_in_subselect::is_expensive_processor(unsigned char *)
 
1856
bool Item_in_subselect::is_expensive_processor(unsigned char *arg __attribute__((unused)))
1886
1857
{
1887
1858
  return exec_method == MATERIALIZATION;
1888
1859
}
1889
1860
 
1890
1861
 
1891
1862
Item_subselect::trans_res
1892
 
Item_allany_subselect::select_transformer(Join *join)
 
1863
Item_allany_subselect::select_transformer(JOIN *join)
1893
1864
{
1894
1865
  exec_method= IN_TO_EXISTS;
1895
1866
  if (upper_item)
1913
1884
}
1914
1885
 
1915
1886
 
1916
 
void subselect_engine::set_session(Session *session_arg)
 
1887
void subselect_engine::set_thd(THD *thd_arg)
1917
1888
{
1918
 
  session= session_arg;
 
1889
  thd= thd_arg;
1919
1890
  if (result)
1920
 
    result->set_session(session_arg);
 
1891
    result->set_thd(thd_arg);
1921
1892
}
1922
1893
 
1923
1894
 
1924
1895
subselect_single_select_engine::
1925
 
subselect_single_select_engine(Select_Lex *select,
 
1896
subselect_single_select_engine(st_select_lex *select,
1926
1897
                               select_result_interceptor *result_arg,
1927
1898
                               Item_subselect *item_arg)
1928
1899
  :subselect_engine(item_arg, result_arg),
1980
1951
void subselect_uniquesubquery_engine::cleanup()
1981
1952
{
1982
1953
  /* Tell handler we don't need the index anymore */
1983
 
  if (tab->table->cursor->inited)
1984
 
    tab->table->cursor->endIndexScan();
 
1954
  if (tab->table->file->inited)
 
1955
    tab->table->file->ha_index_end();
1985
1956
  return;
1986
1957
}
1987
1958
 
1988
1959
 
1989
 
subselect_union_engine::subselect_union_engine(Select_Lex_Unit *u,
 
1960
subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
1990
1961
                                               select_result_interceptor *result_arg,
1991
1962
                                               Item_subselect *item_arg)
1992
1963
  :subselect_engine(item_arg, result_arg)
2026
1997
{
2027
1998
  if (prepared)
2028
1999
    return 0;
2029
 
  join= new Join(session, select_lex->item_list,
 
2000
  join= new JOIN(thd, select_lex->item_list,
2030
2001
                 select_lex->options | SELECT_NO_UNLOCK, result);
2031
2002
  if (!join || !result)
2032
2003
    return 1; /* Fatal error is set already. */
2033
2004
  prepared= 1;
2034
 
  Select_Lex *save_select= session->lex->current_select;
2035
 
  session->lex->current_select= select_lex;
 
2005
  SELECT_LEX *save_select= thd->lex->current_select;
 
2006
  thd->lex->current_select= select_lex;
2036
2007
  if (join->prepare(&select_lex->ref_pointer_array,
2037
2008
                    (TableList*) select_lex->table_list.first,
2038
2009
                    select_lex->with_wild,
2039
2010
                    select_lex->where,
2040
2011
                    select_lex->order_list.elements +
2041
2012
                    select_lex->group_list.elements,
2042
 
                    (Order*) select_lex->order_list.first,
2043
 
                    (Order*) select_lex->group_list.first,
 
2013
                    (order_st*) select_lex->order_list.first,
 
2014
                    (order_st*) select_lex->group_list.first,
2044
2015
                    select_lex->having,
2045
 
                    select_lex, select_lex->master_unit()))
 
2016
                    (order_st*) 0, select_lex,
 
2017
                    select_lex->master_unit()))
2046
2018
    return 1;
2047
 
  session->lex->current_select= save_select;
 
2019
  thd->lex->current_select= save_select;
2048
2020
  return 0;
2049
2021
}
2050
2022
 
2051
2023
int subselect_union_engine::prepare()
2052
2024
{
2053
 
  return unit->prepare(session, result, (uint32_t)SELECT_NO_UNLOCK);
 
2025
  return unit->prepare(thd, result, SELECT_NO_UNLOCK);
2054
2026
}
2055
2027
 
2056
2028
int subselect_uniquesubquery_engine::prepare()
2077
2049
*/
2078
2050
 
2079
2051
bool subselect_single_select_engine::no_rows()
2080
 
{
 
2052
2081
2053
  return !item->assigned();
2082
2054
}
2083
2055
 
2084
2056
 
2085
 
/*
2086
 
 makes storage for the output values for the subquery and calcuates
 
2057
/* 
 
2058
 makes storage for the output values for the subquery and calcuates 
2087
2059
 their data and column types and their nullability.
2088
 
*/
 
2060
*/ 
2089
2061
void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
2090
2062
{
2091
2063
  Item *sel_item;
2134
2106
  }
2135
2107
}
2136
2108
 
2137
 
void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **)
 
2109
void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row __attribute__((unused)))
2138
2110
{
2139
2111
  //this never should be called
2140
2112
  assert(0);
2141
2113
}
2142
2114
 
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);
 
2115
int  init_read_record_seq(JOIN_TAB *tab);
 
2116
int join_read_always_key_or_null(JOIN_TAB *tab);
 
2117
int join_read_next_same_or_null(READ_RECORD *info);
2146
2118
 
2147
2119
int subselect_single_select_engine::exec()
2148
2120
{
2149
 
  char const *save_where= session->where;
2150
 
  Select_Lex *save_select= session->lex->current_select;
2151
 
  session->lex->current_select= select_lex;
 
2121
  char const *save_where= thd->where;
 
2122
  SELECT_LEX *save_select= thd->lex->current_select;
 
2123
  thd->lex->current_select= select_lex;
2152
2124
  if (!join->optimized)
2153
2125
  {
2154
 
    Select_Lex_Unit *unit= select_lex->master_unit();
 
2126
    SELECT_LEX_UNIT *unit= select_lex->master_unit();
2155
2127
 
2156
2128
    unit->set_limit(unit->global_parameters);
 
2129
    if (join->flatten_subqueries())
 
2130
    {
 
2131
      thd->is_fatal_error= true;
 
2132
      return(1);
 
2133
    }
2157
2134
    if (join->optimize())
2158
2135
    {
2159
 
      session->where= save_where;
 
2136
      thd->where= save_where;
2160
2137
      executed= 1;
2161
 
      session->lex->current_select= save_select;
 
2138
      thd->lex->current_select= save_select;
2162
2139
      return(join->error ? join->error : 1);
2163
2140
    }
2164
 
    if (select_lex->uncacheable.none() && session->lex->describe &&
2165
 
        !(join->select_options & SELECT_DESCRIBE) &&
 
2141
    if (!select_lex->uncacheable && thd->lex->describe && 
 
2142
        !(join->select_options & SELECT_DESCRIBE) && 
2166
2143
        join->need_tmp && item->const_item())
2167
2144
    {
2168
2145
      /*
2171
2148
        called by EXPLAIN and we need to preserve the initial query structure
2172
2149
        so we can display it.
2173
2150
       */
2174
 
      select_lex->uncacheable.set(UNCACHEABLE_EXPLAIN);
2175
 
      select_lex->master_unit()->uncacheable.set(UNCACHEABLE_EXPLAIN);
 
2151
      select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
 
2152
      select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
2176
2153
      if (join->init_save_join_tab())
2177
 
        return(1);
 
2154
        return(1);                        /* purecov: inspected */
2178
2155
    }
2179
2156
    if (item->engine_changed)
2180
2157
    {
2181
2158
      return(1);
2182
2159
    }
2183
2160
  }
2184
 
  if (select_lex->uncacheable.any() &&
2185
 
      ! select_lex->uncacheable.test(UNCACHEABLE_EXPLAIN) &&
2186
 
      executed)
 
2161
  if (select_lex->uncacheable &&
 
2162
      select_lex->uncacheable != UNCACHEABLE_EXPLAIN
 
2163
      && executed)
2187
2164
  {
2188
2165
    if (join->reinit())
2189
2166
    {
2190
 
      session->where= save_where;
2191
 
      session->lex->current_select= save_select;
2192
 
      return 1;
 
2167
      thd->where= save_where;
 
2168
      thd->lex->current_select= save_select;
 
2169
      return(1);
2193
2170
    }
2194
2171
    item->reset();
2195
2172
    item->assigned((executed= 0));
2197
2174
  if (!executed)
2198
2175
  {
2199
2176
    item->reset_value_registration();
2200
 
    JoinTable *changed_tabs[MAX_TABLES];
2201
 
    JoinTable **last_changed_tab= changed_tabs;
 
2177
    JOIN_TAB *changed_tabs[MAX_TABLES];
 
2178
    JOIN_TAB **last_changed_tab= changed_tabs;
2202
2179
    if (item->have_guarded_conds())
2203
2180
    {
2204
2181
      /*
2209
2186
      */
2210
2187
      for (uint32_t i=join->const_tables ; i < join->tables ; i++)
2211
2188
      {
2212
 
        JoinTable *tab=join->join_tab+i;
 
2189
        JOIN_TAB *tab=join->join_tab+i;
2213
2190
        if (tab && tab->keyuse)
2214
2191
        {
2215
 
          for (uint32_t key_part= 0;
2216
 
               key_part < tab->ref.key_parts;
2217
 
               key_part++)
 
2192
          for (uint32_t i= 0; i < tab->ref.key_parts; i++)
2218
2193
          {
2219
 
            bool *cond_guard= tab->ref.cond_guards[key_part];
 
2194
            bool *cond_guard= tab->ref.cond_guards[i];
2220
2195
            if (cond_guard && !*cond_guard)
2221
2196
            {
2222
2197
              /* Change the access method to full table scan */
2224
2199
              tab->save_read_record= tab->read_record.read_record;
2225
2200
              tab->read_first_record= init_read_record_seq;
2226
2201
              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;
 
2202
              tab->read_record.thd= join->thd;
 
2203
              tab->read_record.ref_length= tab->table->file->ref_length;
2229
2204
              *(last_changed_tab++)= tab;
2230
2205
              break;
2231
2206
            }
2233
2208
        }
2234
2209
      }
2235
2210
    }
2236
 
 
 
2211
    
2237
2212
    join->exec();
2238
2213
 
2239
2214
    /* Enable the optimizations back */
2240
 
    for (JoinTable **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
 
2215
    for (JOIN_TAB **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
2241
2216
    {
2242
 
      JoinTable *tab= *ptab;
 
2217
      JOIN_TAB *tab= *ptab;
2243
2218
      tab->read_record.record= 0;
2244
2219
      tab->read_record.ref_length= 0;
2245
 
      tab->read_first_record= tab->save_read_first_record;
 
2220
      tab->read_first_record= tab->save_read_first_record; 
2246
2221
      tab->read_record.read_record= tab->save_read_record;
2247
2222
    }
2248
2223
    executed= 1;
2249
 
    session->where= save_where;
2250
 
    session->lex->current_select= save_select;
2251
 
    return(join->error||session->is_fatal_error);
 
2224
    thd->where= save_where;
 
2225
    thd->lex->current_select= save_select;
 
2226
    return(join->error||thd->is_fatal_error);
2252
2227
  }
2253
 
  session->where= save_where;
2254
 
  session->lex->current_select= save_select;
 
2228
  thd->where= save_where;
 
2229
  thd->lex->current_select= save_select;
2255
2230
  return(0);
2256
2231
}
2257
2232
 
2258
2233
int subselect_union_engine::exec()
2259
2234
{
2260
 
  char const *save_where= session->where;
 
2235
  char const *save_where= thd->where;
2261
2236
  int res= unit->exec();
2262
 
  session->where= save_where;
 
2237
  thd->where= save_where;
2263
2238
  return res;
2264
2239
}
2265
2240
 
2266
2241
 
2267
2242
/*
2268
2243
  Search for at least one row satisfying select condition
2269
 
 
 
2244
 
2270
2245
  SYNOPSIS
2271
2246
    subselect_uniquesubquery_engine::scan_table()
2272
2247
 
2273
2248
  DESCRIPTION
2274
2249
    Scan the table using sequential access until we find at least one row
2275
2250
    satisfying select condition.
2276
 
 
 
2251
    
2277
2252
    The caller must set this->empty_result_set=false before calling this
2278
2253
    function. This function will set it to true if it finds a matching row.
2279
2254
 
2287
2262
  int error;
2288
2263
  Table *table= tab->table;
2289
2264
 
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);
 
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);
2296
2271
  table->null_row= 0;
2297
2272
  for (;;)
2298
2273
  {
2299
 
    error=table->cursor->rnd_next(table->record[0]);
 
2274
    error=table->file->rnd_next(table->record[0]);
2300
2275
    if (error && error != HA_ERR_END_OF_FILE)
2301
2276
    {
2302
2277
      error= table->report_error(error);
2313
2288
    }
2314
2289
  }
2315
2290
 
2316
 
  table->cursor->endTableScan();
 
2291
  table->file->ha_rnd_end();
2317
2292
  return(error != 0);
2318
2293
}
2319
2294
 
2362
2337
 
2363
2338
bool subselect_uniquesubquery_engine::copy_ref_key()
2364
2339
{
2365
 
  for (StoredKey **copy= tab->ref.key_copy ; *copy ; copy++)
 
2340
  for (store_key **copy= tab->ref.key_copy ; *copy ; copy++)
2366
2341
  {
2367
 
    StoredKey::store_key_result store_res= (*copy)->copy();
 
2342
    enum store_key::store_key_result store_res;
 
2343
    store_res= (*copy)->copy();
2368
2344
    tab->ref.key_err= store_res;
2369
2345
 
2370
2346
    /*
2392
2368
    }
2393
2369
 
2394
2370
    /*
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.
 
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.  
2400
2376
      TODO: fix the variable an return types.
2401
2377
    */
2402
 
    if (store_res == StoredKey::STORE_KEY_FATAL)
 
2378
    if (store_res == store_key::STORE_KEY_FATAL)
2403
2379
    {
2404
2380
      /*
2405
2381
       Error converting the left IN operand to the column type of the right
2406
 
       IN operand.
 
2382
       IN operand. 
2407
2383
      */
2408
2384
      tab->table->status= STATUS_NOT_FOUND;
2409
2385
      break;
2424
2400
    If some part of the lookup key is NULL, then we're evaluating
2425
2401
      NULL IN (SELECT ... )
2426
2402
    This is a special case, we don't need to search for NULL in the table,
2427
 
    instead, the result value is
 
2403
    instead, the result value is 
2428
2404
      - NULL  if select produces empty row set
2429
2405
      - false otherwise.
2430
2406
 
2431
2407
    In some cases (IN subselect is a top level item, i.e. abort_on_null==true)
2432
2408
    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
 
2409
    return false. 
 
2410
    Otherwise we make a full table scan to see if there is at least one 
2435
2411
    matching row.
2436
 
 
 
2412
    
2437
2413
    The result of this function (info about whether a row was found) is
2438
2414
    stored in this->empty_result_set.
2439
2415
  NOTE
2440
 
 
 
2416
    
2441
2417
  RETURN
2442
2418
    false - ok
2443
2419
    true  - an error occured while scanning
2449
2425
  Table *table= tab->table;
2450
2426
  empty_result_set= true;
2451
2427
  table->status= 0;
2452
 
 
 
2428
 
2453
2429
  /* TODO: change to use of 'full_scan' here? */
2454
2430
  if (copy_ref_key())
2455
2431
    return(1);
2456
2432
  if (table->status)
2457
2433
  {
2458
 
    /*
2459
 
      We know that there will be no rows even if we scan.
 
2434
    /* 
 
2435
      We know that there will be no rows even if we scan. 
2460
2436
      Can be set in copy_ref_key.
2461
2437
    */
2462
2438
    ((Item_in_subselect *) item)->value= 0;
2465
2441
 
2466
2442
  if (null_keypart)
2467
2443
    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],
 
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],
2472
2448
                                     tab->ref.key_buff,
2473
2449
                                     make_prev_keypart_map(tab->ref.key_parts),
2474
2450
                                     HA_READ_KEY_EXACT);
2497
2473
 
2498
2474
  SYNOPSIS
2499
2475
    subselect_indexsubquery_engine:exec()
2500
 
      full_scan
 
2476
      full_scan 
2501
2477
 
2502
2478
  DESCRIPTION
2503
2479
    The engine is used to resolve subqueries in form
2504
2480
 
2505
 
      oe IN (SELECT key FROM tbl WHERE subq_where)
 
2481
      oe IN (SELECT key FROM tbl WHERE subq_where) 
2506
2482
 
2507
 
    The value of the predicate is calculated as follows:
 
2483
    The value of the predicate is calculated as follows: 
2508
2484
    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
 
2485
       table tbl and search for row that satisfies subq_where. If such 
2510
2486
       row is found, return NULL, otherwise return false.
2511
2487
    2. Make an index lookup via key=oe, search for a row that satisfies
2512
2488
       subq_where. If found, return true.
2513
 
    3. If check_null==true, make another lookup via key=NULL, search for a
 
2489
    3. If check_null==true, make another lookup via key=NULL, search for a 
2514
2490
       row that satisfies subq_where. If found, return NULL, otherwise
2515
2491
       return false.
2516
2492
 
2517
2493
  TODO
2518
2494
    The step #1 can be optimized further when the index has several key
2519
2495
    parts. Consider a subquery:
2520
 
 
 
2496
    
2521
2497
      (oe1, oe2) IN (SELECT keypart1, keypart2 FROM tbl WHERE subq_where)
2522
2498
 
2523
2499
    and suppose we need to evaluate it for {oe1, oe2}=={const1, NULL}.
2527
2503
      SELECT keypart1, keypart2 FROM tbl WHERE subq_where            (1)
2528
2504
 
2529
2505
    and checking if it has produced any matching rows, evaluate
2530
 
 
 
2506
    
2531
2507
      SELECT keypart2 FROM tbl WHERE subq_where AND keypart1=const1  (2)
2532
2508
 
2533
 
    If this query produces a row, the result is NULL (as we're evaluating
 
2509
    If this query produces a row, the result is NULL (as we're evaluating 
2534
2510
    "(const1, NULL) IN { (const1, X), ... }", which has a value of UNKNOWN,
2535
2511
    i.e. NULL).  If the query produces no rows, the result is false.
2536
2512
 
2568
2544
 
2569
2545
  if (table->status)
2570
2546
  {
2571
 
    /*
2572
 
      We know that there will be no rows even if we scan.
 
2547
    /* 
 
2548
      We know that there will be no rows even if we scan. 
2573
2549
      Can be set in copy_ref_key.
2574
2550
    */
2575
2551
    ((Item_in_subselect *) item)->value= 0;
2579
2555
  if (null_keypart)
2580
2556
    return(scan_table());
2581
2557
 
2582
 
  if (!table->cursor->inited)
2583
 
    table->cursor->startIndexScan(tab->ref.key, 1);
2584
 
  error= table->cursor->index_read_map(table->record[0],
 
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],
2585
2561
                                     tab->ref.key_buff,
2586
2562
                                     make_prev_keypart_map(tab->ref.key_parts),
2587
2563
                                     HA_READ_KEY_EXACT);
2605
2581
            ((Item_in_subselect *) item)->value= 1;
2606
2582
          break;
2607
2583
        }
2608
 
        error= table->cursor->index_next_same(table->record[0],
 
2584
        error= table->file->index_next_same(table->record[0],
2609
2585
                                            tab->ref.key_buff,
2610
2586
                                            tab->ref.key_length);
2611
2587
        if (error && error != HA_ERR_END_OF_FILE)
2642
2618
}
2643
2619
 
2644
2620
 
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);
 
2621
uint8_t subselect_single_select_engine::uncacheable()
 
2622
{
 
2623
  return select_lex->uncacheable;
 
2624
}
 
2625
 
 
2626
 
 
2627
uint8_t subselect_union_engine::uncacheable()
 
2628
{
 
2629
  return unit->uncacheable;
2666
2630
}
2667
2631
 
2668
2632
 
2713
2677
void subselect_single_select_engine::print(String *str,
2714
2678
                                           enum_query_type query_type)
2715
2679
{
2716
 
  select_lex->print(session, str, query_type);
 
2680
  select_lex->print(thd, str, query_type);
2717
2681
}
2718
2682
 
2719
2683
 
2726
2690
void subselect_uniquesubquery_engine::print(String *str,
2727
2691
                                            enum_query_type query_type)
2728
2692
{
2729
 
  char *table_name= const_cast<char *>(tab->table->getShare()->getTableName());
 
2693
  char *table_name= tab->table->s->table_name.str;
2730
2694
  str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2731
2695
  tab->ref.items[0]->print(str, query_type);
2732
2696
  str->append(STRING_WITH_LEN(" in "));
2733
 
  if (tab->table->getShare()->isTemporaryCategory())
 
2697
  if (tab->table->s->table_category == TABLE_CATEGORY_TEMPORARY)
2734
2698
  {
2735
2699
    /*
2736
2700
      Temporary tables' names change across runs, so they can't be used for
2739
2703
    str->append(STRING_WITH_LEN("<temporary table>"));
2740
2704
  }
2741
2705
  else
2742
 
    str->append(table_name, tab->table->getShare()->getTableNameSize());
2743
 
  KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
 
2706
    str->append(table_name, tab->table->s->table_name.length);
 
2707
  KEY *key_info= tab->table->key_info+ tab->ref.key;
2744
2708
  str->append(STRING_WITH_LEN(" on "));
2745
2709
  str->append(key_info->name);
2746
2710
  if (cond)
2763
2727
  for (uint32_t i= 0; i < key_info->key_parts; i++)
2764
2728
    tab->ref.items[i]->print(str);
2765
2729
  str->append(STRING_WITH_LEN(" in "));
2766
 
  str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
 
2730
  str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2767
2731
  str->append(STRING_WITH_LEN(" on "));
2768
2732
  str->append(key_info->name);
2769
2733
  if (cond)
2781
2745
  str->append(STRING_WITH_LEN("<index_lookup>("));
2782
2746
  tab->ref.items[0]->print(str, query_type);
2783
2747
  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;
 
2748
  str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
 
2749
  KEY *key_info= tab->table->key_info+ tab->ref.key;
2786
2750
  str->append(STRING_WITH_LEN(" on "));
2787
2751
  str->append(key_info->name);
2788
2752
  if (check_null)
2855
2819
    true  error
2856
2820
*/
2857
2821
 
2858
 
bool subselect_uniquesubquery_engine::change_result(Item_subselect *,
2859
 
                                                    select_result_interceptor *)
 
2822
bool subselect_uniquesubquery_engine::change_result(Item_subselect *si __attribute__((unused)),
 
2823
                                                    select_result_interceptor *res __attribute__((unused)))
2860
2824
{
2861
2825
  assert(0);
2862
2826
  return true;
2903
2867
*/
2904
2868
bool subselect_union_engine::no_tables()
2905
2869
{
2906
 
  for (Select_Lex *sl= unit->first_select(); sl; sl= sl->next_select())
 
2870
  for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
2907
2871
  {
2908
2872
    if (sl->table_list.elements)
2909
2873
      return false;
2942
2906
    temporary table has one hash index on all its columns.
2943
2907
  - Create a new result sink that sends the result stream of the subquery to
2944
2908
    the temporary table,
2945
 
  - Create and initialize a new JoinTable, and TABLE_REF objects to perform
 
2909
  - Create and initialize a new JOIN_TAB, and TABLE_REF objects to perform
2946
2910
    lookups into the indexed temporary table.
2947
2911
 
2948
2912
  @notice:
2959
2923
  select_union  *tmp_result_sink;
2960
2924
  /* The table into which the subquery is materialized. */
2961
2925
  Table         *tmp_table;
2962
 
  KeyInfo           *tmp_key; /* The only index on the temporary table. */
 
2926
  KEY           *tmp_key; /* The only index on the temporary table. */
2963
2927
  uint32_t          tmp_key_parts; /* Number of keyparts in tmp_key. */
2964
2928
  Item_in_subselect *item_in= (Item_in_subselect *) item;
2965
2929
 
2972
2936
  */
2973
2937
  if (!(tmp_result_sink= new select_union))
2974
2938
    return(true);
2975
 
 
2976
2939
  if (tmp_result_sink->create_result_table(
2977
 
                         session, tmp_columns, true,
2978
 
                         session->options | TMP_TABLE_ALL_COLUMNS,
2979
 
                         "materialized subselect"))
 
2940
                         thd, tmp_columns, true,
 
2941
                         thd->options | TMP_TABLE_ALL_COLUMNS,
 
2942
                         "materialized subselect", true))
2980
2943
    return(true);
2981
2944
 
2982
2945
  tmp_table= tmp_result_sink->table;
2990
2953
     table since it will not be used, and tell the caller we failed to
2991
2954
     initialize the engine.
2992
2955
  */
2993
 
  if (tmp_table->getShare()->sizeKeys() == 0)
 
2956
  if (tmp_table->s->keys == 0)
2994
2957
  {
2995
 
    assert(tmp_table->getShare()->db_type() == myisam_engine);
 
2958
    assert(tmp_table->s->db_type() == myisam_hton);
2996
2959
    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;
 
2960
      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
    tmp_table->free_tmp_table(thd);
3001
2964
    delete result;
3002
2965
    result= NULL;
3003
2966
    return(true);
3008
2971
    Make sure there is only one index on the temp table, and it doesn't have
3009
2972
    the extra key part created when s->uniques > 0.
3010
2973
  */
3011
 
  assert(tmp_table->getShare()->sizeKeys() == 1 && tmp_columns->elements == tmp_key_parts);
 
2974
  assert(tmp_table->s->keys == 1 && tmp_columns->elements == tmp_key_parts);
3012
2975
 
3013
2976
 
3014
2977
  /* 2. Create/initialize execution related objects. */
3015
2978
 
3016
2979
  /*
3017
 
    Create and initialize the JoinTable that represents an index lookup
 
2980
    Create and initialize the JOIN_TAB that represents an index lookup
3018
2981
    plan operator into the materialized subquery result. Notice that:
3019
 
    - this JoinTable has no corresponding JOIN (and doesn't need one), and
 
2982
    - this JOIN_TAB has no corresponding JOIN (and doesn't need one), and
3020
2983
    - here we initialize only those members that are used by
3021
2984
      subselect_uniquesubquery_engine, so these objects are incomplete.
3022
 
  */
3023
 
  if (!(tab= (JoinTable*) session->alloc(sizeof(JoinTable))))
 
2985
  */ 
 
2986
  if (!(tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
3024
2987
    return(true);
3025
2988
  tab->table= tmp_table;
3026
2989
  tab->ref.key= 0; /* The only temp table index. */
3027
2990
  tab->ref.key_length= tmp_key->key_length;
3028
2991
  if (!(tab->ref.key_buff=
3029
 
        (unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
 
2992
        (unsigned char*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3030
2993
      !(tab->ref.key_copy=
3031
 
        (StoredKey**) session->alloc((sizeof(StoredKey*) *
 
2994
        (store_key**) thd->alloc((sizeof(store_key*) *
3032
2995
                                  (tmp_key_parts + 1)))) ||
3033
2996
      !(tab->ref.items=
3034
 
        (Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
 
2997
        (Item**) thd->alloc(sizeof(Item*) * tmp_key_parts)))
3035
2998
    return(true);
3036
2999
 
3037
 
  KeyPartInfo *cur_key_part= tmp_key->key_part;
3038
 
  StoredKey **ref_key= tab->ref.key_copy;
 
3000
  KEY_PART_INFO *cur_key_part= tmp_key->key_part;
 
3001
  store_key **ref_key= tab->ref.key_copy;
3039
3002
  unsigned char *cur_ref_buff= tab->ref.key_buff;
3040
 
 
 
3003
  
3041
3004
  for (uint32_t i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3042
3005
  {
3043
3006
    tab->ref.items[i]= item_in->left_expr->element_index(i);
3044
3007
    int null_count= test(cur_key_part->field->real_maybe_null());
3045
 
    *ref_key= new store_key_item(session, cur_key_part->field,
 
3008
    *ref_key= new store_key_item(thd, cur_key_part->field,
3046
3009
                                 /* TODO:
3047
3010
                                    the NULL byte is taken into account in
3048
3011
                                    cur_key_part->store_length, so instead of
3088
3051
{
3089
3052
  delete result;
3090
3053
  if (tab)
3091
 
  {
3092
 
    tab->table= NULL;
3093
 
  }
 
3054
    tab->table->free_tmp_table(thd);
3094
3055
}
3095
3056
 
3096
3057
 
3098
3059
  Cleanup performed after each PS execution.
3099
3060
 
3100
3061
  @detail
3101
 
  Called in the end of Join::prepare for PS from Item_subselect::cleanup.
 
3062
  Called in the end of JOIN::prepare for PS from Item_subselect::cleanup.
3102
3063
*/
3103
3064
 
3104
3065
void subselect_hash_sj_engine::cleanup()
3132
3093
  if (!is_materialized)
3133
3094
  {
3134
3095
    int res= 0;
3135
 
    Select_Lex *save_select= session->lex->current_select;
3136
 
    session->lex->current_select= materialize_engine->select_lex;
 
3096
    SELECT_LEX *save_select= thd->lex->current_select;
 
3097
    thd->lex->current_select= materialize_engine->select_lex;
3137
3098
    if ((res= materialize_join->optimize()))
3138
3099
      goto err;
3139
3100
    materialize_join->exec();
3140
 
    if ((res= test(materialize_join->error || session->is_fatal_error)))
 
3101
    if ((res= test(materialize_join->error || thd->is_fatal_error)))
3141
3102
      goto err;
3142
3103
 
3143
3104
    /*
3144
3105
      TODO:
3145
3106
      - 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
 
3107
        we need to add new functionality to JOIN::join_free that can unlock
3147
3108
        all tables in a subquery (and all its subqueries).
3148
3109
      - The temp table used for grouping in the subquery can be freed
3149
3110
        immediately after materialization (yet it's done together with
3156
3117
      statistics, then we test if the temporary table for the query result is
3157
3118
      empty.
3158
3119
    */
3159
 
    tab->table->cursor->info(HA_STATUS_VARIABLE);
3160
 
    if (!tab->table->cursor->stats.records)
 
3120
    tab->table->file->info(HA_STATUS_VARIABLE);
 
3121
    if (!tab->table->file->stats.records)
3161
3122
    {
3162
3123
      empty_result_set= true;
3163
3124
      item_in->value= false;
3170
3131
      tmp_param= NULL;
3171
3132
 
3172
3133
err:
3173
 
    session->lex->current_select= save_select;
 
3134
    thd->lex->current_select= save_select;
3174
3135
    if (res)
3175
3136
      return(res);
3176
3137
  }
3198
3159
           "<the access method for lookups is not yet created>"
3199
3160
         ));
3200
3161
}
3201
 
 
3202
 
} /* namespace drizzled */