26
26
#include <drizzled/server_includes.h>
27
27
#include <drizzled/sql_select.h>
28
#include <drizzled/drizzled_error_messages.h>
28
#include <drizzled/error.h>
29
#include <drizzled/item/cache.h>
30
#include <drizzled/item/subselect.h>
31
#include <drizzled/item/cmpfunc.h>
32
#include <drizzled/item/ref_null_helper.h>
33
#include <drizzled/cached_item.h>
34
#include <drizzled/check_stack_overrun.h>
35
#include <drizzled/item/ref_null_helper.h>
36
#include <drizzled/item/direct_ref.h>
30
38
inline Item * and_items(Item* cond, Item *item)
35
43
Item_subselect::Item_subselect():
36
Item_result_field(), value_assigned(0), thd(0), substitution(0),
44
Item_result_field(), value_assigned(0), session(0), substitution(0),
37
45
engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
38
46
const_item_cache(1), engine_changed(0), changed(0),
39
47
is_correlated(false)
75
SELECT_LEX *outer_select= unit->outer_select();
83
Select_Lex *outer_select= unit->outer_select();
77
85
do not take into account expression inside aggregate functions because
78
86
they can access original table fields
86
94
engine= new subselect_single_select_engine(select_lex, result, this);
89
SELECT_LEX *upper= unit->outer_select();
97
Select_Lex *upper= unit->outer_select();
90
98
if (upper->parsing_place == IN_HAVING)
91
99
upper->subquery_in_having= 1;
97
105
Item_subselect::get_select_lex()
99
107
return unit->first_select();
145
153
Item_subselect::trans_res
146
Item_subselect::select_transformer(JOIN *join __attribute__((unused)))
154
Item_subselect::select_transformer(JOIN *)
152
bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
160
bool Item_subselect::fix_fields(Session *session_param, Item **ref)
154
char const *save_where= thd_param->where;
162
char const *save_where= session_param->where;
155
163
uint8_t uncacheable;
158
166
assert(fixed == 0);
159
engine->set_thd((thd= thd_param));
167
engine->set_session((session= session_param));
161
if (check_stack_overrun(thd, STACK_MIN_SIZE, (unsigned char*)&res))
169
if (check_stack_overrun(session, STACK_MIN_SIZE, (unsigned char*)&res))
164
172
res= engine->prepare();
189
197
if (have_to_be_excluded)
190
198
engine->exclude();
192
thd->where= "checking transformed subquery";
200
session->where= "checking transformed subquery";
193
201
if (!(*ref)->fixed)
194
ret= (*ref)->fix_fields(thd, ref);
195
thd->where= save_where;
202
ret= (*ref)->fix_fields(session, ref);
203
session->where= save_where;
198
206
// Is it one field subselect?
343
351
return const_item_cache;
346
Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
354
Item *Item_subselect::get_tmp_table_item(Session *session_arg)
348
356
if (!with_sum_func && !const_item())
349
357
return new Item_field(result_field);
350
return copy_or_same(thd_arg);
358
return copy_or_same(session_arg);
353
361
void Item_subselect::update_used_tables()
372
Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex)
380
Item_singlerow_subselect::Item_singlerow_subselect(Select_Lex *select_lex)
373
381
:Item_subselect(), value(0)
375
383
init(select_lex, new select_singlerow_subselect(this));
382
390
Item_singlerow_subselect::invalidate_and_restore_select_lex()
384
st_select_lex *result= get_select_lex();
392
Select_Lex *result= get_select_lex();
389
397
This code restore the parse tree in it's state before the execution of
390
398
Item_singlerow_subselect::Item_singlerow_subselect(),
391
and in particular decouples this object from the SELECT_LEX,
392
so that the SELECT_LEX can be used with a different flavor
399
and in particular decouples this object from the Select_Lex,
400
so that the Select_Lex can be used with a different flavor
393
401
or Item_subselect instead, as part of query rewriting.
395
403
unit->item= NULL;
400
Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,
408
Item_maxmin_subselect::Item_maxmin_subselect(Session *session_param,
401
409
Item_subselect *parent,
402
st_select_lex *select_lex,
410
Select_Lex *select_lex,
404
412
:Item_singlerow_subselect(), was_values(true)
476
SELECT_LEX *select_lex= join->select_lex;
484
Select_Lex *select_lex= join->select_lex;
478
486
if (!select_lex->master_unit()->is_union() &&
479
487
!select_lex->table_list.elements &&
480
488
select_lex->item_list.elements == 1 &&
495
503
have_to_be_excluded= 1;
496
if (thd->lex->describe)
504
if (session->lex->describe)
498
506
char warn_buff[DRIZZLE_ERRMSG_SIZE];
499
507
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
500
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
508
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
501
509
ER_SELECT_REDUCED, warn_buff);
503
511
substitution= select_lex->item_list.head();
683
bool Item_in_subselect::test_limit(st_select_lex_unit *unit_arg)
691
bool Item_in_subselect::test_limit(Select_Lex_Unit *unit_arg)
685
693
if (unit_arg->fake_select_lex &&
686
694
unit_arg->fake_select_lex->test_limit())
689
SELECT_LEX *sl= unit_arg->first_select();
697
Select_Lex *sl= unit_arg->first_select();
690
698
for (; sl; sl= sl->next_select())
692
700
if (sl->test_limit())
698
706
Item_in_subselect::Item_in_subselect(Item * left_exp,
699
st_select_lex *select_lex):
707
Select_Lex *select_lex):
700
708
Item_exists_subselect(), left_expr_cache(0), first_execution(true),
701
709
optimizer(0), pushed_cond_guards(NULL), exec_method(NOT_TRANSFORMED),
715
723
Item_allany_subselect::Item_allany_subselect(Item * left_exp,
716
724
chooser_compare_func_creator fc,
717
st_select_lex *select_lex,
725
Select_Lex *select_lex,
719
727
:Item_in_subselect(), func_creator(fc), all(all_arg)
876
884
Must mark the IN predicate as NULL so as to make sure an enclosing NOT
877
predicate will return false. See the comments in
885
predicate will return false. See the comments in
878
886
subselect_uniquesubquery_engine::copy_ref_key for further details.
919
927
Rewrite a single-column subquery using rule-based approach. The subquery
921
929
oe $cmp$ (SELECT ie FROM ... WHERE subq_where ... HAVING subq_having)
923
931
First, try to convert the subquery to scalar-result subquery in one of
926
934
- oe $cmp$ (SELECT MAX(...) ) // handled by Item_singlerow_subselect
927
935
- oe $cmp$ <max>(SELECT ...) // handled by Item_maxmin_subselect
929
937
If that fails, the subquery will be handled with class Item_in_optimizer.
930
938
There are two possibilites:
931
939
- If the subquery execution method is materialization, then the subquery is
944
952
Item_subselect::trans_res
945
953
Item_in_subselect::single_value_transformer(JOIN *join,
954
const Comp_creator *func)
948
SELECT_LEX *select_lex= join->select_lex;
956
Select_Lex *select_lex= join->select_lex;
951
959
Check that the right part of the subselect contains no more than one
1011
1019
it.replace(item);
1014
save_allow_sum_func= thd->lex->allow_sum_func;
1015
thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
1022
save_allow_sum_func= session->lex->allow_sum_func;
1023
session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
1017
1025
Item_sum_(max|min) can't substitute other item => we can use 0 as
1018
1026
reference, also Item_sum_(max|min) can't be fixed after creation, so
1019
1027
we do not check item->fixed
1021
if (item->fix_fields(thd, 0))
1029
if (item->fix_fields(session, 0))
1022
1030
return(RES_ERROR);
1023
thd->lex->allow_sum_func= save_allow_sum_func;
1031
session->lex->allow_sum_func= save_allow_sum_func;
1024
1032
/* we added aggregate function => we have to change statistic */
1025
count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
1033
count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
1028
1036
subs= new Item_singlerow_subselect(select_lex);
1032
1040
Item_maxmin_subselect *item;
1033
subs= item= new Item_maxmin_subselect(thd, this, select_lex, func->l_op());
1041
subs= item= new Item_maxmin_subselect(session, this, select_lex, func->l_op());
1034
1042
if (upper_item)
1035
1043
upper_item->set_sub_test(item);
1042
1050
if (!substitution)
1044
1052
/* We're invoked for the 1st (or the only) SELECT in the subquery UNION */
1045
SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
1053
Select_Lex_Unit *master_unit= select_lex->master_unit();
1046
1054
substitution= optimizer;
1048
SELECT_LEX *current= thd->lex->current_select, *up;
1056
Select_Lex *current= session->lex->current_select, *up;
1050
thd->lex->current_select= up= current->return_after_parsing();
1058
session->lex->current_select= up= current->return_after_parsing();
1051
1059
//optimizer never use Item **ref => we can pass 0 as parameter
1052
if (!optimizer || optimizer->fix_left(thd, 0))
1060
if (!optimizer || optimizer->fix_left(session, 0))
1054
thd->lex->current_select= current;
1062
session->lex->current_select= current;
1055
1063
return(RES_ERROR);
1057
thd->lex->current_select= current;
1065
session->lex->current_select= current;
1060
1068
As far as Item_ref_in_optimizer do not substitute itself on fix_fields
1071
1079
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1073
if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool))))
1081
if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool))))
1074
1082
return(RES_ERROR);
1075
1083
pushed_cond_guards[0]= true;
1096
1104
- If the subquery has aggregates, GROUP BY, or HAVING, convert to
1098
SELECT ie FROM ... HAVING subq_having AND
1106
SELECT ie FROM ... HAVING subq_having AND
1099
1107
trigcond(oe $cmp$ ref_or_null_helper<ie>)
1101
1109
the addition is wrapped into trigger only when we want to distinguish
1102
1110
between NULL and false results.
1126
1134
Item_subselect::trans_res
1127
Item_in_subselect::single_value_in_to_exists_transformer(JOIN * join, Comp_creator *func)
1135
Item_in_subselect::single_value_in_to_exists_transformer(JOIN * join, const Comp_creator *func)
1129
SELECT_LEX *select_lex= join->select_lex;
1137
Select_Lex *select_lex= join->select_lex;
1131
1139
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1132
1140
if (join->having || select_lex->with_sum_func ||
1142
1150
this->full_name()));
1143
1151
if (!abort_on_null && left_expr->maybe_null)
1146
1154
We can encounter "NULL IN (SELECT ...)". Wrap the added condition
1147
1155
within a trig_cond.
1149
1157
item= new Item_func_trig_cond(item, get_cond_guard(0));
1153
1161
AND and comparison functions can't be changed during fix_fields()
1154
1162
we can assign select_lex->having here, and pass 0 as last
1162
1170
we do not check join->having->fixed, because Item_and (from and_items)
1163
1171
or comparison function (from func->create) can't be fixed after creation
1165
tmp= join->having->fix_fields(thd, 0);
1173
tmp= join->having->fix_fields(session, 0);
1166
1174
select_lex->having_fix_field= 0;
1168
1176
return(RES_ERROR);
1181
1189
MY_INT64_NUM_DECIMAL_DIGITS));
1182
1190
select_lex->ref_pointer_array[0]= select_lex->item_list.head();
1184
1192
item= func->create(expr, item);
1185
1193
if (!abort_on_null && orig_item->maybe_null)
1204
1212
and_items) or comparison function (from func->create) can't be
1205
1213
fixed after creation
1207
tmp= join->having->fix_fields(thd, 0);
1215
tmp= join->having->fix_fields(session, 0);
1208
1216
select_lex->having_fix_field= 0;
1210
1218
return(RES_ERROR);
1211
1219
item= new Item_cond_or(item,
1212
1220
new Item_func_isnull(orig_item));
1215
1223
If we may encounter NULL IN (SELECT ...) and care whether subquery
1216
1224
result is NULL or false, wrap condition in a trig_cond.
1238
1246
we do not check join->conds->fixed, because Item_and can't be fixed
1241
if (join->conds->fix_fields(thd, 0))
1249
if (join->conds->fix_fields(session, 0))
1242
1250
return(RES_ERROR);
1266
1274
new_having->name= (char*)in_having_cond;
1267
1275
select_lex->having= join->having= new_having;
1268
1276
select_lex->having_fix_field= 1;
1271
1279
we do not check join->having->fixed, because comparison function
1272
1280
(from func->create) can't be fixed after creation
1274
tmp= join->having->fix_fields(thd, 0);
1282
tmp= join->having->fix_fields(session, 0);
1275
1283
select_lex->having_fix_field= 0;
1277
1285
return(RES_ERROR);
1283
1291
// fix_field of item will be done in time of substituting
1284
1292
substitution= item;
1285
1293
have_to_be_excluded= 1;
1286
if (thd->lex->describe)
1294
if (session->lex->describe)
1288
1296
char warn_buff[DRIZZLE_ERRMSG_SIZE];
1289
1297
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
1290
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1298
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1291
1299
ER_SELECT_REDUCED, warn_buff);
1293
1301
return(RES_REDUCE);
1302
1310
Item_subselect::trans_res
1303
1311
Item_in_subselect::row_value_transformer(JOIN *join)
1305
SELECT_LEX *select_lex= join->select_lex;
1313
Select_Lex *select_lex= join->select_lex;
1306
1314
uint32_t cols_num= left_expr->cols();
1308
1316
if (select_lex->item_list.elements != left_expr->cols())
1318
1326
if (!substitution)
1320
1328
//first call for this unit
1321
SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
1329
Select_Lex_Unit *master_unit= select_lex->master_unit();
1322
1330
substitution= optimizer;
1324
SELECT_LEX *current= thd->lex->current_select, *up;
1325
thd->lex->current_select= up= current->return_after_parsing();
1332
Select_Lex *current= session->lex->current_select, *up;
1333
session->lex->current_select= up= current->return_after_parsing();
1326
1334
//optimizer never use Item **ref => we can pass 0 as parameter
1327
if (!optimizer || optimizer->fix_left(thd, 0))
1335
if (!optimizer || optimizer->fix_left(session, 0))
1329
thd->lex->current_select= current;
1337
session->lex->current_select= current;
1330
1338
return(RES_ERROR);
1333
1341
// we will refer to upper level cache array => we have to save it in PS
1334
1342
optimizer->keep_top_level_cache();
1336
thd->lex->current_select= current;
1344
session->lex->current_select= current;
1337
1345
master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1339
1347
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1341
if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool) *
1349
if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool) *
1342
1350
left_expr->cols())))
1343
1351
return(RES_ERROR);
1344
1352
for (uint32_t i= 0; i < cols_num; i++)
1379
1387
Item_subselect::trans_res
1380
1388
Item_in_subselect::row_value_in_to_exists_transformer(JOIN * join)
1382
SELECT_LEX *select_lex= join->select_lex;
1390
Select_Lex *select_lex= join->select_lex;
1383
1391
Item *having_item= 0;
1384
1392
uint32_t cols_num= left_expr->cols();
1385
1393
bool is_having_used= (join->having || select_lex->with_sum_func ||
1439
1447
return(RES_ERROR);
1441
1449
having_item= and_items(having_item, col_item);
1443
Item *item_nnull_test=
1451
Item *item_nnull_test=
1444
1452
new Item_is_not_null_test(this,
1445
1453
new Item_ref(&select_lex->context,
1508
1516
Item *having_col_item=
1509
1517
new Item_is_not_null_test(this,
1511
Item_ref(&select_lex->context,
1519
Item_ref(&select_lex->context,
1512
1520
select_lex->ref_pointer_array + i,
1513
1521
(char *)"<no matter>",
1514
1522
(char *)"<list ref>"));
1517
1525
item_isnull= new
1518
1526
Item_func_isnull(new
1519
1527
Item_direct_ref(&select_lex->context,
1547
1555
select_lex->where= join->conds= and_items(join->conds, where_item);
1548
1556
select_lex->where->top_level_item();
1549
if (join->conds->fix_fields(thd, 0))
1557
if (join->conds->fix_fields(session, 0))
1550
1558
return(RES_ERROR);
1552
1560
if (having_item)
1562
1570
argument (reference) to fix_fields()
1564
1572
select_lex->having_fix_field= 1;
1565
res= join->having->fix_fields(thd, 0);
1573
res= join->having->fix_fields(session, 0);
1566
1574
select_lex->having_fix_field= 0;
1577
1585
Item_subselect::trans_res
1578
1586
Item_in_subselect::select_transformer(JOIN *join)
1580
return select_in_like_transformer(join, &eq_creator);
1588
return select_in_like_transformer(join, Eq_creator::instance());
1605
1613
Item_subselect::trans_res
1606
Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
1614
Item_in_subselect::select_in_like_transformer(JOIN *join, const Comp_creator *func)
1608
SELECT_LEX *current= thd->lex->current_select, *up;
1609
const char *save_where= thd->where;
1616
Select_Lex *current= session->lex->current_select, *up;
1617
const char *save_where= session->where;
1610
1618
Item_subselect::trans_res res= RES_ERROR;
1615
1623
IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
1616
1624
order_st BY clause becomes meaningless thus we drop it here.
1618
SELECT_LEX *sl= current->master_unit()->first_select();
1626
Select_Lex *sl= current->master_unit()->first_select();
1619
1627
for (; sl; sl= sl->next_select())
1643
thd->lex->current_select= up= current->return_after_parsing();
1651
session->lex->current_select= up= current->return_after_parsing();
1644
1652
result= (!left_expr->fixed &&
1645
left_expr->fix_fields(thd, optimizer->arguments()));
1653
left_expr->fix_fields(session, optimizer->arguments()));
1646
1654
/* fix_fields can change reference to left_expr, we need reassign it */
1647
1655
left_expr= optimizer->arguments()[0];
1649
thd->lex->current_select= current;
1657
session->lex->current_select= current;
1698
bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
1706
bool Item_in_subselect::fix_fields(Session *session_arg, Item **ref)
1700
1708
bool result = 0;
1702
1710
if (exec_method == SEMI_JOIN)
1703
1711
return !( (*ref)= new Item_int(1));
1705
return result || Item_subselect::fix_fields(thd_arg, ref);
1713
return result || Item_subselect::fix_fields(session_arg, ref);
1738
1746
if (engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE)
1740
1748
/* Create/initialize objects in permanent memory. */
1741
subselect_single_select_engine *old_engine;
1743
old_engine= (subselect_single_select_engine*) engine;
1745
if (!(new_engine= new subselect_hash_sj_engine(thd, this,
1749
subselect_single_select_engine *old_engine_ptr;
1751
old_engine_ptr= static_cast<subselect_single_select_engine *>(engine);
1753
if (!(new_engine= new subselect_hash_sj_engine(session, this,
1747
1755
new_engine->init_permanent(unit->get_unit_column_types()))
1749
Item_subselect::trans_res trans_res;
1757
Item_subselect::trans_res new_trans_res;
1751
1759
If for some reason we cannot use materialization for this IN predicate,
1752
1760
delete all materialization-related objects, and apply the IN=>EXISTS
1756
1764
new_engine= NULL;
1757
1765
exec_method= NOT_TRANSFORMED;
1758
1766
if (left_expr->cols() == 1)
1759
trans_res= single_value_in_to_exists_transformer(old_engine->join,
1767
new_trans_res= single_value_in_to_exists_transformer(
1768
old_engine_ptr->join,
1769
Eq_creator::instance());
1762
trans_res= row_value_in_to_exists_transformer(old_engine->join);
1763
res= (trans_res != Item_subselect::RES_OK);
1771
new_trans_res= row_value_in_to_exists_transformer(old_engine_ptr->join);
1772
res= (new_trans_res != Item_subselect::RES_OK);
1765
1774
if (new_engine)
1766
1775
engine= new_engine;
1770
1779
assert(engine->engine_type() == subselect_engine::HASH_SJ_ENGINE);
1771
new_engine= (subselect_hash_sj_engine*) engine;
1780
new_engine= static_cast<subselect_hash_sj_engine *>(engine);
1774
1783
/* Initilizations done in runtime memory, repeated for each execution. */
1831
1840
for (uint32_t i= 0; i < left_expr->cols(); i++)
1833
Cached_item *cur_item_cache= new_Cached_item(thd,
1842
Cached_item *cur_item_cache= new_Cached_item(session,
1834
1843
left_expr->element_index(i),
1835
1844
use_result_field);
1836
1845
if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
1887
void subselect_engine::set_thd(THD *thd_arg)
1896
void subselect_engine::set_session(Session *session_arg)
1898
session= session_arg;
1891
result->set_thd(thd_arg);
1900
result->set_session(session_arg);
1895
1904
subselect_single_select_engine::
1896
subselect_single_select_engine(st_select_lex *select,
1905
subselect_single_select_engine(Select_Lex *select,
1897
1906
select_result_interceptor *result_arg,
1898
1907
Item_subselect *item_arg)
1899
1908
:subselect_engine(item_arg, result_arg),
1960
subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
1969
subselect_union_engine::subselect_union_engine(Select_Lex_Unit *u,
1961
1970
select_result_interceptor *result_arg,
1962
1971
Item_subselect *item_arg)
1963
1972
:subselect_engine(item_arg, result_arg)
2000
join= new JOIN(thd, select_lex->item_list,
2009
join= new JOIN(session, select_lex->item_list,
2001
2010
select_lex->options | SELECT_NO_UNLOCK, result);
2002
2011
if (!join || !result)
2003
2012
return 1; /* Fatal error is set already. */
2005
SELECT_LEX *save_select= thd->lex->current_select;
2006
thd->lex->current_select= select_lex;
2014
Select_Lex *save_select= session->lex->current_select;
2015
session->lex->current_select= select_lex;
2007
2016
if (join->prepare(&select_lex->ref_pointer_array,
2008
2017
(TableList*) select_lex->table_list.first,
2009
2018
select_lex->with_wild,
2016
2025
(order_st*) 0, select_lex,
2017
2026
select_lex->master_unit()))
2019
thd->lex->current_select= save_select;
2028
session->lex->current_select= save_select;
2023
2032
int subselect_union_engine::prepare()
2025
return unit->prepare(thd, result, SELECT_NO_UNLOCK);
2034
return unit->prepare(session, result, (uint32_t)SELECT_NO_UNLOCK);
2028
2037
int subselect_uniquesubquery_engine::prepare()
2051
2060
bool subselect_single_select_engine::no_rows()
2053
2062
return !item->assigned();
2058
makes storage for the output values for the subquery and calcuates
2067
makes storage for the output values for the subquery and calcuates
2059
2068
their data and column types and their nullability.
2061
2070
void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
2063
2072
Item *sel_item;
2119
2128
int subselect_single_select_engine::exec()
2121
char const *save_where= thd->where;
2122
SELECT_LEX *save_select= thd->lex->current_select;
2123
thd->lex->current_select= select_lex;
2130
char const *save_where= session->where;
2131
Select_Lex *save_select= session->lex->current_select;
2132
session->lex->current_select= select_lex;
2124
2133
if (!join->optimized)
2126
SELECT_LEX_UNIT *unit= select_lex->master_unit();
2135
Select_Lex_Unit *unit= select_lex->master_unit();
2128
2137
unit->set_limit(unit->global_parameters);
2129
2138
if (join->flatten_subqueries())
2131
thd->is_fatal_error= true;
2140
session->is_fatal_error= true;
2134
2143
if (join->optimize())
2136
thd->where= save_where;
2145
session->where= save_where;
2138
thd->lex->current_select= save_select;
2147
session->lex->current_select= save_select;
2139
2148
return(join->error ? join->error : 1);
2141
if (!select_lex->uncacheable && thd->lex->describe &&
2142
!(join->select_options & SELECT_DESCRIBE) &&
2150
if (!select_lex->uncacheable && session->lex->describe &&
2151
!(join->select_options & SELECT_DESCRIBE) &&
2143
2152
join->need_tmp && item->const_item())
2189
2198
JOIN_TAB *tab=join->join_tab+i;
2190
2199
if (tab && tab->keyuse)
2192
for (uint32_t i= 0; i < tab->ref.key_parts; i++)
2201
for (uint32_t key_part= 0;
2202
key_part < tab->ref.key_parts;
2194
bool *cond_guard= tab->ref.cond_guards[i];
2205
bool *cond_guard= tab->ref.cond_guards[key_part];
2195
2206
if (cond_guard && !*cond_guard)
2197
2208
/* Change the access method to full table scan */
2199
2210
tab->save_read_record= tab->read_record.read_record;
2200
2211
tab->read_first_record= init_read_record_seq;
2201
2212
tab->read_record.record= tab->table->record[0];
2202
tab->read_record.thd= join->thd;
2213
tab->read_record.session= join->session;
2203
2214
tab->read_record.ref_length= tab->table->file->ref_length;
2204
2215
*(last_changed_tab++)= tab;
2217
2228
JOIN_TAB *tab= *ptab;
2218
2229
tab->read_record.record= 0;
2219
2230
tab->read_record.ref_length= 0;
2220
tab->read_first_record= tab->save_read_first_record;
2231
tab->read_first_record= tab->save_read_first_record;
2221
2232
tab->read_record.read_record= tab->save_read_record;
2224
thd->where= save_where;
2225
thd->lex->current_select= save_select;
2226
return(join->error||thd->is_fatal_error);
2235
session->where= save_where;
2236
session->lex->current_select= save_select;
2237
return(join->error||session->is_fatal_error);
2228
thd->where= save_where;
2229
thd->lex->current_select= save_select;
2239
session->where= save_where;
2240
session->lex->current_select= save_select;
2233
2244
int subselect_union_engine::exec()
2235
char const *save_where= thd->where;
2246
char const *save_where= session->where;
2236
2247
int res= unit->exec();
2237
thd->where= save_where;
2248
session->where= save_where;
2243
2254
Search for at least one row satisfying select condition
2246
2257
subselect_uniquesubquery_engine::scan_table()
2249
2260
Scan the table using sequential access until we find at least one row
2250
2261
satisfying select condition.
2252
2263
The caller must set this->empty_result_set=false before calling this
2253
2264
function. This function will set it to true if it finds a matching row.
2265
2276
if (table->file->inited)
2266
2277
table->file->ha_index_end();
2268
2279
table->file->ha_rnd_init(1);
2269
2280
table->file->extra_opt(HA_EXTRA_CACHE,
2270
current_thd->variables.read_buff_size);
2281
current_session->variables.read_buff_size);
2271
2282
table->null_row= 0;
2371
Check if the error is equal to STORE_KEY_FATAL. This is not expressed
2372
using the store_key::store_key_result enum because ref.key_err is a
2373
boolean and we want to detect both true and STORE_KEY_FATAL from the
2374
space of the union of the values of [true, false] and
2375
store_key::store_key_result.
2382
Check if the error is equal to STORE_KEY_FATAL. This is not expressed
2383
using the store_key::store_key_result enum because ref.key_err is a
2384
boolean and we want to detect both true and STORE_KEY_FATAL from the
2385
space of the union of the values of [true, false] and
2386
store_key::store_key_result.
2376
2387
TODO: fix the variable an return types.
2378
2389
if (store_res == store_key::STORE_KEY_FATAL)
2381
2392
Error converting the left IN operand to the column type of the right
2384
2395
tab->table->status= STATUS_NOT_FOUND;
2400
2411
If some part of the lookup key is NULL, then we're evaluating
2401
2412
NULL IN (SELECT ... )
2402
2413
This is a special case, we don't need to search for NULL in the table,
2403
instead, the result value is
2414
instead, the result value is
2404
2415
- NULL if select produces empty row set
2405
2416
- false otherwise.
2407
2418
In some cases (IN subselect is a top level item, i.e. abort_on_null==true)
2408
2419
the caller doesn't distinguish between NULL and false result and we just
2410
Otherwise we make a full table scan to see if there is at least one
2421
Otherwise we make a full table scan to see if there is at least one
2413
2424
The result of this function (info about whether a row was found) is
2414
2425
stored in this->empty_result_set.
2419
2430
true - an error occured while scanning
2425
2436
Table *table= tab->table;
2426
2437
empty_result_set= true;
2427
2438
table->status= 0;
2429
2440
/* TODO: change to use of 'full_scan' here? */
2430
2441
if (copy_ref_key())
2432
2443
if (table->status)
2435
We know that there will be no rows even if we scan.
2446
We know that there will be no rows even if we scan.
2436
2447
Can be set in copy_ref_key.
2438
2449
((Item_in_subselect *) item)->value= 0;
2475
2486
subselect_indexsubquery_engine:exec()
2479
2490
The engine is used to resolve subqueries in form
2481
oe IN (SELECT key FROM tbl WHERE subq_where)
2492
oe IN (SELECT key FROM tbl WHERE subq_where)
2483
The value of the predicate is calculated as follows:
2494
The value of the predicate is calculated as follows:
2484
2495
1. If oe IS NULL, this is a special case, do a full table scan on
2485
table tbl and search for row that satisfies subq_where. If such
2496
table tbl and search for row that satisfies subq_where. If such
2486
2497
row is found, return NULL, otherwise return false.
2487
2498
2. Make an index lookup via key=oe, search for a row that satisfies
2488
2499
subq_where. If found, return true.
2489
3. If check_null==true, make another lookup via key=NULL, search for a
2500
3. If check_null==true, make another lookup via key=NULL, search for a
2490
2501
row that satisfies subq_where. If found, return NULL, otherwise
2494
2505
The step #1 can be optimized further when the index has several key
2495
2506
parts. Consider a subquery:
2497
2508
(oe1, oe2) IN (SELECT keypart1, keypart2 FROM tbl WHERE subq_where)
2499
2510
and suppose we need to evaluate it for {oe1, oe2}=={const1, NULL}.
2503
2514
SELECT keypart1, keypart2 FROM tbl WHERE subq_where (1)
2505
2516
and checking if it has produced any matching rows, evaluate
2507
2518
SELECT keypart2 FROM tbl WHERE subq_where AND keypart1=const1 (2)
2509
If this query produces a row, the result is NULL (as we're evaluating
2520
If this query produces a row, the result is NULL (as we're evaluating
2510
2521
"(const1, NULL) IN { (const1, X), ... }", which has a value of UNKNOWN,
2511
2522
i.e. NULL). If the query produces no rows, the result is false.
2677
2688
void subselect_single_select_engine::print(String *str,
2678
2689
enum_query_type query_type)
2680
select_lex->print(thd, str, query_type);
2691
select_lex->print(session, str, query_type);
2822
bool subselect_uniquesubquery_engine::change_result(Item_subselect *si __attribute__((unused)),
2823
select_result_interceptor *res __attribute__((unused)))
2833
bool subselect_uniquesubquery_engine::change_result(Item_subselect *,
2834
select_result_interceptor *)
2868
2879
bool subselect_union_engine::no_tables()
2870
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
2881
for (Select_Lex *sl= unit->first_select(); sl; sl= sl->next_select())
2872
2883
if (sl->table_list.elements)
2937
2948
if (!(tmp_result_sink= new select_union))
2939
2950
if (tmp_result_sink->create_result_table(
2940
thd, tmp_columns, true,
2941
thd->options | TMP_TABLE_ALL_COLUMNS,
2951
session, tmp_columns, true,
2952
session->options | TMP_TABLE_ALL_COLUMNS,
2942
2953
"materialized subselect", true))
2960
2971
tmp_table->s->uniques ||
2961
2972
tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
2962
2973
tmp_table->key_info->key_parts > tmp_table->file->max_key_parts());
2963
tmp_table->free_tmp_table(thd);
2974
tmp_table->free_tmp_table(session);
2982
2993
- this JOIN_TAB has no corresponding JOIN (and doesn't need one), and
2983
2994
- here we initialize only those members that are used by
2984
2995
subselect_uniquesubquery_engine, so these objects are incomplete.
2986
if (!(tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
2997
if (!(tab= (JOIN_TAB*) session->alloc(sizeof(JOIN_TAB))))
2988
2999
tab->table= tmp_table;
2989
3000
tab->ref.key= 0; /* The only temp table index. */
2990
3001
tab->ref.key_length= tmp_key->key_length;
2991
3002
if (!(tab->ref.key_buff=
2992
(unsigned char*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3003
(unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
2993
3004
!(tab->ref.key_copy=
2994
(store_key**) thd->alloc((sizeof(store_key*) *
3005
(store_key**) session->alloc((sizeof(store_key*) *
2995
3006
(tmp_key_parts + 1)))) ||
2996
3007
!(tab->ref.items=
2997
(Item**) thd->alloc(sizeof(Item*) * tmp_key_parts)))
3008
(Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
3000
3011
KEY_PART_INFO *cur_key_part= tmp_key->key_part;
3001
3012
store_key **ref_key= tab->ref.key_copy;
3002
3013
unsigned char *cur_ref_buff= tab->ref.key_buff;
3004
3015
for (uint32_t i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3006
3017
tab->ref.items[i]= item_in->left_expr->element_index(i);
3007
3018
int null_count= test(cur_key_part->field->real_maybe_null());
3008
*ref_key= new store_key_item(thd, cur_key_part->field,
3019
*ref_key= new store_key_item(session, cur_key_part->field,
3010
3021
the NULL byte is taken into account in
3011
3022
cur_key_part->store_length, so instead of
3093
3104
if (!is_materialized)
3096
SELECT_LEX *save_select= thd->lex->current_select;
3097
thd->lex->current_select= materialize_engine->select_lex;
3107
Select_Lex *save_select= session->lex->current_select;
3108
session->lex->current_select= materialize_engine->select_lex;
3098
3109
if ((res= materialize_join->optimize()))
3100
3111
materialize_join->exec();
3101
if ((res= test(materialize_join->error || thd->is_fatal_error)))
3112
if ((res= test(materialize_join->error || session->is_fatal_error)))