656
647
use= save_pos= dynamic_element(keyuse, 0, optimizer::KeyUse*);
658
649
found_eq_constant= 0;
659
for (i= 0; i < keyuse->elements-1; i++, use++)
661
if (! use->getUsedTables() && use->getOptimizeFlags() != KEY_OPTIMIZE_REF_OR_NULL)
662
use->getTable()->const_key_parts[use->getKey()]|= use->getKeypartMap();
663
if (use->getKey() == prev->getKey() && use->getTable() == prev->getTable())
653
for (i= 0; i < keyuse->elements-1; i++, use++)
665
if (prev->getKeypart() + 1 < use->getKeypart() ||
666
((prev->getKeypart() == use->getKeypart()) && found_eq_constant))
667
continue; /* remove */
655
if (! use->getUsedTables() && use->getOptimizeFlags() != KEY_OPTIMIZE_REF_OR_NULL)
656
use->getTable()->const_key_parts[use->getKey()]|= use->getKeypartMap();
657
if (use->getKey() == prev->getKey() && use->getTable() == prev->getTable())
659
if (prev->getKeypart() + 1 < use->getKeypart() ||
660
((prev->getKeypart() == use->getKeypart()) && found_eq_constant))
661
continue; /* remove */
663
else if (use->getKeypart() != 0) // First found must be 0
667
/* Valgrind complains about overlapped memcpy when save_pos==use. */
672
found_eq_constant= ! use->getUsedTables();
673
/* Save ptr to first use */
674
if (! use->getTable()->reginfo.join_tab->keyuse)
675
use->getTable()->reginfo.join_tab->keyuse= save_pos;
676
use->getTable()->reginfo.join_tab->checked_keys.set(use->getKey());
669
else if (use->getKeypart() != 0) // First found must be 0
673
/* Valgrind complains about overlapped memcpy when save_pos==use. */
678
found_eq_constant= ! use->getUsedTables();
679
/* Save ptr to first use */
680
if (! use->getTable()->reginfo.join_tab->keyuse)
681
use->getTable()->reginfo.join_tab->keyuse= save_pos;
682
use->getTable()->reginfo.join_tab->checked_keys.set(use->getKey());
679
i= (uint32_t) (save_pos - (optimizer::KeyUse*) keyuse->buffer);
680
set_dynamic(keyuse, (unsigned char*) &key_end, i);
685
i= (uint32_t) (save_pos - (optimizer::KeyUse*) keyuse->buffer);
686
set_dynamic(keyuse, (unsigned char*) &key_end, i);
1215
Check if given expression uses only table fields covered by the given index
1218
uses_index_fields_only()
1219
item Expression to check
1220
tbl The table having the index
1221
keyno The index number
1222
other_tbls_ok true <=> Fields of other non-const tables are allowed
1225
Check if given expression only uses fields covered by index #keyno in the
1226
table tbl. The expression can use any fields in any other tables.
1228
The expression is guaranteed not to be AND or OR - those constructs are
1229
handled outside of this function.
1235
static bool uses_index_fields_only(Item *item, Table *tbl, uint32_t keyno, bool other_tbls_ok)
1237
if (item->const_item())
1241
Don't push down the triggered conditions. Nested outer joins execution
1242
code may need to evaluate a condition several times (both triggered and
1243
untriggered), and there is no way to put thi
1244
TODO: Consider cloning the triggered condition and using the copies for:
1245
1. push the first copy down, to have most restrictive index condition
1247
2. Put the second copy into tab->select_cond.
1249
if (item->type() == Item::FUNC_ITEM &&
1250
((Item_func*)item)->functype() == Item_func::TRIG_COND_FUNC)
1253
if (!(item->used_tables() & tbl->map))
1254
return other_tbls_ok;
1256
Item::Type item_type= item->type();
1257
switch (item_type) {
1258
case Item::FUNC_ITEM:
1260
/* This is a function, apply condition recursively to arguments */
1261
Item_func *item_func= (Item_func*)item;
1263
Item **item_end= (item_func->arguments()) + item_func->argument_count();
1264
for (child= item_func->arguments(); child != item_end; child++)
1266
if (!uses_index_fields_only(*child, tbl, keyno, other_tbls_ok))
1271
case Item::COND_ITEM:
1273
/* This is a function, apply condition recursively to arguments */
1274
List_iterator<Item> li(*((Item_cond*)item)->argument_list());
1276
while ((list_item=li++))
1278
if (!uses_index_fields_only(item, tbl, keyno, other_tbls_ok))
1283
case Item::FIELD_ITEM:
1285
Item_field *item_field= (Item_field*)item;
1286
if (item_field->field->table != tbl)
1288
return item_field->field->part_of_key.test(keyno);
1290
case Item::REF_ITEM:
1291
return uses_index_fields_only(item->real_item(), tbl, keyno,
1294
return false; /* Play it safe, don't push unknown non-const items */
1298
1209
#define ICP_COND_USES_INDEX_ONLY 10
1301
Get a part of the condition that can be checked using only index fields
1304
make_cond_for_index()
1305
cond The source condition
1306
table The table that is partially available
1307
keyno The index in the above table. Only fields covered by the index
1309
other_tbls_ok true <=> Fields of other non-const tables are allowed
1312
Get a part of the condition that can be checked when for the given table
1313
we have values only of fields covered by some index. The condition may
1314
refer to other tables, it is assumed that we have values of all of their
1318
make_cond_for_index(
1319
"cond(t1.field) AND cond(t2.key1) AND cond(t2.non_key) AND cond(t2.key2)",
1322
"cond(t1.field) AND cond(t2.key2)"
1325
Index condition, or NULL if no condition could be inferred.
1327
static Item *make_cond_for_index(Item *cond, Table *table, uint32_t keyno, bool other_tbls_ok)
1331
if (cond->type() == Item::COND_ITEM)
1333
uint32_t n_marked= 0;
1334
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1336
Item_cond_and *new_cond=new Item_cond_and;
1339
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1343
Item *fix= make_cond_for_index(item, table, keyno, other_tbls_ok);
1345
new_cond->argument_list()->push_back(fix);
1346
n_marked += test(item->marker == ICP_COND_USES_INDEX_ONLY);
1348
if (n_marked ==((Item_cond*)cond)->argument_list()->elements)
1349
cond->marker= ICP_COND_USES_INDEX_ONLY;
1350
switch (new_cond->argument_list()->elements) {
1354
return new_cond->argument_list()->head();
1356
new_cond->quick_fix_field();
1362
Item_cond_or *new_cond=new Item_cond_or;
1365
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1369
Item *fix= make_cond_for_index(item, table, keyno, other_tbls_ok);
1372
new_cond->argument_list()->push_back(fix);
1373
n_marked += test(item->marker == ICP_COND_USES_INDEX_ONLY);
1375
if (n_marked ==((Item_cond*)cond)->argument_list()->elements)
1376
cond->marker= ICP_COND_USES_INDEX_ONLY;
1377
new_cond->quick_fix_field();
1378
new_cond->top_level_item();
1383
if (!uses_index_fields_only(cond, table, keyno, other_tbls_ok))
1385
cond->marker= ICP_COND_USES_INDEX_ONLY;
1390
static Item *make_cond_remainder(Item *cond, bool exclude_index)
1392
if (exclude_index && cond->marker == ICP_COND_USES_INDEX_ONLY)
1393
return 0; /* Already checked */
1395
if (cond->type() == Item::COND_ITEM)
1397
table_map tbl_map= 0;
1398
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1400
/* Create new top level AND item */
1401
Item_cond_and *new_cond=new Item_cond_and;
1404
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1408
Item *fix= make_cond_remainder(item, exclude_index);
1411
new_cond->argument_list()->push_back(fix);
1412
tbl_map |= fix->used_tables();
1415
switch (new_cond->argument_list()->elements) {
1419
return new_cond->argument_list()->head();
1421
new_cond->quick_fix_field();
1422
((Item_cond*)new_cond)->used_tables_cache= tbl_map;
1428
Item_cond_or *new_cond=new Item_cond_or;
1431
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1435
Item *fix= make_cond_remainder(item, false);
1438
new_cond->argument_list()->push_back(fix);
1439
tbl_map |= fix->used_tables();
1441
new_cond->quick_fix_field();
1442
((Item_cond*)new_cond)->used_tables_cache= tbl_map;
1443
new_cond->top_level_item();
1451
1213
cleanup JoinTable.
2873
2635
Do update counters for "pairs of brackets" that we've left (marked as
2874
2636
X,Y,Z in the above picture)
2876
for (;next_emb; next_emb= next_emb->embedding)
2638
for (;next_emb; next_emb= next_emb->getEmbedding())
2878
next_emb->nested_join->counter_++;
2879
if (next_emb->nested_join->counter_ == 1)
2640
next_emb->getNestedJoin()->counter_++;
2641
if (next_emb->getNestedJoin()->counter_ == 1)
2882
2644
next_emb is the first table inside a nested join we've "entered". In
2883
2645
the picture above, we're looking at the 'X' bracket. Don't exit yet as
2884
2646
X bracket might have Y pair bracket.
2886
join->cur_embedding_map |= next_emb->nested_join->nj_map;
2648
join->cur_embedding_map |= next_emb->getNestedJoin()->nj_map;
2889
if (next_emb->nested_join->join_list.elements !=
2890
next_emb->nested_join->counter_)
2651
if (next_emb->getNestedJoin()->join_list.elements !=
2652
next_emb->getNestedJoin()->counter_)
2894
2656
We're currently at Y or Z-bracket as depicted in the above picture.
2895
2657
Mark that we've left it and continue walking up the brackets hierarchy.
2897
join->cur_embedding_map &= ~next_emb->nested_join->nj_map;
2659
join->cur_embedding_map &= ~next_emb->getNestedJoin()->nj_map;
2902
COND *optimize_cond(JOIN *join, COND *conds, List<TableList> *join_list, Item::cond_result *cond_value)
2664
COND *optimize_cond(Join *join, COND *conds, List<TableList> *join_list, Item::cond_result *cond_value)
2904
2666
Session *session= join->session;
5409
5179
uint32_t key_length,
5412
unsigned char *key_buffer, *key_pos, *record=table->record[0];
5182
unsigned char *key_pos, *record=table->getInsertRecord();
5414
5184
Cursor *cursor= table->cursor;
5415
5185
uint32_t extra_length= ALIGN_SIZE(key_length)-key_length;
5416
uint32_t *field_lengths,*field_length;
5186
uint32_t *field_length;
5188
std::vector<unsigned char> key_buffer;
5189
std::vector<uint32_t> field_lengths;
5419
if (! memory::multi_malloc(false,
5421
(uint32_t) ((key_length + extra_length) *
5422
(long) cursor->stats.records),
5424
(uint32_t) (field_count*sizeof(*field_lengths)),
5191
key_buffer.resize((key_length + extra_length) * (long) cursor->stats.records);
5192
field_lengths.resize(field_count);
5430
5196
uint32_t total_length= 0;
5431
for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++)
5198
for (ptr= first_field, field_length= &field_lengths[0] ; *ptr ; ptr++)
5433
5200
uint32_t length= (*ptr)->sort_length();
5434
5201
(*field_length++)= length;
5484
5250
if (hash_search(&hash, org_key_pos, key_length))
5486
5252
/* Duplicated found ; Remove the row */
5487
if ((error=cursor->ha_delete_row(record)))
5253
if ((error=cursor->deleteRecord(record)))
5491
5257
(void) my_hash_insert(&hash, org_key_pos);
5492
5258
key_pos+=extra_length;
5494
free((char*) key_buffer);
5495
5260
hash_free(&hash);
5496
5261
cursor->extra(HA_EXTRA_NO_CACHE);
5497
(void) cursor->ha_rnd_end();
5262
(void) cursor->endTableScan();
5501
free((char*) key_buffer);
5502
5266
hash_free(&hash);
5503
5267
cursor->extra(HA_EXTRA_NO_CACHE);
5504
(void) cursor->ha_rnd_end();
5268
(void) cursor->endTableScan();
5506
5270
table->print_error(error,MYF(0));
5510
SORT_FIELD *make_unireg_sortorder(order_st *order, uint32_t *length, SORT_FIELD *sortorder)
5274
SortField *make_unireg_sortorder(Order *order, uint32_t *length, SortField *sortorder)
5512
5276
uint32_t count;
5513
SORT_FIELD *sort,*pos;
5277
SortField *sort,*pos;
5516
for (order_st *tmp = order; tmp; tmp=tmp->next)
5280
for (Order *tmp = order; tmp; tmp=tmp->next)
5518
5282
if (!sortorder)
5519
sortorder= (SORT_FIELD*) memory::sql_alloc(sizeof(SORT_FIELD) *
5283
sortorder= (SortField*) memory::sql_alloc(sizeof(SortField) *
5520
5284
(max(count, *length) + 1));
5521
5285
pos= sort= sortorder;