Commit d448caba authored by peter@mysql.com's avatar peter@mysql.com

Merge mysql.com:/home/pz/mysql/mysql-4.1-root

into mysql.com:/home/pz/mysql/mysql-4.1
parents 50021f6f d9f99816
...@@ -159,6 +159,23 @@ UNIQUE KEY `email` (`email`) ...@@ -159,6 +159,23 @@ UNIQUE KEY `email` (`email`)
INSERT INTO inscrit (pseudo,email) VALUES ('joce','test'); INSERT INTO inscrit (pseudo,email) VALUES ('joce','test');
INSERT INTO inscrit (pseudo,email) VALUES ('joce1','test1'); INSERT INTO inscrit (pseudo,email) VALUES ('joce1','test1');
INSERT INTO inscrit (pseudo,email) VALUES ('2joce1','2test1'); INSERT INTO inscrit (pseudo,email) VALUES ('2joce1','2test1');
EXPLAIN SELECT pseudo,(SELECT email FROM inscrit WHERE pseudo=(SELECT
pseudo FROM inscrit WHERE pseudo='joce')) FROM inscrit WHERE pseudo=(SELECT
pseudo FROM inscrit WHERE pseudo='joce');
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY inscrit const PRIMARY PRIMARY 35 const 1
4 SUBSELECT inscrit const PRIMARY PRIMARY 35 const 1
2 SUBSELECT inscrit const PRIMARY PRIMARY 35 const 1
3 SUBSELECT inscrit const PRIMARY PRIMARY 35 const 1
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo,email FROM
inscrit WHERE pseudo='joce');
Subselect returns more than 1 field
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT * FROM inscrit WHERE
pseudo='joce');
Subselect returns more than 1 field
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo='joce');
pseudo
joce
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo LIKE '%joce%'); SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo LIKE '%joce%');
Subselect returns more than 1 record Subselect returns more than 1 record
drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit;
...@@ -82,6 +82,16 @@ CREATE TABLE `inscrit` ( ...@@ -82,6 +82,16 @@ CREATE TABLE `inscrit` (
INSERT INTO inscrit (pseudo,email) VALUES ('joce','test'); INSERT INTO inscrit (pseudo,email) VALUES ('joce','test');
INSERT INTO inscrit (pseudo,email) VALUES ('joce1','test1'); INSERT INTO inscrit (pseudo,email) VALUES ('joce1','test1');
INSERT INTO inscrit (pseudo,email) VALUES ('2joce1','2test1'); INSERT INTO inscrit (pseudo,email) VALUES ('2joce1','2test1');
EXPLAIN SELECT pseudo,(SELECT email FROM inscrit WHERE pseudo=(SELECT
pseudo FROM inscrit WHERE pseudo='joce')) FROM inscrit WHERE pseudo=(SELECT
pseudo FROM inscrit WHERE pseudo='joce');
-- error 1239
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo,email FROM
inscrit WHERE pseudo='joce');
-- error 1239
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT * FROM inscrit WHERE
pseudo='joce');
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo='joce');
-- error 1240 -- error 1240
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo LIKE '%joce%'); SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo LIKE '%joce%');
......
...@@ -81,15 +81,17 @@ void Item_subselect::make_field (Send_field *tmp_field) ...@@ -81,15 +81,17 @@ void Item_subselect::make_field (Send_field *tmp_field)
bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
int res= engine->prepare();
if (!res)
{
// Is it one field subselect? // Is it one field subselect?
if (engine->cols() > max_columns) if (engine->cols() > max_columns)
{ {
my_message(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL), MYF(0)); my_message(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL), MYF(0));
return 1; return 1;
} }
int res= engine->prepare();
if (!res)
fix_length_and_dec(); fix_length_and_dec();
}
return res; return res;
} }
...@@ -150,6 +152,8 @@ String *Item_singleval_subselect::val_str (String *str) ...@@ -150,6 +152,8 @@ String *Item_singleval_subselect::val_str (String *str)
assign_null(); assign_null();
return 0; return 0;
} }
// Assign temporary buffer with stored value
str_value.set(string_value, 0, string_value.length());
return &str_value; return &str_value;
} }
...@@ -208,7 +212,7 @@ subselect_single_select_engine::subselect_single_select_engine(THD *thd, ...@@ -208,7 +212,7 @@ subselect_single_select_engine::subselect_single_select_engine(THD *thd,
select_subselect *result, select_subselect *result,
Item_subselect *item): Item_subselect *item):
subselect_engine(thd, item, result), subselect_engine(thd, item, result),
executed(0), optimized(0) prepared(0), optimized(0), executed(0)
{ {
select_lex= select; select_lex= select;
SELECT_LEX_UNIT *unit= select_lex->master_unit(); SELECT_LEX_UNIT *unit= select_lex->master_unit();
...@@ -247,6 +251,9 @@ subselect_union_engine::subselect_union_engine(THD *thd, ...@@ -247,6 +251,9 @@ subselect_union_engine::subselect_union_engine(THD *thd,
int subselect_single_select_engine::prepare() int subselect_single_select_engine::prepare()
{ {
if (prepared)
return 0;
prepared= 1;
SELECT_LEX *save_select= thd->lex.select; SELECT_LEX *save_select= thd->lex.select;
thd->lex.select= select_lex; thd->lex.select= select_lex;
if(join->prepare((TABLE_LIST*) select_lex->table_list.first, if(join->prepare((TABLE_LIST*) select_lex->table_list.first,
......
...@@ -80,8 +80,14 @@ class Item_subselect :public Item ...@@ -80,8 +80,14 @@ class Item_subselect :public Item
class Item_singleval_subselect :public Item_subselect class Item_singleval_subselect :public Item_subselect
{ {
protected: protected:
longlong int_value; /* here stored integer value of this item */ longlong int_value; /* Here stored integer value of this item */
double real_value; /* here stored real value of this item */ double real_value; /* Here stored real value of this item */
/*
Here stored string value of this item.
(str_value used only as temporary buffer, because it can be changed
by Item::save_field)
*/
String string_value;
enum Item_result res_type; /* type of results */ enum Item_result res_type; /* type of results */
public: public:
...@@ -91,6 +97,7 @@ class Item_singleval_subselect :public Item_subselect ...@@ -91,6 +97,7 @@ class Item_singleval_subselect :public Item_subselect
{ {
int_value= item->int_value; int_value= item->int_value;
real_value= item->real_value; real_value= item->real_value;
string_value.set(item->string_value, 0, item->string_value.length());
max_length= item->max_length; max_length= item->max_length;
decimals= item->decimals; decimals= item->decimals;
res_type= item->res_type; res_type= item->res_type;
...@@ -172,8 +179,9 @@ class subselect_engine ...@@ -172,8 +179,9 @@ class subselect_engine
class subselect_single_select_engine: public subselect_engine class subselect_single_select_engine: public subselect_engine
{ {
my_bool executed; /* simple subselect is executed */ my_bool prepared; /* simple subselect is prepared */
my_bool optimized; /* simple subselect is optimized */ my_bool optimized; /* simple subselect is optimized */
my_bool executed; /* simple subselect is executed */
st_select_lex *select_lex; /* corresponding select_lex */ st_select_lex *select_lex; /* corresponding select_lex */
JOIN * join; /* corresponding JOIN structure */ JOIN * join; /* corresponding JOIN structure */
public: public:
......
...@@ -884,9 +884,14 @@ bool select_singleval_subselect::send_data(List<Item> &items) ...@@ -884,9 +884,14 @@ bool select_singleval_subselect::send_data(List<Item> &items)
it->decimals= val_item->decimals; it->decimals= val_item->decimals;
it->binary= val_item->binary; it->binary= val_item->binary;
it->int_value= val_item->val_int(); it->int_value= val_item->val_int();
String *s= val_item->val_str(&it->str_value); String *s= val_item->val_str(&it->string_value);
if (s != &it->str_value) if (s != &it->string_value)
it->str_value.set(*s, 0, s->length()); {
it->string_value.set(*s, 0, s->length());
}
// TODO: remove when correct charset handling appeared for Item
it->str_value.set(*s, 0, s->length()); // store charset
it->res_type= val_item->result_type(); it->res_type= val_item->result_type();
} }
it->assigned(1); it->assigned(1);
......
...@@ -944,7 +944,7 @@ void st_select_lex_unit::init_query() ...@@ -944,7 +944,7 @@ void st_select_lex_unit::init_query()
global_parameters= this; global_parameters= this;
select_limit_cnt= HA_POS_ERROR; select_limit_cnt= HA_POS_ERROR;
offset_limit_cnt= 0; offset_limit_cnt= 0;
optimized= 0; prepared= optimized= 0;
item= 0; item= 0;
} }
......
...@@ -227,6 +227,7 @@ class st_select_lex_unit: public st_select_lex_node { ...@@ -227,6 +227,7 @@ class st_select_lex_unit: public st_select_lex_node {
select_result *result; select_result *result;
int res; int res;
bool describe, found_rows_for_union, bool describe, found_rows_for_union,
prepared, //prepare phase already performed for UNION (unit)
optimized; // optimize phase already performed for UNION (unit) optimized; // optimize phase already performed for UNION (unit)
public: public:
/* /*
......
...@@ -104,11 +104,16 @@ bool select_union::flush() ...@@ -104,11 +104,16 @@ bool select_union::flush()
typedef JOIN * JOIN_P; typedef JOIN * JOIN_P;
int st_select_lex_unit::prepare(THD *thd, select_result *result) int st_select_lex_unit::prepare(THD *thd, select_result *result)
{ {
DBUG_ENTER("st_select_lex_unit::prepare");
if (prepared)
DBUG_RETURN(0);
prepared= 1;
describe=(first_select()->options & SELECT_DESCRIBE) ? 1 : 0; describe=(first_select()->options & SELECT_DESCRIBE) ? 1 : 0;
res= 0; res= 0;
found_rows_for_union= false; found_rows_for_union= false;
TMP_TABLE_PARAM tmp_table_param; TMP_TABLE_PARAM tmp_table_param;
DBUG_ENTER("st_select_lex_unit::prepare");
this->thd= thd; this->thd= thd;
this->result= result; this->result= result;
SELECT_LEX *lex_select_save= thd->lex.select; SELECT_LEX *lex_select_save= thd->lex.select;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment