~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/subselect.cc

  • Committer: Monty Taylor
  • Date: 2011-02-13 17:26:39 UTC
  • mfrom: (2157.2.2 give-in-to-pkg-config)
  • mto: This revision was merged to the branch mainline in revision 2166.
  • Revision ID: mordred@inaugust.com-20110213172639-nhy7i72sfhoq13ms
Merged in pkg-config fixes.

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
26
#include "config.h"
39
39
#include <drizzled/item/ref_null_helper.h>
40
40
#include <drizzled/item/direct_ref.h>
41
41
#include <drizzled/join.h>
 
42
#include <drizzled/plugin/storage_engine.h>
42
43
 
43
44
namespace drizzled
44
45
{
180
181
 
181
182
bool Item_subselect::fix_fields(Session *session_param, Item **ref)
182
183
{
183
 
  char const *save_where= session_param->where;
 
184
  char const *save_where= session_param->where();
184
185
  bool res;
185
186
 
186
187
  assert(fixed == 0);
223
224
        engine->exclude();
224
225
      }
225
226
      substitution= 0;
226
 
      session->where= "checking transformed subquery";
 
227
      session->setWhere("checking transformed subquery");
227
228
      if (! (*ref)->fixed)
228
229
      {
229
230
        ret= (*ref)->fix_fields(session, ref);
230
231
      }
231
 
      session->where= save_where;
 
232
      session->setWhere(save_where);
 
233
 
232
234
      return ret;
233
235
    }
234
236
    // Is it one field subselect?
244
246
 
245
247
  if (engine->uncacheable())
246
248
  {
247
 
    const_item_cache= 0;
 
249
    const_item_cache= false;
248
250
    if (engine->uncacheable(UNCACHEABLE_RAND))
249
251
    {
250
252
      used_tables_cache|= RAND_TABLE_BIT;
253
255
  fixed= 1;
254
256
 
255
257
err:
256
 
  session->where= save_where;
 
258
  session->setWhere(save_where);
257
259
  return res;
258
260
}
259
261
 
394
396
  {
395
397
    // did all used tables become static?
396
398
    if (!(used_tables_cache & ~engine->upper_select_const_tables()))
397
 
      const_item_cache= 1;
 
399
      const_item_cache= true;
398
400
  }
399
401
}
400
402
 
668
670
}
669
671
 
670
672
 
671
 
my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value)
 
673
type::Decimal *Item_singlerow_subselect::val_decimal(type::Decimal *decimal_value)
672
674
{
673
675
  if (!exec() && !value->null_value)
674
676
  {
818
820
}
819
821
 
820
822
 
821
 
my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
 
823
type::Decimal *Item_exists_subselect::val_decimal(type::Decimal *decimal_value)
822
824
{
823
825
  assert(fixed == 1);
824
826
  if (exec())
826
828
    reset();
827
829
    return 0;
828
830
  }
829
 
  int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
 
831
  int2_class_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
830
832
  return decimal_value;
831
833
}
832
834
 
929
931
  return value;
930
932
}
931
933
 
932
 
my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
 
