Commit 7642da10 authored by unknown's avatar unknown

Merge sanja.is.com.ua:/home/bell/mysql/mysql-4.1

into sanja.is.com.ua:/home/bell/mysql/work-crash-4.1

parents 7721c758 81a5afb9
...@@ -259,4 +259,5 @@ ...@@ -259,4 +259,5 @@
#define ER_SUBSELECT_NO_1_ROW 1240 #define ER_SUBSELECT_NO_1_ROW 1240
#define ER_UNKNOWN_STMT_HANDLER 1241 #define ER_UNKNOWN_STMT_HANDLER 1241
#define ER_CORRUPT_HELP_DB 1242 #define ER_CORRUPT_HELP_DB 1242
#define ER_ERROR_MESSAGES 243 #define ER_CYCLIC_REFERENCE 1243
#define ER_ERROR_MESSAGES 244
...@@ -8,6 +8,8 @@ SELECT (SELECT 1) UNION SELECT (SELECT 2); ...@@ -8,6 +8,8 @@ SELECT (SELECT 1) UNION SELECT (SELECT 2);
SELECT (SELECT (SELECT 0 UNION SELECT 0)); SELECT (SELECT (SELECT 0 UNION SELECT 0));
(SELECT (SELECT 0 UNION SELECT 0)) (SELECT (SELECT 0 UNION SELECT 0))
0 0
SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a;
Cyclic reference on subqueries
drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit;
create table t1 (a int); create table t1 (a int);
create table t2 (a int, b int); create table t2 (a int, b int);
...@@ -46,7 +48,7 @@ a b ...@@ -46,7 +48,7 @@ a b
1 7 1 7
2 7 2 7
3 8 3 8
select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1) select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)
union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a); union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
a b a b
1 7 1 7
......
select (select 2); select (select 2);
SELECT (SELECT 1) UNION SELECT (SELECT 2); SELECT (SELECT 1) UNION SELECT (SELECT 2);
SELECT (SELECT (SELECT 0 UNION SELECT 0)); SELECT (SELECT (SELECT 0 UNION SELECT 0));
-- error 1243
SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a;
drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit;
create table t1 (a int); create table t1 (a int);
create table t2 (a int, b int); create table t2 (a int, b int);
...@@ -18,7 +20,7 @@ insert into t3 values (6),(7),(3); ...@@ -18,7 +20,7 @@ insert into t3 values (6),(7),(3);
select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1); select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1) select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)
union (select * from t4 order by a limit 2) limit 3; union (select * from t4 order by a limit 2) limit 3;
select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1) select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)
union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a); union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
explain select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1) explain select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)
union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a); union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
......
...@@ -42,6 +42,20 @@ Item::Item() ...@@ -42,6 +42,20 @@ Item::Item()
decimals=0; max_length=0; decimals=0; max_length=0;
next=current_thd->free_list; // Put in free list next=current_thd->free_list; // Put in free list
current_thd->free_list=this; current_thd->free_list=this;
loop_id= 0;
}
bool Item::check_loop(uint id)
{
DBUG_ENTER("Item::check_loop");
DBUG_PRINT("info", ("id %u, name %s", id, name));
if (loop_id == id)
{
DBUG_PRINT("info", ("id match"));
DBUG_RETURN(1);
}
loop_id= id;
DBUG_RETURN(0);
} }
void Item::set_name(const char *str,uint length) void Item::set_name(const char *str,uint length)
...@@ -862,6 +876,11 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) ...@@ -862,6 +876,11 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
{ {
depended_from= last; depended_from= last;
thd->lex.current_select->mark_as_dependent(last); thd->lex.current_select->mark_as_dependent(last);
if (check_loop(thd->check_loops_counter++))
{
my_message(ER_CYCLIC_REFERENCE, ER(ER_CYCLIC_REFERENCE), MYF(0));
return 1;
}
} }
} }
else if (!ref) else if (!ref)
...@@ -873,6 +892,14 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) ...@@ -873,6 +892,14 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
return 0; return 0;
} }
bool Item_ref::check_loop(uint id)
{
DBUG_ENTER("Item_ref::check_loop");
if (Item_ident::check_loop(id))
DBUG_RETURN(1);
DBUG_RETURN((*ref)->check_loop(id));
}
/* /*
** If item is a const function, calculate it and return a const item ** If item is a const function, calculate it and return a const item
** The original item is freed if not returned ** The original item is freed if not returned
......
...@@ -20,10 +20,11 @@ ...@@ -20,10 +20,11 @@
#endif #endif
struct st_table_list; struct st_table_list;
void item_init(void); /* Init item functions */ void item_init(void); /* Init item functions */
class Item { class Item {
Item(const Item &); /* Prevent use of these */ uint loop_id; /* Used to find selfrefering loops */
Item(const Item &); /* Prevent use of these */
void operator=(Item &); void operator=(Item &);
public: public:
static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); } static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); }
...@@ -88,6 +89,8 @@ public: ...@@ -88,6 +89,8 @@ public:
virtual CHARSET_INFO *charset() const { return str_value.charset(); }; virtual CHARSET_INFO *charset() const { return str_value.charset(); };
virtual bool binary() const { return str_value.charset()->state & MY_CS_BINSORT ? 1 : 0 ; } virtual bool binary() const { return str_value.charset()->state & MY_CS_BINSORT ? 1 : 0 ; }
virtual void set_charset(CHARSET_INFO *cs) { str_value.set_charset(cs); } virtual void set_charset(CHARSET_INFO *cs) { str_value.set_charset(cs); }
virtual bool check_loop(uint id);
}; };
...@@ -434,6 +437,7 @@ public: ...@@ -434,6 +437,7 @@ public:
void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); } void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); }
enum Item_result result_type () const { return (*ref)->result_type(); } enum Item_result result_type () const { return (*ref)->result_type(); }
table_map used_tables() const { return (*ref)->used_tables(); } table_map used_tables() const { return (*ref)->used_tables(); }
bool check_loop(uint id);
}; };
......
...@@ -344,6 +344,14 @@ void Item_func_interval::update_used_tables() ...@@ -344,6 +344,14 @@ void Item_func_interval::update_used_tables()
const_item_cache&=item->const_item(); const_item_cache&=item->const_item();
} }
bool Item_func_interval::check_loop(uint id)
{
DBUG_ENTER("Item_func_interval::check_loop");
if (Item_func::check_loop(id))
DBUG_RETURN(1);
DBUG_RETURN(item->check_loop(id));
}
void Item_func_between::fix_length_and_dec() void Item_func_between::fix_length_and_dec()
{ {
max_length=1; max_length=1;
...@@ -776,6 +784,16 @@ Item_func_case::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -776,6 +784,16 @@ Item_func_case::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return 0; return 0;
} }
bool Item_func_case::check_loop(uint id)
{
DBUG_ENTER("Item_func_case::check_loop");
if (Item_func::check_loop(id))
DBUG_RETURN(1);
DBUG_RETURN((first_expr && first_expr->check_loop(id)) ||
(else_expr && else_expr->check_loop(id)));
}
void Item_func_case::update_used_tables() void Item_func_case::update_used_tables()
{ {
Item_func::update_used_tables(); Item_func::update_used_tables();
...@@ -1137,6 +1155,20 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -1137,6 +1155,20 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return 0; return 0;
} }
bool Item_cond::check_loop(uint id)
{
DBUG_ENTER("Item_cond::check_loop");
if (Item_func::check_loop(id))
DBUG_RETURN(1);
List_iterator<Item> li(list);
Item *item;
while ((item= li++))
{
if (item->check_loop(id))
DBUG_RETURN(1);
}
DBUG_RETURN(0);
}
void Item_cond::split_sum_func(List<Item> &fields) void Item_cond::split_sum_func(List<Item> &fields)
{ {
......
...@@ -186,6 +186,7 @@ public: ...@@ -186,6 +186,7 @@ public:
~Item_func_interval() { delete item; } ~Item_func_interval() { delete item; }
const char *func_name() const { return "interval"; } const char *func_name() const { return "interval"; }
void update_used_tables(); void update_used_tables();
bool check_loop(uint id);
}; };
...@@ -262,6 +263,7 @@ public: ...@@ -262,6 +263,7 @@ public:
void print(String *str); void print(String *str);
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref); bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
Item *find_item(String *str); Item *find_item(String *str);
bool check_loop(uint id);
}; };
...@@ -424,6 +426,13 @@ class Item_func_in :public Item_int_func ...@@ -424,6 +426,13 @@ class Item_func_in :public Item_int_func
enum Functype functype() const { return IN_FUNC; } enum Functype functype() const { return IN_FUNC; }
const char *func_name() const { return " IN "; } const char *func_name() const { return " IN "; }
void update_used_tables(); void update_used_tables();
bool check_loop(uint id)
{
DBUG_ENTER("Item_func_in::check_loop");
if (Item_func::check_loop(id))
DBUG_RETURN(1);
DBUG_RETURN(item->check_loop(id));
}
}; };
...@@ -563,6 +572,7 @@ public: ...@@ -563,6 +572,7 @@ public:
void print(String *str); void print(String *str);
void split_sum_func(List<Item> &fields); void split_sum_func(List<Item> &fields);
friend int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds); friend int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
bool check_loop(uint id);
}; };
......
...@@ -126,6 +126,22 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -126,6 +126,22 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return 0; return 0;
} }
bool Item_func::check_loop(uint id)
{
DBUG_ENTER("Item_func::check_loop");
if (Item_result_field::check_loop(id))
DBUG_RETURN(1);
if (arg_count)
{
Item **arg,**arg_end;
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
{
if ((*arg)->check_loop(id))
DBUG_RETURN(1);
}
}
DBUG_RETURN(0);
}
void Item_func::split_sum_func(List<Item> &fields) void Item_func::split_sum_func(List<Item> &fields)
{ {
...@@ -2264,6 +2280,19 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) ...@@ -2264,6 +2280,19 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
return 0; return 0;
} }
bool Item_func_match::check_loop(uint id)
{
DBUG_ENTER("Item_func_match::check_loop");
if (Item_real_func::check_loop(id))
DBUG_RETURN(1);
List_iterator<Item> li(fields);
Item *item;
while ((item= li++))
if (item->check_loop(id))
DBUG_RETURN(1);
DBUG_RETURN(0);
}
bool Item_func_match::fix_index() bool Item_func_match::fix_index()
{ {
......
...@@ -128,6 +128,7 @@ public: ...@@ -128,6 +128,7 @@ public:
bool is_null() { (void) val_int(); return null_value; } bool is_null() { (void) val_int(); return null_value; }
friend class udf_handler; friend class udf_handler;
Field *tmp_table_field(TABLE *t_arg); Field *tmp_table_field(TABLE *t_arg);
bool check_loop(uint id);
}; };
...@@ -606,6 +607,13 @@ public: ...@@ -606,6 +607,13 @@ public:
const_item_cache&= item->const_item(); const_item_cache&= item->const_item();
with_sum_func= with_sum_func || item->with_sum_func; with_sum_func= with_sum_func || item->with_sum_func;
} }
bool check_loop(uint id)
{
DBUG_ENTER("Item_func_field::check_loop");
if (Item_int_func::check_loop(id))
DBUG_RETURN(1);
DBUG_RETURN(item->check_loop(id));
}
}; };
...@@ -971,6 +979,7 @@ public: ...@@ -971,6 +979,7 @@ public:
bool fix_index(); bool fix_index();
void init_search(bool no_order); void init_search(bool no_order);
bool check_loop(uint id);
}; };
......
...@@ -105,6 +105,13 @@ public: ...@@ -105,6 +105,13 @@ public:
|| Item_func::fix_fields(thd, tlist, ref)); || Item_func::fix_fields(thd, tlist, ref));
} }
const char *func_name() const { return "concat_ws"; } const char *func_name() const { return "concat_ws"; }
bool check_loop(uint id)
{
DBUG_ENTER("Item_func_concat_ws::check_loop");
if (Item_str_func::check_loop(id))
DBUG_RETURN(1);
DBUG_RETURN(separator->check_loop(id));
}
}; };
class Item_func_reverse :public Item_str_func class Item_func_reverse :public Item_str_func
...@@ -361,6 +368,13 @@ public: ...@@ -361,6 +368,13 @@ public:
void fix_length_and_dec(); void fix_length_and_dec();
void update_used_tables(); void update_used_tables();
const char *func_name() const { return "elt"; } const char *func_name() const { return "elt"; }
bool check_loop(uint id)
{
DBUG_ENTER("Item_func_elt::check_loop");
if (Item_str_func::check_loop(id))
DBUG_RETURN(1);
DBUG_RETURN(item->check_loop(id));
}
}; };
...@@ -381,6 +395,13 @@ public: ...@@ -381,6 +395,13 @@ public:
void fix_length_and_dec(); void fix_length_and_dec();
void update_used_tables(); void update_used_tables();
const char *func_name() const { return "make_set"; } const char *func_name() const { return "make_set"; }
bool check_loop(uint id)
{
DBUG_ENTER("Item_func_make_set::check_loop");
if (Item_str_func::check_loop(id))
DBUG_RETURN(1);
DBUG_RETURN(item->check_loop(id));
}
}; };
......
...@@ -95,6 +95,15 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -95,6 +95,15 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return res; return res;
} }
bool Item_subselect::check_loop(uint id)
{
DBUG_ENTER("Item_subselect::check_loop");
if (Item_result_field::check_loop(id))
DBUG_RETURN(1);
DBUG_RETURN(engine->check_loop(id));
}
void Item_subselect::fix_length_and_dec() void Item_subselect::fix_length_and_dec()
{ {
engine->fix_length_and_dec(); engine->fix_length_and_dec();
...@@ -228,6 +237,7 @@ subselect_single_select_engine::subselect_single_select_engine(THD *thd, ...@@ -228,6 +237,7 @@ subselect_single_select_engine::subselect_single_select_engine(THD *thd,
thd->fatal_error= 1; thd->fatal_error= 1;
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
} }
unit->item= item;
this->select_lex= select_lex; this->select_lex= select_lex;
} }
...@@ -353,3 +363,18 @@ bool subselect_union_engine::depended() ...@@ -353,3 +363,18 @@ bool subselect_union_engine::depended()
{ {
return unit->dependent; return unit->dependent;
} }
bool subselect_single_select_engine::check_loop(uint id)
{
DBUG_ENTER("subselect_single_select_engine::check_loop");
DBUG_RETURN(join->check_loop(id));
}
bool subselect_union_engine::check_loop(uint id)
{
DBUG_ENTER("subselect_union_engine::check_loop");
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
if (sl->join && sl->join->check_loop(id))
DBUG_RETURN(1);
DBUG_RETURN(0);
}
...@@ -70,6 +70,7 @@ public: ...@@ -70,6 +70,7 @@ public:
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref); bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
virtual void fix_length_and_dec(); virtual void fix_length_and_dec();
table_map used_tables() const; table_map used_tables() const;
bool check_loop(uint id);
friend class select_subselect; friend class select_subselect;
}; };
...@@ -176,6 +177,7 @@ public: ...@@ -176,6 +177,7 @@ public:
virtual uint cols()= 0; /* return number of columnss in select */ virtual uint cols()= 0; /* return number of columnss in select */
virtual bool depended()= 0; /* depended from outer select */ virtual bool depended()= 0; /* depended from outer select */
enum Item_result type() { return res_type; } enum Item_result type() { return res_type; }
virtual bool check_loop(uint id)= 0;
}; };
class subselect_single_select_engine: public subselect_engine class subselect_single_select_engine: public subselect_engine
...@@ -189,11 +191,12 @@ public: ...@@ -189,11 +191,12 @@ public:
subselect_single_select_engine(THD *thd, st_select_lex *select, subselect_single_select_engine(THD *thd, st_select_lex *select,
select_subselect *result, select_subselect *result,
Item_subselect *item); Item_subselect *item);
virtual int prepare(); int prepare();
virtual void fix_length_and_dec(); void fix_length_and_dec();
virtual int exec(); int exec();
virtual uint cols(); uint cols();
virtual bool depended(); bool depended();
bool check_loop(uint id);
}; };
class subselect_union_engine: public subselect_engine class subselect_union_engine: public subselect_engine
...@@ -204,9 +207,10 @@ public: ...@@ -204,9 +207,10 @@ public:
st_select_lex_unit *u, st_select_lex_unit *u,
select_subselect *result, select_subselect *result,
Item_subselect *item); Item_subselect *item);
virtual int prepare(); int prepare();
virtual void fix_length_and_dec(); void fix_length_and_dec();
virtual int exec(); int exec();
virtual uint cols(); uint cols();
virtual bool depended(); bool depended();
bool check_loop(uint id);
}; };
...@@ -252,4 +252,5 @@ ...@@ -252,4 +252,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -246,4 +246,5 @@ ...@@ -246,4 +246,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -254,4 +254,5 @@ ...@@ -254,4 +254,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -243,4 +243,5 @@ ...@@ -243,4 +243,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -248,4 +248,5 @@ ...@@ -248,4 +248,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -243,4 +243,5 @@ ...@@ -243,4 +243,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -246,4 +246,5 @@ ...@@ -246,4 +246,5 @@
"Subselect return more than 1 field", "Subselect return more than 1 field",
"Subselect return more than 1 record", "Subselect return more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -243,4 +243,5 @@ ...@@ -243,4 +243,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -245,4 +245,5 @@ ...@@ -245,4 +245,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -243,4 +243,5 @@ ...@@ -243,4 +243,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -245,4 +245,5 @@ ...@@ -245,4 +245,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -243,4 +243,5 @@ ...@@ -243,4 +243,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -245,4 +245,5 @@ ...@@ -245,4 +245,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -245,4 +245,5 @@ ...@@ -245,4 +245,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -247,4 +247,5 @@ ...@@ -247,4 +247,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -243,4 +243,5 @@ ...@@ -243,4 +243,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -247,4 +247,5 @@ ...@@ -247,4 +247,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -246,4 +246,5 @@ ...@@ -246,4 +246,5 @@
" ", " ",
" ", " ",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file " ",
...@@ -239,4 +239,5 @@ ...@@ -239,4 +239,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -251,4 +251,5 @@ ...@@ -251,4 +251,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -244,4 +244,5 @@ ...@@ -244,4 +244,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -243,4 +243,5 @@ ...@@ -243,4 +243,5 @@
"Subselect returns more than 1 field", "Subselect returns more than 1 field",
"Subselect returns more than 1 record", "Subselect returns more than 1 record",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "Cyclic reference on subqueries",
...@@ -248,4 +248,5 @@ ...@@ -248,4 +248,5 @@
"i i i 1 ", "i i i 1 ",
"i i i 1 ", "i i i 1 ",
"Unknown prepared statement handler (%ld) given to %s", "Unknown prepared statement handler (%ld) given to %s",
"Help database is corrupt or does not exist", "Help database is corrupt or does not exist",
\ No newline at end of file "i i",
...@@ -494,6 +494,7 @@ public: ...@@ -494,6 +494,7 @@ public:
uint32 query_length; uint32 query_length;
uint32 db_length; uint32 db_length;
uint select_number; //number of select (used for EXPLAIN) uint select_number; //number of select (used for EXPLAIN)
uint check_loops_counter; //last id used to check loops
/* variables.transaction_isolation is reset to this after each commit */ /* variables.transaction_isolation is reset to this after each commit */
enum_tx_isolation session_tx_isolation; enum_tx_isolation session_tx_isolation;
char scramble[9]; char scramble[9];
......
...@@ -2867,7 +2867,8 @@ mysql_init_query(THD *thd) ...@@ -2867,7 +2867,8 @@ mysql_init_query(THD *thd)
lex->select_lex.prev= &lex->unit.slave; lex->select_lex.prev= &lex->unit.slave;
lex->olap=lex->describe=0; lex->olap=lex->describe=0;
lex->derived_tables= false; lex->derived_tables= false;
thd->select_number= lex->select_lex.select_number= 1; thd->check_loops_counter= thd->select_number=
lex->select_lex.select_number= 1;
thd->free_list= 0; thd->free_list= 0;
thd->total_warn_count=0; // Warnings for this query thd->total_warn_count=0; // Warnings for this query
thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0; thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0;
......
...@@ -1035,6 +1035,24 @@ JOIN::cleanup(THD *thd) ...@@ -1035,6 +1035,24 @@ JOIN::cleanup(THD *thd)
DBUG_RETURN(error); DBUG_RETURN(error);
} }
bool JOIN::check_loop(uint id)
{
DBUG_ENTER("JOIN::check_loop");
Item *item;
List_iterator<Item> it(all_fields);
DBUG_PRINT("info", ("all_fields:"));
while ((item= it++))
if (item->check_loop(id))
DBUG_RETURN(1);
DBUG_PRINT("info", ("where:"));
if (select_lex->where && select_lex->where->check_loop(id))
DBUG_RETURN(1);
DBUG_PRINT("info", ("having:"));
if (select_lex->having && select_lex->having->check_loop(id))
DBUG_RETURN(1);
DBUG_RETURN(0);
}
int int
mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &fields, COND *conds, mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &fields, COND *conds,
ORDER *order, ORDER *group,Item *having, ORDER *proc_param, ORDER *order, ORDER *group,Item *having, ORDER *proc_param,
......
...@@ -244,7 +244,8 @@ class JOIN :public Sql_alloc ...@@ -244,7 +244,8 @@ class JOIN :public Sql_alloc
int global_optimize(); int global_optimize();
int reinit(); int reinit();
void exec(); void exec();
int cleanup(THD *thd); int cleanup(THD *thd);
bool check_loop(uint id);
}; };
......
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