diff options
author | unknown <Sinisa@sinisa.nasamreza.org> | 2002-02-21 13:40:22 +0200 |
---|---|---|
committer | unknown <Sinisa@sinisa.nasamreza.org> | 2002-02-21 13:40:22 +0200 |
commit | c0b5bf5e1454c33eb29d4978ded77b501e77a4b3 (patch) | |
tree | 619ba93cf85437c2306a46763a7987c0fc5b152a /sql/sql_select.cc | |
parent | 66d4f05c263389526f9fc92733ecfc68c82d3c3d (diff) | |
download | mariadb-git-c0b5bf5e1454c33eb29d4978ded77b501e77a4b3.tar.gz |
some UNION bug fixes..
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r-- | sql/sql_select.cc | 299 |
1 files changed, 168 insertions, 131 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 69cac90e2be..ae6c38a874e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -144,7 +144,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab); static void init_sum_functions(Item_sum **func); static bool update_sum_func(Item_sum **func); static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, - bool distinct); + bool distinct, const char *message=NullS); static void describe_info(THD *thd, const char *info); /* @@ -195,6 +195,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, Procedure *procedure; List<Item> all_fields(fields); bool select_distinct; + SELECT_LEX *select_lex = &(thd->lex.select_lex); DBUG_ENTER("mysql_select"); /* Check that all tables, fields, conds and order are ok */ @@ -350,10 +351,13 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, } if (cond_value == Item::COND_FALSE || !thd->select_limit) { /* Impossible cond */ - error=return_zero_rows(result, tables, fields, - join.tmp_table_param.sum_func_count != 0 && !group, - select_options,"Impossible WHERE",having, - procedure); + if (select_options & SELECT_DESCRIBE && select_lex->next) + select_describe(&join,false,false,false,"Impossible WHERE"); + else + error=return_zero_rows(result, tables, fields, + join.tmp_table_param.sum_func_count != 0 && !group, + select_options,"Impossible WHERE",having, + procedure); delete procedure; DBUG_RETURN(error); } @@ -366,17 +370,23 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, { if (res < 0) { - error=return_zero_rows(result, tables, fields, !group, - select_options,"No matching min/max row", - having,procedure); + if (select_options & SELECT_DESCRIBE && select_lex->next) + select_describe(&join,false,false,false,"No matching min/max row"); + else + error=return_zero_rows(result, tables, fields, !group, + select_options,"No matching min/max row", + having,procedure); delete procedure; DBUG_RETURN(error); } if (select_options & SELECT_DESCRIBE) { - describe_info(thd,"Select tables optimized away"); + if (select_lex->next) + select_describe(&join,false,false,false,"Select tables optimized away"); + else + describe_info(thd,"Select tables optimized away"); delete procedure; - DBUG_RETURN(0); + DBUG_RETURN(error); } tables=0; // All tables resolved } @@ -385,7 +395,12 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, { // Only test of functions error=0; if (select_options & SELECT_DESCRIBE) - describe_info(thd,"No tables used"); + { + if (select_lex->next) + select_describe(&join,false,false,false,"No tables used"); + else + describe_info(thd,"No tables used"); + } else { result->send_fields(fields,1); @@ -463,11 +478,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, } if (make_join_select(&join,select,conds)) { - error=return_zero_rows(result,tables,fields, - join.tmp_table_param.sum_func_count != 0 && !group, - select_options, - "Impossible WHERE noticed after reading const tables", - having,procedure); + if (select_options & SELECT_DESCRIBE && select_lex->next) + select_describe(&join,false,false,false,"Impossible WHERE noticed after reading const tables"); + else + error=return_zero_rows(result,tables,fields, + join.tmp_table_param.sum_func_count != 0 && !group, + select_options, + "Impossible WHERE noticed after reading const tables", + having,procedure); goto err; } @@ -535,7 +553,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, make_join_readinfo(&join, (select_options & (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) | - (thd->lex.select_lex.ftfunc_list.elements ? SELECT_NO_JOIN_CACHE : 0)); + (select_lex->ftfunc_list.elements ? SELECT_NO_JOIN_CACHE : 0)); /* Need to tell Innobase that to play it safe, it should fetch all columns of the tables: this is because MySQL @@ -2516,6 +2534,7 @@ static void make_join_readinfo(JOIN *join,uint options) { uint i; + SELECT_LEX *select_lex = &(join->thd->lex.select_lex); DBUG_ENTER("make_join_readinfo"); for (i=join->const_tables ; i < join->tables ; i++) @@ -2598,7 +2617,7 @@ make_join_readinfo(JOIN *join,uint options) /* These init changes read_record */ if (tab->use_quick == 2) { - join->thd->lex.select_lex.options|=QUERY_NO_GOOD_INDEX_USED; + select_lex->options|=QUERY_NO_GOOD_INDEX_USED; tab->read_first_record= join_init_quick_read_record; statistic_increment(select_range_check_count, &LOCK_status); } @@ -2613,7 +2632,7 @@ make_join_readinfo(JOIN *join,uint options) } else { - join->thd->lex.select_lex.options|=QUERY_NO_INDEX_USED; + select_lex->options|=QUERY_NO_INDEX_USED; statistic_increment(select_scan_count, &LOCK_status); } } @@ -2625,7 +2644,7 @@ make_join_readinfo(JOIN *join,uint options) } else { - join->thd->lex.select_lex.options|=QUERY_NO_INDEX_USED; + select_lex->options|=QUERY_NO_INDEX_USED; statistic_increment(select_full_join_count, &LOCK_status); } } @@ -2913,7 +2932,7 @@ return_zero_rows(select_result *result,TABLE_LIST *tables,List<Item> &fields, DBUG_ENTER("return_zero_rows"); if (select_options & SELECT_DESCRIBE) - { + { describe_info(current_thd, info); DBUG_RETURN(0); } @@ -6940,16 +6959,17 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab) ****************************************************************************/ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, - bool distinct) + bool distinct,const char *message) { List<Item> field_list; Item *item; THD *thd=join->thd; + SELECT_LEX *select_lex = &(join->thd->lex.select_lex); DBUG_ENTER("select_describe"); /* Don't log this into the slow query log */ - join->thd->lex.select_lex.options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED); - if (join->thd->lex.select == &join->thd->lex.select_lex) + select_lex->options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED); + if (join->thd->lex.select == select_lex) { field_list.push_back(new Item_empty_string("table",NAME_LEN)); field_list.push_back(new Item_empty_string("type",10)); @@ -6970,133 +6990,150 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, } char buff[512],*buff_ptr; String tmp(buff,sizeof(buff)),*packet= &thd->packet; - table_map used_tables=0; - for (uint i=0 ; i < join->tables ; i++) + if (message) { - JOIN_TAB *tab=join->join_tab+i; - TABLE *table=tab->table; - - if (tab->type == JT_ALL && tab->select && tab->select->quick) - tab->type= JT_RANGE; packet->length(0); - net_store_data(packet,table->table_name); - net_store_data(packet,join_type_str[tab->type]); - tmp.length(0); - key_map bits; - uint j; - for (j=0,bits=tab->keys ; bits ; j++,bits>>=1) - { - if (bits & 1) - { - if (tmp.length()) - tmp.append(','); - tmp.append(table->key_info[j].name); - } - } - if (tmp.length()) - net_store_data(packet,tmp.ptr(),tmp.length()); - else - net_store_null(packet); - if (tab->ref.key_parts) + net_store_null(packet); + net_store_null(packet); + net_store_null(packet); + net_store_null(packet); + net_store_null(packet); + net_store_null(packet); + net_store_null(packet); + net_store_data(packet,message,strlen(message)); + if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) + DBUG_VOID_RETURN; + } + else + { + table_map used_tables=0; + for (uint i=0 ; i < join->tables ; i++) { - net_store_data(packet,table->key_info[tab->ref.key].name); - net_store_data(packet,(uint32) tab->ref.key_length); + JOIN_TAB *tab=join->join_tab+i; + TABLE *table=tab->table; + + if (tab->type == JT_ALL && tab->select && tab->select->quick) + tab->type= JT_RANGE; + packet->length(0); + net_store_data(packet,table->table_name); + net_store_data(packet,join_type_str[tab->type]); tmp.length(0); - for (store_key **ref=tab->ref.key_copy ; *ref ; ref++) + key_map bits; + uint j; + for (j=0,bits=tab->keys ; bits ; j++,bits>>=1) { - if (tmp.length()) - tmp.append(','); - tmp.append((*ref)->name()); + if (bits & 1) + { + if (tmp.length()) + tmp.append(','); + tmp.append(table->key_info[j].name); + } } - net_store_data(packet,tmp.ptr(),tmp.length()); - } - else if (tab->type == JT_NEXT) - { - net_store_data(packet,table->key_info[tab->index].name); - net_store_data(packet,(uint32) table->key_info[tab->index].key_length); - net_store_null(packet); - } - else if (tab->select && tab->select->quick) - { - net_store_data(packet,table->key_info[tab->select->quick->index].name);; - net_store_data(packet,(uint32) tab->select->quick->max_used_key_length); - net_store_null(packet); - } - else - { - net_store_null(packet); - net_store_null(packet); - net_store_null(packet); - } - sprintf(buff,"%.0f",join->best_positions[i].records_read); - net_store_data(packet,buff); - my_bool key_read=table->key_read; - if (tab->type == JT_NEXT && - ((table->used_keys & ((key_map) 1 << tab->index)))) - key_read=1; - - buff_ptr=buff; - if (tab->info) - net_store_data(packet,tab->info); - else if (tab->select) - { - if (tab->use_quick == 2) + if (tmp.length()) + net_store_data(packet,tmp.ptr(),tmp.length()); + else + net_store_null(packet); + if (tab->ref.key_parts) { - sprintf(buff_ptr,"range checked for each record (index map: %u)", - tab->keys); - buff_ptr=strend(buff_ptr); + net_store_data(packet,table->key_info[tab->ref.key].name); + net_store_data(packet,(uint32) tab->ref.key_length); + tmp.length(0); + for (store_key **ref=tab->ref.key_copy ; *ref ; ref++) + { + if (tmp.length()) + tmp.append(','); + tmp.append((*ref)->name()); + } + net_store_data(packet,tmp.ptr(),tmp.length()); + } + else if (tab->type == JT_NEXT) + { + net_store_data(packet,table->key_info[tab->index].name); + net_store_data(packet,(uint32) table->key_info[tab->index].key_length); + net_store_null(packet); + } + else if (tab->select && tab->select->quick) + { + net_store_data(packet,table->key_info[tab->select->quick->index].name);; + net_store_data(packet,(uint32) tab->select->quick->max_used_key_length); + net_store_null(packet); } else - buff_ptr=strmov(buff_ptr,"where used"); - } - if (key_read) - { - if (buff != buff_ptr) { - buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + net_store_null(packet); + net_store_null(packet); + net_store_null(packet); } - buff_ptr=strmov(buff_ptr,"Using index"); - } - if (table->reginfo.not_exists_optimize) - { - if (buff != buff_ptr) + sprintf(buff,"%.0f",join->best_positions[i].records_read); + net_store_data(packet,buff); + my_bool key_read=table->key_read; + if (tab->type == JT_NEXT && + ((table->used_keys & ((key_map) 1 << tab->index)))) + key_read=1; + + buff_ptr=buff; + if (tab->info) + net_store_data(packet,tab->info); + else if (tab->select) { - buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + if (tab->use_quick == 2) + { + sprintf(buff_ptr,"range checked for each record (index map: %u)", + tab->keys); + buff_ptr=strend(buff_ptr); + } + else + buff_ptr=strmov(buff_ptr,"where used"); } - buff_ptr=strmov(buff_ptr,"Not exists"); - } - if (need_tmp_table) - { - need_tmp_table=0; - if (buff != buff_ptr) + if (key_read) { - buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + if (buff != buff_ptr) + { + buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + } + buff_ptr=strmov(buff_ptr,"Using index"); } - buff_ptr=strmov(buff_ptr,"Using temporary"); - } - if (need_order) - { - need_order=0; - if (buff != buff_ptr) + if (table->reginfo.not_exists_optimize) { - buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + if (buff != buff_ptr) + { + buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + } + buff_ptr=strmov(buff_ptr,"Not exists"); } - buff_ptr=strmov(buff_ptr,"Using filesort"); - } - if (distinct & test_all_bits(used_tables,thd->used_tables)) - { - if (buff != buff_ptr) + if (need_tmp_table) { - buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + need_tmp_table=0; + if (buff != buff_ptr) + { + buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + } + buff_ptr=strmov(buff_ptr,"Using temporary"); } - buff_ptr=strmov(buff_ptr,"Distinct"); - } - net_store_data(packet,buff,(uint) (buff_ptr - buff)); - if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) - DBUG_VOID_RETURN; /* purecov: inspected */ + if (need_order) + { + need_order=0; + if (buff != buff_ptr) + { + buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + } + buff_ptr=strmov(buff_ptr,"Using filesort"); + } + if (distinct & test_all_bits(used_tables,thd->used_tables)) + { + if (buff != buff_ptr) + { + buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + } + buff_ptr=strmov(buff_ptr,"Distinct"); + } + net_store_data(packet,buff,(uint) (buff_ptr - buff)); + if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) + DBUG_VOID_RETURN; /* Purecov: Inspected */ - // For next iteration - used_tables|=table->map; + // For next iteration + used_tables|=table->map; + } } if (!join->thd->lex.select->next) send_eof(&thd->net); |