~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/subselect.cc

  • Committer: patrick crews
  • Date: 2010-09-29 15:15:19 UTC
  • mfrom: (1099.4.188 drizzle)
  • Revision ID: gleebix@gmail.com-20100929151519-6mrmzd1ciw2p9nws
Tags: 2010.09.1802
Update translations

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/**
17
17
  @file
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;
 
184
  uint8_t uncacheable;
185
185
  bool res;
186
186
 
187
187
  assert(fixed == 0);
209
209
 
210
210
      // did we changed top item of WHERE condition
211
211
      if (unit->outer_select()->where == (*ref))
212
 
      {
213
 
        unit->outer_select()->where= substitution; // correct WHERE for PS
214
 
      }
 
212
        unit->outer_select()->where= substitution; // correct WHERE for PS
215
213
      else if (unit->outer_select()->having == (*ref))
216
 
      {
217
 
        unit->outer_select()->having= substitution; // correct HAVING for PS
218
 
      }
 
214
        unit->outer_select()->having= substitution; // correct HAVING for PS
219
215
 
220
216
      (*ref)= substitution;
221
217
      substitution->name= name;
222
218
      if (have_to_be_excluded)
223
 
      {
224
 
        engine->exclude();
225
 
      }
 
219
        engine->exclude();
226
220
      substitution= 0;
227
 
      session->setWhere("checking transformed subquery");
228
 
      if (! (*ref)->fixed)
229
 
      {
230
 
        ret= (*ref)->fix_fields(session, ref);
231
 
      }
232
 
      session->setWhere(save_where);
233
 
 
 
221
      session->where= "checking transformed subquery";
 
222
      if (!(*ref)->fixed)
 
223
        ret= (*ref)->fix_fields(session, ref);
 
224
      session->where= save_where;
234
225
      return ret;
235
226
    }
236
227
    // Is it one field subselect?
244
235
  else
245
236
    goto err;
246
237
 
247
 
  if (engine->uncacheable())
 
238
  if ((uncacheable= engine->uncacheable()))
248
239
  {
249
 
    const_item_cache= false;
250
 
    if (engine->uncacheable(UNCACHEABLE_RAND))
251
 
    {
 
240
    const_item_cache= 0;
 
241
    if (uncacheable & UNCACHEABLE_RAND)
252
242
      used_tables_cache|= RAND_TABLE_BIT;
253
 
    }
254
243
  }
255
244
  fixed= 1;
256
245
 
257
246
err:
258
 
  session->setWhere(save_where);
 
247
  session->where= save_where;
259
248
  return res;
260
249
}
261
250
 
270
259
    {
271
260
      List_iterator<Item> li(lex->item_list);
272
261
      Item *item;
273
 
      Order *order;
 
262
      order_st *order;
274
263
 
275
264
      if (lex->where && (lex->where)->walk(processor, walk_subquery, argument))
276
265
        return 1;
283
272
        if (item->walk(processor, walk_subquery, argument))
284
273
          return 1;
285
274
      }
286
 
      for (order= (Order*) lex->order_list.first ; order; order= order->next)
 
275
      for (order= (order_st*) lex->order_list.first ; order; order= order->next)
287
276
      {
288
277
        if ((*order->item)->walk(processor, walk_subquery, argument))
289
278
          return 1;
290
279
      }
291
 
      for (order= (Order*) lex->group_list.first ; order; order= order->next)
 
280
      for (order= (order_st*) lex->group_list.first ; order; order= order->next)
292
281
      {
293
282
        if ((*order->item)->walk(processor, walk_subquery, argument))
294
283
          return 1;
392
381
 
393
382
void Item_subselect::update_used_tables()
394
383
{
395
 
  if (! engine->uncacheable())
 
384
  if (!engine->uncacheable())
396
385
  {
397
386
    // did all used tables become static?
398
387
    if (!(used_tables_cache & ~engine->upper_select_const_tables()))
399
 
      const_item_cache= true;
 
388
      const_item_cache= 1;
400
389
  }
401
390
}
402
391
 
670
659
}
671
660
 
672
661
 
673
 
type::Decimal *Item_singlerow_subselect::val_decimal(type::Decimal *decimal_value)
 
662
my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value)
674
663
{
675
664
  if (!exec() && !value->null_value)
676
665
  {
820
809
}
821
810
 
822
811
 
823
 
type::Decimal *Item_exists_subselect::val_decimal(type::Decimal *decimal_value)
 
812
my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
824
813
{
825
814
  assert(fixed == 1);
826
815
  if (exec())
828
817
    reset();
829
818
    return 0;
830
819
  }
831
 
  int2_class_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
 
820
  int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
832
821
  return decimal_value;
833
822
}
834
823
 
931
920
  return value;
932
921
}
933
922
 
934
 
type::Decimal *Item_in_subselect::val_decimal(type::Decimal *decimal_value)
 
923
my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
935
924
{
936
925
  /*
937
926
    As far as Item_in_subselect called only from Item_in_optimizer this
948
937
  }
949
938
  if (was_null && !value)
950
939
    null_value= 1;
951
 
  int2_class_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
 
940
  int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
952
941
  return decimal_value;
953
942
}
954
943
 
1015
1004
    later in this method.
1016
1005
  */
