~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/subselect.cc

Cleaned up a few global tests which aren't happy now.

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
 
#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
 
#include <drizzled/plugin/storage_engine.h>
43
 
 
44
 
namespace drizzled
45
 
{
46
 
 
47
 
extern plugin::StorageEngine *myisam_engine;
48
37
 
49
38
inline Item * and_items(Item* cond, Item *item)
50
39
{
51
40
  return (cond? (new Item_cond_and(cond, item)) : item);
52
41
}
53
42
 
54
 
Item_subselect::Item_subselect() :
55
 
  Item_result_field(),
56
 
  value_assigned(false),
57
 
  session(NULL),
58
 
  substitution(NULL),
59
 
  unit(NULL),
60
 
  engine(NULL),
61
 
  old_engine(NULL),
62
 
  used_tables_cache(0),
63
 
  max_columns(0),
64
 
  parsing_place(NO_MATTER),
65
 
  have_to_be_excluded(false),
66
 
  const_item_cache(true),
67
 
  engine_changed(false),
68
 
  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),
69
47
  is_correlated(false)
70
48
{
71
49
  with_subselect= 1;
91
69
  if (unit->item)
92
70
  {
93
71
    /*
94
 
      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
95
73
      => we do not copy old_engine here
96
74
    */
97
75
    engine= unit->item->engine;
173
151
}
174
152
 
175
153
Item_subselect::trans_res
176
 
Item_subselect::select_transformer(Join *)
 
154
Item_subselect::select_transformer(JOIN *)
177
155
{
178
156
  return(RES_OK);
179
157
}
181
159
 
182
160
bool Item_subselect::fix_fields(Session *session_param, Item **ref)
183
161
{
184
 
  char const *save_where= session_param->where();
 
162
  char const *save_where= session_param->where;
 
163
  uint8_t uncacheable;
185
164
  bool res;
186
165
 
187
166
  assert(fixed == 0);
209
188
 
210
189
      // did we changed top item of WHERE condition
211
190
      if (unit->outer_select()->where == (*ref))
212
 
      {
213
 
        unit->outer_select()->where= substitution; // correct WHERE for PS
214
 
      }
 
191
        unit->outer_select()->where= substitution; // correct WHERE for PS
215
192
      else if (unit->outer_select()->having == (*ref))
216
 
      {
217
 
        unit->outer_select()->having= substitution; // correct HAVING for PS
218
 
      }
 
193
        unit->outer_select()->having= substitution; // correct HAVING for PS
219
194
 
220
195
      (*ref)= substitution;
221
196
      substitution->name= name;
222
197
      if (have_to_be_excluded)
223
 
      {
224
 
        engine->exclude();
225
 
      }
 
198
        engine->exclude();
226
199
      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
 
 
 
200
      session->where= "checking transformed subquery";
 
201
      if (!(*ref)->fixed)
 
202
        ret= (*ref)->fix_fields(session, ref);
 
203
      session->where= save_where;
234
204
      return ret;
235
205
    }
236
206
    // Is it one field subselect?
244
214
  else
245
215
    goto err;
246
216
 
247
 
  if (engine->uncacheable())
 
217
  if ((uncacheable= engine->uncacheable()))
248
218
  {
249
 
    const_item_cache= false;
250
 
    if (engine->uncacheable(UNCACHEABLE_RAND))
251
 
    {
 
219
    const_item_cache= 0;
 
220
    if (uncacheable & UNCACHEABLE_RAND)
252
221
      used_tables_cache|= RAND_TABLE_BIT;
253
 
    }
254
222
  }
255
223
  fixed= 1;
256
224
 
257
225
err:
258
 
  session->setWhere(save_where);
 
226
  session->where= save_where;
259
227
  return res;
260
228
}
261
229
 
270
238
    {
271
239
      List_iterator<Item> li(lex->item_list);
272
240
      Item *item;
273
 
      Order *order;
 
241
      order_st *order;
274
242
 
275
243
      if (lex->where && (lex->where)->walk(processor, walk_subquery, argument))
276
244
        return 1;
283
251
        if (item->walk(processor, walk_subquery, argument))
284
252
          return 1;
285
253
      }
