mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
merge
BitKeeper/etc/ignore: auto-union BitKeeper/etc/logging_ok: auto-union client/mysqldump.c: Auto merged include/my_sys.h: Auto merged include/mysql_com.h: Auto merged isam/open.c: Auto merged libmysql/libmysql.c: Auto merged mysql-test/r/isam.result: Auto merged mysql-test/r/myisam.result: Auto merged mysql-test/r/rpl_loaddata.result: Auto merged mysql-test/r/rpl_log.result: Auto merged mysql-test/r/show_check.result: Auto merged mysql-test/t/myisam.test: Auto merged sql/ha_myisam.cc: Auto merged sql/item.h: Auto merged sql/item_func.cc: Auto merged sql/item_func.h: Auto merged sql/item_sum.cc: Auto merged sql/mysql_priv.h: Auto merged sql/mysqld.cc: Auto merged sql/repl_failsafe.cc: Auto merged sql/set_var.cc: Auto merged sql/slave.cc: Auto merged sql/slave.h: Auto merged sql/sql_class.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_insert.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_repl.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_show.cc: Auto merged sql/share/portuguese/errmsg.txt: Auto merged sql/share/spanish/errmsg.txt: Auto merged sql/sql_table.cc: Auto merged sql/sql_union.cc: Auto merged sql/sql_yacc.yy: Auto merged sql/handler.cc: Merge sql/sql_acl.cc: Merge and code cleanup of acl_getroot()
This commit is contained in:
@ -1414,7 +1414,6 @@ JOIN::exec()
|
||||
curr_join->group_list : curr_join->order,
|
||||
curr_join->select_limit, unit->select_limit_cnt))
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
}
|
||||
curr_join->having= curr_join->tmp_having;
|
||||
thd->proc_info="Sending data";
|
||||
@ -2046,28 +2045,34 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
|
||||
|
||||
static void
|
||||
add_key_field(KEY_FIELD **key_fields,uint and_level,
|
||||
Field *field,bool eq_func,Item *value,
|
||||
Field *field,bool eq_func,Item **value, uint num_values,
|
||||
table_map usable_tables)
|
||||
{
|
||||
uint exists_optimize= 0;
|
||||
if (!(field->flags & PART_KEY_FLAG))
|
||||
{
|
||||
// Don't remove column IS NULL on a LEFT JOIN table
|
||||
if (!eq_func || !value || value->type() != Item::NULL_ITEM ||
|
||||
!field->table->maybe_null || field->null_ptr)
|
||||
if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
|
||||
!field->table->maybe_null || field->null_ptr)
|
||||
return; // Not a key. Skip it
|
||||
exists_optimize= KEY_OPTIMIZE_EXISTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
table_map used_tables=0;
|
||||
if (value && ((used_tables=value->used_tables()) &
|
||||
(field->table->map | RAND_TABLE_BIT)))
|
||||
bool optimizable=0;
|
||||
for (uint i=0; i<num_values; i++)
|
||||
{
|
||||
used_tables|=(*value)->used_tables();
|
||||
if (!((*value)->used_tables() & (field->table->map | RAND_TABLE_BIT)))
|
||||
optimizable=1;
|
||||
}
|
||||
if (!optimizable)
|
||||
return;
|
||||
if (!(usable_tables & field->table->map))
|
||||
{
|
||||
if (!eq_func || !value || value->type() != Item::NULL_ITEM ||
|
||||
!field->table->maybe_null || field->null_ptr)
|
||||
if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
|
||||
!field->table->maybe_null || field->null_ptr)
|
||||
return; // Can't use left join optimize
|
||||
exists_optimize= KEY_OPTIMIZE_EXISTS;
|
||||
}
|
||||
@ -2078,12 +2083,6 @@ add_key_field(KEY_FIELD **key_fields,uint and_level,
|
||||
field->table->keys_in_use_for_query);
|
||||
stat[0].keys|= possible_keys; // Add possible keys
|
||||
|
||||
if (!value)
|
||||
{ // Probably BETWEEN or IN
|
||||
stat[0].const_keys |= possible_keys;
|
||||
return; // Can't be used as eq key
|
||||
}
|
||||
|
||||
/*
|
||||
Save the following cases:
|
||||
Field op constant
|
||||
@ -2092,26 +2091,38 @@ add_key_field(KEY_FIELD **key_fields,uint and_level,
|
||||
Field op formula
|
||||
Field IS NULL
|
||||
Field IS NOT NULL
|
||||
Field BETWEEN ...
|
||||
Field IN ...
|
||||
*/
|
||||
stat[0].key_dependent|=used_tables;
|
||||
if (value->const_item())
|
||||
stat[0].const_keys |= possible_keys;
|
||||
|
||||
bool is_const=1;
|
||||
for (uint i=0; i<num_values; i++)
|
||||
is_const&= (*value)->const_item();
|
||||
if (is_const)
|
||||
stat[0].const_keys |= possible_keys;
|
||||
/*
|
||||
We can't always use indexes when comparing a string index to a
|
||||
number. cmp_type() is checked to allow compare of dates to numbers
|
||||
*/
|
||||
number. cmp_type() is checked to allow compare of dates to numbers.
|
||||
eq_func is NEVER true when num_values > 1
|
||||
*/
|
||||
if (!eq_func ||
|
||||
field->result_type() == STRING_RESULT &&
|
||||
value->result_type() != STRING_RESULT &&
|
||||
field->cmp_type() != value->result_type())
|
||||
(*value)->result_type() != STRING_RESULT &&
|
||||
field->cmp_type() != (*value)->result_type())
|
||||
return;
|
||||
}
|
||||
}
|
||||
DBUG_ASSERT(num_values == 1);
|
||||
/*
|
||||
For the moment eq_func is always true. This slot is reserved for future
|
||||
extensions where we want to remembers other things than just eq comparisons
|
||||
*/
|
||||
DBUG_ASSERT(eq_func);
|
||||
/* Store possible eq field */
|
||||
(*key_fields)->field= field;
|
||||
(*key_fields)->eq_func= eq_func;
|
||||
(*key_fields)->val= value;
|
||||
(*key_fields)->val= *value;
|
||||
(*key_fields)->level= and_level;
|
||||
(*key_fields)->optimize= exists_optimize;
|
||||
(*key_fields)++;
|
||||
@ -2160,12 +2171,13 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
|
||||
case Item_func::OPTIMIZE_NONE:
|
||||
break;
|
||||
case Item_func::OPTIMIZE_KEY:
|
||||
// BETWEEN or IN
|
||||
if (cond_func->key_item()->real_item()->type() == Item::FIELD_ITEM &&
|
||||
!(cond_func->used_tables() & OUTER_REF_TABLE_BIT))
|
||||
add_key_field(key_fields,*and_level,
|
||||
((Item_field*) (cond_func->key_item()->real_item()))
|
||||
->field,
|
||||
0,(Item*) 0,usable_tables);
|
||||
((Item_field*) (cond_func->key_item()->real_item()))->field, 0,
|
||||
cond_func->arguments()+1, cond_func->argument_count()-1,
|
||||
usable_tables);
|
||||
break;
|
||||
case Item_func::OPTIMIZE_OP:
|
||||
{
|
||||
@ -2179,7 +2191,7 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
|
||||
((Item_field*) (cond_func->arguments()[0])->real_item())
|
||||
->field,
|
||||
equal_func,
|
||||
(cond_func->arguments()[1]),usable_tables);
|
||||
cond_func->arguments()+1, 1, usable_tables);
|
||||
}
|
||||
if (cond_func->arguments()[1]->real_item()->type() == Item::FIELD_ITEM &&
|
||||
cond_func->functype() != Item_func::LIKE_FUNC &&
|
||||
@ -2189,7 +2201,7 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
|
||||
((Item_field*) (cond_func->arguments()[1])->real_item())
|
||||
->field,
|
||||
equal_func,
|
||||
(cond_func->arguments()[0]),usable_tables);
|
||||
cond_func->arguments(),1,usable_tables);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2198,11 +2210,14 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
|
||||
if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM &&
|
||||
!(cond_func->used_tables() & OUTER_REF_TABLE_BIT))
|
||||
{
|
||||
Item *tmp=new Item_null;
|
||||
if (!tmp) // Should never be true
|
||||
return;
|
||||
add_key_field(key_fields,*and_level,
|
||||
((Item_field*) (cond_func->arguments()[0])->real_item())
|
||||
->field,
|
||||
cond_func->functype() == Item_func::ISNULL_FUNC,
|
||||
new Item_null, usable_tables);
|
||||
&tmp, 1, usable_tables);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -3992,7 +4007,7 @@ change_cond_ref_to_const(I_List<COND_CMP> *save_list,Item *and_father,
|
||||
|
||||
|
||||
static void
|
||||
propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_level,
|
||||
propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_father,
|
||||
COND *cond)
|
||||
{
|
||||
if (cond->type() == Item::COND_ITEM)
|
||||
@ -4018,7 +4033,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_level,
|
||||
cond_cmp->cmp_func->arguments()[1]);
|
||||
}
|
||||
}
|
||||
else if (and_level != cond && !cond->marker) // In a AND group
|
||||
else if (and_father != cond && !cond->marker) // In a AND group
|
||||
{
|
||||
if (cond->type() == Item::FUNC_ITEM &&
|
||||
(((Item_func*) cond)->functype() == Item_func::EQ_FUNC ||
|
||||
@ -4036,7 +4051,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_level,
|
||||
func->arguments()[1]=resolve_const_item(func->arguments()[1],
|
||||
func->arguments()[0]);
|
||||
func->update_used_tables();
|
||||
change_cond_ref_to_const(save_list,and_level,and_level,
|
||||
change_cond_ref_to_const(save_list,and_father,and_father,
|
||||
func->arguments()[0],
|
||||
func->arguments()[1]);
|
||||
}
|
||||
@ -4045,7 +4060,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_level,
|
||||
func->arguments()[0]=resolve_const_item(func->arguments()[0],
|
||||
func->arguments()[1]);
|
||||
func->update_used_tables();
|
||||
change_cond_ref_to_const(save_list,and_level,and_level,
|
||||
change_cond_ref_to_const(save_list,and_father,and_father,
|
||||
func->arguments()[1],
|
||||
func->arguments()[0]);
|
||||
}
|
||||
@ -8206,7 +8221,7 @@ update_tmptable_sum_func(Item_sum **func_ptr,
|
||||
{
|
||||
Item_sum *func;
|
||||
while ((func= *(func_ptr++)))
|
||||
func->update_field(0);
|
||||
func->update_field();
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user