~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/item_subselect.cc

  • Committer: Brian Aker
  • Date: 2008-07-20 05:41:52 UTC
  • Revision ID: brian@tangent.org-20080720054152-5laf6plsb0o7h6ss
Documentation cleanup

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