22
22
@defgroup Query_Optimizer Query Optimizer
28
28
#include <iostream>
29
29
#include <algorithm>
32
#include <drizzled/sql_select.h> /* include join.h */
34
#include <drizzled/error.h>
35
#include <drizzled/gettext.h>
36
#include <drizzled/util/test.h>
37
#include <drizzled/name_resolution_context_state.h>
38
#include <drizzled/nested_join.h>
39
#include <drizzled/probes.h>
40
#include <drizzled/show.h>
41
#include <drizzled/item/cache.h>
42
#include <drizzled/item/cmpfunc.h>
43
#include <drizzled/item/copy_string.h>
44
#include <drizzled/item/uint.h>
45
#include <drizzled/cached_item.h>
46
#include <drizzled/sql_base.h>
47
#include <drizzled/field/blob.h>
48
#include <drizzled/check_stack_overrun.h>
49
#include <drizzled/lock.h>
50
#include <drizzled/item/outer_ref.h>
51
#include <drizzled/index_hint.h>
52
#include <drizzled/records.h>
53
#include <drizzled/internal/iocache.h>
54
#include <drizzled/drizzled.h>
55
#include <drizzled/plugin/storage_engine.h>
57
#include <drizzled/sql_union.h>
58
#include <drizzled/optimizer/key_field.h>
59
#include <drizzled/optimizer/position.h>
60
#include <drizzled/optimizer/sargable_param.h>
61
#include <drizzled/optimizer/key_use.h>
62
#include <drizzled/optimizer/range.h>
63
#include <drizzled/optimizer/quick_range_select.h>
64
#include <drizzled/optimizer/quick_ror_intersect_select.h>
66
#include <drizzled/filesort.h>
67
#include <drizzled/sql_lex.h>
68
#include <drizzled/session.h>
69
#include <drizzled/sort_field.h>
70
#include <drizzled/select_result.h>
32
#include "drizzled/sql_select.h" /* include join.h */
34
#include "drizzled/error.h"
35
#include "drizzled/gettext.h"
36
#include "drizzled/util/test.h"
37
#include "drizzled/name_resolution_context_state.h"
38
#include "drizzled/nested_join.h"
39
#include "drizzled/probes.h"
40
#include "drizzled/show.h"
41
#include "drizzled/item/cache.h"
42
#include "drizzled/item/cmpfunc.h"
43
#include "drizzled/item/copy_string.h"
44
#include "drizzled/item/uint.h"
45
#include "drizzled/cached_item.h"
46
#include "drizzled/sql_base.h"
47
#include "drizzled/field/blob.h"
48
#include "drizzled/check_stack_overrun.h"
49
#include "drizzled/lock.h"
50
#include "drizzled/item/outer_ref.h"
51
#include "drizzled/index_hint.h"
52
#include "drizzled/records.h"
53
#include "drizzled/internal/iocache.h"
54
#include "drizzled/drizzled.h"
56
#include "drizzled/sql_union.h"
57
#include "drizzled/optimizer/key_field.h"
58
#include "drizzled/optimizer/position.h"
59
#include "drizzled/optimizer/sargable_param.h"
60
#include "drizzled/optimizer/key_use.h"
61
#include "drizzled/optimizer/range.h"
62
#include "drizzled/optimizer/quick_range_select.h"
63
#include "drizzled/optimizer/quick_ror_intersect_select.h"
65
#include "drizzled/filesort.h"
72
67
using namespace std;
213
208
bool direct_ref= false;
215
List<Item_outer_ref>::iterator ref_it(select->inner_refs_list.begin());
210
List_iterator<Item_outer_ref> ref_it(select->inner_refs_list);
216
211
while ((ref= ref_it++))
218
213
Item *item= ref->outer_ref;
219
214
Item **item_ref= ref->ref;
220
215
Item_ref *new_ref;
222
@todo this field item already might be present in the select list.
217
TODO: this field item already might be present in the select list.
223
218
In this case instead of adding new field item we could use an
224
219
existing one. The change will lead to less operations for copying fields,
225
220
smaller temporary tables and less data passed through filesort.
1905
1901
Item_cond_and *and_cond= new Item_cond_and(eq_list);
1906
1902
and_cond->quick_fix_field();
1907
1903
List<Item> *args= and_cond->argument_list();
1908
List<Item_equal>::iterator it(cond_equal.current_level.begin());
1904
List_iterator_fast<Item_equal> it(cond_equal.current_level);
1909
1905
while ((item_equal= it++))
1911
1907
item_equal->fix_length_and_dec();
1912
1908
item_equal->update_used_tables();
1913
set_if_bigger(session->getLex()->current_select->max_equal_elems,
1909
set_if_bigger(session->lex->current_select->max_equal_elems,
1914
1910
item_equal->members());
1916
1912
and_cond->cond_equal= cond_equal;
2476
2472
static void propagate_cond_constants(Session *session,
2477
list<COND_CMP>& save_list,
2473
vector<COND_CMP>& save_list,
2478
2474
COND *and_father,
2481
2477
if (cond->type() == Item::COND_ITEM)
2483
2479
bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2484
List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
2480
List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
2486
list<COND_CMP> save;
2482
vector<COND_CMP> save;
2487
2483
while ((item=li++))
2489
2485
propagate_cond_constants(session, save, and_level ? cond : item, item);
2493
2489
// Handle other found items
2494
for (list<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
2490
for (vector<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
2496
Item **args= iter->second->arguments();
2492
Item **args= iter->cmp_func->arguments();
2497
2493
if (not args[0]->const_item())
2499
change_cond_ref_to_const(session, save, iter->first,
2500
iter->first, args[0], args[1] );
2495
change_cond_ref_to_const(session, save_list, iter->and_level,
2496
iter->and_level, args[0], args[1] );
3362
int join_read_const_table(JoinTable *tab, optimizer::Position *pos)
3365
Table *table=tab->table;
3366
table->const_table=1;
3368
table->status=STATUS_NO_RECORD;
3370
if (tab->type == AM_SYSTEM)
3372
if ((error=join_read_system(tab)))
3373
{ // Info for DESCRIBE
3374
tab->info="const row not found";
3375
/* Mark for EXPLAIN that the row was not found */
3376
pos->setFanout(0.0);
3377
pos->clearRefDependMap();
3378
if (! table->maybe_null || error > 0)
3384
if (! table->key_read &&
3385
table->covering_keys.test(tab->ref.key) &&
3386
! table->no_keyread &&
3387
(int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS)
3390
table->cursor->extra(HA_EXTRA_KEYREAD);
3391
tab->index= tab->ref.key;
3393
error=join_read_const(tab);
3394
if (table->key_read)
3397
table->cursor->extra(HA_EXTRA_NO_KEYREAD);
3401
tab->info="unique row not found";
3402
/* Mark for EXPLAIN that the row was not found */
3403
pos->setFanout(0.0);
3404
pos->clearRefDependMap();
3405
if (!table->maybe_null || error > 0)
3409
if (*tab->on_expr_ref && !table->null_row)
3411
if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
3412
table->mark_as_null_row();
3414
if (!table->null_row)
3415
table->maybe_null=0;
3417
/* Check appearance of new constant items in Item_equal objects */
3418
Join *join= tab->join;
3420
update_const_equal_items(join->conds, tab);
3422
for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
3424
TableList *embedded;
3425
TableList *embedding= tbl;
3428
embedded= embedding;
3429
if (embedded->on_expr)
3430
update_const_equal_items(embedded->on_expr, tab);
3431
embedding= embedded->getEmbedding();
3434
embedding->getNestedJoin()->join_list.head() == embedded);
3440
int join_read_system(JoinTable *tab)
3442
Table *table= tab->table;
3444
if (table->status & STATUS_GARBAGE) // If first read
3446
if ((error=table->cursor->read_first_row(table->getInsertRecord(),
3447
table->getShare()->getPrimaryKey())))
3449
if (error != HA_ERR_END_OF_FILE)
3450
return table->report_error(error);
3451
tab->table->mark_as_null_row();
3452
table->emptyRecord(); // Make empty record
3455
table->storeRecord();
3457
else if (!table->status) // Only happens with left join
3458
table->restoreRecord(); // restore old record
3460
return table->status ? -1 : 0;
3375
3464
Read a (constant) table when there is at most one matching row.