~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/subselect.cc

edit

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
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>
32
31
#include <drizzled/sql_select.h>
33
32
#include <drizzled/error.h>
34
33
#include <drizzled/item/cache.h>
40
39
#include <drizzled/item/ref_null_helper.h>
41
40
#include <drizzled/item/direct_ref.h>
42
41
#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>
48
42
 
49
43
namespace drizzled
50
44
{
186
180
 
187
181
bool Item_subselect::fix_fields(Session *session_param, Item **ref)
188
182
{
189
 
  char const *save_where= session_param->where();
 
183
  char const *save_where= session_param->where;
190
184
  bool res;
191
185
 
192
186
  assert(fixed == 0);
229
223
        engine->exclude();
230
224
      }
231
225
      substitution= 0;
232
 
      session->setWhere("checking transformed subquery");
 
226
      session->where= "checking transformed subquery";
233
227
      if (! (*ref)->fixed)
234
228
      {
235
229
        ret= (*ref)->fix_fields(session, ref);
236
230
      }
237
 
      session->setWhere(save_where);
238
 
 
 
231
      session->where= save_where;
239
232
      return ret;
240
233
    }
241
234
    // Is it one field subselect?
260
253
  fixed= 1;
261
254
 
262
255
err:
263
 
  session->setWhere(save_where);
 
256
  session->where= save_where;
264
257
  return res;
265
258
}
266
259
 
