~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/subselect.cc

  • Committer: Monty Taylor
  • Date: 2011-03-10 18:09:05 UTC
  • mfrom: (2225.2.2 refactor)
  • mto: This revision was merged to the branch mainline in revision 2228.
  • Revision ID: mordred@inaugust.com-20110310180905-ttx05t7q7ff6nl7c
Merge Olad: Refactoring

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
  subselect Item
21
21
 
22
22
  @todo
23
 
    - add function from mysql_select that use JOIN* as parameter to JOIN
 
23
    - add function from select_query that use JOIN* as parameter to JOIN
24
24
    methods (sql_select.h/sql_select.cc)
25
25
*/
26
 
#include "config.h"
 
26
#include <config.h>
27
27
 
28
28
#include <cstdio>
29
29
#include <limits.h>
30
30
 
 
31
#include <drizzled/session.h>
31
32
#include <drizzled/sql_select.h>
32
33
#include <drizzled/error.h>
33
34
#include <drizzled/item/cache.h>
39
40
#include <drizzled/item/ref_null_helper.h>
40
41
#include <drizzled/item/direct_ref.h>
41
42
#include <drizzled/join.h>
 
43
#include <drizzled/plugin/storage_engine.h>
 
44
#include <drizzled/select_singlerow_subselect.h>
 
45
#include <drizzled/select_max_min_finder_subselect.h>
 
46
#include <drizzled/select_exists_subselect.h>
 
47
#include <drizzled/select_union.h>
42
48
 
43
49
namespace drizzled
44
50
{
180
186
 
181
187
bool Item_subselect::fix_fields(Session *session_param, Item **ref)
182
188
{
183
 
  char const *save_where= session_param->where;
 
189
  char const *save_where= session_param->where();
184
190
  bool res;
185
191
 
186
192
  assert(fixed == 0);
223
229
        engine->exclude();
224
230
      }
225
231
      substitution= 0;
226
 
      session->where= "checking transformed subquery";
 
232
      session->setWhere("checking transformed subquery");
227
233
      if (! (*ref)->fixed)
228
234
      {
229
235
        ret= (*ref)->fix_fields(session, ref);
230
236
      }
231
 
      session->where= save_where;
 
237
      session->setWhere(save_where);
 
238
 
232
239
      return ret;
233
240
    }
234
241
    // Is it one field subselect?
244
251
 
245
252
  if (engine->uncacheable())
