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

after review changes (SCRUM)

removed outer resolving flag (because of movingtransformation after fix_fields)
parent 100a101a
......@@ -23,8 +23,7 @@
#include <m_ctype.h>
#include "my_dir.h"
static void mark_as_dependent(bool outer_resolving,
SELECT_LEX *last, SELECT_LEX_NODE *current,
static void mark_as_dependent(SELECT_LEX *last, SELECT_LEX_NODE *current,
Item_ident *item);
/*****************************************************************************
......@@ -796,28 +795,17 @@ bool Item_ref_null_helper::get_date(TIME *ltime, bool fuzzydate)
SYNOPSIS
mark_as_dependent()
outer_resolving - flag of outer resolving
last - select from which current item depend
current - current select
item - item which should be marked
*/
static void mark_as_dependent(bool outer_resolving,
SELECT_LEX *last, SELECT_LEX_NODE *current,
static void mark_as_dependent(SELECT_LEX *last, SELECT_LEX_NODE *current,
Item_ident *item)
{
/*
only last check is need, i.e.
"last != current"
first check added for speed up (check boolean should be faster
then comparing pointers and this condition usually true)
*/
if (!outer_resolving || ((SELECT_LEX_NODE *)last) != current)
{
// store pointer on SELECT_LEX from wich item is dependent
item->depended_from= last;
current->mark_as_dependent(last);
}
// store pointer on SELECT_LEX from wich item is dependent
item->depended_from= last;
current->mark_as_dependent(last);
}
......@@ -827,8 +815,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{
TABLE_LIST *where= 0;
Field *tmp= (Field *)not_found_field;
if (outer_resolving ||
(tmp= find_field_in_tables(thd, this, tables, &where, 0)) ==
if ((tmp= find_field_in_tables(thd, this, tables, &where, 0)) ==
not_found_field)
{
/*
......@@ -849,9 +836,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
uint counter;
// Prevent using outer fields in subselects, that is not supported now
SELECT_LEX *cursel=(SELECT_LEX *) thd->lex.current_select;
if (outer_resolving ||
cursel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE)
for (SELECT_LEX *sl=(outer_resolving?cursel:cursel->outer_select());
if (cursel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE)
for (SELECT_LEX *sl= cursel->outer_select();
sl;
sl= sl->outer_select())
{
......@@ -901,12 +887,12 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
if (rf->fix_fields(thd, tables, ref) || rf->check_cols(1))
return 1;
mark_as_dependent(outer_resolving, last, cursel, rf);
mark_as_dependent(last, cursel, rf);
return 0;
}
else
{
mark_as_dependent(outer_resolving, last, cursel, this);
mark_as_dependent(last, cursel, this);
if (last->having_fix_field)
{
Item_ref *rf;
......@@ -915,7 +901,6 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
(char *)field_name);
if (!rf)
return 1;
(rf)->outer_resolving= outer_resolving;
return rf->fix_fields(thd, tables, ref) || rf->check_cols(1);
}
}
......@@ -1309,16 +1294,13 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
if (!ref)
{
TABLE_LIST *where= 0, *table_list;
SELECT_LEX *sl= (outer_resolving?
thd->lex.current_select->select_lex():
thd->lex.current_select->outer_select());
SELECT_LEX *sl= thd->lex.current_select->outer_select();
/*
Finding only in current select will be performed for selects that have
not outer one and for derived tables (which not support using outer
fields for now)
*/
if (outer_resolving ||
(ref= find_item_in_list(this,
if ((ref= find_item_in_list(this,
*(thd->lex.current_select->get_item_list()),
&counter,
((sl &&
......@@ -1382,7 +1364,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
Item_field* fld;
if (!((*reference)= fld= new Item_field(tmp)))
return 1;
mark_as_dependent(outer_resolving, last, thd->lex.current_select, fld);
mark_as_dependent(last, thd->lex.current_select, fld);
return 0;
}
else
......@@ -1393,7 +1375,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
"forward reference in item list");
return -1;
}
mark_as_dependent(outer_resolving, last, thd->lex.current_select,
mark_as_dependent(last, thd->lex.current_select,
this);
ref= last->ref_pointer_array + counter;
}
......
......@@ -188,8 +188,6 @@ class Item {
bool binary() const
{ return charset()->state & MY_CS_BINSORT ? 1 : 0 ; }
virtual void set_outer_resolving() {}
// Row emulation
virtual uint cols() { return 1; }
virtual Item* el(uint i) { return this; }
......@@ -210,16 +208,14 @@ class Item_ident :public Item
const char *table_name;
const char *field_name;
st_select_lex *depended_from;
bool outer_resolving; /* used for items from reduced subselect */
Item_ident(const char *db_name_par,const char *table_name_par,
const char *field_name_par)
:db_name(db_name_par), table_name(table_name_par),
field_name(field_name_par), depended_from(0), outer_resolving(0)
field_name(field_name_par), depended_from(0)
{ name = (char*) field_name_par; }
// Constructor used by Item_field & Item_ref (see Item comment)
Item_ident(THD *thd, Item_ident &item);
const char *full_name() const;
void set_outer_resolving() { outer_resolving= 1; }
};
......@@ -825,7 +821,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 **);
void set_outer_resolving() { arg->set_outer_resolving(); }
void print(String *str);
virtual bool basic_const_item() const { return true; }
int save_in_field(Field *field, bool no_conversions)
......@@ -848,7 +843,6 @@ class Item_insert_value : public Item_field
Item_field((const char *)NULL, (const char *)NULL, (const char *)NULL), arg(a) {}
bool eq(const Item *item, bool binary_cmp) const;
bool fix_fields(THD *, struct st_table_list *, Item **);
void set_outer_resolving() { arg->set_outer_resolving(); }
void print(String *str);
virtual bool basic_const_item() const { return true; }
int save_in_field(Field *field, bool no_conversions)
......
......@@ -1094,13 +1094,6 @@ void Item_func_case::split_sum_func(Item **ref_pointer_array,
}
void Item_func_case::set_outer_resolving()
{
first_expr->set_outer_resolving();
else_expr->set_outer_resolving();
Item_func::set_outer_resolving();
}
void Item_func_case::update_used_tables()
{
Item_func::update_used_tables();
......@@ -1669,15 +1662,6 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return 0;
}
void Item_cond::set_outer_resolving()
{
Item_func::set_outer_resolving();
List_iterator<Item> li(list);
Item *item;
while ((item= li++))
item->set_outer_resolving();
}
void Item_cond::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
{
List_iterator<Item> li(list);
......
......@@ -370,7 +370,6 @@ class Item_func_case :public Item_func
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
Item *find_item(String *str);
void set_outer_resolving();
};
......@@ -633,11 +632,6 @@ class Item_func_in :public Item_int_func
void update_used_tables();
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
bool nulls_in_row();
void set_outer_resolving()
{
item->set_outer_resolving();
Item_int_func::set_outer_resolving();
}
};
/* Functions used by where clause */
......@@ -796,7 +790,6 @@ class Item_cond :public Item_bool_func
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
friend int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
void top_level_item() { abort_on_null=1; }
void set_outer_resolving();
};
......
......@@ -136,15 +136,6 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return 0;
}
void Item_func::set_outer_resolving()
{
if (arg_count)
{
Item **arg,**arg_end;
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
(*arg)->set_outer_resolving();
}
}
void Item_func::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
{
......@@ -2443,14 +2434,6 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
return 0;
}
void Item_func_match::set_outer_resolving()
{
Item_real_func::set_outer_resolving();
List_iterator<Item> li(fields);
Item *item;
while ((item= li++))
item->set_outer_resolving();
}
bool Item_func_match::fix_index()
{
......
......@@ -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);
void set_outer_resolving();
Item *get_tmp_table_item(THD *thd);
};
......@@ -648,11 +647,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;
}
void set_outer_resolving()
{
item->set_outer_resolving();
Item_int_func::set_outer_resolving();
}
};
......@@ -1030,7 +1024,6 @@ class Item_func_match :public Item_real_func
bool fix_index();
void init_search(bool no_order);
void set_outer_resolving();
};
......
......@@ -123,9 +123,3 @@ void Item_row::bring_value()
for (uint i= 0; i < arg_count; i++)
items[i]->bring_value();
}
void Item_row::set_outer_resolving()
{
for (uint i= 0; i < arg_count; i++)
items[i]->set_outer_resolving();
}
......@@ -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();
void set_outer_resolving();
uint cols() { return arg_count; }
Item* el(uint i) { return items[i]; }
......
......@@ -107,11 +107,6 @@ class Item_func_concat_ws :public Item_str_func
}
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
const char *func_name() const { return "concat_ws"; }
void set_outer_resolving()
{
separator->set_outer_resolving();
Item_func::set_outer_resolving();
}
};
class Item_func_reverse :public Item_str_func
......@@ -390,11 +385,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"; }
void set_outer_resolving()
{
item->set_outer_resolving();
Item_str_func::set_outer_resolving();
}
};
......@@ -417,11 +407,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"; }
void set_outer_resolving()
{
item->set_outer_resolving();
Item_str_func::set_outer_resolving();
}
};
......
......@@ -20,9 +20,6 @@
SUBSELECT TODO:
- add function from mysql_select that use JOIN* as parameter to JOIN methods
(sql_select.h/sql_select.cc)
- remove double 'having' & 'having_list' from JOIN
(sql_select.h/sql_select.cc)
*/
#ifdef __GNUC__
......@@ -72,8 +69,7 @@ Item_subselect::~Item_subselect()
}
Item_subselect::trans_res
Item_subselect::select_transformer(THD *thd,
JOIN *join)
Item_subselect::select_transformer(JOIN *join)
{
DBUG_ENTER("Item_subselect::select_transformer");
DBUG_RETURN(OK);
......@@ -169,8 +165,7 @@ void Item_singlerow_subselect::reset()
}
Item_subselect::trans_res
Item_singlerow_subselect::select_transformer(THD *thd,
JOIN *join)
Item_singlerow_subselect::select_transformer(JOIN *join)
{
SELECT_LEX *select_lex= join->select_lex;
......@@ -190,15 +185,14 @@ Item_singlerow_subselect::select_transformer(THD *thd,
{
have_to_be_excluded= 1;
if (thd->lex.describe)
if (join->thd->lex.describe)
{
char warn_buff[MYSQL_ERRMSG_SIZE];
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
push_warning(join->thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_SELECT_REDUCED, warn_buff);
}
substitution= select_lex->item_list.head();
substitution->set_outer_resolving();
if (select_lex->where || select_lex->having)
{
......@@ -337,32 +331,16 @@ Item_exists_subselect::Item_exists_subselect(THD *thd,
bool Item_in_subselect::test_limit(SELECT_LEX_UNIT *unit)
{
SELECT_LEX_NODE *global= unit->global_parameters;
if (global->select_limit != HA_POS_ERROR)
{
my_error(ER_NOT_SUPPORTED_YET, MYF(0),
"LIMIT & IN/ALL/ANY/SOME subquery");
if (unit->global_parameters == unit &&
unit->global_parameters->test_limit())
return(1);
}
SELECT_LEX *sl= unit->first_select();
for (; sl; sl= sl->next_select())
{
if (sl->select_limit != HA_POS_ERROR)
{
my_error(ER_NOT_SUPPORTED_YET, MYF(0),
"LIMIT & IN/ALL/ANY/SOME subquery");
if (sl->test_limit())
return(1);
}
// We need only 1 row to determinate existence
sl->select_limit= 1;
// no sense in ORDER BY without LIMIT
sl->order_list.empty();
}
// no sense in ORDER BY without LIMIT
global->order_list.empty();
// We need only 1 row to determinate existence
global->select_limit= 1;
return(0);
}
......@@ -377,6 +355,7 @@ Item_in_subselect::Item_in_subselect(THD *thd, Item * left_exp,
maybe_null= 1;
abort_on_null= 0;
reset();
//if test_limit will fail then error will be reported to client
test_limit(select_lex->master_unit());
DBUG_VOID_RETURN;
}
......@@ -393,6 +372,7 @@ Item_allany_subselect::Item_allany_subselect(THD *thd, Item * left_exp,
max_columns= 1;
abort_on_null= 0;
reset();
//if test_limit will fail then error will be reported to client
test_limit(select_lex->master_unit());
DBUG_VOID_RETURN;
}
......@@ -493,8 +473,7 @@ Item_allany_subselect::Item_allany_subselect(Item_allany_subselect *item):
}
Item_subselect::trans_res
Item_in_subselect::single_value_transformer(THD *thd,
JOIN *join,
Item_in_subselect::single_value_transformer(JOIN *join,
Item *left_expr,
compare_func_creator func)
{
......@@ -502,6 +481,7 @@ Item_in_subselect::single_value_transformer(THD *thd,
SELECT_LEX *select_lex= join->select_lex;
THD *thd= join->thd;
thd->where= "scalar IN/ALL/ANY subquery";
if (!substitution)
......@@ -538,8 +518,8 @@ Item_in_subselect::single_value_transformer(THD *thd,
my_error(ER_CARDINALITY_COL, MYF(0), 1);
DBUG_RETURN(ERROR);
}
else
item= (Item*) select_lex->item_list.head();
item= (Item*) select_lex->item_list.head();
if (join->having || select_lex->with_sum_func ||
select_lex->group_list.elements)
......@@ -657,12 +637,12 @@ Item_in_subselect::single_value_transformer(THD *thd,
}
Item_subselect::trans_res
Item_in_subselect::row_value_transformer(THD *thd,
JOIN *join,
Item *left_expr)
Item_in_subselect::row_value_transformer(JOIN *join,
Item *left_expr)
{
DBUG_ENTER("Item_in_subselect::row_value_transformer");
THD *thd= join->thd;
thd->where= "row IN/ALL/ANY subquery";
SELECT_LEX *select_lex= join->select_lex;
......@@ -730,20 +710,18 @@ Item_in_subselect::row_value_transformer(THD *thd,
}
Item_subselect::trans_res
Item_in_subselect::select_transformer(THD *thd, JOIN *join)
Item_in_subselect::select_transformer(JOIN *join)
{
if (left_expr->cols() == 1)
return single_value_transformer(thd, join, left_expr,
return single_value_transformer(join, left_expr,
&Item_bool_func2::eq_creator);
else
return row_value_transformer(thd, join, left_expr);
return row_value_transformer(join, left_expr);
}
Item_subselect::trans_res
Item_allany_subselect::select_transformer(THD *thd,
JOIN *join)
Item_allany_subselect::select_transformer(JOIN *join)
{
return single_value_transformer(thd, join, left_expr, func);
return single_value_transformer(join, left_expr, func);
}
subselect_single_select_engine::subselect_single_select_engine(THD *thd,
......
......@@ -75,7 +75,7 @@ class Item_subselect :public Item_result_field
{
null_value= 1;
}
virtual trans_res select_transformer(THD *thd, JOIN *join);
virtual trans_res select_transformer(JOIN *join);
bool assigned() { return value_assigned; }
void assigned(bool a) { value_assigned= a; }
enum Type type() const;
......@@ -117,7 +117,7 @@ class Item_singlerow_subselect :public Item_subselect
decimals= item->decimals;
}
void reset();
trans_res select_transformer(THD *thd, JOIN *join);
trans_res select_transformer(JOIN *join);
void store(uint i, Item* item);
double val();
longlong val_int ();
......@@ -174,7 +174,7 @@ class Item_in_subselect :public Item_exists_subselect
protected:
Item * left_expr;
/*
expr & optinizer used in subselect rewriting to store Item for
expr & optimizer used in subselect rewriting to store Item for
all JOIN in UNION
*/
Item *expr;
......@@ -191,11 +191,11 @@ class Item_in_subselect :public Item_exists_subselect
null_value= 0;
was_null= 0;
}
trans_res select_transformer(THD *thd, JOIN *join);
trans_res single_value_transformer(THD *thd, JOIN *join,
trans_res select_transformer(JOIN *join);
trans_res single_value_transformer(JOIN *join,
Item *left_expr,
compare_func_creator func);
trans_res row_value_transformer(THD *thd, JOIN * join,
trans_res row_value_transformer(JOIN * join,
Item *left_expr);
longlong val_int();
double val();
......@@ -218,7 +218,7 @@ class Item_allany_subselect :public Item_in_subselect
Item_allany_subselect(THD *thd, Item * left_expr, compare_func_creator f,
st_select_lex *select_lex);
Item_allany_subselect(Item_allany_subselect *item);
trans_res select_transformer(THD *thd, JOIN *join);
trans_res select_transformer(JOIN *join);
};
class subselect_engine: public Sql_alloc
......
......@@ -943,3 +943,24 @@ compare_func_creator comp_le_creator(bool invert);
compare_func_creator comp_lt_creator(bool invert);
compare_func_creator comp_ne_creator(bool invert);
/*
clean/setup table fields and map
SYNOPSYS
setup_table_map()
table - TABLE structure pointer (which should be setup)
table_list TABLE_LIST structure pointer (owner of TABLE)
tablenr - table number
*/
inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
{
table->used_fields= 0;
table->const_table= 0;
table->outer_join= table->null_row= 0;
table->status= STATUS_NO_RECORD;
table->keys_in_use_for_query= table->keys_in_use;
table->maybe_null= test(table->outer_join= table_list->outer_join);
table->tablenr= tablenr;
table->map= (table_map) 1 << tablenr;
table->force_index= table_list->force_index;
}
......@@ -2019,18 +2019,9 @@ bool setup_tables(TABLE_LIST *tables)
for (TABLE_LIST *table_list=tables ; table_list ;
table_list=table_list->next,tablenr++)
{
TABLE *table=table_list->table;
table->used_fields=0;
table->const_table=0;
table->outer_join=table->null_row=0;
table->status=STATUS_NO_RECORD;
table->keys_in_use_for_query= table->keys_in_use;
TABLE *table= table_list->table;
setup_table_map(table, table_list, tablenr);
table->used_keys= table->keys_for_keyread;
table->maybe_null=test(table->outer_join=table_list->outer_join);
table->tablenr=tablenr;
table->map= (table_map) 1 << tablenr;
table->force_index= table_list->force_index;
if (table_list->use_index)
{
key_map map= get_key_map_from_key_list(table,
......
......@@ -1209,8 +1209,29 @@ TABLE_LIST *st_select_lex_node::add_table_to_list(THD *thd, Table_ident *table,
{
return 0;
}
ulong st_select_lex_node::get_table_join_options() { return 0; }
ulong st_select_lex_node::get_table_join_options()
{
return 0;
}
/*
prohibit using LIMIT clause
*/
bool st_select_lex_node::test_limit()
{
if (select_limit != HA_POS_ERROR)
{
my_error(ER_NOT_SUPPORTED_YET, MYF(0),
"LIMIT & IN/ALL/ANY/SOME subquery");
return(1);
}
// We need only 1 row to determinate existence
select_limit= 1;
// no sense in ORDER BY without LIMIT
order_list.empty();
return(0);
}
/*
Interface method of table list creation for query
......
......@@ -256,6 +256,8 @@ class st_select_lex_node {
virtual void set_lock_for_tables(thr_lock_type lock_type) {}
void mark_as_dependent(st_select_lex *last);
bool test_limit();
friend class st_select_lex_unit;
friend bool mysql_new_select(struct st_lex *lex, bool move_down);
private:
......
......@@ -321,7 +321,7 @@ JOIN::prepare(Item ***rref_pointer_array,
!select_lex->fake_select)
{
Item_subselect::trans_res res;
if ((res= subselect->select_transformer(thd, this)) !=
if ((res= subselect->select_transformer(this)) !=
Item_subselect::OK)
DBUG_RETURN((res == Item_subselect::ERROR));
}
......
......@@ -291,16 +291,7 @@ int st_select_lex_unit::exec()
setup_table
*/
DBUG_PRINT("SUBS", ("shared %s", table_list->real_name));
TABLE *table= table_list->table;
table->used_fields=0;
table->const_table=0;
table->outer_join=table->null_row=0;
table->status=STATUS_NO_RECORD;
table->keys_in_use_for_query= table->keys_in_use;
table->maybe_null=test(table->outer_join=table_list->outer_join);
table->tablenr=tablenr;
table->map= (table_map) 1 << tablenr;
table->force_index= table_list->force_index;
setup_table_map(table_list->table, table_list, tablenr);
}
}
res= sl->join->optimize();
......
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