~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/subselect.cc

  • Committer: Stewart Smith
  • Date: 2009-05-15 06:57:12 UTC
  • mto: (991.1.5 for-brian)
  • mto: This revision was merged to the branch mainline in revision 1022.
  • Revision ID: stewart@flamingspork.com-20090515065712-bmionylacjmexmmm
Make sql_mode=NO_AUTO_VALUE_ON_ZERO default for Drizzle.

Also fix DEFAULT keyword handling for auto-increment so that it defaults to
NULL and not 0 so that the following is valid and generates two auto-inc
values:

create table t1 (a int auto_increment primary key)
insert into t1 (a) values (default);
insert into t1 (a) values (default);

Important to note that 0 is no longer magic. So this gives you duplicate
primary key error:

insert into t1 (a) values(0);
insert into t1 (a) values(0);

as you've inserted the explicit value of 0 twice.

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(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);
 
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)
2152
2134
    Select_Lex_Unit *unit= select_lex->master_unit();
2153
2135
 
2154
2136
    unit->set_limit(unit->global_parameters);
 
2137
    if (join->flatten_subqueries())
 
2138
    {
 
2139
      session->is_fatal_error= true;
 
2140
      return(1);
 
2141
    }
2155
2142
    if (join->optimize())
2156
2143
    {
2157
 
      session->setWhere(save_where);
 
2144
      session->where= save_where;
2158
2145
      executed= 1;
2159
2146
      session->lex->current_select= save_select;
2160
2147
      return(join->error ? join->error : 1);
2161
2148
    }
2162
 
    if (save_join_if_explain())
2163
 
     return(1);
2164
 
 
 
2149
    if (!select_lex->uncacheable && session->lex->describe &&
 
2150
        !(join->select_options & SELECT_DESCRIBE) &&
 
2151
        join->need_tmp && item->const_item())
 
2152
    {
 
2153
      /*
 
2154
        Force join->join_tmp creation, because this subquery will be replaced
 
2155
        by a simple select from the materialization temp table by optimize()
 
2156
        called by EXPLAIN and we need to preserve the initial query structure
 
2157
        so we can display it.
 
2158
       */
 
2159
      select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
 
2160
      select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
 
2161
      if (join->init_save_join_tab())
 
2162
        return(1);                        /* purecov: inspected */
 
2163
    }
2165
2164
    if (item->engine_changed)
2166
2165
    {
2167
2166
      return(1);
2168
2167
    }
2169
2168
  }
2170
 
  if (select_lex->uncacheable.any() &&
2171
 
      ! select_lex->uncacheable.test(UNCACHEABLE_EXPLAIN) &&
2172
 
      executed)
 
2169
  if (select_lex->uncacheable &&
 
2170
      select_lex->uncacheable != UNCACHEABLE_EXPLAIN
 
2171
      && executed)