286
 
      for (order= (Order*) lex->order_list.first ; order; order= order->next)
 
254
      for (order= (order_st*) lex->order_list.first ; order; order= order->next)
287
255
      {
288
256
        if ((*order->item)->walk(processor, walk_subquery, argument))
289
257
          return 1;
290
258
      }
291
 
      for (order= (Order*) lex->group_list.first ; order; order= order->next)
 
259
      for (order= (order_st*) lex->group_list.first ; order; order= order->next)
292
260
      {
293
261
        if ((*order->item)->walk(processor, walk_subquery, argument))
294
262
          return 1;
392
360
 
393
361
void Item_subselect::update_used_tables()
394
362
{
395
 
  if (! engine->uncacheable())
 
363
  if (!engine->uncacheable())
396
364
  {
397
365
    // did all used tables become static?
398
366
    if (!(used_tables_cache & ~engine->upper_select_const_tables()))
399
 
      const_item_cache= true;
 
367
      const_item_cache= 1;
400
368
  }
401
369
}
402
370
 
508
476
  Make rollback for it, or special name resolving mode in 5.0.
509
477
*/
510
478
Item_subselect::trans_res
511
 
Item_singlerow_subselect::select_transformer(Join *join)
 
479
Item_singlerow_subselect::select_transformer(JOIN *join)
512
480
{
513
481
  if (changed)
514
482
    return(RES_OK);
536
504
    if (session->lex->describe)
537
505
    {
538
506
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
539
 
      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);
540
508
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
541
509
                   ER_SELECT_REDUCED, warn_buff);
542
510
    }
580
548
  }
581
549
  else
582
550
  {
583
 
    if (!(row= (Item_cache**) memory::sql_alloc(sizeof(Item_cache*)*max_columns)))
 
551
    if (!(row= (Item_cache**) sql_alloc(sizeof(Item_cache*)*max_columns)))
584
552
      return;
585
553
    engine->fix_length_and_dec(row);
586
554
    value= *row;
670
638
}
671
639
 
672
640
 
673
 
type::Decimal *Item_singlerow_subselect::val_decimal(type::Decimal *decimal_value)
 
641
my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value)
674
642
{
675
643
  if (!exec() && !value->null_value)
676
644
  {
736
704
}
737
705
 
738
706
Item_in_subselect::Item_in_subselect(Item * left_exp,
739
 
                                     Select_Lex *select_lex) :
740
 
  Item_exists_subselect(),
741
 
  left_expr(left_exp),
742
 
  left_expr_cache(NULL),
743
 
  first_execution(true),
744
 
  optimizer(NULL),
745
 
  pushed_cond_guards(NULL),
746
 
  sj_convert_priority(0),
747
 
  expr_join_nest(NULL),
748
 
  exec_method(NOT_TRANSFORMED),
749
 
  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)
750
711
{
 
712
  left_expr= left_exp;
751
713
  init(select_lex, new select_exists_subselect(this));
752
714
  max_columns= UINT_MAX;
753
715
  maybe_null= 1;
820
782
}
821
783
 
822
784
 
823
 
type::Decimal *Item_exists_subselect::val_decimal(type::Decimal *decimal_value)
 
785
my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
824
786
{
825
787
  assert(fixed == 1);
826
788
  if (exec())
828
790
    reset();
829
791
    return 0;
830
792
  }
831
 
  int2_class_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
 
793
  int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
832
794
  return decimal_value;
833
795
}
834
796
 
931
893
  return value;
932
894
}
933
895
 
934
 
type::Decimal *Item_in_subselect::val_decimal(type::Decimal *decimal_value)
 
