diff options
author | serg@serg.mylan <> | 2003-08-12 15:30:47 +0200 |
---|---|---|
committer | serg@serg.mylan <> | 2003-08-12 15:30:47 +0200 |
commit | bc9f6cde5012e239339a840ab14d50fa14950051 (patch) | |
tree | b98c946de4b65b7b7b518b7cc759c2c093da613b /sql | |
parent | ad976d1ea188afc3a2c1bcb9feabaf679bd2e903 (diff) | |
parent | 06e5657993f20a4caa37db96c05adc9eabc392bb (diff) | |
download | mariadb-git-bc9f6cde5012e239339a840ab14d50fa14950051.tar.gz |
Merge bk-internal:/home/bk/mysql-4.0/
into serg.mylan:/usr/home/serg/Abk/mysql-4.0
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 2 | ||||
-rw-r--r-- | sql/opt_range.cc | 13 | ||||
-rw-r--r-- | sql/sql_select.cc | 69 |
3 files changed, 50 insertions, 34 deletions
diff --git a/sql/field.cc b/sql/field.cc index 9babe069300..e56d53b1bda 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -742,7 +742,7 @@ void Field_decimal::store(double nr) char buff[320]; fyllchar = zerofill ? (char) '0' : (char) ' '; -#ifdef HAVE_SNPRINTF_ +#ifdef HAVE_SNPRINTF buff[sizeof(buff)-1]=0; // Safety snprintf(buff,sizeof(buff)-1, "%.*f",(int) dec,nr); #else diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 2d949810b63..c7bad3b18f3 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -794,18 +794,15 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond) DBUG_RETURN(new SEL_TREE(SEL_TREE::ALWAYS)); DBUG_RETURN(new SEL_TREE(SEL_TREE::IMPOSSIBLE)); } + table_map ref_tables=cond->used_tables(); - if (ref_tables & ~(param->prev_tables | param->read_tables | - param->current_table)) - DBUG_RETURN(0); // Can't be calculated yet if (cond->type() != Item::FUNC_ITEM) { // Should be a field if (ref_tables & param->current_table) DBUG_RETURN(0); DBUG_RETURN(new SEL_TREE(SEL_TREE::MAYBE)); } - if (!(ref_tables & param->current_table)) - DBUG_RETURN(new SEL_TREE(SEL_TREE::MAYBE)); // This may be false or true + Item_func *cond_func= (Item_func*) cond; if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE) DBUG_RETURN(0); // Can't be calculated @@ -847,6 +844,12 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond) DBUG_RETURN(0); // Can't optimize this IN } + if (ref_tables & ~(param->prev_tables | param->read_tables | + param->current_table)) + DBUG_RETURN(0); // Can't be calculated yet + if (!(ref_tables & param->current_table)) + DBUG_RETURN(new SEL_TREE(SEL_TREE::MAYBE)); // This may be false or true + /* check field op const */ /* btw, ft_func's arguments()[0] isn't FIELD_ITEM. SerG*/ if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6675a310464..c676f389da7 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1425,28 +1425,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) { bool 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=1; } 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=1; } @@ -1457,12 +1463,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 Field LIKE constant where constant doesn't start with a wildcard @@ -1470,24 +1470,34 @@ 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 + also 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); + // DBUG_ASSERT(eq_func); /* QQ: Can I uncomment this ASSERT ? */ /* 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=(*key_fields)->const_level=and_level; (*key_fields)->exists_optimize=exists_optimize; (*key_fields)++; @@ -1541,10 +1551,12 @@ 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()->type() == Item::FIELD_ITEM) add_key_field(key_fields,*and_level, - ((Item_field*) (cond_func->key_item()))->field, - 0,(Item*) 0,usable_tables); + ((Item_field*) (cond_func->key_item()))->field, 0, + cond_func->arguments()+1, cond_func->argument_count()-1, + usable_tables); break; case Item_func::OPTIMIZE_OP: { @@ -1556,7 +1568,7 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level, add_key_field(key_fields,*and_level, ((Item_field*) (cond_func->arguments()[0]))->field, equal_func, - (cond_func->arguments()[1]),usable_tables); + cond_func->arguments()+1, 1, usable_tables); } if (cond_func->arguments()[1]->type() == Item::FIELD_ITEM && cond_func->functype() != Item_func::LIKE_FUNC) @@ -1564,7 +1576,7 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level, add_key_field(key_fields,*and_level, ((Item_field*) (cond_func->arguments()[1]))->field, equal_func, - (cond_func->arguments()[0]),usable_tables); + cond_func->arguments(),1,usable_tables); } break; } @@ -1572,10 +1584,11 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level, /* column_name IS [NOT] NULL */ if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM) { + Item *tmp=new Item_null; add_key_field(key_fields,*and_level, ((Item_field*) (cond_func->arguments()[0]))->field, cond_func->functype() == Item_func::ISNULL_FUNC, - new Item_null, usable_tables); + &tmp, 1, usable_tables); } break; } @@ -3267,7 +3280,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) @@ -3293,7 +3306,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 || @@ -3311,7 +3324,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]); } @@ -3320,7 +3333,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]); } |