273
266
  {
274
267
    for (Select_Lex *lex= unit->first_select(); lex; lex= lex->next_select())
275
268
    {
276
 
      List<Item>::iterator li(lex->item_list.begin());
 
269
      List_iterator<Item> li(lex->item_list);
277
270
      Item *item;
278
271
      Order *order;
279
272
 
538
531
  {
539
532
 
540
533
    have_to_be_excluded= 1;
541
 
    if (session->getLex()->describe)
 
534
    if (session->lex->describe)
542
535
    {
543
536
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
544
537
      snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
1057
1050
        upper_item->set_sum_test(item);
1058
1051
      *select_lex->ref_pointer_array= item;
1059
1052
      {
1060
 
        List<Item>::iterator it(select_lex->item_list.begin());
 
1053
        List_iterator<Item> it(select_lex->item_list);
1061
1054
        it++;
1062
1055
        it.replace(item);
1063
1056
      }
1064
1057
 
1065
 
      save_allow_sum_func= session->getLex()->allow_sum_func;
1066
 
      session->getLex()->allow_sum_func|= 1 << session->getLex()->current_select->nest_level;
 
1058
      save_allow_sum_func= session->lex->allow_sum_func;
 
1059
      session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
1067
1060
      /*
1068
1061
        Item_sum_(max|min) can't substitute other item => we can use 0 as
1069
1062
        reference, also Item_sum_(max|min) can't be fixed after creation, so
1071
1064
      */
1072
1065
      if (item->fix_fields(session, 0))
1073
1066
        return(RES_ERROR);
1074
 
      session->getLex()->allow_sum_func= save_allow_sum_func;
 
1067
      session->lex->allow_sum_func= save_allow_sum_func;
1075
1068
      /* we added aggregate function => we have to change statistic */
1076
1069
      count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
1077
1070
                        0);
1096
1089
    Select_Lex_Unit *master_unit= select_lex->master_unit();
1097
1090
    substitution= optimizer;
1098
1091
 
1099
 
    Select_Lex *current= session->getLex()->current_select, *up;
 
1092
    Select_Lex *current= session->lex->current_select, *up;
1100
1093
 
1101
 
    session->getLex()->current_select= up= current->return_after_parsing();
 
1094
    session->lex->current_select= up= current->return_after_parsing();
1102
1095
    //optimizer never use Item **ref => we can pass 0 as parameter
1103
1096
    if (!optimizer || optimizer->fix_left(session, 0))
1104
1097
    {
1105
 
      session->getLex()->current_select= current;
 
1098
      session->lex->current_select= current;
1106
1099
      return(RES_ERROR);
1107
1100
    }
1108
 
    session->getLex()->current_select= current;
 
1101
    session->lex->current_select= current;
1109
1102
 
1110
1103
    /*
1111
1104
      As far as  Item_ref_in_optimizer do not substitute itself on fix_fields
1121
1114
 
1122
1115
  if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1123
1116
  {
1124
 
    if (!(pushed_cond_guards= (bool*)join->session->getMemRoot()->allocate(sizeof(bool))))
 
1117
    if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool))))
1125
1118
      return(RES_ERROR);
1126
1119
    pushed_cond_guards[0]= true;
1127
1120
  }
1226
1219
    {
1227
1220
      bool tmp;
1228
1221
      Item *having= item, *orig_item= item;
1229
 
      select_lex->item_list.clear();
 
1222
      select_lex->item_list.empty();
1230
1223
      select_lex->item_list.push_back(new Item_int("Not_used",
1231
1224
                                                   (int64_t) 1,
1232
1225
                                                   MY_INT64_NUM_DECIMAL_DIGITS));
1334
1327
        // fix_field of item will be done in time of substituting
1335
1328
        substitution= item;
1336
1329
        have_to_be_excluded= 1;
1337
 
        if (session->getLex()->describe)
 
1330
        if (session->lex->describe)
1338
1331
        {
1339
1332
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
1340
1333
          snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
1372
1365
    Select_Lex_Unit *master_unit= select_lex->master_unit();
1373
1366
    substitution= optimizer;
1374
1367
 
1375
 
    Select_Lex *current= session->getLex()->current_select, *up;
1376
 
    session->getLex()->current_select= up= current->return_after_parsing();
 
1368
    Select_Lex *current= session->lex->current_select, *up;
 
1369
    session->lex->current_select= up= current->return_after_parsing();
1377
1370
    //optimizer never use Item **ref => we can pass 0 as parameter
1378
1371
    if (!optimizer || optimizer->fix_left(session, 0))
1379
1372
    {
1380
 
      session->getLex()->current_select= current;
 
1373
      session->lex->current_select= current;
1381
1374
      return(RES_ERROR);
1382
1375
    }
1383
1376
 
1384
1377
    // we will refer to upper level cache array => we have to save it in PS
1385
1378
    optimizer->keep_top_level_cache();
1386
1379
 
1387
 
    session->getLex()->current_select= current;
 
1380
    session->lex->current_select= current;
1388
1381
    master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
1389
1382
 
1390
1383
    if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1391
1384
    {
1392
 
      if (!(pushed_cond_guards= (bool*)join->session->getMemRoot()->allocate(sizeof(bool) *
 
1385
      if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool) *
1393
1386
                                                        left_expr->cols())))
1394
1387
        return(RES_ERROR);
1395
1388
      for (uint32_t i= 0; i < cols_num; i++)
1656
1649
Item_subselect::trans_res
1657
1650
Item_in_subselect::select_in_like_transformer(Join *join, const Comp_creator *func)
1658
1651
{
1659
 
  Select_Lex *current= session->getLex()->current_select, *up;
1660
 
  const char *save_where= session->where();
 
1652
  Select_Lex *current= session->lex->current_select, *up;
 
1653
  const char *save_where= session->where;
1661
1654
  Item_subselect::trans_res res= RES_ERROR;
1662
1655
  bool result;
1663
1656
 
1677
1670
  if (changed)
1678
1671
    return(RES_OK);
1679
1672
 
1680
 
  session->setWhere("IN/ALL/ANY subquery");
 
1673
  session->where= "IN/ALL/ANY subquery";
1681
1674
 
1682
1675
  /*
1683
1676
    In some optimisation cases we will not need this Item_in_optimizer
1691
1684
      goto err;
1692
1685
  }
1693
1686
 
1694
 
  session->getLex()->current_select= up= current->return_after_parsing();
 
1687
  session->lex->current_select= up= current->return_after_parsing();
1695
1688
  result= (!left_expr->fixed &&
1696
1689
           left_expr->fix_fields(session, optimizer->arguments()));
1697
1690
  /* fix_fields can change reference to left_expr, we need reassign it */
1698
1691
  left_expr= optimizer->arguments()[0];
1699
1692
 
1700
 
  session->getLex()->current_select= current;
 
1693
  session->lex->current_select= current;
1701
1694
  if (result)
1702
1695
    goto err;
1703
1696
 
1728
1721
    res= row_value_transformer(join);
1729
1722
  }
1730
1723
err:
1731
 
  session->setWhere(save_where);
 
1724
  session->where= save_where;
1732
1725
  return(res);
1733
1726
}
1734
1727
 
2038
2031
  if (!join || !result)
2039
2032
    return 1; /* Fatal error is set already. */
2040
2033
  prepared= 1;
2041
 
  Select_Lex *save_select= session->getLex()->current_select;
2042
 
  session->getLex()->current_select= select_lex;
 
2034
  Select_Lex *save_select= session->lex->current_select;
 
2035
  session->lex->current_select= select_lex;
2043
2036
  if (join->prepare(&select_lex->ref_pointer_array,
2044
2037
                    (TableList*) select_lex->table_list.first,
2045
2038
                    select_lex->with_wild,
2051
2044
                    select_lex->having,
2052
2045
                    select_lex, select_lex->master_unit()))
2053
2046
    return 1;
2054
 
  session->getLex()->current_select= save_select;
 
2047
  session->lex->current_select= save_select;
2055
2048
  return 0;
2056
2049
}
2057
2050
 
