Commit 5ed5dac0 authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

cyclic reference test removed, becouse testing of Item::fixed field apply more strict limitation

parent 0469dd49
......@@ -122,6 +122,9 @@ SELECT (SELECT 1.5,'c','a') = ROW(1.5,2,'a');
0
SELECT (SELECT * FROM (SELECT 'test' a,'test' b) a);
Cardinality error (more/less than 1 columns)
SELECT 1 as a,(SELECT a+a) b,(SELECT b);
a b (SELECT b)
1 2 2
create table t1 (a int);
create table t2 (a int, b int);
create table t3 (a int);
......
......@@ -54,6 +54,8 @@ SELECT (SELECT 1.5,'c','a') = ROW(1.5,2,'a');
-- error 1239
SELECT (SELECT * FROM (SELECT 'test' a,'test' b) a);
SELECT 1 as a,(SELECT a+a) b,(SELECT b);
create table t1 (a int);
create table t2 (a int, b int);
create table t3 (a int);
......
......@@ -71,19 +71,6 @@ Item_ident::Item_ident(Item_ident &item):
depended_from(item.depended_from)
{}
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);
}
bool Item::check_cols(uint c)
{
if (c != 1)
......@@ -680,7 +667,6 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return 1;
r->depended_from= last;
cursel->mark_as_dependent(last);
thd->add_possible_loop(r);
return 0;
}
else
......@@ -1170,7 +1156,6 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
}
ref= (depended_from= last)->ref_pointer_array + counter-1;
thd->lex.current_select->mark_as_dependent(last);
thd->add_possible_loop(this);
}
}
else if (!ref)
......@@ -1208,14 +1193,6 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
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));
}
bool Item_default_value::eq(const Item *item, bool binary_cmp) const
{
return item->type() == DEFAULT_VALUE_ITEM &&
......
......@@ -92,7 +92,6 @@ class Item {
virtual bool get_date(TIME *ltime,bool fuzzydate);
virtual bool get_time(TIME *ltime);
virtual bool is_null() { return 0; };
virtual bool check_loop(uint id);
virtual void top_level_item() {}
virtual Item * get_same() { return this; }
virtual Item * get_tmp_table_item() { return get_same(); }
......@@ -500,7 +499,6 @@ class Item_ref :public Item_ident
enum Item_result result_type () const { return (*ref)->result_type(); }
enum_field_types field_type() const { return (*ref)->field_type(); }
table_map used_tables() const { return (*ref)->used_tables(); }
bool check_loop(uint id);
};
class Item_in_subselect;
......@@ -689,10 +687,6 @@ class Item_default_value : public Item_field
enum Type type() const { return DEFAULT_VALUE_ITEM; }
bool eq(const Item *item, bool binary_cmp) const;
bool fix_fields(THD *, struct st_table_list *, Item **);
bool check_loop(uint id)
{
return Item_field::check_loop(id) || arg->check_loop(id);
}
void set_outer_resolving() { arg->set_outer_resolving(); }
void print(String *str);
virtual bool basic_const_item() const { return true; }
......
......@@ -925,16 +925,6 @@ void Item_func_case::set_outer_resolving()
Item_func::set_outer_resolving();
}
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()
{
Item_func::update_used_tables();
......@@ -1486,21 +1476,6 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
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::set_outer_resolving()
{
Item_func::set_outer_resolving();
......
......@@ -354,7 +354,6 @@ class Item_func_case :public Item_func
void print(String *str);
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
Item *find_item(String *str);
bool check_loop(uint id);
void set_outer_resolving();
};
......@@ -637,13 +636,6 @@ class Item_func_in :public Item_int_func
const char *func_name() const { return " IN "; }
void update_used_tables();
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
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));
}
bool nulls_in_row();
void set_outer_resolving()
{
......@@ -789,7 +781,6 @@ class Item_cond :public Item_bool_func
void print(String *str);
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
friend int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
bool check_loop(uint id);
void top_level_item() { abort_on_null=1; }
void set_outer_resolving();
};
......
......@@ -128,23 +128,6 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
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::set_outer_resolving()
{
if (arg_count)
......@@ -2365,20 +2348,6 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
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);
}
void Item_func_match::set_outer_resolving()
{
Item_real_func::set_outer_resolving();
......
......@@ -133,7 +133,6 @@ class Item_func :public Item_result_field
friend class udf_handler;
Field *tmp_table_field() { return result_field; }
Field *tmp_table_field(TABLE *t_arg);
bool check_loop(uint id);
void set_outer_resolving();
Item * get_tmp_table_item();
};
......@@ -627,13 +626,6 @@ class Item_func_field :public Item_int_func
const_item_cache&= item->const_item();
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));
}
void set_outer_resolving()
{
item->set_outer_resolving();
......@@ -1013,7 +1005,6 @@ class Item_func_match :public Item_real_func
bool fix_index();
void init_search(bool no_order);
bool check_loop(uint id);
void set_outer_resolving();
};
......
......@@ -120,13 +120,3 @@ void Item_row::set_outer_resolving()
for (uint i= 0; i < arg_count; i++)
items[i]->set_outer_resolving();
}
bool Item_row::check_loop(uint id)
{
if (Item::check_loop(id))
return 1;
for (uint i= 0; i < arg_count; i++)
if (items[i]->check_loop(id))
return 1;
return 0;
}
......@@ -68,7 +68,6 @@ class Item_row: public Item
bool const_item() const { return const_item_cache; };
enum Item_result result_type() const { return ROW_RESULT; }
void update_used_tables();
bool check_loop(uint id);
void set_outer_resolving();
uint cols() { return arg_count; }
......
......@@ -106,13 +106,6 @@ class Item_func_concat_ws :public Item_str_func
Item_func::fix_fields(thd, tlist, ref));
}
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));
}
void set_outer_resolving()
{
separator->set_outer_resolving();
......@@ -389,13 +382,6 @@ class Item_func_elt :public Item_str_func
void fix_length_and_dec();
void update_used_tables();
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));
}
void set_outer_resolving()
{
item->set_outer_resolving();
......@@ -422,13 +408,6 @@ class Item_func_make_set :public Item_str_func
void fix_length_and_dec();
void update_used_tables();
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));
}
void set_outer_resolving()
{
item->set_outer_resolving();
......
......@@ -108,15 +108,6 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
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));
}
Item::Type Item_subselect::type() const
{
return SUBSELECT_ITEM;
......@@ -858,21 +849,6 @@ bool subselect_union_engine::uncacheable()
return unit->uncacheable;
}
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);
}
void subselect_single_select_engine::exclude()
{
select_lex->master_unit()->exclude_level();
......
......@@ -83,7 +83,6 @@ class Item_subselect :public Item_result_field
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
virtual void fix_length_and_dec();
table_map used_tables() const;
bool check_loop(uint id);
friend class select_subselect;
friend class Item_in_optimizer;
......@@ -226,7 +225,6 @@ class subselect_engine: public Sql_alloc
virtual bool dependent()= 0; /* depended from outer select */
virtual bool uncacheable()= 0; /* query is uncacheable */
enum Item_result type() { return res_type; }
virtual bool check_loop(uint id)= 0;
virtual void exclude()= 0;
bool may_be_null() { return maybe_null; };
};
......@@ -248,7 +246,6 @@ class subselect_single_select_engine: public subselect_engine
uint cols();
bool dependent();
bool uncacheable();
bool check_loop(uint id);
void exclude();
};
......@@ -266,6 +263,5 @@ class subselect_union_engine: public subselect_engine
uint cols();
bool dependent();
bool uncacheable();
bool check_loop(uint id);
void exclude();
};
......@@ -479,14 +479,6 @@ void THD::close_active_vio()
}
#endif
void THD::add_possible_loop (Item *item)
{
if (!possible_loops)
{
possible_loops= new List<Item>;
}
possible_loops->push_back(item);
}
/*****************************************************************************
** Functions to provide a interface to select results
......
......@@ -506,7 +506,6 @@ class THD :public ilink {
table_map used_tables;
USER_CONN *user_connect;
CHARSET_INFO *db_charset;
List<Item> *possible_loops; // Items that may cause loops in subselects
List<TABLE> temporary_tables_should_be_free; // list of temporary tables
List <MYSQL_ERROR> warn_list;
uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END];
......@@ -521,7 +520,6 @@ class THD :public ilink {
uint32 query_length;
uint32 db_length;
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 */
enum_tx_isolation session_tx_isolation;
// extend scramble to handle new auth
......@@ -661,8 +659,6 @@ class THD :public ilink {
#else
void clear_error();
#endif
void add_possible_loop(Item *);
};
/*
......
......@@ -3146,18 +3146,16 @@ mysql_init_query(THD *thd)
lex->select_lex.prev= &lex->unit.slave;
lex->select_lex.link_next= lex->select_lex.slave= lex->select_lex.next= 0;
lex->select_lex.link_prev= (st_select_lex_node**)&(lex->all_selects_list);
lex->olap=lex->describe=0;
lex->olap=lex->describe= 0;
lex->derived_tables= false;
lex->lock_option=TL_READ;
lex->found_colon=0;
thd->check_loops_counter= thd->select_number=
lex->select_lex.select_number= 1;
lex->lock_option= TL_READ;
lex->found_colon= 0;
thd->select_number= lex->select_lex.select_number= 1;
thd->free_list= 0;
thd->total_warn_count=0; // Warnings for this query
thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0;
thd->sent_row_count= thd->examined_row_count= 0;
thd->fatal_error= thd->rand_used= 0;
thd->possible_loops= 0;
thd->server_status &= ~SERVER_MORE_RESULTS_EXISTS;
DBUG_VOID_RETURN;
}
......
......@@ -1274,24 +1274,6 @@ JOIN::cleanup(THD *thd)
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
mysql_select(THD *thd, Item ***rref_pointer_array,
TABLE_LIST *tables, uint wild_num, List<Item> &fields,
......@@ -1329,23 +1311,6 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
{
DBUG_RETURN(-1);
}
if (thd->possible_loops)
{
Item *item;
while (thd->possible_loops->elements)
{
item= thd->possible_loops->pop();
if (item->check_loop(thd->check_loops_counter++))
{
delete thd->possible_loops;
thd->possible_loops= 0;
my_message(ER_CYCLIC_REFERENCE, ER(ER_CYCLIC_REFERENCE), MYF(0));
return 1;
}
}
delete thd->possible_loops;
thd->possible_loops= 0;
}
}
if ((err= join->optimize()))
......
......@@ -261,7 +261,6 @@ class JOIN :public Sql_alloc
int reinit();
void exec();
int cleanup(THD *thd);
bool check_loop(uint id);
void restore_tmp();
inline void init_items_ref_array()
......
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