1017
1006
  if ((abort_on_null || (upper_item && upper_item->top_level())) &&
1018
 
      select_lex->master_unit()->uncacheable.none() && !func->eqne_op())
 
1007
      !select_lex->master_unit()->uncacheable && !func->eqne_op())
1019
1008
  {
1020
1009
    if (substitution)
1021
1010
    {
1111
1100
                              (char *)"<no matter>",
1112
1101
                              (char *)in_left_expr_name);
1113
1102
 
1114
 
    master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1103
    master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1115
1104
  }
1116
1105
 
1117
1106
  if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1118
1107
  {
1119
 
    if (!(pushed_cond_guards= (bool*)join->session->getMemRoot()->allocate(sizeof(bool))))
 
1108
    if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool))))
1120
1109
      return(RES_ERROR);
1121
1110
    pushed_cond_guards[0]= true;
1122
1111
  }
1174
1163
{
1175
1164
  Select_Lex *select_lex= join->select_lex;
1176
1165
 
1177
 
  select_lex->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1166
  select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1178
1167
  if (join->having || select_lex->with_sum_func ||
1179
1168
      select_lex->group_list.elements)
1180
1169
  {
1380
1369
    optimizer->keep_top_level_cache();
1381
1370
 
1382
1371
    session->lex->current_select= current;
1383
 
    master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1372
    master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1384
1373
 
1385
1374
    if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1386
1375
    {
1387
 
      if (!(pushed_cond_guards= (bool*)join->session->getMemRoot()->allocate(sizeof(bool) *
 
1376
      if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool) *
1388
1377
                                                        left_expr->cols())))
1389
1378
        return(RES_ERROR);
1390
1379
      for (uint32_t i= 0; i < cols_num; i++)
1432
1421
                        select_lex->group_list.first ||
1433
1422
                        !select_lex->table_list.elements);
1434
1423
 
1435
 
  select_lex->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1424
  select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1436
1425
  if (is_having_used)
1437
1426
  {
1438
1427
    /*
1652
1641
Item_in_subselect::select_in_like_transformer(Join *join, const Comp_creator *func)
1653
1642
{
1654
1643
  Select_Lex *current= session->lex->current_select, *up;
1655
 
  const char *save_where= session->where();
 
1644
  const char *save_where= session->where;
1656
1645
  Item_subselect::trans_res res= RES_ERROR;
1657
1646
  bool result;
1658
1647
 
1672
1661
  if (changed)
1673
1662
    return(RES_OK);
1674
1663
 
1675
 
  session->setWhere("IN/ALL/ANY subquery");
 
1664
  session->where= "IN/ALL/ANY subquery";
1676
1665
 
1677
1666
  /*
1678
1667
    In some optimisation cases we will not need this Item_in_optimizer
1723
1712
    res= row_value_transformer(join);
1724
1713
  }
1725
1714
err:
1726
 
  session->setWhere(save_where);
 
1715
  session->where= save_where;
1727
1716
  return(res);
1728
1717
}
1729
1718
 
2041
2030
                    select_lex->where,
2042
2031
                    select_lex->order_list.elements +
2043
2032
                    select_lex->group_list.elements,
2044
 
                    (Order*) select_lex->order_list.first,
2045
 
                    (Order*) select_lex->group_list.first,
 
2033
                    (order_st*) select_lex->order_list.first,
 
2034
                    (order_st*) select_lex->group_list.first,
2046
2035
                    select_lex->having,
2047
2036
                    select_lex, select_lex->master_unit()))
2048
2037
    return 1;
2142
2131
  assert(0);
2143
2132
}
2144
2133
 
 
2134
int  init_read_record_seq(JoinTable *tab);
 
2135
int join_read_always_key_or_null(JoinTable *tab);
 
2136
int join_read_next_same_or_null(ReadRecord *info);
 
2137
 
2145
2138
int subselect_single_select_engine::exec()
2146
2139
{
2147
 
  char const *save_where= session->where();
 
2140
  char const *save_where= session->where;
2148
2141
  Select_Lex *save_select= session->lex->current_select;
2149
2142
  session->lex->current_select= select_lex;
2150
2143
  if (!join->optimized)
2154
2147
    unit->set_limit(unit->global_parameters);
2155
2148
    if (join->optimize())
2156
2149
    {
2157
 
      session->setWhere(save_where);
 
2150
      session->where= save_where;
2158
2151
      executed= 1;
2159
2152
      session->lex->current_select= save_select;
2160
2153
      return(join->error ? join->error : 1);
2161
2154
    }
2162
 
    if (save_join_if_explain())
2163
 
     return(1);
2164
 
 
 
2155
    if (!select_lex->uncacheable && session->lex->describe &&
 
2156
        !(join->select_options & SELECT_DESCRIBE) &&
 
2157
        join->need_tmp && item->const_item())
 
2158
    {
 
2159
      /*
 
2160
        Force join->join_tmp creation, because this subquery will be replaced
 
2161
        by a simple select from the materialization temp table by optimize()
 
2162
        called by EXPLAIN and we need to preserve the initial query structure
 
2163
        so we can display it.
 
2164
       */
 
2165
      select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
 
2166
      select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
 
2167
      if (join->init_save_join_tab())
 
2168
        return(1);
 
2169
    }
2165
2170
    if (item->engine_changed)
2166
2171
    {
2167
2172
      return(1);
2168
2173
    }
2169
2174
  }
2170
 
  if (select_lex->uncacheable.any() &&
2171
 
      ! select_lex->uncacheable.test(UNCACHEABLE_EXPLAIN) &&
2172
 
      executed)
 
2175
  if (select_lex->uncacheable &&
 
2176
      select_lex->uncacheable != UNCACHEABLE_EXPLAIN
 
2177
      && executed)
2173
2178
  {
2174
2179
    if (join->reinit())
2175
2180
    {
2176
 
      session->setWhere(save_where);
 
2181
      session->where= save_where;
2177
2182
      session->lex->current_select= save_select;
2178
 
      return 1;
 
2183
      return(1);
2179
2184
    }
2180
2185
    item->reset();
2181
2186
    item->assigned((executed= 0));
2232
2237
      tab->read_record.read_record= tab->save_read_record;
2233
2238
    }
2234
2239
    executed= 1;
2235
 
    session->setWhere(save_where);
 
2240
    session->where= save_where;
2236
2241
    session->lex->current_select= save_select;
2237
2242
    return(join->error||session->is_fatal_error);
2238
2243
  }
2239
 
  session->setWhere(save_where);
 
2244
  session->where= save_where;
2240
2245
  session->lex->current_select= save_select;
2241
2246
  return(0);
2242
2247
}
2243
2248
 
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
2249
int subselect_union_engine::exec()
2283
2250
{
2284
 
  char const *save_where= session->where();
 
2251
  char const *save_where= session->where;
2285
2252
  int res= unit->exec();
2286
 
  session->setWhere(save_where);
2287
 
 
 
2253
  session->where= save_where;
2288
2254
  return res;
2289
2255
}
2290
2256
 
2315
2281
  if (table->cursor->inited)
2316
2282
    table->cursor->endIndexScan();
2317
2283
 
2318
 
  if ((error= table->cursor->startTableScan(1)))