2096
2089
void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
2097
2090
{
2098
2091
  Item *sel_item;
2099
 
  List<Item>::iterator li(item_list.begin());
 
2092
  List_iterator_fast<Item> li(item_list);
2100
2093
  res_type= STRING_RESULT;
2101
2094
  res_field_type= DRIZZLE_TYPE_VARCHAR;
2102
2095
  for (uint32_t i= 0; (sel_item= li++); i++)
2149
2142
 
2150
2143
int subselect_single_select_engine::exec()
2151
2144
{
2152
 
  char const *save_where= session->where();
2153
 
  Select_Lex *save_select= session->getLex()->current_select;
2154
 
  session->getLex()->current_select= select_lex;
 
2145
  char const *save_where= session->where;
 
2146
  Select_Lex *save_select= session->lex->current_select;
 
2147
  session->lex->current_select= select_lex;
2155
2148
  if (!join->optimized)
2156
2149
  {
2157
2150
    Select_Lex_Unit *unit= select_lex->master_unit();
2159
2152
    unit->set_limit(unit->global_parameters);
2160
2153
    if (join->optimize())
2161
2154
    {
2162
 
      session->setWhere(save_where);
 
2155
      session->where= save_where;
2163
2156
      executed= 1;
2164
 
      session->getLex()->current_select= save_select;
 
2157
      session->lex->current_select= save_select;
2165
2158
      return(join->error ? join->error : 1);
2166
2159
    }
2167
2160
    if (save_join_if_explain())
2178
2171
  {
2179
2172
    if (join->reinit())
2180
2173
    {
2181
 
      session->setWhere(save_where);
2182
 
      session->getLex()->current_select= save_select;
 
2174
      session->where= save_where;
 
2175
      session->lex->current_select= save_select;
2183
2176
      return 1;
2184
2177
    }
2185
2178
    item->reset();
2237
2230
      tab->read_record.read_record= tab->save_read_record;
2238
2231
    }
2239
2232
    executed= 1;
2240
 
    session->setWhere(save_where);
2241
 
    session->getLex()->current_select= save_select;
 
2233
    session->where= save_where;
 
2234
    session->lex->current_select= save_select;
2242
2235
    return(join->error||session->is_fatal_error);
2243
2236
  }
2244
 
  session->setWhere(save_where);
2245
 
  session->getLex()->current_select= save_select;
 
2237
  session->where= save_where;
 
2238
  session->lex->current_select= save_select;
2246
2239
  return(0);
2247
2240
}
2248
2241
 
2262
2255
        make a replacement JOIN by calling make_simple_join(). 
2263
2256
     5) The Item_subselect is cacheable
