32
33
void optimizer::add_key_part(DYNAMIC_ARRAY *keyuse_array,
33
34
optimizer::KeyField *key_field)
35
Field *field= key_field->field;
36
Field *field= key_field->getField();
36
37
Table *form= field->table;
39
if (key_field->eq_func && ! (key_field->optimize & KEY_OPTIMIZE_EXISTS))
39
if (key_field->isEqualityCondition() &&
40
! (key_field->getOptimizeFlags() & KEY_OPTIMIZE_EXISTS))
41
42
for (uint32_t key= 0; key < form->sizeKeys(); key++)
49
50
if (field->eq(form->key_info[key].key_part[part].field))
51
keyuse.table= field->table;
52
keyuse.val= key_field->val;
55
keyuse.keypart_map= (key_part_map) 1 << part;
56
keyuse.used_tables= key_field->val->used_tables();
57
keyuse.optimize= key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL;
58
keyuse.null_rejecting= key_field->null_rejecting;
59
keyuse.cond_guard= key_field->cond_guard;
52
optimizer::KeyUse keyuse(field->table,
53
key_field->getValue(),
54
key_field->getValue()->used_tables(),
57
key_field->getOptimizeFlags() & KEY_OPTIMIZE_REF_OR_NULL,
60
key_field->rejectNullValues(),
61
key_field->getConditionalGuard());
60
62
insert_dynamic(keyuse_array, (unsigned char*) &keyuse);
132
140
The result of this is that we're missing some 'ref' accesses.
133
141
TODO: OptimizerTeam: Fix this
135
if (! new_fields->val->const_item())
143
if (! new_fields->getValue()->const_item())
138
146
If the value matches, we can use the key reference.
139
147
If not, we keep it until we have examined all new values
141
if (old->val->eq(new_fields->val, old->field->binary()))
149
if (old->getValue()->eq(new_fields->getValue(), old->getField()->binary()))
143
old->level= and_level;
144
old->optimize= ((old->optimize & new_fields->optimize &
145
KEY_OPTIMIZE_EXISTS) |
146
((old->optimize | new_fields->optimize) &
147
KEY_OPTIMIZE_REF_OR_NULL));
148
old->null_rejecting= (old->null_rejecting &&
149
new_fields->null_rejecting);
151
old->setLevel(and_level);
152
old->setOptimizeFlags(((old->getOptimizeFlags() &
153
new_fields->getOptimizeFlags() &
154
KEY_OPTIMIZE_EXISTS) |
155
((old->getOptimizeFlags() |
156
new_fields->getOptimizeFlags()) &
157
KEY_OPTIMIZE_REF_OR_NULL)));
158
old->setRejectNullValues(old->rejectNullValues() &&
159
new_fields->rejectNullValues());
152
else if (old->eq_func && new_fields->eq_func &&
153
old->val->eq_by_collation(new_fields->val,
154
old->field->binary(),
155
old->field->charset()))
162
else if (old->isEqualityCondition() &&
163
new_fields->isEqualityCondition() &&
164
old->getValue()->eq_by_collation(new_fields->getValue(),
165
old->getField()->binary(),
166
old->getField()->charset()))
158
old->level= and_level;
159
old->optimize= ((old->optimize & new_fields->optimize &
160
KEY_OPTIMIZE_EXISTS) |
161
((old->optimize | new_fields->optimize) &
162
KEY_OPTIMIZE_REF_OR_NULL));
163
old->null_rejecting= (old->null_rejecting &&
164
new_fields->null_rejecting);
169
old->setLevel(and_level);
170
old->setOptimizeFlags(((old->getOptimizeFlags() &
171
new_fields->getOptimizeFlags() &
172
KEY_OPTIMIZE_EXISTS) |
173
((old->getOptimizeFlags() |
174
new_fields->getOptimizeFlags()) &
175
KEY_OPTIMIZE_REF_OR_NULL)));
176
old->setRejectNullValues(old->rejectNullValues() &&
177
new_fields->rejectNullValues());
166
else if (old->eq_func && new_fields->eq_func &&
167
((old->val->const_item() && old->val->is_null()) ||
168
new_fields->val->is_null()))
179
else if (old->isEqualityCondition() &&
180
new_fields->isEqualityCondition() &&
181
((old->getValue()->const_item() &&
182
old->getValue()->is_null()) ||
183
new_fields->getValue()->is_null()))
170
185
/* field = expression OR field IS NULL */
171
old->level= and_level;
172
old->optimize= KEY_OPTIMIZE_REF_OR_NULL;
186
old->setLevel(and_level);
187
old->setOptimizeFlags(KEY_OPTIMIZE_REF_OR_NULL);
174
189
Remember the NOT NULL value unless the value does not depend
177
if (! old->val->used_tables() && old->val->is_null())
178
old->val= new_fields->val;
192
if (! old->getValue()->used_tables() &&
193
old->getValue()->is_null())
195
old->setValue(new_fields->getValue());
179
197
/* The referred expression can be NULL: */
180
old->null_rejecting= 0;
198
old->setRejectNullValues(false);
341
359
/* Store possible eq field */
342
(*key_fields)->field= field;
343
(*key_fields)->eq_func= eq_func;
344
(*key_fields)->val= *value;
345
(*key_fields)->level= and_level;
346
(*key_fields)->optimize= exists_optimize;
360
(*key_fields)->setField(field);
361
(*key_fields)->setEqualityConditionUsed(eq_func);
362
(*key_fields)->setValue(*value);
363
(*key_fields)->setLevel(and_level);
364
(*key_fields)->setOptimizeFlags(exists_optimize);
348
366
If the condition has form "tbl.keypart = othertbl.field" and
349
367
othertbl.field can be NULL, there will be no matches if othertbl.field
351
369
We use null_rejecting in add_not_null_conds() to add
352
370
'othertbl.field IS NOT NULL' to tab->select_cond.
354
(*key_fields)->null_rejecting= ((cond->functype() == Item_func::EQ_FUNC ||
355
cond->functype() == Item_func::MULT_EQUAL_FUNC) &&
356
((*value)->type() == Item::FIELD_ITEM) &&
357
((Item_field*)*value)->field->maybe_null());
358
(*key_fields)->cond_guard= NULL;
372
(*key_fields)->setRejectNullValues((cond->functype() == Item_func::EQ_FUNC ||
373
cond->functype() == Item_func::MULT_EQUAL_FUNC) &&
374
((*value)->type() == Item::FIELD_ITEM) &&
375
((Item_field*)*value)->field->maybe_null());
376
(*key_fields)->setConditionalGuard(NULL);
411
429
while ((item= li++))
412
add_key_fields(join, key_fields, and_level, item, usable_tables,
414
for (; org_key_fields != *key_fields ; org_key_fields++)
415
org_key_fields->level= *and_level;
438
for (; org_key_fields != *key_fields; org_key_fields++)
439
org_key_fields->setLevel(*and_level);
420
add_key_fields(join, key_fields, and_level, li++, usable_tables,
423
451
while ((item= li++))
425
453
optimizer::KeyField *start_key_fields= *key_fields;
427
add_key_fields(join, key_fields, and_level, item, usable_tables,
429
461
*key_fields= merge_key_fields(org_key_fields, start_key_fields,
430
462
*key_fields, ++(*and_level));
443
475
((Item_func*)cond)->functype() == Item_func::TRIG_COND_FUNC)
445
477
Item *cond_arg= ((Item_func*)cond)->arguments()[0];
446
if (! join->group_list && ! join->order &&
478
if (! join->group_list &&
447
480
join->unit->item &&
448
481
join->unit->item->substype() == Item_subselect::IN_SUBS &&
449
482
! join->unit->is_union())
451
484
optimizer::KeyField *save= *key_fields;
452
add_key_fields(join, key_fields, and_level, cond_arg, usable_tables,
454
// Indicate that this ref access candidate is for subquery lookup:
491
/* Indicate that this ref access candidate is for subquery lookup */
455
492
for (; save != *key_fields; save++)
456
save->cond_guard= ((Item_func_trig_cond*)cond)->get_trig_var();
493
save->setConditionalGuard(((Item_func_trig_cond*)cond)->get_trig_var());