2319
 
  {
2320
 
    table->print_error(error, MYF(0));
2321
 
    return 1;
2322
 
  }
2323
 
 
2324
 
  assert(table->getSession());
 
2284
  table->cursor->startTableScan(1);
2325
2285
  table->cursor->extra_opt(HA_EXTRA_CACHE,
2326
 
                           table->getSession()->variables.read_buff_size);
 
2286
                           current_session->variables.read_buff_size);
2327
2287
  table->null_row= 0;
2328
2288
  for (;;)
2329
2289
  {
2498
2458
    return(scan_table());
2499
2459
 
2500
2460
  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
 
 
 
2461
    table->cursor->startIndexScan(tab->ref.key, 0);
2511
2462
  error= table->cursor->index_read_map(table->record[0],
2512
2463
                                     tab->ref.key_buff,
2513
2464
                                     make_prev_keypart_map(tab->ref.key_parts),
2620
2571
    return(scan_table());
2621
2572
 
2622
2573
  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
 
  }
 
2574
    table->cursor->startIndexScan(tab->ref.key, 1);
2632
2575
  error= table->cursor->index_read_map(table->record[0],
2633
2576
                                     tab->ref.key_buff,
2634
2577
                                     make_prev_keypart_map(tab->ref.key_parts),
2690
2633
}
2691
2634
 
2692
2635
 
2693
 
bool subselect_single_select_engine::uncacheable()
2694
 
{
2695
 
  return select_lex->uncacheable.any();
2696
 
}
2697
 
 
2698
 
 
2699
 
bool subselect_single_select_engine::uncacheable(uint32_t bit_pos)
2700
 
{
2701
 
  return select_lex->uncacheable.test(bit_pos);
2702
 
}
2703
 
 
2704
 
 
2705
 
bool subselect_union_engine::uncacheable()
2706
 
{
2707
 
  return unit->uncacheable.any();
2708
 
}
2709
 
 
2710
 
 
2711
 
bool subselect_union_engine::uncacheable(uint32_t bit_pos)
2712
 
{
2713
 
  return unit->uncacheable.test(bit_pos);
 
2636
uint8_t subselect_single_select_engine::uncacheable()
 
2637
{
 
2638
  return select_lex->uncacheable;
 
2639
}
 
2640
 
 
2641
 
 
2642
uint8_t subselect_union_engine::uncacheable()
 
2643
{
 
2644
  return unit->uncacheable;
2714
2645
}
2715
2646
 
2716
2647
 
3068
2999
    - here we initialize only those members that are used by
3069
3000
      subselect_uniquesubquery_engine, so these objects are incomplete.
3070
3001
  */
3071
 
  if (!(tab= (JoinTable*) session->getMemRoot()->allocate(sizeof(JoinTable))))
 
3002
  if (!(tab= (JoinTable*) session->alloc(sizeof(JoinTable))))
3072
3003
    return(true);
3073
 
  new (tab) JoinTable();
3074
3004
  tab->table= tmp_table;
3075
3005
  tab->ref.key= 0; /* The only temp table index. */
3076
3006
  tab->ref.key_length= tmp_key->key_length;
3077
3007
  if (!(tab->ref.key_buff=
3078
3008
        (unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3079
3009
      !(tab->ref.key_copy=
3080
 
        (StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
 
3010
        (StoredKey**) session->alloc((sizeof(StoredKey*) *
3081
3011
                                  (tmp_key_parts + 1)))) ||
3082
3012
      !(tab->ref.items=
3083
 
        (Item**) session->getMemRoot()->allocate(sizeof(Item*) * tmp_key_parts)))
 
3013
        (Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
3084
3014
    return(true);
3085
3015
 
3086
3016
  KeyPartInfo *cur_key_part= tmp_key->key_part;
3185
3115
    session->lex->current_select= materialize_engine->select_lex;
3186
3116
    if ((res= materialize_join->optimize()))
3187
3117
      goto err;
3188
 
 
3189
 
    if (materialize_engine->save_join_if_explain())
3190
 
      goto err;
3191
 
 
3192
3118
    materialize_join->exec();
3193
3119
    if ((res= test(materialize_join->error || session->is_fatal_error)))
3194
3120
      goto err;