934
type::Decimal *Item_in_subselect::val_decimal(type::Decimal *decimal_value)
933
935
{
934
936
  /*
935
937
    As far as Item_in_subselect called only from Item_in_optimizer this
946
948
  }
947
949
  if (was_null && !value)
948
950
    null_value= 1;
949
 
  int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
 
951
  int2_class_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
950
952
  return decimal_value;
951
953
}
952
954
 
1114
1116
 
1115
1117
  if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1116
1118
  {
1117
 
    if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool))))
 
1119
    if (!(pushed_cond_guards= (bool*)join->session->getMemRoot()->allocate(sizeof(bool))))
1118
1120
      return(RES_ERROR);
1119
1121
    pushed_cond_guards[0]= true;
1120
1122
  }
1382
1384
 
1383
1385
    if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1384
1386
    {
1385
 
      if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool) *
 
1387
      if (!(pushed_cond_guards= (bool*)join->session->getMemRoot()->allocate(sizeof(bool) *
1386
1388
                                                        left_expr->cols())))
1387
1389
        return(RES_ERROR);
1388
1390
      for (uint32_t i= 0; i < cols_num; i++)
1650
1652
Item_in_subselect::select_in_like_transformer(Join *join, const Comp_creator *func)
1651
1653
{
1652
1654
  Select_Lex *current= session->lex->current_select, *up;
1653
 
  const char *save_where= session->where;
 
1655
  const char *save_where= session->where();
1654
1656
  Item_subselect::trans_res res= RES_ERROR;
1655
1657
  bool result;
1656
1658
 
1670
1672
  if (changed)
1671
1673
    return(RES_OK);
1672
1674
 
1673
 
  session->where= "IN/ALL/ANY subquery";
 
1675
  session->setWhere("IN/ALL/ANY subquery");
1674
1676
 
1675
1677
  /*
1676
1678
    In some optimisation cases we will not need this Item_in_optimizer
1721
1723
    res= row_value_transformer(join);
1722
1724
  }
1723
1725
err:
1724
 
  session->where= save_where;
 
1726
  session->setWhere(save_where);
1725
1727
  return(res);
1726
1728
}
1727
1729
 
2140
2142
  assert(0);
2141
2143
}
2142
2144
 
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
2145
int subselect_single_select_engine::exec()
2148
2146
{
2149
 
  char const *save_where= session->where;
 
2147
  char const *save_where= session->where();
2150
2148
  Select_Lex *save_select= session->lex->current_select;
2151
2149
  session->lex->current_select= select_lex;
2152
2150
  if (!join->optimized)
2156
2154
    unit->set_limit(unit->global_parameters);
2157
2155
    if (join->optimize())
2158
2156
    {
2159
 
      session->where= save_where;
 
2157
      session->setWhere(save_where);
2160
2158
      executed= 1;
2161
2159
      session->lex->current_select= save_select;
2162
2160
      return(join->error ? join->error : 1);
2163
2161
    }
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
 
    }
 
2162
    if (save_join_if_explain())
 
2163
     return(1);
 
2164
 
2179
2165
    if (item->engine_changed)
2180
2166
    {
2181
2167
      return(1);
2187
2173
  {
2188
2174
    if (join->reinit())
2189
2175
    {
2190
 
      session->where= save_where;
 
2176
      session->setWhere(save_where);
2191
2177
      session->lex->current_select= save_select;
2192
2178
      return 1;
2193
2179
    }
2246
2232
      tab->read_record.read_record= tab->save_read_record;
2247
2233
    }
2248
2234
    executed= 1;
2249
 
    session->where= save_where;
 
2235
    session->setWhere(save_where);
2250
2236
    session->lex->current_select= save_select;
2251
2237
    return(join->error||session->is_fatal_error);
2252
2238
  }
2253
 
  session->where= save_where;
 
2239
  session->setWhere(save_where);
2254
2240
  session->lex->current_select= save_select;
2255
2241
  return(0);
2256
2242
}
2257
2243
 
 
2244
bool 
 
2245
subselect_single_select_engine::save_join_if_explain()
 
2246
{
 
2247
  /*
 
2248
    Save this JOIN to join->tmp_join since the original layout will be
 
2249
    replaced when JOIN::exec() calls make_simple_join() if:
 
2250
     1) We are executing an EXPLAIN query
 
2251
     2) An uncacheable flag has not been set for the select_lex. If
 
2252
        set, JOIN::optimize() has already saved the JOIN
 
2253
     3) Call does not come from select_describe()). If it does,
 
2254
        JOIN::exec() will not call make_simple_join() and the JOIN we
 
2255
        plan to save will not be replaced anyway.
 
2256
     4) A temp table is needed. This is what triggers JOIN::exec() to
 
2257
        make a replacement JOIN by calling make_simple_join(). 
 
2258
     5) The Item_subselect is cacheable
 
2259
  */
 
2260
  if (session->lex->describe &&                          // 1
 
2261
      select_lex->uncacheable.none() &&                  // 2
 
2262
      !(join->select_options & SELECT_DESCRIBE) &&       // 3
 
2263
      join->need_tmp &&                                  // 4
 
2264
      item->const_item())                                // 5
 
2265
  {
 
2266
    /*
 
2267
      Save this JOIN to join->tmp_join since the original layout will
 
2268
      be replaced when JOIN::exec() calls make_simple_join() due to
 
2269
      need_tmp==TRUE. The original layout is needed so we can describe
 
2270
      the query. No need to do this if uncacheable != 0 since in this
 
2271
      case the JOIN has already been saved during JOIN::optimize()
 
2272
    */
 
2273
    select_lex->uncacheable.set(UNCACHEABLE_EXPLAIN);
 
2274
    select_lex->master_unit()->uncacheable.set(UNCACHEABLE_EXPLAIN);
 
2275
    if (join->init_save_join_tab())
 
2276
      return true;
 
2277
  }
 
2278
  return false;
 
2279
}
 
