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)
29
29
#include <limits.h>
31
#include <drizzled/session.h>
32
31
#include <drizzled/sql_select.h>
33
32
#include <drizzled/error.h>
34
33
#include <drizzled/item/cache.h>
40
39
#include <drizzled/item/ref_null_helper.h>
41
40
#include <drizzled/item/direct_ref.h>
42
41
#include <drizzled/join.h>
43
#include <drizzled/plugin/storage_engine.h>
44
#include <drizzled/select_singlerow_subselect.h>
45
#include <drizzled/select_max_min_finder_subselect.h>
46
#include <drizzled/select_exists_subselect.h>
47
#include <drizzled/select_union.h>
215
210
// did we changed top item of WHERE condition
216
211
if (unit->outer_select()->where == (*ref))
218
unit->outer_select()->where= substitution; // correct WHERE for PS
212
unit->outer_select()->where= substitution; // correct WHERE for PS
220
213
else if (unit->outer_select()->having == (*ref))
222
unit->outer_select()->having= substitution; // correct HAVING for PS
214
unit->outer_select()->having= substitution; // correct HAVING for PS
225
216
(*ref)= substitution;
226
217
substitution->name= name;
227
218
if (have_to_be_excluded)
232
session->setWhere("checking transformed subquery");
235
ret= (*ref)->fix_fields(session, ref);
237
session->setWhere(save_where);
221
session->where= "checking transformed subquery";
223
ret= (*ref)->fix_fields(session, ref);
224
session->where= save_where;
241
227
// Is it one field subselect?
252
if (engine->uncacheable())
238
if ((uncacheable= engine->uncacheable()))
254
const_item_cache= false;
255
if (engine->uncacheable(UNCACHEABLE_RAND))
241
if (uncacheable & UNCACHEABLE_RAND)
257
242
used_tables_cache|= RAND_TABLE_BIT;
263
session->setWhere(save_where);
247
session->where= save_where;
274
258
for (Select_Lex *lex= unit->first_select(); lex; lex= lex->next_select())
276
List<Item>::iterator li(lex->item_list.begin());
260
List_iterator<Item> li(lex->item_list);
280
264
if (lex->where && (lex->where)->walk(processor, walk_subquery, argument))
288
272
if (item->walk(processor, walk_subquery, argument))
291
for (order= (Order*) lex->order_list.first ; order; order= order->next)
275
for (order= (order_st*) lex->order_list.first ; order; order= order->next)
293
277
if ((*order->item)->walk(processor, walk_subquery, argument))
296
for (order= (Order*) lex->group_list.first ; order; order= order->next)
280
for (order= (order_st*) lex->group_list.first ; order; order= order->next)
298
282
if ((*order->item)->walk(processor, walk_subquery, argument))
398
382
void Item_subselect::update_used_tables()
400
if (! engine->uncacheable())
384
if (!engine->uncacheable())
402
386
// did all used tables become static?
403
387
if (!(used_tables_cache & ~engine->upper_select_const_tables()))
404
const_item_cache= true;
540
524
have_to_be_excluded= 1;
541
if (session->getLex()->describe)
525
if (session->lex->describe)
543
527
char warn_buff[DRIZZLE_ERRMSG_SIZE];
544
528
snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
836
int2_class_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
820
int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
837
821
return decimal_value;
954
938
if (was_null && !value)
956
int2_class_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
940
int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
957
941
return decimal_value;
1057
1041
upper_item->set_sum_test(item);
1058
1042
*select_lex->ref_pointer_array= item;
1060
List<Item>::iterator it(select_lex->item_list.begin());
1044
List_iterator<Item> it(select_lex->item_list);
1062
1046
it.replace(item);
1065
save_allow_sum_func= session->getLex()->allow_sum_func;
1066
session->getLex()->allow_sum_func|= 1 << session->getLex()->current_select->nest_level;
1049
save_allow_sum_func= session->lex->allow_sum_func;
1050
session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
1068
1052
Item_sum_(max|min) can't substitute other item => we can use 0 as
1069
1053
reference, also Item_sum_(max|min) can't be fixed after creation, so
1072
1056
if (item->fix_fields(session, 0))
1073
1057
return(RES_ERROR);
1074
session->getLex()->allow_sum_func= save_allow_sum_func;
1058
session->lex->allow_sum_func= save_allow_sum_func;
1075
1059
/* we added aggregate function => we have to change statistic */
1076
1060
count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
1096
1080
Select_Lex_Unit *master_unit= select_lex->master_unit();
1097
1081
substitution= optimizer;
1099
Select_Lex *current= session->getLex()->current_select, *up;
1083
Select_Lex *current= session->lex->current_select, *up;
1101
session->getLex()->current_select= up= current->return_after_parsing();
1085
session->lex->current_select= up= current->return_after_parsing();
1102
1086
//optimizer never use Item **ref => we can pass 0 as parameter
1103
1087
if (!optimizer || optimizer->fix_left(session, 0))
1105
session->getLex()->current_select= current;
1089
session->lex->current_select= current;
1106
1090
return(RES_ERROR);
1108
session->getLex()->current_select= current;
1092
session->lex->current_select= current;
1111
1095
As far as Item_ref_in_optimizer do not substitute itself on fix_fields
1116
1100
(char *)"<no matter>",
1117
1101
(char *)in_left_expr_name);
1119
master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
1103
master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1122
1106
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1124
if (!(pushed_cond_guards= (bool*)join->session->getMemRoot()->allocate(sizeof(bool))))
1108
if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool))))
1125
1109
return(RES_ERROR);
1126
1110
pushed_cond_guards[0]= true;
1180
1164
Select_Lex *select_lex= join->select_lex;
1182
select_lex->uncacheable.set(UNCACHEABLE_DEPENDENT);
1166
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1183
1167
if (join->having || select_lex->with_sum_func ||
1184
1168
select_lex->group_list.elements)
1228
1212
Item *having= item, *orig_item= item;
1229
select_lex->item_list.clear();
1213
select_lex->item_list.empty();
1230
1214
select_lex->item_list.push_back(new Item_int("Not_used",
1232
1216
MY_INT64_NUM_DECIMAL_DIGITS));
1334
1318
// fix_field of item will be done in time of substituting
1335
1319
substitution= item;
1336
1320
have_to_be_excluded= 1;
1337
if (session->getLex()->describe)
1321
if (session->lex->describe)
1339
1323
char warn_buff[DRIZZLE_ERRMSG_SIZE];
1340
1324
snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
1372
1356
Select_Lex_Unit *master_unit= select_lex->master_unit();
1373
1357
substitution= optimizer;
1375
Select_Lex *current= session->getLex()->current_select, *up;
1376
session->getLex()->current_select= up= current->return_after_parsing();
1359
Select_Lex *current= session->lex->current_select, *up;
1360
session->lex->current_select= up= current->return_after_parsing();
1377
1361
//optimizer never use Item **ref => we can pass 0 as parameter
1378
1362
if (!optimizer || optimizer->fix_left(session, 0))
1380
session->getLex()->current_select= current;
1364
session->lex->current_select= current;
1381
1365
return(RES_ERROR);
1384
1368
// we will refer to upper level cache array => we have to save it in PS
1385
1369
optimizer->keep_top_level_cache();
1387
session->getLex()->current_select= current;
1388
master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
1371
session->lex->current_select= current;
1372
master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1390
1374
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1392
if (!(pushed_cond_guards= (bool*)join->session->getMemRoot()->allocate(sizeof(bool) *
1376
if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool) *
1393
1377
left_expr->cols())))
1394
1378
return(RES_ERROR);
1395
1379
for (uint32_t i= 0; i < cols_num; i++)
1656
1640
Item_subselect::trans_res
1657
1641
Item_in_subselect::select_in_like_transformer(Join *join, const Comp_creator *func)
1659
Select_Lex *current= session->getLex()->current_select, *up;
1660
const char *save_where= session->where();
1643
Select_Lex *current= session->lex->current_select, *up;
1644
const char *save_where= session->where;
1661
1645
Item_subselect::trans_res res= RES_ERROR;
1694
session->getLex()->current_select= up= current->return_after_parsing();
1678
session->lex->current_select= up= current->return_after_parsing();
1695
1679
result= (!left_expr->fixed &&
1696
1680
left_expr->fix_fields(session, optimizer->arguments()));
1697
1681
/* fix_fields can change reference to left_expr, we need reassign it */
1698
1682
left_expr= optimizer->arguments()[0];
1700
session->getLex()->current_select= current;
1684
session->lex->current_select= current;
2038
2022
if (!join || !result)
2039
2023
return 1; /* Fatal error is set already. */
2041
Select_Lex *save_select= session->getLex()->current_select;
2042
session->getLex()->current_select= select_lex;
2025
Select_Lex *save_select= session->lex->current_select;
2026
session->lex->current_select= select_lex;
2043
2027
if (join->prepare(&select_lex->ref_pointer_array,
2044
2028
(TableList*) select_lex->table_list.first,
2045
2029
select_lex->with_wild,
2046
2030
select_lex->where,
2047
2031
select_lex->order_list.elements +
2048
2032
select_lex->group_list.elements,
2049
(Order*) select_lex->order_list.first,
2050
(Order*) select_lex->group_list.first,
2033
(order_st*) select_lex->order_list.first,
2034
(order_st*) select_lex->group_list.first,
2051
2035
select_lex->having,
2052
2036
select_lex, select_lex->master_unit()))
2054
session->getLex()->current_select= save_select;
2038
session->lex->current_select= save_select;
2096
2080
void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
2098
2082
Item *sel_item;
2099
List<Item>::iterator li(item_list.begin());
2083
List_iterator_fast<Item> li(item_list);
2100
2084
res_type= STRING_RESULT;
2101
2085
res_field_type= DRIZZLE_TYPE_VARCHAR;
2102
2086
for (uint32_t i= 0; (sel_item= li++); i++)
2134
int init_read_record_seq(JoinTable *tab);
2135
int join_read_always_key_or_null(JoinTable *tab);
2136
int join_read_next_same_or_null(ReadRecord *info);
2150
2138
int subselect_single_select_engine::exec()
2152
char const *save_where= session->where();
2153
Select_Lex *save_select= session->getLex()->current_select;
2154
session->getLex()->current_select= select_lex;
2140
char const *save_where= session->where;
2141
Select_Lex *save_select= session->lex->current_select;
2142
session->lex->current_select= select_lex;
2155
2143
if (!join->optimized)
2157
2145
Select_Lex_Unit *unit= select_lex->master_unit();
2159
2147
unit->set_limit(unit->global_parameters);
2160
2148
if (join->optimize())
2162
session->setWhere(save_where);
2150
session->where= save_where;
2164
session->getLex()->current_select= save_select;
2152
session->lex->current_select= save_select;
2165
2153
return(join->error ? join->error : 1);
2167
if (save_join_if_explain())
2155
if (!select_lex->uncacheable && session->lex->describe &&
2156
!(join->select_options & SELECT_DESCRIBE) &&
2157
join->need_tmp && item->const_item())
2160
Force join->join_tmp creation, because this subquery will be replaced
2161
by a simple select from the materialization temp table by optimize()
2162
called by EXPLAIN and we need to preserve the initial query structure
2163
so we can display it.
2165
select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
2166
select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
2167
if (join->init_save_join_tab())
2170
2170
if (item->engine_changed)
2175
if (select_lex->uncacheable.any() &&
2176
! select_lex->uncacheable.test(UNCACHEABLE_EXPLAIN) &&
2175
if (select_lex->uncacheable &&
2176
select_lex->uncacheable != UNCACHEABLE_EXPLAIN
2179
2179
if (join->reinit())
2181
session->setWhere(save_where);
2182
session->getLex()->current_select= save_select;
2181
session->where= save_where;
2182
session->lex->current_select= save_select;
2186
2186
item->assigned((executed= 0));
2237
2237
tab->read_record.read_record= tab->save_read_record;
2240
session->setWhere(save_where);
2241
session->getLex()->current_select= save_select;
2240
session->where= save_where;
2241
session->lex->current_select= save_select;
2242
2242
return(join->error||session->is_fatal_error);
2244
session->setWhere(save_where);
2245
session->getLex()->current_select= save_select;
2244
session->where= save_where;
2245
session->lex->current_select= save_select;
2250
subselect_single_select_engine::save_join_if_explain()
2253
Save this JOIN to join->tmp_join since the original layout will be
2254
replaced when JOIN::exec() calls make_simple_join() if:
2255
1) We are executing an EXPLAIN query
2256
2) An uncacheable flag has not been set for the select_lex. If
2257
set, JOIN::optimize() has already saved the JOIN
2258
3) Call does not come from select_describe()). If it does,
2259
JOIN::exec() will not call make_simple_join() and the JOIN we
2260
plan to save will not be replaced anyway.
2261
4) A temp table is needed. This is what triggers JOIN::exec() to
2262
make a replacement JOIN by calling make_simple_join().
2263
5) The Item_subselect is cacheable
2265
if (session->getLex()->describe && // 1
2266
select_lex->uncacheable.none() && // 2
2267
!(join->select_options & SELECT_DESCRIBE) && // 3
2268
join->need_tmp && // 4
2269
item->const_item()) // 5
2272
Save this JOIN to join->tmp_join since the original layout will
2273
be replaced when JOIN::exec() calls make_simple_join() due to
2274
need_tmp==TRUE. The original layout is needed so we can describe
2275
the query. No need to do this if uncacheable != 0 since in this
2276
case the JOIN has already been saved during JOIN::optimize()
2278
select_lex->uncacheable.set(UNCACHEABLE_EXPLAIN);
2279
select_lex->master_unit()->uncacheable.set(UNCACHEABLE_EXPLAIN);
2280
if (join->init_save_join_tab())
2287
2249
int subselect_union_engine::exec()
2289
char const *save_where= session->where();
2251
char const *save_where= session->where;
2290
2252
int res= unit->exec();
2291
session->setWhere(save_where);
2253
session->where= save_where;
2320
2281
if (table->cursor->inited)
2321
2282
table->cursor->endIndexScan();
2323
if ((error= table->cursor->startTableScan(1)))
2325
table->print_error(error, MYF(0));
2329
assert(table->getSession());
2284
table->cursor->startTableScan(1);
2330
2285
table->cursor->extra_opt(HA_EXTRA_CACHE,
2331
table->getSession()->variables.read_buff_size);
2286
current_session->variables.read_buff_size);
2332
2287
table->null_row= 0;
2503
2458
return(scan_table());
2505
2460
if (!table->cursor->inited)
2507
error= table->cursor->startIndexScan(tab->ref.key, 0);
2511
error= table->report_error(error);
2512
return (error != 0);
2461
table->cursor->startIndexScan(tab->ref.key, 0);
2516
2462
error= table->cursor->index_read_map(table->record[0],
2517
2463
tab->ref.key_buff,
2518
2464
make_prev_keypart_map(tab->ref.key_parts),
2625
2571
return(scan_table());
2627
2573
if (!table->cursor->inited)
2629
error= table->cursor->startIndexScan(tab->ref.key, 1);
2633
error= table->report_error(error);
2574
table->cursor->startIndexScan(tab->ref.key, 1);
2637
2575
error= table->cursor->index_read_map(table->record[0],
2638
2576
tab->ref.key_buff,
2639
2577
make_prev_keypart_map(tab->ref.key_parts),
2698
bool subselect_single_select_engine::uncacheable()
2700
return select_lex->uncacheable.any();
2704
bool subselect_single_select_engine::uncacheable(uint32_t bit_pos)
2706
return select_lex->uncacheable.test(bit_pos);
2710
bool subselect_union_engine::uncacheable()
2712
return unit->uncacheable.any();
2716
bool subselect_union_engine::uncacheable(uint32_t bit_pos)
2718
return unit->uncacheable.test(bit_pos);
2636
uint8_t subselect_single_select_engine::uncacheable()
2638
return select_lex->uncacheable;
2642
uint8_t subselect_union_engine::uncacheable()
2644
return unit->uncacheable;
2779
2705
void subselect_uniquesubquery_engine::print(String *str,
2780
2706
enum_query_type query_type)
2782
const char *table_name= tab->table->getShare()->getTableName();
2708
char *table_name= const_cast<char *>(tab->table->getShare()->getTableName());
2783
2709
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2784
2710
tab->ref.items[0]->print(str, query_type);
2785
2711
str->append(STRING_WITH_LEN(" in "));
3073
2999
- here we initialize only those members that are used by
3074
3000
subselect_uniquesubquery_engine, so these objects are incomplete.
3076
if (!(tab= (JoinTable*) session->getMemRoot()->allocate(sizeof(JoinTable))))
3002
if (!(tab= (JoinTable*) session->alloc(sizeof(JoinTable))))
3078
new (tab) JoinTable();
3079
3004
tab->table= tmp_table;
3080
3005
tab->ref.key= 0; /* The only temp table index. */
3081
3006
tab->ref.key_length= tmp_key->key_length;
3082
3007
if (!(tab->ref.key_buff=
3083
3008
(unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3084
3009
!(tab->ref.key_copy=
3085
(StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
3010
(StoredKey**) session->alloc((sizeof(StoredKey*) *
3086
3011
(tmp_key_parts + 1)))) ||
3087
3012
!(tab->ref.items=
3088
(Item**) session->getMemRoot()->allocate(sizeof(Item*) * tmp_key_parts)))
3013
(Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
3091
3016
KeyPartInfo *cur_key_part= tmp_key->key_part;
3186
3111
if (!is_materialized)
3189
Select_Lex *save_select= session->getLex()->current_select;
3190
session->getLex()->current_select= materialize_engine->select_lex;
3114
Select_Lex *save_select= session->lex->current_select;
3115
session->lex->current_select= materialize_engine->select_lex;
3191
3116
if ((res= materialize_join->optimize()))
3194
if (materialize_engine->save_join_if_explain())
3197
3118
materialize_join->exec();
3198
3119
if ((res= test(materialize_join->error || session->is_fatal_error)))