12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
23
23
- add function from mysql_select that use JOIN* as parameter to JOIN
24
24
methods (sql_select.h/sql_select.cc)
31
#include <drizzled/sql_select.h>
32
#include <drizzled/error.h>
33
#include <drizzled/item/cache.h>
34
#include <drizzled/item/subselect.h>
35
#include <drizzled/item/cmpfunc.h>
36
#include <drizzled/item/ref_null_helper.h>
37
#include <drizzled/cached_item.h>
38
#include <drizzled/check_stack_overrun.h>
39
#include <drizzled/item/ref_null_helper.h>
40
#include <drizzled/item/direct_ref.h>
41
#include <drizzled/join.h>
46
extern plugin::StorageEngine *myisam_engine;
27
#ifdef USE_PRAGMA_IMPLEMENTATION
28
#pragma implementation // gcc: Class implementation
31
#include "mysql_priv.h"
32
#include "sql_select.h"
48
34
inline Item * and_items(Item* cond, Item *item)
50
36
return (cond? (new Item_cond_and(cond, item)) : item);
53
Item_subselect::Item_subselect() :
55
value_assigned(false),
63
parsing_place(NO_MATTER),
64
have_to_be_excluded(false),
65
const_item_cache(true),
66
engine_changed(false),
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),
85
60
which depends on alterations to the parse tree implemented here.
63
DBUG_ENTER("Item_subselect::init");
64
DBUG_PRINT("enter", ("select_lex: 0x%lx", (long) select_lex));
88
65
unit= select_lex->master_unit();
93
Item can be changed in JOIN::prepare while engine in Join::optimize
70
Item can be changed in JOIN::prepare while engine in JOIN::optimize
94
71
=> we do not copy old_engine here
96
73
engine= unit->item->engine;
115
92
engine= new subselect_single_select_engine(select_lex, result, this);
118
Select_Lex *upper= unit->outer_select();
95
SELECT_LEX *upper= unit->outer_select();
119
96
if (upper->parsing_place == IN_HAVING)
120
97
upper->subquery_in_having= 1;
126
103
Item_subselect::get_select_lex()
128
105
return unit->first_select();
142
120
engine->cleanup();
144
122
value_assigned= 0;
148
126
void Item_singlerow_subselect::cleanup()
128
DBUG_ENTER("Item_singlerow_subselect::cleanup");
150
129
value= 0; row= 0;
151
130
Item_subselect::cleanup();
156
135
void Item_in_subselect::cleanup()
137
DBUG_ENTER("Item_in_subselect::cleanup");
158
138
if (left_expr_cache)
160
140
left_expr_cache->delete_elements();
161
141
delete left_expr_cache;
162
142
left_expr_cache= NULL;
164
first_execution= true;
144
first_execution= TRUE;
165
145
Item_subselect::cleanup();
169
149
Item_subselect::~Item_subselect()
174
154
Item_subselect::trans_res
175
Item_subselect::select_transformer(Join *)
155
Item_subselect::select_transformer(JOIN *join)
157
DBUG_ENTER("Item_subselect::select_transformer");
181
bool Item_subselect::fix_fields(Session *session_param, Item **ref)
162
bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
183
char const *save_where= session_param->where;
164
char const *save_where= thd_param->where;
187
engine->set_session((session= session_param));
168
DBUG_ASSERT(fixed == 0);
169
engine->set_thd((thd= thd_param));
189
if (check_stack_overrun(session, STACK_MIN_SIZE, (unsigned char*)&res))
171
if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res))
192
174
res= engine->prepare();
209
191
// did we changed top item of WHERE condition
210
192
if (unit->outer_select()->where == (*ref))
212
unit->outer_select()->where= substitution; // correct WHERE for PS
193
unit->outer_select()->where= substitution; // correct WHERE for PS
214
194
else if (unit->outer_select()->having == (*ref))
216
unit->outer_select()->having= substitution; // correct HAVING for PS
195
unit->outer_select()->having= substitution; // correct HAVING for PS
219
197
(*ref)= substitution;
220
198
substitution->name= name;
221
199
if (have_to_be_excluded)
226
session->where= "checking transformed subquery";
229
ret= (*ref)->fix_fields(session, ref);
231
session->where= save_where;
202
thd->where= "checking transformed subquery";
204
ret= (*ref)->fix_fields(thd, ref);
205
thd->where= save_where;
234
208
// Is it one field subselect?
235
209
if (engine->cols() > max_columns)
237
211
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
240
214
fix_length_and_dec();
245
if (engine->uncacheable())
219
if ((uncacheable= engine->uncacheable()))
247
221
const_item_cache= 0;
248
if (engine->uncacheable(UNCACHEABLE_RAND))
222
if (uncacheable & UNCACHEABLE_RAND)
250
223
used_tables_cache|= RAND_TABLE_BIT;
256
session->where= save_where;
228
thd->where= save_where;
261
233
bool Item_subselect::walk(Item_processor processor, bool walk_subquery,
262
unsigned char *argument)
265
237
if (walk_subquery)
267
for (Select_Lex *lex= unit->first_select(); lex; lex= lex->next_select())
239
for (SELECT_LEX *lex= unit->first_select(); lex; lex= lex->next_select())
269
241
List_iterator<Item> li(lex->item_list);
273
245
if (lex->where && (lex->where)->walk(processor, walk_subquery, argument))
281
253
if (item->walk(processor, walk_subquery, argument))
284
for (order= (Order*) lex->order_list.first ; order; order= order->next)
256
for (order= (ORDER*) lex->order_list.first ; order; order= order->next)
286
258
if ((*order->item)->walk(processor, walk_subquery, argument))
289
for (order= (Order*) lex->group_list.first ; order; order= order->next)
261
for (order= (ORDER*) lex->group_list.first ; order; order= order->next)
291
263
if ((*order->item)->walk(processor, walk_subquery, argument))
381
354
return const_item_cache;
384
Item *Item_subselect::get_tmp_table_item(Session *session_arg)
357
Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
386
359
if (!with_sum_func && !const_item())
387
360
return new Item_field(result_field);
388
return copy_or_same(session_arg);
361
return copy_or_same(thd_arg);
391
364
void Item_subselect::update_used_tables()
393
if (! engine->uncacheable())
366
if (!engine->uncacheable())
395
368
// did all used tables become static?
396
369
if (!(used_tables_cache & ~engine->upper_select_const_tables()))
410
Item_singlerow_subselect::Item_singlerow_subselect(Select_Lex *select_lex)
383
Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex)
411
384
:Item_subselect(), value(0)
386
DBUG_ENTER("Item_singlerow_subselect::Item_singlerow_subselect");
413
387
init(select_lex, new select_singlerow_subselect(this));
415
389
max_columns= UINT_MAX;
420
394
Item_singlerow_subselect::invalidate_and_restore_select_lex()
422
Select_Lex *result= get_select_lex();
396
DBUG_ENTER("Item_singlerow_subselect::invalidate_and_restore_select_lex");
397
st_select_lex *result= get_select_lex();
427
402
This code restore the parse tree in it's state before the execution of
428
403
Item_singlerow_subselect::Item_singlerow_subselect(),
429
and in particular decouples this object from the Select_Lex,
430
so that the Select_Lex can be used with a different flavor
404
and in particular decouples this object from the SELECT_LEX,
405
so that the SELECT_LEX can be used with a different flavor
431
406
or Item_subselect instead, as part of query rewriting.
433
408
unit->item= NULL;
438
Item_maxmin_subselect::Item_maxmin_subselect(Session *session_param,
413
Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,
439
414
Item_subselect *parent,
440
Select_Lex *select_lex,
415
st_select_lex *select_lex,
442
:Item_singlerow_subselect(), was_values(true)
417
:Item_singlerow_subselect(), was_values(TRUE)
419
DBUG_ENTER("Item_maxmin_subselect::Item_maxmin_subselect");
445
421
init(select_lex, new select_max_min_finder_subselect(this, max_arg));
458
434
this subquery always creates during preparation, so we can assign
461
session= session_param;
466
442
void Item_maxmin_subselect::cleanup()
444
DBUG_ENTER("Item_maxmin_subselect::cleanup");
468
445
Item_singlerow_subselect::cleanup();
471
By default it is true to avoid true reporting by
448
By default it is TRUE to avoid TRUE reporting by
472
449
Item_func_not_all/Item_func_nop_all if this item was never called.
474
Engine exec() set it to false by reset_value_registration() call.
475
select_max_min_finder_subselect::send_data() set it back to true if some
451
Engine exec() set it to FALSE by reset_value_registration() call.
452
select_max_min_finder_subselect::send_data() set it back to TRUE if some
476
453
value will be found.
506
483
Make rollback for it, or special name resolving mode in 5.0.
508
485
Item_subselect::trans_res
509
Item_singlerow_subselect::select_transformer(Join *join)
486
Item_singlerow_subselect::select_transformer(JOIN *join)
488
DBUG_ENTER("Item_singlerow_subselect::select_transformer");
514
Select_Lex *select_lex= join->select_lex;
492
SELECT_LEX *select_lex= join->select_lex;
516
494
if (!select_lex->master_unit()->is_union() &&
517
495
!select_lex->table_list.elements &&
518
496
select_lex->item_list.elements == 1 &&
533
511
have_to_be_excluded= 1;
534
if (session->lex->describe)
512
if (thd->lex->describe)
536
char warn_buff[DRIZZLE_ERRMSG_SIZE];
537
snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
538
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
514
char warn_buff[MYSQL_ERRMSG_SIZE];
515
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
516
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
539
517
ER_SELECT_REDUCED, warn_buff);
541
519
substitution= select_lex->item_list.head();
544
522
'upper' select is not really dependent => we remove this dependence
546
524
substitution->walk(&Item::remove_dependence_processor, 0,
547
(unsigned char *) select_lex->outer_select());
525
(uchar *) select_lex->outer_select());
526
DBUG_RETURN(RES_REDUCE);
554
void Item_singlerow_subselect::store(uint32_t i, Item *item)
532
void Item_singlerow_subselect::store(uint i, Item *item)
556
534
row[i]->store(item);
701
Item_exists_subselect::Item_exists_subselect(Select_Lex *select_lex):
679
Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex):
682
DBUG_ENTER("Item_exists_subselect::Item_exists_subselect");
705
684
init(select_lex, new select_exists_subselect(this));
706
685
max_columns= UINT_MAX;
707
686
null_value= 0; //can't be NULL
708
687
maybe_null= 0; //can't be NULL
721
bool Item_in_subselect::test_limit(Select_Lex_Unit *unit_arg)
700
bool Item_in_subselect::test_limit(st_select_lex_unit *unit_arg)
723
702
if (unit_arg->fake_select_lex &&
724
703
unit_arg->fake_select_lex->test_limit())
727
Select_Lex *sl= unit_arg->first_select();
706
SELECT_LEX *sl= unit_arg->first_select();
728
707
for (; sl; sl= sl->next_select())
730
709
if (sl->test_limit())
736
715
Item_in_subselect::Item_in_subselect(Item * left_exp,
737
Select_Lex *select_lex) :
738
Item_exists_subselect(),
740
left_expr_cache(NULL),
741
first_execution(true),
743
pushed_cond_guards(NULL),
744
sj_convert_priority(0),
745
expr_join_nest(NULL),
746
exec_method(NOT_TRANSFORMED),
716
st_select_lex *select_lex):
717
Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
718
optimizer(0), pushed_cond_guards(NULL), exec_method(NOT_TRANSFORMED),
721
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
749
723
init(select_lex, new select_exists_subselect(this));
750
724
max_columns= UINT_MAX;
754
728
//if test_limit will fail then error will be reported to client
755
729
test_limit(select_lex->master_unit());
759
733
Item_allany_subselect::Item_allany_subselect(Item * left_exp,
760
734
chooser_compare_func_creator fc,
761
Select_Lex *select_lex,
735
st_select_lex *select_lex,
763
737
:Item_in_subselect(), func_creator(fc), all(all_arg)
739
DBUG_ENTER("Item_allany_subselect::Item_allany_subselect");
765
740
left_expr= left_exp;
766
741
func= func_creator(all_arg);
767
742
init(select_lex, new select_exists_subselect(this));
907
str->set((uint64_t)value, &my_charset_bin);
883
str->set((ulonglong)value, &my_charset_bin);
912
888
bool Item_in_subselect::val_bool()
890
DBUG_ASSERT(fixed == 1);
920
896
Must mark the IN predicate as NULL so as to make sure an enclosing NOT
921
predicate will return false. See the comments in
897
predicate will return FALSE. See the comments in
922
898
subselect_uniquesubquery_engine::copy_ref_key for further details.
963
939
Rewrite a single-column subquery using rule-based approach. The subquery
965
941
oe $cmp$ (SELECT ie FROM ... WHERE subq_where ... HAVING subq_having)
967
943
First, try to convert the subquery to scalar-result subquery in one of
970
946
- oe $cmp$ (SELECT MAX(...) ) // handled by Item_singlerow_subselect
971
947
- oe $cmp$ <max>(SELECT ...) // handled by Item_maxmin_subselect
973
949
If that fails, the subquery will be handled with class Item_in_optimizer.
974
950
There are two possibilites:
975
951
- If the subquery execution method is materialization, then the subquery is
988
964
Item_subselect::trans_res
989
Item_in_subselect::single_value_transformer(Join *join,
990
const Comp_creator *func)
965
Item_in_subselect::single_value_transformer(JOIN *join,
992
Select_Lex *select_lex= join->select_lex;
968
SELECT_LEX *select_lex= join->select_lex;
969
DBUG_ENTER("Item_in_subselect::single_value_transformer");
995
972
Check that the right part of the subselect contains no more than one
1055
1032
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;
1035
save_allow_sum_func= thd->lex->allow_sum_func;
1036
thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
1061
1038
Item_sum_(max|min) can't substitute other item => we can use 0 as
1062
1039
reference, also Item_sum_(max|min) can't be fixed after creation, so
1063
1040
we do not check item->fixed
1065
if (item->fix_fields(session, 0))
1067
session->lex->allow_sum_func= save_allow_sum_func;
1042
if (item->fix_fields(thd, 0))
1043
DBUG_RETURN(RES_ERROR);
1044
thd->lex->allow_sum_func= save_allow_sum_func;
1068
1045
/* we added aggregate function => we have to change statistic */
1069
count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
1046
count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
1072
1049
subs= new Item_singlerow_subselect(select_lex);
1076
1053
Item_maxmin_subselect *item;
1077
subs= item= new Item_maxmin_subselect(session, this, select_lex, func->l_op());
1054
subs= item= new Item_maxmin_subselect(thd, this, select_lex, func->l_op());
1078
1055
if (upper_item)
1079
1056
upper_item->set_sub_test(item);
1081
1058
/* fix fields is already called for left expression */
1082
1059
substitution= func->create(left_expr, subs);
1060
DBUG_RETURN(RES_OK);
1086
1063
if (!substitution)
1088
1065
/* We're invoked for the 1st (or the only) SELECT in the subquery UNION */
1089
Select_Lex_Unit *master_unit= select_lex->master_unit();
1066
SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
1090
1067
substitution= optimizer;
1092
Select_Lex *current= session->lex->current_select, *up;
1069
SELECT_LEX *current= thd->lex->current_select, *up;
1094
session->lex->current_select= up= current->return_after_parsing();
1071
thd->lex->current_select= up= current->return_after_parsing();
1095
1072
//optimizer never use Item **ref => we can pass 0 as parameter
1096
if (!optimizer || optimizer->fix_left(session, 0))
1073
if (!optimizer || optimizer->fix_left(thd, 0))
1098
session->lex->current_select= current;
1075
thd->lex->current_select= current;
1076
DBUG_RETURN(RES_ERROR);
1101
session->lex->current_select= current;
1078
thd->lex->current_select= current;
1104
1081
As far as Item_ref_in_optimizer do not substitute itself on fix_fields
1109
1086
(char *)"<no matter>",
1110
1087
(char *)in_left_expr_name);
1112
master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
1089
master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1115
1092
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1117
if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool))))
1119
pushed_cond_guards[0]= true;
1094
if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool))))
1095
DBUG_RETURN(RES_ERROR);
1096
pushed_cond_guards[0]= TRUE;
1140
1117
- If the subquery has aggregates, GROUP BY, or HAVING, convert to
1142
SELECT ie FROM ... HAVING subq_having AND
1119
SELECT ie FROM ... HAVING subq_having AND
1143
1120
trigcond(oe $cmp$ ref_or_null_helper<ie>)
1145
1122
the addition is wrapped into trigger only when we want to distinguish
1146
between NULL and false results.
1123
between NULL and FALSE results.
1148
1125
- Otherwise (no aggregates/GROUP BY/HAVING) convert it to one of the
1151
= If we don't need to distinguish between NULL and false subquery:
1128
= If we don't need to distinguish between NULL and FALSE subquery:
1153
1130
SELECT 1 FROM ... WHERE (oe $cmp$ ie) AND subq_where
1155
1132
= If we need to distinguish between those:
1170
1147
Item_subselect::trans_res
1171
Item_in_subselect::single_value_in_to_exists_transformer(Join * join, const Comp_creator *func)
1148
Item_in_subselect::single_value_in_to_exists_transformer(JOIN * join, Comp_creator *func)
1173
Select_Lex *select_lex= join->select_lex;
1150
SELECT_LEX *select_lex= join->select_lex;
1151
DBUG_ENTER("Item_in_subselect::single_value_in_to_exists_transformer");
1175
select_lex->uncacheable.set(UNCACHEABLE_DEPENDENT);
1153
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1176
1154
if (join->having || select_lex->with_sum_func ||
1177
1155
select_lex->group_list.elements)
1206
1184
we do not check join->having->fixed, because Item_and (from and_items)
1207
1185
or comparison function (from func->create) can't be fixed after creation
1209
tmp= join->having->fix_fields(session, 0);
1187
tmp= join->having->fix_fields(thd, 0);
1210
1188
select_lex->having_fix_field= 0;
1190
DBUG_RETURN(RES_ERROR);
1221
1199
Item *having= item, *orig_item= item;
1222
1200
select_lex->item_list.empty();
1223
1201
select_lex->item_list.push_back(new Item_int("Not_used",
1225
1203
MY_INT64_NUM_DECIMAL_DIGITS));
1226
1204
select_lex->ref_pointer_array[0]= select_lex->item_list.head();
1228
1206
item= func->create(expr, item);
1229
1207
if (!abort_on_null && orig_item->maybe_null)
1248
1226
and_items) or comparison function (from func->create) can't be
1249
1227
fixed after creation
1251
tmp= join->having->fix_fields(session, 0);
1229
tmp= join->having->fix_fields(thd, 0);
1252
1230
select_lex->having_fix_field= 0;
1232
DBUG_RETURN(RES_ERROR);
1255
1233
item= new Item_cond_or(item,
1256
1234
new Item_func_isnull(orig_item));
1259
1237
If we may encounter NULL IN (SELECT ...) and care whether subquery
1260
result is NULL or false, wrap condition in a trig_cond.
1238
result is NULL or FALSE, wrap condition in a trig_cond.
1262
1240
if (!abort_on_null && left_expr->maybe_null)
1264
1242
if (!(item= new Item_func_trig_cond(item, get_cond_guard(0))))
1243
DBUG_RETURN(RES_ERROR);
1268
TODO: figure out why the following is done here in
1246
TODO: figure out why the following is done here in
1269
1247
single_value_transformer but there is no corresponding action in
1270
1248
row_value_transformer?
1306
1284
if (!(new_having= new Item_func_trig_cond(new_having,
1307
1285
get_cond_guard(0))))
1286
DBUG_RETURN(RES_ERROR);
1310
1288
new_having->name= (char*)in_having_cond;
1311
1289
select_lex->having= join->having= new_having;
1312
1290
select_lex->having_fix_field= 1;
1315
1293
we do not check join->having->fixed, because comparison function
1316
1294
(from func->create) can't be fixed after creation
1318
tmp= join->having->fix_fields(session, 0);
1296
tmp= join->having->fix_fields(thd, 0);
1319
1297
select_lex->having_fix_field= 0;
1299
DBUG_RETURN(RES_ERROR);
1327
1305
// fix_field of item will be done in time of substituting
1328
1306
substitution= item;
1329
1307
have_to_be_excluded= 1;
1330
if (session->lex->describe)
1308
if (thd->lex->describe)
1332
char warn_buff[DRIZZLE_ERRMSG_SIZE];
1333
snprintf(warn_buff, sizeof(warn_buff), ER(ER_SELECT_REDUCED), select_lex->select_number);
1334
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1310
char warn_buff[MYSQL_ERRMSG_SIZE];
1311
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
1312
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1335
1313
ER_SELECT_REDUCED, warn_buff);
1315
DBUG_RETURN(RES_REDUCE);
1320
DBUG_RETURN(RES_OK);
1346
1324
Item_subselect::trans_res
1347
Item_in_subselect::row_value_transformer(Join *join)
1325
Item_in_subselect::row_value_transformer(JOIN *join)
1349
Select_Lex *select_lex= join->select_lex;
1350
uint32_t cols_num= left_expr->cols();
1327
SELECT_LEX *select_lex= join->select_lex;
1328
uint cols_num= left_expr->cols();
1330
DBUG_ENTER("Item_in_subselect::row_value_transformer");
1352
1332
if (select_lex->item_list.elements != left_expr->cols())
1354
1334
my_error(ER_OPERAND_COLUMNS, MYF(0), left_expr->cols());
1335
DBUG_RETURN(RES_ERROR);
1362
1342
if (!substitution)
1364
1344
//first call for this unit
1365
Select_Lex_Unit *master_unit= select_lex->master_unit();
1345
SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
1366
1346
substitution= optimizer;
1368
Select_Lex *current= session->lex->current_select, *up;
1369
session->lex->current_select= up= current->return_after_parsing();
1348
SELECT_LEX *current= thd->lex->current_select, *up;
1349
thd->lex->current_select= up= current->return_after_parsing();
1370
1350
//optimizer never use Item **ref => we can pass 0 as parameter
1371
if (!optimizer || optimizer->fix_left(session, 0))
1351
if (!optimizer || optimizer->fix_left(thd, 0))
1373
session->lex->current_select= current;
1353
thd->lex->current_select= current;
1354
DBUG_RETURN(RES_ERROR);
1377
1357
// we will refer to upper level cache array => we have to save it in PS
1378
1358
optimizer->keep_top_level_cache();
1380
session->lex->current_select= current;
1381
master_unit->uncacheable.set(UNCACHEABLE_DEPENDENT);
1360
thd->lex->current_select= current;
1361
master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1383
1363
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1385
if (!(pushed_cond_guards= (bool*)join->session->alloc(sizeof(bool) *
1365
if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool) *
1386
1366
left_expr->cols())))
1388
for (uint32_t i= 0; i < cols_num; i++)
1389
pushed_cond_guards[i]= true;
1367
DBUG_RETURN(RES_ERROR);
1368
for (uint i= 0; i < cols_num; i++)
1369
pushed_cond_guards[i]= TRUE;
1423
1403
Item_subselect::trans_res
1424
Item_in_subselect::row_value_in_to_exists_transformer(Join * join)
1404
Item_in_subselect::row_value_in_to_exists_transformer(JOIN * join)
1426
Select_Lex *select_lex= join->select_lex;
1406
SELECT_LEX *select_lex= join->select_lex;
1427
1407
Item *having_item= 0;
1428
uint32_t cols_num= left_expr->cols();
1408
uint cols_num= left_expr->cols();
1429
1409
bool is_having_used= (join->having || select_lex->with_sum_func ||
1430
1410
select_lex->group_list.first ||
1431
1411
!select_lex->table_list.elements);
1433
select_lex->uncacheable.set(UNCACHEABLE_DEPENDENT);
1413
DBUG_ENTER("Item_in_subselect::row_value_in_to_exists_transformer");
1415
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1434
1416
if (is_having_used)
1447
1429
TODO: say here explicitly if the order of AND parts matters or not.
1449
1431
Item *item_having_part2= 0;
1450
for (uint32_t i= 0; i < cols_num; i++)
1432
for (uint i= 0; i < cols_num; i++)
1452
assert((left_expr->fixed && select_lex->ref_pointer_array[i]->fixed) ||
1434
DBUG_ASSERT(left_expr->fixed &&
1435
select_lex->ref_pointer_array[i]->fixed ||
1453
1436
(select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
1454
1437
((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
1455
1438
Item_ref::OUTER_REF));
1456
1439
if (select_lex->ref_pointer_array[i]->
1457
1440
check_cols(left_expr->element_index(i)->cols()))
1441
DBUG_RETURN(RES_ERROR);
1460
1443
new Item_func_eq(new
1461
1444
Item_ref(&select_lex->context,
1480
1463
if (!abort_on_null && left_expr->element_index(i)->maybe_null)
1482
1465
if (!(col_item= new Item_func_trig_cond(col_item, get_cond_guard(i))))
1466
DBUG_RETURN(RES_ERROR);
1485
1468
having_item= and_items(having_item, col_item);
1487
Item *item_nnull_test=
1470
Item *item_nnull_test=
1488
1471
new Item_is_not_null_test(this,
1489
1472
new Item_ref(&select_lex->context,
1525
1508
Item *where_item= 0;
1526
for (uint32_t i= 0; i < cols_num; i++)
1509
for (uint i= 0; i < cols_num; i++)
1528
1511
Item *item, *item_isnull;
1529
assert((left_expr->fixed && select_lex->ref_pointer_array[i]->fixed) ||
1512
DBUG_ASSERT(left_expr->fixed &&
1513
select_lex->ref_pointer_array[i]->fixed ||
1530
1514
(select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
1531
1515
((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
1532
1516
Item_ref::OUTER_REF));
1533
1517
if (select_lex->ref_pointer_array[i]->
1534
1518
check_cols(left_expr->element_index(i)->cols()))
1519
DBUG_RETURN(RES_ERROR);
1537
1521
new Item_func_eq(new
1538
1522
Item_direct_ref(&select_lex->context,
1552
1536
Item *having_col_item=
1553
1537
new Item_is_not_null_test(this,
1555
Item_ref(&select_lex->context,
1539
Item_ref(&select_lex->context,
1556
1540
select_lex->ref_pointer_array + i,
1557
1541
(char *)"<no matter>",
1558
1542
(char *)"<list ref>"));
1561
1545
item_isnull= new
1562
1546
Item_func_isnull(new
1563
1547
Item_direct_ref(&select_lex->context,
1567
1551
(char *)"<list ref>")
1569
1553
item= new Item_cond_or(item, item_isnull);
1571
1555
TODO: why we create the above for cases where the right part
1574
1558
if (left_expr->element_index(i)->maybe_null)
1576
1560
if (!(item= new Item_func_trig_cond(item, get_cond_guard(i))))
1578
if (!(having_col_item=
1561
DBUG_RETURN(RES_ERROR);
1562
if (!(having_col_item=
1579
1563
new Item_func_trig_cond(having_col_item, get_cond_guard(i))))
1564
DBUG_RETURN(RES_ERROR);
1582
1566
having_item= and_items(having_item, having_col_item);
1606
1590
argument (reference) to fix_fields()
1608
1592
select_lex->having_fix_field= 1;
1609
res= join->having->fix_fields(session, 0);
1593
res= join->having->fix_fields(thd, 0);
1610
1594
select_lex->having_fix_field= 0;
1597
DBUG_RETURN(RES_ERROR);
1601
DBUG_RETURN(RES_OK);
1621
1605
Item_subselect::trans_res
1622
Item_in_subselect::select_transformer(Join *join)
1606
Item_in_subselect::select_transformer(JOIN *join)
1624
return select_in_like_transformer(join, Eq_creator::instance());
1608
return select_in_like_transformer(join, &eq_creator);
1649
1633
Item_subselect::trans_res
1650
Item_in_subselect::select_in_like_transformer(Join *join, const Comp_creator *func)
1634
Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
1652
Select_Lex *current= session->lex->current_select, *up;
1653
const char *save_where= session->where;
1636
SELECT_LEX *current= thd->lex->current_select, *up;
1637
const char *save_where= thd->where;
1654
1638
Item_subselect::trans_res res= RES_ERROR;
1641
DBUG_ENTER("Item_in_subselect::select_in_like_transformer");
1659
1645
IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
1660
1646
ORDER BY clause becomes meaningless thus we drop it here.
1662
Select_Lex *sl= current->master_unit()->first_select();
1648
SELECT_LEX *sl= current->master_unit()->first_select();
1663
1649
for (; sl; sl= sl->next_select())
1687
session->lex->current_select= up= current->return_after_parsing();
1673
thd->lex->current_select= up= current->return_after_parsing();
1688
1674
result= (!left_expr->fixed &&
1689
left_expr->fix_fields(session, optimizer->arguments()));
1675
left_expr->fix_fields(thd, optimizer->arguments()));
1690
1676
/* fix_fields can change reference to left_expr, we need reassign it */
1691
1677
left_expr= optimizer->arguments()[0];
1693
session->lex->current_select= current;
1679
thd->lex->current_select= current;
1742
bool Item_in_subselect::fix_fields(Session *session_arg, Item **ref)
1728
bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
1744
1730
bool result = 0;
1746
1732
if (exec_method == SEMI_JOIN)
1747
1733
return !( (*ref)= new Item_int(1));
1749
return result || Item_subselect::fix_fields(session_arg, ref);
1735
if (thd_arg->lex->view_prepare_mode && left_expr && !left_expr->fixed)
1736
result = left_expr->fix_fields(thd_arg, &left_expr);
1738
return result || Item_subselect::fix_fields(thd_arg, ref);
1773
@retval true memory allocation error occurred
1774
@retval false an execution method was chosen successfully
1762
@retval TRUE memory allocation error occurred
1763
@retval FALSE an execution method was chosen successfully
1777
1766
bool Item_in_subselect::setup_engine()
1779
1768
subselect_hash_sj_engine *new_engine= NULL;
1771
DBUG_ENTER("Item_in_subselect::setup_engine");
1782
1773
if (engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE)
1784
1775
/* Create/initialize objects in permanent memory. */
1785
subselect_single_select_engine *old_engine_ptr;
1787
old_engine_ptr= static_cast<subselect_single_select_engine *>(engine);
1789
if (!(new_engine= new subselect_hash_sj_engine(session, this,
1776
subselect_single_select_engine *old_engine;
1778
old_engine= (subselect_single_select_engine*) engine;
1780
if (!(new_engine= new subselect_hash_sj_engine(thd, this,
1791
1782
new_engine->init_permanent(unit->get_unit_column_types()))
1793
Item_subselect::trans_res new_trans_res;
1784
Item_subselect::trans_res trans_res;
1795
1786
If for some reason we cannot use materialization for this IN predicate,
1796
1787
delete all materialization-related objects, and apply the IN=>EXISTS
1800
1791
new_engine= NULL;
1801
1792
exec_method= NOT_TRANSFORMED;
1802
1793
if (left_expr->cols() == 1)
1803
new_trans_res= single_value_in_to_exists_transformer(
1804
old_engine_ptr->join,
1805
Eq_creator::instance());
1794
trans_res= single_value_in_to_exists_transformer(old_engine->join,
1807
new_trans_res= row_value_in_to_exists_transformer(old_engine_ptr->join);
1808
res= (new_trans_res != Item_subselect::RES_OK);
1797
trans_res= row_value_in_to_exists_transformer(old_engine->join);
1798
res= (trans_res != Item_subselect::RES_OK);
1810
1800
if (new_engine)
1811
1801
engine= new_engine;
1815
assert(engine->engine_type() == subselect_engine::HASH_SJ_ENGINE);
1816
new_engine= static_cast<subselect_hash_sj_engine *>(engine);
1805
DBUG_ASSERT(engine->engine_type() == subselect_engine::HASH_SJ_ENGINE);
1806
new_engine= (subselect_hash_sj_engine*) engine;
1819
1809
/* Initilizations done in runtime memory, repeated for each execution. */
1843
1833
but it takes a different kind of collection of items, and the
1844
1834
list we push to is dynamically allocated.
1846
@retval true if a memory allocation error occurred or the cache is
1836
@retval TRUE if a memory allocation error occurred or the cache is
1847
1837
not applicable to the current query
1848
@retval false if success
1838
@retval FALSE if success
1851
1841
bool Item_in_subselect::init_left_expr_cache()
1853
Join *outer_join= NULL;
1844
Next_select_func end_select;
1845
bool use_result_field= FALSE;
1855
1847
outer_join= unit->outer_select()->join;
1856
if (! outer_join || ! outer_join->tables || ! outer_join->join_tab)
1848
if (!outer_join || !outer_join->tables)
1851
If we use end_[send | write]_group to handle complete rows of the outer
1852
query, make the cache of the left IN operand use Item_field::result_field
1853
instead of Item_field::field. We need this because normally
1854
Cached_item_field uses Item::field to fetch field data, while
1855
copy_ref_key() that copies the left IN operand into a lookup key uses
1856
Item::result_field. In the case end_[send | write]_group result_field is
1857
one row behind field.
1859
end_select= outer_join->join_tab[outer_join->tables-1].next_select;
1860
if (end_select == end_send_group || end_select == end_write_group)
1861
use_result_field= TRUE;
1859
1863
if (!(left_expr_cache= new List<Cached_item>))
1862
for (uint32_t i= 0; i < left_expr->cols(); i++)
1866
for (uint i= 0; i < left_expr->cols(); i++)
1864
Cached_item *cur_item_cache= new_Cached_item(session, left_expr->element_index(i));
1868
Cached_item *cur_item_cache= new_Cached_item(thd,
1869
left_expr->element_index(i),
1865
1871
if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
1878
1884
make_cond_for_table() in such a way that it is unchanged when we use
1879
1885
the IN=>EXISTS transformation to compute IN.
1881
@retval true if the predicate is expensive
1882
@retval false otherwise
1887
@retval TRUE if the predicate is expensive
1888
@retval FALSE otherwise
1885
bool Item_in_subselect::is_expensive_processor(unsigned char *)
1891
bool Item_in_subselect::is_expensive_processor(uchar *arg)
1887
1893
return exec_method == MATERIALIZATION;
1891
1897
Item_subselect::trans_res
1892
Item_allany_subselect::select_transformer(Join *join)
1898
Item_allany_subselect::select_transformer(JOIN *join)
1900
DBUG_ENTER("Item_allany_subselect::select_transformer");
1894
1901
exec_method= IN_TO_EXISTS;
1895
1902
if (upper_item)
1896
1903
upper_item->show= 1;
1897
return(select_in_like_transformer(join, func));
1904
DBUG_RETURN(select_in_like_transformer(join, func));
1916
void subselect_engine::set_session(Session *session_arg)
1923
void subselect_engine::set_thd(THD *thd_arg)
1918
session= session_arg;
1920
result->set_session(session_arg);
1927
result->set_thd(thd_arg);
1924
1931
subselect_single_select_engine::
1925
subselect_single_select_engine(Select_Lex *select,
1932
subselect_single_select_engine(st_select_lex *select,
1926
1933
select_result_interceptor *result_arg,
1927
1934
Item_subselect *item_arg)
1928
1935
:subselect_engine(item_arg, result_arg),
1980
1989
void subselect_uniquesubquery_engine::cleanup()
1991
DBUG_ENTER("subselect_uniquesubquery_engine::cleanup");
1982
1992
/* Tell handler we don't need the index anymore */
1983
if (tab->table->cursor->inited)
1984
tab->table->cursor->endIndexScan();
1993
if (tab->table->file->inited)
1994
tab->table->file->ha_index_end();
1989
subselect_union_engine::subselect_union_engine(Select_Lex_Unit *u,
1999
subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
1990
2000
select_result_interceptor *result_arg,
1991
2001
Item_subselect *item_arg)
1992
2002
:subselect_engine(item_arg, result_arg)
2029
join= new Join(session, select_lex->item_list,
2039
join= new JOIN(thd, select_lex->item_list,
2030
2040
select_lex->options | SELECT_NO_UNLOCK, result);
2031
2041
if (!join || !result)
2032
2042
return 1; /* Fatal error is set already. */
2034
Select_Lex *save_select= session->lex->current_select;
2035
session->lex->current_select= select_lex;
2044
SELECT_LEX *save_select= thd->lex->current_select;
2045
thd->lex->current_select= select_lex;
2036
2046
if (join->prepare(&select_lex->ref_pointer_array,
2037
(TableList*) select_lex->table_list.first,
2047
(TABLE_LIST*) select_lex->table_list.first,
2038
2048
select_lex->with_wild,
2039
2049
select_lex->where,
2040
2050
select_lex->order_list.elements +
2041
2051
select_lex->group_list.elements,
2042
(Order*) select_lex->order_list.first,
2043
(Order*) select_lex->group_list.first,
2052
(ORDER*) select_lex->order_list.first,
2053
(ORDER*) select_lex->group_list.first,
2044
2054
select_lex->having,
2045
select_lex, select_lex->master_unit()))
2055
(ORDER*) 0, select_lex,
2056
select_lex->master_unit()))
2047
session->lex->current_select= save_select;
2058
thd->lex->current_select= save_select;
2051
2062
int subselect_union_engine::prepare()
2053
return unit->prepare(session, result, (uint32_t)SELECT_NO_UNLOCK);
2064
return unit->prepare(thd, result, SELECT_NO_UNLOCK);
2056
2067
int subselect_uniquesubquery_engine::prepare()
2058
2069
/* Should never be called. */
2072
2083
return value is undefined if last execution ended in an error.
2075
true - Last subselect execution has produced no rows
2086
TRUE - Last subselect execution has produced no rows
2079
2090
bool subselect_single_select_engine::no_rows()
2081
2092
return !item->assigned();
2086
makes storage for the output values for the subquery and calcuates
2097
makes storage for the output values for the subquery and calcuates
2087
2098
their data and column types and their nullability.
2089
2100
void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
2091
2102
Item *sel_item;
2092
2103
List_iterator_fast<Item> li(item_list);
2093
2104
res_type= STRING_RESULT;
2094
res_field_type= DRIZZLE_TYPE_VARCHAR;
2095
for (uint32_t i= 0; (sel_item= li++); i++)
2105
res_field_type= MYSQL_TYPE_VAR_STRING;
2106
for (uint i= 0; (sel_item= li++); i++)
2097
2108
item->max_length= sel_item->max_length;
2098
2109
res_type= sel_item->result_type();
2137
void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **)
2148
void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row)
2139
2150
//this never should be called
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);
2154
int init_read_record_seq(JOIN_TAB *tab);
2155
int join_read_always_key_or_null(JOIN_TAB *tab);
2156
int join_read_next_same_or_null(READ_RECORD *info);
2147
2158
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;
2160
DBUG_ENTER("subselect_single_select_engine::exec");
2161
char const *save_where= thd->where;
2162
SELECT_LEX *save_select= thd->lex->current_select;
2163
thd->lex->current_select= select_lex;
2152
2164
if (!join->optimized)
2154
Select_Lex_Unit *unit= select_lex->master_unit();
2166
SELECT_LEX_UNIT *unit= select_lex->master_unit();
2156
2168
unit->set_limit(unit->global_parameters);
2169
if (join->flatten_subqueries())
2171
thd->is_fatal_error= TRUE;
2157
2174
if (join->optimize())
2159
session->where= save_where;
2176
thd->where= save_where;
2161
session->lex->current_select= save_select;
2162
return(join->error ? join->error : 1);
2178
thd->lex->current_select= save_select;
2179
DBUG_RETURN(join->error ? join->error : 1);
2164
if (select_lex->uncacheable.none() && session->lex->describe &&
2165
!(join->select_options & SELECT_DESCRIBE) &&
2181
if (!select_lex->uncacheable && thd->lex->describe &&
2182
!(join->select_options & SELECT_DESCRIBE) &&
2166
2183
join->need_tmp && item->const_item())
2171
2188
called by EXPLAIN and we need to preserve the initial query structure
2172
2189
so we can display it.
2174
select_lex->uncacheable.set(UNCACHEABLE_EXPLAIN);
2175
select_lex->master_unit()->uncacheable.set(UNCACHEABLE_EXPLAIN);
2191
select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
2192
select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
2176
2193
if (join->init_save_join_tab())
2194
DBUG_RETURN(1); /* purecov: inspected */
2179
2196
if (item->engine_changed)
2184
if (select_lex->uncacheable.any() &&
2185
! select_lex->uncacheable.test(UNCACHEABLE_EXPLAIN) &&
2201
if (select_lex->uncacheable &&
2202
select_lex->uncacheable != UNCACHEABLE_EXPLAIN
2188
2205
if (join->reinit())
2190
session->where= save_where;
2191
session->lex->current_select= save_select;
2207
thd->where= save_where;
2208
thd->lex->current_select= save_select;
2195
2212
item->assigned((executed= 0));
2207
2224
pushed down into the subquery. Those optimizations are ref[_or_null]
2208
2225
acceses. Change them to be full table scans.
2210
for (uint32_t i=join->const_tables ; i < join->tables ; i++)
2227
for (uint i=join->const_tables ; i < join->tables ; i++)
2212
JoinTable *tab=join->join_tab+i;
2229
JOIN_TAB *tab=join->join_tab+i;
2213
2230
if (tab && tab->keyuse)
2215
for (uint32_t key_part= 0;
2216
key_part < tab->ref.key_parts;
2232
for (uint i= 0; i < tab->ref.key_parts; i++)
2219
bool *cond_guard= tab->ref.cond_guards[key_part];
2234
bool *cond_guard= tab->ref.cond_guards[i];
2220
2235
if (cond_guard && !*cond_guard)
2222
2237
/* Change the access method to full table scan */
2224
2239
tab->save_read_record= tab->read_record.read_record;
2225
2240
tab->read_first_record= init_read_record_seq;
2226
2241
tab->read_record.record= tab->table->record[0];
2227
tab->read_record.session= join->session;
2228
tab->read_record.ref_length= tab->table->cursor->ref_length;
2242
tab->read_record.thd= join->thd;
2243
tab->read_record.ref_length= tab->table->file->ref_length;
2229
2244
*(last_changed_tab++)= tab;
2239
2254
/* Enable the optimizations back */
2240
for (JoinTable **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
2255
for (JOIN_TAB **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
2242
JoinTable *tab= *ptab;
2257
JOIN_TAB *tab= *ptab;
2243
2258
tab->read_record.record= 0;
2244
2259
tab->read_record.ref_length= 0;
2245
tab->read_first_record= tab->save_read_first_record;
2260
tab->read_first_record= tab->save_read_first_record;
2246
2261
tab->read_record.read_record= tab->save_read_record;
2249
session->where= save_where;
2250
session->lex->current_select= save_select;
2251
return(join->error||session->is_fatal_error);
2264
thd->where= save_where;
2265
thd->lex->current_select= save_select;
2266
DBUG_RETURN(join->error||thd->is_fatal_error);
2253
session->where= save_where;
2254
session->lex->current_select= save_select;
2268
thd->where= save_where;
2269
thd->lex->current_select= save_select;
2258
2273
int subselect_union_engine::exec()
2260
char const *save_where= session->where;
2275
char const *save_where= thd->where;
2261
2276
int res= unit->exec();
2262
session->where= save_where;
2277
thd->where= save_where;
2268
2283
Search for at least one row satisfying select condition
2271
2286
subselect_uniquesubquery_engine::scan_table()
2274
2289
Scan the table using sequential access until we find at least one row
2275
2290
satisfying select condition.
2277
The caller must set this->empty_result_set=false before calling this
2278
function. This function will set it to true if it finds a matching row.
2292
The caller must set this->empty_result_set=FALSE before calling this
2293
function. This function will set it to TRUE if it finds a matching row.
2285
2300
int subselect_uniquesubquery_engine::scan_table()
2288
Table *table= tab->table;
2290
if (table->cursor->inited)
2291
table->cursor->endIndexScan();
2293
table->cursor->startTableScan(1);
2294
table->cursor->extra_opt(HA_EXTRA_CACHE,
2295
current_session->variables.read_buff_size);
2303
TABLE *table= tab->table;
2304
DBUG_ENTER("subselect_uniquesubquery_engine::scan_table");
2306
if (table->file->inited)
2307
table->file->ha_index_end();
2309
table->file->ha_rnd_init(1);
2310
table->file->extra_opt(HA_EXTRA_CACHE,
2311
current_thd->variables.read_buff_size);
2296
2312
table->null_row= 0;
2299
error=table->cursor->rnd_next(table->record[0]);
2315
error=table->file->rnd_next(table->record[0]);
2300
2316
if (error && error != HA_ERR_END_OF_FILE)
2302
error= table->report_error(error);
2318
error= report_error(table, error);
2305
2321
/* No more rows */
2328
2344
Copy ref key and check for null parts in it.
2329
2345
Depending on the nullability and conversion problems this function
2330
2346
recognizes and processes the following states :
2331
1. Partial match on top level. This means IN has a value of false
2347
1. Partial match on top level. This means IN has a value of FALSE
2332
2348
regardless of the data in the subquery table.
2333
2349
Detected by finding a NULL in the left IN operand of a top level
2335
We may actually skip reading the subquery, so return true to skip
2351
We may actually skip reading the subquery, so return TRUE to skip
2336
2352
the table scan in subselect_uniquesubquery_engine::exec and make
2337
the value of the IN predicate a NULL (that is equal to false on
2353
the value of the IN predicate a NULL (that is equal to FALSE on
2339
2355
2. No exact match when IN is nested inside another predicate.
2340
2356
Detected by finding a NULL in the left IN operand when IN is not
2341
2357
a top level predicate.
2342
2358
We cannot have an exact match. But we must proceed further with a
2343
2359
table scan to find out if it's a partial match (and IN has a value
2344
of NULL) or no match (and IN has a value of false).
2345
So we return false to continue with the scan and see if there are
2360
of NULL) or no match (and IN has a value of FALSE).
2361
So we return FALSE to continue with the scan and see if there are
2346
2362
any record that would constitute a partial match (as we cannot
2347
2363
determine that from the index).
2348
2364
3. Error converting the left IN operand to the column type of the
2349
2365
right IN operand. This counts as no match (and IN has the value of
2350
false). We mark the subquery table cursor as having no more rows
2366
FALSE). We mark the subquery table cursor as having no more rows
2351
2367
(to ensure that the processing that follows will not find a match)
2352
and return false, so IN is not treated as returning NULL.
2368
and return FALSE, so IN is not treated as returning NULL.
2356
false - The value of the IN predicate is not known. Proceed to find the
2372
FALSE - The value of the IN predicate is not known. Proceed to find the
2357
2373
value of the IN predicate using the determined values of
2358
2374
null_keypart and table->status.
2359
true - IN predicate has a value of NULL. Stop the processing right there
2375
TRUE - IN predicate has a value of NULL. Stop the processing right there
2360
2376
and return NULL to the outer predicates.
2363
2379
bool subselect_uniquesubquery_engine::copy_ref_key()
2365
for (StoredKey **copy= tab->ref.key_copy ; *copy ; copy++)
2381
DBUG_ENTER("subselect_uniquesubquery_engine::copy_ref_key");
2383
for (store_key **copy= tab->ref.key_copy ; *copy ; copy++)
2367
StoredKey::store_key_result store_res= (*copy)->copy();
2385
enum store_key::store_key_result store_res;
2386
store_res= (*copy)->copy();
2368
2387
tab->ref.key_err= store_res;
2395
Check if the error is equal to STORE_KEY_FATAL. This is not expressed
2396
using the StoredKey::store_key_result enum because ref.key_err is a
2397
boolean and we want to detect both true and STORE_KEY_FATAL from the
2398
space of the union of the values of [true, false] and
2399
StoredKey::store_key_result.
2414
Check if the error is equal to STORE_KEY_FATAL. This is not expressed
2415
using the store_key::store_key_result enum because ref.key_err is a
2416
boolean and we want to detect both TRUE and STORE_KEY_FATAL from the
2417
space of the union of the values of [TRUE, FALSE] and
2418
store_key::store_key_result.
2400
2419
TODO: fix the variable an return types.
2402
if (store_res == StoredKey::STORE_KEY_FATAL)
2421
if (store_res == store_key::STORE_KEY_FATAL)
2405
2424
Error converting the left IN operand to the column type of the right
2408
2427
tab->table->status= STATUS_NOT_FOUND;
2424
2443
If some part of the lookup key is NULL, then we're evaluating
2425
2444
NULL IN (SELECT ... )
2426
2445
This is a special case, we don't need to search for NULL in the table,
2427
instead, the result value is
2446
instead, the result value is
2428
2447
- NULL if select produces empty row set
2431
In some cases (IN subselect is a top level item, i.e. abort_on_null==true)
2432
the caller doesn't distinguish between NULL and false result and we just
2434
Otherwise we make a full table scan to see if there is at least one
2450
In some cases (IN subselect is a top level item, i.e. abort_on_null==TRUE)
2451
the caller doesn't distinguish between NULL and FALSE result and we just
2453
Otherwise we make a full table scan to see if there is at least one
2437
2456
The result of this function (info about whether a row was found) is
2438
2457
stored in this->empty_result_set.
2443
true - an error occured while scanning
2462
TRUE - an error occured while scanning
2446
2465
int subselect_uniquesubquery_engine::exec()
2467
DBUG_ENTER("subselect_uniquesubquery_engine::exec");
2449
Table *table= tab->table;
2450
empty_result_set= true;
2469
TABLE *table= tab->table;
2470
empty_result_set= TRUE;
2451
2471
table->status= 0;
2453
2473
/* TODO: change to use of 'full_scan' here? */
2454
2474
if (copy_ref_key())
2456
2476
if (table->status)
2459
We know that there will be no rows even if we scan.
2479
We know that there will be no rows even if we scan.
2460
2480
Can be set in copy_ref_key.
2462
2482
((Item_in_subselect *) item)->value= 0;
2466
2486
if (null_keypart)
2467
return(scan_table());
2469
if (!table->cursor->inited)
2470
table->cursor->startIndexScan(tab->ref.key, 0);
2471
error= table->cursor->index_read_map(table->record[0],
2487
DBUG_RETURN(scan_table());
2489
if (!table->file->inited)
2490
table->file->ha_index_init(tab->ref.key, 0);
2491
error= table->file->index_read_map(table->record[0],
2472
2492
tab->ref.key_buff,
2473
2493
make_prev_keypart_map(tab->ref.key_parts),
2474
2494
HA_READ_KEY_EXACT);
2495
DBUG_PRINT("info", ("lookup result: %i", error));
2476
2497
error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
2477
error= table->report_error(error);
2498
error= report_error(table, error);
2499
2520
subselect_indexsubquery_engine:exec()
2503
2524
The engine is used to resolve subqueries in form
2505
oe IN (SELECT key FROM tbl WHERE subq_where)
2526
oe IN (SELECT key FROM tbl WHERE subq_where)
2507
The value of the predicate is calculated as follows:
2528
The value of the predicate is calculated as follows:
2508
2529
1. If oe IS NULL, this is a special case, do a full table scan on
2509
table tbl and search for row that satisfies subq_where. If such
2510
row is found, return NULL, otherwise return false.
2530
table tbl and search for row that satisfies subq_where. If such
2531
row is found, return NULL, otherwise return FALSE.
2511
2532
2. Make an index lookup via key=oe, search for a row that satisfies
2512
subq_where. If found, return true.
2513
3. If check_null==true, make another lookup via key=NULL, search for a
2533
subq_where. If found, return TRUE.
2534
3. If check_null==TRUE, make another lookup via key=NULL, search for a
2514
2535
row that satisfies subq_where. If found, return NULL, otherwise
2518
2539
The step #1 can be optimized further when the index has several key
2519
2540
parts. Consider a subquery:
2521
2542
(oe1, oe2) IN (SELECT keypart1, keypart2 FROM tbl WHERE subq_where)
2523
2544
and suppose we need to evaluate it for {oe1, oe2}=={const1, NULL}.
2527
2548
SELECT keypart1, keypart2 FROM tbl WHERE subq_where (1)
2529
2550
and checking if it has produced any matching rows, evaluate
2531
2552
SELECT keypart2 FROM tbl WHERE subq_where AND keypart1=const1 (2)
2533
If this query produces a row, the result is NULL (as we're evaluating
2554
If this query produces a row, the result is NULL (as we're evaluating
2534
2555
"(const1, NULL) IN { (const1, X), ... }", which has a value of UNKNOWN,
2535
i.e. NULL). If the query produces no rows, the result is false.
2556
i.e. NULL). If the query produces no rows, the result is FALSE.
2537
2558
We currently evaluate (1) by doing a full table scan. (2) can be
2538
2559
evaluated by doing a "ref" scan on "keypart1=const1", which can be much
2565
2587
/* Copy the ref key and check for nulls... */
2566
2588
if (copy_ref_key())
2569
2591
if (table->status)
2572
We know that there will be no rows even if we scan.
2594
We know that there will be no rows even if we scan.
2573
2595
Can be set in copy_ref_key.
2575
2597
((Item_in_subselect *) item)->value= 0;
2579
2601
if (null_keypart)
2580
return(scan_table());
2602
DBUG_RETURN(scan_table());
2582
if (!table->cursor->inited)
2583
table->cursor->startIndexScan(tab->ref.key, 1);
2584
error= table->cursor->index_read_map(table->record[0],
2604
if (!table->file->inited)
2605
table->file->ha_index_init(tab->ref.key, 1);
2606
error= table->file->index_read_map(table->record[0],
2585
2607
tab->ref.key_buff,
2586
2608
make_prev_keypart_map(tab->ref.key_parts),
2587
2609
HA_READ_KEY_EXACT);
2589
2611
error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
2590
error= table->report_error(error);
2612
error= report_error(table, error);
2599
2621
if ((!cond || cond->val_int()) && (!having || having->val_int()))
2601
empty_result_set= false;
2623
empty_result_set= FALSE;
2602
2624
if (null_finding)
2603
2625
((Item_in_subselect *) item)->was_null= 1;
2605
2627
((Item_in_subselect *) item)->value= 1;
2608
error= table->cursor->index_next_same(table->record[0],
2630
error= table->file->index_next_same(table->record[0],
2609
2631
tab->ref.key_buff,
2610
2632
tab->ref.key_length);
2611
2633
if (error && error != HA_ERR_END_OF_FILE)
2613
error= table->report_error(error);
2635
error= report_error(table, error);
2651
DBUG_RETURN(error != 0);
2633
uint32_t subselect_single_select_engine::cols()
2655
uint subselect_single_select_engine::cols()
2635
2657
return select_lex->item_list.elements;
2639
uint32_t subselect_union_engine::cols()
2661
uint subselect_union_engine::cols()
2641
2663
return unit->types.elements;
2645
bool subselect_single_select_engine::uncacheable()
2647
return select_lex->uncacheable.any();
2651
bool subselect_single_select_engine::uncacheable(uint32_t bit_pos)
2653
return select_lex->uncacheable.test(bit_pos);
2657
bool subselect_union_engine::uncacheable()
2659
return unit->uncacheable.any();
2663
bool subselect_union_engine::uncacheable(uint32_t bit_pos)
2665
return unit->uncacheable.test(bit_pos);
2667
uint8 subselect_single_select_engine::uncacheable()
2669
return select_lex->uncacheable;
2673
uint8 subselect_union_engine::uncacheable()
2675
return unit->uncacheable;
2680
2690
void subselect_uniquesubquery_engine::exclude()
2682
2692
//this never should be called
2687
table_map subselect_engine::calc_const_tables(TableList *table)
2697
table_map subselect_engine::calc_const_tables(TABLE_LIST *table)
2689
2699
table_map map= 0;
2690
2700
for (; table; table= table->next_leaf)
2692
Table *tbl= table->table;
2702
TABLE *tbl= table->table;
2693
2703
if (tbl && tbl->const_table)
2694
2704
map|= tbl->map;
2700
2710
table_map subselect_single_select_engine::upper_select_const_tables()
2702
return calc_const_tables((TableList *) select_lex->outer_select()->
2712
return calc_const_tables((TABLE_LIST *) select_lex->outer_select()->
2707
2717
table_map subselect_union_engine::upper_select_const_tables()
2709
return calc_const_tables((TableList *) unit->outer_select()->leaf_tables);
2719
return calc_const_tables((TABLE_LIST *) unit->outer_select()->leaf_tables);
2713
2723
void subselect_single_select_engine::print(String *str,
2714
2724
enum_query_type query_type)
2716
select_lex->print(session, str, query_type);
2726
select_lex->print(thd, str, query_type);
2726
2736
void subselect_uniquesubquery_engine::print(String *str,
2727
2737
enum_query_type query_type)
2729
char *table_name= const_cast<char *>(tab->table->getShare()->getTableName());
2739
char *table_name= tab->table->s->table_name.str;
2730
2740
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2731
2741
tab->ref.items[0]->print(str, query_type);
2732
2742
str->append(STRING_WITH_LEN(" in "));
2733
if (tab->table->getShare()->isTemporaryCategory())
2743
if (tab->table->s->table_category == TABLE_CATEGORY_TEMPORARY)
2736
2746
Temporary tables' names change across runs, so they can't be used for
2739
2749
str->append(STRING_WITH_LEN("<temporary table>"));
2742
str->append(table_name, tab->table->getShare()->getTableNameSize());
2743
KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
2752
str->append(table_name, tab->table->s->table_name.length);
2753
KEY *key_info= tab->table->key_info+ tab->ref.key;
2744
2754
str->append(STRING_WITH_LEN(" on "));
2745
2755
str->append(key_info->name);
2761
2771
KEY *key_info= tab->table->key_info + tab->ref.key;
2762
2772
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2763
for (uint32_t i= 0; i < key_info->key_parts; i++)
2773
for (uint i= 0; i < key_info->key_parts; i++)
2764
2774
tab->ref.items[i]->print(str);
2765
2775
str->append(STRING_WITH_LEN(" in "));
2766
str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
2776
str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2767
2777
str->append(STRING_WITH_LEN(" on "));
2768
2778
str->append(key_info->name);
2781
2791
str->append(STRING_WITH_LEN("<index_lookup>("));
2782
2792
tab->ref.items[0]->print(str, query_type);
2783
2793
str->append(STRING_WITH_LEN(" in "));
2784
str->append(tab->table->getShare()->getTableName(), tab->table->getShare()->getTableNameSize());
2785
KeyInfo *key_info= tab->table->key_info+ tab->ref.key;
2794
str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2795
KEY *key_info= tab->table->key_info+ tab->ref.key;
2786
2796
str->append(STRING_WITH_LEN(" on "));
2787
2797
str->append(key_info->name);
2788
2798
if (check_null)
2897
2907
Report about presence of tables in subquery.
2900
true there are not tables used in subquery
2910
TRUE there are not tables used in subquery
2902
false there are some tables in subquery
2912
FALSE there are some tables in subquery
2904
2914
bool subselect_union_engine::no_tables()
2906
for (Select_Lex *sl= unit->first_select(); sl; sl= sl->next_select())
2916
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
2908
2918
if (sl->table_list.elements)
2942
2952
temporary table has one hash index on all its columns.
2943
2953
- Create a new result sink that sends the result stream of the subquery to
2944
2954
the temporary table,
2945
- Create and initialize a new JoinTable, and TABLE_REF objects to perform
2955
- Create and initialize a new JOIN_TAB, and TABLE_REF objects to perform
2946
2956
lookups into the indexed temporary table.
2949
2959
Currently Item_subselect::init() already chooses and creates at parse
2950
2960
time an engine with a corresponding JOIN to execute the subquery.
2952
@retval true if error
2953
@retval false otherwise
2962
@retval TRUE if error
2963
@retval FALSE otherwise
2956
2966
bool subselect_hash_sj_engine::init_permanent(List<Item> *tmp_columns)
2958
2968
/* The result sink where we will materialize the subquery result. */
2959
2969
select_union *tmp_result_sink;
2960
2970
/* The table into which the subquery is materialized. */
2962
KeyInfo *tmp_key; /* The only index on the temporary table. */
2963
uint32_t tmp_key_parts; /* Number of keyparts in tmp_key. */
2972
KEY *tmp_key; /* The only index on the temporary table. */
2973
uint tmp_key_parts; /* Number of keyparts in tmp_key. */
2964
2974
Item_in_subselect *item_in= (Item_in_subselect *) item;
2976
DBUG_ENTER("subselect_hash_sj_engine::init_permanent");
2966
2978
/* 1. Create/initialize materialization related objects. */
2971
2983
managed (created/filled/etc) internally by the interceptor.
2973
2985
if (!(tmp_result_sink= new select_union))
2976
2987
if (tmp_result_sink->create_result_table(
2977
session, tmp_columns, true,
2978
session->options | TMP_TABLE_ALL_COLUMNS,
2979
"materialized subselect"))
2988
thd, tmp_columns, TRUE,
2989
thd->options | TMP_TABLE_ALL_COLUMNS,
2990
"materialized subselect", TRUE))
2982
2993
tmp_table= tmp_result_sink->table;
2983
2994
tmp_key= tmp_table->key_info;
2990
3001
table since it will not be used, and tell the caller we failed to
2991
3002
initialize the engine.
2993
if (tmp_table->getShare()->sizeKeys() == 0)
3004
if (tmp_table->s->keys == 0)
2995
assert(tmp_table->getShare()->db_type() == myisam_engine);
2997
tmp_table->getShare()->uniques ||
2998
tmp_table->key_info->key_length >= tmp_table->cursor->getEngine()->max_key_length() ||
2999
tmp_table->key_info->key_parts > tmp_table->cursor->getEngine()->max_key_parts());
3006
DBUG_ASSERT(tmp_table->s->db_type() == myisam_hton);
3008
tmp_table->s->uniques ||
3009
tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
3010
tmp_table->key_info->key_parts > tmp_table->file->max_key_parts());
3011
free_tmp_table(thd, tmp_table);
3005
3016
result= tmp_result_sink;
3008
3019
Make sure there is only one index on the temp table, and it doesn't have
3009
3020
the extra key part created when s->uniques > 0.
3011
assert(tmp_table->getShare()->sizeKeys() == 1 && tmp_columns->elements == tmp_key_parts);
3022
DBUG_ASSERT(tmp_table->s->keys == 1 && tmp_columns->elements == tmp_key_parts);
3014
3025
/* 2. Create/initialize execution related objects. */
3017
Create and initialize the JoinTable that represents an index lookup
3028
Create and initialize the JOIN_TAB that represents an index lookup
3018
3029
plan operator into the materialized subquery result. Notice that:
3019
- this JoinTable has no corresponding JOIN (and doesn't need one), and
3030
- this JOIN_TAB has no corresponding JOIN (and doesn't need one), and
3020
3031
- here we initialize only those members that are used by
3021
3032
subselect_uniquesubquery_engine, so these objects are incomplete.
3023
if (!(tab= (JoinTable*) session->alloc(sizeof(JoinTable))))
3034
if (!(tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
3025
3036
tab->table= tmp_table;
3026
3037
tab->ref.key= 0; /* The only temp table index. */
3027
3038
tab->ref.key_length= tmp_key->key_length;
3028
3039
if (!(tab->ref.key_buff=
3029
(unsigned char*) session->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3040
(uchar*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3030
3041
!(tab->ref.key_copy=
3031
(StoredKey**) session->alloc((sizeof(StoredKey*) *
3042
(store_key**) thd->alloc((sizeof(store_key*) *
3032
3043
(tmp_key_parts + 1)))) ||
3033
3044
!(tab->ref.items=
3034
(Item**) session->alloc(sizeof(Item*) * tmp_key_parts)))
3037
KeyPartInfo *cur_key_part= tmp_key->key_part;
3038
StoredKey **ref_key= tab->ref.key_copy;
3039
unsigned char *cur_ref_buff= tab->ref.key_buff;
3041
for (uint32_t i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3045
(Item**) thd->alloc(sizeof(Item*) * tmp_key_parts)))
3048
KEY_PART_INFO *cur_key_part= tmp_key->key_part;
3049
store_key **ref_key= tab->ref.key_copy;
3050
uchar *cur_ref_buff= tab->ref.key_buff;
3052
for (uint i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3043
3054
tab->ref.items[i]= item_in->left_expr->element_index(i);
3044
3055
int null_count= test(cur_key_part->field->real_maybe_null());
3045
*ref_key= new store_key_item(session, cur_key_part->field,
3056
*ref_key= new store_key_item(thd, cur_key_part->field,
3047
3058
the NULL byte is taken into account in
3048
3059
cur_key_part->store_length, so instead of
3098
3107
Cleanup performed after each PS execution.
3101
Called in the end of Join::prepare for PS from Item_subselect::cleanup.
3110
Called in the end of JOIN::prepare for PS from Item_subselect::cleanup.
3104
3113
void subselect_hash_sj_engine::cleanup()
3106
is_materialized= false;
3115
is_materialized= FALSE;
3107
3116
result->cleanup(); /* Resets the temp table as well. */
3108
3117
materialize_engine->cleanup();
3109
3118
subselect_uniquesubquery_engine::cleanup();
3117
3126
If needed materialize the subquery into a temporary table, then
3118
3127
copmpute the predicate via a lookup into this table.
3120
@retval true if error
3121
@retval false otherwise
3129
@retval TRUE if error
3130
@retval FALSE otherwise
3124
3133
int subselect_hash_sj_engine::exec()
3126
3135
Item_in_subselect *item_in= (Item_in_subselect *) item;
3137
DBUG_ENTER("subselect_hash_sj_engine::exec");
3129
3140
Optimize and materialize the subquery during the first execution of
3130
3141
the subquery predicate.
3132
3143
if (!is_materialized)
3135
Select_Lex *save_select= session->lex->current_select;
3136
session->lex->current_select= materialize_engine->select_lex;
3146
SELECT_LEX *save_select= thd->lex->current_select;
3147
thd->lex->current_select= materialize_engine->select_lex;
3137
3148
if ((res= materialize_join->optimize()))
3139
3150
materialize_join->exec();
3140
if ((res= test(materialize_join->error || session->is_fatal_error)))
3151
if ((res= test(materialize_join->error || thd->is_fatal_error)))
3145
3156
- Unlock all subquery tables as we don't need them. To implement this
3146
we need to add new functionality to Join::join_free that can unlock
3157
we need to add new functionality to JOIN::join_free that can unlock
3147
3158
all tables in a subquery (and all its subqueries).
3148
3159
- The temp table used for grouping in the subquery can be freed
3149
3160
immediately after materialization (yet it's done together with
3152
is_materialized= true;
3163
is_materialized= TRUE;
3154
3165
If the subquery returned no rows, the temporary table is empty, so we know
3155
directly that the result of IN is false. We first update the table
3166
directly that the result of IN is FALSE. We first update the table
3156
3167
statistics, then we test if the temporary table for the query result is
3159
tab->table->cursor->info(HA_STATUS_VARIABLE);
3160
if (!tab->table->cursor->stats.records)
3170
tab->table->file->info(HA_STATUS_VARIABLE);
3171
if (!tab->table->file->stats.records)
3162
empty_result_set= true;
3163
item_in->value= false;
3164
/* TODO: check we need this: item_in->null_value= false; */
3173
empty_result_set= TRUE;
3174
item_in->value= FALSE;
3175
/* TODO: check we need this: item_in->null_value= FALSE; */
3167
3178
/* Set tmp_param only if its usable, i.e. tmp_param->copy_field != NULL. */
3168
3179
tmp_param= &(item_in->unit->outer_select()->join->tmp_table_param);