mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
after review changes (SCRUM)
removed outer resolving flag (because of movingtransformation after fix_fields)
This commit is contained in:
46
sql/item.cc
46
sql/item.cc
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
}
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
{
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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();
|
||||
|
Reference in New Issue
Block a user