diff options
author | ram@gw.mysql.r18.ru <> | 2004-03-19 12:36:55 +0400 |
---|---|---|
committer | ram@gw.mysql.r18.ru <> | 2004-03-19 12:36:55 +0400 |
commit | fd01314cc8eef86d14543538ae6e108c8708e70b (patch) | |
tree | aeea70f904a6438cab4d823064329643ef78654b /sql/sql_base.cc | |
parent | fc17aad767fa91ce94864c350c9f29aadcf769d8 (diff) | |
download | mariadb-git-fd01314cc8eef86d14543538ae6e108c8708e70b.tar.gz |
Fix for the bug #2976: NATURAL JOIN produces duplicate columns.
Improvement natural join code in the setup_conds().
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r-- | sql/sql_base.cc | 61 |
1 files changed, 33 insertions, 28 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 1766063c5ec..e7bb9a778e2 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2293,11 +2293,20 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, thd->used_tables|=table->map; while ((field = *ptr++)) { - Item_field *item= new Item_field(field); - if (!found++) - (void) it->replace(item); // Replace '*' - else - it->after(item); + /* Skip duplicate field names if NATURAL JOIN is used */ + if (table->outer_join || + !tables->natural_join || + tables->natural_join->table->outer_join || + !find_field_in_table(thd, tables->natural_join->table, + field->field_name, strlen(field->field_name), + 0, 0)) + { + Item_field *item= new Item_field(field); + if (!found++) + (void) it->replace(item); // Replace '*' + else + it->after(item); + } /* Mark if field used before in this select. Used by 'insert' to verify if a field name is used twice @@ -2377,30 +2386,26 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) DBUG_RETURN(1); cond_and->top_level_item(); - uint i,j; - for (i=0 ; i < t1->fields ; i++) + Field **t1_field, *t2_field; + for (t1_field= t1->field; (*t1_field); t1_field++) { - // TODO: This could be optimized to use hashed names if t2 had a hash - for (j=0 ; j < t2->fields ; j++) - { - if (!my_strcasecmp(system_charset_info, - t1->field[i]->field_name, - t2->field[j]->field_name)) - { - Item_func_eq *tmp=new Item_func_eq(new Item_field(t1->field[i]), - new Item_field(t2->field[j])); - if (!tmp) - DBUG_RETURN(1); - tmp->fix_length_and_dec(); // Update cmp_type - tmp->const_item_cache=0; - /* Mark field used for table cache */ - t1->field[i]->query_id=t2->field[j]->query_id=thd->query_id; - cond_and->list.push_back(tmp); - t1->used_keys.intersect(t1->field[i]->part_of_key); - t2->used_keys.intersect(t2->field[j]->part_of_key); - break; - } - } + const char *t1_field_name= (*t1_field)->field_name; + + if ((t2_field= find_field_in_table(thd, t2, t1_field_name, + strlen(t1_field_name), 0, 0))) + { + Item_func_eq *tmp=new Item_func_eq(new Item_field(*t1_field), + new Item_field(t2_field)); + if (!tmp) + DBUG_RETURN(1); + tmp->fix_length_and_dec(); // Update cmp_type + tmp->const_item_cache= 0; + /* Mark field used for table cache */ + (*t1_field)->query_id= t2_field->query_id= thd->query_id; + cond_and->list.push_back(tmp); + t1->used_keys.intersect((*t1_field)->part_of_key); + t2->used_keys.intersect(t2_field->part_of_key); + } } cond_and->used_tables_cache= t1->map | t2->map; thd->lex->current_select->cond_count+= cond_and->list.elements; |