2173
2172
  {
2174
2173
    if (join->reinit())
2175
2174
    {
2176
 
      session->setWhere(save_where);
 
2175
      session->where= save_where;
2177
2176
      session->lex->current_select= save_select;
2178
 
      return 1;
 
2177
      return(1);
2179
2178
    }
2180
2179
    item->reset();
2181
2180
    item->assigned((executed= 0));
2183
2182
  if (!executed)
2184
2183
  {
2185
2184
    item->reset_value_registration();
2186
 
    JoinTable *changed_tabs[MAX_TABLES];
2187
 
    JoinTable **last_changed_tab= changed_tabs;
 
2185
    JOIN_TAB *changed_tabs[MAX_TABLES];
 
2186
    JOIN_TAB **last_changed_tab= changed_tabs;
2188
2187
    if (item->have_guarded_conds())
2189
2188
    {
2190
2189
      /*
2195
2194
      */
2196
2195
      for (uint32_t i=join->const_tables ; i < join->tables ; i++)
2197
2196
      {
2198
 
        JoinTable *tab=join->join_tab+i;
 
2197
        JOIN_TAB *tab=join->join_tab+i;
2199
2198
        if (tab && tab->keyuse)
2200
2199
        {
2201
2200
          for (uint32_t key_part= 0;
2211
2210
              tab->read_first_record= init_read_record_seq;
2212
2211
              tab->read_record.record= tab->table->record[0];
2213
2212
              tab->read_record.session= join->session;
2214
 
              tab->read_record.ref_length= tab->table->cursor->ref_length;
 
2213
              tab->read_record.ref_length= tab->table->file->ref_length;
2215
2214
              *(last_changed_tab++)= tab;
2216
2215
              break;
2217
2216
            }
2223
2222
    join->exec();
2224
2223
 
2225
2224
    /* Enable the optimizations back */
2226
 
    for (JoinTable **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
 
2225
    for (JOIN_TAB **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
2227
2226
    {
2228
 
      JoinTable *tab= *ptab;
 
2227
      JOIN_TAB *tab= *ptab;
2229
2228
      tab->read_record.record= 0;
2230
2229
      tab->read_record.ref_length= 0;
2231
2230
      tab->read_first_record= tab->save_read_first_record;
2232
2231
      tab->read_record.read_record= tab->save_read_record;
2233
2232
    }
2234
2233
    executed= 1;
2235
 
    session->setWhere(save_where);
 
2234
    session->where= save_where;
2236
2235
    session->lex->current_select= save_select;
2237
2236
    return(join->error||session->is_fatal_error);
2238
2237
  }
2239
 
  session->setWhere(save_where);
 
2238
  session->where= save_where;
2240
2239
  session->lex->current_select= save_select;
2241
2240
  return(0);
2242
2241
}
2243
2242
 
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
2243
int subselect_union_engine::exec()
2283
2244
{
2284
 
  char const *save_where= session->where();
 
2245
  char const *save_where= session->where;
2285
2246
  int res= unit->exec();
2286
 
  session->setWhere(save_where);
2287
 
 
 
2247
  session->where= save_where;
2288
2248
  return res;
2289
2249
}
2290
2250
 
2312
2272
  int error;
2313
2273
  Table *table= tab->table;
2314
2274
 
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);
 
2275
  if (table->file->inited)
 
2276
    table->file->ha_index_end();
 
2277
 
 
2278
  table->file->ha_rnd_init(1);
 
2279
  table->file->extra_opt(HA_EXTRA_CACHE,
 
2280
                         current_session->variables.read_buff_size);
2327
2281
  table->null_row= 0;
2328
2282
  for (;;)
2329
2283
  {
2330
 
    error=table->cursor->rnd_next(table->record[0]);
 
2284
    error=table->file->rnd_next(table->record[0]);
2331
2285
    if (error && error != HA_ERR_END_OF_FILE)
2332
2286
    {
2333
2287
      error= table->report_error(error);
2344
2298
    }
2345
2299
  }
2346
2300
 
2347
 
  table->cursor->endTableScan();
 
2301
  table->file->ha_rnd_end();
2348
2302
  return(error != 0);
2349
2303
}
2350
2304
 
2393
2347
 
2394
2348
bool subselect_uniquesubquery_engine::copy_ref_key()
2395
2349
{
2396
 
  for (StoredKey **copy= tab->ref.key_copy ; *copy ; copy++)
 
2350
  for (store_key **copy= tab->ref.key_copy ; *copy ; copy++)
2397
2351
  {
2398
 
    StoredKey::store_key_result store_res= (*copy)->copy();
 
2352
    enum store_key::store_key_result store_res;
 
2353
    store_res= (*copy)->copy();
2399
2354
    tab->ref.key_err= store_res;
2400
2355
 
2401
2356
    /*
2424
2379
 
2425
2380
    /*
2426
2381
      Check if the error is equal to STORE_KEY_FATAL. This is not expressed
2427
 
      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
2428
2383
      boolean and we want to detect both true and STORE_KEY_FATAL from the
2429
2384
      space of the union of the values of [true, false] and
2430
 
      StoredKey::store_key_result.
 
2385
      store_key::store_key_result.
2431
2386
      TODO: fix the variable an return types.
2432
2387
    */
2433
 
    if (store_res == StoredKey::STORE_KEY_FATAL)
 
2388
    if (store_res == store_key::STORE_KEY_FATAL)
2434
2389
    {
2435
2390
      /*
2436
2391
       Error converting the left IN operand to the column type of the right
2497
2452
  if (null_keypart)
2498
2453
    return(scan_table());
2499
2454
 
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],
 
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],
2512
2458
                                     tab->ref.key_buff,
2513
2459
                                     make_prev_keypart_map(tab->ref.key_parts),
2514
2460
                                     HA_READ_KEY_EXACT);
2619
2565
  if (null_keypart)
2620
2566
    return(scan_table());
2621
2567
 
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],
 
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],
2633
2571
                                     tab->ref.key_buff,
2634
2572
                                     make_prev_keypart_map(tab->ref.key_parts),
2635
2573
                                     HA_READ_KEY_EXACT);
2653
2591
            ((Item_in_subselect *) item)->value= 1;
2654
2592
          break;
2655
2593
        }
2656
 
        error= table->cursor->index_next_same(table->record[0],
 
2594
        error= table->file->index_next_same(table->record[0],
2657
2595
                                            tab->ref.key_buff,
2658
2596
                                            tab->ref.key_length);
2659
2597
        if (error && error != HA_ERR_END_OF_FILE)
2690
2628
}
2691
2629
 
2692
2630
 
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);
 
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;
2714
2640
}
2715
2641
 
2716
2642
 
2774
2700
void subselect_uniquesubquery_engine::print(String *str,
2775
2701
                                            enum_query_type query_type)
2776
2702
{
2777
 
  char *table_name= const_cast<char *>(tab->table->getShare()->getTableName());
 
2703
  char *table_name= tab->table->s->table_name.str;
2778
2704
  str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2779
2705
  tab->ref.items[0]->print(str, query_type);
2780
2706
  str->append(STRING_WITH_LEN(" in "));
2781
 
  if (tab->table->getShare()->isTemporaryCategory())
 
2707
  if (tab->table->s->table_category == TABLE_CATEGORY_TEMPORARY)
2782
2708
  {
2783
2709
    /*
2784
2710
      Temporary tables' names change across runs, so they can't be used for
2787
2713
    str->append(STRING_WITH_LEN("<temporary table>"));
2788
2714
  }
2789
2715
  else
2790
 
    str->append(table_name, tab->table->getShare()->getTableNameSize());
2791
 
  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;
2792
2718
  str->append(STRING_WITH_LEN(" on "));
2793
2719
  str->append(key_info->name);
2794
2720
  if (cond)
2811
2737
  for (uint32_t i= 0; i < key_info->key_parts; i++)
2812
2738
    tab->ref.items[i]->print(str);
2813
2739
  str->append(STRING_WITH_LEN(" in "));
2814
 
  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);
2815
2741
  str->append(STRING_WITH_LEN(" on "));
2816
2742
  str->append(key_info->name);
2817
2743
  if (cond)
2829
2755
  str->append(STRING_WITH_LEN("<index_lookup>("));
2830
2756
  tab->ref.items[0]->print(str, query_type);
2831
2757
  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;
 
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;
2834
2760
  str->append(STRING_WITH_LEN(" on "));
2835
2761
  str->append(key_info->name);
2836
2762
  if (check_null)
2990
2916
    temporary table has one hash index on all its columns.
2991
2917
  - Create a new result sink that sends the result stream of the subquery to
2992
2918
    the temporary table,
2993
 
  - 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
2994
2920
    lookups into the indexed temporary table.
2995
2921
 
2996
2922
  @notice:
3007
2933
  select_union  *tmp_result_sink;
3008
2934
  /* The table into which the subquery is materialized. */
3009
2935
  Table         *tmp_table;
3010
 
  KeyInfo           *tmp_key; /* The only index on the temporary table. */
 
2936
  KEY           *tmp_key; /* The only index on the temporary table. */
3011
2937
  uint32_t          tmp_key_parts; /* Number of keyparts in tmp_key. */
3012
2938
  Item_in_subselect *item_in= (Item_in_subselect *) item;
3013
2939
 
3020
2946
  */
3021
2947
  if (!(tmp_result_sink= new select_union))
3022
2948
    return(true);
3023
 
 
3024
2949
  if (tmp_result_sink->create_result_table(
3025
2950
                         session, tmp_columns, true,
3026
2951
                         session->options | TMP_TABLE_ALL_COLUMNS,
3027
 
                         "materialized subselect"))
 
2952
                         "materialized subselect", true))
3028
2953
    return(true);
3029
2954
 
3030
2955
  tmp_table= tmp_result_sink->table;
3038
2963
     table since it will not be used, and tell the caller we failed to
3039
2964
     initialize the engine.
3040
2965
  */
3041
 
  if (tmp_table->getShare()->sizeKeys() == 0)
 
2966
  if (tmp_table->s->keys == 0)
3042
2967
  {
3043
 
    assert(tmp_table->getShare()->db_type() == myisam_engine);
 
2968
    assert(tmp_table->s->db_type() == myisam_engine);
3044
2969
    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;
 
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);
3049
2974
    delete result;
3050
2975
    result= NULL;
3051
2976
    return(true);
3056
2981
    Make sure there is only one index on the temp table, and it doesn't have
3057
2982
    the extra key part created when s->uniques > 0.
3058
2983
  */
3059
 
  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);
3060
2985
 
3061
2986
 
3062
2987
  /* 2. Create/initialize execution related objects. */
3063
2988
 
3064
2989
  /*
3065
 
    Create and initialize the JoinTable that represents an index lookup
 
2990
    Create and initialize the JOIN_TAB that represents an index lookup
3066
2991
    plan operator into the materialized subquery result. Notice that:
3067
 
    - 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
3068
2993
    - here we initialize only those members that are used by
3069
2994
      subselect_uniquesubquery_engine, so these objects are incomplete.
3070
2995
  */
3071
 
  if (!(tab= (JoinTable*) session->getMemRoot()->allocate(sizeof(JoinTable))))
 
2996
  if (!(tab= (JOIN_TAB*) session->alloc(sizeof(JOIN_TAB))))
3072
2997
    return(true);
3073
 
  new (tab) JoinTable();
3074
2998
  tab->table= tmp_table;
3075
2999
  tab->ref.key= 0; /* The only temp table index. */
3076
3000
  tab->ref.key_length= tmp_key->key_length;
3077
3001
  if (!(tab->ref.key_buff=
3078
3002
        (unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3079
3003
      !(tab->ref.key_copy=
3080
 
        (StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
 
3004
        (store_key**) session->alloc((sizeof(store_key*) *
3081
3005
                                  (tmp_key_parts + 1)))) ||
3082
3006
      !(tab->ref.items=
3083
 
        (Item**) session->getMemRoot()->allocate(sizeof(Item*) * tmp_key_parts)))
 
3007
        (Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
3084
3008
    return(true);
3085
3009
 
3086
 
  KeyPartInfo *cur_key_part= tmp_key->key_part;
3087
 
  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;
3088
3012
  unsigned char *cur_ref_buff= tab->ref.key_buff;
3089
3013
 
3090
3014
  for (uint32_t i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3137
3061
{
3138
3062
  delete result;
3139
3063
  if (tab)
3140
 
  {
3141
 
    tab->table= NULL;
3142
 
  }
 
3064
    tab->table->free_tmp_table(session);
3143
3065
}
3144
3066
 
3145
3067
 
3147
3069
  Cleanup performed after each PS execution.
3148
3070
 
3149
3071
  @detail
3150
 
  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.
3151
3073
*/
3152
3074
 
3153
3075
void subselect_hash_sj_engine::cleanup()
3185
3107
    session->lex->current_select= materialize_engine->select_lex;
3186
3108
    if ((res= materialize_join->optimize()))
3187
3109
      goto err;
3188
 
 
3189
 
    if (materialize_engine->save_join_if_explain())
3190
 
      goto err;
3191
 
 
3192
3110
    materialize_join->exec();
3193
3111
    if ((res= test(materialize_join->error || session->is_fatal_error)))
3194
3112
      goto err;
3196
3114
    /*
3197
3115
      TODO:
3198
3116
      - 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
 
3117
        we need to add new functionality to JOIN::join_free that can unlock
3200
3118
        all tables in a subquery (and all its subqueries).
3201
3119
      - The temp table used for grouping in the subquery can be freed
3202
3120
        immediately after materialization (yet it's done together with
3209
3127
      statistics, then we test if the temporary table for the query result is
3210
3128
      empty.
3211
3129
    */
3212
 
    tab->table->cursor->info(HA_STATUS_VARIABLE);
3213
 
    if (!tab->table->cursor->stats.records)
 
3130
    tab->table->file->info(HA_STATUS_VARIABLE);
 
3131
    if (!tab->table->file->stats.records)
3214
3132
    {
3215
3133
      empty_result_set= true;
3216
3134
      item_in->value= false;
3251
3169
           "<the access method for lookups is not yet created>"
3252
3170
         ));
3253
3171
}
3254
 
 
3255
 
} /* namespace drizzled */