896
my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
935
897
{
936
898
  /*
937
899
    As far as Item_in_subselect called only from Item_in_optimizer this
948
910
  }
949
911
  if (was_null && !value)
950
912
    null_value= 1;
951
 
  int2_class_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
 
913
  int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
952
914
  return decimal_value;
953
915
}
954
916
 
988
950
*/
989
951
 
990
952
Item_subselect::trans_res
991
 
Item_in_subselect::single_value_transformer(Join *join,
 
953
Item_in_subselect::single_value_transformer(JOIN *join,
992
954
                                            const Comp_creator *func)
993
955
{
994
956
  Select_Lex *select_lex= join->select_lex;
1015
977
    later in this method.
1016
978
  */
1017
979
  if ((abort_on_null || (upper_item && upper_item->top_level())) &&
1018
 
      select_lex->master_unit()->uncacheable.none() && !func->eqne_op())
 
980
      !select_lex->master_unit()->uncacheable && !func->eqne_op())
1019
981
  {
1020
982
    if (substitution)
1021
983
    {
1111
1073
                              (char *)"<no matter>",
1112
1074
                              (char *)in_left_expr_name);
1113
1075
 
1114
 
    master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1076
    master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1115
1077
  }
1116
1078
 
1117
1079
  if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1118
1080
  {
1119
 
    if (!(pushed_cond_guards= (bool*)join->session->getMemRoot()->allocate(sizeof(bool))))
 
1081
    if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool))))
1120
1082
      return(RES_ERROR);
1121
1083
    pushed_cond_guards[0]= true;
1122
1084
  }
1170
1132
*/
1171
1133
 
1172
1134
Item_subselect::trans_res
1173
 
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)
1174
1136
{
1175
1137
  Select_Lex *select_lex= join->select_lex;
1176
1138
 
1177
 
  select_lex->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1139
  select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1178
1140
  if (join->having || select_lex->with_sum_func ||
1179
1141
      select_lex->group_list.elements)
1180
1142
  {
1332
1294
        if (session->lex->describe)
1333
1295
        {
1334
1296
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
1335
 
          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);
1336
1298
          push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1337
1299
                       ER_SELECT_REDUCED, warn_buff);
1338
1300
        }
1346
1308
 
1347
1309
 
1348
1310
Item_subselect::trans_res
1349
 
Item_in_subselect::row_value_transformer(Join *join)
 