2264
2257
  */
2265
 
  if (session->getLex()->describe &&                          // 1
 
2258
  if (session->lex->describe &&                          // 1
2266
2259
      select_lex->uncacheable.none() &&                  // 2
2267
2260
      !(join->select_options & SELECT_DESCRIBE) &&       // 3
2268
2261
      join->need_tmp &&                                  // 4
2286
2279
 
2287
2280
int subselect_union_engine::exec()
2288
2281
{
2289
 
  char const *save_where= session->where();
 
2282
  char const *save_where= session->where;
2290
2283
  int res= unit->exec();
2291
 
  session->setWhere(save_where);
2292
 
 
 
2284
  session->where= save_where;
2293
2285
  return res;
2294
2286
}
2295
2287
 
2326
2318
    return 1;
2327
2319
  }
2328
2320
 
2329
 
  assert(table->getSession());
2330
2321
  table->cursor->extra_opt(HA_EXTRA_CACHE,
2331
 
                           table->getSession()->variables.read_buff_size);
 
2322
                           current_session->variables.read_buff_size);
2332
2323
  table->null_row= 0;
2333
2324
  for (;;)
2334
2325
  {
2779
2770
void subselect_uniquesubquery_engine::print(String *str,
2780
2771
                                            enum_query_type query_type)
2781
2772
{
2782
 
  const char *table_name= tab->table->getShare()->getTableName();
 
2773
  char *table_name= const_cast<char *>(tab->table->getShare()->getTableName());
2783
2774
  str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2784
2775
  tab->ref.items[0]->print(str, query_type);
2785
2776
  str->append(STRING_WITH_LEN(" in "));
3073
3064
    - here we initialize only those members that are used by
3074
3065
      subselect_uniquesubquery_engine, so these objects are incomplete.
3075
3066
  */
3076
 
  if (!(tab= (JoinTable*) session->getMemRoot()->allocate(sizeof(JoinTable))))
 
3067
  if (!(tab= (JoinTable*) session->alloc(sizeof(JoinTable))))
3077
3068
    return(true);
3078
3069
  new (tab) JoinTable();
3079
3070
  tab->table= tmp_table;
3082
3073
  if (!(tab->ref.key_buff=
3083
3074
        (unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3084
3075
      !(tab->ref.key_copy=
3085
 
        (StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
 
3076
        (StoredKey**) session->alloc((sizeof(StoredKey*) *
3086
3077
                                  (tmp_key_parts + 1)))) ||
3087
3078
      !(tab->ref.items=
3088
 
        (Item**) session->getMemRoot()->allocate(sizeof(Item*) * tmp_key_parts)))
 
3079
        (Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
3089
3080
    return(true);
3090
3081
 
3091
3082
  KeyPartInfo *cur_key_part= tmp_key->key_part;
3186
3177
  if (!is_materialized)
3187
3178
  {
3188
3179
    int res= 0;
3189
 
    Select_Lex *save_select= session->getLex()->current_select;
3190
 
    session->getLex()->current_select= materialize_engine->select_lex;
 
3180
    Select_Lex *save_select= session->lex->current_select;
 
3181
    session->lex->current_select= materialize_engine->select_lex;
3191
3182
    if ((res= materialize_join->optimize()))
3192
3183
      goto err;
3193
3184
 
3228
3219
      tmp_param= NULL;
3229
3220
 
3230
3221
err:
3231
 
    session->getLex()->current_select= save_select;
 
3222
    session->lex->current_select= save_select;
3232
3223
    if (res)
3233
3224
      return(res);
3234
3225
  }