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;
3370
int join_read_const_table(JoinTable *tab, optimizer::Position *pos)
3373
Table *table=tab->table;
3374
table->const_table=1;
3376
table->status=STATUS_NO_RECORD;
3378
if (tab->type == AM_SYSTEM)
3380
if ((error=join_read_system(tab)))
3381
{ // Info for DESCRIBE
3382
tab->info="const row not found";
3383
/* Mark for EXPLAIN that the row was not found */
3384
pos->setFanout(0.0);
3385
pos->clearRefDependMap();
3386
if (! table->maybe_null || error > 0)
3392
if (! table->key_read &&
3393
table->covering_keys.test(tab->ref.key) &&
3394
! table->no_keyread &&
3395
(int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS)
3398
table->cursor->extra(HA_EXTRA_KEYREAD);
3399
tab->index= tab->ref.key;
3401
error=join_read_const(tab);
3402
if (table->key_read)
3405
table->cursor->extra(HA_EXTRA_NO_KEYREAD);
3409
tab->info="unique row not found";
3410
/* Mark for EXPLAIN that the row was not found */
3411
pos->setFanout(0.0);
3412
pos->clearRefDependMap();
3413
if (!table->maybe_null || error > 0)
3417
if (*tab->on_expr_ref && !table->null_row)
3419
if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
3420
table->mark_as_null_row();
3422
if (!table->null_row)
3423
table->maybe_null=0;
3425
/* Check appearance of new constant items in Item_equal objects */
3426
Join *join= tab->join;
3428
update_const_equal_items(join->conds, tab);
3430
for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
3432
TableList *embedded;
3433
TableList *embedding= tbl;
3436
embedded= embedding;
3437
if (embedded->on_expr)
3438
update_const_equal_items(embedded->on_expr, tab);
3439
embedding= embedded->getEmbedding();
3442
embedding->getNestedJoin()->join_list.head() == embedded);
3448
int join_read_system(JoinTable *tab)
3450
Table *table= tab->table;
3452
if (table->status & STATUS_GARBAGE) // If first read
3454
if ((error=table->cursor->read_first_row(table->getInsertRecord(),
3455
table->getShare()->getPrimaryKey())))
3457
if (error != HA_ERR_END_OF_FILE)
3458
return table->report_error(error);
3459
tab->table->mark_as_null_row();
3460
table->emptyRecord(); // Make empty record
3463
table->storeRecord();
3465
else if (!table->status) // Only happens with left join
3466
table->restoreRecord(); // restore old record
3468
return table->status ? -1 : 0;
3375
3472
Read a (constant) table when there is at most one matching row.