1311
Item_in_subselect::row_value_transformer(JOIN *join)
1350
1312
{
1351
1313
  Select_Lex *select_lex= join->select_lex;
1352
1314
  uint32_t cols_num= left_expr->cols();
1380
1342
    optimizer->keep_top_level_cache();
1381
1343
 
1382
1344
    session->lex->current_select= current;
1383
 
    master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1345
    master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1384
1346
 
1385
1347
    if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1386
1348
    {
1387
 
      if (!(pushed_cond_guards= (bool*)join->session->getMemRoot()->allocate(sizeof(bool) *
 
1349
      if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool) *
1388
1350
                                                        left_expr->cols())))
1389
1351
        return(RES_ERROR);
1390
1352
      for (uint32_t i= 0; i < cols_num; i++)
1423
1385
*/
1424
1386
 
1425
1387
Item_subselect::trans_res
1426
 
Item_in_subselect::row_value_in_to_exists_transformer(Join * join)
 
1388
Item_in_subselect::row_value_in_to_exists_transformer(JOIN * join)
1427
1389
{
1428
1390
  Select_Lex *select_lex= join->select_lex;
1429
1391
  Item *having_item= 0;
1432
1394
                        select_lex->group_list.first ||
1433
1395
                        !select_lex->table_list.elements);
1434
1396
 
1435
 
  select_lex->uncacheable.set(UNCACHEABLE_DEPENDENT);
 
1397
  select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1436
1398
  if (is_having_used)
1437
1399
  {
1438
1400
    /*
1621
1583
 
1622
1584
 
1623
1585
Item_subselect::trans_res
1624
 
Item_in_subselect::select_transformer(Join *join)
 
1586
Item_in_subselect::select_transformer(JOIN *join)
1625
1587
{
1626
1588
  return select_in_like_transformer(join, Eq_creator::instance());
1627
1589
}
1649
1611
*/
1650
1612
 
1651
1613
Item_subselect::trans_res
1652
 
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)
1653
1615
{
1654
1616
  Select_Lex *current= session->lex->current_select, *up;
1655
 
  const char *save_where= session->where();
 
1617
  const char *save_where= session->where;
1656
1618
  Item_subselect::trans_res res= RES_ERROR;
1657
1619
  bool result;
1658
1620
 
1659
1621
  {
1660
1622
    /*
1661
1623
      IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
1662
 
      ORDER BY clause becomes meaningless thus we drop it here.
 
1624
      order_st BY clause becomes meaningless thus we drop it here.
1663
1625
    */
1664
1626
    Select_Lex *sl= current->master_unit()->first_select();
1665
1627
    for (; sl; sl= sl->next_select())
1672
1634
  if (changed)
1673
1635
    return(RES_OK);
1674
1636
 
1675
 
  session->setWhere("IN/ALL/ANY subquery");
 
1637
  session->where= "IN/ALL/ANY subquery";
1676
1638
 
1677
1639
  /*
1678
1640
    In some optimisation cases we will not need this Item_in_optimizer
1723
1685
    res= row_value_transformer(join);
1724
1686
  }
1725
1687
err:
1726
 
  session->setWhere(save_where);
 
1688
  session->where= save_where;
1727
1689
  return(res);
1728
1690
}
1729
1691
 
1852
1814
 
1853
1815
bool Item_in_subselect::init_left_expr_cache()
1854
1816
{
1855
 
  Join *outer_join= NULL;
 
1817
  JOIN *outer_join;
 
1818
  Next_select_func end_select;
 
1819
  bool use_result_field= false;
1856
1820
 
1857
1821
  outer_join= unit->outer_select()->join;
1858
 
  if (! outer_join || ! outer_join->tables || ! outer_join->join_tab)
 
1822
  if (!outer_join || !outer_join->tables)
1859
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;
1860
1836
 
1861
1837
  if (!(left_expr_cache= new List<Cached_item>))
1862
1838
    return true;
1863
1839
 
1864
1840
  for (uint32_t i= 0; i < left_expr->cols(); i++)
1865
1841
  {
1866
 
    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);
1867
1845
    if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
1868
1846
      return true;
1869
1847
  }
1891
1869
 
1892
1870
 
1893
1871
Item_subselect::trans_res
1894
 
Item_allany_subselect::select_transformer(Join *join)
 
1872
Item_allany_subselect::select_transformer(JOIN *join)
1895
1873
{
1896
1874
  exec_method= IN_TO_EXISTS;
1897
1875
  if (upper_item)
1982
1960
void subselect_uniquesubquery_engine::cleanup()
1983
1961
{
1984
1962
  /* Tell handler we don't need the index anymore */
1985
 
  if (tab->table->cursor->inited)
1986
 
    tab->table->cursor->endIndexScan();
 
1963
  if (tab->table->file->inited)
 
1964
    tab->table->file->ha_index_end();
1987
1965
  return;
1988
1966
}
1989
1967
 
2028
2006
{
2029
2007
  if (prepared)
2030
2008
    return 0;
2031
 
  join= new Join(session, select_lex->item_list,
 
2009
  join= new JOIN(session, select_lex->item_list,
2032
2010
                 select_lex->options | SELECT_NO_UNLOCK, result);
2033
2011
  if (!join || !result)
2034
2012
    return 1; /* Fatal error is set already. */
2041
2019
                    select_lex->where,
2042
2020
                    select_lex->order_list.elements +
2043
2021
                    select_lex->group_list.elements,
2044
 
                    (Order*) select_lex->order_list.first,
2045
 
                    (Order*) select_lex->group_list.first,
 
2022
                    (order_st*) select_lex->order_list.first,
 
2023
                    (order_st*) select_lex->group_list.first,
2046
2024
                    select_lex->having,
2047
2025
                    select_lex, select_lex->master_unit()))
2048
2026
    return 1;
2142
2120
  assert(0);
2143
2121
}
2144
2122
 
 
2123
int  init_read_record_seq(JoinTable *tab);
 
2124
int join_read_always_key_or_null(JoinTable *tab);
 
2125
int join_read_next_same_or_null(READ_RECORD *info);
 
2126
 
2145
2127
int subselect_single_select_engine::exec()
2146
2128
{
2147
 
  char const *save_where= session->where();
 
2129
  char const *save_where= session->where;
2148
2130
  Select_Lex *save_select= session->lex->current_select;
2149
2131
  session->lex->current_select= select_lex;
2150
2132
  if (!join->optimized)
2154
2136
    unit->set_limit(unit->global_parameters);
2155
2137
    if (join->optimize())
2156
2138
    {
2157
 
      session->setWhere(save_where);
 
2139
      session->where= save_where;
2158
2140
      executed= 1;
2159
2141
      session->lex->current_select= save_select;
2160
2142
      return(join->error ? join->error : 1);
2161
2143
    }
2162
 
    if (save_join_if_explain())
2163
 
     return(1);
2164
 
 
 
2144
    if (!select_lex->uncacheable && session->lex->describe &&
 
2145
        !(join->select_options & SELECT_DESCRIBE) &&
 
2146
        join->need_tmp && item->const_item())
 
2147
    {
 
2148
      /*
 
2149
        Force join->join_tmp creation, because this subquery will be replaced
 
2150
        by a simple select from the materialization temp table by optimize()
 
2151
        called by EXPLAIN and we need to preserve the initial query structure
 
2152
        so we can display it.
 
2153
       */
 
2154
      select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
 
2155
      select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
 
2156
      if (join->init_save_join_tab())
 
2157
        return(1);
 
2158
    }
2165
2159
    if (item->engine_changed)
2166
2160
    {
2167
2161
      return(1);
2168
2162
    }
2169
2163
  }
2170
 
  if (select_lex->uncacheable.any() &&
2171
 
      ! select_lex->uncacheable.test(UNCACHEABLE_EXPLAIN) &&
2172
 
      executed)
 
2164
  if (select_lex->uncacheable &&
 
2165
      select_lex->uncacheable != UNCACHEABLE_EXPLAIN
 
2166
      && executed)
2173
2167
  {
2174
2168
    if (join->reinit())
2175
2169
    {
2176
 
      session->setWhere(save_where);
 
2170
      session->where= save_where;
2177
2171
      session->lex->current_select= save_select;
2178
 
      return 1;
 
2172
      return(1);
2179
2173
    }
2180
2174
    item->reset();
2181
2175
    item->assigned((executed= 0));
2211
2205
              tab->read_first_record= init_read_record_seq;
2212
2206
              tab->read_record.record= tab->table->record[0];
2213
2207
              tab->read_record.session= join->session;
2214
 
              tab->read_record.ref_length= tab->table->cursor->ref_length;
 
2208
              tab->read_record.ref_length= tab->table->file->ref_length;
2215
2209
              *(last_changed_tab++)= tab;
2216
2210
              break;
2217
2211
            }
2232
2226
      tab->read_record.read_record= tab->save_read_record;
2233
2227
    }