246
253
  {
247
 
    const_item_cache= 0;
 
254
    const_item_cache= false;
248
255
    if (engine->uncacheable(UNCACHEABLE_RAND))
249
256
    {
250
257
      used_tables_cache|= RAND_TABLE_BIT;
253
260
  fixed= 1;
254
261
 
255
262
err:
256
 
  session->where= save_where;
 
263
  session->setWhere(save_where);
257
264
  return res;
258
265
}
259
266
 
266
273
  {
267
274
    for (Select_Lex *lex= unit->first_select(); lex; lex= lex->next_select())
268
275
    {
269
 
      List_iterator<Item> li(lex->item_list);
 
276
      List<Item>::iterator li(lex->item_list.begin());
270
277
      Item *item;
271
278
      Order *order;
272
279
 
394
401
  {
395
402
    // did all used tables become static?
396
403
    if (!(used_tables_cache & ~engine->upper_select_const_tables()))
397
 
      const_item_cache= 1;
 
404
      const_item_cache= true;
398
405
  }
399
406
}
400
407
 
401
408
 
402
 
void Item_subselect::print(String *str, enum_query_type query_type)
 
409
void Item_subselect::print(String *str)
403
410
{
404
411
  str->append('(');
405
 
  engine->print(str, query_type);
 
412
  engine->print(str);
406
413
  str->append(')');
407
414
}
408
415
 
480
487
}
481
488
 
482
489
 
483
 
void Item_maxmin_subselect::print(String *str, enum_query_type query_type)
 
490
void Item_maxmin_subselect::print(String *str)
484
491
{
485
492
  str->append(max?"<max>":"<min>", 5);
486
 
  Item_singlerow_subselect::print(str, query_type);
 
493
  Item_singlerow_subselect::print(str);
487
494
}
488
495
 
489
496
 
515
522
 
516
523
  if (!select_lex->master_unit()->is_union() &&
517
524
      !select_lex->table_list.elements &&
518
 
      select_lex->item_list.elements == 1 &&
519
 
      !select_lex->item_list.head()->with_sum_func &&
 
525
      select_lex->item_list.size() == 1 &&
 
526
      !select_lex->item_list.front().with_sum_func &&
520
527
      /*
521
528
        We cant change name of Item_field or Item_ref, because it will
522
529
        prevent it's correct resolving, but we should save name of
524
531
        list is field or reference.
525
532
        TODO: solve above problem
526
533
      */
527
 
      !(select_lex->item_list.head()->type() == FIELD_ITEM ||
528
 
        select_lex->item_list.head()->type() == REF_ITEM) &&
 
534
      !(select_lex->item_list.front().type() == FIELD_ITEM ||
 
535
        select_lex->item_list.front().type() == REF_ITEM) &&
529
536
      !join->conds && !join->having
530
537
      )
531
538
  {
532
539
 
533
540
    have_to_be_excluded= 1;
534
 
    if (session->lex->describe)
 
541
    if (session->getLex()->describe)
535
542
    {
536
543
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
537
544
      snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
538
545
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
539
546
                   ER_SELECT_REDUCED, warn_buff);
540
547
    }
541
 
    substitution= select_lex->item_list.head();
 
548
    substitution= &select_lex->item_list.front();
542
549
    /*
543
550
      as far as we moved content to upper level, field which depend of
544
551
      'upper' select is not really dependent => we remove this dependence
668
675
}
669
676
 
670
677
 
671
 
my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value)
 
678
type::Decimal *Item_singlerow_subselect::val_decimal(type::Decimal *decimal_value)
672
679
{
673
680
  if (!exec() && !value->null_value)
674
681
  {
711
718
}
712
719
 
713
720
 
714
 
void Item_exists_subselect::print(String *str, enum_query_type query_type)
 
721
void Item_exists_subselect::print(String *str)
715
722
{
716
723
  str->append(STRING_WITH_LEN("exists"));
717
 
  Item_subselect::print(str, query_type);
 
724
  Item_subselect::print(str);
718
725
}
719
726
 
720
727
 
818
825
}
819
826
 
820
827
 
821
 
my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
 
828
type::Decimal *Item_exists_subselect::val_decimal(type::Decimal *decimal_value)
822
829
{
823
830
  assert(fixed == 1);
824
831
  if (exec())
826
833
    reset();
827
834
    return 0;
828
835
  }
829
 
  int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
 
836
  int2_class_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
830
837
  return decimal_value;
831
838
}
832
839
 
929
936
  return value;
930
937
}
931
938
 
932
 
my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
 
939
type::Decimal *Item_in_subselect::val_decimal(type::Decimal *decimal_value)
933
940
{
934
941
  /*
935
942
    As far as Item_in_subselect called only from Item_in_optimizer this
946
953
  }
947
954
  if (was_null && !value)
948
955
    null_value= 1;
949
 
  int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
 
956
  int2_class_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
950
957
  return decimal_value;
951
958
}
952
959
 
995
1002
    Check that the right part of the subselect contains no more than one
996
1003
    column. E.g. in SELECT 1 IN (SELECT * ..) the right part is (SELECT * ...)
997
1004
  */
998
 
  if (select_lex->item_list.elements > 1)
 
1005
  if (select_lex->item_list.size() > 1)
999
1006
  {
1000
1007
    my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
1001
1008
    return(RES_ERROR);
1050
1057
        upper_item->set_sum_test(item);
1051
1058
      *select_lex->ref_pointer_array= item;
1052
1059
      {
1053
 
        List_iterator<Item> it(select_lex->item_list);
 
1060
        List<Item>::iterator it(select_lex->item_list.begin());
1054
1061
        it++;
1055
1062
        it.replace(item);
1056
1063
      }
1057
1064
 
1058
 
      save_allow_sum_func= session->lex->allow_sum_func;
1059
 
      session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
 
1065
      save_allow_sum_func= session->getLex()->allow_sum_func;
 
1066
      session->getLex()->allow_sum_func|= 1 << session->getLex()->current_select->nest_level;
1060
1067
      /*
1061
1068
        Item_sum_(max|min) can't substitute other item => we can use 0 as
1062
1069
        reference, also Item_sum_(max|min) can't be fixed after creation, so
1064
1071
      */
1065
1072
      if (item->fix_fields(session, 0))
1066
1073
        return(RES_ERROR);
1067
 
      session->lex->allow_sum_func= save_allow_sum_func;
 
1074
      session->getLex()->allow_sum_func= save_allow_sum_func;
1068
1075
      /* we added aggregate function => we have to change statistic */
1069
1076
      count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
1070
1077
                        0);
1089
1096
    Select_Lex_Unit *master_unit= select_lex->master_unit();
1090
1097
    substitution= optimizer;
1091
1098
 
1092
 
    Select_Lex *current= session->lex->current_select, *up;
 
1099
    Select_Lex *current= session->getLex()->current_select, *up;
1093
1100
 
1094
 
    session->lex->current_select= up= current->return_after_parsing();
 
1101
    session->getLex()->current_select= up= current->return_after_parsing();
1095
1102
    //optimizer never use Item **ref => we can pass 0 as parameter
1096
1103
    if (!optimizer || optimizer->fix_left(session, 0))
1097
1104
    {
1098
 
      session->lex->current_select= current;
 
1105
      session->getLex()->current_select= current;
1099
1106
      return(RES_ERROR);
1100
1107
    }
1101
 
    session->lex->current_select= current;
 
1108
    session->getLex()->current_select= current;
1102
1109
 
1103
1110
    /*
1104
1111
      As far as  Item_ref_in_optimizer do not substitute itself on fix_fields
1114
1121
 
1115
1122
  if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1116
1123
  {
1117
 
    if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool))))
 
1124
    if (!(pushed_cond_guards= (bool*)join->session->getMemRoot()->allocate(sizeof(bool))))
1118
1125
      return(RES_ERROR);
1119
1126
    pushed_cond_guards[0]= true;
1120
1127
  }
1201
1208
    select_lex->having= join->having= and_items(join->having, item);
1202
1209
    if (join->having == item)
1203
1210
      item->name= (char*)in_having_cond;
 
1211
    select_lex->having->top_level_item();
1204
1212
    select_lex->having_fix_field= 1;
1205
1213
    /*
1206
1214
      we do not check join->having->fixed, because Item_and (from and_items)
1213
1221
  }
1214
1222
  else
1215
1223
  {
1216
 
    Item *item= (Item*) select_lex->item_list.head();
 
1224
    Item *item= &select_lex->item_list.front();
1217
1225
 
1218
1226
    if (select_lex->table_list.elements)
1219
1227
    {
1220
1228
      bool tmp;
1221
1229
      Item *having= item, *orig_item= item;
1222
 
      select_lex->item_list.empty();
 
1230
      select_lex->item_list.clear();
1223
1231
      select_lex->item_list.push_back(new Item_int("Not_used",
1224
1232
                                                   (int64_t) 1,
1225
1233
                                                   MY_INT64_NUM_DECIMAL_DIGITS));
1226
 
      select_lex->ref_pointer_array[0]= select_lex->item_list.head();
 
1234
      select_lex->ref_pointer_array[0]= &select_lex->item_list.front();
1227
1235
 
1228
1236
      item= func->create(expr, item);
1229
1237
      if (!abort_on_null && orig_item->maybe_null)
1327
1335
        // fix_field of item will be done in time of substituting
1328
1336
        substitution= item;
1329
1337
        have_to_be_excluded= 1;
1330
 
        if (session->lex->describe)
 
1338
        if (session->getLex()->describe)
1331
1339
        {
1332
1340
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
1333
1341
          snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
1349
1357
  Select_Lex *select_lex= join->select_lex;
1350
1358
  uint32_t cols_num= left_expr->cols();
1351
1359
 
1352
 
  if (select_lex->item_list.elements != left_expr->cols())
 
1360
  if (select_lex->item_list.size() != left_expr->cols())
1353
1361
  {
1354
1362
    my_error(ER_OPERAND_COLUMNS, MYF(0), left_expr->cols());
1355
1363
    return(RES_ERROR);
1365
1373
    Select_Lex_Unit *master_unit= select_lex->master_unit();
1366
1374
    substitution= optimizer;
1367
1375
 
1368
 
    Select_Lex *current= session->lex->current_select, *up;
1369
 
    session->lex->current_select= up= current->return_after_parsing();
 
1376
    Select_Lex *current= session->getLex()->current_select, *up;
 
1377
    session->getLex()->current_select= up= current->return_after_parsing();
1370
1378
    //optimizer never use Item **ref => we can pass 0 as parameter
1371
1379
    if (!optimizer || optimizer->fix_left(session, 0))
1372
1380
    {
1373
 
      session->lex->current_select= current;
 
1381
      session->getLex()->current_select= current;
1374
1382
      return(RES_ERROR);
1375
1383
    }
1376
1384
 
1377
1385
    // we will refer to upper level cache array => we have to save it in PS
1378
1386
    optimizer->keep_top_level_cache();
1379
1387
 
1380
 
    session->lex->current_select= current;
 
1388
    session->getLex()->current_select= current;
1381
1389
    master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
1382
1390
 
1383
1391
    if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1384
1392
    {
1385
 
      if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool) *
 
1393
      if (!(pushed_cond_guards= (bool*)join->session->getMemRoot()->allocate(sizeof(bool) *
1386
1394
                                                        left_expr->cols())))
1387
1395
        return(RES_ERROR);
1388
1396
      for (uint32_t i= 0; i < cols_num; i++)
1649
1657
Item_subselect::trans_res
1650
1658
Item_in_subselect::select_in_like_transformer(Join *join, const Comp_creator *func)
1651
1659
{
1652
 
  Select_Lex *current= session->lex->current_select, *up;
1653
 
  const char *save_where= session->where;
 
1660
  Select_Lex *current= session->getLex()->current_select, *up;
 
1661
  const char *save_where= session->where();
1654
1662
  Item_subselect::trans_res res= RES_ERROR;
1655
1663
  bool result;
1656
1664
 
1670
1678
  if (changed)
1671
1679
    return(RES_OK);
1672
1680
 
1673
 
  session->where= "IN/ALL/ANY subquery";
 
1681
  session->setWhere("IN/ALL/ANY subquery");
1674
1682
 
1675
1683
  /*
1676
1684
    In some optimisation cases we will not need this Item_in_optimizer
1684
1692
      goto err;
1685
1693
  }
1686
1694
 
1687
 
  session->lex->current_select= up= current->return_after_parsing();
 
1695
  session->getLex()->current_select= up= current->return_after_parsing();
1688
1696
  result= (!left_expr->fixed &&
1689
1697
           left_expr->fix_fields(session, optimizer->arguments()));
1690
1698
  /* fix_fields can change reference to left_expr, we need reassign it */
1691
1699
  left_expr= optimizer->arguments()[0];
1692
1700
 
1693
 
  session->lex->current_select= current;
 
1701
  session->getLex()->current_select= current;
1694
1702
  if (result)
1695
1703
    goto err;
1696
1704
 
1721
1729
    res= row_value_transformer(join);
1722
1730
  }
