~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/subselect.cc

  • Committer: Lee Bieber
  • Date: 2010-11-07 19:34:48 UTC
  • mfrom: (1910.1.2 build)
  • Revision ID: kalebral@gmail.com-20101107193448-64kdu912qej354sh
Merge Stewart - including adapting and expanding the "differences from mysql" page from the wiki.
Merge Stewart - fix bug 668143: drizzleslap with --commit runs second iteration data load in a transaction

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