2234
2228
    executed= 1;
2235
 
    session->setWhere(save_where);
 
2229
    session->where= save_where;
2236
2230
    session->lex->current_select= save_select;
2237
2231
    return(join->error||session->is_fatal_error);
2238
2232
  }
2239
 
  session->setWhere(save_where);
 
2233
  session->where= save_where;
2240
2234
  session->lex->current_select= save_select;
2241
2235
  return(0);
2242
2236
}
2243
2237
 
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
2238
int subselect_union_engine::exec()
2283
2239
{
2284
 
  char const *save_where= session->where();
 
2240
  char const *save_where= session->where;
2285
2241
  int res= unit->exec();
2286
 
  session->setWhere(save_where);
2287
 
 
 
2242
  session->where= save_where;
2288
2243
  return res;
2289
2244
}
2290
2245
 
2312
2267
  int error;
2313
2268
  Table *table= tab->table;
2314
2269
 
2315
 
  if (table->cursor->inited)
2316
 
    table->cursor->endIndexScan();
2317
 
 
2318
 
  if ((error= table->cursor->startTableScan(1)))
2319
 
  {
2320
 
    table->print_error(error, MYF(0));
2321
 
    return 1;
2322
 
  }
2323
 
 
2324
 
  assert(table->getSession());
2325
 
  table->cursor->extra_opt(HA_EXTRA_CACHE,
2326
 
                           table->getSession()->variables.read_buff_size);
 
