23
23
- add function from mysql_select that use JOIN* as parameter to JOIN
24
24
methods (sql_select.h/sql_select.cc)
26
#include <drizzled/server_includes.h>
27
#include <drizzled/sql_select.h>
28
#include <drizzled/drizzled_error_messages.h>
27
#ifdef USE_PRAGMA_IMPLEMENTATION
28
#pragma implementation // gcc: Class implementation
31
#include "mysql_priv.h"
32
#include "sql_select.h"
30
34
inline Item * and_items(Item* cond, Item *item)
36
40
Item_result_field(), value_assigned(0), thd(0), substitution(0),
37
41
engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
38
42
const_item_cache(1), engine_changed(0), changed(0),
113
120
engine->cleanup();
115
122
value_assigned= 0;
119
126
void Item_singlerow_subselect::cleanup()
128
DBUG_ENTER("Item_singlerow_subselect::cleanup");
121
129
value= 0; row= 0;
122
130
Item_subselect::cleanup();
127
135
void Item_in_subselect::cleanup()
137
DBUG_ENTER("Item_in_subselect::cleanup");
129
138
if (left_expr_cache)
131
140
left_expr_cache->delete_elements();
132
141
delete left_expr_cache;
133
142
left_expr_cache= NULL;
135
first_execution= true;
144
first_execution= TRUE;
136
145
Item_subselect::cleanup();
140
149
Item_subselect::~Item_subselect()
145
154
Item_subselect::trans_res
146
Item_subselect::select_transformer(JOIN *join __attribute__((unused)))
155
Item_subselect::select_transformer(JOIN *join)
157
DBUG_ENTER("Item_subselect::select_transformer");
152
162
bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
154
164
char const *save_where= thd_param->where;
168
DBUG_ASSERT(fixed == 0);
159
169
engine->set_thd((thd= thd_param));
161
if (check_stack_overrun(thd, STACK_MIN_SIZE, (unsigned char*)&res))
171
if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res))
164
174
res= engine->prepare();
243
253
if (item->walk(processor, walk_subquery, argument))
246
for (order= (order_st*) lex->order_list.first ; order; order= order->next)
256
for (order= (ORDER*) lex->order_list.first ; order; order= order->next)
248
258
if ((*order->item)->walk(processor, walk_subquery, argument))
251
for (order= (order_st*) lex->group_list.first ; order; order= order->next)
261
for (order= (ORDER*) lex->group_list.first ; order; order= order->next)
253
263
if ((*order->item)->walk(processor, walk_subquery, argument))
285
295
bool Item_in_subselect::exec()
287
assert(exec_method != MATERIALIZATION ||
297
DBUG_ENTER("Item_in_subselect::exec");
298
DBUG_ASSERT(exec_method != MATERIALIZATION ||
288
299
(exec_method == MATERIALIZATION &&
289
300
engine->engine_type() == subselect_engine::HASH_SJ_ENGINE));
372
383
Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex)
373
384
:Item_subselect(), value(0)
386
DBUG_ENTER("Item_singlerow_subselect::Item_singlerow_subselect");
375
387
init(select_lex, new select_singlerow_subselect(this));
377
389
max_columns= UINT_MAX;
382
394
Item_singlerow_subselect::invalidate_and_restore_select_lex()
396
DBUG_ENTER("Item_singlerow_subselect::invalidate_and_restore_select_lex");
384
397
st_select_lex *result= get_select_lex();
389
402
This code restore the parse tree in it's state before the execution of
395
408
unit->item= NULL;
400
413
Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,
401
414
Item_subselect *parent,
402
415
st_select_lex *select_lex,
404
:Item_singlerow_subselect(), was_values(true)
417
:Item_singlerow_subselect(), was_values(TRUE)
419
DBUG_ENTER("Item_maxmin_subselect::Item_maxmin_subselect");
407
421
init(select_lex, new select_max_min_finder_subselect(this, max_arg));
428
442
void Item_maxmin_subselect::cleanup()
444
DBUG_ENTER("Item_maxmin_subselect::cleanup");
430
445
Item_singlerow_subselect::cleanup();
433
By default it is true to avoid true reporting by
448
By default it is TRUE to avoid TRUE reporting by
434
449
Item_func_not_all/Item_func_nop_all if this item was never called.
436
Engine exec() set it to false by reset_value_registration() call.
437
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
438
453
value will be found.
495
511
have_to_be_excluded= 1;
496
512
if (thd->lex->describe)
498
char warn_buff[DRIZZLE_ERRMSG_SIZE];
514
char warn_buff[MYSQL_ERRMSG_SIZE];
499
515
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
500
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
516
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
501
517
ER_SELECT_REDUCED, warn_buff);
503
519
substitution= select_lex->item_list.head();
506
522
'upper' select is not really dependent => we remove this dependence
508
524
substitution->walk(&Item::remove_dependence_processor, 0,
509
(unsigned char *) select_lex->outer_select());
525
(uchar *) select_lex->outer_select());
526
DBUG_RETURN(RES_REDUCE);
516
void Item_singlerow_subselect::store(uint32_t i, Item *item)
532
void Item_singlerow_subselect::store(uint i, Item *item)
518
534
row[i]->store(item);
698
715
Item_in_subselect::Item_in_subselect(Item * left_exp,
699
716
st_select_lex *select_lex):
700
Item_exists_subselect(), left_expr_cache(0), first_execution(true),
717
Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
701
718
optimizer(0), pushed_cond_guards(NULL), exec_method(NOT_TRANSFORMED),
721
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
704
722
left_expr= left_exp;
705
723
init(select_lex, new select_exists_subselect(this));
706
724
max_columns= UINT_MAX;
863
str->set((uint64_t)value, &my_charset_bin);
883
str->set((ulonglong)value, &my_charset_bin);
868
888
bool Item_in_subselect::val_bool()
890
DBUG_ASSERT(fixed == 1);
876
896
Must mark the IN predicate as NULL so as to make sure an enclosing NOT
877
predicate will return false. See the comments in
897
predicate will return FALSE. See the comments in
878
898
subselect_uniquesubquery_engine::copy_ref_key for further details.
1019
1040
we do not check item->fixed
1021
1042
if (item->fix_fields(thd, 0))
1043
DBUG_RETURN(RES_ERROR);
1023
1044
thd->lex->allow_sum_func= save_allow_sum_func;
1024
1045
/* we added aggregate function => we have to change statistic */
1025
1046
count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
1080
1101
perform the IN -> EXISTS transformation.
1082
1103
if (exec_method == MATERIALIZATION)
1104
DBUG_RETURN(RES_OK);
1085
1106
/* Perform the IN=>EXISTS transformation. */
1086
return(single_value_in_to_exists_transformer(join, func));
1107
DBUG_RETURN(single_value_in_to_exists_transformer(join, func));
1099
1120
trigcond(oe $cmp$ ref_or_null_helper<ie>)
1101
1122
the addition is wrapped into trigger only when we want to distinguish
1102
between NULL and false results.
1123
between NULL and FALSE results.
1104
1125
- Otherwise (no aggregates/GROUP BY/HAVING) convert it to one of the
1107
= 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:
1109
1130
SELECT 1 FROM ... WHERE (oe $cmp$ ie) AND subq_where
1127
1148
Item_in_subselect::single_value_in_to_exists_transformer(JOIN * join, Comp_creator *func)
1129
1150
SELECT_LEX *select_lex= join->select_lex;
1151
DBUG_ENTER("Item_in_subselect::single_value_in_to_exists_transformer");
1131
1153
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1132
1154
if (join->having || select_lex->with_sum_func ||
1177
1199
Item *having= item, *orig_item= item;
1178
1200
select_lex->item_list.empty();
1179
1201
select_lex->item_list.push_back(new Item_int("Not_used",
1181
1203
MY_INT64_NUM_DECIMAL_DIGITS));
1182
1204
select_lex->ref_pointer_array[0]= select_lex->item_list.head();
1207
1229
tmp= join->having->fix_fields(thd, 0);
1208
1230
select_lex->having_fix_field= 0;
1232
DBUG_RETURN(RES_ERROR);
1211
1233
item= new Item_cond_or(item,
1212
1234
new Item_func_isnull(orig_item));
1215
1237
If we may encounter NULL IN (SELECT ...) and care whether subquery
1216
result is NULL or false, wrap condition in a trig_cond.
1238
result is NULL or FALSE, wrap condition in a trig_cond.
1218
1240
if (!abort_on_null && left_expr->maybe_null)
1220
1242
if (!(item= new Item_func_trig_cond(item, get_cond_guard(0))))
1243
DBUG_RETURN(RES_ERROR);
1224
1246
TODO: figure out why the following is done here in
1285
1307
have_to_be_excluded= 1;
1286
1308
if (thd->lex->describe)
1288
char warn_buff[DRIZZLE_ERRMSG_SIZE];
1310
char warn_buff[MYSQL_ERRMSG_SIZE];
1289
1311
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
1290
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1312
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1291
1313
ER_SELECT_REDUCED, warn_buff);
1315
DBUG_RETURN(RES_REDUCE);
1320
DBUG_RETURN(RES_OK);
1303
1325
Item_in_subselect::row_value_transformer(JOIN *join)
1305
1327
SELECT_LEX *select_lex= join->select_lex;
1306
uint32_t cols_num= left_expr->cols();
1328
uint cols_num= left_expr->cols();
1330
DBUG_ENTER("Item_in_subselect::row_value_transformer");
1308
1332
if (select_lex->item_list.elements != left_expr->cols())
1310
1334
my_error(ER_OPERAND_COLUMNS, MYF(0), left_expr->cols());
1335
DBUG_RETURN(RES_ERROR);
1382
1406
SELECT_LEX *select_lex= join->select_lex;
1383
1407
Item *having_item= 0;
1384
uint32_t cols_num= left_expr->cols();
1408
uint cols_num= left_expr->cols();
1385
1409
bool is_having_used= (join->having || select_lex->with_sum_func ||
1386
1410
select_lex->group_list.first ||
1387
1411
!select_lex->table_list.elements);
1413
DBUG_ENTER("Item_in_subselect::row_value_in_to_exists_transformer");
1389
1415
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1390
1416
if (is_having_used)
1403
1429
TODO: say here explicitly if the order of AND parts matters or not.
1405
1431
Item *item_having_part2= 0;
1406
for (uint32_t i= 0; i < cols_num; i++)
1432
for (uint i= 0; i < cols_num; i++)
1408
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 ||
1409
1436
(select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
1410
1437
((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
1411
1438
Item_ref::OUTER_REF));
1412
1439
if (select_lex->ref_pointer_array[i]->
1413
1440
check_cols(left_expr->element_index(i)->cols()))
1441
DBUG_RETURN(RES_ERROR);
1416
1443
new Item_func_eq(new
1417
1444
Item_ref(&select_lex->context,
1481
1508
Item *where_item= 0;
1482
for (uint32_t i= 0; i < cols_num; i++)
1509
for (uint i= 0; i < cols_num; i++)
1484
1511
Item *item, *item_isnull;
1485
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 ||
1486
1514
(select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
1487
1515
((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
1488
1516
Item_ref::OUTER_REF));
1489
1517
if (select_lex->ref_pointer_array[i]->
1490
1518
check_cols(left_expr->element_index(i)->cols()))
1519
DBUG_RETURN(RES_ERROR);
1493
1521
new Item_func_eq(new
1494
1522
Item_direct_ref(&select_lex->context,
1610
1638
Item_subselect::trans_res res= RES_ERROR;
1641
DBUG_ENTER("Item_in_subselect::select_in_like_transformer");
1615
1645
IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
1616
order_st BY clause becomes meaningless thus we drop it here.
1646
ORDER BY clause becomes meaningless thus we drop it here.
1618
1648
SELECT_LEX *sl= current->master_unit()->first_select();
1619
1649
for (; sl; sl= sl->next_select())
1702
1732
if (exec_method == SEMI_JOIN)
1703
1733
return !( (*ref)= new Item_int(1));
1735
if (thd_arg->lex->view_prepare_mode && left_expr && !left_expr->fixed)
1736
result = left_expr->fix_fields(thd_arg, &left_expr);
1705
1738
return result || Item_subselect::fix_fields(thd_arg, ref);
1729
@retval true memory allocation error occurred
1730
@retval false an execution method was chosen successfully
1762
@retval TRUE memory allocation error occurred
1763
@retval FALSE an execution method was chosen successfully
1733
1766
bool Item_in_subselect::setup_engine()
1735
1768
subselect_hash_sj_engine *new_engine= NULL;
1771
DBUG_ENTER("Item_in_subselect::setup_engine");
1738
1773
if (engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE)
1798
1833
but it takes a different kind of collection of items, and the
1799
1834
list we push to is dynamically allocated.
1801
@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
1802
1837
not applicable to the current query
1803
@retval false if success
1838
@retval FALSE if success
1806
1841
bool Item_in_subselect::init_left_expr_cache()
1808
1843
JOIN *outer_join;
1809
1844
Next_select_func end_select;
1810
bool use_result_field= false;
1845
bool use_result_field= FALSE;
1812
1847
outer_join= unit->outer_select()->join;
1813
1848
if (!outer_join || !outer_join->tables)
1816
1851
If we use end_[send | write]_group to handle complete rows of the outer
1817
1852
query, make the cache of the left IN operand use Item_field::result_field
1824
1859
end_select= outer_join->join_tab[outer_join->tables-1].next_select;
1825
1860
if (end_select == end_send_group || end_select == end_write_group)
1826
use_result_field= true;
1861
use_result_field= TRUE;
1828
1863
if (!(left_expr_cache= new List<Cached_item>))
1831
for (uint32_t i= 0; i < left_expr->cols(); i++)
1866
for (uint i= 0; i < left_expr->cols(); i++)
1833
1868
Cached_item *cur_item_cache= new_Cached_item(thd,
1834
1869
left_expr->element_index(i),
1835
1870
use_result_field);
1836
1871
if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
1849
1884
make_cond_for_table() in such a way that it is unchanged when we use
1850
1885
the IN=>EXISTS transformation to compute IN.
1852
@retval true if the predicate is expensive
1853
@retval false otherwise
1887
@retval TRUE if the predicate is expensive
1888
@retval FALSE otherwise
1856
bool Item_in_subselect::is_expensive_processor(unsigned char *arg __attribute__((unused)))
1891
bool Item_in_subselect::is_expensive_processor(uchar *arg)
1858
1893
return exec_method == MATERIALIZATION;
1862
1897
Item_subselect::trans_res
1863
1898
Item_allany_subselect::select_transformer(JOIN *join)
1900
DBUG_ENTER("Item_allany_subselect::select_transformer");
1865
1901
exec_method= IN_TO_EXISTS;
1866
1902
if (upper_item)
1867
1903
upper_item->show= 1;
1868
return(select_in_like_transformer(join, func));
1904
DBUG_RETURN(select_in_like_transformer(join, func));
2005
2044
SELECT_LEX *save_select= thd->lex->current_select;
2006
2045
thd->lex->current_select= select_lex;
2007
2046
if (join->prepare(&select_lex->ref_pointer_array,
2008
(TableList*) select_lex->table_list.first,
2047
(TABLE_LIST*) select_lex->table_list.first,
2009
2048
select_lex->with_wild,
2010
2049
select_lex->where,
2011
2050
select_lex->order_list.elements +
2012
2051
select_lex->group_list.elements,
2013
(order_st*) select_lex->order_list.first,
2014
(order_st*) select_lex->group_list.first,
2052
(ORDER*) select_lex->order_list.first,
2053
(ORDER*) select_lex->group_list.first,
2015
2054
select_lex->having,
2016
(order_st*) 0, select_lex,
2055
(ORDER*) 0, select_lex,
2017
2056
select_lex->master_unit()))
2019
2058
thd->lex->current_select= save_select;
2063
2102
Item *sel_item;
2064
2103
List_iterator_fast<Item> li(item_list);
2065
2104
res_type= STRING_RESULT;
2066
res_field_type= DRIZZLE_TYPE_VARCHAR;
2067
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++)
2069
2108
item->max_length= sel_item->max_length;
2070
2109
res_type= sel_item->result_type();
2128
2168
unit->set_limit(unit->global_parameters);
2129
2169
if (join->flatten_subqueries())
2131
thd->is_fatal_error= true;
2171
thd->is_fatal_error= TRUE;
2134
2174
if (join->optimize())
2136
2176
thd->where= save_where;
2138
2178
thd->lex->current_select= save_select;
2139
return(join->error ? join->error : 1);
2179
DBUG_RETURN(join->error ? join->error : 1);
2141
2181
if (!select_lex->uncacheable && thd->lex->describe &&
2142
2182
!(join->select_options & SELECT_DESCRIBE) &&
2151
2191
select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
2152
2192
select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
2153
2193
if (join->init_save_join_tab())
2154
return(1); /* purecov: inspected */
2194
DBUG_RETURN(1); /* purecov: inspected */
2156
2196
if (item->engine_changed)
2161
2201
if (select_lex->uncacheable &&
2184
2224
pushed down into the subquery. Those optimizations are ref[_or_null]
2185
2225
acceses. Change them to be full table scans.
2187
for (uint32_t i=join->const_tables ; i < join->tables ; i++)
2227
for (uint i=join->const_tables ; i < join->tables ; i++)
2189
2229
JOIN_TAB *tab=join->join_tab+i;
2190
2230
if (tab && tab->keyuse)
2192
for (uint32_t i= 0; i < tab->ref.key_parts; i++)
2232
for (uint i= 0; i < tab->ref.key_parts; i++)
2194
2234
bool *cond_guard= tab->ref.cond_guards[i];
2195
2235
if (cond_guard && !*cond_guard)
2249
2289
Scan the table using sequential access until we find at least one row
2250
2290
satisfying select condition.
2252
The caller must set this->empty_result_set=false before calling this
2253
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.
2260
2300
int subselect_uniquesubquery_engine::scan_table()
2263
Table *table= tab->table;
2303
TABLE *table= tab->table;
2304
DBUG_ENTER("subselect_uniquesubquery_engine::scan_table");
2265
2306
if (table->file->inited)
2266
2307
table->file->ha_index_end();
2303
2344
Copy ref key and check for null parts in it.
2304
2345
Depending on the nullability and conversion problems this function
2305
2346
recognizes and processes the following states :
2306
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
2307
2348
regardless of the data in the subquery table.
2308
2349
Detected by finding a NULL in the left IN operand of a top level
2310
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
2311
2352
the table scan in subselect_uniquesubquery_engine::exec and make
2312
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
2314
2355
2. No exact match when IN is nested inside another predicate.
2315
2356
Detected by finding a NULL in the left IN operand when IN is not
2316
2357
a top level predicate.
2317
2358
We cannot have an exact match. But we must proceed further with a
2318
2359
table scan to find out if it's a partial match (and IN has a value
2319
of NULL) or no match (and IN has a value of false).
2320
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
2321
2362
any record that would constitute a partial match (as we cannot
2322
2363
determine that from the index).
2323
2364
3. Error converting the left IN operand to the column type of the
2324
2365
right IN operand. This counts as no match (and IN has the value of
2325
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
2326
2367
(to ensure that the processing that follows will not find a match)
2327
and return false, so IN is not treated as returning NULL.
2368
and return FALSE, so IN is not treated as returning NULL.
2331
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
2332
2373
value of the IN predicate using the determined values of
2333
2374
null_keypart and table->status.
2334
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
2335
2376
and return NULL to the outer predicates.
2338
2379
bool subselect_uniquesubquery_engine::copy_ref_key()
2381
DBUG_ENTER("subselect_uniquesubquery_engine::copy_ref_key");
2340
2383
for (store_key **copy= tab->ref.key_copy ; *copy ; copy++)
2342
2385
enum store_key::store_key_result store_res;
2371
2414
Check if the error is equal to STORE_KEY_FATAL. This is not expressed
2372
2415
using the store_key::store_key_result enum because ref.key_err is a
2373
boolean and we want to detect both true and STORE_KEY_FATAL from the
2374
space of the union of the values of [true, false] and
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
2375
2418
store_key::store_key_result.
2376
2419
TODO: fix the variable an return types.
2402
2445
This is a special case, we don't need to search for NULL in the table,
2403
2446
instead, the result value is
2404
2447
- NULL if select produces empty row set
2407
In some cases (IN subselect is a top level item, i.e. abort_on_null==true)
2408
the caller doesn't distinguish between NULL and false result and we just
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
2410
2453
Otherwise we make a full table scan to see if there is at least one
2419
true - an error occured while scanning
2462
TRUE - an error occured while scanning
2422
2465
int subselect_uniquesubquery_engine::exec()
2467
DBUG_ENTER("subselect_uniquesubquery_engine::exec");
2425
Table *table= tab->table;
2426
empty_result_set= true;
2469
TABLE *table= tab->table;
2470
empty_result_set= TRUE;
2427
2471
table->status= 0;
2429
2473
/* TODO: change to use of 'full_scan' here? */
2430
2474
if (copy_ref_key())
2432
2476
if (table->status)
2448
2492
tab->ref.key_buff,
2449
2493
make_prev_keypart_map(tab->ref.key_parts),
2450
2494
HA_READ_KEY_EXACT);
2495
DBUG_PRINT("info", ("lookup result: %i", error));
2452
2497
error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
2453
error= table->report_error(error);
2498
error= report_error(table, error);
2483
2528
The value of the predicate is calculated as follows:
2484
2529
1. If oe IS NULL, this is a special case, do a full table scan on
2485
2530
table tbl and search for row that satisfies subq_where. If such
2486
row is found, return NULL, otherwise return false.
2531
row is found, return NULL, otherwise return FALSE.
2487
2532
2. Make an index lookup via key=oe, search for a row that satisfies
2488
subq_where. If found, return true.
2489
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
2490
2535
row that satisfies subq_where. If found, return NULL, otherwise
2494
2539
The step #1 can be optimized further when the index has several key
2509
2554
If this query produces a row, the result is NULL (as we're evaluating
2510
2555
"(const1, NULL) IN { (const1, X), ... }", which has a value of UNKNOWN,
2511
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.
2513
2558
We currently evaluate (1) by doing a full table scan. (2) can be
2514
2559
evaluated by doing a "ref" scan on "keypart1=const1", which can be much
2651
DBUG_RETURN(error != 0);
2609
uint32_t subselect_single_select_engine::cols()
2655
uint subselect_single_select_engine::cols()
2611
2657
return select_lex->item_list.elements;
2615
uint32_t subselect_union_engine::cols()
2661
uint subselect_union_engine::cols()
2617
2663
return unit->types.elements;
2621
uint8_t subselect_single_select_engine::uncacheable()
2667
uint8 subselect_single_select_engine::uncacheable()
2623
2669
return select_lex->uncacheable;
2627
uint8_t subselect_union_engine::uncacheable()
2673
uint8 subselect_union_engine::uncacheable()
2629
2675
return unit->uncacheable;
2644
2690
void subselect_uniquesubquery_engine::exclude()
2646
2692
//this never should be called
2651
table_map subselect_engine::calc_const_tables(TableList *table)
2697
table_map subselect_engine::calc_const_tables(TABLE_LIST *table)
2653
2699
table_map map= 0;
2654
2700
for (; table; table= table->next_leaf)
2656
Table *tbl= table->table;
2702
TABLE *tbl= table->table;
2657
2703
if (tbl && tbl->const_table)
2658
2704
map|= tbl->map;
2664
2710
table_map subselect_single_select_engine::upper_select_const_tables()
2666
return calc_const_tables((TableList *) select_lex->outer_select()->
2712
return calc_const_tables((TABLE_LIST *) select_lex->outer_select()->
2671
2717
table_map subselect_union_engine::upper_select_const_tables()
2673
return calc_const_tables((TableList *) unit->outer_select()->leaf_tables);
2719
return calc_const_tables((TABLE_LIST *) unit->outer_select()->leaf_tables);
2725
2771
KEY *key_info= tab->table->key_info + tab->ref.key;
2726
2772
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2727
for (uint32_t i= 0; i < key_info->key_parts; i++)
2773
for (uint i= 0; i < key_info->key_parts; i++)
2728
2774
tab->ref.items[i]->print(str);
2729
2775
str->append(STRING_WITH_LEN(" in "));
2730
2776
str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2814
2860
@param res new select_result object
2822
bool subselect_uniquesubquery_engine::change_result(Item_subselect *si __attribute__((unused)),
2823
select_result_interceptor *res __attribute__((unused)))
2868
bool subselect_uniquesubquery_engine::change_result(Item_subselect *si,
2869
select_result_interceptor *res)
2831
2877
Report about presence of tables in subquery.
2834
true there are not tables used in subquery
2880
TRUE there are not tables used in subquery
2836
false there are some tables in subquery
2882
FALSE there are some tables in subquery
2838
2884
bool subselect_single_select_engine::no_tables()
2861
2907
Report about presence of tables in subquery.
2864
true there are not tables used in subquery
2910
TRUE there are not tables used in subquery
2866
false there are some tables in subquery
2912
FALSE there are some tables in subquery
2868
2914
bool subselect_union_engine::no_tables()
2870
2916
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
2872
2918
if (sl->table_list.elements)
2880
2926
Report about presence of tables in subquery.
2883
true there are not tables used in subquery
2929
TRUE there are not tables used in subquery
2885
false there are some tables in subquery
2931
FALSE there are some tables in subquery
2888
2934
bool subselect_uniquesubquery_engine::no_tables()
2922
2968
/* The result sink where we will materialize the subquery result. */
2923
2969
select_union *tmp_result_sink;
2924
2970
/* The table into which the subquery is materialized. */
2926
2972
KEY *tmp_key; /* The only index on the temporary table. */
2927
uint32_t tmp_key_parts; /* Number of keyparts in tmp_key. */
2973
uint tmp_key_parts; /* Number of keyparts in tmp_key. */
2928
2974
Item_in_subselect *item_in= (Item_in_subselect *) item;
2976
DBUG_ENTER("subselect_hash_sj_engine::init_permanent");
2930
2978
/* 1. Create/initialize materialization related objects. */
2935
2983
managed (created/filled/etc) internally by the interceptor.
2937
2985
if (!(tmp_result_sink= new select_union))
2939
2987
if (tmp_result_sink->create_result_table(
2940
thd, tmp_columns, true,
2988
thd, tmp_columns, TRUE,
2941
2989
thd->options | TMP_TABLE_ALL_COLUMNS,
2942
"materialized subselect", true))
2990
"materialized subselect", TRUE))
2945
2993
tmp_table= tmp_result_sink->table;
2946
2994
tmp_key= tmp_table->key_info;
2956
3004
if (tmp_table->s->keys == 0)
2958
assert(tmp_table->s->db_type() == myisam_hton);
3006
DBUG_ASSERT(tmp_table->s->db_type() == myisam_hton);
2960
3008
tmp_table->s->uniques ||
2961
3009
tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
2962
3010
tmp_table->key_info->key_parts > tmp_table->file->max_key_parts());
2963
tmp_table->free_tmp_table(thd);
3011
free_tmp_table(thd, tmp_table);
2968
3016
result= tmp_result_sink;
2971
3019
Make sure there is only one index on the temp table, and it doesn't have
2972
3020
the extra key part created when s->uniques > 0.
2974
assert(tmp_table->s->keys == 1 && tmp_columns->elements == tmp_key_parts);
3022
DBUG_ASSERT(tmp_table->s->keys == 1 && tmp_columns->elements == tmp_key_parts);
2977
3025
/* 2. Create/initialize execution related objects. */
2984
3032
subselect_uniquesubquery_engine, so these objects are incomplete.
2986
3034
if (!(tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
2988
3036
tab->table= tmp_table;
2989
3037
tab->ref.key= 0; /* The only temp table index. */
2990
3038
tab->ref.key_length= tmp_key->key_length;
2991
3039
if (!(tab->ref.key_buff=
2992
(unsigned char*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
3040
(uchar*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
2993
3041
!(tab->ref.key_copy=
2994
3042
(store_key**) thd->alloc((sizeof(store_key*) *
2995
3043
(tmp_key_parts + 1)))) ||
2996
3044
!(tab->ref.items=
2997
3045
(Item**) thd->alloc(sizeof(Item*) * tmp_key_parts)))
3000
3048
KEY_PART_INFO *cur_key_part= tmp_key->key_part;
3001
3049
store_key **ref_key= tab->ref.key_copy;
3002
unsigned char *cur_ref_buff= tab->ref.key_buff;
3050
uchar *cur_ref_buff= tab->ref.key_buff;
3004
for (uint32_t i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3052
for (uint i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3006
3054
tab->ref.items[i]= item_in->left_expr->element_index(i);
3007
3055
int null_count= test(cur_key_part->field->real_maybe_null());
3078
3126
If needed materialize the subquery into a temporary table, then
3079
3127
copmpute the predicate via a lookup into this table.
3081
@retval true if error
3082
@retval false otherwise
3129
@retval TRUE if error
3130
@retval FALSE otherwise
3085
3133
int subselect_hash_sj_engine::exec()
3087
3135
Item_in_subselect *item_in= (Item_in_subselect *) item;
3137
DBUG_ENTER("subselect_hash_sj_engine::exec");
3090
3140
Optimize and materialize the subquery during the first execution of
3091
3141
the subquery predicate.
3110
3160
immediately after materialization (yet it's done together with
3113
is_materialized= true;
3163
is_materialized= TRUE;
3115
3165
If the subquery returned no rows, the temporary table is empty, so we know
3116
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
3117
3167
statistics, then we test if the temporary table for the query result is
3120
3170
tab->table->file->info(HA_STATUS_VARIABLE);
3121
3171
if (!tab->table->file->stats.records)
3123
empty_result_set= true;
3124
item_in->value= false;
3125
/* 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; */
3128
3178
/* Set tmp_param only if its usable, i.e. tmp_param->copy_field != NULL. */
3129
3179
tmp_param= &(item_in->unit->outer_select()->join->tmp_table_param);