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
- add function from select_query that use JOIN* as parameter to JOIN
23
- add function from mysql_select that use JOIN* as parameter to JOIN
24
24
methods (sql_select.h/sql_select.cc)
26
#include <drizzled/server_includes.h>
31
27
#include <drizzled/sql_select.h>
32
28
#include <drizzled/error.h>
33
29
#include <drizzled/item/cache.h>
38
34
#include <drizzled/check_stack_overrun.h>
39
35
#include <drizzled/item/ref_null_helper.h>
40
36
#include <drizzled/item/direct_ref.h>
41
#include <drizzled/join.h>
42
#include <drizzled/plugin/storage_engine.h>
47
extern plugin::StorageEngine *myisam_engine;
49
38
inline Item * and_items(Item* cond, Item *item)
51
40
return (cond? (new Item_cond_and(cond, item)) : item);
54
Item_subselect::Item_subselect() :
56
value_assigned(false),
64
parsing_place(NO_MATTER),
65
have_to_be_excluded(false),
66
const_item_cache(true),
67
engine_changed(false),
43
Item_subselect::Item_subselect():
44
Item_result_field(), value_assigned(0), session(0), substitution(0),
45
engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
46
const_item_cache(1), engine_changed(0), changed(0),
69
47
is_correlated(false)
210
189
// did we changed top item of WHERE condition
211
190
if (unit->outer_select()->where == (*ref))
213
unit->outer_select()->where= substitution; // correct WHERE for PS
191
unit->outer_select()->where= substitution; // correct WHERE for PS
215
192
else if (unit->outer_select()->having == (*ref))
217
unit->outer_select()->having= substitution; // correct HAVING for PS
193
unit->outer_select()->having= substitution; // correct HAVING for PS
220
195
(*ref)= substitution;
221
196
substitution->name= name;
222
197
if (have_to_be_excluded)
227
session->setWhere("checking transformed subquery");
230
ret= (*ref)->fix_fields(session, ref);
232
session->setWhere(save_where);
200
session->where= "checking transformed subquery";
202
ret= (*ref)->fix_fields(session, ref);
203
session->where= save_where;
236
206
// Is it one field subselect?
247
if (engine->uncacheable())
217
if ((uncacheable= engine->uncacheable()))
249
const_item_cache= false;
250
if (engine->uncacheable(UNCACHEABLE_RAND))
220
if (uncacheable & UNCACHEABLE_RAND)
252
221
used_tables_cache|= RAND_TABLE_BIT;
258
session->setWhere(save_where);
226
session->where= save_where;
283
251
if (item->walk(processor, walk_subquery, argument))
286
for (order= (Order*) lex->order_list.first ; order; order= order->next)
254
for (order= (order_st*) lex->order_list.first ; order; order= order->next)
288
256
if ((*order->item)->walk(processor, walk_subquery, argument))
291
for (order= (Order*) lex->group_list.first ; order; order= order->next)
259
for (order= (order_st*) lex->group_list.first ; order; order= order->next)
293
261
if ((*order->item)->walk(processor, walk_subquery, argument))
393
361
void Item_subselect::update_used_tables()
395
if (! engine->uncacheable())
363
if (!engine->uncacheable())
397
365
// did all used tables become static?
398
366
if (!(used_tables_cache & ~engine->upper_select_const_tables()))
399
const_item_cache= true;
508
476
Make rollback for it, or special name resolving mode in 5.0.
510
478
Item_subselect::trans_res
511
Item_singlerow_subselect::select_transformer(Join *join)
479
Item_singlerow_subselect::select_transformer(JOIN *join)
536
504
if (session->lex->describe)
538
506
char warn_buff[DRIZZLE_ERRMSG_SIZE];
539
snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
507
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
540
508
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
541
509
ER_SELECT_REDUCED, warn_buff);
738
706
Item_in_subselect::Item_in_subselect(Item * left_exp,
739
Select_Lex *select_lex) :
740
Item_exists_subselect(),
742
left_expr_cache(NULL),
743
first_execution(true),
745
pushed_cond_guards(NULL),
746
sj_convert_priority(0),
747
expr_join_nest(NULL),
748
exec_method(NOT_TRANSFORMED),
707
Select_Lex *select_lex):
708
Item_exists_subselect(), left_expr_cache(0), first_execution(true),
709
optimizer(0), pushed_cond_guards(NULL), exec_method(NOT_TRANSFORMED),
751
713
init(select_lex, new select_exists_subselect(this));
752
714
max_columns= UINT_MAX;
831
int2_class_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
793
int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
832
794
return decimal_value;
949
911
if (was_null && !value)
951
int2_class_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
913
int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
952
914
return decimal_value;
990
952
Item_subselect::trans_res
991
Item_in_subselect::single_value_transformer(Join *join,
953
Item_in_subselect::single_value_transformer(JOIN *join,
992
954
const Comp_creator *func)
994
956
Select_Lex *select_lex= join->select_lex;
1111
1073
(char *)"<no matter>",
1112
1074
(char *)in_left_expr_name);
1114
master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
1076
master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1117
1079
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1119
if (!(pushed_cond_guards= (bool*)join->session->getMemRoot()->allocate(sizeof(bool))))
1081
if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool))))
1120
1082
return(RES_ERROR);
1121
1083
pushed_cond_guards[0]= true;
1172
1134
Item_subselect::trans_res
1173
Item_in_subselect::single_value_in_to_exists_transformer(Join * join, const Comp_creator *func)
1135
Item_in_subselect::single_value_in_to_exists_transformer(JOIN * join, const Comp_creator *func)
1175
1137
Select_Lex *select_lex= join->select_lex;
1177
select_lex->uncacheable.set(UNCACHEABLE_DEPENDENT);
1139
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1178
1140
if (join->having || select_lex->with_sum_func ||
1179
1141
select_lex->group_list.elements)
1332
1294
if (session->lex->describe)
1334
1296
char warn_buff[DRIZZLE_ERRMSG_SIZE];
1335
snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
1297
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
1336
1298
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1337
1299
ER_SELECT_REDUCED, warn_buff);
1348
1310
Item_subselect::trans_res
1349
Item_in_subselect::row_value_transformer(Join *join)
1311
Item_in_subselect::row_value_transformer(JOIN *join)
1351
1313
Select_Lex *select_lex= join->select_lex;
1352
1314
uint32_t cols_num= left_expr->cols();
1380
1342
optimizer->keep_top_level_cache();
1382
1344
session->lex->current_select= current;
1383
master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
1345
master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1385
1347
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1387
if (!(pushed_cond_guards= (bool*)join->session->getMemRoot()->allocate(sizeof(bool) *
1349
if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool) *
1388
1350
left_expr->cols())))
1389
1351
return(RES_ERROR);
1390
1352
for (uint32_t i= 0; i < cols_num; i++)
1623
1585
Item_subselect::trans_res
1624
Item_in_subselect::select_transformer(Join *join)
1586
Item_in_subselect::select_transformer(JOIN *join)
1626
1588
return select_in_like_transformer(join, Eq_creator::instance());
1651
1613
Item_subselect::trans_res
1652
Item_in_subselect::select_in_like_transformer(Join *join, const Comp_creator *func)
1614
Item_in_subselect::select_in_like_transformer(JOIN *join, const Comp_creator *func)
1654
1616
Select_Lex *current= session->lex->current_select, *up;
1655
const char *save_where= session->where();
1617
const char *save_where= session->where;
1656
1618
Item_subselect::trans_res res= RES_ERROR;
1661
1623
IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
1662
ORDER BY clause becomes meaningless thus we drop it here.
1624
order_st BY clause becomes meaningless thus we drop it here.
1664
1626
Select_Lex *sl= current->master_unit()->first_select();
1665
1627
for (; sl; sl= sl->next_select())
1853
1815
bool Item_in_subselect::init_left_expr_cache()
1855
Join *outer_join= NULL;
1818
Next_select_func end_select;
1819
bool use_result_field= false;
1857
1821
outer_join= unit->outer_select()->join;
1858
if (! outer_join || ! outer_join->tables || ! outer_join->join_tab)
1822
if (!outer_join || !outer_join->tables)
1825
If we use end_[send | write]_group to handle complete rows of the outer
1826
query, make the cache of the left IN operand use Item_field::result_field
1827
instead of Item_field::field. We need this because normally
1828
Cached_item_field uses Item::field to fetch field data, while
1829
copy_ref_key() that copies the left IN operand into a lookup key uses
1830
Item::result_field. In the case end_[send | write]_group result_field is
1831
one row behind field.
1833
end_select= outer_join->join_tab[outer_join->tables-1].next_select;
1834
if (end_select == end_send_group || end_select == end_write_group)
1835
use_result_field= true;
1861
1837
if (!(left_expr_cache= new List<Cached_item>))
1864
1840
for (uint32_t i= 0; i < left_expr->cols(); i++)
1866
Cached_item *cur_item_cache= new_Cached_item(session, left_expr->element_index(i));
1842
Cached_item *cur_item_cache= new_Cached_item(session,
1843
left_expr->element_index(i),
1867
1845
if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
1982
1960
void subselect_uniquesubquery_engine::cleanup()
1984
1962
/* Tell handler we don't need the index anymore */
1985
if (tab->table->cursor->inited)
1986
tab->table->cursor->endIndexScan();
1963
if (tab->table->file->inited)
1964
tab->table->file->ha_index_end();
2031
join= new Join(session, select_lex->item_list,
2009
join= new JOIN(session, select_lex->item_list,
2032
2010
select_lex->options | SELECT_NO_UNLOCK, result);
2033
2011
if (!join || !result)
2034
2012
return 1; /* Fatal error is set already. */
2041
2019
select_lex->where,
2042
2020
select_lex->order_list.elements +
2043
2021
select_lex->group_list.elements,
2044
(Order*) select_lex->order_list.first,
2045
(Order*) select_lex->group_list.first,
2022
(order_st*) select_lex->order_list.first,
2023
(order_st*) select_lex->group_list.first,
2046
2024
select_lex->having,
2047
2025
select_lex, select_lex->master_unit()))
2123
int init_read_record_seq(JoinTable *tab);
2124
int join_read_always_key_or_null(JoinTable *tab);
2125
int join_read_next_same_or_null(READ_RECORD *info);
2145
2127
int subselect_single_select_engine::exec()
2147
char const *save_where= session->where();
2129
char const *save_where= session->where;
2148
2130
Select_Lex *save_select= session->lex->current_select;
2149
2131
session->lex->current_select= select_lex;
2150
2132
if (!join->optimized)
2154
2136
unit->set_limit(unit->global_parameters);
2155
2137
if (join->optimize())
2157
session->setWhere(save_where);
2139
session->where= save_where;
2159
2141
session->lex->current_select= save_select;
2160
2142
return(join->error ? join->error : 1);
2162
if (save_join_if_explain())
2144
if (!select_lex->uncacheable && session->lex->describe &&
2145
!(join->select_options & SELECT_DESCRIBE) &&
2146
join->need_tmp && item->const_item())
2149
Force join->join_tmp creation, because this subquery will be replaced
2150
by a simple select from the materialization temp table by optimize()
2151
called by EXPLAIN and we need to preserve the initial query structure
2152
so we can display it.
2154
select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
2155
select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
2156
if (join->init_save_join_tab())
2165
2159
if (item->engine_changed)
2170
if (select_lex->uncacheable.any() &&
2171
! select_lex->uncacheable.test(UNCACHEABLE_EXPLAIN) &&
2164
if (select_lex->uncacheable &&
2165
select_lex->uncacheable != UNCACHEABLE_EXPLAIN
2174
2168
if (join->reinit())
2176
session->setWhere(save_where);
2170
session->where= save_where;
2177
2171
session->lex->current_select= save_select;
2181
2175
item->assigned((executed= 0));
2211
2205
tab->read_first_record= init_read_record_seq;
2212
2206
tab->read_record.record= tab->table->record[0];
2213
2207
tab->read_record.session= join->session;
2214
tab->read_record.ref_length= tab->table->cursor->ref_length;
2208
tab->read_record.ref_length= tab->table->file->ref_length;
2215
2209
*(last_changed_tab++)= tab;
2232
2226
tab->read_record.read_record= tab->save_read_record;
2235
session->setWhere(save_where);
2229
session->where= save_where;
2236
2230
session->lex->current_select= save_select;
2237
2231
return(join->error||session->is_fatal_error);
2239
session->setWhere(save_where);
2233
session->where= save_where;
2240
2234
session->lex->current_select= save_select;
2245
subselect_single_select_engine::save_join_if_explain()
2248
Save this JOIN to join->tmp_join since the original layout will be
2249
replaced when JOIN::exec() calls make_simple_join() if:
2250
1) We are executing an EXPLAIN query
2251
2) An uncacheable flag has not been set for the select_lex. If
2252
set, JOIN::optimize() has already saved the JOIN
2253
3) Call does not come from select_describe()). If it does,
2254
JOIN::exec() will not call make_simple_join() and the JOIN we
2255
plan to save will not be replaced anyway.
2256
4) A temp table is needed. This is what triggers JOIN::exec() to
2257
make a replacement JOIN by calling make_simple_join().
2258
5) The Item_subselect is cacheable
2260
if (session->lex->describe && // 1
2261
select_lex->uncacheable.none() && // 2
2262
!(join->select_options & SELECT_DESCRIBE) && // 3
2263
join->need_tmp && // 4
2264
item->const_item()) // 5
2267
Save this JOIN to join->tmp_join since the original layout will
2268
be replaced when JOIN::exec() calls make_simple_join() due to
2269
need_tmp==TRUE. The original layout is needed so we can describe
2270
the query. No need to do this if uncacheable != 0 since in this
2271
case the JOIN has already been saved during JOIN::optimize()
2273
select_lex->uncacheable.set(UNCACHEABLE_EXPLAIN);
2274
select_lex->master_unit()->uncacheable.set(UNCACHEABLE_EXPLAIN);
2275
if (join->init_save_join_tab())
2282
2238
int subselect_union_engine::exec()
2284
char const *save_where= session->where();
2240
char const *save_where= session->where;
2285
2241
int res= unit->exec();
2286
session->setWhere(save_where);
2242
session->where= save_where;
2313
2268
Table *table= tab->table;
2315
if (table->cursor->inited)
2316
table->cursor->endIndexScan();
2318
if ((error= table->cursor->startTableScan(1)))
2320
table->print_error(error, MYF(0));
2324
assert(table->getSession());
2325
table->cursor->extra_opt(HA_EXTRA_CACHE,
2326
table->getSession()->variables.read_buff_size);
2270
if (table->file->inited)
2271
table->file->ha_index_end();
2273
table->file->ha_rnd_init(1);
2274
table->file->extra_opt(HA_EXTRA_CACHE,
2275
current_session->variables.read_buff_size);
2327
2276
table->null_row= 0;
2330
error=table->cursor->rnd_next(table->record[0]);
2279
error=table->file->rnd_next(table->record[0]);
2331
2280
if (error && error != HA_ERR_END_OF_FILE)
2333
2282
error= table->report_error(error);
2396
2345
for (StoredKey **copy= tab->ref.key_copy ; *copy ; copy++)
2398
StoredKey::store_key_result store_res= (*copy)->copy();
2347
enum StoredKey::store_key_result store_res;
2348
store_res= (*copy)->copy();
2399
2349
tab->ref.key_err= store_res;
2497
2447
if (null_keypart)
2498
2448
return(scan_table());
2500
if (!table->cursor->inited)
2502
error= table->cursor->startIndexScan(tab->ref.key, 0);
2506
error= table->report_error(error);
2507
return (error != 0);
2511
error= table->cursor->index_read_map(table->record[0],
2450
if (!table->file->inited)
2451
table->file->ha_index_init(tab->ref.key, 0);
2452
error= table->file->index_read_map(table->record[0],
2512
2453
tab->ref.key_buff,
2513
2454
make_prev_keypart_map(tab->ref.key_parts),
2514
2455
HA_READ_KEY_EXACT);
2619
2560
if (null_keypart)
2620
2561
return(scan_table());
2622
if (!table->cursor->inited)
2624
error= table->cursor->startIndexScan(tab->ref.key, 1);
2628
error= table->report_error(error);
2632
error= table->cursor->index_read_map(table->record[0],
2563
if (!table->file->inited)
2564
table->file->ha_index_init(tab->ref.key, 1);
2565
error= table->file->index_read_map(table->record[0],
2633
2566
tab->ref.key_buff,
2634
2567
make_prev_keypart_map(tab->ref.key_parts),
2635
2568
HA_READ_KEY_EXACT);
2653
2586
((Item_in_subselect *) item)->value= 1;
2656
error= table->cursor->index_next_same(table->record[0],
2589
error= table->file->index_next_same(table->record[0],
2657
2590
tab->ref.key_buff,
2658
2591
tab->ref.key_length);
2659
2592
if (error && error != HA_ERR_END_OF_FILE)
2693
bool subselect_single_select_engine::uncacheable()
2695
return select_lex->uncacheable.any();
2699
bool subselect_single_select_engine::uncacheable(uint32_t bit_pos)
2701
return select_lex->uncacheable.test(bit_pos);
2705
bool subselect_union_engine::uncacheable()
2707
return unit->uncacheable.any();
2711
bool subselect_union_engine::uncacheable(uint32_t bit_pos)
2713
return unit->uncacheable.test(bit_pos);
2626
uint8_t subselect_single_select_engine::uncacheable()
2628
return select_lex->uncacheable;
2632
uint8_t subselect_union_engine::uncacheable()
2634
return unit->uncacheable;
2774
2695
void subselect_uniquesubquery_engine::print(String *str,
2775
2696
enum_query_type query_type)
2777
char *table_name= const_cast<char *>(tab->table->getShare()->getTableName());
2698
char *table_name= tab->table->s->table_name.str;
2778
2699
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2779
2700
tab->ref.items[0]->print(str, query_type);
2780
2701
str->append(STRING_WITH_LEN(" in "));
2781
if (tab->table->getShare()->isTemporaryCategory())
2702
if (tab->table->s->table_category == TABLE_CATEGORY_TEMPORARY)
2784
2705
Temporary tables' names change across runs, so they can't be used for
2787
2708
str->append(STRING_WITH_LEN("<temporary table>"));
2790
str->append(table_name, tab->table->getShare()->getTableNameSize());
2791
KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
2711
str->append(table_name, tab->table->s->table_name.length);
2712
KEY *key_info= tab->table->key_info+ tab->ref.key;
2792
2713
str->append(STRING_WITH_LEN(" on "));
2793
2714
str->append(key_info->name);
2811
2732
for (uint32_t i= 0; i < key_info->key_parts; i++)
2812
2733
tab->ref.items[i]->print(str);
2813
2734
str->append(STRING_WITH_LEN(" in "));
2814
str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
2735
str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2815
2736
str->append(STRING_WITH_LEN(" on "));
2816
2737
str->append(key_info->name);
2829
2750
str->append(STRING_WITH_LEN("<index_lookup>("));
2830
2751
tab->ref.items[0]->print(str, query_type);
2831
2752
str->append(STRING_WITH_LEN(" in "));
2832
str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
2833
KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
2753
str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2754
KEY *key_info= tab->table->key_info+ tab->ref.key;
2834
2755
str->append(STRING_WITH_LEN(" on "));
2835
2756
str->append(key_info->name);
2836
2757
if (check_null)
3007
2928
select_union *tmp_result_sink;
3008
2929
/* The table into which the subquery is materialized. */
3009
2930
Table *tmp_table;
3010
KeyInfo *tmp_key; /* The only index on the temporary table. */
2931
KEY *tmp_key; /* The only index on the temporary table. */
3011
2932
uint32_t tmp_key_parts; /* Number of keyparts in tmp_key. */
3012
2933
Item_in_subselect *item_in= (Item_in_subselect *) item;
3021
2942
if (!(tmp_result_sink= new select_union))
3024
2944
if (tmp_result_sink->create_result_table(
3025
2945
session, tmp_columns, true,
3026
2946
session->options | TMP_TABLE_ALL_COLUMNS,
3027
"materialized subselect"))
2947
"materialized subselect", true))
3030
2950
tmp_table= tmp_result_sink->table;
3038
2958
table since it will not be used, and tell the caller we failed to
3039
2959
initialize the engine.
3041
if (tmp_table->getShare()->sizeKeys() == 0)
2961
if (tmp_table->s->keys == 0)
3043
assert(tmp_table->getShare()->db_type() == myisam_engine);
2963
assert(tmp_table->s->db_type() == myisam_engine);
3045
tmp_table->getShare()->uniques ||
3046
tmp_table->key_info->key_length >= tmp_table->cursor->getEngine()->max_key_length() ||
3047
tmp_table->key_info->key_parts > tmp_table->cursor->getEngine()->max_key_parts());
2965
tmp_table->s->uniques ||
2966
tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
2967
tmp_table->key_info->key_parts > tmp_table->file->max_key_parts());
2968
tmp_table->free_tmp_table(session);
3056
2976
Make sure there is only one index on the temp table, and it doesn't have
3057
2977
the extra key part created when s->uniques > 0.
3059
assert(tmp_table->getShare()->sizeKeys() == 1 && tmp_columns->elements == tmp_key_parts);
2979
assert(tmp_table->s->keys == 1 && tmp_columns->elements == tmp_key_parts);
3062
2982
/* 2. Create/initialize execution related objects. */
3068
2988
- here we initialize only those members that are used by
3069
2989
subselect_uniquesubquery_engine, so these objects are incomplete.
3071
if (!(tab= (JoinTable*) session->getMemRoot()->allocate(sizeof(JoinTable))))
2991
if (!(tab= (JoinTable*) session->alloc(sizeof(JoinTable))))
3073
new (tab) JoinTable();
3074
2993
tab->table= tmp_table;
3075
2994
tab->ref.key= 0; /* The only temp table index. */
3076
2995
tab->ref.key_length= tmp_key->key_length;
3077
2996
if (!(tab->ref.key_buff=
3078
2997
(unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3079
2998
!(tab->ref.key_copy=
3080
(StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
2999
(StoredKey**) session->alloc((sizeof(StoredKey*) *
3081
3000
(tmp_key_parts + 1)))) ||
3082
3001
!(tab->ref.items=
3083
(Item**) session->getMemRoot()->allocate(sizeof(Item*) * tmp_key_parts)))
3002
(Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
3086
KeyPartInfo *cur_key_part= tmp_key->key_part;
3005
KEY_PART_INFO *cur_key_part= tmp_key->key_part;
3087
3006
StoredKey **ref_key= tab->ref.key_copy;
3088
3007
unsigned char *cur_ref_buff= tab->ref.key_buff;
3147
3064
Cleanup performed after each PS execution.
3150
Called in the end of Join::prepare for PS from Item_subselect::cleanup.
3067
Called in the end of JOIN::prepare for PS from Item_subselect::cleanup.
3153
3070
void subselect_hash_sj_engine::cleanup()
3185
3102
session->lex->current_select= materialize_engine->select_lex;
3186
3103
if ((res= materialize_join->optimize()))
3189
if (materialize_engine->save_join_if_explain())
3192
3105
materialize_join->exec();
3193
3106
if ((res= test(materialize_join->error || session->is_fatal_error)))
3198
3111
- Unlock all subquery tables as we don't need them. To implement this
3199
we need to add new functionality to Join::join_free that can unlock
3112
we need to add new functionality to JOIN::join_free that can unlock
3200
3113
all tables in a subquery (and all its subqueries).
3201
3114
- The temp table used for grouping in the subquery can be freed
3202
3115
immediately after materialization (yet it's done together with
3209
3122
statistics, then we test if the temporary table for the query result is
3212
tab->table->cursor->info(HA_STATUS_VARIABLE);
3213
if (!tab->table->cursor->stats.records)
3125
tab->table->file->info(HA_STATUS_VARIABLE);
3126
if (!tab->table->file->stats.records)
3215
3128
empty_result_set= true;
3216
3129
item_in->value= false;