2270
  if (table->file->inited)
 
2271
    table->file->ha_index_end();
 
2272
 
 
2273
  table->file->ha_rnd_init(1);
 
2274
  table->file->extra_opt(HA_EXTRA_CACHE,
 
2275
                         current_session->variables.read_buff_size);
2327
2276
  table->null_row= 0;
2328
2277
  for (;;)
2329
2278
  {
2330
 
    error=table->cursor->rnd_next(table->record[0]);
 
2279
    error=table->file->rnd_next(table->record[0]);
2331
2280
    if (error && error != HA_ERR_END_OF_FILE)
2332
2281
    {
2333
2282
      error= table->report_error(error);
2344
2293
    }
2345
2294
  }
2346
2295
 
2347
 
  table->cursor->endTableScan();
 
2296
  table->file->ha_rnd_end();
2348
2297
  return(error != 0);
2349
2298
}
2350
2299
 
2395
2344
{
2396
2345
  for (StoredKey **copy= tab->ref.key_copy ; *copy ; copy++)
2397
2346
  {
2398
 
    StoredKey::store_key_result store_res= (*copy)->copy();
 
2347
    enum StoredKey::store_key_result store_res;
 
2348
    store_res= (*copy)->copy();
2399
2349
    tab->ref.key_err= store_res;
2400
2350
 
2401
2351
    /*
2497
2447
  if (null_keypart)
2498
2448
    return(scan_table());
2499
2449
 
2500
 
  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
 
 
2511
 
  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],
2512
2453
                                     tab->ref.key_buff,
2513
2454
                                     make_prev_keypart_map(tab->ref.key_parts),
2514
2455
                                     HA_READ_KEY_EXACT);
2619
2560
  if (null_keypart)
2620
2561
    return(scan_table());
2621
2562
 
2622
 
  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
 
  }
2632
 
  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],
2633
2566
                                     tab->ref.key_buff,
2634
2567
                                     make_prev_keypart_map(tab->ref.key_parts),
2635
2568
                                     HA_READ_KEY_EXACT);
2653
2586
            ((Item_in_subselect *) item)->value= 1;
2654
2587
          break;
2655
2588
        }
2656
 
        error= table->cursor->index_next_same(table->record[0],
 
2589
        error= table->file->index_next_same(table->record[0],
2657
2590
                                            tab->ref.key_buff,
2658
2591
                                            tab->ref.key_length);
2659
2592
        if (error && error != HA_ERR_END_OF_FILE)
2690
2623
}
2691
2624
 
2692
2625
 
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);
 
2626
uint8_t subselect_single_select_engine::uncacheable()
 
2627
{
 
2628
  return select_lex->uncacheable;
 
2629
}
 
2630
 
 
2631
 
 
2632
uint8_t subselect_union_engine::uncacheable()
 
2633
{
 
2634
  return unit->uncacheable;
2714
2635
}
2715
2636
 
2716
2637
 
2774
2695
void subselect_uniquesubquery_engine::print(String *str,
2775
2696
                                            enum_query_type query_type)
2776
2697
{
2777
 
  char *table_name= const_cast<char *>(tab->table->getShare()->getTableName());
 
2698
  char *table_name= tab->table->s->table_name.str;
2778
2699
  str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2779
2700
  tab->ref.items[0]->print(str, query_type);
2780
2701
  str->append(STRING_WITH_LEN(" in "));
2781
 
  if (tab->table->getShare()->isTemporaryCategory())
 
2702
  if (tab->table->s->table_category == TABLE_CATEGORY_TEMPORARY)
2782
2703
  {
2783
2704
    /*
2784
2705
      Temporary tables' names change across runs, so they can't be used for
2787
2708
    str->append(STRING_WITH_LEN("<temporary table>"));
2788
2709
  }
2789
2710
  else
2790
 
    str->append(table_name, tab->table->getShare()->getTableNameSize());
2791
 
  KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
 
2711
    str->append(table_name, tab->table->s->table_name.length);
 
2712
  KEY *key_info= tab->table->key_info+ tab->ref.key;
2792
2713
  str->append(STRING_WITH_LEN(" on "));
2793
2714
  str->append(key_info->name);
2794
2715
  if (cond)
2811
2732
  for (uint32_t i= 0; i < key_info->key_parts; i++)
2812
2733
    tab->ref.items[i]->print(str);
2813
2734
  str->append(STRING_WITH_LEN(" in "));
2814
 
  str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
 
2735
  str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2815
2736
  str->append(STRING_WITH_LEN(" on "));
2816
2737
  str->append(key_info->name);
2817
2738
  if (cond)
2829
2750
  str->append(STRING_WITH_LEN("<index_lookup>("));
2830
2751
  tab->ref.items[0]->print(str, query_type);
2831
2752
  str->append(STRING_WITH_LEN(" in "));
2832
 
  str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
2833
 
  KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
 
2753
  str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
 
2754
  KEY *key_info= tab->table->key_info+ tab->ref.key;
2834
2755
  str->append(STRING_WITH_LEN(" on "));
2835
2756
  str->append(key_info->name);
2836
2757
  if (check_null)
3007
2928
  select_union  *tmp_result_sink;
3008
2929
  /* The table into which the subquery is materialized. */
3009
2930
  Table         *tmp_table;
3010
 
  KeyInfo           *tmp_key; /* The only index on the temporary table. */
 
2931
  KEY           *tmp_key; /* The only index on the temporary table. */
3011
2932
  uint32_t          tmp_key_parts; /* Number of keyparts in tmp_key. */
3012
2933
  Item_in_subselect *item_in= (Item_in_subselect *) item;
3013
2934
 
3020
2941
  */
3021
2942
  if (!(tmp_result_sink= new select_union))
3022
2943
    return(true);
3023
 
 
3024
2944
  if (tmp_result_sink->create_result_table(
3025
2945
                         session, tmp_columns, true,
3026
2946
                         session->options | TMP_TABLE_ALL_COLUMNS,
3027
 
                         "materialized subselect"))
 
2947
                         "materialized subselect", true))
