1
/* Copyright (C) 2000 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
23
- add function from mysql_select that use JOIN* as parameter to JOIN
24
methods (sql_select.h/sql_select.cc)
27
#ifdef USE_PRAGMA_IMPLEMENTATION
28
#pragma implementation // gcc: Class implementation
31
#include "mysql_priv.h"
32
#include "sql_select.h"
34
inline Item * and_items(Item* cond, Item *item)
36
return (cond? (new Item_cond_and(cond, item)) : item);
39
Item_subselect::Item_subselect():
40
Item_result_field(), value_assigned(0), thd(0), substitution(0),
41
engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
42
const_item_cache(1), engine_changed(0), changed(0),
48
Item value is NULL if select_result_interceptor didn't change this value
49
(i.e. some rows will be found returned)
55
void Item_subselect::init(st_select_lex *select_lex,
56
select_result_interceptor *result)
59
Please see Item_singlerow_subselect::invalidate_and_restore_select_lex(),
60
which depends on alterations to the parse tree implemented here.
63
unit= select_lex->master_unit();
68
Item can be changed in JOIN::prepare while engine in JOIN::optimize
69
=> we do not copy old_engine here
71
engine= unit->item->engine;
72
parsing_place= unit->item->parsing_place;
73
unit->item->engine= 0;
75
engine->change_result(this, result);
79
SELECT_LEX *outer_select= unit->outer_select();
81
do not take into account expression inside aggregate functions because
82
they can access original table fields
84
parsing_place= (outer_select->in_sum_expr ?
86
outer_select->parsing_place);
88
engine= new subselect_union_engine(unit, result, this);
90
engine= new subselect_single_select_engine(select_lex, result, this);
93
SELECT_LEX *upper= unit->outer_select();
94
if (upper->parsing_place == IN_HAVING)
95
upper->subquery_in_having= 1;
101
Item_subselect::get_select_lex()
103
return unit->first_select();
106
void Item_subselect::cleanup()
108
Item_result_field::cleanup();
123
void Item_singlerow_subselect::cleanup()
126
Item_subselect::cleanup();
131
void Item_in_subselect::cleanup()
135
left_expr_cache->delete_elements();
136
delete left_expr_cache;
137
left_expr_cache= NULL;
139
first_execution= true;
140
Item_subselect::cleanup();
144
Item_subselect::~Item_subselect()
149
Item_subselect::trans_res
150
Item_subselect::select_transformer(JOIN *join __attribute__((__unused__)))
156
bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
158
char const *save_where= thd_param->where;
163
engine->set_thd((thd= thd_param));
165
if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res))
168
res= engine->prepare();
170
// all transformation is done (used by prepared statements)
176
Substitute the current item with an Item_in_optimizer that was
177
created by Item_in_subselect::select_in_like_transformer and
178
call fix_fields for the substituted item which in turn calls
179
engine->prepare for the subquery predicate.
185
// did we changed top item of WHERE condition
186
if (unit->outer_select()->where == (*ref))
187
unit->outer_select()->where= substitution; // correct WHERE for PS
188
else if (unit->outer_select()->having == (*ref))
189
unit->outer_select()->having= substitution; // correct HAVING for PS
191
(*ref)= substitution;
192
substitution->name= name;
193
if (have_to_be_excluded)
196
thd->where= "checking transformed subquery";
198
ret= (*ref)->fix_fields(thd, ref);
199
thd->where= save_where;
202
// Is it one field subselect?
203
if (engine->cols() > max_columns)
205
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
208
fix_length_and_dec();
213
if ((uncacheable= engine->uncacheable()))
216
if (uncacheable & UNCACHEABLE_RAND)
217
used_tables_cache|= RAND_TABLE_BIT;
222
thd->where= save_where;
227
bool Item_subselect::walk(Item_processor processor, bool walk_subquery,
233
for (SELECT_LEX *lex= unit->first_select(); lex; lex= lex->next_select())
235
List_iterator<Item> li(lex->item_list);
239
if (lex->where && (lex->where)->walk(processor, walk_subquery, argument))
241
if (lex->having && (lex->having)->walk(processor, walk_subquery,
247
if (item->walk(processor, walk_subquery, argument))
250
for (order= (ORDER*) lex->order_list.first ; order; order= order->next)
252
if ((*order->item)->walk(processor, walk_subquery, argument))
255
for (order= (ORDER*) lex->group_list.first ; order; order= order->next)
257
if ((*order->item)->walk(processor, walk_subquery, argument))
262
return (this->*processor)(argument);
266
bool Item_subselect::exec()
271
/* Do not execute subselect in case of a fatal error */
286
Compute the IN predicate if the left operand's cache changed.
289
bool Item_in_subselect::exec()
291
assert(exec_method != MATERIALIZATION ||
292
(exec_method == MATERIALIZATION &&
293
engine->engine_type() == subselect_engine::HASH_SJ_ENGINE));
295
Initialize the cache of the left predicate operand. This has to be done as
296
late as now, because Cached_item directly contains a resolved field (not
297
an item, and in some cases (when temp tables are created), these fields
298
end up pointing to the wrong field. One solution is to change Cached_item
299
to not resolve its field upon creation, but to resolve it dynamically
300
from a given Item_ref object.
301
TODO: the cache should be applied conditionally based on:
302
- rules - e.g. only if the left operand is known to be ordered, and/or
303
- on a cost-based basis, that takes into account the cost of a cache
304
lookup, the cache hit rate, and the savings per cache hit.
306
if (!left_expr_cache && exec_method == MATERIALIZATION)
307
init_left_expr_cache();
309
/* If the new left operand is already in the cache, reuse the old result. */
310
if (left_expr_cache && test_if_item_cache_changed(*left_expr_cache) < 0)
312
/* Always compute IN for the first row as the cache is not valid for it. */
313
if (!first_execution)
315
first_execution= false;
319
The exec() method below updates item::value, and item::null_value, thus if
320
we don't call it, the next call to item::val_int() will return whatever
321
result was computed by its previous call.
323
return(Item_subselect::exec());
327
Item::Type Item_subselect::type() const
329
return SUBSELECT_ITEM;
333
void Item_subselect::fix_length_and_dec()
335
engine->fix_length_and_dec(0);
339
table_map Item_subselect::used_tables() const
341
return (table_map) (engine->uncacheable() ? used_tables_cache : 0L);
345
bool Item_subselect::const_item() const
347
return const_item_cache;
350
Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
352
if (!with_sum_func && !const_item())
353
return new Item_field(result_field);
354
return copy_or_same(thd_arg);
357
void Item_subselect::update_used_tables()
359
if (!engine->uncacheable())
361
// did all used tables become static?
362
if (!(used_tables_cache & ~engine->upper_select_const_tables()))
368
void Item_subselect::print(String *str, enum_query_type query_type)
371
engine->print(str, query_type);
376
Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex)
377
:Item_subselect(), value(0)
379
init(select_lex, new select_singlerow_subselect(this));
381
max_columns= UINT_MAX;
386
Item_singlerow_subselect::invalidate_and_restore_select_lex()
388
st_select_lex *result= get_select_lex();
393
This code restore the parse tree in it's state before the execution of
394
Item_singlerow_subselect::Item_singlerow_subselect(),
395
and in particular decouples this object from the SELECT_LEX,
396
so that the SELECT_LEX can be used with a different flavor
397
or Item_subselect instead, as part of query rewriting.
404
Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,
405
Item_subselect *parent,
406
st_select_lex *select_lex,
408
:Item_singlerow_subselect(), was_values(true)
411
init(select_lex, new select_max_min_finder_subselect(this, max_arg));
417
Following information was collected during performing fix_fields()
418
of Items belonged to subquery, which will be not repeated
420
used_tables_cache= parent->get_used_tables_cache();
421
const_item_cache= parent->get_const_item_cache();
424
this subquery always creates during preparation, so we can assign
432
void Item_maxmin_subselect::cleanup()
434
Item_singlerow_subselect::cleanup();
437
By default it is true to avoid true reporting by
438
Item_func_not_all/Item_func_nop_all if this item was never called.
440
Engine exec() set it to false by reset_value_registration() call.
441
select_max_min_finder_subselect::send_data() set it back to true if some
449
void Item_maxmin_subselect::print(String *str, enum_query_type query_type)
451
str->append(max?"<max>":"<min>", 5);
452
Item_singlerow_subselect::print(str, query_type);
456
void Item_singlerow_subselect::reset()
460
value->null_value= 1;
466
- We cant change name of Item_field or Item_ref, because it will
467
prevent it's correct resolving, but we should save name of
468
removed item => we do not make optimization if top item of
469
list is field or reference.
470
- switch off this optimization for prepare statement,
471
because we do not rollback this changes.
472
Make rollback for it, or special name resolving mode in 5.0.
474
Item_subselect::trans_res
475
Item_singlerow_subselect::select_transformer(JOIN *join)
480
SELECT_LEX *select_lex= join->select_lex;
482
if (!select_lex->master_unit()->is_union() &&
483
!select_lex->table_list.elements &&
484
select_lex->item_list.elements == 1 &&
485
!select_lex->item_list.head()->with_sum_func &&
487
We cant change name of Item_field or Item_ref, because it will
488
prevent it's correct resolving, but we should save name of
489
removed item => we do not make optimization if top item of
490
list is field or reference.
491
TODO: solve above problem
493
!(select_lex->item_list.head()->type() == FIELD_ITEM ||
494
select_lex->item_list.head()->type() == REF_ITEM) &&
495
!join->conds && !join->having
499
have_to_be_excluded= 1;
500
if (thd->lex->describe)
502
char warn_buff[MYSQL_ERRMSG_SIZE];
503
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
504
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
505
ER_SELECT_REDUCED, warn_buff);
507
substitution= select_lex->item_list.head();
509
as far as we moved content to upper level, field which depend of
510
'upper' select is not really dependent => we remove this dependence
512
substitution->walk(&Item::remove_dependence_processor, 0,
513
(uchar *) select_lex->outer_select());
520
void Item_singlerow_subselect::store(uint i, Item *item)
525
enum Item_result Item_singlerow_subselect::result_type() const
527
return engine->type();
531
Don't rely on the result type to calculate field type.
532
Ask the engine instead.
534
enum_field_types Item_singlerow_subselect::field_type() const
536
return engine->field_type();
539
void Item_singlerow_subselect::fix_length_and_dec()
541
if ((max_columns= engine->cols()) == 1)
543
engine->fix_length_and_dec(row= &value);
547
if (!(row= (Item_cache**) sql_alloc(sizeof(Item_cache*)*max_columns)))
549
engine->fix_length_and_dec(row);
552
unsigned_flag= value->unsigned_flag;
554
If there are not tables in subquery then ability to have NULL value
555
depends on SELECT list (if single row subquery have tables then it
556
always can be NULL if there are not records fetched).
558
if (engine->no_tables())
559
maybe_null= engine->may_be_null();
562
uint Item_singlerow_subselect::cols()
564
return engine->cols();
567
bool Item_singlerow_subselect::check_cols(uint c)
569
if (c != engine->cols())
571
my_error(ER_OPERAND_COLUMNS, MYF(0), c);
577
bool Item_singlerow_subselect::null_inside()
579
for (uint i= 0; i < max_columns ; i++)
581
if (row[i]->null_value)
587
void Item_singlerow_subselect::bring_value()
592
double Item_singlerow_subselect::val_real()
595
if (!exec() && !value->null_value)
598
return value->val_real();
607
int64_t Item_singlerow_subselect::val_int()
610
if (!exec() && !value->null_value)
613
return value->val_int();
622
String *Item_singlerow_subselect::val_str(String *str)
624
if (!exec() && !value->null_value)
627
return value->val_str(str);
637
my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value)
639
if (!exec() && !value->null_value)
642
return value->val_decimal(decimal_value);
652
bool Item_singlerow_subselect::val_bool()
654
if (!exec() && !value->null_value)
657
return value->val_bool();
667
Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex):
671
init(select_lex, new select_exists_subselect(this));
672
max_columns= UINT_MAX;
673
null_value= 0; //can't be NULL
674
maybe_null= 0; //can't be NULL
680
void Item_exists_subselect::print(String *str, enum_query_type query_type)
682
str->append(STRING_WITH_LEN("exists"));
683
Item_subselect::print(str, query_type);
687
bool Item_in_subselect::test_limit(st_select_lex_unit *unit_arg)
689
if (unit_arg->fake_select_lex &&
690
unit_arg->fake_select_lex->test_limit())
693
SELECT_LEX *sl= unit_arg->first_select();
694
for (; sl; sl= sl->next_select())
696
if (sl->test_limit())
702
Item_in_subselect::Item_in_subselect(Item * left_exp,
703
st_select_lex *select_lex):
704
Item_exists_subselect(), left_expr_cache(0), first_execution(true),
705
optimizer(0), pushed_cond_guards(NULL), exec_method(NOT_TRANSFORMED),
709
init(select_lex, new select_exists_subselect(this));
710
max_columns= UINT_MAX;
714
//if test_limit will fail then error will be reported to client
715
test_limit(select_lex->master_unit());
719
Item_allany_subselect::Item_allany_subselect(Item * left_exp,
720
chooser_compare_func_creator fc,
721
st_select_lex *select_lex,
723
:Item_in_subselect(), func_creator(fc), all(all_arg)
726
func= func_creator(all_arg);
727
init(select_lex, new select_exists_subselect(this));
731
//if test_limit will fail then error will be reported to client
732
test_limit(select_lex->master_unit());
737
void Item_exists_subselect::fix_length_and_dec()
741
max_columns= engine->cols();
742
/* We need only 1 row to determine existence */
743
unit->global_parameters->select_limit= new Item_int((int32) 1);
746
double Item_exists_subselect::val_real()
754
return (double) value;
757
int64_t Item_exists_subselect::val_int()
768
String *Item_exists_subselect::val_str(String *str)
776
str->set((uint64_t)value,&my_charset_bin);
781
my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
789
int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
790
return decimal_value;
794
bool Item_exists_subselect::val_bool()
806
double Item_in_subselect::val_real()
809
As far as Item_in_subselect called only from Item_in_optimizer this
810
method should not be used
821
if (was_null && !value)
823
return (double) value;
827
int64_t Item_in_subselect::val_int()
830
As far as Item_in_subselect called only from Item_in_optimizer this
831
method should not be used
841
if (was_null && !value)
847
String *Item_in_subselect::val_str(String *str)
850
As far as Item_in_subselect called only from Item_in_optimizer this
851
method should not be used
862
if (was_null && !value)
867
str->set((uint64_t)value, &my_charset_bin);
872
bool Item_in_subselect::val_bool()
880
Must mark the IN predicate as NULL so as to make sure an enclosing NOT
881
predicate will return false. See the comments in
882
subselect_uniquesubquery_engine::copy_ref_key for further details.
887
if (was_null && !value)
892
my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
895
As far as Item_in_subselect called only from Item_in_optimizer this
896
method should not be used
907
if (was_null && !value)
909
int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
910
return decimal_value;
915
Rewrite a single-column IN/ALL/ANY subselect
918
Item_in_subselect::single_value_transformer()
919
join Join object of the subquery (i.e. 'child' join).
920
func Subquery comparison creator
923
Rewrite a single-column subquery using rule-based approach. The subquery
925
oe $cmp$ (SELECT ie FROM ... WHERE subq_where ... HAVING subq_having)
927
First, try to convert the subquery to scalar-result subquery in one of
930
- oe $cmp$ (SELECT MAX(...) ) // handled by Item_singlerow_subselect
931
- oe $cmp$ <max>(SELECT ...) // handled by Item_maxmin_subselect
933
If that fails, the subquery will be handled with class Item_in_optimizer.
934
There are two possibilites:
935
- If the subquery execution method is materialization, then the subquery is
936
not transformed any further.
937
- Otherwise the IN predicates is transformed into EXISTS by injecting
938
equi-join predicates and possibly other helper predicates. For details
939
see method single_value_in_like_transformer().
942
RES_OK Either subquery was transformed, or appopriate
943
predicates where injected into it.
944
RES_REDUCE The subquery was reduced to non-subquery
948
Item_subselect::trans_res
949
Item_in_subselect::single_value_transformer(JOIN *join,
952
SELECT_LEX *select_lex= join->select_lex;
955
Check that the right part of the subselect contains no more than one
956
column. E.g. in SELECT 1 IN (SELECT * ..) the right part is (SELECT * ...)
958
if (select_lex->item_list.elements > 1)
960
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
965
If this is an ALL/ANY single-value subselect, try to rewrite it with
966
a MIN/MAX subselect. We can do that if a possible NULL result of the
967
subselect can be ignored.
968
E.g. SELECT * FROM t1 WHERE b > ANY (SELECT a FROM t2) can be rewritten
969
with SELECT * FROM t1 WHERE b > (SELECT MAX(a) FROM t2).
970
We can't check that this optimization is safe if it's not a top-level
971
item of the WHERE clause (e.g. because the WHERE clause can contain IS
972
NULL/IS NOT NULL functions). If so, we rewrite ALL/ANY with NOT EXISTS
973
later in this method.
975
if ((abort_on_null || (upper_item && upper_item->top_level())) &&
976
!select_lex->master_unit()->uncacheable && !func->eqne_op())
980
// It is second (third, ...) SELECT of UNION => All is done
985
if (!select_lex->group_list.elements &&
986
!select_lex->having &&
987
!select_lex->with_sum_func &&
988
!(select_lex->next_select()) &&
989
select_lex->table_list.elements)
991
Item_sum_hybrid *item;
992
nesting_map save_allow_sum_func;
996
(ALL && (> || =>)) || (ANY && (< || =<))
997
for ALL condition is inverted
999
item= new Item_sum_max(*select_lex->ref_pointer_array);
1004
(ALL && (< || =<)) || (ANY && (> || =>))
1005
for ALL condition is inverted
1007
item= new Item_sum_min(*select_lex->ref_pointer_array);
1010
upper_item->set_sum_test(item);
1011
*select_lex->ref_pointer_array= item;
1013
List_iterator<Item> it(select_lex->item_list);
1018
save_allow_sum_func= thd->lex->allow_sum_func;
1019
thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
1021
Item_sum_(max|min) can't substitute other item => we can use 0 as
1022
reference, also Item_sum_(max|min) can't be fixed after creation, so
1023
we do not check item->fixed
1025
if (item->fix_fields(thd, 0))
1027
thd->lex->allow_sum_func= save_allow_sum_func;
1028
/* we added aggregate function => we have to change statistic */
1029
count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
1032
subs= new Item_singlerow_subselect(select_lex);
1036
Item_maxmin_subselect *item;
1037
subs= item= new Item_maxmin_subselect(thd, this, select_lex, func->l_op());
1039
upper_item->set_sub_test(item);
1041
/* fix fields is already called for left expression */
1042
substitution= func->create(left_expr, subs);
1048
/* We're invoked for the 1st (or the only) SELECT in the subquery UNION */
1049
SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
1050
substitution= optimizer;
1052
SELECT_LEX *current= thd->lex->current_select, *up;
1054
thd->lex->current_select= up= current->return_after_parsing();
1055
//optimizer never use Item **ref => we can pass 0 as parameter
1056
if (!optimizer || optimizer->fix_left(thd, 0))
1058
thd->lex->current_select= current;
1061
thd->lex->current_select= current;
1064
As far as Item_ref_in_optimizer do not substitute itself on fix_fields
1065
we can use same item for all selects.
1067
expr= new Item_direct_ref(&select_lex->context,
1068
(Item**)optimizer->get_cache(),
1069
(char *)"<no matter>",
1070
(char *)in_left_expr_name);
1072
master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1075
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1077
if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool))))
1079
pushed_cond_guards[0]= true;
1083
If this IN predicate can be computed via materialization, do not
1084
perform the IN -> EXISTS transformation.
1086
if (exec_method == MATERIALIZATION)
1089
/* Perform the IN=>EXISTS transformation. */
1090
return(single_value_in_to_exists_transformer(join, func));
1095
Transofrm an IN predicate into EXISTS via predicate injection.
1097
@details The transformation injects additional predicates into the subquery
1098
(and makes the subquery correlated) as follows.
1100
- If the subquery has aggregates, GROUP BY, or HAVING, convert to
1102
SELECT ie FROM ... HAVING subq_having AND
1103
trigcond(oe $cmp$ ref_or_null_helper<ie>)
1105
the addition is wrapped into trigger only when we want to distinguish
1106
between NULL and false results.
1108
- Otherwise (no aggregates/GROUP BY/HAVING) convert it to one of the
1111
= If we don't need to distinguish between NULL and false subquery:
1113
SELECT 1 FROM ... WHERE (oe $cmp$ ie) AND subq_where
1115
= If we need to distinguish between those:
1118
WHERE subq_where AND trigcond((oe $cmp$ ie) OR (ie IS NULL))
1119
HAVING trigcond(<is_not_null_test>(ie))
1121
@param join Join object of the subquery (i.e. 'child' join).
1122
@param func Subquery comparison creator
1124
@retval RES_OK Either subquery was transformed, or appopriate
1125
predicates where injected into it.
1126
@retval RES_REDUCE The subquery was reduced to non-subquery
1127
@retval RES_ERROR Error
1130
Item_subselect::trans_res
1131
Item_in_subselect::single_value_in_to_exists_transformer(JOIN * join, Comp_creator *func)
1133
SELECT_LEX *select_lex= join->select_lex;
1135
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1136
if (join->having || select_lex->with_sum_func ||
1137
select_lex->group_list.elements)
1140
Item *item= func->create(expr,
1141
new Item_ref_null_helper(&select_lex->context,
1146
this->full_name()));
1147
if (!abort_on_null && left_expr->maybe_null)
1150
We can encounter "NULL IN (SELECT ...)". Wrap the added condition
1153
item= new Item_func_trig_cond(item, get_cond_guard(0));
1157
AND and comparison functions can't be changed during fix_fields()
1158
we can assign select_lex->having here, and pass 0 as last
1159
argument (reference) to fix_fields()
1161
select_lex->having= join->having= and_items(join->having, item);
1162
if (join->having == item)
1163
item->name= (char*)in_having_cond;
1164
select_lex->having_fix_field= 1;
1166
we do not check join->having->fixed, because Item_and (from and_items)
1167
or comparison function (from func->create) can't be fixed after creation
1169
tmp= join->having->fix_fields(thd, 0);
1170
select_lex->having_fix_field= 0;
1176
Item *item= (Item*) select_lex->item_list.head();
1178
if (select_lex->table_list.elements)
1181
Item *having= item, *orig_item= item;
1182
select_lex->item_list.empty();
1183
select_lex->item_list.push_back(new Item_int("Not_used",
1185
MY_INT64_NUM_DECIMAL_DIGITS));
1186
select_lex->ref_pointer_array[0]= select_lex->item_list.head();
1188
item= func->create(expr, item);
1189
if (!abort_on_null && orig_item->maybe_null)
1191
having= new Item_is_not_null_test(this, having);
1192
if (left_expr->maybe_null)
1194
if (!(having= new Item_func_trig_cond(having,
1195
get_cond_guard(0))))
1199
Item_is_not_null_test can't be changed during fix_fields()
1200
we can assign select_lex->having here, and pass 0 as last
1201
argument (reference) to fix_fields()
1203
having->name= (char*)in_having_cond;
1204
select_lex->having= join->having= having;
1205
select_lex->having_fix_field= 1;
1207
we do not check join->having->fixed, because Item_and (from
1208
and_items) or comparison function (from func->create) can't be
1209
fixed after creation
1211
tmp= join->having->fix_fields(thd, 0);
1212
select_lex->having_fix_field= 0;
1215
item= new Item_cond_or(item,
1216
new Item_func_isnull(orig_item));
1219
If we may encounter NULL IN (SELECT ...) and care whether subquery
1220
result is NULL or false, wrap condition in a trig_cond.
1222
if (!abort_on_null && left_expr->maybe_null)
1224
if (!(item= new Item_func_trig_cond(item, get_cond_guard(0))))
1228
TODO: figure out why the following is done here in
1229
single_value_transformer but there is no corresponding action in
1230
row_value_transformer?
1232
item->name= (char *)in_additional_cond;
1235
AND can't be changed during fix_fields()
1236
we can assign select_lex->having here, and pass 0 as last
1237
argument (reference) to fix_fields()
1239
select_lex->where= join->conds= and_items(join->conds, item);
1240
select_lex->where->top_level_item();
1242
we do not check join->conds->fixed, because Item_and can't be fixed
1245
if (join->conds->fix_fields(thd, 0))
1251
if (select_lex->master_unit()->is_union())
1254
comparison functions can't be changed during fix_fields()
1255
we can assign select_lex->having here, and pass 0 as last
1256
argument (reference) to fix_fields()
1260
new Item_ref_null_helper(&select_lex->context, this,
1261
select_lex->ref_pointer_array,
1262
(char *)"<no matter>",
1263
(char *)"<result>"));
1264
if (!abort_on_null && left_expr->maybe_null)
1266
if (!(new_having= new Item_func_trig_cond(new_having,
1267
get_cond_guard(0))))
1270
new_having->name= (char*)in_having_cond;
1271
select_lex->having= join->having= new_having;
1272
select_lex->having_fix_field= 1;
1275
we do not check join->having->fixed, because comparison function
1276
(from func->create) can't be fixed after creation
1278
tmp= join->having->fix_fields(thd, 0);
1279
select_lex->having_fix_field= 0;
1285
// it is single select without tables => possible optimization
1286
item= func->create(left_expr, item);
1287
// fix_field of item will be done in time of substituting
1289
have_to_be_excluded= 1;
1290
if (thd->lex->describe)
1292
char warn_buff[MYSQL_ERRMSG_SIZE];
1293
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
1294
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1295
ER_SELECT_REDUCED, warn_buff);
1306
Item_subselect::trans_res
1307
Item_in_subselect::row_value_transformer(JOIN *join)
1309
SELECT_LEX *select_lex= join->select_lex;
1310
uint cols_num= left_expr->cols();
1312
if (select_lex->item_list.elements != left_expr->cols())
1314
my_error(ER_OPERAND_COLUMNS, MYF(0), left_expr->cols());
1319
Wrap the current IN predicate in an Item_in_optimizer. The actual
1320
substitution in the Item tree takes place in Item_subselect::fix_fields.
1324
//first call for this unit
1325
SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
1326
substitution= optimizer;
1328
SELECT_LEX *current= thd->lex->current_select, *up;
1329
thd->lex->current_select= up= current->return_after_parsing();
1330
//optimizer never use Item **ref => we can pass 0 as parameter
1331
if (!optimizer || optimizer->fix_left(thd, 0))
1333
thd->lex->current_select= current;
1337
// we will refer to upper level cache array => we have to save it in PS
1338
optimizer->keep_top_level_cache();
1340
thd->lex->current_select= current;
1341
master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1343
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1345
if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool) *
1346
left_expr->cols())))
1348
for (uint i= 0; i < cols_num; i++)
1349
pushed_cond_guards[i]= true;
1354
If this IN predicate can be computed via materialization, do not
1355
perform the IN -> EXISTS transformation.
1357
if (exec_method == MATERIALIZATION)
1360
/* Perform the IN=>EXISTS transformation. */
1361
return(row_value_in_to_exists_transformer(join));
1366
Tranform a (possibly non-correlated) IN subquery into a correlated EXISTS.
1369
The IF-ELSE below can be refactored so that there is no duplication of the
1370
statements that create the new conditions. For this we have to invert the IF
1371
and the FOR statements as this:
1372
for (each left operand)
1373
create the equi-join condition
1374
if (is_having_used || !abort_on_null)
1375
create the "is null" and is_not_null_test items
1377
add the equi-join and the null tests to HAVING
1379
add the equi-join and the "is null" to WHERE
1380
add the is_not_null_test to HAVING
1383
Item_subselect::trans_res
1384
Item_in_subselect::row_value_in_to_exists_transformer(JOIN * join)
1386
SELECT_LEX *select_lex= join->select_lex;
1387
Item *having_item= 0;
1388
uint cols_num= left_expr->cols();
1389
bool is_having_used= (join->having || select_lex->with_sum_func ||
1390
select_lex->group_list.first ||
1391
!select_lex->table_list.elements);
1393
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1397
(l1, l2, l3) IN (SELECT v1, v2, v3 ... HAVING having) =>
1398
EXISTS (SELECT ... HAVING having and
1399
(l1 = v1 or is null v1) and
1400
(l2 = v2 or is null v2) and
1401
(l3 = v3 or is null v3) and
1402
is_not_null_test(v1) and
1403
is_not_null_test(v2) and
1404
is_not_null_test(v3))
1405
where is_not_null_test used to register nulls in case if we have
1406
not found matching to return correct NULL value
1407
TODO: say here explicitly if the order of AND parts matters or not.
1409
Item *item_having_part2= 0;
1410
for (uint i= 0; i < cols_num; i++)
1412
assert((left_expr->fixed && select_lex->ref_pointer_array[i]->fixed) ||
1413
(select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
1414
((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
1415
Item_ref::OUTER_REF));
1416
if (select_lex->ref_pointer_array[i]->
1417
check_cols(left_expr->element_index(i)->cols()))
1420
new Item_func_eq(new
1421
Item_ref(&select_lex->context,
1422
(*optimizer->get_cache())->
1424
(char *)"<no matter>",
1425
(char *)in_left_expr_name),
1427
Item_ref(&select_lex->context,
1428
select_lex->ref_pointer_array + i,
1429
(char *)"<no matter>",
1430
(char *)"<list ref>")
1433
new Item_func_isnull(new
1434
Item_ref(&select_lex->context,
1435
select_lex->ref_pointer_array+i,
1436
(char *)"<no matter>",
1437
(char *)"<list ref>")
1439
Item *col_item= new Item_cond_or(item_eq, item_isnull);
1440
if (!abort_on_null && left_expr->element_index(i)->maybe_null)
1442
if (!(col_item= new Item_func_trig_cond(col_item, get_cond_guard(i))))
1445
having_item= and_items(having_item, col_item);
1447
Item *item_nnull_test=
1448
new Item_is_not_null_test(this,
1449
new Item_ref(&select_lex->context,
1451
ref_pointer_array + i,
1452
(char *)"<no matter>",
1453
(char *)"<list ref>"));
1454
if (!abort_on_null && left_expr->element_index(i)->maybe_null)
1456
if (!(item_nnull_test=
1457
new Item_func_trig_cond(item_nnull_test, get_cond_guard(i))))
1460
item_having_part2= and_items(item_having_part2, item_nnull_test);
1461
item_having_part2->top_level_item();
1463
having_item= and_items(having_item, item_having_part2);
1464
having_item->top_level_item();
1469
(l1, l2, l3) IN (SELECT v1, v2, v3 ... WHERE where) =>
1470
EXISTS (SELECT ... WHERE where and
1471
(l1 = v1 or is null v1) and
1472
(l2 = v2 or is null v2) and
1473
(l3 = v3 or is null v3)
1474
HAVING is_not_null_test(v1) and
1475
is_not_null_test(v2) and
1476
is_not_null_test(v3))
1477
where is_not_null_test register NULLs values but reject rows
1479
in case when we do not need correct NULL, we have simplier construction:
1480
EXISTS (SELECT ... WHERE where and
1485
Item *where_item= 0;
1486
for (uint i= 0; i < cols_num; i++)
1488
Item *item, *item_isnull;
1489
assert((left_expr->fixed && select_lex->ref_pointer_array[i]->fixed) ||
1490
(select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
1491
((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
1492
Item_ref::OUTER_REF));
1493
if (select_lex->ref_pointer_array[i]->
1494
check_cols(left_expr->element_index(i)->cols()))
1497
new Item_func_eq(new
1498
Item_direct_ref(&select_lex->context,
1499
(*optimizer->get_cache())->
1501
(char *)"<no matter>",
1502
(char *)in_left_expr_name),
1504
Item_direct_ref(&select_lex->context,
1506
ref_pointer_array+i,
1507
(char *)"<no matter>",
1508
(char *)"<list ref>")
1512
Item *having_col_item=
1513
new Item_is_not_null_test(this,
1515
Item_ref(&select_lex->context,
1516
select_lex->ref_pointer_array + i,
1517
(char *)"<no matter>",
1518
(char *)"<list ref>"));
1522
Item_func_isnull(new
1523
Item_direct_ref(&select_lex->context,
1525
ref_pointer_array+i,
1526
(char *)"<no matter>",
1527
(char *)"<list ref>")
1529
item= new Item_cond_or(item, item_isnull);
1531
TODO: why we create the above for cases where the right part
1534
if (left_expr->element_index(i)->maybe_null)
1536
if (!(item= new Item_func_trig_cond(item, get_cond_guard(i))))
1538
if (!(having_col_item=
1539
new Item_func_trig_cond(having_col_item, get_cond_guard(i))))
1542
having_item= and_items(having_item, having_col_item);
1544
where_item= and_items(where_item, item);
1547
AND can't be changed during fix_fields()
1548
we can assign select_lex->where here, and pass 0 as last
1549
argument (reference) to fix_fields()
1551
select_lex->where= join->conds= and_items(join->conds, where_item);
1552
select_lex->where->top_level_item();
1553
if (join->conds->fix_fields(thd, 0))
1559
select_lex->having= join->having= and_items(join->having, having_item);
1560
if (having_item == select_lex->having)
1561
having_item->name= (char*)in_having_cond;
1562
select_lex->having->top_level_item();
1564
AND can't be changed during fix_fields()
1565
we can assign select_lex->having here, and pass 0 as last
1566
argument (reference) to fix_fields()
1568
select_lex->having_fix_field= 1;
1569
res= join->having->fix_fields(thd, 0);
1570
select_lex->having_fix_field= 0;
1581
Item_subselect::trans_res
1582
Item_in_subselect::select_transformer(JOIN *join)
1584
return select_in_like_transformer(join, &eq_creator);
1589
Prepare IN/ALL/ANY/SOME subquery transformation and call appropriate
1590
transformation function.
1592
To decide which transformation procedure (scalar or row) applicable here
1593
we have to call fix_fields() for left expression to be able to call
1594
cols() method on it. Also this method make arena management for
1595
underlying transformation methods.
1597
@param join JOIN object of transforming subquery
1598
@param func creator of condition function of subquery
1603
RES_REDUCE OK, and current subquery was reduced during
1609
Item_subselect::trans_res
1610
Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
1612
SELECT_LEX *current= thd->lex->current_select, *up;
1613
const char *save_where= thd->where;
1614
Item_subselect::trans_res res= RES_ERROR;
1619
IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
1620
ORDER BY clause becomes meaningless thus we drop it here.
1622
SELECT_LEX *sl= current->master_unit()->first_select();
1623
for (; sl; sl= sl->next_select())
1633
thd->where= "IN/ALL/ANY subquery";
1636
In some optimisation cases we will not need this Item_in_optimizer
1637
object, but we can't know it here, but here we need address correct
1638
reference on left expresion.
1642
result= (!(optimizer= new Item_in_optimizer(left_expr, this)));
1647
thd->lex->current_select= up= current->return_after_parsing();
1648
result= (!left_expr->fixed &&
1649
left_expr->fix_fields(thd, optimizer->arguments()));
1650
/* fix_fields can change reference to left_expr, we need reassign it */
1651
left_expr= optimizer->arguments()[0];
1653
thd->lex->current_select= current;
1658
If we didn't choose an execution method up to this point, we choose
1659
the IN=>EXISTS transformation.
1661
if (exec_method == NOT_TRANSFORMED)
1662
exec_method= IN_TO_EXISTS;
1665
Both transformers call fix_fields() only for Items created inside them,
1666
and all those items do not make permanent changes in the current item arena
1667
which allows us to call them with changed arena (if we do not know the
1668
nature of Item, we have to call fix_fields() for it only with the original
1669
arena to avoid memory leak).
1671
if (left_expr->cols() == 1)
1672
res= single_value_transformer(join, func);
1675
/* we do not support row operation for ALL/ANY/SOME */
1676
if (func != &eq_creator)
1678
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
1681
res= row_value_transformer(join);
1684
thd->where= save_where;
1689
void Item_in_subselect::print(String *str, enum_query_type query_type)
1691
if (exec_method == IN_TO_EXISTS)
1692
str->append(STRING_WITH_LEN("<exists>"));
1695
left_expr->print(str, query_type);
1696
str->append(STRING_WITH_LEN(" in "));
1698
Item_subselect::print(str, query_type);
1702
bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
1706
if (exec_method == SEMI_JOIN)
1707
return !( (*ref)= new Item_int(1));
1709
return result || Item_subselect::fix_fields(thd_arg, ref);
1714
Try to create an engine to compute the subselect via materialization,
1715
and if this fails, revert to execution via the IN=>EXISTS transformation.
1718
The purpose of this method is to hide the implementation details
1719
of this Item's execution. The method creates a new engine for
1720
materialized execution, and initializes the engine.
1722
If this initialization fails
1723
- either because it wasn't possible to create the needed temporary table
1725
- or because of a memory allocation error,
1726
then we revert back to execution via the IN=>EXISTS tranformation.
1728
The initialization of the new engine is divided in two parts - a permanent
1729
one that lives across prepared statements, and one that is repeated for each
1733
@retval true memory allocation error occurred
1734
@retval false an execution method was chosen successfully
1737
bool Item_in_subselect::setup_engine()
1739
subselect_hash_sj_engine *new_engine= NULL;
1742
if (engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE)
1744
/* Create/initialize objects in permanent memory. */
1745
subselect_single_select_engine *old_engine;
1747
old_engine= (subselect_single_select_engine*) engine;
1749
if (!(new_engine= new subselect_hash_sj_engine(thd, this,
1751
new_engine->init_permanent(unit->get_unit_column_types()))
1753
Item_subselect::trans_res trans_res;
1755
If for some reason we cannot use materialization for this IN predicate,
1756
delete all materialization-related objects, and apply the IN=>EXISTS
1761
exec_method= NOT_TRANSFORMED;
1762
if (left_expr->cols() == 1)
1763
trans_res= single_value_in_to_exists_transformer(old_engine->join,
1766
trans_res= row_value_in_to_exists_transformer(old_engine->join);
1767
res= (trans_res != Item_subselect::RES_OK);
1774
assert(engine->engine_type() == subselect_engine::HASH_SJ_ENGINE);
1775
new_engine= (subselect_hash_sj_engine*) engine;
1778
/* Initilizations done in runtime memory, repeated for each execution. */
1782
Reset the LIMIT 1 set in Item_exists_subselect::fix_length_and_dec.
1784
Currently we set the subquery LIMIT to infinity, and this is correct
1785
because we forbid at parse time LIMIT inside IN subqueries (see
1786
Item_in_subselect::test_limit). However, once we allow this, here
1787
we should set the correct limit if given in the query.
1789
unit->global_parameters->select_limit= NULL;
1790
if ((res= new_engine->init_runtime()))
1799
Initialize the cache of the left operand of the IN predicate.
1801
@note This method has the same purpose as alloc_group_fields(),
1802
but it takes a different kind of collection of items, and the
1803
list we push to is dynamically allocated.
1805
@retval true if a memory allocation error occurred or the cache is
1806
not applicable to the current query
1807
@retval false if success
1810
bool Item_in_subselect::init_left_expr_cache()
1813
Next_select_func end_select;
1814
bool use_result_field= false;
1816
outer_join= unit->outer_select()->join;
1817
if (!outer_join || !outer_join->tables)
1820
If we use end_[send | write]_group to handle complete rows of the outer
1821
query, make the cache of the left IN operand use Item_field::result_field
1822
instead of Item_field::field. We need this because normally
1823
Cached_item_field uses Item::field to fetch field data, while
1824
copy_ref_key() that copies the left IN operand into a lookup key uses
1825
Item::result_field. In the case end_[send | write]_group result_field is
1826
one row behind field.
1828
end_select= outer_join->join_tab[outer_join->tables-1].next_select;
1829
if (end_select == end_send_group || end_select == end_write_group)
1830
use_result_field= true;
1832
if (!(left_expr_cache= new List<Cached_item>))
1835
for (uint i= 0; i < left_expr->cols(); i++)
1837
Cached_item *cur_item_cache= new_Cached_item(thd,
1838
left_expr->element_index(i),
1840
if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
1848
Callback to test if an IN predicate is expensive.
1851
IN predicates are considered expensive only if they will be executed via
1852
materialization. The return value affects the behavior of
1853
make_cond_for_table() in such a way that it is unchanged when we use
1854
the IN=>EXISTS transformation to compute IN.
1856
@retval true if the predicate is expensive
1857
@retval false otherwise
1860
bool Item_in_subselect::is_expensive_processor(uchar *arg __attribute__((__unused__)))
1862
return exec_method == MATERIALIZATION;
1866
Item_subselect::trans_res
1867
Item_allany_subselect::select_transformer(JOIN *join)
1869
exec_method= IN_TO_EXISTS;
1871
upper_item->show= 1;
1872
return(select_in_like_transformer(join, func));
1876
void Item_allany_subselect::print(String *str, enum_query_type query_type)
1878
if (exec_method == IN_TO_EXISTS)
1879
str->append(STRING_WITH_LEN("<exists>"));
1882
left_expr->print(str, query_type);
1884
str->append(func->symbol(all));
1885
str->append(all ? " all " : " any ", 5);
1887
Item_subselect::print(str, query_type);
1891
void subselect_engine::set_thd(THD *thd_arg)
1895
result->set_thd(thd_arg);
1899
subselect_single_select_engine::
1900
subselect_single_select_engine(st_select_lex *select,
1901
select_result_interceptor *result_arg,
1902
Item_subselect *item_arg)
1903
:subselect_engine(item_arg, result_arg),
1904
prepared(0), executed(0), select_lex(select), join(0)
1906
select_lex->master_unit()->item= item_arg;
1910
void subselect_single_select_engine::cleanup()
1912
prepared= executed= 0;
1919
void subselect_union_engine::cleanup()
1921
unit->reinit_exec_mechanism();
1927
bool subselect_union_engine::is_executed() const
1929
return unit->executed;
1934
Check if last execution of the subquery engine produced any rows
1937
subselect_union_engine::no_rows()
1940
Check if last execution of the subquery engine produced any rows. The
1941
return value is undefined if last execution ended in an error.
1944
true - Last subselect execution has produced no rows
1948
bool subselect_union_engine::no_rows()
1950
/* Check if we got any rows when reading UNION result from temp. table: */
1951
return test(!unit->fake_select_lex->join->send_records);
1955
void subselect_uniquesubquery_engine::cleanup()
1957
/* Tell handler we don't need the index anymore */
1958
if (tab->table->file->inited)
1959
tab->table->file->ha_index_end();
1964
subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
1965
select_result_interceptor *result_arg,
1966
Item_subselect *item_arg)
1967
:subselect_engine(item_arg, result_arg)
1970
unit->item= item_arg;
1975
Create and prepare the JOIN object that represents the query execution
1976
plan for the subquery.
1979
This method is called from Item_subselect::fix_fields. For prepared
1980
statements it is called both during the PREPARE and EXECUTE phases in the
1982
- During PREPARE the optimizer needs some properties
1983
(join->fields_list.elements) of the JOIN to proceed with preparation of
1984
the remaining query (namely to complete ::fix_fields for the subselect
1985
related classes. In the end of PREPARE the JOIN is deleted.
1986
- When we EXECUTE the query, Item_subselect::fix_fields is called again, and
1987
the JOIN object is re-created again, prepared and executed. In the end of
1988
execution it is deleted.
1989
In all cases the JOIN is created in runtime memory (not in the permanent
1993
Re-check what properties of 'join' are needed during prepare, and see if
1994
we can avoid creating a JOIN during JOIN::prepare of the outer join.
1996
@retval 0 if success
2000
int subselect_single_select_engine::prepare()
2004
join= new JOIN(thd, select_lex->item_list,
2005
select_lex->options | SELECT_NO_UNLOCK, result);
2006
if (!join || !result)
2007
return 1; /* Fatal error is set already. */
2009
SELECT_LEX *save_select= thd->lex->current_select;
2010
thd->lex->current_select= select_lex;
2011
if (join->prepare(&select_lex->ref_pointer_array,
2012
(TABLE_LIST*) select_lex->table_list.first,
2013
select_lex->with_wild,
2015
select_lex->order_list.elements +
2016
select_lex->group_list.elements,
2017
(ORDER*) select_lex->order_list.first,
2018
(ORDER*) select_lex->group_list.first,
2020
(ORDER*) 0, select_lex,
2021
select_lex->master_unit()))
2023
thd->lex->current_select= save_select;
2027
int subselect_union_engine::prepare()
2029
return unit->prepare(thd, result, SELECT_NO_UNLOCK);
2032
int subselect_uniquesubquery_engine::prepare()
2034
/* Should never be called. */
2041
Check if last execution of the subquery engine produced any rows
2044
subselect_single_select_engine::no_rows()
2047
Check if last execution of the subquery engine produced any rows. The
2048
return value is undefined if last execution ended in an error.
2051
true - Last subselect execution has produced no rows
2055
bool subselect_single_select_engine::no_rows()
2057
return !item->assigned();
2062
makes storage for the output values for the subquery and calcuates
2063
their data and column types and their nullability.
2065
void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
2068
List_iterator_fast<Item> li(item_list);
2069
res_type= STRING_RESULT;
2070
res_field_type= MYSQL_TYPE_STRING;
2071
for (uint i= 0; (sel_item= li++); i++)
2073
item->max_length= sel_item->max_length;
2074
res_type= sel_item->result_type();
2075
res_field_type= sel_item->field_type();
2076
item->decimals= sel_item->decimals;
2077
item->unsigned_flag= sel_item->unsigned_flag;
2078
maybe_null= sel_item->maybe_null;
2079
if (!(row[i]= Item_cache::get_cache(sel_item)))
2081
row[i]->setup(sel_item);
2083
if (item_list.elements > 1)
2084
res_type= ROW_RESULT;
2087
void subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
2089
assert(row || select_lex->item_list.elements==1);
2090
set_row(select_lex->item_list, row);
2091
item->collation.set(row[0]->collation);
2096
void subselect_union_engine::fix_length_and_dec(Item_cache **row)
2098
assert(row || unit->first_select()->item_list.elements==1);
2100
if (unit->first_select()->item_list.elements == 1)
2102
set_row(unit->types, row);
2103
item->collation.set(row[0]->collation);
2107
bool maybe_null_saved= maybe_null;
2108
set_row(unit->types, row);
2109
maybe_null= maybe_null_saved;
2113
void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row __attribute__((__unused__)))
2115
//this never should be called
2119
int init_read_record_seq(JOIN_TAB *tab);
2120
int join_read_always_key_or_null(JOIN_TAB *tab);
2121
int join_read_next_same_or_null(READ_RECORD *info);
2123
int subselect_single_select_engine::exec()
2125
char const *save_where= thd->where;
2126
SELECT_LEX *save_select= thd->lex->current_select;
2127
thd->lex->current_select= select_lex;
2128
if (!join->optimized)
2130
SELECT_LEX_UNIT *unit= select_lex->master_unit();
2132
unit->set_limit(unit->global_parameters);
2133
if (join->flatten_subqueries())
2135
thd->is_fatal_error= true;
2138
if (join->optimize())
2140
thd->where= save_where;
2142
thd->lex->current_select= save_select;
2143
return(join->error ? join->error : 1);
2145
if (!select_lex->uncacheable && thd->lex->describe &&
2146
!(join->select_options & SELECT_DESCRIBE) &&
2147
join->need_tmp && item->const_item())
2150
Force join->join_tmp creation, because this subquery will be replaced
2151
by a simple select from the materialization temp table by optimize()
2152
called by EXPLAIN and we need to preserve the initial query structure
2153
so we can display it.
2155
select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
2156
select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
2157
if (join->init_save_join_tab())
2158
return(1); /* purecov: inspected */
2160
if (item->engine_changed)
2165
if (select_lex->uncacheable &&
2166
select_lex->uncacheable != UNCACHEABLE_EXPLAIN
2171
thd->where= save_where;
2172
thd->lex->current_select= save_select;
2176
item->assigned((executed= 0));
2180
item->reset_value_registration();
2181
JOIN_TAB *changed_tabs[MAX_TABLES];
2182
JOIN_TAB **last_changed_tab= changed_tabs;
2183
if (item->have_guarded_conds())
2186
For at least one of the pushed predicates the following is true:
2187
We should not apply optimizations based on the condition that was
2188
pushed down into the subquery. Those optimizations are ref[_or_null]
2189
acceses. Change them to be full table scans.
2191
for (uint i=join->const_tables ; i < join->tables ; i++)
2193
JOIN_TAB *tab=join->join_tab+i;
2194
if (tab && tab->keyuse)
2196
for (uint i= 0; i < tab->ref.key_parts; i++)
2198
bool *cond_guard= tab->ref.cond_guards[i];
2199
if (cond_guard && !*cond_guard)
2201
/* Change the access method to full table scan */
2202
tab->save_read_first_record= tab->read_first_record;
2203
tab->save_read_record= tab->read_record.read_record;
2204
tab->read_first_record= init_read_record_seq;
2205
tab->read_record.record= tab->table->record[0];
2206
tab->read_record.thd= join->thd;
2207
tab->read_record.ref_length= tab->table->file->ref_length;
2208
*(last_changed_tab++)= tab;
2218
/* Enable the optimizations back */
2219
for (JOIN_TAB **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
2221
JOIN_TAB *tab= *ptab;
2222
tab->read_record.record= 0;
2223
tab->read_record.ref_length= 0;
2224
tab->read_first_record= tab->save_read_first_record;
2225
tab->read_record.read_record= tab->save_read_record;
2228
thd->where= save_where;
2229
thd->lex->current_select= save_select;
2230
return(join->error||thd->is_fatal_error);
2232
thd->where= save_where;
2233
thd->lex->current_select= save_select;
2237
int subselect_union_engine::exec()
2239
char const *save_where= thd->where;
2240
int res= unit->exec();
2241
thd->where= save_where;
2247
Search for at least one row satisfying select condition
2250
subselect_uniquesubquery_engine::scan_table()
2253
Scan the table using sequential access until we find at least one row
2254
satisfying select condition.
2256
The caller must set this->empty_result_set=false before calling this
2257
function. This function will set it to true if it finds a matching row.
2264
int subselect_uniquesubquery_engine::scan_table()
2267
TABLE *table= tab->table;
2269
if (table->file->inited)
2270
table->file->ha_index_end();
2272
table->file->ha_rnd_init(1);
2273
table->file->extra_opt(HA_EXTRA_CACHE,
2274
current_thd->variables.read_buff_size);
2278
error=table->file->rnd_next(table->record[0]);
2279
if (error && error != HA_ERR_END_OF_FILE)
2281
error= report_error(table, error);
2288
if (!cond || cond->val_int())
2290
empty_result_set= false;
2295
table->file->ha_rnd_end();
2301
Copy ref key and check for null parts in it
2304
subselect_uniquesubquery_engine::copy_ref_key()
2307
Copy ref key and check for null parts in it.
2308
Depending on the nullability and conversion problems this function
2309
recognizes and processes the following states :
2310
1. Partial match on top level. This means IN has a value of false
2311
regardless of the data in the subquery table.
2312
Detected by finding a NULL in the left IN operand of a top level
2314
We may actually skip reading the subquery, so return true to skip
2315
the table scan in subselect_uniquesubquery_engine::exec and make
2316
the value of the IN predicate a NULL (that is equal to false on
2318
2. No exact match when IN is nested inside another predicate.
2319
Detected by finding a NULL in the left IN operand when IN is not
2320
a top level predicate.
2321
We cannot have an exact match. But we must proceed further with a
2322
table scan to find out if it's a partial match (and IN has a value
2323
of NULL) or no match (and IN has a value of false).
2324
So we return false to continue with the scan and see if there are
2325
any record that would constitute a partial match (as we cannot
2326
determine that from the index).
2327
3. Error converting the left IN operand to the column type of the
2328
right IN operand. This counts as no match (and IN has the value of
2329
false). We mark the subquery table cursor as having no more rows
2330
(to ensure that the processing that follows will not find a match)
2331
and return false, so IN is not treated as returning NULL.
2335
false - The value of the IN predicate is not known. Proceed to find the
2336
value of the IN predicate using the determined values of
2337
null_keypart and table->status.
2338
true - IN predicate has a value of NULL. Stop the processing right there
2339
and return NULL to the outer predicates.
2342
bool subselect_uniquesubquery_engine::copy_ref_key()
2344
for (store_key **copy= tab->ref.key_copy ; *copy ; copy++)
2346
enum store_key::store_key_result store_res;
2347
store_res= (*copy)->copy();
2348
tab->ref.key_err= store_res;
2351
When there is a NULL part in the key we don't need to make index
2352
lookup for such key thus we don't need to copy whole key.
2353
If we later should do a sequential scan return OK. Fail otherwise.
2355
See also the comment for the subselect_uniquesubquery_engine::exec()
2358
null_keypart= (*copy)->null_key;
2361
bool top_level= ((Item_in_subselect *) item)->is_top_level_item();
2364
/* Partial match on top level */
2369
/* No exact match when IN is nested inside another predicate */
2375
Check if the error is equal to STORE_KEY_FATAL. This is not expressed
2376
using the store_key::store_key_result enum because ref.key_err is a
2377
boolean and we want to detect both true and STORE_KEY_FATAL from the
2378
space of the union of the values of [true, false] and
2379
store_key::store_key_result.
2380
TODO: fix the variable an return types.
2382
if (store_res == store_key::STORE_KEY_FATAL)
2385
Error converting the left IN operand to the column type of the right
2388
tab->table->status= STATUS_NOT_FOUND;
2400
subselect_uniquesubquery_engine::exec()
2403
Find rows corresponding to the ref key using index access.
2404
If some part of the lookup key is NULL, then we're evaluating
2405
NULL IN (SELECT ... )
2406
This is a special case, we don't need to search for NULL in the table,
2407
instead, the result value is
2408
- NULL if select produces empty row set
2411
In some cases (IN subselect is a top level item, i.e. abort_on_null==true)
2412
the caller doesn't distinguish between NULL and false result and we just
2414
Otherwise we make a full table scan to see if there is at least one
2417
The result of this function (info about whether a row was found) is
2418
stored in this->empty_result_set.
2423
true - an error occured while scanning
2426
int subselect_uniquesubquery_engine::exec()
2429
TABLE *table= tab->table;
2430
empty_result_set= true;
2433
/* TODO: change to use of 'full_scan' here? */
2439
We know that there will be no rows even if we scan.
2440
Can be set in copy_ref_key.
2442
((Item_in_subselect *) item)->value= 0;
2447
return(scan_table());
2449
if (!table->file->inited)
2450
table->file->ha_index_init(tab->ref.key, 0);
2451
error= table->file->index_read_map(table->record[0],
2453
make_prev_keypart_map(tab->ref.key_parts),
2456
error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
2457
error= report_error(table, error);
2462
if (!table->status && (!cond || cond->val_int()))
2464
((Item_in_subselect *) item)->value= 1;
2465
empty_result_set= false;
2468
((Item_in_subselect *) item)->value= 0;
2476
Index-lookup subselect 'engine' - run the subquery
2479
subselect_indexsubquery_engine:exec()
2483
The engine is used to resolve subqueries in form
2485
oe IN (SELECT key FROM tbl WHERE subq_where)
2487
The value of the predicate is calculated as follows:
2488
1. If oe IS NULL, this is a special case, do a full table scan on
2489
table tbl and search for row that satisfies subq_where. If such
2490
row is found, return NULL, otherwise return false.
2491
2. Make an index lookup via key=oe, search for a row that satisfies
2492
subq_where. If found, return true.
2493
3. If check_null==true, make another lookup via key=NULL, search for a
2494
row that satisfies subq_where. If found, return NULL, otherwise
2498
The step #1 can be optimized further when the index has several key
2499
parts. Consider a subquery:
2501
(oe1, oe2) IN (SELECT keypart1, keypart2 FROM tbl WHERE subq_where)
2503
and suppose we need to evaluate it for {oe1, oe2}=={const1, NULL}.
2504
Current code will do a full table scan and obtain correct result. There
2505
is a better option: instead of evaluating
2507
SELECT keypart1, keypart2 FROM tbl WHERE subq_where (1)
2509
and checking if it has produced any matching rows, evaluate
2511
SELECT keypart2 FROM tbl WHERE subq_where AND keypart1=const1 (2)
2513
If this query produces a row, the result is NULL (as we're evaluating
2514
"(const1, NULL) IN { (const1, X), ... }", which has a value of UNKNOWN,
2515
i.e. NULL). If the query produces no rows, the result is false.
2517
We currently evaluate (1) by doing a full table scan. (2) can be
2518
evaluated by doing a "ref" scan on "keypart1=const1", which can be much
2519
cheaper. We can use index statistics to quickly check whether "ref" scan
2520
will be cheaper than full table scan.
2527
int subselect_indexsubquery_engine::exec()
2530
bool null_finding= 0;
2531
TABLE *table= tab->table;
2533
((Item_in_subselect *) item)->value= 0;
2534
empty_result_set= true;
2540
/* We need to check for NULL if there wasn't a matching value */
2541
*tab->ref.null_ref_key= 0; // Search first for not null
2542
((Item_in_subselect *) item)->was_null= 0;
2545
/* Copy the ref key and check for nulls... */
2552
We know that there will be no rows even if we scan.
2553
Can be set in copy_ref_key.
2555
((Item_in_subselect *) item)->value= 0;
2560
return(scan_table());
2562
if (!table->file->inited)
2563
table->file->ha_index_init(tab->ref.key, 1);
2564
error= table->file->index_read_map(table->record[0],
2566
make_prev_keypart_map(tab->ref.key_parts),
2569
error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
2570
error= report_error(table, error);
2579
if ((!cond || cond->val_int()) && (!having || having->val_int()))
2581
empty_result_set= false;
2583
((Item_in_subselect *) item)->was_null= 1;
2585
((Item_in_subselect *) item)->value= 1;
2588
error= table->file->index_next_same(table->record[0],
2590
tab->ref.key_length);
2591
if (error && error != HA_ERR_END_OF_FILE)
2593
error= report_error(table, error);
2599
if (!check_null || null_finding)
2600
break; /* We don't need to check nulls */
2601
*tab->ref.null_ref_key= 1;
2603
/* Check if there exists a row with a null value in the index */
2604
if ((error= (safe_index_read(tab) == 1)))
2613
uint subselect_single_select_engine::cols()
2615
return select_lex->item_list.elements;
2619
uint subselect_union_engine::cols()
2621
return unit->types.elements;
2625
uint8 subselect_single_select_engine::uncacheable()
2627
return select_lex->uncacheable;
2631
uint8 subselect_union_engine::uncacheable()
2633
return unit->uncacheable;
2637
void subselect_single_select_engine::exclude()
2639
select_lex->master_unit()->exclude_level();
2642
void subselect_union_engine::exclude()
2644
unit->exclude_level();
2648
void subselect_uniquesubquery_engine::exclude()
2650
//this never should be called
2655
table_map subselect_engine::calc_const_tables(TABLE_LIST *table)
2658
for (; table; table= table->next_leaf)
2660
TABLE *tbl= table->table;
2661
if (tbl && tbl->const_table)
2668
table_map subselect_single_select_engine::upper_select_const_tables()
2670
return calc_const_tables((TABLE_LIST *) select_lex->outer_select()->
2675
table_map subselect_union_engine::upper_select_const_tables()
2677
return calc_const_tables((TABLE_LIST *) unit->outer_select()->leaf_tables);
2681
void subselect_single_select_engine::print(String *str,
2682
enum_query_type query_type)
2684
select_lex->print(thd, str, query_type);
2688
void subselect_union_engine::print(String *str, enum_query_type query_type)
2690
unit->print(str, query_type);
2694
void subselect_uniquesubquery_engine::print(String *str,
2695
enum_query_type query_type)
2697
char *table_name= tab->table->s->table_name.str;
2698
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2699
tab->ref.items[0]->print(str, query_type);
2700
str->append(STRING_WITH_LEN(" in "));
2701
if (tab->table->s->table_category == TABLE_CATEGORY_TEMPORARY)
2704
Temporary tables' names change across runs, so they can't be used for
2707
str->append(STRING_WITH_LEN("<temporary table>"));
2710
str->append(table_name, tab->table->s->table_name.length);
2711
KEY *key_info= tab->table->key_info+ tab->ref.key;
2712
str->append(STRING_WITH_LEN(" on "));
2713
str->append(key_info->name);
2716
str->append(STRING_WITH_LEN(" where "));
2717
cond->print(str, query_type);
2724
The above ::print method should be changed as below. Do it after
2725
all other tests pass.
2727
void subselect_uniquesubquery_engine::print(String *str)
2729
KEY *key_info= tab->table->key_info + tab->ref.key;
2730
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2731
for (uint i= 0; i < key_info->key_parts; i++)
2732
tab->ref.items[i]->print(str);
2733
str->append(STRING_WITH_LEN(" in "));
2734
str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2735
str->append(STRING_WITH_LEN(" on "));
2736
str->append(key_info->name);
2739
str->append(STRING_WITH_LEN(" where "));
2746
void subselect_indexsubquery_engine::print(String *str,
2747
enum_query_type query_type)
2749
str->append(STRING_WITH_LEN("<index_lookup>("));
2750
tab->ref.items[0]->print(str, query_type);
2751
str->append(STRING_WITH_LEN(" in "));
2752
str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2753
KEY *key_info= tab->table->key_info+ tab->ref.key;
2754
str->append(STRING_WITH_LEN(" on "));
2755
str->append(key_info->name);
2757
str->append(STRING_WITH_LEN(" checking NULL"));
2760
str->append(STRING_WITH_LEN(" where "));
2761
cond->print(str, query_type);
2765
str->append(STRING_WITH_LEN(" having "));
2766
having->print(str, query_type);
2772
change select_result object of engine.
2774
@param si new subselect Item
2775
@param res new select_result object
2783
bool subselect_single_select_engine::change_result(Item_subselect *si,
2784
select_result_interceptor *res)
2788
return select_lex->join->change_result(result);
2793
change select_result object of engine.
2795
@param si new subselect Item
2796
@param res new select_result object
2804
bool subselect_union_engine::change_result(Item_subselect *si,
2805
select_result_interceptor *res)
2808
int rc= unit->change_result(res, result);
2815
change select_result emulation, never should be called.
2817
@param si new subselect Item
2818
@param res new select_result object
2826
bool subselect_uniquesubquery_engine::change_result(Item_subselect *si __attribute__((__unused__)),
2827
select_result_interceptor *res __attribute__((__unused__)))
2835
Report about presence of tables in subquery.
2838
true there are not tables used in subquery
2840
false there are some tables in subquery
2842
bool subselect_single_select_engine::no_tables()
2844
return(select_lex->table_list.elements == 0);
2849
Check statically whether the subquery can return NULL
2852
subselect_single_select_engine::may_be_null()
2855
false can guarantee that the subquery never return NULL
2858
bool subselect_single_select_engine::may_be_null()
2860
return ((no_tables() && !join->conds && !join->having) ? maybe_null : 1);
2865
Report about presence of tables in subquery.
2868
true there are not tables used in subquery
2870
false there are some tables in subquery
2872
bool subselect_union_engine::no_tables()
2874
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
2876
if (sl->table_list.elements)
2884
Report about presence of tables in subquery.
2887
true there are not tables used in subquery
2889
false there are some tables in subquery
2892
bool subselect_uniquesubquery_engine::no_tables()
2894
/* returning value is correct, but this method should never be called */
2899
/******************************************************************************
2900
WL#1110 - Implementation of class subselect_hash_sj_engine
2901
******************************************************************************/
2905
Create all structures needed for IN execution that can live between PS
2909
- Create a temporary table to store the result of the IN subquery. The
2910
temporary table has one hash index on all its columns.
2911
- Create a new result sink that sends the result stream of the subquery to
2912
the temporary table,
2913
- Create and initialize a new JOIN_TAB, and TABLE_REF objects to perform
2914
lookups into the indexed temporary table.
2917
Currently Item_subselect::init() already chooses and creates at parse
2918
time an engine with a corresponding JOIN to execute the subquery.
2920
@retval true if error
2921
@retval false otherwise
2924
bool subselect_hash_sj_engine::init_permanent(List<Item> *tmp_columns)
2926
/* The result sink where we will materialize the subquery result. */
2927
select_union *tmp_result_sink;
2928
/* The table into which the subquery is materialized. */
2930
KEY *tmp_key; /* The only index on the temporary table. */
2931
uint tmp_key_parts; /* Number of keyparts in tmp_key. */
2932
Item_in_subselect *item_in= (Item_in_subselect *) item;
2934
/* 1. Create/initialize materialization related objects. */
2937
Create and initialize a select result interceptor that stores the
2938
result stream in a temporary table. The temporary table itself is
2939
managed (created/filled/etc) internally by the interceptor.
2941
if (!(tmp_result_sink= new select_union))
2943
if (tmp_result_sink->create_result_table(
2944
thd, tmp_columns, true,
2945
thd->options | TMP_TABLE_ALL_COLUMNS,
2946
"materialized subselect", true))
2949
tmp_table= tmp_result_sink->table;
2950
tmp_key= tmp_table->key_info;
2951
tmp_key_parts= tmp_key->key_parts;
2954
If the subquery has blobs, or the total key lenght is bigger than some
2955
length, then the created index cannot be used for lookups and we
2956
can't use hash semi join. If this is the case, delete the temporary
2957
table since it will not be used, and tell the caller we failed to
2958
initialize the engine.
2960
if (tmp_table->s->keys == 0)
2962
assert(tmp_table->s->db_type() == myisam_hton);
2964
tmp_table->s->uniques ||
2965
tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
2966
tmp_table->key_info->key_parts > tmp_table->file->max_key_parts());
2967
free_tmp_table(thd, tmp_table);
2972
result= tmp_result_sink;
2975
Make sure there is only one index on the temp table, and it doesn't have
2976
the extra key part created when s->uniques > 0.
2978
assert(tmp_table->s->keys == 1 && tmp_columns->elements == tmp_key_parts);
2981
/* 2. Create/initialize execution related objects. */
2984
Create and initialize the JOIN_TAB that represents an index lookup
2985
plan operator into the materialized subquery result. Notice that:
2986
- this JOIN_TAB has no corresponding JOIN (and doesn't need one), and
2987
- here we initialize only those members that are used by
2988
subselect_uniquesubquery_engine, so these objects are incomplete.
2990
if (!(tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
2992
tab->table= tmp_table;
2993
tab->ref.key= 0; /* The only temp table index. */
2994
tab->ref.key_length= tmp_key->key_length;
2995
if (!(tab->ref.key_buff=
2996
(uchar*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
2997
!(tab->ref.key_copy=
2998
(store_key**) thd->alloc((sizeof(store_key*) *
2999
(tmp_key_parts + 1)))) ||
3001
(Item**) thd->alloc(sizeof(Item*) * tmp_key_parts)))
3004
KEY_PART_INFO *cur_key_part= tmp_key->key_part;
3005
store_key **ref_key= tab->ref.key_copy;
3006
uchar *cur_ref_buff= tab->ref.key_buff;
3008
for (uint i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3010
tab->ref.items[i]= item_in->left_expr->element_index(i);
3011
int null_count= test(cur_key_part->field->real_maybe_null());
3012
*ref_key= new store_key_item(thd, cur_key_part->field,
3014
the NULL byte is taken into account in
3015
cur_key_part->store_length, so instead of
3016
cur_ref_buff + test(maybe_null), we could
3017
use that information instead.
3019
cur_ref_buff + null_count,
3020
null_count ? tab->ref.key_buff : 0,
3021
cur_key_part->length, tab->ref.items[i]);
3022
cur_ref_buff+= cur_key_part->store_length;
3024
*ref_key= NULL; /* End marker. */
3025
tab->ref.key_err= 1;
3026
tab->ref.key_parts= tmp_key_parts;
3033
Initialize members of the engine that need to be re-initilized at each
3036
@retval true if a memory allocation error occurred
3037
@retval false if success
3040
bool subselect_hash_sj_engine::init_runtime()
3043
Create and optimize the JOIN that will be used to materialize
3044
the subquery if not yet created.
3046
materialize_engine->prepare();
3047
/* Let our engine reuse this query plan for materialization. */
3048
materialize_join= materialize_engine->join;
3049
materialize_join->change_result(result);
3054
subselect_hash_sj_engine::~subselect_hash_sj_engine()
3058
free_tmp_table(thd, tab->table);
3063
Cleanup performed after each PS execution.
3066
Called in the end of JOIN::prepare for PS from Item_subselect::cleanup.
3069
void subselect_hash_sj_engine::cleanup()
3071
is_materialized= false;
3072
result->cleanup(); /* Resets the temp table as well. */
3073
materialize_engine->cleanup();
3074
subselect_uniquesubquery_engine::cleanup();
3079
Execute a subquery IN predicate via materialization.
3082
If needed materialize the subquery into a temporary table, then
3083
copmpute the predicate via a lookup into this table.
3085
@retval true if error
3086
@retval false otherwise
3089
int subselect_hash_sj_engine::exec()
3091
Item_in_subselect *item_in= (Item_in_subselect *) item;
3094
Optimize and materialize the subquery during the first execution of
3095
the subquery predicate.
3097
if (!is_materialized)
3100
SELECT_LEX *save_select= thd->lex->current_select;
3101
thd->lex->current_select= materialize_engine->select_lex;
3102
if ((res= materialize_join->optimize()))
3104
materialize_join->exec();
3105
if ((res= test(materialize_join->error || thd->is_fatal_error)))
3110
- Unlock all subquery tables as we don't need them. To implement this
3111
we need to add new functionality to JOIN::join_free that can unlock
3112
all tables in a subquery (and all its subqueries).
3113
- The temp table used for grouping in the subquery can be freed
3114
immediately after materialization (yet it's done together with
3117
is_materialized= true;
3119
If the subquery returned no rows, the temporary table is empty, so we know
3120
directly that the result of IN is false. We first update the table
3121
statistics, then we test if the temporary table for the query result is
3124
tab->table->file->info(HA_STATUS_VARIABLE);
3125
if (!tab->table->file->stats.records)
3127
empty_result_set= true;
3128
item_in->value= false;
3129
/* TODO: check we need this: item_in->null_value= false; */
3132
/* Set tmp_param only if its usable, i.e. tmp_param->copy_field != NULL. */
3133
tmp_param= &(item_in->unit->outer_select()->join->tmp_table_param);
3134
if (tmp_param && !tmp_param->copy_field)
3138
thd->lex->current_select= save_select;
3144
Lookup the left IN operand in the hash index of the materialized subquery.
3146
return(subselect_uniquesubquery_engine::exec());
3151
Print the state of this engine into a string for debugging and views.
3154
void subselect_hash_sj_engine::print(String *str, enum_query_type query_type)
3156
str->append(STRING_WITH_LEN(" <materialize> ("));
3157
materialize_engine->print(str, query_type);
3158
str->append(STRING_WITH_LEN(" ), "));
3160
subselect_uniquesubquery_engine::print(str, query_type);
3162
str->append(STRING_WITH_LEN(
3163
"<the access method for lookups is not yet created>"