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))
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;
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);
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++)
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(JOIN_TAB *tab);
2124
int join_read_always_key_or_null(JOIN_TAB *tab);
2125
int join_read_next_same_or_null(READ_RECORD *info);
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)
2152
2134
Select_Lex_Unit *unit= select_lex->master_unit();
2154
2136
unit->set_limit(unit->global_parameters);
2137
if (join->flatten_subqueries())
2139
session->is_fatal_error= true;
2155
2142
if (join->optimize())
2157
session->setWhere(save_where);
2144
session->where= save_where;
2159
2146
session->lex->current_select= save_select;
2160
2147
return(join->error ? join->error : 1);
2162
if (save_join_if_explain())
2149
if (!select_lex->uncacheable && session->lex->describe &&
2150
!(join->select_options & SELECT_DESCRIBE) &&
2151
join->need_tmp && item->const_item())
2154
Force join->join_tmp creation, because this subquery will be replaced
2155
by a simple select from the materialization temp table by optimize()
2156
called by EXPLAIN and we need to preserve the initial query structure
2157
so we can display it.
2159
select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
2160
select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
2161
if (join->init_save_join_tab())
2162
return(1); /* purecov: inspected */
2165
2164
if (item->engine_changed)
2170
if (select_lex->uncacheable.any() &&
2171
! select_lex->uncacheable.test(UNCACHEABLE_EXPLAIN) &&
2169
if (select_lex->uncacheable &&
2170
select_lex->uncacheable != UNCACHEABLE_EXPLAIN
2174
2173
if (join->reinit())
2176
session->setWhere(save_where);
2175
session->where= save_where;
2177
2176
session->lex->current_select= save_select;
2181
2180
item->assigned((executed= 0));
2185
2184
item->reset_value_registration();
2186
JoinTable *changed_tabs[MAX_TABLES];
2187
JoinTable **last_changed_tab= changed_tabs;
2185
JOIN_TAB *changed_tabs[MAX_TABLES];
2186
JOIN_TAB **last_changed_tab= changed_tabs;
2188
2187
if (item->have_guarded_conds())
2211
2210
tab->read_first_record= init_read_record_seq;
2212
2211
tab->read_record.record= tab->table->record[0];
2213
2212
tab->read_record.session= join->session;
2214
tab->read_record.ref_length= tab->table->cursor->ref_length;
2213
tab->read_record.ref_length= tab->table->file->ref_length;
2215
2214
*(last_changed_tab++)= tab;
2225
2224
/* Enable the optimizations back */
2226
for (JoinTable **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
2225
for (JOIN_TAB **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
2228
JoinTable *tab= *ptab;
2227
JOIN_TAB *tab= *ptab;
2229
2228
tab->read_record.record= 0;
2230
2229
tab->read_record.ref_length= 0;
2231
2230
tab->read_first_record= tab->save_read_first_record;
2232
2231
tab->read_record.read_record= tab->save_read_record;
2235
session->setWhere(save_where);
2234
session->where= save_where;
2236
2235
session->lex->current_select= save_select;
2237
2236
return(join->error||session->is_fatal_error);
2239
session->setWhere(save_where);
2238
session->where= save_where;
2240
2239
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
2243
int subselect_union_engine::exec()
2284
char const *save_where= session->where();
2245
char const *save_where= session->where;
2285
2246
int res= unit->exec();
2286
session->setWhere(save_where);
2247
session->where= save_where;
2313
2273
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);
2275
if (table->file->inited)
2276
table->file->ha_index_end();
2278
table->file->ha_rnd_init(1);
2279
table->file->extra_opt(HA_EXTRA_CACHE,
2280
current_session->variables.read_buff_size);
2327
2281
table->null_row= 0;
2330
error=table->cursor->rnd_next(table->record[0]);
2284
error=table->file->rnd_next(table->record[0]);
2331
2285
if (error && error != HA_ERR_END_OF_FILE)
2333
2287
error= table->report_error(error);
2394
2348
bool subselect_uniquesubquery_engine::copy_ref_key()
2396
for (StoredKey **copy= tab->ref.key_copy ; *copy ; copy++)
2350
for (store_key **copy= tab->ref.key_copy ; *copy ; copy++)
2398
StoredKey::store_key_result store_res= (*copy)->copy();
2352
enum store_key::store_key_result store_res;
2353
store_res= (*copy)->copy();
2399
2354
tab->ref.key_err= store_res;
2426
2381
Check if the error is equal to STORE_KEY_FATAL. This is not expressed
2427
using the StoredKey::store_key_result enum because ref.key_err is a
2382
using the store_key::store_key_result enum because ref.key_err is a
2428
2383
boolean and we want to detect both true and STORE_KEY_FATAL from the
2429
2384
space of the union of the values of [true, false] and
2430
StoredKey::store_key_result.
2385
store_key::store_key_result.
2431
2386
TODO: fix the variable an return types.
2433
if (store_res == StoredKey::STORE_KEY_FATAL)
2388
if (store_res == store_key::STORE_KEY_FATAL)
2436
2391
Error converting the left IN operand to the column type of the right
2497
2452
if (null_keypart)
2498
2453
return(scan_table());
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],
2455
if (!table->file->inited)
2456
table->file->ha_index_init(tab->ref.key, 0);
2457
error= table->file->index_read_map(table->record[0],
2512
2458
tab->ref.key_buff,
2513
2459
make_prev_keypart_map(tab->ref.key_parts),
2514
2460
HA_READ_KEY_EXACT);
2619
2565
if (null_keypart)
2620
2566
return(scan_table());
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],
2568
if (!table->file->inited)
2569
table->file->ha_index_init(tab->ref.key, 1);
2570
error= table->file->index_read_map(table->record[0],
2633
2571
tab->ref.key_buff,
2634
2572
make_prev_keypart_map(tab->ref.key_parts),
2635
2573
HA_READ_KEY_EXACT);
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);
2631
uint8_t subselect_single_select_engine::uncacheable()
2633
return select_lex->uncacheable;
2637
uint8_t subselect_union_engine::uncacheable()
2639
return unit->uncacheable;
2774
2700
void subselect_uniquesubquery_engine::print(String *str,
2775
2701
enum_query_type query_type)
2777
char *table_name= const_cast<char *>(tab->table->getShare()->getTableName());
2703
char *table_name= tab->table->s->table_name.str;
2778
2704
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2779
2705
tab->ref.items[0]->print(str, query_type);
2780
2706
str->append(STRING_WITH_LEN(" in "));
2781
if (tab->table->getShare()->isTemporaryCategory())
2707
if (tab->table->s->table_category == TABLE_CATEGORY_TEMPORARY)
2784
2710
Temporary tables' names change across runs, so they can't be used for
2787
2713
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;
2716
str->append(table_name, tab->table->s->table_name.length);
2717
KEY *key_info= tab->table->key_info+ tab->ref.key;
2792
2718
str->append(STRING_WITH_LEN(" on "));
2793
2719
str->append(key_info->name);
2811
2737
for (uint32_t i= 0; i < key_info->key_parts; i++)
2812
2738
tab->ref.items[i]->print(str);
2813
2739
str->append(STRING_WITH_LEN(" in "));
2814
str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
2740
str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2815
2741
str->append(STRING_WITH_LEN(" on "));
2816
2742
str->append(key_info->name);
2829
2755
str->append(STRING_WITH_LEN("<index_lookup>("));
2830
2756
tab->ref.items[0]->print(str, query_type);
2831
2757
str->append(STRING_WITH_LEN(" in "));
2832
str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
2833
KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
2758
str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2759
KEY *key_info= tab->table->key_info+ tab->ref.key;
2834
2760
str->append(STRING_WITH_LEN(" on "));
2835
2761
str->append(key_info->name);
2836
2762
if (check_null)
2990
2916
temporary table has one hash index on all its columns.
2991
2917
- Create a new result sink that sends the result stream of the subquery to
2992
2918
the temporary table,
2993
- Create and initialize a new JoinTable, and TABLE_REF objects to perform
2919
- Create and initialize a new JOIN_TAB, and TABLE_REF objects to perform
2994
2920
lookups into the indexed temporary table.
3007
2933
select_union *tmp_result_sink;
3008
2934
/* The table into which the subquery is materialized. */
3009
2935
Table *tmp_table;
3010
KeyInfo *tmp_key; /* The only index on the temporary table. */
2936
KEY *tmp_key; /* The only index on the temporary table. */
3011
2937
uint32_t tmp_key_parts; /* Number of keyparts in tmp_key. */
3012
2938
Item_in_subselect *item_in= (Item_in_subselect *) item;
3021
2947
if (!(tmp_result_sink= new select_union))
3024
2949
if (tmp_result_sink->create_result_table(
3025
2950
session, tmp_columns, true,
3026
2951
session->options | TMP_TABLE_ALL_COLUMNS,
3027
"materialized subselect"))
2952
"materialized subselect", true))
3030
2955
tmp_table= tmp_result_sink->table;
3038
2963
table since it will not be used, and tell the caller we failed to
3039
2964
initialize the engine.
3041
if (tmp_table->getShare()->sizeKeys() == 0)
2966
if (tmp_table->s->keys == 0)
3043
assert(tmp_table->getShare()->db_type() == myisam_engine);
2968
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());
2970
tmp_table->s->uniques ||
2971
tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
2972
tmp_table->key_info->key_parts > tmp_table->file->max_key_parts());
2973
tmp_table->free_tmp_table(session);
3056
2981
Make sure there is only one index on the temp table, and it doesn't have
3057
2982
the extra key part created when s->uniques > 0.
3059
assert(tmp_table->getShare()->sizeKeys() == 1 && tmp_columns->elements == tmp_key_parts);
2984
assert(tmp_table->s->keys == 1 && tmp_columns->elements == tmp_key_parts);
3062
2987
/* 2. Create/initialize execution related objects. */
3065
Create and initialize the JoinTable that represents an index lookup
2990
Create and initialize the JOIN_TAB that represents an index lookup
3066
2991
plan operator into the materialized subquery result. Notice that:
3067
- this JoinTable has no corresponding JOIN (and doesn't need one), and
2992
- this JOIN_TAB has no corresponding JOIN (and doesn't need one), and
3068
2993
- here we initialize only those members that are used by
3069
2994
subselect_uniquesubquery_engine, so these objects are incomplete.
3071
if (!(tab= (JoinTable*) session->getMemRoot()->allocate(sizeof(JoinTable))))
2996
if (!(tab= (JOIN_TAB*) session->alloc(sizeof(JOIN_TAB))))
3073
new (tab) JoinTable();
3074
2998
tab->table= tmp_table;
3075
2999
tab->ref.key= 0; /* The only temp table index. */
3076
3000
tab->ref.key_length= tmp_key->key_length;
3077
3001
if (!(tab->ref.key_buff=
3078
3002
(unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3079
3003
!(tab->ref.key_copy=
3080
(StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
3004
(store_key**) session->alloc((sizeof(store_key*) *
3081
3005
(tmp_key_parts + 1)))) ||
3082
3006
!(tab->ref.items=
3083
(Item**) session->getMemRoot()->allocate(sizeof(Item*) * tmp_key_parts)))
3007
(Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
3086
KeyPartInfo *cur_key_part= tmp_key->key_part;
3087
StoredKey **ref_key= tab->ref.key_copy;
3010
KEY_PART_INFO *cur_key_part= tmp_key->key_part;
3011
store_key **ref_key= tab->ref.key_copy;
3088
3012
unsigned char *cur_ref_buff= tab->ref.key_buff;
3090
3014
for (uint32_t i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3198
3116
- Unlock all subquery tables as we don't need them. To implement this
3199
we need to add new functionality to Join::join_free that can unlock
3117
we need to add new functionality to JOIN::join_free that can unlock
3200
3118
all tables in a subquery (and all its subqueries).
3201
3119
- The temp table used for grouping in the subquery can be freed
3202
3120
immediately after materialization (yet it's done together with
3209
3127
statistics, then we test if the temporary table for the query result is
3212
tab->table->cursor->info(HA_STATUS_VARIABLE);
3213
if (!tab->table->cursor->stats.records)
3130
tab->table->file->info(HA_STATUS_VARIABLE);
3131
if (!tab->table->file->stats.records)
3215
3133
empty_result_set= true;
3216
3134
item_in->value= false;