3028
2948
    return(true);
3029
2949
 
3030
2950
  tmp_table= tmp_result_sink->table;
3038
2958
     table since it will not be used, and tell the caller we failed to
3039
2959
     initialize the engine.
3040
2960
  */
3041
 
  if (tmp_table->getShare()->sizeKeys() == 0)
 
2961
  if (tmp_table->s->keys == 0)
3042
2962
  {
3043
 
    assert(tmp_table->getShare()->db_type() == myisam_engine);
 
2963
    assert(tmp_table->s->db_type() == myisam_engine);
3044
2964
    assert(
3045
 
      tmp_table->getShare()->uniques ||
3046
 
      tmp_table->key_info->key_length >= tmp_table->cursor->getEngine()->max_key_length() ||
3047
 
      tmp_table->key_info->key_parts > tmp_table->cursor->getEngine()->max_key_parts());
3048
 
    tmp_table= NULL;
 
2965
      tmp_table->s->uniques ||
 
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());
 
2968
    tmp_table->free_tmp_table(session);
3049
2969
    delete result;
3050
2970
    result= NULL;
3051
2971
    return(true);
3056
2976
    Make sure there is only one index on the temp table, and it doesn't have
3057
2977
    the extra key part created when s->uniques > 0.
3058
2978
  */
3059
 
  assert(tmp_table->getShare()->sizeKeys() == 1 && tmp_columns->elements == tmp_key_parts);
 