1723
1731
err:
1724
 
  session->where= save_where;
 
1732
  session->setWhere(save_where);
1725
1733
  return(res);
1726
1734
}
1727
1735
 
1728
1736
 
1729
 
void Item_in_subselect::print(String *str, enum_query_type query_type)
 
1737
void Item_in_subselect::print(String *str)
1730
1738
{
1731
1739
  if (exec_method == IN_TO_EXISTS)
1732
1740
    str->append(STRING_WITH_LEN("<exists>"));
1733
1741
  else
1734
1742
  {
1735
 
    left_expr->print(str, query_type);
 
1743
    left_expr->print(str);
1736
1744
    str->append(STRING_WITH_LEN(" in "));
1737
1745
  }
1738
 
  Item_subselect::print(str, query_type);
 
1746
  Item_subselect::print(str);
1739
1747
}
1740
1748
 
1741
1749
 
1898
1906
}
1899
1907
 
1900
1908
 
1901
 
void Item_allany_subselect::print(String *str, enum_query_type query_type)
 
1909
void Item_allany_subselect::print(String *str)
1902
1910
{
1903
1911
  if (exec_method == IN_TO_EXISTS)
1904
1912
    str->append(STRING_WITH_LEN("<exists>"));
1905
1913
  else
1906
1914
  {
1907
 
    left_expr->print(str, query_type);
 
1915
    left_expr->print(str);
1908
1916
    str->append(' ');
1909
1917
    str->append(func->symbol(all));
1910
1918
    str->append(all ? " all " : " any ", 5);
1911
1919
  }
1912
 
  Item_subselect::print(str, query_type);
 
1920
  Item_subselect::print(str);
1913
1921
}
1914
1922
 
