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"
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"
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>
67
72
using namespace std;
208
213
bool direct_ref= false;
210
List_iterator<Item_outer_ref> ref_it(select->inner_refs_list);
215
List<Item_outer_ref>::iterator ref_it(select->inner_refs_list.begin());
211
216
while ((ref= ref_it++))
213
218
Item *item= ref->outer_ref;
214
219
Item **item_ref= ref->ref;
215
220
Item_ref *new_ref;
217
TODO: this field item already might be present in the select list.
222
@todo this field item already might be present in the select list.
218
223
In this case instead of adding new field item we could use an
219
224
existing one. The change will lead to less operations for copying fields,
220
225
smaller temporary tables and less data passed through filesort.
1901
1905
Item_cond_and *and_cond= new Item_cond_and(eq_list);
1902
1906
and_cond->quick_fix_field();
1903
1907
List<Item> *args= and_cond->argument_list();
1904
List_iterator_fast<Item_equal> it(cond_equal.current_level);
1908
List<Item_equal>::iterator it(cond_equal.current_level.begin());
1905
1909
while ((item_equal= it++))
1907
1911
item_equal->fix_length_and_dec();
1908
1912
item_equal->update_used_tables();
1909
set_if_bigger(session->lex->current_select->max_equal_elems,
1913
set_if_bigger(session->getLex()->current_select->max_equal_elems,
1910
1914
item_equal->members());
1912
1916
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;
3472
3375
Read a (constant) table when there is at most one matching row.