mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
Merge sanja.is.com.ua:/home/bell/mysql/mysql-4.1
into sanja.is.com.ua:/home/bell/mysql/work-crash-4.1
This commit is contained in:
commit
94b84a7008
35 changed files with 199 additions and 39 deletions
|
@ -262,4 +262,5 @@
|
|||
#define ER_CYCLIC_REFERENCE 1243
|
||||
#define ER_AUTO_CONVERT 1244
|
||||
#define ER_ILLEGAL_REFERENCE 1245
|
||||
#define ER_ERROR_MESSAGES 246
|
||||
#define ER_SELECT_REDUCED 1246
|
||||
#define ER_ERROR_MESSAGES 247
|
||||
|
|
|
@ -513,3 +513,30 @@ x y
|
|||
4 2
|
||||
2 1
|
||||
drop table t1, t2;
|
||||
SELECT * FROM (SELECT 1) WHERE 1 IN (SELECT *);
|
||||
No tables used
|
||||
drop table if exists t;
|
||||
CREATE TABLE t (id int(11) default NULL, KEY id (id)) TYPE=MyISAM CHARSET=latin1;
|
||||
INSERT INTO t VALUES (1),(2);
|
||||
SELECT * FROM t WHERE id IN (SELECT 1);
|
||||
id
|
||||
1
|
||||
EXPLAIN SELECT * FROM t WHERE id IN (SELECT 1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t ref id id 5 const 1 Using where; Using index
|
||||
Warnings:
|
||||
Note 1246 Select 2 was reduced during optimisation
|
||||
SELECT * FROM t WHERE id IN (SELECT 1 UNION SELECT 3);
|
||||
id
|
||||
1
|
||||
EXPLAIN SELECT * FROM t WHERE id IN (SELECT 1 UNION SELECT 3);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t index NULL id 5 NULL 2 Using where; Using index
|
||||
2 DEPENDENT SUBSELECT No tables used
|
||||
3 UNION No tables used
|
||||
SELECT * FROM t WHERE id IN (SELECT 5 UNION SELECT 3);
|
||||
id
|
||||
SELECT * FROM t WHERE id IN (SELECT 5 UNION SELECT 2);
|
||||
id
|
||||
2
|
||||
drop table if exists t;
|
||||
|
|
|
@ -306,3 +306,17 @@ select * from t1;
|
|||
replace LOW_PRIORITY into t1 (x, y) VALUES ((SELECT a+1 FROM t2), (SELECT a FROM t2));
|
||||
select * from t1;
|
||||
drop table t1, t2;
|
||||
|
||||
-- error 1096
|
||||
SELECT * FROM (SELECT 1) WHERE 1 IN (SELECT *);
|
||||
drop table if exists t;
|
||||
CREATE TABLE t (id int(11) default NULL, KEY id (id)) TYPE=MyISAM CHARSET=latin1;
|
||||
INSERT INTO t VALUES (1),(2);
|
||||
SELECT * FROM t WHERE id IN (SELECT 1);
|
||||
EXPLAIN SELECT * FROM t WHERE id IN (SELECT 1);
|
||||
SELECT * FROM t WHERE id IN (SELECT 1 UNION SELECT 3);
|
||||
EXPLAIN SELECT * FROM t WHERE id IN (SELECT 1 UNION SELECT 3);
|
||||
SELECT * FROM t WHERE id IN (SELECT 5 UNION SELECT 3);
|
||||
SELECT * FROM t WHERE id IN (SELECT 5 UNION SELECT 2);
|
||||
drop table if exists t;
|
||||
|
||||
|
|
50
sql/item.cc
50
sql/item.cc
|
@ -463,41 +463,41 @@ bool Item_asterisk_remover::fix_fields(THD *thd,
|
|||
((Item_field*) item)->field_name[0] == '*')
|
||||
{
|
||||
Item_field *fitem= (Item_field*) item;
|
||||
if (!list->next || fitem->db_name || fitem->table_name)
|
||||
{
|
||||
TABLE_LIST *table= find_table_in_list(list,
|
||||
fitem->db_name,
|
||||
fitem->table_name);
|
||||
if (table)
|
||||
if (list)
|
||||
if (!list->next || fitem->db_name || fitem->table_name)
|
||||
{
|
||||
TABLE * tb= table->table;
|
||||
if (find_table_in_list(table->next, fitem->db_name,
|
||||
fitem->table_name) != 0 ||
|
||||
tb->fields == 1)
|
||||
TABLE_LIST *table= find_table_in_list(list,
|
||||
fitem->db_name,
|
||||
fitem->table_name);
|
||||
if (table)
|
||||
{
|
||||
if ((item= new Item_field(tb->field[0])))
|
||||
TABLE * tb= table->table;
|
||||
if (find_table_in_list(table->next, fitem->db_name,
|
||||
fitem->table_name) != 0 ||
|
||||
tb->fields == 1)
|
||||
{
|
||||
res= 0;
|
||||
tb->field[0]->query_id= thd->query_id;
|
||||
tb->used_keys&= tb->field[0]->part_of_key;
|
||||
tb->used_fields= tb->fields;
|
||||
if ((item= new Item_field(tb->field[0])))
|
||||
{
|
||||
res= 0;
|
||||
tb->field[0]->query_id= thd->query_id;
|
||||
tb->used_keys&= tb->field[0]->part_of_key;
|
||||
tb->used_fields= tb->fields;
|
||||
}
|
||||
else
|
||||
thd->fatal_error= 1; // can't create Item => out of memory
|
||||
}
|
||||
else
|
||||
thd->fatal_error= 1; // can't create Item => out of memory
|
||||
my_message(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL),
|
||||
MYF(0));
|
||||
}
|
||||
else
|
||||
my_message(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL),
|
||||
MYF(0));
|
||||
my_error(ER_BAD_TABLE_ERROR, MYF(0), fitem->table_name);
|
||||
}
|
||||
else
|
||||
if (!fitem->table_name)
|
||||
my_error(ER_NO_TABLES_USED, MYF(0));
|
||||
else
|
||||
my_error(ER_BAD_TABLE_ERROR, MYF(0), fitem->table_name);
|
||||
}
|
||||
my_message(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL),
|
||||
MYF(0));
|
||||
else
|
||||
my_message(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL),
|
||||
MYF(0));
|
||||
my_error(ER_NO_TABLES_USED, MYF(0));
|
||||
}
|
||||
else
|
||||
res= item->fix_fields(thd, list, &item);
|
||||
|
|
|
@ -33,7 +33,7 @@ SUBSELECT TODO:
|
|||
#include "sql_select.h"
|
||||
|
||||
Item_subselect::Item_subselect():
|
||||
Item_result_field(), engine_owner(1), value_assigned(0)
|
||||
Item_result_field(), engine_owner(1), value_assigned(0), substitution(0)
|
||||
{
|
||||
assign_null();
|
||||
/*
|
||||
|
@ -89,6 +89,13 @@ void Item_subselect::make_field (Send_field *tmp_field)
|
|||
|
||||
bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
{
|
||||
if (substitution)
|
||||
{
|
||||
(*ref)= substitution;
|
||||
engine->exclude();
|
||||
return substitution->fix_fields(thd, tables, ref);
|
||||
}
|
||||
|
||||
char const *save_where= thd->where;
|
||||
int res= engine->prepare();
|
||||
if (!res)
|
||||
|
@ -291,12 +298,12 @@ void Item_in_subselect::single_value_transformer(st_select_lex *select_lex,
|
|||
else
|
||||
item= (Item*) sl->item_list.pop();
|
||||
|
||||
left_expr= new Item_outer_select_context_saver(left_expr);
|
||||
Item *expr= new Item_outer_select_context_saver(left_expr);
|
||||
|
||||
if (sl->having || sl->with_sum_func || sl->group_list.first)
|
||||
{
|
||||
sl->item_list.push_back(item);
|
||||
item= (*func)(left_expr, new Item_ref(sl->item_list.head_ref(),
|
||||
item= (*func)(expr, new Item_ref(sl->item_list.head_ref(),
|
||||
0, "<result>"));
|
||||
if (sl->having)
|
||||
sl->having= new Item_cond_and(sl->having, item);
|
||||
|
@ -307,11 +314,42 @@ void Item_in_subselect::single_value_transformer(st_select_lex *select_lex,
|
|||
{
|
||||
sl->item_list.empty();
|
||||
sl->item_list.push_back(new Item_int(1));
|
||||
item= (*func)(left_expr, new Item_asterisk_remover(item));
|
||||
if (sl->where)
|
||||
sl->where= new Item_cond_and(sl->where, item);
|
||||
if (sl->table_list.elements)
|
||||
{
|
||||
item= (*func)(expr, new Item_asterisk_remover(item));
|
||||
if (sl->where)
|
||||
sl->where= new Item_cond_and(sl->where, item);
|
||||
else
|
||||
sl->where= item;
|
||||
}
|
||||
else
|
||||
sl->where= item;
|
||||
{
|
||||
if (item->type() == Item::FIELD_ITEM &&
|
||||
((Item_field*) item)->field_name[0] == '*')
|
||||
{
|
||||
my_error(ER_NO_TABLES_USED, MYF(0));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
if (select_lex->next_select())
|
||||
{
|
||||
// it is in union => we should perform it
|
||||
sl->having= (*func)(expr, item);
|
||||
}
|
||||
else
|
||||
{
|
||||
// it is single select without tables => possible optimization
|
||||
item= (*func)(left_expr, item);
|
||||
substitution= item;
|
||||
THD *thd= current_thd;
|
||||
if (thd->lex.describe)
|
||||
{
|
||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||
sprintf(warn_buff, ER(ER_SELECT_REDUCED), sl->select_number);
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_SELECT_REDUCED, warn_buff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
|
@ -502,3 +540,17 @@ bool subselect_union_engine::check_loop(uint id)
|
|||
DBUG_RETURN(1);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
void subselect_single_select_engine::exclude()
|
||||
{
|
||||
select_lex->master_unit()->exclude_level();
|
||||
//if (current_thd->lex->describe)
|
||||
}
|
||||
|
||||
void subselect_union_engine::exclude()
|
||||
{
|
||||
unit->exclude_level();
|
||||
// for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
|
||||
// if (sl->join && sl->join->check_loop(id))
|
||||
// DBUG_RETURN(1);
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@ class Item_subselect :public Item_result_field
|
|||
my_bool engine_owner; /* Is this item owner of engine */
|
||||
my_bool value_assigned; /* value already assigned to subselect */
|
||||
protected:
|
||||
/* substitution instead of subselect in case of optimization */
|
||||
Item *substitution;
|
||||
/* engine that perform execution of subselect (single select or union) */
|
||||
subselect_engine *engine;
|
||||
/* allowed number of columns (1 for single value subqueries) */
|
||||
|
@ -45,6 +47,7 @@ public:
|
|||
Item_subselect();
|
||||
Item_subselect(Item_subselect *item)
|
||||
{
|
||||
substitution= item->substitution;
|
||||
null_value= item->null_value;
|
||||
decimals= item->decimals;
|
||||
max_columns= item->max_columns;
|
||||
|
@ -213,6 +216,7 @@ public:
|
|||
virtual bool depended()= 0; /* depended from outer select */
|
||||
enum Item_result type() { return res_type; }
|
||||
virtual bool check_loop(uint id)= 0;
|
||||
virtual void exclude()= 0;
|
||||
};
|
||||
|
||||
class subselect_single_select_engine: public subselect_engine
|
||||
|
@ -232,6 +236,7 @@ public:
|
|||
uint cols();
|
||||
bool depended();
|
||||
bool check_loop(uint id);
|
||||
void exclude();
|
||||
};
|
||||
|
||||
class subselect_union_engine: public subselect_engine
|
||||
|
@ -248,4 +253,5 @@ public:
|
|||
uint cols();
|
||||
bool depended();
|
||||
bool check_loop(uint id);
|
||||
void exclude();
|
||||
};
|
||||
|
|
|
@ -256,3 +256,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -250,3 +250,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -258,3 +258,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -247,3 +247,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -252,3 +252,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -247,3 +247,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -250,3 +250,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -247,3 +247,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -249,3 +249,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -247,3 +247,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -249,3 +249,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -247,3 +247,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -249,3 +249,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -249,3 +249,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -251,3 +251,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -247,3 +247,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -251,3 +251,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s"
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -250,3 +250,4 @@
|
|||
"Циклическая ссылка на подзапрос",
|
||||
"Преобразование поля '%s' из %s в %s",
|
||||
"Ссылка '%-.64s' не поддерживается (%s)",
|
||||
"Select %u был упразднен в процессе оптимизации",
|
||||
|
|
|
@ -243,3 +243,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -255,3 +255,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -248,3 +248,4 @@
|
|||
"Cyclic reference on subqueries",
|
||||
"Converting column '%s' from %s to %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -247,3 +247,4 @@
|
|||
"Syklisk referens i subselect",
|
||||
"Konvertar kolumn '%s' från %s till %s",
|
||||
"Reference '%-.64s' not supported (%s)",
|
||||
"Select %u was reduced during optimisation",
|
||||
|
|
|
@ -252,3 +252,4 @@
|
|||
"Циклiчне посилання на пiдзапит",
|
||||
"Перетворення стовбца '%s' з %s у %s",
|
||||
"Посилання '%-.64s' не пiдтримуется (%s)",
|
||||
"Select %u was скасовано при оптимiзацii",
|
||||
|
|
|
@ -2082,7 +2082,7 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
|||
|
||||
while ((item=it++))
|
||||
{
|
||||
if (item->type() == Item::FIELD_ITEM &&
|
||||
if (item->type() == Item::FIELD_ITEM && ((Item_field*) item)->field_name &&
|
||||
((Item_field*) item)->field_name[0] == '*')
|
||||
{
|
||||
uint elem= fields.elements;
|
||||
|
|
|
@ -1058,6 +1058,31 @@ void st_select_lex_node::exclude()
|
|||
*/
|
||||
}
|
||||
|
||||
void st_select_lex_unit::exclude_level()
|
||||
{
|
||||
SELECT_LEX_UNIT *units= 0, **units_last= &units;
|
||||
for(SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
|
||||
{
|
||||
if (sl->link_prev && (*sl->link_prev= sl->link_next))
|
||||
sl->link_next->link_prev= sl->link_prev;
|
||||
SELECT_LEX_UNIT **last= 0;
|
||||
for (SELECT_LEX_UNIT *u= sl->first_inner_unit(); u; u= u->next_unit())
|
||||
last= (SELECT_LEX_UNIT**)&(u->next);
|
||||
if (last)
|
||||
{
|
||||
(*units_last)= sl->first_inner_unit();
|
||||
units_last= last;
|
||||
}
|
||||
}
|
||||
if (units)
|
||||
{
|
||||
(*prev)= units;
|
||||
(*units_last)= (SELECT_LEX_UNIT*)next;
|
||||
}
|
||||
else
|
||||
(*prev)= next;
|
||||
}
|
||||
|
||||
st_select_lex* st_select_lex_node::select_lex()
|
||||
{
|
||||
DBUG_ENTER("st_select_lex_node::select_lex (never should be called)");
|
||||
|
|
|
@ -242,6 +242,8 @@ public:
|
|||
List<String> *ignore_index= 0);
|
||||
virtual void set_lock_for_tables(thr_lock_type lock_type) {}
|
||||
void mark_as_dependent(st_select_lex *last);
|
||||
|
||||
friend class st_select_lex_unit;
|
||||
private:
|
||||
void fast_exclude();
|
||||
};
|
||||
|
@ -288,6 +290,7 @@ public:
|
|||
st_select_lex* outer_select();
|
||||
st_select_lex* first_select() { return (st_select_lex*) slave; }
|
||||
st_select_lex_unit* next_unit() { return (st_select_lex_unit*) next; }
|
||||
void st_select_lex_unit::exclude_level();
|
||||
|
||||
/* UNION methods */
|
||||
int prepare(THD *thd, select_result *result);
|
||||
|
|
|
@ -1329,7 +1329,6 @@ mysql_execute_command(THD *thd)
|
|||
*/
|
||||
thd->old_total_warn_count= thd->total_warn_count;
|
||||
|
||||
thd->net.report_error= 0;
|
||||
if (thd->slave_thread)
|
||||
{
|
||||
/*
|
||||
|
@ -2957,6 +2956,8 @@ mysql_parse(THD *thd, char *inBuf, uint length)
|
|||
|
||||
mysql_init_query(thd);
|
||||
thd->query_length = length;
|
||||
thd->net.report_error= 0;
|
||||
|
||||
if (query_cache_send_result_to_client(thd, inBuf, length) <= 0)
|
||||
{
|
||||
LEX *lex=lex_start(thd, (uchar*) inBuf, length);
|
||||
|
@ -2969,8 +2970,13 @@ mysql_parse(THD *thd, char *inBuf, uint length)
|
|||
}
|
||||
else
|
||||
{
|
||||
mysql_execute_command(thd);
|
||||
query_cache_end_of_result(&thd->net);
|
||||
if (thd->net.report_error)
|
||||
send_error(thd, 0, NullS);
|
||||
else
|
||||
{
|
||||
mysql_execute_command(thd);
|
||||
query_cache_end_of_result(&thd->net);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -214,7 +214,11 @@ int st_select_lex_unit::exec()
|
|||
if (dependent || !item || !item->assigned())
|
||||
{
|
||||
if (optimized && item && item->assigned())
|
||||
{
|
||||
item->assigned(0); // We will reinit & rexecute unit
|
||||
item->assign_null();
|
||||
table->file->delete_all_rows();
|
||||
}
|
||||
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
|
||||
{
|
||||
thd->lex.current_select= sl;
|
||||
|
|
|
@ -3328,11 +3328,10 @@ describe:
|
|||
YYABORT;
|
||||
}
|
||||
opt_describe_column
|
||||
| describe_command select
|
||||
| describe_command { Lex->describe=1; } select
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->select_lex.options|= SELECT_DESCRIBE;
|
||||
lex->describe=1;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue