~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/subselect.cc

  • Committer: Brian Aker
  • Date: 2009-05-23 17:13:03 UTC
  • mfrom: (1034.1.8 merge)
  • Revision ID: brian@gaz-20090523171303-d28xhutqic0xe2b4
Merge Brian

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
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 <cstdio>
29
 
#include <limits.h>
30
 
 
 
26
#include <drizzled/server_includes.h>
31
27
#include <drizzled/sql_select.h>
32
28
#include <drizzled/error.h>
33
29
#include <drizzled/item/cache.h>
38
34
#include <drizzled/check_stack_overrun.h>
39
35
#include <drizzled/item/ref_null_helper.h>
40
36
#include <drizzled/item/direct_ref.h>
41
 
#include <drizzled/join.h>
42
 
 
43
 
namespace drizzled
44
 
{
45
 
 
46
 
extern plugin::StorageEngine *myisam_engine;
47
37
 
48
38
inline Item * and_items(Item* cond, Item *item)
49
39
{
50
40
  return (cond? (new Item_cond_and(cond, item)) : item);
51
41
}
52
42
 
53
 
Item_subselect::Item_subselect() :
54
 
  Item_result_field(),
55
 
  value_assigned(false),
56
 
  session(NULL),
57
 
  substitution(NULL),
58
 
  unit(NULL),
59
 
  engine(NULL),
60
 
  old_engine(NULL),
61
 
  used_tables_cache(0),
62
 
  max_columns(0),
63
 
  parsing_place(NO_MATTER),
64
 
  have_to_be_excluded(false),
65
 
  const_item_cache(true),
66
 
  engine_changed(false),
67
 
  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),
68
47
  is_correlated(false)
69
48
{
70
49
  with_subselect= 1;
90
69
  if (unit->item)
91
70
  {
92
71
    /*
93
 
      Item can be changed in JOIN::prepare while engine in Join::optimize
 
72
      Item can be changed in JOIN::prepare while engine in JOIN::optimize
94
73
      => we do not copy old_engine here
95
74
    */
96
75
    engine= unit->item->engine;
172
151
}
173
152
 
174
153
Item_subselect::trans_res
175
 
Item_subselect::select_transformer(Join *)
 
154
Item_subselect::select_transformer(JOIN *)
176
155
{
177
156
  return(RES_OK);
178
157
}
181
160
bool Item_subselect::fix_fields(Session *session_param, Item **ref)
182
161
{
183
162
  char const *save_where= session_param->where;
 
163
  uint8_t uncacheable;
184
164
  bool res;
185
165
 
186
166
  assert(fixed == 0);
208
188
 
209
189
      // did we changed top item of WHERE condition
210
190
      if (unit->outer_select()->where == (*ref))
211
 
      {
212
 
        unit->outer_select()->where= substitution; // correct WHERE for PS
213
 
      }
 
191
        unit->outer_select()->where= substitution; // correct WHERE for PS
214
192
      else if (unit->outer_select()->having == (*ref))
215
 
      {
216
 
        unit->outer_select()->having= substitution; // correct HAVING for PS
217
 
      }
 
193
        unit->outer_select()->having= substitution; // correct HAVING for PS
218
194
 
219
195
      (*ref)= substitution;
220
196
      substitution->name= name;
221
197
      if (have_to_be_excluded)
222
 
      {
223
 
        engine->exclude();
224
 
      }
 
198
        engine->exclude();
225
199
      substitution= 0;
226
200
      session->where= "checking transformed subquery";
227
 
      if (! (*ref)->fixed)
228
 
      {
229
 
        ret= (*ref)->fix_fields(session, ref);
230
 
      }
 
201
      if (!(*ref)->fixed)
 
202
        ret= (*ref)->fix_fields(session, ref);
231
203
      session->where= save_where;
232
204
      return ret;
233
205
    }
242
214
  else
243
215
    goto err;
244
216
 
245
 
  if (engine->uncacheable())
 
217
  if ((uncacheable= engine->uncacheable()))
246
218
  {
247
219
    const_item_cache= 0;
248
 
    if (engine->uncacheable(UNCACHEABLE_RAND))
249
 
    {
 
220
    if (uncacheable & UNCACHEABLE_RAND)
250
221
      used_tables_cache|= RAND_TABLE_BIT;
251
 
    }
252
222
  }
253
223
  fixed= 1;
254
224
 
268
238
    {
269
239
      List_iterator<Item> li(lex->item_list);
270
240
      Item *item;
271
 
      Order *order;
 
241
      order_st *order;
272
242
 
273
243
      if (lex->where && (lex->where)->walk(processor, walk_subquery, argument))
274
244
        return 1;
281
251
        if (item->walk(processor, walk_subquery, argument))
282
252
          return 1;
283
253
      }
284
 
      for (order= (Order*) lex->order_list.first ; order; order= order->next)
 
254
      for (order= (order_st*) lex->order_list.first ; order; order= order->next)
285
255
      {
286
256
        if ((*order->item)->walk(processor, walk_subquery, argument))
287
257
          return 1;
288
258
      }
289
 
      for (order= (Order*) lex->group_list.first ; order; order= order->next)
 
259
      for (order= (order_st*) lex->group_list.first ; order; order= order->next)
290
260
      {
291
261
        if ((*order->item)->walk(processor, walk_subquery, argument))
292
262
          return 1;
390
360
 
391
361
void Item_subselect::update_used_tables()
392
362
{
393
 
  if (! engine->uncacheable())
 
363
  if (!engine->uncacheable())
394
364
  {
395
365
    // did all used tables become static?
396
366
    if (!(used_tables_cache & ~engine->upper_select_const_tables()))
506
476
  Make rollback for it, or special name resolving mode in 5.0.
507
477
*/
508
478
Item_subselect::trans_res
509
 
Item_singlerow_subselect::select_transformer(Join *join)
 
479
Item_singlerow_subselect::select_transformer(JOIN *join)
510
480
{
511
481
  if (changed)
512
482
    return(RES_OK);
534
504
    if (session->lex->describe)
535
505
    {
536
506
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
537
 
      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);
538
508
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
539
509
                   ER_SELECT_REDUCED, warn_buff);
540
510
    }
578
548
  }
579
549
  else
580
550
  {
581
 
    if (!(row= (Item_cache**) memory::sql_alloc(sizeof(Item_cache*)*max_columns)))
 
551
    if (!(row= (Item_cache**) sql_alloc(sizeof(Item_cache*)*max_columns)))
582
552
      return;
583
553
    engine->fix_length_and_dec(row);
584
554
    value= *row;
734
704
}
735
705
 
736
706
Item_in_subselect::Item_in_subselect(Item * left_exp,
737
 
                                     Select_Lex *select_lex) :
738
 
  Item_exists_subselect(),
739
 
  left_expr(left_exp),
740
 
  left_expr_cache(NULL),
741
 
  first_execution(true),
742
 
  optimizer(NULL),
743
 
  pushed_cond_guards(NULL),
744
 
  sj_convert_priority(0),
745
 
  expr_join_nest(NULL),
746
 
  exec_method(NOT_TRANSFORMED),
747
 
  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)
748
711
{
 
712
  left_expr= left_exp;
749
713
  init(select_lex, new select_exists_subselect(this));
750
714
  max_columns= UINT_MAX;
751
715
  maybe_null= 1;
986
950
*/
987
951
 
988
952
Item_subselect::trans_res
989
 
Item_in_subselect::single_value_transformer(Join *join,
 
953
Item_in_subselect::single_value_transformer(JOIN *join,
990
954
                                            const Comp_creator *func)
991
955
{
992
956
  Select_Lex *select_lex= join->select_lex;
1013
977
    later in this method.
1014
978
  */
1015
979
  if ((abort_on_null || (upper_item && upper_item->top_level())) &&
1016
 
      select_lex->master_unit()->uncacheable.none() && !func->eqne_op())
 
980
      !select_lex->master_unit()->uncacheable && !func->eqne_op())
1017
981
  {
1018
982
    if (substitution)
1019
983
    {
1109
1073
                              (char *)"<no matter>",
1110
1074
                              (char *)in_left_expr_name);
1111
1075
 
1112
 
    master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1076
    master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1113
1077
  }
1114
1078
 
1115
1079
  if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1168
1132
*/
1169
1133
 
1170
1134
Item_subselect::trans_res
1171
 
Item_in_subselect::single_value_in_to_exists_transformer(Join * join, const Comp_creator *func)
 
1135
Item_in_subselect::single_value_in_to_exists_transformer(JOIN * join, const Comp_creator *func)
1172
1136
{
1173
1137
  Select_Lex *select_lex= join->select_lex;
1174
1138
 
1175
 
  select_lex->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1139
  select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1176
1140
  if (join->having || select_lex->with_sum_func ||
1177
1141
      select_lex->group_list.elements)
1178
1142
  {
1330
1294
        if (session->lex->describe)
1331
1295
        {
1332
1296
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
1333
 
          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);
1334
1298
          push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1335
1299
                       ER_SELECT_REDUCED, warn_buff);
1336
1300
        }
1344
1308
 
1345
1309
 
1346
1310
Item_subselect::trans_res
1347
 
Item_in_subselect::row_value_transformer(Join *join)
 
1311
Item_in_subselect::row_value_transformer(JOIN *join)
1348
1312
{
1349
1313
  Select_Lex *select_lex= join->select_lex;
1350
1314
  uint32_t cols_num= left_expr->cols();
1378
1342
    optimizer->keep_top_level_cache();
1379
1343
 
1380
1344
    session->lex->current_select= current;
1381
 
    master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1345
    master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1382
1346
 
1383
1347
    if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1384
1348
    {
1421
1385
*/
1422
1386
 
1423
1387
Item_subselect::trans_res
1424
 
Item_in_subselect::row_value_in_to_exists_transformer(Join * join)
 
1388
Item_in_subselect::row_value_in_to_exists_transformer(JOIN * join)
1425
1389
{
1426
1390
  Select_Lex *select_lex= join->select_lex;
1427
1391
  Item *having_item= 0;
1430
1394
                        select_lex->group_list.first ||
1431
1395
                        !select_lex->table_list.elements);
1432
1396
 
1433
 
  select_lex->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1397
  select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1434
1398
  if (is_having_used)
1435
1399
  {
1436
1400
    /*
1619
1583
 
1620
1584
 
1621
1585
Item_subselect::trans_res
1622
 
Item_in_subselect::select_transformer(Join *join)
 
1586
Item_in_subselect::select_transformer(JOIN *join)
1623
1587
{
1624
1588
  return select_in_like_transformer(join, Eq_creator::instance());
1625
1589
}
1647
1611
*/
1648
1612
 
1649
1613
Item_subselect::trans_res
1650
 
Item_in_subselect::select_in_like_transformer(Join *join, const Comp_creator *func)
 
1614
Item_in_subselect::select_in_like_transformer(JOIN *join, const Comp_creator *func)
1651
1615
{
1652
1616
  Select_Lex *current= session->lex->current_select, *up;
1653
1617
  const char *save_where= session->where;
1657
1621
  {
1658
1622
    /*
1659
1623
      IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
1660
 
      ORDER BY clause becomes meaningless thus we drop it here.
 
1624
      order_st BY clause becomes meaningless thus we drop it here.
1661
1625
    */
1662
1626
    Select_Lex *sl= current->master_unit()->first_select();
1663
1627
    for (; sl; sl= sl->next_select())
1850
1814
 
1851
1815
bool Item_in_subselect::init_left_expr_cache()
1852
1816
{
1853
 
  Join *outer_join= NULL;
 
1817
  JOIN *outer_join;
 
1818
  Next_select_func end_select;
 
1819
  bool use_result_field= false;
1854
1820
 
1855
1821
  outer_join= unit->outer_select()->join;
1856
 
  if (! outer_join || ! outer_join->tables || ! outer_join->join_tab)
 
1822
  if (!outer_join || !outer_join->tables)
1857
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;
1858
1836
 
1859
1837
  if (!(left_expr_cache= new List<Cached_item>))
1860
1838
    return true;
1861
1839
 
1862
1840
  for (uint32_t i= 0; i < left_expr->cols(); i++)
1863
1841
  {
1864
 
    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);
1865
1845
    if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
1866
1846
      return true;
1867
1847
  }
1889
1869
 
1890
1870
 
1891
1871
Item_subselect::trans_res
1892
 
Item_allany_subselect::select_transformer(Join *join)
 
1872
Item_allany_subselect::select_transformer(JOIN *join)
1893
1873
{
1894
1874
  exec_method= IN_TO_EXISTS;
1895
1875
  if (upper_item)
1980
1960
void subselect_uniquesubquery_engine::cleanup()
1981
1961
{
1982
1962
  /* Tell handler we don't need the index anymore */
1983
 
  if (tab->table->cursor->inited)
1984
 
    tab->table->cursor->endIndexScan();
 
1963
  if (tab->table->file->inited)
 
1964
    tab->table->file->ha_index_end();
1985
1965
  return;
1986
1966
}
1987
1967
 
2026
2006
{
2027
2007
  if (prepared)
2028
2008
    return 0;
2029
 
  join= new Join(session, select_lex->item_list,
 
2009
  join= new JOIN(session, select_lex->item_list,
2030
2010
                 select_lex->options | SELECT_NO_UNLOCK, result);
2031
2011
  if (!join || !result)
2032
2012
    return 1; /* Fatal error is set already. */
2039
2019
                    select_lex->where,
2040
2020
                    select_lex->order_list.elements +
2041
2021
                    select_lex->group_list.elements,
2042
 
                    (Order*) select_lex->order_list.first,
2043
 
                    (Order*) select_lex->group_list.first,
 
2022
                    (order_st*) select_lex->order_list.first,
 
2023
                    (order_st*) select_lex->group_list.first,
2044
2024
                    select_lex->having,
2045
2025
                    select_lex, select_lex->master_unit()))
2046
2026
    return 1;
2140
2120
  assert(0);
2141
2121
}
2142
2122
 
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);
 
2123
int  init_read_record_seq(JOIN_TAB *tab);
 
2124
int join_read_always_key_or_null(JOIN_TAB *tab);
 
2125
int join_read_next_same_or_null(READ_RECORD *info);
2146
2126
 
2147
2127
int subselect_single_select_engine::exec()
2148
2128
{
2154
2134
    Select_Lex_Unit *unit= select_lex->master_unit();
2155
2135
 
2156
2136
    unit->set_limit(unit->global_parameters);
 
2137
    if (join->flatten_subqueries())
 
2138
    {
 
2139
      session->is_fatal_error= true;
 
2140
      return(1);
 
2141
    }
2157
2142
    if (join->optimize())
2158
2143
    {
2159
2144
      session->where= save_where;
2161
2146
      session->lex->current_select= save_select;
2162
2147
      return(join->error ? join->error : 1);
2163
2148
    }
2164
 
    if (select_lex->uncacheable.none() && session->lex->describe &&
 
2149
    if (!select_lex->uncacheable && session->lex->describe &&
2165
2150
        !(join->select_options & SELECT_DESCRIBE) &&
2166
2151
        join->need_tmp && item->const_item())
2167
2152
    {
2171
2156
        called by EXPLAIN and we need to preserve the initial query structure
2172
2157
        so we can display it.
2173
2158
       */
2174
 
      select_lex->uncacheable.set(UNCACHEABLE_EXPLAIN);
2175
 
      select_lex->master_unit()->uncacheable.set(UNCACHEABLE_EXPLAIN);
 
2159
      select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
 
2160
      select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
2176
2161
      if (join->init_save_join_tab())
2177
 
        return(1);
 
2162
        return(1);                        /* purecov: inspected */
2178
2163
    }
2179
2164
    if (item->engine_changed)
2180
2165
    {
2181
2166
      return(1);
2182
2167
    }
2183
2168
  }
2184
 
  if (select_lex->uncacheable.any() &&
2185
 
      ! select_lex->uncacheable.test(UNCACHEABLE_EXPLAIN) &&
2186
 
      executed)
 
2169
  if (select_lex->uncacheable &&
 
2170
      select_lex->uncacheable != UNCACHEABLE_EXPLAIN
 
2171
      && executed)
2187
2172
  {
2188
2173
    if (join->reinit())
2189
2174
    {
2190
2175
      session->where= save_where;
2191
2176
      session->lex->current_select= save_select;
2192
 
      return 1;
 
2177
      return(1);
2193
2178
    }
2194
2179
    item->reset();
2195
2180
    item->assigned((executed= 0));
2197
2182
  if (!executed)
2198
2183
  {
2199
2184
    item->reset_value_registration();
2200
 
    JoinTable *changed_tabs[MAX_TABLES];
2201
 
    JoinTable **last_changed_tab= changed_tabs;
 
2185
    JOIN_TAB *changed_tabs[MAX_TABLES];
 
2186
    JOIN_TAB **last_changed_tab= changed_tabs;
2202
2187
    if (item->have_guarded_conds())
2203
2188
    {
2204
2189
      /*
2209
2194
      */
2210
2195
      for (uint32_t i=join->const_tables ; i < join->tables ; i++)
2211
2196
      {
2212
 
        JoinTable *tab=join->join_tab+i;
 
2197
        JOIN_TAB *tab=join->join_tab+i;
2213
2198
        if (tab && tab->keyuse)
2214
2199
        {
2215
2200
          for (uint32_t key_part= 0;
2225
2210
              tab->read_first_record= init_read_record_seq;
2226
2211
              tab->read_record.record= tab->table->record[0];
2227
2212
              tab->read_record.session= join->session;
2228
 
              tab->read_record.ref_length= tab->table->cursor->ref_length;
 
2213
              tab->read_record.ref_length= tab->table->file->ref_length;
2229
2214
              *(last_changed_tab++)= tab;
2230
2215
              break;
2231
2216
            }
2237
2222
    join->exec();
2238
2223
 
2239
2224
    /* Enable the optimizations back */
2240
 
    for (JoinTable **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
 
2225
    for (JOIN_TAB **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
2241
2226
    {
2242
 
      JoinTable *tab= *ptab;
 
2227
      JOIN_TAB *tab= *ptab;
2243
2228
      tab->read_record.record= 0;
2244
2229
      tab->read_record.ref_length= 0;
2245
2230
      tab->read_first_record= tab->save_read_first_record;
2287
2272
  int error;
2288
2273
  Table *table= tab->table;
2289
2274
 
2290
 
  if (table->cursor->inited)
2291
 
    table->cursor->endIndexScan();
 
2275
  if (table->file->inited)
 
2276
    table->file->ha_index_end();
2292
2277
 
2293
 
  table->cursor->startTableScan(1);
2294
 
  table->cursor->extra_opt(HA_EXTRA_CACHE,
2295
 
                           current_session->variables.read_buff_size);
 
2278
  table->file->ha_rnd_init(1);
 
2279
  table->file->extra_opt(HA_EXTRA_CACHE,
 
2280
                         current_session->variables.read_buff_size);
2296
2281
  table->null_row= 0;
2297
2282
  for (;;)
2298
2283
  {
2299
 
    error=table->cursor->rnd_next(table->record[0]);
 
2284
    error=table->file->rnd_next(table->record[0]);
2300
2285
    if (error && error != HA_ERR_END_OF_FILE)
2301
2286
    {
2302
2287
      error= table->report_error(error);
2313
2298
    }
2314
2299
  }
2315
2300
 
2316
 
  table->cursor->endTableScan();
 
2301
  table->file->ha_rnd_end();
2317
2302
  return(error != 0);
2318
2303
}
2319
2304
 
2362
2347
 
2363
2348
bool subselect_uniquesubquery_engine::copy_ref_key()
2364
2349
{
2365
 
  for (StoredKey **copy= tab->ref.key_copy ; *copy ; copy++)
 
2350
  for (store_key **copy= tab->ref.key_copy ; *copy ; copy++)
2366
2351
  {
2367
 
    StoredKey::store_key_result store_res= (*copy)->copy();
 
2352
    enum store_key::store_key_result store_res;
 
2353
    store_res= (*copy)->copy();
2368
2354
    tab->ref.key_err= store_res;
2369
2355
 
2370
2356
    /*
2393
2379
 
2394
2380
    /*
2395
2381
      Check if the error is equal to STORE_KEY_FATAL. This is not expressed
2396
 
      using the StoredKey::store_key_result enum because ref.key_err is a
 
2382
      using the store_key::store_key_result enum because ref.key_err is a
2397
2383
      boolean and we want to detect both true and STORE_KEY_FATAL from the
2398
2384
      space of the union of the values of [true, false] and
2399
 
      StoredKey::store_key_result.
 
2385
      store_key::store_key_result.
2400
2386
      TODO: fix the variable an return types.
2401
2387
    */
2402
 
    if (store_res == StoredKey::STORE_KEY_FATAL)
 
2388
    if (store_res == store_key::STORE_KEY_FATAL)
2403
2389
    {
2404
2390
      /*
2405
2391
       Error converting the left IN operand to the column type of the right
2466
2452
  if (null_keypart)
2467
2453
    return(scan_table());
2468
2454
 
2469
 
  if (!table->cursor->inited)
2470
 
    table->cursor->startIndexScan(tab->ref.key, 0);
2471
 
  error= table->cursor->index_read_map(table->record[0],
 
2455
  if (!table->file->inited)
 
2456
    table->file->ha_index_init(tab->ref.key, 0);
 
2457
  error= table->file->index_read_map(table->record[0],
2472
2458
                                     tab->ref.key_buff,
2473
2459
                                     make_prev_keypart_map(tab->ref.key_parts),
2474
2460
                                     HA_READ_KEY_EXACT);
2579
2565
  if (null_keypart)
2580
2566
    return(scan_table());
2581
2567
 
2582
 
  if (!table->cursor->inited)
2583
 
    table->cursor->startIndexScan(tab->ref.key, 1);
2584
 
  error= table->cursor->index_read_map(table->record[0],
 
2568
  if (!table->file->inited)
 
2569
    table->file->ha_index_init(tab->ref.key, 1);
 
2570
  error= table->file->index_read_map(table->record[0],
2585
2571
                                     tab->ref.key_buff,
2586
2572
                                     make_prev_keypart_map(tab->ref.key_parts),
2587
2573
                                     HA_READ_KEY_EXACT);
2605
2591
            ((Item_in_subselect *) item)->value= 1;
2606
2592
          break;
2607
2593
        }
2608
 
        error= table->cursor->index_next_same(table->record[0],
 
2594
        error= table->file->index_next_same(table->record[0],
2609
2595
                                            tab->ref.key_buff,
2610
2596
                                            tab->ref.key_length);
2611
2597
        if (error && error != HA_ERR_END_OF_FILE)
2642
2628
}
2643
2629
 
2644
2630
 
2645
 
bool subselect_single_select_engine::uncacheable()
2646
 
{
2647
 
  return select_lex->uncacheable.any();
2648
 
}
2649
 
 
2650
 
 
2651
 
bool subselect_single_select_engine::uncacheable(uint32_t bit_pos)
2652
 
{
2653
 
  return select_lex->uncacheable.test(bit_pos);
2654
 
}
2655
 
 
2656
 
 
2657
 
bool subselect_union_engine::uncacheable()
2658
 
{
2659
 
  return unit->uncacheable.any();
2660
 
}
2661
 
 
2662
 
 
2663
 
bool subselect_union_engine::uncacheable(uint32_t bit_pos)
2664
 
{
2665
 
  return unit->uncacheable.test(bit_pos);
 
2631
uint8_t subselect_single_select_engine::uncacheable()
 
2632
{
 
2633
  return select_lex->uncacheable;
 
2634
}
 
2635
 
 
2636
 
 
2637
uint8_t subselect_union_engine::uncacheable()
 
2638
{
 
2639
  return unit->uncacheable;
2666
2640
}
2667
2641
 
2668
2642
 
2726
2700
void subselect_uniquesubquery_engine::print(String *str,
2727
2701
                                            enum_query_type query_type)
2728
2702
{
2729
 
  char *table_name= const_cast<char *>(tab->table->getShare()->getTableName());
 
2703
  char *table_name= tab->table->s->table_name.str;
2730
2704
  str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2731
2705
  tab->ref.items[0]->print(str, query_type);
2732
2706
  str->append(STRING_WITH_LEN(" in "));
2733
 
  if (tab->table->getShare()->isTemporaryCategory())
 
2707
  if (tab->table->s->table_category == TABLE_CATEGORY_TEMPORARY)
2734
2708
  {
2735
2709
    /*
2736
2710
      Temporary tables' names change across runs, so they can't be used for
2739
2713
    str->append(STRING_WITH_LEN("<temporary table>"));
2740
2714
  }
2741
2715
  else
2742
 
    str->append(table_name, tab->table->getShare()->getTableNameSize());
2743
 
  KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
 
2716
    str->append(table_name, tab->table->s->table_name.length);
 
2717
  KEY *key_info= tab->table->key_info+ tab->ref.key;
2744
2718
  str->append(STRING_WITH_LEN(" on "));
2745
2719
  str->append(key_info->name);
2746
2720
  if (cond)
2763
2737
  for (uint32_t i= 0; i < key_info->key_parts; i++)
2764
2738
    tab->ref.items[i]->print(str);
2765
2739
  str->append(STRING_WITH_LEN(" in "));
2766
 
  str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
 
2740
  str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2767
2741
  str->append(STRING_WITH_LEN(" on "));
2768
2742
  str->append(key_info->name);
2769
2743
  if (cond)
2781
2755
  str->append(STRING_WITH_LEN("<index_lookup>("));
2782
2756
  tab->ref.items[0]->print(str, query_type);
2783
2757
  str->append(STRING_WITH_LEN(" in "));
2784
 
  str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
2785
 
  KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
 
2758
  str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
 
2759
  KEY *key_info= tab->table->key_info+ tab->ref.key;
2786
2760
  str->append(STRING_WITH_LEN(" on "));
2787
2761
  str->append(key_info->name);
2788
2762
  if (check_null)
2942
2916
    temporary table has one hash index on all its columns.
2943
2917
  - Create a new result sink that sends the result stream of the subquery to
2944
2918
    the temporary table,
2945
 
  - Create and initialize a new JoinTable, and TABLE_REF objects to perform
 
2919
  - Create and initialize a new JOIN_TAB, and TABLE_REF objects to perform
2946
2920
    lookups into the indexed temporary table.
2947
2921
 
2948
2922
  @notice:
2959
2933
  select_union  *tmp_result_sink;
2960
2934
  /* The table into which the subquery is materialized. */
2961
2935
  Table         *tmp_table;
2962
 
  KeyInfo           *tmp_key; /* The only index on the temporary table. */
 
2936
  KEY           *tmp_key; /* The only index on the temporary table. */
2963
2937
  uint32_t          tmp_key_parts; /* Number of keyparts in tmp_key. */
2964
2938
  Item_in_subselect *item_in= (Item_in_subselect *) item;
2965
2939
 
2972
2946
  */
2973
2947
  if (!(tmp_result_sink= new select_union))
2974
2948
    return(true);
2975
 
 
2976
2949
  if (tmp_result_sink->create_result_table(
2977
2950
                         session, tmp_columns, true,
2978
2951
                         session->options | TMP_TABLE_ALL_COLUMNS,
2979
 
                         "materialized subselect"))
 
2952
                         "materialized subselect", true))
2980
2953
    return(true);
2981
2954
 
2982
2955
  tmp_table= tmp_result_sink->table;
2990
2963
     table since it will not be used, and tell the caller we failed to
2991
2964
     initialize the engine.
2992
2965
  */
2993
 
  if (tmp_table->getShare()->sizeKeys() == 0)
 
2966
  if (tmp_table->s->keys == 0)
2994
2967
  {
2995
 
    assert(tmp_table->getShare()->db_type() == myisam_engine);
 
2968
    assert(tmp_table->s->db_type() == myisam_engine);
2996
2969
    assert(
2997
 
      tmp_table->getShare()->uniques ||
2998
 
      tmp_table->key_info->key_length >= tmp_table->cursor->getEngine()->max_key_length() ||
2999
 
      tmp_table->key_info->key_parts > tmp_table->cursor->getEngine()->max_key_parts());
3000
 
    tmp_table= NULL;
 
2970
      tmp_table->s->uniques ||
 
2971
      tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
 
2972
      tmp_table->key_info->key_parts > tmp_table->file->max_key_parts());
 
2973
    tmp_table->free_tmp_table(session);
3001
2974
    delete result;
3002
2975
    result= NULL;
3003
2976
    return(true);
3008
2981
    Make sure there is only one index on the temp table, and it doesn't have
3009
2982
    the extra key part created when s->uniques > 0.
3010
2983
  */
3011
 
  assert(tmp_table->getShare()->sizeKeys() == 1 && tmp_columns->elements == tmp_key_parts);
 
2984
  assert(tmp_table->s->keys == 1 && tmp_columns->elements == tmp_key_parts);
3012
2985
 
3013
2986
 
3014
2987
  /* 2. Create/initialize execution related objects. */
3015
2988
 
3016
2989
  /*
3017
 
    Create and initialize the JoinTable that represents an index lookup
 
2990
    Create and initialize the JOIN_TAB that represents an index lookup
3018
2991
    plan operator into the materialized subquery result. Notice that:
3019
 
    - this JoinTable has no corresponding JOIN (and doesn't need one), and
 
2992
    - this JOIN_TAB has no corresponding JOIN (and doesn't need one), and
3020
2993
    - here we initialize only those members that are used by
3021
2994
      subselect_uniquesubquery_engine, so these objects are incomplete.
3022
2995
  */
3023
 
  if (!(tab= (JoinTable*) session->alloc(sizeof(JoinTable))))
 
2996
  if (!(tab= (JOIN_TAB*) session->alloc(sizeof(JOIN_TAB))))
3024
2997
    return(true);
3025
2998
  tab->table= tmp_table;
3026
2999
  tab->ref.key= 0; /* The only temp table index. */
3028
3001
  if (!(tab->ref.key_buff=
3029
3002
        (unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3030
3003
      !(tab->ref.key_copy=
3031
 
        (StoredKey**) session->alloc((sizeof(StoredKey*) *
 
3004
        (store_key**) session->alloc((sizeof(store_key*) *
3032
3005
                                  (tmp_key_parts + 1)))) ||
3033
3006
      !(tab->ref.items=
3034
3007
        (Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
3035
3008
    return(true);
3036
3009
 
3037
 
  KeyPartInfo *cur_key_part= tmp_key->key_part;
3038
 
  StoredKey **ref_key= tab->ref.key_copy;
 
3010
  KEY_PART_INFO *cur_key_part= tmp_key->key_part;
 
3011
  store_key **ref_key= tab->ref.key_copy;
3039
3012
  unsigned char *cur_ref_buff= tab->ref.key_buff;
3040
3013
 
3041
3014
  for (uint32_t i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3088
3061
{
3089
3062
  delete result;
3090
3063
  if (tab)
3091
 
  {
3092
 
    tab->table= NULL;
3093
 
  }
 
3064
    tab->table->free_tmp_table(session);
3094
3065
}
3095
3066
 
3096
3067
 
3098
3069
  Cleanup performed after each PS execution.
3099
3070
 
3100
3071
  @detail
3101
 
  Called in the end of Join::prepare for PS from Item_subselect::cleanup.
 
3072
  Called in the end of JOIN::prepare for PS from Item_subselect::cleanup.
3102
3073
*/
3103
3074
 
3104
3075
void subselect_hash_sj_engine::cleanup()
3143
3114
    /*
3144
3115
      TODO:
3145
3116
      - Unlock all subquery tables as we don't need them. To implement this
3146
 
        we need to add new functionality to Join::join_free that can unlock
 
3117
        we need to add new functionality to JOIN::join_free that can unlock
3147
3118
        all tables in a subquery (and all its subqueries).
3148
3119
      - The temp table used for grouping in the subquery can be freed
3149
3120
        immediately after materialization (yet it's done together with
3156
3127
      statistics, then we test if the temporary table for the query result is
3157
3128
      empty.
3158
3129
    */
3159
 
    tab->table->cursor->info(HA_STATUS_VARIABLE);
3160
 
    if (!tab->table->cursor->stats.records)
 
3130
    tab->table->file->info(HA_STATUS_VARIABLE);
 
3131
    if (!tab->table->file->stats.records)
3161
3132
    {
3162
3133
      empty_result_set= true;
3163
3134
      item_in->value= false;
3198
3169
           "<the access method for lookups is not yet created>"
3199
3170
         ));
3200
3171
}
3201
 
 
3202
 
} /* namespace drizzled */