2979
  assert(tmp_table->s->keys == 1 && tmp_columns->elements == tmp_key_parts);
3060
2980
 
3061
2981
 
3062
2982
  /* 2. Create/initialize execution related objects. */
3068
2988
    - here we initialize only those members that are used by
3069
2989
      subselect_uniquesubquery_engine, so these objects are incomplete.
3070
2990
  */
3071
 
  if (!(tab= (JoinTable*) session->getMemRoot()->allocate(sizeof(JoinTable))))
 
2991
  if (!(tab= (JoinTable*) session->alloc(sizeof(JoinTable))))
3072
2992
    return(true);
3073
 
  new (tab) JoinTable();
3074
2993
  tab->table= tmp_table;
3075
2994
  tab->ref.key= 0; /* The only temp table index. */
3076
2995
  tab->ref.key_length= tmp_key->key_length;
3077
2996
  if (!(tab->ref.key_buff=
3078
2997
        (unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3079
2998
      !(tab->ref.key_copy=
3080
 
        (StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
 
2999
        (StoredKey**) session->alloc((sizeof(StoredKey*) *
3081
3000
                                  (tmp_key_parts + 1)))) ||
3082
3001
      !(tab->ref.items=
3083
 
        (Item**) session->getMemRoot()->allocate(sizeof(Item*) * tmp_key_parts)))
 
3002
        (Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
3084
3003
    return(true);
3085
3004
 
3086
 
  KeyPartInfo *cur_key_part= tmp_key->key_part;
 
3005
  KEY_PART_INFO *cur_key_part= tmp_key->key_part;
3087
3006
  StoredKey **ref_key= tab->ref.key_copy;
3088
3007
  unsigned char *cur_ref_buff= tab->ref.key_buff;
3089
3008
 
3137
3056
{
3138
3057
  delete result;
3139
3058
  if (tab)
3140
 
  {
3141
 
    tab->table= NULL;
3142
 
  }
 
3059
    tab->table->free_tmp_table(session);
3143
3060
}
3144
3061
 
3145
3062
 
3147
3064
  Cleanup performed after each PS execution.
3148
3065
 
3149
3066
  @detail
3150
 
  Called in the end of Join::prepare for PS from Item_subselect::cleanup.
 
3067
  Called in the end of JOIN::prepare for PS from Item_subselect::cleanup.
3151
3068
*/
3152
3069
 
3153
3070
void subselect_hash_sj_engine::cleanup()
3185
3102
    session->lex->current_select= materialize_engine->select_lex;
3186
3103
    if ((res= materialize_join->optimize()))
3187
3104
      goto err;
3188
 
 
3189
 
    if (materialize_engine->save_join_if_explain())
3190
 
      goto err;
3191
 
 
3192
3105
    materialize_join->exec();
3193
3106
    if ((res= test(materialize_join->error || session->is_fatal_error)))
3194
3107
      goto err;
3196
3109
    /*
3197
3110
      TODO:
3198
3111
      - Unlock all subquery tables as we don't need them. To implement this
3199
 
        we need to add new functionality to Join::join_free that can unlock
 
3112
        we need to add new functionality to JOIN::join_free that can unlock
3200
3113
        all tables in a subquery (and all its subqueries).
3201
3114
      - The temp table used for grouping in the subquery can be freed
3202
3115
        immediately after materialization (yet it's done together with
3209
3122
      statistics, then we test if the temporary table for the query result is
3210
3123
      empty.
3211
3124
    */
3212
 
    tab->table->cursor->info(HA_STATUS_VARIABLE);
3213
 
    if (!tab->table->cursor->stats.records)
 
3125
    tab->table->file->info(HA_STATUS_VARIABLE);
 
3126
    if (!tab->table->file->stats.records)
3214
3127
    {
3215
3128
      empty_result_set= true;
3216
3129
      item_in->value= false;
3251
3164
           "<the access method for lookups is not yet created>"
3252
3165
         ));
3253
3166
}
3254
 
 
3255
 
} /* namespace drizzled */