diff options
author | bell@sanja.is.com.ua <> | 2004-05-14 13:33:02 +0300 |
---|---|---|
committer | bell@sanja.is.com.ua <> | 2004-05-14 13:33:02 +0300 |
commit | 71a374dc1384db2c5e48a059bcdd3624ddcc4564 (patch) | |
tree | 073417895d29c0f914a61109875c76ce21b4369c /sql | |
parent | a71771788e31f7b5c624bc1915bdd7f95ed257b6 (diff) | |
parent | 8885ce0dd77f499a5672fb7f38278bdc9dcf3393 (diff) | |
download | mariadb-git-71a374dc1384db2c5e48a059bcdd3624ddcc4564.tar.gz |
Merge
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.cc | 11 | ||||
-rw-r--r-- | sql/sql_class.h | 3 | ||||
-rw-r--r-- | sql/sql_lex.cc | 1 | ||||
-rw-r--r-- | sql/sql_lex.h | 3 | ||||
-rw-r--r-- | sql/sql_select.cc | 145 | ||||
-rw-r--r-- | sql/sql_union.cc | 34 |
6 files changed, 137 insertions, 60 deletions
diff --git a/sql/item.cc b/sql/item.cc index 11a9e88bdd6..084d006fef2 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -369,9 +369,14 @@ const char *Item_ident::full_name() const } else { - tmp=(char*) sql_alloc((uint) strlen(table_name)+ - (uint) strlen(field_name)+2); - strxmov(tmp,table_name,".",field_name,NullS); + if (table_name[0]) + { + tmp= (char*) sql_alloc((uint) strlen(table_name) + + (uint) strlen(field_name) + 2); + strxmov(tmp, table_name, ".", field_name, NullS); + } + else + tmp= (char*) field_name; } return tmp; } diff --git a/sql/sql_class.h b/sql/sql_class.h index e602b7d6d5f..9ed49c22119 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -773,7 +773,7 @@ public: uint current_tablenr,tmp_table; uint server_status,open_options,system_thread; uint32 db_length; - uint select_number; //number of select (used for EXPLAIN) + int select_number; //number of select (used for EXPLAIN) /* variables.transaction_isolation is reset to this after each commit */ enum_tx_isolation session_tx_isolation; enum_check_fields count_cuted_fields; @@ -1152,7 +1152,6 @@ class select_union :public select_result { TABLE *table; COPY_INFO info; TMP_TABLE_PARAM tmp_table_param; - bool not_describe; select_union(TABLE *table_par); ~select_union(); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 5fa8b37285e..586706be6c1 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1007,6 +1007,7 @@ void st_select_lex_unit::init_query() fake_select_lex= 0; cleaned= 0; item_list.empty(); + describe= 0; } void st_select_lex::init_query() diff --git a/sql/sql_lex.h b/sql/sql_lex.h index aa3e81fd9c9..6e1e9fdecad 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -339,6 +339,7 @@ public: st_select_lex *fake_select_lex; st_select_lex *union_distinct; /* pointer to the last UNION DISTINCT */ + bool describe; /* union exec() called for EXPLAIN */ void init_query(); bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result); @@ -423,7 +424,7 @@ public: ulong table_join_options; uint in_sum_expr; - uint select_number; /* number of select (used for EXPLAIN) */ + int select_number; /* number of select (used for EXPLAIN) */ uint with_wild; /* item list contain '*' */ bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */ /* TRUE when having fix field called in processing of this SELECT */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 47ecc57cf16..8f57ca5b08d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9134,7 +9134,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, if (message) { - item_list.push_back(new Item_int((int32) join->select_lex->select_number)); + item_list.push_back(new Item_int((longlong) + join->select_lex->select_number)); item_list.push_back(new Item_string(join->select_lex->type, strlen(join->select_lex->type), cs)); for (uint i=0 ; i < 7; i++) @@ -9143,6 +9144,49 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, if (result->send_data(item_list)) join->error= 1; } + else if (join->select_lex == join->unit->fake_select_lex) + { + /* + Here is guessing about fake_select_lex to avoid union SELECT + execution to get accurate information + */ + char table_name_buffer[64]; + item_list.empty(); + /* id */ + item_list.push_back(new Item_int((int32) + join->select_lex->select_number)); + /* select_type */ + item_list.push_back(new Item_string(join->select_lex->type, + strlen(join->select_lex->type), + cs)); + /* table */ + int len= my_snprintf(table_name_buffer, sizeof(table_name_buffer)-1, + "<union%d>", + -join->select_lex->select_number); + item_list.push_back(new Item_string(table_name_buffer, len, cs)); + item_list.push_back(new Item_string(join_type_str[JT_ALL], + strlen(join_type_str[JT_ALL]), + cs)); + /* possible_keys */ + item_list.push_back(item_null); + /* key*/ + item_list.push_back(item_null); + /* key_len */ + item_list.push_back(item_null); + /* ref */ + item_list.push_back(item_null); + /* rows */ + item_list.push_back(item_null); + /* extra */ + if (join->unit->global_parameters->order_list.first) + item_list.push_back(new Item_string("Using filesort", + 14, cs)); + else + item_list.push_back(new Item_string("", 0, cs)); + + if (result->send_data(item_list)) + join->error= 1; + } else { table_map used_tables=0; @@ -9152,36 +9196,41 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, TABLE *table=tab->table; char buff[512],*buff_ptr=buff; char buff1[512], buff2[512]; - char derived_name[64]; + char table_name_buffer[64]; String tmp1(buff1,sizeof(buff1),cs); String tmp2(buff2,sizeof(buff2),cs); tmp1.length(0); tmp2.length(0); item_list.empty(); + /* id */ item_list.push_back(new Item_int((int32) join->select_lex->select_number)); + /* select_type */ item_list.push_back(new Item_string(join->select_lex->type, strlen(join->select_lex->type), cs)); if (tab->type == JT_ALL && tab->select && tab->select->quick) tab->type= JT_RANGE; + /* table */ if (table->derived_select_number) { /* Derived table name generation */ - int len= my_snprintf(derived_name, sizeof(derived_name)-1, + int len= my_snprintf(table_name_buffer, sizeof(table_name_buffer)-1, "<derived%u>", table->derived_select_number); - item_list.push_back(new Item_string(derived_name, len, cs)); + item_list.push_back(new Item_string(table_name_buffer, len, cs)); } else item_list.push_back(new Item_string(table->table_name, strlen(table->table_name), cs)); + /* type */ item_list.push_back(new Item_string(join_type_str[tab->type], strlen(join_type_str[tab->type]), cs)); uint j; + /* possible_keys */ if (!tab->keys.is_clear_all()) { for (j=0 ; j < table->keys ; j++) @@ -9198,6 +9247,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length(),cs)); else item_list.push_back(item_null); + /* key key_len ref */ if (tab->ref.key_parts) { KEY *key_info=table->key_info+ tab->ref.key; @@ -9236,9 +9286,11 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, item_list.push_back(item_null); item_list.push_back(item_null); } + /* rows */ item_list.push_back(new Item_int((longlong) (ulonglong) join->best_positions[i]. records_read, 21)); + /* extra */ my_bool key_read=table->key_read; if ((tab->type == JT_NEXT || tab->type == JT_CONST) && table->used_keys.is_set(tab->index)) @@ -9303,32 +9355,53 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) DBUG_ENTER("mysql_explain_union"); int res= 0; SELECT_LEX *first= unit->first_select(); + for (SELECT_LEX *sl= first; sl; sl= sl->next_select()) { // drop UNCACHEABLE_EXPLAIN, because it is for internal usage only uint8 uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN); - - res= mysql_explain_select(thd, sl, - (((&thd->lex->select_lex)==sl)? - ((thd->lex->all_selects_list != sl) ? - primary_key_name : "SIMPLE"): - ((sl == first)? - ((sl->linkage == DERIVED_TABLE_TYPE) ? - "DERIVED": - ((uncacheable & UNCACHEABLE_DEPENDENT) ? - "DEPENDENT SUBQUERY": - (uncacheable?"UNCACHEABLE SUBQUERY": - "SUBQUERY"))): - ((uncacheable & UNCACHEABLE_DEPENDENT) ? - "DEPENDENT UNION": - uncacheable?"UNCACHEABLE UNION": - "UNION"))), - result); - if (res) - break; - + sl->type= (((&thd->lex->select_lex)==sl)? + ((thd->lex->all_selects_list != sl) ? + primary_key_name : "SIMPLE"): + ((sl == first)? + ((sl->linkage == DERIVED_TABLE_TYPE) ? + "DERIVED": + ((uncacheable & UNCACHEABLE_DEPENDENT) ? + "DEPENDENT SUBQUERY": + (uncacheable?"UNCACHEABLE SUBQUERY": + "SUBQUERY"))): + ((uncacheable & UNCACHEABLE_DEPENDENT) ? + "DEPENDENT UNION": + uncacheable?"UNCACHEABLE UNION": + "UNION"))); + sl->options|= SELECT_DESCRIBE; + } + if (first->next_select()) + { + unit->fake_select_lex->select_number= -first->select_number; + unit->fake_select_lex->type= "UNION RESULT"; + unit->fake_select_lex->options|= SELECT_DESCRIBE; + if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE))) + res= unit->exec(); + res|= unit->cleanup(); + } + else + { + thd->lex->current_select= first; + res= mysql_select(thd, &first->ref_pointer_array, + (TABLE_LIST*) first->table_list.first, + first->with_wild, first->item_list, + first->where, + first->order_list.elements + + first->group_list.elements, + (ORDER*) first->order_list.first, + (ORDER*) first->group_list.first, + first->having, + (ORDER*) thd->lex->proc_list.first, + first->options | thd->options | SELECT_DESCRIBE, + result, unit, first); } if (res > 0 || thd->net.report_error) res= -1; // mysql_explain_select do not report error @@ -9336,30 +9409,6 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) } -int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type, - select_result *result) -{ - DBUG_ENTER("mysql_explain_select"); - DBUG_PRINT("info", ("Select 0x%lx, type %s", (ulong)select_lex, type)) - select_lex->type= type; - thd->lex->current_select= select_lex; - SELECT_LEX_UNIT *unit= select_lex->master_unit(); - int res= mysql_select(thd, &select_lex->ref_pointer_array, - (TABLE_LIST*) select_lex->table_list.first, - select_lex->with_wild, select_lex->item_list, - select_lex->where, - select_lex->order_list.elements + - select_lex->group_list.elements, - (ORDER*) select_lex->order_list.first, - (ORDER*) select_lex->group_list.first, - select_lex->having, - (ORDER*) thd->lex->proc_list.first, - select_lex->options | thd->options | SELECT_DESCRIBE, - result, unit, select_lex); - DBUG_RETURN(res); -} - - void st_select_lex::print(THD *thd, String *str) { if (!thd) diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 63638b618d9..fe009f89e76 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -41,7 +41,7 @@ int mysql_union(THD *thd, LEX *lex, select_result *result, ***************************************************************************/ select_union::select_union(TABLE *table_par) - :table(table_par), not_describe(0) + :table(table_par) { bzero((char*) &info,sizeof(info)); /* @@ -149,6 +149,8 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, select_result *tmp_result; DBUG_ENTER("st_select_lex_unit::prepare"); + describe= test(additional_options & SELECT_DESCRIBE); + /* result object should be reassigned even if preparing already done for max/min subquery (ALL/ANY optimization) @@ -156,7 +158,26 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, result= sel_result; if (prepared) + { + if (describe) + { + /* fast reinit for EXPLAIN */ + for (sl= first_select_in_union(); sl; sl= sl->next_select()) + { + sl->join->result= result; + select_limit_cnt= HA_POS_ERROR; + offset_limit_cnt= 0; + if (!sl->join->procedure && + result->prepare(sl->join->fields_list, this)) + { + DBUG_RETURN(1); + } + sl->join->select_options|= SELECT_DESCRIBE; + sl->join->reinit(); + } + } DBUG_RETURN(0); + } prepared= 1; res= 0; @@ -169,8 +190,9 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, { if (!(tmp_result= union_result= new select_union(0))) goto err; - union_result->not_describe= 1; union_result->tmp_table_param.init(); + if (describe) + tmp_result= sel_result; } else { @@ -327,11 +349,11 @@ int st_select_lex_unit::exec() ulonglong add_rows=0; DBUG_ENTER("st_select_lex_unit::exec"); - if (executed && !uncacheable) + if (executed && !uncacheable && !describe) DBUG_RETURN(0); executed= 1; - if (uncacheable || !item || !item->assigned()) + if (uncacheable || !item || !item->assigned() || describe) { if (optimized && item && item->assigned()) { @@ -350,7 +372,7 @@ int st_select_lex_unit::exec() res= sl->join->reinit(); else { - if (sl != global_parameters) + if (sl != global_parameters && !describe) { offset_limit_cnt= sl->offset_limit; select_limit_cnt= sl->select_limit+sl->offset_limit; @@ -362,7 +384,7 @@ int st_select_lex_unit::exec() We can't use LIMIT at this stage if we are using ORDER BY for the whole query */ - if (sl->order_list.first) + if (sl->order_list.first || describe) select_limit_cnt= HA_POS_ERROR; else select_limit_cnt= sl->select_limit+sl->offset_limit; |