~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/subselect.cc

  • Committer: Padraig O'Sullivan
  • Date: 2009-09-13 01:03:01 UTC
  • mto: (1126.9.2 captain-20090915-01)
  • mto: This revision was merged to the branch mainline in revision 1133.
  • Revision ID: osullivan.padraig@gmail.com-20090913010301-tcvvezipx1124acy
Added calls to the dtrace delete begin/end probes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
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
 
#include "config.h"
27
 
 
28
 
#include <limits.h>
29
 
 
 
26
#include <drizzled/server_includes.h>
30
27
#include <drizzled/sql_select.h>
31
28
#include <drizzled/error.h>
32
29
#include <drizzled/item/cache.h>
37
34
#include <drizzled/check_stack_overrun.h>
38
35
#include <drizzled/item/ref_null_helper.h>
39
36
#include <drizzled/item/direct_ref.h>
40
 
#include <drizzled/join.h>
41
 
 
42
 
namespace drizzled
43
 
{
44
 
 
45
 
extern plugin::StorageEngine *myisam_engine;
46
37
 
47
38
inline Item * and_items(Item* cond, Item *item)
48
39
{
49
40
  return (cond? (new Item_cond_and(cond, item)) : item);
50
41
}
51
42
 
52
 
Item_subselect::Item_subselect() :
53
 
  Item_result_field(),
54
 
  value_assigned(false),
55
 
  session(NULL),
56
 
  substitution(NULL),
57
 
  unit(NULL),
58
 
  engine(NULL),
59
 
  old_engine(NULL),
60
 
  used_tables_cache(0),
61
 
  max_columns(0),
62
 
  parsing_place(NO_MATTER),
63
 
  have_to_be_excluded(false),
64
 
  const_item_cache(true),
65
 
  engine_changed(false),
66
 
  changed(false),
 
43
Item_subselect::Item_subselect():
 
44
  Item_result_field(), value_assigned(0), session(0), substitution(0),
 
45
  engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
 
46
  const_item_cache(1), engine_changed(0), changed(0),
67
47
  is_correlated(false)
68
48
{
69
49
  with_subselect= 1;
524
504
    if (session->lex->describe)
525
505
    {
526
506
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
527
 
      snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
 
507
      sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
528
508
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
529
509
                   ER_SELECT_REDUCED, warn_buff);
530
510
    }
568
548
  }
569
549
  else
570
550
  {
571
 
    if (!(row= (Item_cache**) memory::sql_alloc(sizeof(Item_cache*)*max_columns)))
 
551
    if (!(row= (Item_cache**) sql_alloc(sizeof(Item_cache*)*max_columns)))
572
552
      return;
573
553
    engine->fix_length_and_dec(row);
574
554
    value= *row;
724
704
}
725
705
 
726
706
Item_in_subselect::Item_in_subselect(Item * left_exp,
727
 
                                     Select_Lex *select_lex) :
728
 
  Item_exists_subselect(),
729
 
  left_expr(left_exp),
730
 
  left_expr_cache(NULL),
731
 
  first_execution(true),
732
 
  optimizer(NULL),
733
 
  pushed_cond_guards(NULL),
734
 
  sj_convert_priority(0),
735
 
  expr_join_nest(NULL),
736
 
  exec_method(NOT_TRANSFORMED),
737
 
  upper_item(NULL)
 
707
                                     Select_Lex *select_lex):
 
708
  Item_exists_subselect(), left_expr_cache(0), first_execution(true),
 
709
  optimizer(0), pushed_cond_guards(NULL), exec_method(NOT_TRANSFORMED),
 
710
  upper_item(0)
738
711
{
 
712
  left_expr= left_exp;
739
713
  init(select_lex, new select_exists_subselect(this));
740
714
  max_columns= UINT_MAX;
741
715
  maybe_null= 1;
1320
1294
        if (session->lex->describe)
1321
1295
        {
1322
1296
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
1323
 
          snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
 
1297
          sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
1324
1298
          push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1325
1299
                       ER_SELECT_REDUCED, warn_buff);
1326
1300
        }
1647
1621
  {
1648
1622
    /*
1649
1623
      IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
1650
 
      ORDER BY clause becomes meaningless thus we drop it here.
 
1624
      order_st BY clause becomes meaningless thus we drop it here.
1651
1625
    */
1652
1626
    Select_Lex *sl= current->master_unit()->first_select();
1653
1627
    for (; sl; sl= sl->next_select())
1840
1814
 
1841
1815
bool Item_in_subselect::init_left_expr_cache()
1842
1816
{
1843
 
  JOIN *outer_join= NULL;
 
1817
  JOIN *outer_join;
 
1818
  Next_select_func end_select;
 
1819
  bool use_result_field= false;
1844
1820
 
1845
1821
  outer_join= unit->outer_select()->join;
1846
 
  if (! outer_join || ! outer_join->tables || ! outer_join->join_tab)
 
1822
  if (!outer_join || !outer_join->tables)
1847
1823
    return true;
 
1824
  /*
 
1825
    If we use end_[send | write]_group to handle complete rows of the outer
 
1826
    query, make the cache of the left IN operand use Item_field::result_field
 
1827
    instead of Item_field::field.  We need this because normally
 
1828
    Cached_item_field uses Item::field to fetch field data, while
 
1829
    copy_ref_key() that copies the left IN operand into a lookup key uses
 
1830
    Item::result_field. In the case end_[send | write]_group result_field is
 
1831
    one row behind field.
 
1832
  */
 
1833
  end_select= outer_join->join_tab[outer_join->tables-1].next_select;
 
1834
  if (end_select == end_send_group || end_select == end_write_group)
 
1835
    use_result_field= true;
1848
1836
 
1849
1837
  if (!(left_expr_cache= new List<Cached_item>))
1850
1838
    return true;
1851
1839
 
1852
1840
  for (uint32_t i= 0; i < left_expr->cols(); i++)
1853
1841
  {
1854
 
    Cached_item *cur_item_cache= new_Cached_item(session, left_expr->element_index(i));
 
1842
    Cached_item *cur_item_cache= new_Cached_item(session,
 
1843
                                                 left_expr->element_index(i),
 
1844
                                                 use_result_field);
1855
1845
    if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
1856
1846
      return true;
1857
1847
  }
1970
1960
void subselect_uniquesubquery_engine::cleanup()
1971
1961
{
1972
1962
  /* Tell handler we don't need the index anymore */
1973
 
  if (tab->table->cursor->inited)
1974
 
    tab->table->cursor->ha_index_end();
 
1963
  if (tab->table->file->inited)
 
1964
    tab->table->file->ha_index_end();
1975
1965
  return;
1976
1966
}
1977
1967
 
2164
2154
      select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
2165
2155
      select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
2166
2156
      if (join->init_save_join_tab())
2167
 
        return(1);
 
2157
        return(1);                        /* purecov: inspected */
2168
2158
    }
2169
2159
    if (item->engine_changed)
2170
2160
    {
2215
2205
              tab->read_first_record= init_read_record_seq;
2216
2206
              tab->read_record.record= tab->table->record[0];
2217
2207
              tab->read_record.session= join->session;
2218
 
              tab->read_record.ref_length= tab->table->cursor->ref_length;
 
2208
              tab->read_record.ref_length= tab->table->file->ref_length;
2219
2209
              *(last_changed_tab++)= tab;
2220
2210
              break;
2221
2211
            }
2277
2267
  int error;
2278
2268
  Table *table= tab->table;
2279
2269
 
2280
 
  if (table->cursor->inited)
2281
 
    table->cursor->ha_index_end();
 
2270
  if (table->file->inited)
 
2271
    table->file->ha_index_end();
2282
2272
 
2283
 
  table->cursor->ha_rnd_init(1);
2284
 
  table->cursor->extra_opt(HA_EXTRA_CACHE,
 
2273
  table->file->ha_rnd_init(1);
 
2274
  table->file->extra_opt(HA_EXTRA_CACHE,
2285
2275
                         current_session->variables.read_buff_size);
2286
2276
  table->null_row= 0;
2287
2277
  for (;;)
2288
2278
  {
2289
 
    error=table->cursor->rnd_next(table->record[0]);
 
2279
    error=table->file->rnd_next(table->record[0]);
2290
2280
    if (error && error != HA_ERR_END_OF_FILE)
2291
2281
    {
2292
2282
      error= table->report_error(error);
2303
2293
    }
2304
2294
  }
2305
2295
 
2306
 
  table->cursor->ha_rnd_end();
 
2296
  table->file->ha_rnd_end();
2307
2297
  return(error != 0);
2308
2298
}
2309
2299
 
2354
2344
{
2355
2345
  for (StoredKey **copy= tab->ref.key_copy ; *copy ; copy++)
2356
2346
  {
2357
 
    StoredKey::store_key_result store_res= (*copy)->copy();
 
2347
    enum StoredKey::store_key_result store_res;
 
2348
    store_res= (*copy)->copy();
2358
2349
    tab->ref.key_err= store_res;
2359
2350
 
2360
2351
    /*
2456
2447
  if (null_keypart)
2457
2448
    return(scan_table());
2458
2449
 
2459
 
  if (!table->cursor->inited)
2460
 
    table->cursor->ha_index_init(tab->ref.key, 0);
2461
 
  error= table->cursor->index_read_map(table->record[0],
 
2450
  if (!table->file->inited)
 
2451
    table->file->ha_index_init(tab->ref.key, 0);
 
2452
  error= table->file->index_read_map(table->record[0],
2462
2453
                                     tab->ref.key_buff,
2463
2454
                                     make_prev_keypart_map(tab->ref.key_parts),
2464
2455
                                     HA_READ_KEY_EXACT);
2569
2560
  if (null_keypart)
2570
2561
    return(scan_table());
2571
2562
 
2572
 
  if (!table->cursor->inited)
2573
 
    table->cursor->ha_index_init(tab->ref.key, 1);
2574
 
  error= table->cursor->index_read_map(table->record[0],
 
2563
  if (!table->file->inited)
 
2564
    table->file->ha_index_init(tab->ref.key, 1);
 
2565
  error= table->file->index_read_map(table->record[0],
2575
2566
                                     tab->ref.key_buff,
2576
2567
                                     make_prev_keypart_map(tab->ref.key_parts),
2577
2568
                                     HA_READ_KEY_EXACT);
2595
2586
            ((Item_in_subselect *) item)->value= 1;
2596
2587
          break;
2597
2588
        }
2598
 
        error= table->cursor->index_next_same(table->record[0],
 
2589
        error= table->file->index_next_same(table->record[0],
2599
2590
                                            tab->ref.key_buff,
2600
2591
                                            tab->ref.key_length);
2601
2592
        if (error && error != HA_ERR_END_OF_FILE)
2953
2944
  if (tmp_result_sink->create_result_table(
2954
2945
                         session, tmp_columns, true,
2955
2946
                         session->options | TMP_TABLE_ALL_COLUMNS,
2956
 
                         "materialized subselect"))
 
2947
                         "materialized subselect", true))
2957
2948
    return(true);
2958
2949
 
2959
2950
  tmp_table= tmp_result_sink->table;
2972
2963
    assert(tmp_table->s->db_type() == myisam_engine);
2973
2964
    assert(
2974
2965
      tmp_table->s->uniques ||
2975
 
      tmp_table->key_info->key_length >= tmp_table->cursor->getEngine()->max_key_length() ||
2976
 
      tmp_table->key_info->key_parts > tmp_table->cursor->getEngine()->max_key_parts());
 
2966
      tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
 
2967
      tmp_table->key_info->key_parts > tmp_table->file->max_key_parts());
2977
2968
    tmp_table->free_tmp_table(session);
2978
2969
    delete result;
2979
2970
    result= NULL;
3131
3122
      statistics, then we test if the temporary table for the query result is
3132
3123
      empty.
3133
3124
    */
3134
 
    tab->table->cursor->info(HA_STATUS_VARIABLE);
3135
 
    if (!tab->table->cursor->stats.records)
 
3125
    tab->table->file->info(HA_STATUS_VARIABLE);
 
3126
    if (!tab->table->file->stats.records)
3136
3127
    {
3137
3128
      empty_result_set= true;
3138
3129
      item_in->value= false;
3173
3164
           "<the access method for lookups is not yet created>"
3174
3165
         ));
3175
3166
}
3176
 
 
3177
 
} /* namespace drizzled */