23
- add function from mysql_select that use JOIN* as parameter to JOIN
23
- add function from select_query 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>
31
32
#include <drizzled/sql_select.h>
32
33
#include <drizzled/error.h>
33
34
#include <drizzled/item/cache.h>
39
40
#include <drizzled/item/ref_null_helper.h>
40
41
#include <drizzled/item/direct_ref.h>
41
42
#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>
223
229
engine->exclude();
226
session->where= "checking transformed subquery";
232
session->setWhere("checking transformed subquery");
227
233
if (! (*ref)->fixed)
229
235
ret= (*ref)->fix_fields(session, ref);
231
session->where= save_where;
237
session->setWhere(save_where);
234
241
// Is it one field subselect?
395
402
// did all used tables become static?
396
403
if (!(used_tables_cache & ~engine->upper_select_const_tables()))
404
const_item_cache= true;
402
void Item_subselect::print(String *str, enum_query_type query_type)
409
void Item_subselect::print(String *str)
404
411
str->append('(');
405
engine->print(str, query_type);
406
413
str->append(')');
483
void Item_maxmin_subselect::print(String *str, enum_query_type query_type)
490
void Item_maxmin_subselect::print(String *str)
485
492
str->append(max?"<max>":"<min>", 5);
486
Item_singlerow_subselect::print(str, query_type);
493
Item_singlerow_subselect::print(str);
516
523
if (!select_lex->master_unit()->is_union() &&
517
524
!select_lex->table_list.elements &&
518
select_lex->item_list.elements == 1 &&
519
!select_lex->item_list.head()->with_sum_func &&
525
select_lex->item_list.size() == 1 &&
526
!select_lex->item_list.front().with_sum_func &&
521
528
We cant change name of Item_field or Item_ref, because it will
522
529
prevent it's correct resolving, but we should save name of
524
531
list is field or reference.
525
532
TODO: solve above problem
527
!(select_lex->item_list.head()->type() == FIELD_ITEM ||
528
select_lex->item_list.head()->type() == REF_ITEM) &&
534
!(select_lex->item_list.front().type() == FIELD_ITEM ||
535
select_lex->item_list.front().type() == REF_ITEM) &&
529
536
!join->conds && !join->having
533
540
have_to_be_excluded= 1;
534
if (session->lex->describe)
541
if (session->getLex()->describe)
536
543
char warn_buff[DRIZZLE_ERRMSG_SIZE];
537
544
snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
538
545
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
539
546
ER_SELECT_REDUCED, warn_buff);
541
substitution= select_lex->item_list.head();
548
substitution= &select_lex->item_list.front();
543
550
as far as we moved content to upper level, field which depend of
544
551
'upper' select is not really dependent => we remove this dependence
714
void Item_exists_subselect::print(String *str, enum_query_type query_type)
721
void Item_exists_subselect::print(String *str)
716
723
str->append(STRING_WITH_LEN("exists"));
717
Item_subselect::print(str, query_type);
724
Item_subselect::print(str);
829
int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
836
int2_class_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
830
837
return decimal_value;
947
954
if (was_null && !value)
949
int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
956
int2_class_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
950
957
return decimal_value;
995
1002
Check that the right part of the subselect contains no more than one
996
1003
column. E.g. in SELECT 1 IN (SELECT * ..) the right part is (SELECT * ...)
998
if (select_lex->item_list.elements > 1)
1005
if (select_lex->item_list.size() > 1)
1000
1007
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
1001
1008
return(RES_ERROR);
1050
1057
upper_item->set_sum_test(item);
1051
1058
*select_lex->ref_pointer_array= item;
1053
List_iterator<Item> it(select_lex->item_list);
1060
List<Item>::iterator it(select_lex->item_list.begin());
1055
1062
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;
1065
save_allow_sum_func= session->getLex()->allow_sum_func;
1066
session->getLex()->allow_sum_func|= 1 << session->getLex()->current_select->nest_level;
1061
1068
Item_sum_(max|min) can't substitute other item => we can use 0 as
1062
1069
reference, also Item_sum_(max|min) can't be fixed after creation, so
1065
1072
if (item->fix_fields(session, 0))
1066
1073
return(RES_ERROR);
1067
session->lex->allow_sum_func= save_allow_sum_func;
1074
session->getLex()->allow_sum_func= save_allow_sum_func;
1068
1075
/* we added aggregate function => we have to change statistic */
1069
1076
count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
1089
1096
Select_Lex_Unit *master_unit= select_lex->master_unit();
1090
1097
substitution= optimizer;
1092
Select_Lex *current= session->lex->current_select, *up;
1099
Select_Lex *current= session->getLex()->current_select, *up;
1094
session->lex->current_select= up= current->return_after_parsing();
1101
session->getLex()->current_select= up= current->return_after_parsing();
1095
1102
//optimizer never use Item **ref => we can pass 0 as parameter
1096
1103
if (!optimizer || optimizer->fix_left(session, 0))
1098
session->lex->current_select= current;
1105
session->getLex()->current_select= current;
1099
1106
return(RES_ERROR);
1101
session->lex->current_select= current;
1108
session->getLex()->current_select= current;
1104
1111
As far as Item_ref_in_optimizer do not substitute itself on fix_fields
1201
1208
select_lex->having= join->having= and_items(join->having, item);
1202
1209
if (join->having == item)
1203
1210
item->name= (char*)in_having_cond;
1211
select_lex->having->top_level_item();
1204
1212
select_lex->having_fix_field= 1;
1206
1214
we do not check join->having->fixed, because Item_and (from and_items)
1216
Item *item= (Item*) select_lex->item_list.head();
1224
Item *item= &select_lex->item_list.front();
1218
1226
if (select_lex->table_list.elements)
1221
1229
Item *having= item, *orig_item= item;
1222
select_lex->item_list.empty();
1230
select_lex->item_list.clear();
1223
1231
select_lex->item_list.push_back(new Item_int("Not_used",
1225
1233
MY_INT64_NUM_DECIMAL_DIGITS));
1226
select_lex->ref_pointer_array[0]= select_lex->item_list.head();
1234
select_lex->ref_pointer_array[0]= &select_lex->item_list.front();
1228
1236
item= func->create(expr, item);
1229
1237
if (!abort_on_null && orig_item->maybe_null)
1327
1335
// fix_field of item will be done in time of substituting
1328
1336
substitution= item;
1329
1337
have_to_be_excluded= 1;
1330
if (session->lex->describe)
1338
if (session->getLex()->describe)
1332
1340
char warn_buff[DRIZZLE_ERRMSG_SIZE];
1333
1341
snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
1349
1357
Select_Lex *select_lex= join->select_lex;
1350
1358
uint32_t cols_num= left_expr->cols();
1352
if (select_lex->item_list.elements != left_expr->cols())
1360
if (select_lex->item_list.size() != left_expr->cols())
1354
1362
my_error(ER_OPERAND_COLUMNS, MYF(0), left_expr->cols());
1355
1363
return(RES_ERROR);
1365
1373
Select_Lex_Unit *master_unit= select_lex->master_unit();
1366
1374
substitution= optimizer;
1368
Select_Lex *current= session->lex->current_select, *up;
1369
session->lex->current_select= up= current->return_after_parsing();
1376
Select_Lex *current= session->getLex()->current_select, *up;
1377
session->getLex()->current_select= up= current->return_after_parsing();
1370
1378
//optimizer never use Item **ref => we can pass 0 as parameter
1371
1379
if (!optimizer || optimizer->fix_left(session, 0))
1373
session->lex->current_select= current;
1381
session->getLex()->current_select= current;
1374
1382
return(RES_ERROR);
1377
1385
// we will refer to upper level cache array => we have to save it in PS
1378
1386
optimizer->keep_top_level_cache();
1380
session->lex->current_select= current;
1388
session->getLex()->current_select= current;
1381
1389
master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
1383
1391
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1385
if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool) *
1393
if (!(pushed_cond_guards= (bool*)join->session->getMemRoot()->allocate(sizeof(bool) *
1386
1394
left_expr->cols())))
1387
1395
return(RES_ERROR);
1388
1396
for (uint32_t i= 0; i < cols_num; i++)
1649
1657
Item_subselect::trans_res
1650
1658
Item_in_subselect::select_in_like_transformer(Join *join, const Comp_creator *func)
1652
Select_Lex *current= session->lex->current_select, *up;
1653
const char *save_where= session->where;
1660
Select_Lex *current= session->getLex()->current_select, *up;
1661
const char *save_where= session->where();
1654
1662
Item_subselect::trans_res res= RES_ERROR;
1687
session->lex->current_select= up= current->return_after_parsing();
1695
session->getLex()->current_select= up= current->return_after_parsing();
1688
1696
result= (!left_expr->fixed &&
1689
1697
left_expr->fix_fields(session, optimizer->arguments()));
1690
1698
/* fix_fields can change reference to left_expr, we need reassign it */
1691
1699
left_expr= optimizer->arguments()[0];
1693
session->lex->current_select= current;
1701
session->getLex()->current_select= current;
1721
1729
res= row_value_transformer(join);
1724
session->where= save_where;
1732
session->setWhere(save_where);
1729
void Item_in_subselect::print(String *str, enum_query_type query_type)
1737
void Item_in_subselect::print(String *str)
1731
1739
if (exec_method == IN_TO_EXISTS)
1732
1740
str->append(STRING_WITH_LEN("<exists>"));
1735
left_expr->print(str, query_type);
1743
left_expr->print(str);
1736
1744
str->append(STRING_WITH_LEN(" in "));
1738
Item_subselect::print(str, query_type);
1746
Item_subselect::print(str);
1901
void Item_allany_subselect::print(String *str, enum_query_type query_type)
1909
void Item_allany_subselect::print(String *str)
1903
1911
if (exec_method == IN_TO_EXISTS)
1904
1912
str->append(STRING_WITH_LEN("<exists>"));
1907
left_expr->print(str, query_type);
1915
left_expr->print(str);
1908
1916
str->append(' ');
1909
1917
str->append(func->symbol(all));
1910
1918
str->append(all ? " all " : " any ", 5);
1912
Item_subselect::print(str, query_type);
1920
Item_subselect::print(str);
2031
2039
if (!join || !result)
2032
2040
return 1; /* Fatal error is set already. */
2034
Select_Lex *save_select= session->lex->current_select;
2035
session->lex->current_select= select_lex;
2042
Select_Lex *save_select= session->getLex()->current_select;
2043
session->getLex()->current_select= select_lex;
2036
2044
if (join->prepare(&select_lex->ref_pointer_array,
2037
2045
(TableList*) select_lex->table_list.first,
2038
2046
select_lex->with_wild,
2089
2097
void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
2091
2099
Item *sel_item;
2092
List_iterator_fast<Item> li(item_list);
2100
List<Item>::iterator li(item_list.begin());
2093
2101
res_type= STRING_RESULT;
2094
2102
res_field_type= DRIZZLE_TYPE_VARCHAR;
2095
2103
for (uint32_t i= 0; (sel_item= li++); i++)
2105
2113
row[i]->setup(sel_item);
2107
if (item_list.elements > 1)
2115
if (item_list.size() > 1)
2108
2116
res_type= ROW_RESULT;
2111
2119
void subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
2113
assert(row || select_lex->item_list.elements==1);
2121
assert(row || select_lex->item_list.size() == 1);
2114
2122
set_row(select_lex->item_list, row);
2115
2123
item->collation.set(row[0]->collation);
2116
2124
if (cols() != 1)
2120
2128
void subselect_union_engine::fix_length_and_dec(Item_cache **row)
2122
assert(row || unit->first_select()->item_list.elements==1);
2130
assert(row || unit->first_select()->item_list.size() == 1);
2124
if (unit->first_select()->item_list.elements == 1)
2132
if (unit->first_select()->item_list.size() == 1)
2126
2134
set_row(unit->types, row);
2127
2135
item->collation.set(row[0]->collation);
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);
2147
2151
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;
2153
char const *save_where= session->where();
2154
Select_Lex *save_select= session->getLex()->current_select;
2155
session->getLex()->current_select= select_lex;
2152
2156
if (!join->optimized)
2154
2158
Select_Lex_Unit *unit= select_lex->master_unit();
2156
2160
unit->set_limit(unit->global_parameters);
2157
2161
if (join->optimize())
2159
session->where= save_where;
2163
session->setWhere(save_where);
2161
session->lex->current_select= save_select;
2165
session->getLex()->current_select= save_select;
2162
2166
return(join->error ? join->error : 1);
2164
if (select_lex->uncacheable.none() && session->lex->describe &&
2165
!(join->select_options & SELECT_DESCRIBE) &&
2166
join->need_tmp && item->const_item())
2169
Force join->join_tmp creation, because this subquery will be replaced
2170
by a simple select from the materialization temp table by optimize()
2171
called by EXPLAIN and we need to preserve the initial query structure
2172
so we can display it.
2174
select_lex->uncacheable.set(UNCACHEABLE_EXPLAIN);
2175
select_lex->master_unit()->uncacheable.set(UNCACHEABLE_EXPLAIN);
2176
if (join->init_save_join_tab())
2168
if (save_join_if_explain())
2179
2171
if (item->engine_changed)
2246
2238
tab->read_record.read_record= tab->save_read_record;
2249
session->where= save_where;
2250
session->lex->current_select= save_select;
2241
session->setWhere(save_where);
2242
session->getLex()->current_select= save_select;
2251
2243
return(join->error||session->is_fatal_error);
2253
session->where= save_where;
2254
session->lex->current_select= save_select;
2245
session->setWhere(save_where);
2246
session->getLex()->current_select= save_select;
2251
subselect_single_select_engine::save_join_if_explain()
2254
Save this JOIN to join->tmp_join since the original layout will be
2255
replaced when JOIN::exec() calls make_simple_join() if:
2256
1) We are executing an EXPLAIN query
2257
2) An uncacheable flag has not been set for the select_lex. If
2258
set, JOIN::optimize() has already saved the JOIN
2259
3) Call does not come from select_describe()). If it does,
2260
JOIN::exec() will not call make_simple_join() and the JOIN we
2261
plan to save will not be replaced anyway.
2262
4) A temp table is needed. This is what triggers JOIN::exec() to
2263
make a replacement JOIN by calling make_simple_join().
2264
5) The Item_subselect is cacheable
2266
if (session->getLex()->describe && // 1
2267
select_lex->uncacheable.none() && // 2
2268
!(join->select_options & SELECT_DESCRIBE) && // 3
2269
join->need_tmp && // 4
2270
item->const_item()) // 5
2273
Save this JOIN to join->tmp_join since the original layout will
2274
be replaced when JOIN::exec() calls make_simple_join() due to
2275
need_tmp==TRUE. The original layout is needed so we can describe
2276
the query. No need to do this if uncacheable != 0 since in this
2277
case the JOIN has already been saved during JOIN::optimize()
2279
select_lex->uncacheable.set(UNCACHEABLE_EXPLAIN);
2280
select_lex->master_unit()->uncacheable.set(UNCACHEABLE_EXPLAIN);
2281
if (join->init_save_join_tab())
2258
2288
int subselect_union_engine::exec()
2260
char const *save_where= session->where;
2290
char const *save_where= session->where();
2261
2291
int res= unit->exec();
2262
session->where= save_where;
2292
session->setWhere(save_where);
2290
2321
if (table->cursor->inited)
2291
2322
table->cursor->endIndexScan();
2293
table->cursor->startTableScan(1);
2324
if ((error= table->cursor->startTableScan(1)))
2326
table->print_error(error, MYF(0));
2330
assert(table->getSession());
2294
2331
table->cursor->extra_opt(HA_EXTRA_CACHE,
2295
current_session->variables.read_buff_size);
2332
table->getSession()->variables.read_buff_size);
2296
2333
table->null_row= 0;
2467
2504
return(scan_table());
2469
2506
if (!table->cursor->inited)
2470
table->cursor->startIndexScan(tab->ref.key, 0);
2508
error= table->cursor->startIndexScan(tab->ref.key, 0);
2512
error= table->report_error(error);
2513
return (error != 0);
2471
2517
error= table->cursor->index_read_map(table->record[0],
2472
2518
tab->ref.key_buff,
2473
2519
make_prev_keypart_map(tab->ref.key_parts),
2580
2626
return(scan_table());
2582
2628
if (!table->cursor->inited)
2583
table->cursor->startIndexScan(tab->ref.key, 1);
2630
error= table->cursor->startIndexScan(tab->ref.key, 1);
2634
error= table->report_error(error);
2584
2638
error= table->cursor->index_read_map(table->record[0],
2585
2639
tab->ref.key_buff,
2586
2640
make_prev_keypart_map(tab->ref.key_parts),
2633
2687
uint32_t subselect_single_select_engine::cols()
2635
return select_lex->item_list.elements;
2689
return select_lex->item_list.size();
2639
2693
uint32_t subselect_union_engine::cols()
2641
return unit->types.elements;
2695
return unit->types.size();
2713
void subselect_single_select_engine::print(String *str,
2714
enum_query_type query_type)
2716
select_lex->print(session, str, query_type);
2720
void subselect_union_engine::print(String *str, enum_query_type query_type)
2722
unit->print(str, query_type);
2726
void subselect_uniquesubquery_engine::print(String *str,
2727
enum_query_type query_type)
2729
char *table_name= const_cast<char *>(tab->table->getShare()->getTableName());
2767
void subselect_single_select_engine::print(String *str)
2769
select_lex->print(session, str);
2773
void subselect_union_engine::print(String *str)
2779
void subselect_uniquesubquery_engine::print(String *str)
2781
const char *table_name= tab->table->getShare()->getTableName();
2730
2782
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2731
tab->ref.items[0]->print(str, query_type);
2783
tab->ref.items[0]->print(str);
2732
2784
str->append(STRING_WITH_LEN(" in "));
2733
2785
if (tab->table->getShare()->isTemporaryCategory())
2778
void subselect_indexsubquery_engine::print(String *str,
2779
enum_query_type query_type)
2830
void subselect_indexsubquery_engine::print(String *str)
2781
2832
str->append(STRING_WITH_LEN("<index_lookup>("));
2782
tab->ref.items[0]->print(str, query_type);
2833
tab->ref.items[0]->print(str);
2783
2834
str->append(STRING_WITH_LEN(" in "));
2784
2835
str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
2785
2836
KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
2792
2843
str->append(STRING_WITH_LEN(" where "));
2793
cond->print(str, query_type);
2797
2848
str->append(STRING_WITH_LEN(" having "));
2798
having->print(str, query_type);
2800
2851
str->append(')');
3008
3059
Make sure there is only one index on the temp table, and it doesn't have
3009
3060
the extra key part created when s->uniques > 0.
3011
assert(tmp_table->getShare()->sizeKeys() == 1 && tmp_columns->elements == tmp_key_parts);
3062
assert(tmp_table->getShare()->sizeKeys() == 1 && tmp_columns->size() == tmp_key_parts);
3014
3065
/* 2. Create/initialize execution related objects. */
3020
3071
- here we initialize only those members that are used by
3021
3072
subselect_uniquesubquery_engine, so these objects are incomplete.
3023
if (!(tab= (JoinTable*) session->alloc(sizeof(JoinTable))))
3074
if (!(tab= (JoinTable*) session->getMemRoot()->allocate(sizeof(JoinTable))))
3076
new (tab) JoinTable();
3025
3077
tab->table= tmp_table;
3026
3078
tab->ref.key= 0; /* The only temp table index. */
3027
3079
tab->ref.key_length= tmp_key->key_length;
3028
3080
if (!(tab->ref.key_buff=
3029
3081
(unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3030
3082
!(tab->ref.key_copy=
3031
(StoredKey**) session->alloc((sizeof(StoredKey*) *
3083
(StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
3032
3084
(tmp_key_parts + 1)))) ||
3033
3085
!(tab->ref.items=
3034
(Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
3086
(Item**) session->getMemRoot()->allocate(sizeof(Item*) * tmp_key_parts)))
3037
3089
KeyPartInfo *cur_key_part= tmp_key->key_part;
3132
3184
if (!is_materialized)
3135
Select_Lex *save_select= session->lex->current_select;
3136
session->lex->current_select= materialize_engine->select_lex;
3187
Select_Lex *save_select= session->getLex()->current_select;
3188
session->getLex()->current_select= materialize_engine->select_lex;
3137
3189
if ((res= materialize_join->optimize()))
3192
if (materialize_engine->save_join_if_explain())
3139
3195
materialize_join->exec();
3140
3196
if ((res= test(materialize_join->error || session->is_fatal_error)))
3186
3242
Print the state of this engine into a string for debugging and views.
3189
void subselect_hash_sj_engine::print(String *str, enum_query_type query_type)
3245
void subselect_hash_sj_engine::print(String *str)
3191
3247
str->append(STRING_WITH_LEN(" <materialize> ("));
3192
materialize_engine->print(str, query_type);
3248
materialize_engine->print(str);
3193
3249
str->append(STRING_WITH_LEN(" ), "));
3195
subselect_uniquesubquery_engine::print(str, query_type);
3251
subselect_uniquesubquery_engine::print(str);
3197
3253
str->append(STRING_WITH_LEN(
3198
3254
"<the access method for lookups is not yet created>"