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 */
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>
31
27
#include <drizzled/sql_select.h>
32
#include <drizzled/error.h>
33
#include <drizzled/item/cache.h>
34
#include <drizzled/item/subselect.h>
35
#include <drizzled/item/cmpfunc.h>
36
#include <drizzled/item/ref_null_helper.h>
37
#include <drizzled/cached_item.h>
38
#include <drizzled/check_stack_overrun.h>
39
#include <drizzled/item/ref_null_helper.h>
40
#include <drizzled/item/direct_ref.h>
41
#include <drizzled/join.h>
46
extern plugin::StorageEngine *myisam_engine;
28
#include <drizzled/drizzled_error_messages.h>
48
30
inline Item * and_items(Item* cond, Item *item)
50
32
return (cond? (new Item_cond_and(cond, item)) : item);
53
Item_subselect::Item_subselect() :
55
value_assigned(false),
63
parsing_place(NO_MATTER),
64
have_to_be_excluded(false),
65
const_item_cache(true),
66
engine_changed(false),
35
Item_subselect::Item_subselect():
36
Item_result_field(), value_assigned(0), thd(0), substitution(0),
37
engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
38
const_item_cache(1), engine_changed(0), changed(0),
68
39
is_correlated(false)
115
86
engine= new subselect_single_select_engine(select_lex, result, this);
118
Select_Lex *upper= unit->outer_select();
89
SELECT_LEX *upper= unit->outer_select();
119
90
if (upper->parsing_place == IN_HAVING)
120
91
upper->subquery_in_having= 1;
126
97
Item_subselect::get_select_lex()
128
99
return unit->first_select();
174
145
Item_subselect::trans_res
175
Item_subselect::select_transformer(Join *)
146
Item_subselect::select_transformer(JOIN *join __attribute__((unused)))
181
bool Item_subselect::fix_fields(Session *session_param, Item **ref)
152
bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
183
char const *save_where= session_param->where;
154
char const *save_where= thd_param->where;
186
158
assert(fixed == 0);
187
engine->set_session((session= session_param));
159
engine->set_thd((thd= thd_param));
189
if (check_stack_overrun(session, STACK_MIN_SIZE, (unsigned char*)&res))
161
if (check_stack_overrun(thd, STACK_MIN_SIZE, (unsigned char*)&res))
192
164
res= engine->prepare();
209
181
// did we changed top item of WHERE condition
210
182
if (unit->outer_select()->where == (*ref))
212
unit->outer_select()->where= substitution; // correct WHERE for PS
183
unit->outer_select()->where= substitution; // correct WHERE for PS
214
184
else if (unit->outer_select()->having == (*ref))
216
unit->outer_select()->having= substitution; // correct HAVING for PS
185
unit->outer_select()->having= substitution; // correct HAVING for PS
219
187
(*ref)= substitution;
220
188
substitution->name= name;
221
189
if (have_to_be_excluded)
226
session->where= "checking transformed subquery";
229
ret= (*ref)->fix_fields(session, ref);
231
session->where= save_where;
192
thd->where= "checking transformed subquery";
194
ret= (*ref)->fix_fields(thd, ref);
195
thd->where= save_where;
234
198
// Is it one field subselect?
245
if (engine->uncacheable())
209
if ((uncacheable= engine->uncacheable()))
247
211
const_item_cache= 0;
248
if (engine->uncacheable(UNCACHEABLE_RAND))
212
if (uncacheable & UNCACHEABLE_RAND)
250
213
used_tables_cache|= RAND_TABLE_BIT;
256
session->where= save_where;
218
thd->where= save_where;
265
227
if (walk_subquery)
267
for (Select_Lex *lex= unit->first_select(); lex; lex= lex->next_select())
229
for (SELECT_LEX *lex= unit->first_select(); lex; lex= lex->next_select())
269
231
List_iterator<Item> li(lex->item_list);
273
235
if (lex->where && (lex->where)->walk(processor, walk_subquery, argument))
281
243
if (item->walk(processor, walk_subquery, argument))
284
for (order= (Order*) lex->order_list.first ; order; order= order->next)
246
for (order= (order_st*) lex->order_list.first ; order; order= order->next)
286
248
if ((*order->item)->walk(processor, walk_subquery, argument))
289
for (order= (Order*) lex->group_list.first ; order; order= order->next)
251
for (order= (order_st*) lex->group_list.first ; order; order= order->next)
291
253
if ((*order->item)->walk(processor, walk_subquery, argument))
381
343
return const_item_cache;
384
Item *Item_subselect::get_tmp_table_item(Session *session_arg)
346
Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
386
348
if (!with_sum_func && !const_item())
387
349
return new Item_field(result_field);
388
return copy_or_same(session_arg);
350
return copy_or_same(thd_arg);
391
353
void Item_subselect::update_used_tables()
393
if (! engine->uncacheable())
355
if (!engine->uncacheable())
395
357
// did all used tables become static?
396
358
if (!(used_tables_cache & ~engine->upper_select_const_tables()))
410
Item_singlerow_subselect::Item_singlerow_subselect(Select_Lex *select_lex)
372
Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex)
411
373
:Item_subselect(), value(0)
413
375
init(select_lex, new select_singlerow_subselect(this));
420
382
Item_singlerow_subselect::invalidate_and_restore_select_lex()
422
Select_Lex *result= get_select_lex();
384
st_select_lex *result= get_select_lex();
427
389
This code restore the parse tree in it's state before the execution of
428
390
Item_singlerow_subselect::Item_singlerow_subselect(),
429
and in particular decouples this object from the Select_Lex,
430
so that the Select_Lex can be used with a different flavor
391
and in particular decouples this object from the SELECT_LEX,
392
so that the SELECT_LEX can be used with a different flavor
431
393
or Item_subselect instead, as part of query rewriting.
433
395
unit->item= NULL;
438
Item_maxmin_subselect::Item_maxmin_subselect(Session *session_param,
400
Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,
439
401
Item_subselect *parent,
440
Select_Lex *select_lex,
402
st_select_lex *select_lex,
442
404
:Item_singlerow_subselect(), was_values(true)
506
468
Make rollback for it, or special name resolving mode in 5.0.
508
470
Item_subselect::trans_res
509
Item_singlerow_subselect::select_transformer(Join *join)
471
Item_singlerow_subselect::select_transformer(JOIN *join)
514
Select_Lex *select_lex= join->select_lex;
476
SELECT_LEX *select_lex= join->select_lex;
516
478
if (!select_lex->master_unit()->is_union() &&
517
479
!select_lex->table_list.elements &&
518
480
select_lex->item_list.elements == 1 &&
533
495
have_to_be_excluded= 1;
534
if (session->lex->describe)
496
if (thd->lex->describe)
536
498
char warn_buff[DRIZZLE_ERRMSG_SIZE];
537
snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
538
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
499
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
500
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
539
501
ER_SELECT_REDUCED, warn_buff);
541
503
substitution= select_lex->item_list.head();
721
bool Item_in_subselect::test_limit(Select_Lex_Unit *unit_arg)
683
bool Item_in_subselect::test_limit(st_select_lex_unit *unit_arg)
723
685
if (unit_arg->fake_select_lex &&
724
686
unit_arg->fake_select_lex->test_limit())
727
Select_Lex *sl= unit_arg->first_select();
689
SELECT_LEX *sl= unit_arg->first_select();
728
690
for (; sl; sl= sl->next_select())
730
692
if (sl->test_limit())
736
698
Item_in_subselect::Item_in_subselect(Item * left_exp,
737
Select_Lex *select_lex) :
738
Item_exists_subselect(),
740
left_expr_cache(NULL),
741
first_execution(true),
743
pushed_cond_guards(NULL),
744
sj_convert_priority(0),
745
expr_join_nest(NULL),
746
exec_method(NOT_TRANSFORMED),
699
st_select_lex *select_lex):
700
Item_exists_subselect(), left_expr_cache(0), first_execution(true),
701
optimizer(0), pushed_cond_guards(NULL), exec_method(NOT_TRANSFORMED),
749
705
init(select_lex, new select_exists_subselect(this));
750
706
max_columns= UINT_MAX;
759
715
Item_allany_subselect::Item_allany_subselect(Item * left_exp,
760
716
chooser_compare_func_creator fc,
761
Select_Lex *select_lex,
717
st_select_lex *select_lex,
763
719
:Item_in_subselect(), func_creator(fc), all(all_arg)
963
919
Rewrite a single-column subquery using rule-based approach. The subquery
965
921
oe $cmp$ (SELECT ie FROM ... WHERE subq_where ... HAVING subq_having)
967
923
First, try to convert the subquery to scalar-result subquery in one of
970
926
- oe $cmp$ (SELECT MAX(...) ) // handled by Item_singlerow_subselect
971
927
- oe $cmp$ <max>(SELECT ...) // handled by Item_maxmin_subselect
973
929
If that fails, the subquery will be handled with class Item_in_optimizer.
974
930
There are two possibilites:
975
931
- If the subquery execution method is materialization, then the subquery is
988
944
Item_subselect::trans_res
989
Item_in_subselect::single_value_transformer(Join *join,
990
const Comp_creator *func)
945
Item_in_subselect::single_value_transformer(JOIN *join,
992
Select_Lex *select_lex= join->select_lex;
948
SELECT_LEX *select_lex= join->select_lex;
995
951
Check that the right part of the subselect contains no more than one
1055
1011
it.replace(item);
1058
save_allow_sum_func= session->lex->allow_sum_func;
1059
session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
1014
save_allow_sum_func= thd->lex->allow_sum_func;
1015
thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
1061
1017
Item_sum_(max|min) can't substitute other item => we can use 0 as
1062
1018
reference, also Item_sum_(max|min) can't be fixed after creation, so
1063
1019
we do not check item->fixed
1065
if (item->fix_fields(session, 0))
1021
if (item->fix_fields(thd, 0))
1066
1022
return(RES_ERROR);
1067
session->lex->allow_sum_func= save_allow_sum_func;
1023
thd->lex->allow_sum_func= save_allow_sum_func;
1068
1024
/* we added aggregate function => we have to change statistic */
1069
count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
1025
count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
1072
1028
subs= new Item_singlerow_subselect(select_lex);
1076
1032
Item_maxmin_subselect *item;
1077
subs= item= new Item_maxmin_subselect(session, this, select_lex, func->l_op());
1033
subs= item= new Item_maxmin_subselect(thd, this, select_lex, func->l_op());
1078
1034
if (upper_item)
1079
1035
upper_item->set_sub_test(item);
1086
1042
if (!substitution)
1088
1044
/* We're invoked for the 1st (or the only) SELECT in the subquery UNION */
1089
Select_Lex_Unit *master_unit= select_lex->master_unit();
1045
SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
1090
1046
substitution= optimizer;
1092
Select_Lex *current= session->lex->current_select, *up;
1048
SELECT_LEX *current= thd->lex->current_select, *up;
1094
session->lex->current_select= up= current->return_after_parsing();
1050
thd->lex->current_select= up= current->return_after_parsing();
1095
1051
//optimizer never use Item **ref => we can pass 0 as parameter
1096
if (!optimizer || optimizer->fix_left(session, 0))
1052
if (!optimizer || optimizer->fix_left(thd, 0))
1098
session->lex->current_select= current;
1054
thd->lex->current_select= current;
1099
1055
return(RES_ERROR);
1101
session->lex->current_select= current;
1057
thd->lex->current_select= current;
1104
1060
As far as Item_ref_in_optimizer do not substitute itself on fix_fields
1109
1065
(char *)"<no matter>",
1110
1066
(char *)in_left_expr_name);
1112
master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
1068
master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1115
1071
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1117
if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool))))
1073
if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool))))
1118
1074
return(RES_ERROR);
1119
1075
pushed_cond_guards[0]= true;
1140
1096
- If the subquery has aggregates, GROUP BY, or HAVING, convert to
1142
SELECT ie FROM ... HAVING subq_having AND
1098
SELECT ie FROM ... HAVING subq_having AND
1143
1099
trigcond(oe $cmp$ ref_or_null_helper<ie>)
1145
1101
the addition is wrapped into trigger only when we want to distinguish
1146
1102
between NULL and false results.
1170
1126
Item_subselect::trans_res
1171
Item_in_subselect::single_value_in_to_exists_transformer(Join * join, const Comp_creator *func)
1127
Item_in_subselect::single_value_in_to_exists_transformer(JOIN * join, Comp_creator *func)
1173
Select_Lex *select_lex= join->select_lex;
1129
SELECT_LEX *select_lex= join->select_lex;
1175
select_lex->uncacheable.set(UNCACHEABLE_DEPENDENT);
1131
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1176
1132
if (join->having || select_lex->with_sum_func ||
1177
1133
select_lex->group_list.elements)
1186
1142
this->full_name()));
1187
1143
if (!abort_on_null && left_expr->maybe_null)
1190
1146
We can encounter "NULL IN (SELECT ...)". Wrap the added condition
1191
1147
within a trig_cond.
1193
1149
item= new Item_func_trig_cond(item, get_cond_guard(0));
1197
1153
AND and comparison functions can't be changed during fix_fields()
1198
1154
we can assign select_lex->having here, and pass 0 as last
1206
1162
we do not check join->having->fixed, because Item_and (from and_items)
1207
1163
or comparison function (from func->create) can't be fixed after creation
1209
tmp= join->having->fix_fields(session, 0);
1165
tmp= join->having->fix_fields(thd, 0);
1210
1166
select_lex->having_fix_field= 0;
1212
1168
return(RES_ERROR);
1248
1204
and_items) or comparison function (from func->create) can't be
1249
1205
fixed after creation
1251
tmp= join->having->fix_fields(session, 0);
1207
tmp= join->having->fix_fields(thd, 0);
1252
1208
select_lex->having_fix_field= 0;
1254
1210
return(RES_ERROR);
1255
1211
item= new Item_cond_or(item,
1256
1212
new Item_func_isnull(orig_item));
1259
1215
If we may encounter NULL IN (SELECT ...) and care whether subquery
1260
1216
result is NULL or false, wrap condition in a trig_cond.
1310
1266
new_having->name= (char*)in_having_cond;
1311
1267
select_lex->having= join->having= new_having;
1312
1268
select_lex->having_fix_field= 1;
1315
1271
we do not check join->having->fixed, because comparison function
1316
1272
(from func->create) can't be fixed after creation
1318
tmp= join->having->fix_fields(session, 0);
1274
tmp= join->having->fix_fields(thd, 0);
1319
1275
select_lex->having_fix_field= 0;
1321
1277
return(RES_ERROR);
1327
1283
// fix_field of item will be done in time of substituting
1328
1284
substitution= item;
1329
1285
have_to_be_excluded= 1;
1330
if (session->lex->describe)
1286
if (thd->lex->describe)
1332
1288
char warn_buff[DRIZZLE_ERRMSG_SIZE];
1333
snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
1334
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1289
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
1290
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1335
1291
ER_SELECT_REDUCED, warn_buff);
1337
1293
return(RES_REDUCE);
1346
1302
Item_subselect::trans_res
1347
Item_in_subselect::row_value_transformer(Join *join)
1303
Item_in_subselect::row_value_transformer(JOIN *join)
1349
Select_Lex *select_lex= join->select_lex;
1305
SELECT_LEX *select_lex= join->select_lex;
1350
1306
uint32_t cols_num= left_expr->cols();
1352
1308
if (select_lex->item_list.elements != left_expr->cols())
1362
1318
if (!substitution)
1364
1320
//first call for this unit
1365
Select_Lex_Unit *master_unit= select_lex->master_unit();
1321
SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
1366
1322
substitution= optimizer;
1368
Select_Lex *current= session->lex->current_select, *up;
1369
session->lex->current_select= up= current->return_after_parsing();
1324
SELECT_LEX *current= thd->lex->current_select, *up;
1325
thd->lex->current_select= up= current->return_after_parsing();
1370
1326
//optimizer never use Item **ref => we can pass 0 as parameter
1371
if (!optimizer || optimizer->fix_left(session, 0))
1327
if (!optimizer || optimizer->fix_left(thd, 0))
1373
session->lex->current_select= current;
1329
thd->lex->current_select= current;
1374
1330
return(RES_ERROR);
1377
1333
// we will refer to upper level cache array => we have to save it in PS
1378
1334
optimizer->keep_top_level_cache();
1380
session->lex->current_select= current;
1381
master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
1336
thd->lex->current_select= current;
1337
master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1383
1339
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1385
if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool) *
1341
if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool) *
1386
1342
left_expr->cols())))
1387
1343
return(RES_ERROR);
1388
1344
for (uint32_t i= 0; i < cols_num; i++)
1423
1379
Item_subselect::trans_res
1424
Item_in_subselect::row_value_in_to_exists_transformer(Join * join)
1380
Item_in_subselect::row_value_in_to_exists_transformer(JOIN * join)
1426
Select_Lex *select_lex= join->select_lex;
1382
SELECT_LEX *select_lex= join->select_lex;
1427
1383
Item *having_item= 0;
1428
1384
uint32_t cols_num= left_expr->cols();
1429
1385
bool is_having_used= (join->having || select_lex->with_sum_func ||
1430
1386
select_lex->group_list.first ||
1431
1387
!select_lex->table_list.elements);
1433
select_lex->uncacheable.set(UNCACHEABLE_DEPENDENT);
1389
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1434
1390
if (is_having_used)
1552
1508
Item *having_col_item=
1553
1509
new Item_is_not_null_test(this,
1555
Item_ref(&select_lex->context,
1511
Item_ref(&select_lex->context,
1556
1512
select_lex->ref_pointer_array + i,
1557
1513
(char *)"<no matter>",
1558
1514
(char *)"<list ref>"));
1561
1517
item_isnull= new
1562
1518
Item_func_isnull(new
1563
1519
Item_direct_ref(&select_lex->context,
1591
1547
select_lex->where= join->conds= and_items(join->conds, where_item);
1592
1548
select_lex->where->top_level_item();
1593
if (join->conds->fix_fields(session, 0))
1549
if (join->conds->fix_fields(thd, 0))
1594
1550
return(RES_ERROR);
1596
1552
if (having_item)
1606
1562
argument (reference) to fix_fields()
1608
1564
select_lex->having_fix_field= 1;
1609
res= join->having->fix_fields(session, 0);
1565
res= join->having->fix_fields(thd, 0);
1610
1566
select_lex->having_fix_field= 0;
1621
1577
Item_subselect::trans_res
1622
Item_in_subselect::select_transformer(Join *join)
1578
Item_in_subselect::select_transformer(JOIN *join)
1624
return select_in_like_transformer(join, Eq_creator::instance());
1580
return select_in_like_transformer(join, &eq_creator);
1649
1605
Item_subselect::trans_res
1650
Item_in_subselect::select_in_like_transformer(Join *join, const Comp_creator *func)
1606
Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
1652
Select_Lex *current= session->lex->current_select, *up;
1653
const char *save_where= session->where;
1608
SELECT_LEX *current= thd->lex->current_select, *up;
1609
const char *save_where= thd->where;
1654
1610
Item_subselect::trans_res res= RES_ERROR;
1659
1615
IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
1660
ORDER BY clause becomes meaningless thus we drop it here.
1616
order_st BY clause becomes meaningless thus we drop it here.
1662
Select_Lex *sl= current->master_unit()->first_select();
1618
SELECT_LEX *sl= current->master_unit()->first_select();
1663
1619
for (; sl; sl= sl->next_select())
1687
session->lex->current_select= up= current->return_after_parsing();
1643
thd->lex->current_select= up= current->return_after_parsing();
1688
1644
result= (!left_expr->fixed &&
1689
left_expr->fix_fields(session, optimizer->arguments()));
1645
left_expr->fix_fields(thd, optimizer->arguments()));
1690
1646
/* fix_fields can change reference to left_expr, we need reassign it */
1691
1647
left_expr= optimizer->arguments()[0];
1693
session->lex->current_select= current;
1649
thd->lex->current_select= current;
1742
bool Item_in_subselect::fix_fields(Session *session_arg, Item **ref)
1698
bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
1744
1700
bool result = 0;
1746
1702
if (exec_method == SEMI_JOIN)
1747
1703
return !( (*ref)= new Item_int(1));
1749
return result || Item_subselect::fix_fields(session_arg, ref);
1705
return result || Item_subselect::fix_fields(thd_arg, ref);
1782
1738
if (engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE)
1784
1740
/* Create/initialize objects in permanent memory. */
1785
subselect_single_select_engine *old_engine_ptr;
1787
old_engine_ptr= static_cast<subselect_single_select_engine *>(engine);
1789
if (!(new_engine= new subselect_hash_sj_engine(session, this,
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,
1791
1747
new_engine->init_permanent(unit->get_unit_column_types()))
1793
Item_subselect::trans_res new_trans_res;
1749
Item_subselect::trans_res trans_res;
1795
1751
If for some reason we cannot use materialization for this IN predicate,
1796
1752
delete all materialization-related objects, and apply the IN=>EXISTS
1800
1756
new_engine= NULL;
1801
1757
exec_method= NOT_TRANSFORMED;
1802
1758
if (left_expr->cols() == 1)
1803
new_trans_res= single_value_in_to_exists_transformer(
1804
old_engine_ptr->join,
1805
Eq_creator::instance());
1759
trans_res= single_value_in_to_exists_transformer(old_engine->join,
1807
new_trans_res= row_value_in_to_exists_transformer(old_engine_ptr->join);
1808
res= (new_trans_res != Item_subselect::RES_OK);
1762
trans_res= row_value_in_to_exists_transformer(old_engine->join);
1763
res= (trans_res != Item_subselect::RES_OK);
1810
1765
if (new_engine)
1811
1766
engine= new_engine;
1851
1806
bool Item_in_subselect::init_left_expr_cache()
1853
Join *outer_join= NULL;
1809
Next_select_func end_select;
1810
bool use_result_field= false;
1855
1812
outer_join= unit->outer_select()->join;
1856
if (! outer_join || ! outer_join->tables || ! outer_join->join_tab)
1813
if (!outer_join || !outer_join->tables)
1816
If we use end_[send | write]_group to handle complete rows of the outer
1817
query, make the cache of the left IN operand use Item_field::result_field
1818
instead of Item_field::field. We need this because normally
1819
Cached_item_field uses Item::field to fetch field data, while
1820
copy_ref_key() that copies the left IN operand into a lookup key uses
1821
Item::result_field. In the case end_[send | write]_group result_field is
1822
one row behind field.
1824
end_select= outer_join->join_tab[outer_join->tables-1].next_select;
1825
if (end_select == end_send_group || end_select == end_write_group)
1826
use_result_field= true;
1859
1828
if (!(left_expr_cache= new List<Cached_item>))
1862
1831
for (uint32_t i= 0; i < left_expr->cols(); i++)
1864
Cached_item *cur_item_cache= new_Cached_item(session, left_expr->element_index(i));
1833
Cached_item *cur_item_cache= new_Cached_item(thd,
1834
left_expr->element_index(i),
1865
1836
if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
1882
1853
@retval false otherwise
1885
bool Item_in_subselect::is_expensive_processor(unsigned char *)
1856
bool Item_in_subselect::is_expensive_processor(unsigned char *arg __attribute__((unused)))
1887
1858
return exec_method == MATERIALIZATION;
1891
1862
Item_subselect::trans_res
1892
Item_allany_subselect::select_transformer(Join *join)
1863
Item_allany_subselect::select_transformer(JOIN *join)
1894
1865
exec_method= IN_TO_EXISTS;
1895
1866
if (upper_item)
1916
void subselect_engine::set_session(Session *session_arg)
1887
void subselect_engine::set_thd(THD *thd_arg)
1918
session= session_arg;
1920
result->set_session(session_arg);
1891
result->set_thd(thd_arg);
1924
1895
subselect_single_select_engine::
1925
subselect_single_select_engine(Select_Lex *select,
1896
subselect_single_select_engine(st_select_lex *select,
1926
1897
select_result_interceptor *result_arg,
1927
1898
Item_subselect *item_arg)
1928
1899
:subselect_engine(item_arg, result_arg),
1980
1951
void subselect_uniquesubquery_engine::cleanup()
1982
1953
/* Tell handler we don't need the index anymore */
1983
if (tab->table->cursor->inited)
1984
tab->table->cursor->endIndexScan();
1954
if (tab->table->file->inited)
1955
tab->table->file->ha_index_end();
1989
subselect_union_engine::subselect_union_engine(Select_Lex_Unit *u,
1960
subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
1990
1961
select_result_interceptor *result_arg,
1991
1962
Item_subselect *item_arg)
1992
1963
:subselect_engine(item_arg, result_arg)
2029
join= new Join(session, select_lex->item_list,
2000
join= new JOIN(thd, select_lex->item_list,
2030
2001
select_lex->options | SELECT_NO_UNLOCK, result);
2031
2002
if (!join || !result)
2032
2003
return 1; /* Fatal error is set already. */
2034
Select_Lex *save_select= session->lex->current_select;
2035
session->lex->current_select= select_lex;
2005
SELECT_LEX *save_select= thd->lex->current_select;
2006
thd->lex->current_select= select_lex;
2036
2007
if (join->prepare(&select_lex->ref_pointer_array,
2037
2008
(TableList*) select_lex->table_list.first,
2038
2009
select_lex->with_wild,
2039
2010
select_lex->where,
2040
2011
select_lex->order_list.elements +
2041
2012
select_lex->group_list.elements,
2042
(Order*) select_lex->order_list.first,
2043
(Order*) select_lex->group_list.first,
2013
(order_st*) select_lex->order_list.first,
2014
(order_st*) select_lex->group_list.first,
2044
2015
select_lex->having,
2045
select_lex, select_lex->master_unit()))
2016
(order_st*) 0, select_lex,
2017
select_lex->master_unit()))
2047
session->lex->current_select= save_select;
2019
thd->lex->current_select= save_select;
2051
2023
int subselect_union_engine::prepare()
2053
return unit->prepare(session, result, (uint32_t)SELECT_NO_UNLOCK);
2025
return unit->prepare(thd, result, SELECT_NO_UNLOCK);
2056
2028
int subselect_uniquesubquery_engine::prepare()
2079
2051
bool subselect_single_select_engine::no_rows()
2081
2053
return !item->assigned();
2086
makes storage for the output values for the subquery and calcuates
2058
makes storage for the output values for the subquery and calcuates
2087
2059
their data and column types and their nullability.
2089
2061
void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
2091
2063
Item *sel_item;
2137
void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **)
2109
void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row __attribute__((unused)))
2139
2111
//this never should be called
2143
int init_read_record_seq(JoinTable *tab);
2144
int join_read_always_key_or_null(JoinTable *tab);
2145
int join_read_next_same_or_null(ReadRecord *info);
2115
int init_read_record_seq(JOIN_TAB *tab);
2116
int join_read_always_key_or_null(JOIN_TAB *tab);
2117
int join_read_next_same_or_null(READ_RECORD *info);
2147
2119
int subselect_single_select_engine::exec()
2149
char const *save_where= session->where;
2150
Select_Lex *save_select= session->lex->current_select;
2151
session->lex->current_select= select_lex;
2121
char const *save_where= thd->where;
2122
SELECT_LEX *save_select= thd->lex->current_select;
2123
thd->lex->current_select= select_lex;
2152
2124
if (!join->optimized)
2154
Select_Lex_Unit *unit= select_lex->master_unit();
2126
SELECT_LEX_UNIT *unit= select_lex->master_unit();
2156
2128
unit->set_limit(unit->global_parameters);
2129
if (join->flatten_subqueries())
2131
thd->is_fatal_error= true;
2157
2134
if (join->optimize())
2159
session->where= save_where;
2136
thd->where= save_where;
2161
session->lex->current_select= save_select;
2138
thd->lex->current_select= save_select;
2162
2139
return(join->error ? join->error : 1);
2164
if (select_lex->uncacheable.none() && session->lex->describe &&
2165
!(join->select_options & SELECT_DESCRIBE) &&
2141
if (!select_lex->uncacheable && thd->lex->describe &&
2142
!(join->select_options & SELECT_DESCRIBE) &&
2166
2143
join->need_tmp && item->const_item())
2171
2148
called by EXPLAIN and we need to preserve the initial query structure
2172
2149
so we can display it.
2174
select_lex->uncacheable.set(UNCACHEABLE_EXPLAIN);
2175
select_lex->master_unit()->uncacheable.set(UNCACHEABLE_EXPLAIN);
2151
select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
2152
select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
2176
2153
if (join->init_save_join_tab())
2154
return(1); /* purecov: inspected */
2179
2156
if (item->engine_changed)
2184
if (select_lex->uncacheable.any() &&
2185
! select_lex->uncacheable.test(UNCACHEABLE_EXPLAIN) &&
2161
if (select_lex->uncacheable &&
2162
select_lex->uncacheable != UNCACHEABLE_EXPLAIN
2188
2165
if (join->reinit())
2190
session->where= save_where;
2191
session->lex->current_select= save_select;
2167
thd->where= save_where;
2168
thd->lex->current_select= save_select;
2195
2172
item->assigned((executed= 0));
2199
2176
item->reset_value_registration();
2200
JoinTable *changed_tabs[MAX_TABLES];
2201
JoinTable **last_changed_tab= changed_tabs;
2177
JOIN_TAB *changed_tabs[MAX_TABLES];
2178
JOIN_TAB **last_changed_tab= changed_tabs;
2202
2179
if (item->have_guarded_conds())
2210
2187
for (uint32_t i=join->const_tables ; i < join->tables ; i++)
2212
JoinTable *tab=join->join_tab+i;
2189
JOIN_TAB *tab=join->join_tab+i;
2213
2190
if (tab && tab->keyuse)
2215
for (uint32_t key_part= 0;
2216
key_part < tab->ref.key_parts;
2192
for (uint32_t i= 0; i < tab->ref.key_parts; i++)
2219
bool *cond_guard= tab->ref.cond_guards[key_part];
2194
bool *cond_guard= tab->ref.cond_guards[i];
2220
2195
if (cond_guard && !*cond_guard)
2222
2197
/* Change the access method to full table scan */
2224
2199
tab->save_read_record= tab->read_record.read_record;
2225
2200
tab->read_first_record= init_read_record_seq;
2226
2201
tab->read_record.record= tab->table->record[0];
2227
tab->read_record.session= join->session;
2228
tab->read_record.ref_length= tab->table->cursor->ref_length;
2202
tab->read_record.thd= join->thd;
2203
tab->read_record.ref_length= tab->table->file->ref_length;
2229
2204
*(last_changed_tab++)= tab;
2239
2214
/* Enable the optimizations back */
2240
for (JoinTable **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
2215
for (JOIN_TAB **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
2242
JoinTable *tab= *ptab;
2217
JOIN_TAB *tab= *ptab;
2243
2218
tab->read_record.record= 0;
2244
2219
tab->read_record.ref_length= 0;
2245
tab->read_first_record= tab->save_read_first_record;
2220
tab->read_first_record= tab->save_read_first_record;
2246
2221
tab->read_record.read_record= tab->save_read_record;
2249
session->where= save_where;
2250
session->lex->current_select= save_select;
2251
return(join->error||session->is_fatal_error);
2224
thd->where= save_where;
2225
thd->lex->current_select= save_select;
2226
return(join->error||thd->is_fatal_error);
2253
session->where= save_where;
2254
session->lex->current_select= save_select;
2228
thd->where= save_where;
2229
thd->lex->current_select= save_select;
2258
2233
int subselect_union_engine::exec()
2260
char const *save_where= session->where;
2235
char const *save_where= thd->where;
2261
2236
int res= unit->exec();
2262
session->where= save_where;
2237
thd->where= save_where;
2268
2243
Search for at least one row satisfying select condition
2271
2246
subselect_uniquesubquery_engine::scan_table()
2274
2249
Scan the table using sequential access until we find at least one row
2275
2250
satisfying select condition.
2277
2252
The caller must set this->empty_result_set=false before calling this
2278
2253
function. This function will set it to true if it finds a matching row.
2288
2263
Table *table= tab->table;
2290
if (table->cursor->inited)
2291
table->cursor->endIndexScan();
2293
table->cursor->startTableScan(1);
2294
table->cursor->extra_opt(HA_EXTRA_CACHE,
2295
current_session->variables.read_buff_size);
2265
if (table->file->inited)
2266
table->file->ha_index_end();
2268
table->file->ha_rnd_init(1);
2269
table->file->extra_opt(HA_EXTRA_CACHE,
2270
current_thd->variables.read_buff_size);
2296
2271
table->null_row= 0;
2299
error=table->cursor->rnd_next(table->record[0]);
2274
error=table->file->rnd_next(table->record[0]);
2300
2275
if (error && error != HA_ERR_END_OF_FILE)
2302
2277
error= table->report_error(error);
2363
2338
bool subselect_uniquesubquery_engine::copy_ref_key()
2365
for (StoredKey **copy= tab->ref.key_copy ; *copy ; copy++)
2340
for (store_key **copy= tab->ref.key_copy ; *copy ; copy++)
2367
StoredKey::store_key_result store_res= (*copy)->copy();
2342
enum store_key::store_key_result store_res;
2343
store_res= (*copy)->copy();
2368
2344
tab->ref.key_err= store_res;
2395
Check if the error is equal to STORE_KEY_FATAL. This is not expressed
2396
using the StoredKey::store_key_result enum because ref.key_err is a
2397
boolean and we want to detect both true and STORE_KEY_FATAL from the
2398
space of the union of the values of [true, false] and
2399
StoredKey::store_key_result.
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.
2400
2376
TODO: fix the variable an return types.
2402
if (store_res == StoredKey::STORE_KEY_FATAL)
2378
if (store_res == store_key::STORE_KEY_FATAL)
2405
2381
Error converting the left IN operand to the column type of the right
2408
2384
tab->table->status= STATUS_NOT_FOUND;
2424
2400
If some part of the lookup key is NULL, then we're evaluating
2425
2401
NULL IN (SELECT ... )
2426
2402
This is a special case, we don't need to search for NULL in the table,
2427
instead, the result value is
2403
instead, the result value is
2428
2404
- NULL if select produces empty row set
2429
2405
- false otherwise.
2431
2407
In some cases (IN subselect is a top level item, i.e. abort_on_null==true)
2432
2408
the caller doesn't distinguish between NULL and false result and we just
2434
Otherwise we make a full table scan to see if there is at least one
2410
Otherwise we make a full table scan to see if there is at least one
2437
2413
The result of this function (info about whether a row was found) is
2438
2414
stored in this->empty_result_set.
2443
2419
true - an error occured while scanning
2449
2425
Table *table= tab->table;
2450
2426
empty_result_set= true;
2451
2427
table->status= 0;
2453
2429
/* TODO: change to use of 'full_scan' here? */
2454
2430
if (copy_ref_key())
2456
2432
if (table->status)
2459
We know that there will be no rows even if we scan.
2435
We know that there will be no rows even if we scan.
2460
2436
Can be set in copy_ref_key.
2462
2438
((Item_in_subselect *) item)->value= 0;
2466
2442
if (null_keypart)
2467
2443
return(scan_table());
2469
if (!table->cursor->inited)
2470
table->cursor->startIndexScan(tab->ref.key, 0);
2471
error= table->cursor->index_read_map(table->record[0],
2445
if (!table->file->inited)
2446
table->file->ha_index_init(tab->ref.key, 0);
2447
error= table->file->index_read_map(table->record[0],
2472
2448
tab->ref.key_buff,
2473
2449
make_prev_keypart_map(tab->ref.key_parts),
2474
2450
HA_READ_KEY_EXACT);
2499
2475
subselect_indexsubquery_engine:exec()
2503
2479
The engine is used to resolve subqueries in form
2505
oe IN (SELECT key FROM tbl WHERE subq_where)
2481
oe IN (SELECT key FROM tbl WHERE subq_where)
2507
The value of the predicate is calculated as follows:
2483
The value of the predicate is calculated as follows:
2508
2484
1. If oe IS NULL, this is a special case, do a full table scan on
2509
table tbl and search for row that satisfies subq_where. If such
2485
table tbl and search for row that satisfies subq_where. If such
2510
2486
row is found, return NULL, otherwise return false.
2511
2487
2. Make an index lookup via key=oe, search for a row that satisfies
2512
2488
subq_where. If found, return true.
2513
3. If check_null==true, make another lookup via key=NULL, search for a
2489
3. If check_null==true, make another lookup via key=NULL, search for a
2514
2490
row that satisfies subq_where. If found, return NULL, otherwise
2518
2494
The step #1 can be optimized further when the index has several key
2519
2495
parts. Consider a subquery:
2521
2497
(oe1, oe2) IN (SELECT keypart1, keypart2 FROM tbl WHERE subq_where)
2523
2499
and suppose we need to evaluate it for {oe1, oe2}=={const1, NULL}.
2527
2503
SELECT keypart1, keypart2 FROM tbl WHERE subq_where (1)
2529
2505
and checking if it has produced any matching rows, evaluate
2531
2507
SELECT keypart2 FROM tbl WHERE subq_where AND keypart1=const1 (2)
2533
If this query produces a row, the result is NULL (as we're evaluating
2509
If this query produces a row, the result is NULL (as we're evaluating
2534
2510
"(const1, NULL) IN { (const1, X), ... }", which has a value of UNKNOWN,
2535
2511
i.e. NULL). If the query produces no rows, the result is false.
2579
2555
if (null_keypart)
2580
2556
return(scan_table());
2582
if (!table->cursor->inited)
2583
table->cursor->startIndexScan(tab->ref.key, 1);
2584
error= table->cursor->index_read_map(table->record[0],
2558
if (!table->file->inited)
2559
table->file->ha_index_init(tab->ref.key, 1);
2560
error= table->file->index_read_map(table->record[0],
2585
2561
tab->ref.key_buff,
2586
2562
make_prev_keypart_map(tab->ref.key_parts),
2587
2563
HA_READ_KEY_EXACT);
2645
bool subselect_single_select_engine::uncacheable()
2647
return select_lex->uncacheable.any();
2651
bool subselect_single_select_engine::uncacheable(uint32_t bit_pos)
2653
return select_lex->uncacheable.test(bit_pos);
2657
bool subselect_union_engine::uncacheable()
2659
return unit->uncacheable.any();
2663
bool subselect_union_engine::uncacheable(uint32_t bit_pos)
2665
return unit->uncacheable.test(bit_pos);
2621
uint8_t subselect_single_select_engine::uncacheable()
2623
return select_lex->uncacheable;
2627
uint8_t subselect_union_engine::uncacheable()
2629
return unit->uncacheable;
2713
2677
void subselect_single_select_engine::print(String *str,
2714
2678
enum_query_type query_type)
2716
select_lex->print(session, str, query_type);
2680
select_lex->print(thd, str, query_type);
2726
2690
void subselect_uniquesubquery_engine::print(String *str,
2727
2691
enum_query_type query_type)
2729
char *table_name= const_cast<char *>(tab->table->getShare()->getTableName());
2693
char *table_name= tab->table->s->table_name.str;
2730
2694
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2731
2695
tab->ref.items[0]->print(str, query_type);
2732
2696
str->append(STRING_WITH_LEN(" in "));
2733
if (tab->table->getShare()->isTemporaryCategory())
2697
if (tab->table->s->table_category == TABLE_CATEGORY_TEMPORARY)
2736
2700
Temporary tables' names change across runs, so they can't be used for
2739
2703
str->append(STRING_WITH_LEN("<temporary table>"));
2742
str->append(table_name, tab->table->getShare()->getTableNameSize());
2743
KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
2706
str->append(table_name, tab->table->s->table_name.length);
2707
KEY *key_info= tab->table->key_info+ tab->ref.key;
2744
2708
str->append(STRING_WITH_LEN(" on "));
2745
2709
str->append(key_info->name);
2763
2727
for (uint32_t i= 0; i < key_info->key_parts; i++)
2764
2728
tab->ref.items[i]->print(str);
2765
2729
str->append(STRING_WITH_LEN(" in "));
2766
str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
2730
str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2767
2731
str->append(STRING_WITH_LEN(" on "));
2768
2732
str->append(key_info->name);
2781
2745
str->append(STRING_WITH_LEN("<index_lookup>("));
2782
2746
tab->ref.items[0]->print(str, query_type);
2783
2747
str->append(STRING_WITH_LEN(" in "));
2784
str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
2785
KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
2748
str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2749
KEY *key_info= tab->table->key_info+ tab->ref.key;
2786
2750
str->append(STRING_WITH_LEN(" on "));
2787
2751
str->append(key_info->name);
2788
2752
if (check_null)
2858
bool subselect_uniquesubquery_engine::change_result(Item_subselect *,
2859
select_result_interceptor *)
2822
bool subselect_uniquesubquery_engine::change_result(Item_subselect *si __attribute__((unused)),
2823
select_result_interceptor *res __attribute__((unused)))
2942
2906
temporary table has one hash index on all its columns.
2943
2907
- Create a new result sink that sends the result stream of the subquery to
2944
2908
the temporary table,
2945
- Create and initialize a new JoinTable, and TABLE_REF objects to perform
2909
- Create and initialize a new JOIN_TAB, and TABLE_REF objects to perform
2946
2910
lookups into the indexed temporary table.
2959
2923
select_union *tmp_result_sink;
2960
2924
/* The table into which the subquery is materialized. */
2961
2925
Table *tmp_table;
2962
KeyInfo *tmp_key; /* The only index on the temporary table. */
2926
KEY *tmp_key; /* The only index on the temporary table. */
2963
2927
uint32_t tmp_key_parts; /* Number of keyparts in tmp_key. */
2964
2928
Item_in_subselect *item_in= (Item_in_subselect *) item;
2973
2937
if (!(tmp_result_sink= new select_union))
2976
2939
if (tmp_result_sink->create_result_table(
2977
session, tmp_columns, true,
2978
session->options | TMP_TABLE_ALL_COLUMNS,
2979
"materialized subselect"))
2940
thd, tmp_columns, true,
2941
thd->options | TMP_TABLE_ALL_COLUMNS,
2942
"materialized subselect", true))
2982
2945
tmp_table= tmp_result_sink->table;
2990
2953
table since it will not be used, and tell the caller we failed to
2991
2954
initialize the engine.
2993
if (tmp_table->getShare()->sizeKeys() == 0)
2956
if (tmp_table->s->keys == 0)
2995
assert(tmp_table->getShare()->db_type() == myisam_engine);
2958
assert(tmp_table->s->db_type() == myisam_hton);
2997
tmp_table->getShare()->uniques ||
2998
tmp_table->key_info->key_length >= tmp_table->cursor->getEngine()->max_key_length() ||
2999
tmp_table->key_info->key_parts > tmp_table->cursor->getEngine()->max_key_parts());
2960
tmp_table->s->uniques ||
2961
tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
2962
tmp_table->key_info->key_parts > tmp_table->file->max_key_parts());
2963
tmp_table->free_tmp_table(thd);
3008
2971
Make sure there is only one index on the temp table, and it doesn't have
3009
2972
the extra key part created when s->uniques > 0.
3011
assert(tmp_table->getShare()->sizeKeys() == 1 && tmp_columns->elements == tmp_key_parts);
2974
assert(tmp_table->s->keys == 1 && tmp_columns->elements == tmp_key_parts);
3014
2977
/* 2. Create/initialize execution related objects. */
3017
Create and initialize the JoinTable that represents an index lookup
2980
Create and initialize the JOIN_TAB that represents an index lookup
3018
2981
plan operator into the materialized subquery result. Notice that:
3019
- this JoinTable has no corresponding JOIN (and doesn't need one), and
2982
- this JOIN_TAB has no corresponding JOIN (and doesn't need one), and
3020
2983
- here we initialize only those members that are used by
3021
2984
subselect_uniquesubquery_engine, so these objects are incomplete.
3023
if (!(tab= (JoinTable*) session->alloc(sizeof(JoinTable))))
2986
if (!(tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
3025
2988
tab->table= tmp_table;
3026
2989
tab->ref.key= 0; /* The only temp table index. */
3027
2990
tab->ref.key_length= tmp_key->key_length;
3028
2991
if (!(tab->ref.key_buff=
3029
(unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
2992
(unsigned char*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3030
2993
!(tab->ref.key_copy=
3031
(StoredKey**) session->alloc((sizeof(StoredKey*) *
2994
(store_key**) thd->alloc((sizeof(store_key*) *
3032
2995
(tmp_key_parts + 1)))) ||
3033
2996
!(tab->ref.items=
3034
(Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
2997
(Item**) thd->alloc(sizeof(Item*) * tmp_key_parts)))
3037
KeyPartInfo *cur_key_part= tmp_key->key_part;
3038
StoredKey **ref_key= tab->ref.key_copy;
3000
KEY_PART_INFO *cur_key_part= tmp_key->key_part;
3001
store_key **ref_key= tab->ref.key_copy;
3039
3002
unsigned char *cur_ref_buff= tab->ref.key_buff;
3041
3004
for (uint32_t i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3043
3006
tab->ref.items[i]= item_in->left_expr->element_index(i);
3044
3007
int null_count= test(cur_key_part->field->real_maybe_null());
3045
*ref_key= new store_key_item(session, cur_key_part->field,
3008
*ref_key= new store_key_item(thd, cur_key_part->field,
3047
3010
the NULL byte is taken into account in
3048
3011
cur_key_part->store_length, so instead of
3132
3093
if (!is_materialized)
3135
Select_Lex *save_select= session->lex->current_select;
3136
session->lex->current_select= materialize_engine->select_lex;
3096
SELECT_LEX *save_select= thd->lex->current_select;
3097
thd->lex->current_select= materialize_engine->select_lex;
3137
3098
if ((res= materialize_join->optimize()))
3139
3100
materialize_join->exec();
3140
if ((res= test(materialize_join->error || session->is_fatal_error)))
3101
if ((res= test(materialize_join->error || thd->is_fatal_error)))
3145
3106
- Unlock all subquery tables as we don't need them. To implement this
3146
we need to add new functionality to Join::join_free that can unlock
3107
we need to add new functionality to JOIN::join_free that can unlock
3147
3108
all tables in a subquery (and all its subqueries).
3148
3109
- The temp table used for grouping in the subquery can be freed
3149
3110
immediately after materialization (yet it's done together with
3156
3117
statistics, then we test if the temporary table for the query result is
3159
tab->table->cursor->info(HA_STATUS_VARIABLE);
3160
if (!tab->table->cursor->stats.records)
3120
tab->table->file->info(HA_STATUS_VARIABLE);
3121
if (!tab->table->file->stats.records)
3162
3123
empty_result_set= true;
3163
3124
item_in->value= false;