23
23
- add function from mysql_select that use JOIN* as parameter to JOIN
24
24
methods (sql_select.h/sql_select.cc)
26
#include <drizzled/server_includes.h>
27
#include <drizzled/sql_select.h>
28
#include <drizzled/error.h>
29
#include <drizzled/item/subselect.h>
30
#include <drizzled/item/cmpfunc.h>
31
#include <drizzled/cached_item.h>
32
#include <drizzled/check_stack_overrun.h>
27
#ifdef USE_PRAGMA_IMPLEMENTATION
28
#pragma implementation // gcc: Class implementation
31
#include "mysql_priv.h"
32
#include "sql_select.h"
34
34
inline Item * and_items(Item* cond, Item *item)
39
39
Item_subselect::Item_subselect():
40
Item_result_field(), value_assigned(0), session(0), substitution(0),
40
Item_result_field(), value_assigned(0), thd(0), substitution(0),
41
41
engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
42
42
const_item_cache(1), engine_changed(0), changed(0),
43
43
is_correlated(false)
149
149
Item_subselect::trans_res
150
Item_subselect::select_transformer(JOIN *join __attribute__((unused)))
150
Item_subselect::select_transformer(JOIN *join __attribute__((__unused__)))
156
bool Item_subselect::fix_fields(Session *session_param, Item **ref)
156
bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
158
char const *save_where= session_param->where;
158
char const *save_where= thd_param->where;
162
162
assert(fixed == 0);
163
engine->set_session((session= session_param));
163
engine->set_thd((thd= thd_param));
165
if (check_stack_overrun(session, STACK_MIN_SIZE, (unsigned char*)&res))
165
if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res))
168
168
res= engine->prepare();
193
193
if (have_to_be_excluded)
194
194
engine->exclude();
196
session->where= "checking transformed subquery";
196
thd->where= "checking transformed subquery";
197
197
if (!(*ref)->fixed)
198
ret= (*ref)->fix_fields(session, ref);
199
session->where= save_where;
198
ret= (*ref)->fix_fields(thd, ref);
199
thd->where= save_where;
202
202
// Is it one field subselect?
247
247
if (item->walk(processor, walk_subquery, argument))
250
for (order= (order_st*) lex->order_list.first ; order; order= order->next)
250
for (order= (ORDER*) lex->order_list.first ; order; order= order->next)
252
252
if ((*order->item)->walk(processor, walk_subquery, argument))
255
for (order= (order_st*) lex->group_list.first ; order; order= order->next)
255
for (order= (ORDER*) lex->group_list.first ; order; order= order->next)
257
257
if ((*order->item)->walk(processor, walk_subquery, argument))
347
347
return const_item_cache;
350
Item *Item_subselect::get_tmp_table_item(Session *session_arg)
350
Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
352
352
if (!with_sum_func && !const_item())
353
353
return new Item_field(result_field);
354
return copy_or_same(session_arg);
354
return copy_or_same(thd_arg);
357
357
void Item_subselect::update_used_tables()
404
Item_maxmin_subselect::Item_maxmin_subselect(Session *session_param,
404
Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,
405
405
Item_subselect *parent,
406
406
st_select_lex *select_lex,
499
499
have_to_be_excluded= 1;
500
if (session->lex->describe)
500
if (thd->lex->describe)
502
char warn_buff[DRIZZLE_ERRMSG_SIZE];
502
char warn_buff[MYSQL_ERRMSG_SIZE];
503
503
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
504
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
504
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
505
505
ER_SELECT_REDUCED, warn_buff);
507
507
substitution= select_lex->item_list.head();
510
510
'upper' select is not really dependent => we remove this dependence
512
512
substitution->walk(&Item::remove_dependence_processor, 0,
513
(unsigned char *) select_lex->outer_select());
513
(uchar *) select_lex->outer_select());
514
514
return(RES_REDUCE);
520
void Item_singlerow_subselect::store(uint32_t i, Item *item)
520
void Item_singlerow_subselect::store(uint i, Item *item)
522
522
row[i]->store(item);
559
559
maybe_null= engine->may_be_null();
562
uint32_t Item_singlerow_subselect::cols()
562
uint Item_singlerow_subselect::cols()
564
564
return engine->cols();
567
bool Item_singlerow_subselect::check_cols(uint32_t c)
567
bool Item_singlerow_subselect::check_cols(uint c)
569
569
if (c != engine->cols())
741
741
max_columns= engine->cols();
742
742
/* We need only 1 row to determine existence */
743
unit->global_parameters->select_limit= new Item_int((int32_t) 1);
743
unit->global_parameters->select_limit= new Item_int((int32) 1);
746
746
double Item_exists_subselect::val_real()
880
880
Must mark the IN predicate as NULL so as to make sure an enclosing NOT
881
predicate will return false. See the comments in
881
predicate will return false. See the comments in
882
882
subselect_uniquesubquery_engine::copy_ref_key for further details.
923
923
Rewrite a single-column subquery using rule-based approach. The subquery
925
925
oe $cmp$ (SELECT ie FROM ... WHERE subq_where ... HAVING subq_having)
927
927
First, try to convert the subquery to scalar-result subquery in one of
930
930
- oe $cmp$ (SELECT MAX(...) ) // handled by Item_singlerow_subselect
931
931
- oe $cmp$ <max>(SELECT ...) // handled by Item_maxmin_subselect
933
933
If that fails, the subquery will be handled with class Item_in_optimizer.
934
934
There are two possibilites:
935
935
- If the subquery execution method is materialization, then the subquery is
948
948
Item_subselect::trans_res
949
949
Item_in_subselect::single_value_transformer(JOIN *join,
950
const Comp_creator *func)
952
952
SELECT_LEX *select_lex= join->select_lex;
1015
1015
it.replace(item);
1018
save_allow_sum_func= session->lex->allow_sum_func;
1019
session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
1018
save_allow_sum_func= thd->lex->allow_sum_func;
1019
thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
1021
1021
Item_sum_(max|min) can't substitute other item => we can use 0 as
1022
1022
reference, also Item_sum_(max|min) can't be fixed after creation, so
1023
1023
we do not check item->fixed
1025
if (item->fix_fields(session, 0))
1025
if (item->fix_fields(thd, 0))
1026
1026
return(RES_ERROR);
1027
session->lex->allow_sum_func= save_allow_sum_func;
1027
thd->lex->allow_sum_func= save_allow_sum_func;
1028
1028
/* we added aggregate function => we have to change statistic */
1029
count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
1029
count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
1032
1032
subs= new Item_singlerow_subselect(select_lex);
1036
1036
Item_maxmin_subselect *item;
1037
subs= item= new Item_maxmin_subselect(session, this, select_lex, func->l_op());
1037
subs= item= new Item_maxmin_subselect(thd, this, select_lex, func->l_op());
1038
1038
if (upper_item)
1039
1039
upper_item->set_sub_test(item);
1049
1049
SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
1050
1050
substitution= optimizer;
1052
SELECT_LEX *current= session->lex->current_select, *up;
1052
SELECT_LEX *current= thd->lex->current_select, *up;
1054
session->lex->current_select= up= current->return_after_parsing();
1054
thd->lex->current_select= up= current->return_after_parsing();
1055
1055
//optimizer never use Item **ref => we can pass 0 as parameter
1056
if (!optimizer || optimizer->fix_left(session, 0))
1056
if (!optimizer || optimizer->fix_left(thd, 0))
1058
session->lex->current_select= current;
1058
thd->lex->current_select= current;
1059
1059
return(RES_ERROR);
1061
session->lex->current_select= current;
1061
thd->lex->current_select= current;
1064
1064
As far as Item_ref_in_optimizer do not substitute itself on fix_fields
1075
1075
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1077
if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool))))
1077
if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool))))
1078
1078
return(RES_ERROR);
1079
1079
pushed_cond_guards[0]= true;
1100
1100
- If the subquery has aggregates, GROUP BY, or HAVING, convert to
1102
SELECT ie FROM ... HAVING subq_having AND
1102
SELECT ie FROM ... HAVING subq_having AND
1103
1103
trigcond(oe $cmp$ ref_or_null_helper<ie>)
1105
1105
the addition is wrapped into trigger only when we want to distinguish
1106
1106
between NULL and false results.
1130
1130
Item_subselect::trans_res
1131
Item_in_subselect::single_value_in_to_exists_transformer(JOIN * join, const Comp_creator *func)
1131
Item_in_subselect::single_value_in_to_exists_transformer(JOIN * join, Comp_creator *func)
1133
1133
SELECT_LEX *select_lex= join->select_lex;
1146
1146
this->full_name()));
1147
1147
if (!abort_on_null && left_expr->maybe_null)
1150
1150
We can encounter "NULL IN (SELECT ...)". Wrap the added condition
1151
1151
within a trig_cond.
1153
1153
item= new Item_func_trig_cond(item, get_cond_guard(0));
1157
1157
AND and comparison functions can't be changed during fix_fields()
1158
1158
we can assign select_lex->having here, and pass 0 as last
1166
1166
we do not check join->having->fixed, because Item_and (from and_items)
1167
1167
or comparison function (from func->create) can't be fixed after creation
1169
tmp= join->having->fix_fields(session, 0);
1169
tmp= join->having->fix_fields(thd, 0);
1170
1170
select_lex->having_fix_field= 0;
1172
1172
return(RES_ERROR);
1185
1185
MY_INT64_NUM_DECIMAL_DIGITS));
1186
1186
select_lex->ref_pointer_array[0]= select_lex->item_list.head();
1188
1188
item= func->create(expr, item);
1189
1189
if (!abort_on_null && orig_item->maybe_null)
1208
1208
and_items) or comparison function (from func->create) can't be
1209
1209
fixed after creation
1211
tmp= join->having->fix_fields(session, 0);
1211
tmp= join->having->fix_fields(thd, 0);
1212
1212
select_lex->having_fix_field= 0;
1214
1214
return(RES_ERROR);
1215
1215
item= new Item_cond_or(item,
1216
1216
new Item_func_isnull(orig_item));
1219
1219
If we may encounter NULL IN (SELECT ...) and care whether subquery
1220
1220
result is NULL or false, wrap condition in a trig_cond.
1242
1242
we do not check join->conds->fixed, because Item_and can't be fixed
1245
if (join->conds->fix_fields(session, 0))
1245
if (join->conds->fix_fields(thd, 0))
1246
1246
return(RES_ERROR);
1270
1270
new_having->name= (char*)in_having_cond;
1271
1271
select_lex->having= join->having= new_having;
1272
1272
select_lex->having_fix_field= 1;
1275
1275
we do not check join->having->fixed, because comparison function
1276
1276
(from func->create) can't be fixed after creation
1278
tmp= join->having->fix_fields(session, 0);
1278
tmp= join->having->fix_fields(thd, 0);
1279
1279
select_lex->having_fix_field= 0;
1281
1281
return(RES_ERROR);
1287
1287
// fix_field of item will be done in time of substituting
1288
1288
substitution= item;
1289
1289
have_to_be_excluded= 1;
1290
if (session->lex->describe)
1290
if (thd->lex->describe)
1292
char warn_buff[DRIZZLE_ERRMSG_SIZE];
1292
char warn_buff[MYSQL_ERRMSG_SIZE];
1293
1293
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
1294
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1294
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1295
1295
ER_SELECT_REDUCED, warn_buff);
1297
1297
return(RES_REDUCE);
1307
1307
Item_in_subselect::row_value_transformer(JOIN *join)
1309
1309
SELECT_LEX *select_lex= join->select_lex;
1310
uint32_t cols_num= left_expr->cols();
1310
uint cols_num= left_expr->cols();
1312
1312
if (select_lex->item_list.elements != left_expr->cols())
1325
1325
SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
1326
1326
substitution= optimizer;
1328
SELECT_LEX *current= session->lex->current_select, *up;
1329
session->lex->current_select= up= current->return_after_parsing();
1328
SELECT_LEX *current= thd->lex->current_select, *up;
1329
thd->lex->current_select= up= current->return_after_parsing();
1330
1330
//optimizer never use Item **ref => we can pass 0 as parameter
1331
if (!optimizer || optimizer->fix_left(session, 0))
1331
if (!optimizer || optimizer->fix_left(thd, 0))
1333
session->lex->current_select= current;
1333
thd->lex->current_select= current;
1334
1334
return(RES_ERROR);
1337
1337
// we will refer to upper level cache array => we have to save it in PS
1338
1338
optimizer->keep_top_level_cache();
1340
session->lex->current_select= current;
1340
thd->lex->current_select= current;
1341
1341
master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1343
1343
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1345
if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool) *
1345
if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool) *
1346
1346
left_expr->cols())))
1347
1347
return(RES_ERROR);
1348
for (uint32_t i= 0; i < cols_num; i++)
1348
for (uint i= 0; i < cols_num; i++)
1349
1349
pushed_cond_guards[i]= true;
1386
1386
SELECT_LEX *select_lex= join->select_lex;
1387
1387
Item *having_item= 0;
1388
uint32_t cols_num= left_expr->cols();
1388
uint cols_num= left_expr->cols();
1389
1389
bool is_having_used= (join->having || select_lex->with_sum_func ||
1390
1390
select_lex->group_list.first ||
1391
1391
!select_lex->table_list.elements);
1407
1407
TODO: say here explicitly if the order of AND parts matters or not.
1409
1409
Item *item_having_part2= 0;
1410
for (uint32_t i= 0; i < cols_num; i++)
1410
for (uint i= 0; i < cols_num; i++)
1412
1412
assert((left_expr->fixed && select_lex->ref_pointer_array[i]->fixed) ||
1413
1413
(select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
1443
1443
return(RES_ERROR);
1445
1445
having_item= and_items(having_item, col_item);
1447
Item *item_nnull_test=
1447
Item *item_nnull_test=
1448
1448
new Item_is_not_null_test(this,
1449
1449
new Item_ref(&select_lex->context,
1485
1485
Item *where_item= 0;
1486
for (uint32_t i= 0; i < cols_num; i++)
1486
for (uint i= 0; i < cols_num; i++)
1488
1488
Item *item, *item_isnull;
1489
1489
assert((left_expr->fixed && select_lex->ref_pointer_array[i]->fixed) ||
1512
1512
Item *having_col_item=
1513
1513
new Item_is_not_null_test(this,
1515
Item_ref(&select_lex->context,
1515
Item_ref(&select_lex->context,
1516
1516
select_lex->ref_pointer_array + i,
1517
1517
(char *)"<no matter>",
1518
1518
(char *)"<list ref>"));
1521
1521
item_isnull= new
1522
1522
Item_func_isnull(new
1523
1523
Item_direct_ref(&select_lex->context,
1551
1551
select_lex->where= join->conds= and_items(join->conds, where_item);
1552
1552
select_lex->where->top_level_item();
1553
if (join->conds->fix_fields(session, 0))
1553
if (join->conds->fix_fields(thd, 0))
1554
1554
return(RES_ERROR);
1556
1556
if (having_item)
1566
1566
argument (reference) to fix_fields()
1568
1568
select_lex->having_fix_field= 1;
1569
res= join->having->fix_fields(session, 0);
1569
res= join->having->fix_fields(thd, 0);
1570
1570
select_lex->having_fix_field= 0;
1581
1581
Item_subselect::trans_res
1582
1582
Item_in_subselect::select_transformer(JOIN *join)
1584
return select_in_like_transformer(join, Eq_creator::instance());
1584
return select_in_like_transformer(join, &eq_creator);
1609
1609
Item_subselect::trans_res
1610
Item_in_subselect::select_in_like_transformer(JOIN *join, const Comp_creator *func)
1610
Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
1612
SELECT_LEX *current= session->lex->current_select, *up;
1613
const char *save_where= session->where;
1612
SELECT_LEX *current= thd->lex->current_select, *up;
1613
const char *save_where= thd->where;
1614
1614
Item_subselect::trans_res res= RES_ERROR;
1619
1619
IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
1620
order_st BY clause becomes meaningless thus we drop it here.
1620
ORDER BY clause becomes meaningless thus we drop it here.
1622
1622
SELECT_LEX *sl= current->master_unit()->first_select();
1623
1623
for (; sl; sl= sl->next_select())
1647
session->lex->current_select= up= current->return_after_parsing();
1647
thd->lex->current_select= up= current->return_after_parsing();
1648
1648
result= (!left_expr->fixed &&
1649
left_expr->fix_fields(session, optimizer->arguments()));
1649
left_expr->fix_fields(thd, optimizer->arguments()));
1650
1650
/* fix_fields can change reference to left_expr, we need reassign it */
1651
1651
left_expr= optimizer->arguments()[0];
1653
session->lex->current_select= current;
1653
thd->lex->current_select= current;
1702
bool Item_in_subselect::fix_fields(Session *session_arg, Item **ref)
1702
bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
1704
1704
bool result = 0;
1706
1706
if (exec_method == SEMI_JOIN)
1707
1707
return !( (*ref)= new Item_int(1));
1709
return result || Item_subselect::fix_fields(session_arg, ref);
1709
if (thd_arg->lex->view_prepare_mode && left_expr && !left_expr->fixed)
1710
result = left_expr->fix_fields(thd_arg, &left_expr);
1712
return result || Item_subselect::fix_fields(thd_arg, ref);
1747
1750
old_engine= (subselect_single_select_engine*) engine;
1749
if (!(new_engine= new subselect_hash_sj_engine(session, this,
1752
if (!(new_engine= new subselect_hash_sj_engine(thd, this,
1750
1753
old_engine)) ||
1751
1754
new_engine->init_permanent(unit->get_unit_column_types()))
1761
1764
exec_method= NOT_TRANSFORMED;
1762
1765
if (left_expr->cols() == 1)
1763
1766
trans_res= single_value_in_to_exists_transformer(old_engine->join,
1764
Eq_creator::instance());
1766
1769
trans_res= row_value_in_to_exists_transformer(old_engine->join);
1767
1770
res= (trans_res != Item_subselect::RES_OK);
1832
1835
if (!(left_expr_cache= new List<Cached_item>))
1835
for (uint32_t i= 0; i < left_expr->cols(); i++)
1838
for (uint i= 0; i < left_expr->cols(); i++)
1837
Cached_item *cur_item_cache= new_Cached_item(session,
1840
Cached_item *cur_item_cache= new_Cached_item(thd,
1838
1841
left_expr->element_index(i),
1839
1842
use_result_field);
1840
1843
if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
2004
join= new JOIN(session, select_lex->item_list,
2007
join= new JOIN(thd, select_lex->item_list,
2005
2008
select_lex->options | SELECT_NO_UNLOCK, result);
2006
2009
if (!join || !result)
2007
2010
return 1; /* Fatal error is set already. */
2009
SELECT_LEX *save_select= session->lex->current_select;
2010
session->lex->current_select= select_lex;
2012
SELECT_LEX *save_select= thd->lex->current_select;
2013
thd->lex->current_select= select_lex;
2011
2014
if (join->prepare(&select_lex->ref_pointer_array,
2012
(TableList*) select_lex->table_list.first,
2015
(TABLE_LIST*) select_lex->table_list.first,
2013
2016
select_lex->with_wild,
2014
2017
select_lex->where,
2015
2018
select_lex->order_list.elements +
2016
2019
select_lex->group_list.elements,
2017
(order_st*) select_lex->order_list.first,
2018
(order_st*) select_lex->group_list.first,
2020
(ORDER*) select_lex->order_list.first,
2021
(ORDER*) select_lex->group_list.first,
2019
2022
select_lex->having,
2020
(order_st*) 0, select_lex,
2023
(ORDER*) 0, select_lex,
2021
2024
select_lex->master_unit()))
2023
session->lex->current_select= save_select;
2026
thd->lex->current_select= save_select;
2027
2030
int subselect_union_engine::prepare()
2029
return unit->prepare(session, result, SELECT_NO_UNLOCK);
2032
return unit->prepare(thd, result, SELECT_NO_UNLOCK);
2032
2035
int subselect_uniquesubquery_engine::prepare()
2055
2058
bool subselect_single_select_engine::no_rows()
2057
2060
return !item->assigned();
2062
makes storage for the output values for the subquery and calcuates
2065
makes storage for the output values for the subquery and calcuates
2063
2066
their data and column types and their nullability.
2065
2068
void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
2067
2070
Item *sel_item;
2068
2071
List_iterator_fast<Item> li(item_list);
2069
2072
res_type= STRING_RESULT;
2070
res_field_type= DRIZZLE_TYPE_VARCHAR;
2071
for (uint32_t i= 0; (sel_item= li++); i++)
2073
res_field_type= MYSQL_TYPE_STRING;
2074
for (uint i= 0; (sel_item= li++); i++)
2073
2076
item->max_length= sel_item->max_length;
2074
2077
res_type= sel_item->result_type();
2123
2126
int subselect_single_select_engine::exec()
2125
char const *save_where= session->where;
2126
SELECT_LEX *save_select= session->lex->current_select;
2127
session->lex->current_select= select_lex;
2128
char const *save_where= thd->where;
2129
SELECT_LEX *save_select= thd->lex->current_select;
2130
thd->lex->current_select= select_lex;
2128
2131
if (!join->optimized)
2130
2133
SELECT_LEX_UNIT *unit= select_lex->master_unit();
2132
2135
unit->set_limit(unit->global_parameters);
2133
2136
if (join->flatten_subqueries())
2135
session->is_fatal_error= true;
2138
thd->is_fatal_error= true;
2138
2141
if (join->optimize())
2140
session->where= save_where;
2143
thd->where= save_where;
2142
session->lex->current_select= save_select;
2145
thd->lex->current_select= save_select;
2143
2146
return(join->error ? join->error : 1);
2145
if (!select_lex->uncacheable && session->lex->describe &&
2146
!(join->select_options & SELECT_DESCRIBE) &&
2148
if (!select_lex->uncacheable && thd->lex->describe &&
2149
!(join->select_options & SELECT_DESCRIBE) &&
2147
2150
join->need_tmp && item->const_item())
2188
2191
pushed down into the subquery. Those optimizations are ref[_or_null]
2189
2192
acceses. Change them to be full table scans.
2191
for (uint32_t i=join->const_tables ; i < join->tables ; i++)
2194
for (uint i=join->const_tables ; i < join->tables ; i++)
2193
2196
JOIN_TAB *tab=join->join_tab+i;
2194
2197
if (tab && tab->keyuse)
2196
for (uint32_t i= 0; i < tab->ref.key_parts; i++)
2199
for (uint i= 0; i < tab->ref.key_parts; i++)
2198
2201
bool *cond_guard= tab->ref.cond_guards[i];
2199
2202
if (cond_guard && !*cond_guard)
2203
2206
tab->save_read_record= tab->read_record.read_record;
2204
2207
tab->read_first_record= init_read_record_seq;
2205
2208
tab->read_record.record= tab->table->record[0];
2206
tab->read_record.session= join->session;
2209
tab->read_record.thd= join->thd;
2207
2210
tab->read_record.ref_length= tab->table->file->ref_length;
2208
2211
*(last_changed_tab++)= tab;
2221
2224
JOIN_TAB *tab= *ptab;
2222
2225
tab->read_record.record= 0;
2223
2226
tab->read_record.ref_length= 0;
2224
tab->read_first_record= tab->save_read_first_record;
2227
tab->read_first_record= tab->save_read_first_record;
2225
2228
tab->read_record.read_record= tab->save_read_record;
2228
session->where= save_where;
2229
session->lex->current_select= save_select;
2230
return(join->error||session->is_fatal_error);
2231
thd->where= save_where;
2232
thd->lex->current_select= save_select;
2233
return(join->error||thd->is_fatal_error);
2232
session->where= save_where;
2233
session->lex->current_select= save_select;
2235
thd->where= save_where;
2236
thd->lex->current_select= save_select;
2237
2240
int subselect_union_engine::exec()
2239
char const *save_where= session->where;
2242
char const *save_where= thd->where;
2240
2243
int res= unit->exec();
2241
session->where= save_where;
2244
thd->where= save_where;
2247
2250
Search for at least one row satisfying select condition
2250
2253
subselect_uniquesubquery_engine::scan_table()
2253
2256
Scan the table using sequential access until we find at least one row
2254
2257
satisfying select condition.
2256
2259
The caller must set this->empty_result_set=false before calling this
2257
2260
function. This function will set it to true if it finds a matching row.
2264
2267
int subselect_uniquesubquery_engine::scan_table()
2267
Table *table= tab->table;
2270
TABLE *table= tab->table;
2269
2272
if (table->file->inited)
2270
2273
table->file->ha_index_end();
2272
2275
table->file->ha_rnd_init(1);
2273
2276
table->file->extra_opt(HA_EXTRA_CACHE,
2274
current_session->variables.read_buff_size);
2277
current_thd->variables.read_buff_size);
2275
2278
table->null_row= 0;
2278
2281
error=table->file->rnd_next(table->record[0]);
2279
2282
if (error && error != HA_ERR_END_OF_FILE)
2281
error= table->report_error(error);
2284
error= report_error(table, error);
2284
2287
/* No more rows */
2375
Check if the error is equal to STORE_KEY_FATAL. This is not expressed
2376
using the store_key::store_key_result enum because ref.key_err is a
2377
boolean and we want to detect both true and STORE_KEY_FATAL from the
2378
space of the union of the values of [true, false] and
2379
store_key::store_key_result.
2378
Check if the error is equal to STORE_KEY_FATAL. This is not expressed
2379
using the store_key::store_key_result enum because ref.key_err is a
2380
boolean and we want to detect both true and STORE_KEY_FATAL from the
2381
space of the union of the values of [true, false] and
2382
store_key::store_key_result.
2380
2383
TODO: fix the variable an return types.
2382
2385
if (store_res == store_key::STORE_KEY_FATAL)
2385
2388
Error converting the left IN operand to the column type of the right
2388
2391
tab->table->status= STATUS_NOT_FOUND;
2404
2407
If some part of the lookup key is NULL, then we're evaluating
2405
2408
NULL IN (SELECT ... )
2406
2409
This is a special case, we don't need to search for NULL in the table,
2407
instead, the result value is
2410
instead, the result value is
2408
2411
- NULL if select produces empty row set
2409
2412
- false otherwise.
2411
2414
In some cases (IN subselect is a top level item, i.e. abort_on_null==true)
2412
2415
the caller doesn't distinguish between NULL and false result and we just
2414
Otherwise we make a full table scan to see if there is at least one
2417
Otherwise we make a full table scan to see if there is at least one
2417
2420
The result of this function (info about whether a row was found) is
2418
2421
stored in this->empty_result_set.
2423
2426
true - an error occured while scanning
2426
2429
int subselect_uniquesubquery_engine::exec()
2429
Table *table= tab->table;
2432
TABLE *table= tab->table;
2430
2433
empty_result_set= true;
2431
2434
table->status= 0;
2433
2436
/* TODO: change to use of 'full_scan' here? */
2434
2437
if (copy_ref_key())
2436
2439
if (table->status)
2439
We know that there will be no rows even if we scan.
2442
We know that there will be no rows even if we scan.
2440
2443
Can be set in copy_ref_key.
2442
2445
((Item_in_subselect *) item)->value= 0;
2479
2482
subselect_indexsubquery_engine:exec()
2483
2486
The engine is used to resolve subqueries in form
2485
oe IN (SELECT key FROM tbl WHERE subq_where)
2488
oe IN (SELECT key FROM tbl WHERE subq_where)
2487
The value of the predicate is calculated as follows:
2490
The value of the predicate is calculated as follows:
2488
2491
1. If oe IS NULL, this is a special case, do a full table scan on
2489
table tbl and search for row that satisfies subq_where. If such
2492
table tbl and search for row that satisfies subq_where. If such
2490
2493
row is found, return NULL, otherwise return false.
2491
2494
2. Make an index lookup via key=oe, search for a row that satisfies
2492
2495
subq_where. If found, return true.
2493
3. If check_null==true, make another lookup via key=NULL, search for a
2496
3. If check_null==true, make another lookup via key=NULL, search for a
2494
2497
row that satisfies subq_where. If found, return NULL, otherwise
2498
2501
The step #1 can be optimized further when the index has several key
2499
2502
parts. Consider a subquery:
2501
2504
(oe1, oe2) IN (SELECT keypart1, keypart2 FROM tbl WHERE subq_where)
2503
2506
and suppose we need to evaluate it for {oe1, oe2}=={const1, NULL}.
2507
2510
SELECT keypart1, keypart2 FROM tbl WHERE subq_where (1)
2509
2512
and checking if it has produced any matching rows, evaluate
2511
2514
SELECT keypart2 FROM tbl WHERE subq_where AND keypart1=const1 (2)
2513
If this query produces a row, the result is NULL (as we're evaluating
2516
If this query produces a row, the result is NULL (as we're evaluating
2514
2517
"(const1, NULL) IN { (const1, X), ... }", which has a value of UNKNOWN,
2515
2518
i.e. NULL). If the query produces no rows, the result is false.
2613
uint32_t subselect_single_select_engine::cols()
2616
uint subselect_single_select_engine::cols()
2615
2618
return select_lex->item_list.elements;
2619
uint32_t subselect_union_engine::cols()
2622
uint subselect_union_engine::cols()
2621
2624
return unit->types.elements;
2625
uint8_t subselect_single_select_engine::uncacheable()
2628
uint8 subselect_single_select_engine::uncacheable()
2627
2630
return select_lex->uncacheable;
2631
uint8_t subselect_union_engine::uncacheable()
2634
uint8 subselect_union_engine::uncacheable()
2633
2636
return unit->uncacheable;
2655
table_map subselect_engine::calc_const_tables(TableList *table)
2658
table_map subselect_engine::calc_const_tables(TABLE_LIST *table)
2657
2660
table_map map= 0;
2658
2661
for (; table; table= table->next_leaf)
2660
Table *tbl= table->table;
2663
TABLE *tbl= table->table;
2661
2664
if (tbl && tbl->const_table)
2662
2665
map|= tbl->map;
2668
2671
table_map subselect_single_select_engine::upper_select_const_tables()
2670
return calc_const_tables((TableList *) select_lex->outer_select()->
2673
return calc_const_tables((TABLE_LIST *) select_lex->outer_select()->
2675
2678
table_map subselect_union_engine::upper_select_const_tables()
2677
return calc_const_tables((TableList *) unit->outer_select()->leaf_tables);
2680
return calc_const_tables((TABLE_LIST *) unit->outer_select()->leaf_tables);
2681
2684
void subselect_single_select_engine::print(String *str,
2682
2685
enum_query_type query_type)
2684
select_lex->print(session, str, query_type);
2687
select_lex->print(thd, str, query_type);
2729
2732
KEY *key_info= tab->table->key_info + tab->ref.key;
2730
2733
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2731
for (uint32_t i= 0; i < key_info->key_parts; i++)
2734
for (uint i= 0; i < key_info->key_parts; i++)
2732
2735
tab->ref.items[i]->print(str);
2733
2736
str->append(STRING_WITH_LEN(" in "));
2734
2737
str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2826
bool subselect_uniquesubquery_engine::change_result(Item_subselect *si __attribute__((unused)),
2827
select_result_interceptor *res __attribute__((unused)))
2829
bool subselect_uniquesubquery_engine::change_result(Item_subselect *si __attribute__((__unused__)),
2830
select_result_interceptor *res __attribute__((__unused__)))
2926
2929
/* The result sink where we will materialize the subquery result. */
2927
2930
select_union *tmp_result_sink;
2928
2931
/* The table into which the subquery is materialized. */
2930
2933
KEY *tmp_key; /* The only index on the temporary table. */
2931
uint32_t tmp_key_parts; /* Number of keyparts in tmp_key. */
2934
uint tmp_key_parts; /* Number of keyparts in tmp_key. */
2932
2935
Item_in_subselect *item_in= (Item_in_subselect *) item;
2934
2937
/* 1. Create/initialize materialization related objects. */
2941
2944
if (!(tmp_result_sink= new select_union))
2943
2946
if (tmp_result_sink->create_result_table(
2944
session, tmp_columns, true,
2945
session->options | TMP_TABLE_ALL_COLUMNS,
2947
thd, tmp_columns, true,
2948
thd->options | TMP_TABLE_ALL_COLUMNS,
2946
2949
"materialized subselect", true))
2964
2967
tmp_table->s->uniques ||
2965
2968
tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
2966
2969
tmp_table->key_info->key_parts > tmp_table->file->max_key_parts());
2967
tmp_table->free_tmp_table(session);
2970
free_tmp_table(thd, tmp_table);
2986
2989
- this JOIN_TAB has no corresponding JOIN (and doesn't need one), and
2987
2990
- here we initialize only those members that are used by
2988
2991
subselect_uniquesubquery_engine, so these objects are incomplete.
2990
if (!(tab= (JOIN_TAB*) session->alloc(sizeof(JOIN_TAB))))
2993
if (!(tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
2992
2995
tab->table= tmp_table;
2993
2996
tab->ref.key= 0; /* The only temp table index. */
2994
2997
tab->ref.key_length= tmp_key->key_length;
2995
2998
if (!(tab->ref.key_buff=
2996
(unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
2999
(uchar*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
2997
3000
!(tab->ref.key_copy=
2998
(store_key**) session->alloc((sizeof(store_key*) *
3001
(store_key**) thd->alloc((sizeof(store_key*) *
2999
3002
(tmp_key_parts + 1)))) ||
3000
3003
!(tab->ref.items=
3001
(Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
3004
(Item**) thd->alloc(sizeof(Item*) * tmp_key_parts)))
3004
3007
KEY_PART_INFO *cur_key_part= tmp_key->key_part;
3005
3008
store_key **ref_key= tab->ref.key_copy;
3006
unsigned char *cur_ref_buff= tab->ref.key_buff;
3008
for (uint32_t i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3009
uchar *cur_ref_buff= tab->ref.key_buff;
3011
for (uint i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3010
3013
tab->ref.items[i]= item_in->left_expr->element_index(i);
3011
3014
int null_count= test(cur_key_part->field->real_maybe_null());
3012
*ref_key= new store_key_item(session, cur_key_part->field,
3015
*ref_key= new store_key_item(thd, cur_key_part->field,
3014
3017
the NULL byte is taken into account in
3015
3018
cur_key_part->store_length, so instead of
3097
3100
if (!is_materialized)
3100
SELECT_LEX *save_select= session->lex->current_select;
3101
session->lex->current_select= materialize_engine->select_lex;
3103
SELECT_LEX *save_select= thd->lex->current_select;
3104
thd->lex->current_select= materialize_engine->select_lex;
3102
3105
if ((res= materialize_join->optimize()))
3104
3107
materialize_join->exec();
3105
if ((res= test(materialize_join->error || session->is_fatal_error)))
3108
if ((res= test(materialize_join->error || thd->is_fatal_error)))