2280
 
 
2281
 
2258
2282
int subselect_union_engine::exec()
2259
2283
{
2260
 
  char const *save_where= session->where;
 
2284
  char const *save_where= session->where();
2261
2285
  int res= unit->exec();
2262
 
  session->where= save_where;
 
2286
  session->setWhere(save_where);
 
2287
 
2263
2288
  return res;
2264
2289
}
2265
2290
 
2290
2315
  if (table->cursor->inited)
2291
2316
    table->cursor->endIndexScan();
2292
2317
 
2293
 
  table->cursor->startTableScan(1);
 
2318
  if ((error= table->cursor->startTableScan(1)))
 
2319
  {
 
2320
    table->print_error(error, MYF(0));
 
2321
    return 1;
 
2322
  }
 
2323
 
 
2324
  assert(table->getSession());
2294
2325
  table->cursor->extra_opt(HA_EXTRA_CACHE,
2295
 
                           current_session->variables.read_buff_size);
 
2326
                           table->getSession()->variables.read_buff_size);
2296
2327
  table->null_row= 0;
2297
2328
  for (;;)
2298
2329
  {
2467
2498
    return(scan_table());
2468
2499
 
2469
2500
  if (!table->cursor->inited)
2470
 
    table->cursor->startIndexScan(tab->ref.key, 0);
 
2501
  {
 
2502
    error= table->cursor->startIndexScan(tab->ref.key, 0);
 
2503
 
 
2504
    if (error != 0)
 
2505
    {
 
2506
      error= table->report_error(error);
 
2507
      return (error != 0);
 
2508
    }
 
2509
  }
 
2510
 
2471
2511
  error= table->cursor->index_read_map(table->record[0],
2472
2512
                                     tab->ref.key_buff,
2473
2513
                                     make_prev_keypart_map(tab->ref.key_parts),
2580
2620
    return(scan_table());
2581
2621
 
2582
2622
  if (!table->cursor->inited)
2583
 
    table->cursor->startIndexScan(tab->ref.key, 1);
 
2623
  {
 
2624
    error= table->cursor->startIndexScan(tab->ref.key, 1);
 
2625
 
 
2626
    if (error != 0)
 
2627
    {
 
2628
      error= table->report_error(error);
 
2629
      return(error != 0);
 
2630
    }
 
2631
  }
2584
2632
  error= table->cursor->index_read_map(table->record[0],
2585
2633
                                     tab->ref.key_buff,
2586
2634
                                     make_prev_keypart_map(tab->ref.key_parts),
3020
3068
    - here we initialize only those members that are used by
3021
3069
      subselect_uniquesubquery_engine, so these objects are incomplete.
3022
3070
  */
3023
 
  if (!(tab= (JoinTable*) session->alloc(sizeof(JoinTable))))
 
3071
  if (!(tab= (JoinTable*) session->getMemRoot()->allocate(sizeof(JoinTable))))
3024
3072
    return(true);
 
3073
  new (tab) JoinTable();
3025
3074
  tab->table= tmp_table;
3026
3075
  tab->ref.key= 0; /* The only temp table index. */
3027
3076
  tab->ref.key_length= tmp_key->key_length;
3028
3077
  if (!(tab->ref.key_buff=
3029
3078
        (unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3030
3079
      !(tab->ref.key_copy=
3031
 
        (StoredKey**) session->alloc((sizeof(StoredKey*) *
 
3080
        (StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
3032
3081
                                  (tmp_key_parts + 1)))) ||
3033
3082
      !(tab->ref.items=
3034
 
        (Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
 
3083
        (Item**) session->getMemRoot()->allocate(sizeof(Item*) * tmp_key_parts)))
3035
3084
    return(true);
3036
3085
 
3037
3086
  KeyPartInfo *cur_key_part= tmp_key->key_part;
3136
3185
    session->lex->current_select= materialize_engine->select_lex;
3137
3186
    if ((res= materialize_join->optimize()))
3138
3187
      goto err;
 
3188
 
 
3189
    if (materialize_engine->save_join_if_explain())
 
3190
      goto err;
 
3191
 
3139
3192
    materialize_join->exec();
3140
3193
    if ((res= test(materialize_join->error || session->is_fatal_error)))
3141
3194
      goto err;