1915
1923
 
2031
2039
  if (!join || !result)
2032
2040
    return 1; /* Fatal error is set already. */
2033
2041
  prepared= 1;
2034
 
  Select_Lex *save_select= session->lex->current_select;
2035
 
  session->lex->current_select= select_lex;
 
2042
  Select_Lex *save_select= session->getLex()->current_select;
 
2043
  session->getLex()->current_select= select_lex;
2036
2044
  if (join->prepare(&select_lex->ref_pointer_array,
2037
2045
                    (TableList*) select_lex->table_list.first,
2038
2046
                    select_lex->with_wild,
2044
2052
                    select_lex->having,
2045
2053
                    select_lex, select_lex->master_unit()))
2046
2054
    return 1;
2047
 
  session->lex->current_select= save_select;
 
2055
  session->getLex()->current_select= save_select;
2048
2056
  return 0;
2049
2057
}
2050
2058
 
2089
2097
void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
2090
2098
{
2091
2099
  Item *sel_item;
2092
 
  List_iterator_fast<Item> li(item_list);
 
2100
  List<Item>::iterator li(item_list.begin());
2093
2101
  res_type= STRING_RESULT;
2094
2102
  res_field_type= DRIZZLE_TYPE_VARCHAR;
2095
2103
  for (uint32_t i= 0; (sel_item= li++); i++)
2104
2112
      return;
2105
2113
    row[i]->setup(sel_item);
2106
2114
  }
2107
 
  if (item_list.elements > 1)
 
2115
  if (item_list.size() > 1)
2108
2116
    res_type= ROW_RESULT;
2109
2117
}
2110
2118
 
2111
2119
void subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
2112
2120
{
2113
 
  assert(row || select_lex->item_list.elements==1);
 
2121
  assert(row || select_lex->item_list.size() == 1);
2114
2122
  set_row(select_lex->item_list, row);
2115
2123
  item->collation.set(row[0]->collation);
2116
2124
  if (cols() != 1)
2119
2127
 
2120
2128
void subselect_union_engine::fix_length_and_dec(Item_cache **row)
2121
2129
{
2122
 
  assert(row || unit->first_select()->item_list.elements==1);
 
2130
  assert(row || unit->first_select()->item_list.size() == 1);
2123
2131
 
2124
 
  if (unit->first_select()->item_list.elements == 1)
 
2132
  if (unit->first_select()->item_list.size() == 1)
2125
2133
  {
2126
2134
    set_row(unit->types, row);
2127
2135
    item->collation.set(row[0]->collation);
2140
2148
  assert(0);
2141
2149
}
2142
2150
 
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);
2146
 
 
2147
2151
int subselect_single_select_engine::exec()
2148
2152
{
2149
 
  char const *save_where= session->where;
2150
 
  Select_Lex *save_select= session->lex->current_select;
2151
 
  session->lex->current_select= select_lex;
 
2153
  char const *save_where= session->where();
 
2154
  Select_Lex *save_select= session->getLex()->current_select;
 
2155
  session->getLex()->current_select= select_lex;
2152
2156
  if (!join->optimized)
2153
2157
  {
2154
2158
    Select_Lex_Unit *unit= select_lex->master_unit();
2156
2160
    unit->set_limit(unit->global_parameters);
2157
2161
    if (join->optimize())
2158
2162
    {
2159
 
      session->where= save_where;
 
2163
      session->setWhere(save_where);
2160
2164
      executed= 1;
2161
 
      session->lex->current_select= save_select;
 
2165
      session->getLex()->current_select= save_select;
2162
2166
      return(join->error ? join->error : 1);
2163
2167
    }
2164
 
    if (select_lex->uncacheable.none() && session->lex->describe &&
2165
 
        !(join->select_options & SELECT_DESCRIBE) &&
2166
 
        join->need_tmp && item->const_item())
2167
 
    {
2168
 
      /*
2169
 
        Force join->join_tmp creation, because this subquery will be replaced
2170
 
        by a simple select from the materialization temp table by optimize()
2171
 
        called by EXPLAIN and we need to preserve the initial query structure
2172
 
        so we can display it.
2173
 
       */
2174
 
      select_lex->uncacheable.set(UNCACHEABLE_EXPLAIN);
2175
 
      select_lex->master_unit()->uncacheable.set(UNCACHEABLE_EXPLAIN);
2176
 
      if (join->init_save_join_tab())
2177
 
        return(1);
2178
 
    }
 
2168
    if (save_join_if_explain())
 
2169
     return(1);
 
2170
 
2179
2171
    if (item->engine_changed)
2180
2172
    {
2181
2173
      return(1);
2187
2179
  {
2188
2180
    if (join->reinit())
2189
2181
    {
2190
 
      session->where= save_where;
2191
 
      session->lex->current_select= save_select;
 
2182
      session->setWhere(save_where);
 
2183
      session->getLex()->current_select= save_select;
2192
2184
      return 1;
2193
2185
    }
2194
2186
    item->reset();
2246
2238
      tab->read_record.read_record= tab->save_read_record;
2247
2239
    }
2248
2240
    executed= 1;
2249
 
    session->where= save_where;
2250
 
    session->lex->current_select= save_select;
 
2241
    session->setWhere(save_where);
 
2242
    session->getLex()->current_select= save_select;
2251
2243
    return(join->error||session->is_fatal_error);
2252
2244
  }
2253
 
  session->where= save_where;
2254
 
  session->lex->current_select= save_select;
 
2245
  session->setWhere(save_where);
 
2246
  session->getLex()->current_select= save_select;
2255
2247
  return(0);
2256
2248
}
2257
2249
 
 
2250
bool 
 
2251
subselect_single_select_engine::save_join_if_explain()
 
2252
{
 
2253
  /*
 
2254
    Save this JOIN to join->tmp_join since the original layout will be
 
2255
    replaced when JOIN::exec() calls make_simple_join() if:
 
2256
     1) We are executing an EXPLAIN query
 
2257
     2) An uncacheable flag has not been set for the select_lex. If
 
2258
        set, JOIN::optimize() has already saved the JOIN
 
2259
     3) Call does not come from select_describe()). If it does,
 
2260
        JOIN::exec() will not call make_simple_join() and the JOIN we
 
2261
        plan to save will not be replaced anyway.
 
2262
     4) A temp table is needed. This is what triggers JOIN::exec() to
 
2263
        make a replacement JOIN by calling make_simple_join(). 
 
2264
     5) The Item_subselect is cacheable
 
2265
  */
 
2266
  if (session->getLex()->describe &&                          // 1
 
2267
      select_lex->uncacheable.none() &&                  // 2
 
2268
      !(join->select_options & SELECT_DESCRIBE) &&       // 3
 
2269
      join->need_tmp &&                                  // 4
 
2270
      item->const_item())                                // 5
 
2271
  {
 
2272
    /*
 
2273
      Save this JOIN to join->tmp_join since the original layout will
 
2274
      be replaced when JOIN::exec() calls make_simple_join() due to
 
2275
      need_tmp==TRUE. The original layout is needed so we can describe
 
2276
      the query. No need to do this if uncacheable != 0 since in this
 
2277
      case the JOIN has already been saved during JOIN::optimize()
 
2278
    */
 
2279
    select_lex->uncacheable.set(UNCACHEABLE_EXPLAIN);
 
2280
    select_lex->master_unit()->uncacheable.set(UNCACHEABLE_EXPLAIN);
 
2281
    if (join->init_save_join_tab())
 
2282
      return true;
 
2283
  }
 
2284
  return false;
 
2285
}
 
2286
 
 
2287
 
2258
2288
int subselect_union_engine::exec()
2259
2289
{
2260
 
  char const *save_where= session->where;
 
2290
  char const *save_where= session->where();
2261
2291
  int res= unit->exec();
2262
 
  session->where= save_where;
 
2292
  session->setWhere(save_where);
 
2293
 
2263
2294
  return res;
2264
2295
}
2265
2296
 
2290
2321
  if (table->cursor->inited)
2291
2322
    table->cursor->endIndexScan();
2292
2323
 
2293
 
  table->cursor->startTableScan(1);
 
2324
  if ((error= table->cursor->startTableScan(1)))
 
2325
  {
 
2326
    table->print_error(error, MYF(0));
 
2327
    return 1;
 
2328
  }
 
2329
 
 
2330
  assert(table->getSession());
2294
2331
  table->cursor->extra_opt(HA_EXTRA_CACHE,
2295
 
                           current_session->variables.read_buff_size);
 
2332
                           table->getSession()->variables.read_buff_size);
2296
2333
  table->null_row= 0;
2297
2334
  for (;;)
2298
2335
  {
2467
2504
    return(scan_table());
2468
2505
 
2469
2506
  if (!table->cursor->inited)
2470
 
    table->cursor->startIndexScan(tab->ref.key, 0);
 
2507
  {
 
2508
    error= table->cursor->startIndexScan(tab->ref.key, 0);
 
2509
 
 
2510
    if (error != 0)
 
2511
    {
 
2512
      error= table->report_error(error);
 
2513
      return (error != 0);
 
2514
    }
 
2515
  }
 
2516
 
2471
2517
  error= table->cursor->index_read_map(table->record[0],
2472
2518
                                     tab->ref.key_buff,
2473
2519
                                     make_prev_keypart_map(tab->ref.key_parts),
2580
2626
    return(scan_table());
2581
2627
 
2582
2628
  if (!table->cursor->inited)
2583
 
    table->cursor->startIndexScan(tab->ref.key, 1);
 
2629
  {
 
2630
    error= table->cursor->startIndexScan(tab->ref.key, 1);
 
2631
 
 
2632
    if (error != 0)
 
2633
    {
 
2634
      error= table->report_error(error);
 
2635
      return(error != 0);
 
2636
    }
 
2637
  }
2584
2638
  error= table->cursor->index_read_map(table->record[0],
2585
2639
                                     tab->ref.key_buff,
2586
2640
                                     make_prev_keypart_map(tab->ref.key_parts),
2632
2686
 
2633
2687
uint32_t subselect_single_select_engine::cols()
2634
2688
{
2635
 
  return select_lex->item_list.elements;
 
2689
  return select_lex->item_list.size();
2636
2690
}
2637
2691
 
2638
2692
 
2639
2693
uint32_t subselect_union_engine::cols()
2640
2694
{
2641
 
  return unit->types.elements;
 
2695
  return unit->types.size();
2642
2696
}
2643
2697
 
2644
2698
 
2710
2764
}
2711
2765
 
2712
2766
 
2713
 
void subselect_single_select_engine::print(String *str,
2714
 
                                           enum_query_type query_type)
2715
 
{
2716
 
  select_lex->print(session, str, query_type);
2717
 
}
2718
 
 
2719
 
 
2720
 
void subselect_union_engine::print(String *str, enum_query_type query_type)
2721
 
{
2722
 
  unit->print(str, query_type);
2723
 
}
2724
 
 
2725
 
 
2726
 
void subselect_uniquesubquery_engine::print(String *str,
2727
 
                                            enum_query_type query_type)
2728
 
{
2729
 
  char *table_name= const_cast<char *>(tab->table->getShare()->getTableName());
 
2767
void subselect_single_select_engine::print(String *str)
 
2768
{
 
2769
  select_lex->print(session, str);
 
2770
}
 
2771
 
 
2772
 
 
2773
void subselect_union_engine::print(String *str)
 
2774
{
 
2775
  unit->print(str);
 
2776
}
 
2777
 
 
2778
 
 
2779
void subselect_uniquesubquery_engine::print(String *str)
 
2780
{
 
2781
  const char *table_name= tab->table->getShare()->getTableName();
2730
2782
  str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2731
 
  tab->ref.items[0]->print(str, query_type);
 
2783
  tab->ref.items[0]->print(str);
2732
2784
  str->append(STRING_WITH_LEN(" in "));
2733
2785
  if (tab->table->getShare()->isTemporaryCategory())
2734
2786
  {
2746
2798
  if (cond)
2747
2799
  {
2748
2800
    str->append(STRING_WITH_LEN(" where "));
2749
 
    cond->print(str, query_type);
 
2801
    cond->print(str);
2750
2802
  }
2751
2803
  str->append(')');
2752
2804
}
2775
2827
}
2776
2828
*/
2777
2829
 
2778
 
void subselect_indexsubquery_engine::print(String *str,
2779
 
                                           enum_query_type query_type)
 
2830
void subselect_indexsubquery_engine::print(String *str)
2780
2831
{
2781
2832
  str->append(STRING_WITH_LEN("<index_lookup>("));
2782
 
  tab->ref.items[0]->print(str, query_type);
 
2833
  tab->ref.items[0]->print(str);
2783
2834
  str->append(STRING_WITH_LEN(" in "));
2784
2835
  str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
2785
2836
  KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
2790
2841
  if (cond)
2791
2842
  {
2792
2843
    str->append(STRING_WITH_LEN(" where "));
2793
 
    cond->print(str, query_type);
 
2844
    cond->print(str);
2794
2845
  }
2795
2846
  if (having)
2796
2847
  {
2797
2848
    str->append(STRING_WITH_LEN(" having "));
2798
 
    having->print(str, query_type);
 
2849
    having->print(str);
2799
2850
  }
2800
2851
  str->append(')');
2801
2852
}
3008
3059
    Make sure there is only one index on the temp table, and it doesn't have
3009
3060
    the extra key part created when s->uniques > 0.
3010
3061
  */
3011
 
  assert(tmp_table->getShare()->sizeKeys() == 1 && tmp_columns->elements == tmp_key_parts);
 
3062
  assert(tmp_table->getShare()->sizeKeys() == 1 && tmp_columns->size() == tmp_key_parts);
3012
3063
 
3013
3064
 
3014
3065
  /* 2. Create/initialize execution related objects. */
3020
3071
    - here we initialize only those members that are used by
3021
3072
      subselect_uniquesubquery_engine, so these objects are incomplete.
3022
3073
  */
3023
 
  if (!(tab= (JoinTable*) session->alloc(sizeof(JoinTable))))
 
3074
  if (!(tab= (JoinTable*) session->getMemRoot()->allocate(sizeof(JoinTable))))
3024
3075
    return(true);
 
3076
  new (tab) JoinTable();
3025
3077
  tab->table= tmp_table;
3026
3078
  tab->ref.key= 0; /* The only temp table index. */
3027
3079
  tab->ref.key_length= tmp_key->key_length;
3028
3080
  if (!(tab->ref.key_buff=
3029
3081
        (unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3030
3082
      !(tab->ref.key_copy=
3031
 
        (StoredKey**) session->alloc((sizeof(StoredKey*) *
 
3083
        (StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
3032
3084
                                  (tmp_key_parts + 1)))) ||
3033
3085
      !(tab->ref.items=
3034
 
        (Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
 
3086
        (Item**) session->getMemRoot()->allocate(sizeof(Item*) * tmp_key_parts)))
3035
3087
    return(true);
3036
3088
 
3037
3089
  KeyPartInfo *cur_key_part= tmp_key->key_part;
3132
3184
  if (!is_materialized)
3133
3185
  {
3134
3186
    int res= 0;
3135
 
    Select_Lex *save_select= session->lex->current_select;
3136
 
    session->lex->current_select= materialize_engine->select_lex;
 
3187
    Select_Lex *save_select= session->getLex()->current_select;
 
3188
    session->getLex()->current_select= materialize_engine->select_lex;
3137
3189
    if ((res= materialize_join->optimize()))
3138
3190
      goto err;
 
3191
 
 
3192
    if (materialize_engine->save_join_if_explain())
 
3193
      goto err;
 
3194
 
3139
3195
    materialize_join->exec();
3140
3196
    if ((res= test(materialize_join->error || session->is_fatal_error)))
3141
3197
      goto err;
3170
3226
      tmp_param= NULL;
3171
3227
 
3172
3228
err:
3173
 
    session->lex->current_select= save_select;
 
3229
    session->getLex()->current_select= save_select;
3174
3230
    if (res)
3175
3231
      return(res);
3176
3232
  }
3186
3242
  Print the state of this engine into a string for debugging and views.
3187
3243
*/
3188
3244
 
3189
 
void subselect_hash_sj_engine::print(String *str, enum_query_type query_type)
 
3245
void subselect_hash_sj_engine::print(String *str)
3190
3246
{
3191
3247
  str->append(STRING_WITH_LEN(" <materialize> ("));
3192
 
  materialize_engine->print(str, query_type);
 
3248
  materialize_engine->print(str);
3193
3249
  str->append(STRING_WITH_LEN(" ), "));
3194
3250
  if (tab)
3195
 
    subselect_uniquesubquery_engine::print(str, query_type);
 
3251
    subselect_uniquesubquery_engine::print(str);
3196
3252
  else
3197
3253
    str->append(STRING_WITH_LEN(
3198
3254
           "<the access method for lookups is not yet created>"