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 <m_ctype.h>
|
||||||
#include "my_dir.h"
|
#include "my_dir.h"
|
||||||
|
|
||||||
static void mark_as_dependent(bool outer_resolving,
|
static void mark_as_dependent(SELECT_LEX *last, SELECT_LEX_NODE *current,
|
||||||
SELECT_LEX *last, SELECT_LEX_NODE *current,
|
|
||||||
Item_ident *item);
|
Item_ident *item);
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -796,28 +795,17 @@ bool Item_ref_null_helper::get_date(TIME *ltime, bool fuzzydate)
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
mark_as_dependent()
|
mark_as_dependent()
|
||||||
outer_resolving - flag of outer resolving
|
|
||||||
last - select from which current item depend
|
last - select from which current item depend
|
||||||
current - current select
|
current - current select
|
||||||
item - item which should be marked
|
item - item which should be marked
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void mark_as_dependent(bool outer_resolving,
|
static void mark_as_dependent(SELECT_LEX *last, SELECT_LEX_NODE *current,
|
||||||
SELECT_LEX *last, SELECT_LEX_NODE *current,
|
|
||||||
Item_ident *item)
|
Item_ident *item)
|
||||||
{
|
{
|
||||||
/*
|
// store pointer on SELECT_LEX from wich item is dependent
|
||||||
only last check is need, i.e.
|
item->depended_from= last;
|
||||||
"last != current"
|
current->mark_as_dependent(last);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -827,8 +815,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
|||||||
{
|
{
|
||||||
TABLE_LIST *where= 0;
|
TABLE_LIST *where= 0;
|
||||||
Field *tmp= (Field *)not_found_field;
|
Field *tmp= (Field *)not_found_field;
|
||||||
if (outer_resolving ||
|
if ((tmp= find_field_in_tables(thd, this, tables, &where, 0)) ==
|
||||||
(tmp= find_field_in_tables(thd, this, tables, &where, 0)) ==
|
|
||||||
not_found_field)
|
not_found_field)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -849,9 +836,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
|||||||
uint counter;
|
uint counter;
|
||||||
// Prevent using outer fields in subselects, that is not supported now
|
// Prevent using outer fields in subselects, that is not supported now
|
||||||
SELECT_LEX *cursel=(SELECT_LEX *) thd->lex.current_select;
|
SELECT_LEX *cursel=(SELECT_LEX *) thd->lex.current_select;
|
||||||
if (outer_resolving ||
|
if (cursel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE)
|
||||||
cursel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE)
|
for (SELECT_LEX *sl= cursel->outer_select();
|
||||||
for (SELECT_LEX *sl=(outer_resolving?cursel:cursel->outer_select());
|
|
||||||
sl;
|
sl;
|
||||||
sl= sl->outer_select())
|
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))
|
if (rf->fix_fields(thd, tables, ref) || rf->check_cols(1))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
mark_as_dependent(outer_resolving, last, cursel, rf);
|
mark_as_dependent(last, cursel, rf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mark_as_dependent(outer_resolving, last, cursel, this);
|
mark_as_dependent(last, cursel, this);
|
||||||
if (last->having_fix_field)
|
if (last->having_fix_field)
|
||||||
{
|
{
|
||||||
Item_ref *rf;
|
Item_ref *rf;
|
||||||
@ -915,7 +901,6 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
|||||||
(char *)field_name);
|
(char *)field_name);
|
||||||
if (!rf)
|
if (!rf)
|
||||||
return 1;
|
return 1;
|
||||||
(rf)->outer_resolving= outer_resolving;
|
|
||||||
return rf->fix_fields(thd, tables, ref) || rf->check_cols(1);
|
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)
|
if (!ref)
|
||||||
{
|
{
|
||||||
TABLE_LIST *where= 0, *table_list;
|
TABLE_LIST *where= 0, *table_list;
|
||||||
SELECT_LEX *sl= (outer_resolving?
|
SELECT_LEX *sl= thd->lex.current_select->outer_select();
|
||||||
thd->lex.current_select->select_lex():
|
|
||||||
thd->lex.current_select->outer_select());
|
|
||||||
/*
|
/*
|
||||||
Finding only in current select will be performed for selects that have
|
Finding only in current select will be performed for selects that have
|
||||||
not outer one and for derived tables (which not support using outer
|
not outer one and for derived tables (which not support using outer
|
||||||
fields for now)
|
fields for now)
|
||||||
*/
|
*/
|
||||||
if (outer_resolving ||
|
if ((ref= find_item_in_list(this,
|
||||||
(ref= find_item_in_list(this,
|
|
||||||
*(thd->lex.current_select->get_item_list()),
|
*(thd->lex.current_select->get_item_list()),
|
||||||
&counter,
|
&counter,
|
||||||
((sl &&
|
((sl &&
|
||||||
@ -1382,7 +1364,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
|||||||
Item_field* fld;
|
Item_field* fld;
|
||||||
if (!((*reference)= fld= new Item_field(tmp)))
|
if (!((*reference)= fld= new Item_field(tmp)))
|
||||||
return 1;
|
return 1;
|
||||||
mark_as_dependent(outer_resolving, last, thd->lex.current_select, fld);
|
mark_as_dependent(last, thd->lex.current_select, fld);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1393,7 +1375,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
|||||||
"forward reference in item list");
|
"forward reference in item list");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
mark_as_dependent(outer_resolving, last, thd->lex.current_select,
|
mark_as_dependent(last, thd->lex.current_select,
|
||||||
this);
|
this);
|
||||||
ref= last->ref_pointer_array + counter;
|
ref= last->ref_pointer_array + counter;
|
||||||
}
|
}
|
||||||
|
@ -188,8 +188,6 @@ public:
|
|||||||
bool binary() const
|
bool binary() const
|
||||||
{ return charset()->state & MY_CS_BINSORT ? 1 : 0 ; }
|
{ return charset()->state & MY_CS_BINSORT ? 1 : 0 ; }
|
||||||
|
|
||||||
virtual void set_outer_resolving() {}
|
|
||||||
|
|
||||||
// Row emulation
|
// Row emulation
|
||||||
virtual uint cols() { return 1; }
|
virtual uint cols() { return 1; }
|
||||||
virtual Item* el(uint i) { return this; }
|
virtual Item* el(uint i) { return this; }
|
||||||
@ -210,16 +208,14 @@ public:
|
|||||||
const char *table_name;
|
const char *table_name;
|
||||||
const char *field_name;
|
const char *field_name;
|
||||||
st_select_lex *depended_from;
|
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,
|
Item_ident(const char *db_name_par,const char *table_name_par,
|
||||||
const char *field_name_par)
|
const char *field_name_par)
|
||||||
:db_name(db_name_par), table_name(table_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; }
|
{ name = (char*) field_name_par; }
|
||||||
// Constructor used by Item_field & Item_ref (see Item comment)
|
// Constructor used by Item_field & Item_ref (see Item comment)
|
||||||
Item_ident(THD *thd, Item_ident &item);
|
Item_ident(THD *thd, Item_ident &item);
|
||||||
const char *full_name() const;
|
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; }
|
enum Type type() const { return DEFAULT_VALUE_ITEM; }
|
||||||
bool eq(const Item *item, bool binary_cmp) const;
|
bool eq(const Item *item, bool binary_cmp) const;
|
||||||
bool fix_fields(THD *, struct st_table_list *, Item **);
|
bool fix_fields(THD *, struct st_table_list *, Item **);
|
||||||
void set_outer_resolving() { arg->set_outer_resolving(); }
|
|
||||||
void print(String *str);
|
void print(String *str);
|
||||||
virtual bool basic_const_item() const { return true; }
|
virtual bool basic_const_item() const { return true; }
|
||||||
int save_in_field(Field *field, bool no_conversions)
|
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) {}
|
Item_field((const char *)NULL, (const char *)NULL, (const char *)NULL), arg(a) {}
|
||||||
bool eq(const Item *item, bool binary_cmp) const;
|
bool eq(const Item *item, bool binary_cmp) const;
|
||||||
bool fix_fields(THD *, struct st_table_list *, Item **);
|
bool fix_fields(THD *, struct st_table_list *, Item **);
|
||||||
void set_outer_resolving() { arg->set_outer_resolving(); }
|
|
||||||
void print(String *str);
|
void print(String *str);
|
||||||
virtual bool basic_const_item() const { return true; }
|
virtual bool basic_const_item() const { return true; }
|
||||||
int save_in_field(Field *field, bool no_conversions)
|
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()
|
void Item_func_case::update_used_tables()
|
||||||
{
|
{
|
||||||
Item_func::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;
|
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)
|
void Item_cond::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
|
||||||
{
|
{
|
||||||
List_iterator<Item> li(list);
|
List_iterator<Item> li(list);
|
||||||
|
@ -370,7 +370,6 @@ public:
|
|||||||
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
|
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
|
||||||
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
|
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
|
||||||
Item *find_item(String *str);
|
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 update_used_tables();
|
||||||
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
|
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
|
||||||
bool nulls_in_row();
|
bool nulls_in_row();
|
||||||
void set_outer_resolving()
|
|
||||||
{
|
|
||||||
item->set_outer_resolving();
|
|
||||||
Item_int_func::set_outer_resolving();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Functions used by where clause */
|
/* Functions used by where clause */
|
||||||
@ -796,7 +790,6 @@ public:
|
|||||||
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
|
void split_sum_func(Item **ref_pointer_array, 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);
|
||||||
void top_level_item() { abort_on_null=1; }
|
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;
|
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)
|
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;
|
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()
|
bool Item_func_match::fix_index()
|
||||||
{
|
{
|
||||||
|
@ -133,7 +133,6 @@ public:
|
|||||||
friend class udf_handler;
|
friend class udf_handler;
|
||||||
Field *tmp_table_field() { return result_field; }
|
Field *tmp_table_field() { return result_field; }
|
||||||
Field *tmp_table_field(TABLE *t_arg);
|
Field *tmp_table_field(TABLE *t_arg);
|
||||||
void set_outer_resolving();
|
|
||||||
Item *get_tmp_table_item(THD *thd);
|
Item *get_tmp_table_item(THD *thd);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -648,11 +647,6 @@ 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;
|
||||||
}
|
}
|
||||||
void set_outer_resolving()
|
|
||||||
{
|
|
||||||
item->set_outer_resolving();
|
|
||||||
Item_int_func::set_outer_resolving();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1030,7 +1024,6 @@ public:
|
|||||||
|
|
||||||
bool fix_index();
|
bool fix_index();
|
||||||
void init_search(bool no_order);
|
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++)
|
for (uint i= 0; i < arg_count; i++)
|
||||||
items[i]->bring_value();
|
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; };
|
bool const_item() const { return const_item_cache; };
|
||||||
enum Item_result result_type() const { return ROW_RESULT; }
|
enum Item_result result_type() const { return ROW_RESULT; }
|
||||||
void update_used_tables();
|
void update_used_tables();
|
||||||
void set_outer_resolving();
|
|
||||||
|
|
||||||
uint cols() { return arg_count; }
|
uint cols() { return arg_count; }
|
||||||
Item* el(uint i) { return items[i]; }
|
Item* el(uint i) { return items[i]; }
|
||||||
|
@ -107,11 +107,6 @@ public:
|
|||||||
}
|
}
|
||||||
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
|
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
|
||||||
const char *func_name() const { return "concat_ws"; }
|
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
|
class Item_func_reverse :public Item_str_func
|
||||||
@ -390,11 +385,6 @@ 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"; }
|
||||||
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 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"; }
|
||||||
void set_outer_resolving()
|
|
||||||
{
|
|
||||||
item->set_outer_resolving();
|
|
||||||
Item_str_func::set_outer_resolving();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,9 +20,6 @@
|
|||||||
SUBSELECT TODO:
|
SUBSELECT TODO:
|
||||||
- add function from mysql_select that use JOIN* as parameter to JOIN methods
|
- add function from mysql_select that use JOIN* as parameter to JOIN methods
|
||||||
(sql_select.h/sql_select.cc)
|
(sql_select.h/sql_select.cc)
|
||||||
- remove double 'having' & 'having_list' from JOIN
|
|
||||||
(sql_select.h/sql_select.cc)
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
@ -72,8 +69,7 @@ Item_subselect::~Item_subselect()
|
|||||||
}
|
}
|
||||||
|
|
||||||
Item_subselect::trans_res
|
Item_subselect::trans_res
|
||||||
Item_subselect::select_transformer(THD *thd,
|
Item_subselect::select_transformer(JOIN *join)
|
||||||
JOIN *join)
|
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Item_subselect::select_transformer");
|
DBUG_ENTER("Item_subselect::select_transformer");
|
||||||
DBUG_RETURN(OK);
|
DBUG_RETURN(OK);
|
||||||
@ -169,8 +165,7 @@ void Item_singlerow_subselect::reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
Item_subselect::trans_res
|
Item_subselect::trans_res
|
||||||
Item_singlerow_subselect::select_transformer(THD *thd,
|
Item_singlerow_subselect::select_transformer(JOIN *join)
|
||||||
JOIN *join)
|
|
||||||
{
|
{
|
||||||
SELECT_LEX *select_lex= join->select_lex;
|
SELECT_LEX *select_lex= join->select_lex;
|
||||||
|
|
||||||
@ -190,15 +185,14 @@ Item_singlerow_subselect::select_transformer(THD *thd,
|
|||||||
{
|
{
|
||||||
|
|
||||||
have_to_be_excluded= 1;
|
have_to_be_excluded= 1;
|
||||||
if (thd->lex.describe)
|
if (join->thd->lex.describe)
|
||||||
{
|
{
|
||||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||||
sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
|
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);
|
ER_SELECT_REDUCED, warn_buff);
|
||||||
}
|
}
|
||||||
substitution= select_lex->item_list.head();
|
substitution= select_lex->item_list.head();
|
||||||
substitution->set_outer_resolving();
|
|
||||||
|
|
||||||
if (select_lex->where || select_lex->having)
|
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)
|
bool Item_in_subselect::test_limit(SELECT_LEX_UNIT *unit)
|
||||||
{
|
{
|
||||||
SELECT_LEX_NODE *global= unit->global_parameters;
|
if (unit->global_parameters == unit &&
|
||||||
if (global->select_limit != HA_POS_ERROR)
|
unit->global_parameters->test_limit())
|
||||||
{
|
|
||||||
my_error(ER_NOT_SUPPORTED_YET, MYF(0),
|
|
||||||
"LIMIT & IN/ALL/ANY/SOME subquery");
|
|
||||||
return(1);
|
return(1);
|
||||||
}
|
|
||||||
SELECT_LEX *sl= unit->first_select();
|
SELECT_LEX *sl= unit->first_select();
|
||||||
for (; sl; sl= sl->next_select())
|
for (; sl; sl= sl->next_select())
|
||||||
{
|
{
|
||||||
if (sl->select_limit != HA_POS_ERROR)
|
if (sl->test_limit())
|
||||||
{
|
|
||||||
my_error(ER_NOT_SUPPORTED_YET, MYF(0),
|
|
||||||
"LIMIT & IN/ALL/ANY/SOME subquery");
|
|
||||||
return(1);
|
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);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,6 +355,7 @@ Item_in_subselect::Item_in_subselect(THD *thd, Item * left_exp,
|
|||||||
maybe_null= 1;
|
maybe_null= 1;
|
||||||
abort_on_null= 0;
|
abort_on_null= 0;
|
||||||
reset();
|
reset();
|
||||||
|
//if test_limit will fail then error will be reported to client
|
||||||
test_limit(select_lex->master_unit());
|
test_limit(select_lex->master_unit());
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
@ -393,6 +372,7 @@ Item_allany_subselect::Item_allany_subselect(THD *thd, Item * left_exp,
|
|||||||
max_columns= 1;
|
max_columns= 1;
|
||||||
abort_on_null= 0;
|
abort_on_null= 0;
|
||||||
reset();
|
reset();
|
||||||
|
//if test_limit will fail then error will be reported to client
|
||||||
test_limit(select_lex->master_unit());
|
test_limit(select_lex->master_unit());
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
@ -493,8 +473,7 @@ Item_allany_subselect::Item_allany_subselect(Item_allany_subselect *item):
|
|||||||
}
|
}
|
||||||
|
|
||||||
Item_subselect::trans_res
|
Item_subselect::trans_res
|
||||||
Item_in_subselect::single_value_transformer(THD *thd,
|
Item_in_subselect::single_value_transformer(JOIN *join,
|
||||||
JOIN *join,
|
|
||||||
Item *left_expr,
|
Item *left_expr,
|
||||||
compare_func_creator func)
|
compare_func_creator func)
|
||||||
{
|
{
|
||||||
@ -502,6 +481,7 @@ Item_in_subselect::single_value_transformer(THD *thd,
|
|||||||
|
|
||||||
SELECT_LEX *select_lex= join->select_lex;
|
SELECT_LEX *select_lex= join->select_lex;
|
||||||
|
|
||||||
|
THD *thd= join->thd;
|
||||||
thd->where= "scalar IN/ALL/ANY subquery";
|
thd->where= "scalar IN/ALL/ANY subquery";
|
||||||
|
|
||||||
if (!substitution)
|
if (!substitution)
|
||||||
@ -538,8 +518,8 @@ Item_in_subselect::single_value_transformer(THD *thd,
|
|||||||
my_error(ER_CARDINALITY_COL, MYF(0), 1);
|
my_error(ER_CARDINALITY_COL, MYF(0), 1);
|
||||||
DBUG_RETURN(ERROR);
|
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 ||
|
if (join->having || select_lex->with_sum_func ||
|
||||||
select_lex->group_list.elements)
|
select_lex->group_list.elements)
|
||||||
@ -657,12 +637,12 @@ Item_in_subselect::single_value_transformer(THD *thd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Item_subselect::trans_res
|
Item_subselect::trans_res
|
||||||
Item_in_subselect::row_value_transformer(THD *thd,
|
Item_in_subselect::row_value_transformer(JOIN *join,
|
||||||
JOIN *join,
|
Item *left_expr)
|
||||||
Item *left_expr)
|
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Item_in_subselect::row_value_transformer");
|
DBUG_ENTER("Item_in_subselect::row_value_transformer");
|
||||||
|
|
||||||
|
THD *thd= join->thd;
|
||||||
thd->where= "row IN/ALL/ANY subquery";
|
thd->where= "row IN/ALL/ANY subquery";
|
||||||
|
|
||||||
SELECT_LEX *select_lex= join->select_lex;
|
SELECT_LEX *select_lex= join->select_lex;
|
||||||
@ -730,20 +710,18 @@ Item_in_subselect::row_value_transformer(THD *thd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Item_subselect::trans_res
|
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)
|
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);
|
&Item_bool_func2::eq_creator);
|
||||||
else
|
return row_value_transformer(join, left_expr);
|
||||||
return row_value_transformer(thd, join, left_expr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item_subselect::trans_res
|
Item_subselect::trans_res
|
||||||
Item_allany_subselect::select_transformer(THD *thd,
|
Item_allany_subselect::select_transformer(JOIN *join)
|
||||||
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,
|
subselect_single_select_engine::subselect_single_select_engine(THD *thd,
|
||||||
|
@ -75,7 +75,7 @@ public:
|
|||||||
{
|
{
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
}
|
}
|
||||||
virtual trans_res select_transformer(THD *thd, JOIN *join);
|
virtual trans_res select_transformer(JOIN *join);
|
||||||
bool assigned() { return value_assigned; }
|
bool assigned() { return value_assigned; }
|
||||||
void assigned(bool a) { value_assigned= a; }
|
void assigned(bool a) { value_assigned= a; }
|
||||||
enum Type type() const;
|
enum Type type() const;
|
||||||
@ -117,7 +117,7 @@ public:
|
|||||||
decimals= item->decimals;
|
decimals= item->decimals;
|
||||||
}
|
}
|
||||||
void reset();
|
void reset();
|
||||||
trans_res select_transformer(THD *thd, JOIN *join);
|
trans_res select_transformer(JOIN *join);
|
||||||
void store(uint i, Item* item);
|
void store(uint i, Item* item);
|
||||||
double val();
|
double val();
|
||||||
longlong val_int ();
|
longlong val_int ();
|
||||||
@ -174,7 +174,7 @@ class Item_in_subselect :public Item_exists_subselect
|
|||||||
protected:
|
protected:
|
||||||
Item * left_expr;
|
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
|
all JOIN in UNION
|
||||||
*/
|
*/
|
||||||
Item *expr;
|
Item *expr;
|
||||||
@ -191,11 +191,11 @@ public:
|
|||||||
null_value= 0;
|
null_value= 0;
|
||||||
was_null= 0;
|
was_null= 0;
|
||||||
}
|
}
|
||||||
trans_res select_transformer(THD *thd, JOIN *join);
|
trans_res select_transformer(JOIN *join);
|
||||||
trans_res single_value_transformer(THD *thd, JOIN *join,
|
trans_res single_value_transformer(JOIN *join,
|
||||||
Item *left_expr,
|
Item *left_expr,
|
||||||
compare_func_creator func);
|
compare_func_creator func);
|
||||||
trans_res row_value_transformer(THD *thd, JOIN * join,
|
trans_res row_value_transformer(JOIN * join,
|
||||||
Item *left_expr);
|
Item *left_expr);
|
||||||
longlong val_int();
|
longlong val_int();
|
||||||
double val();
|
double val();
|
||||||
@ -218,7 +218,7 @@ public:
|
|||||||
Item_allany_subselect(THD *thd, Item * left_expr, compare_func_creator f,
|
Item_allany_subselect(THD *thd, Item * left_expr, compare_func_creator f,
|
||||||
st_select_lex *select_lex);
|
st_select_lex *select_lex);
|
||||||
Item_allany_subselect(Item_allany_subselect *item);
|
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
|
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_lt_creator(bool invert);
|
||||||
compare_func_creator comp_ne_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 ;
|
for (TABLE_LIST *table_list=tables ; table_list ;
|
||||||
table_list=table_list->next,tablenr++)
|
table_list=table_list->next,tablenr++)
|
||||||
{
|
{
|
||||||
TABLE *table=table_list->table;
|
TABLE *table= table_list->table;
|
||||||
|
setup_table_map(table, table_list, 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->used_keys= table->keys_for_keyread;
|
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)
|
if (table_list->use_index)
|
||||||
{
|
{
|
||||||
key_map map= get_key_map_from_key_list(table,
|
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;
|
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
|
Interface method of table list creation for query
|
||||||
|
@ -256,6 +256,8 @@ public:
|
|||||||
virtual void set_lock_for_tables(thr_lock_type lock_type) {}
|
virtual void set_lock_for_tables(thr_lock_type lock_type) {}
|
||||||
void mark_as_dependent(st_select_lex *last);
|
void mark_as_dependent(st_select_lex *last);
|
||||||
|
|
||||||
|
bool test_limit();
|
||||||
|
|
||||||
friend class st_select_lex_unit;
|
friend class st_select_lex_unit;
|
||||||
friend bool mysql_new_select(struct st_lex *lex, bool move_down);
|
friend bool mysql_new_select(struct st_lex *lex, bool move_down);
|
||||||
private:
|
private:
|
||||||
|
@ -321,7 +321,7 @@ JOIN::prepare(Item ***rref_pointer_array,
|
|||||||
!select_lex->fake_select)
|
!select_lex->fake_select)
|
||||||
{
|
{
|
||||||
Item_subselect::trans_res res;
|
Item_subselect::trans_res res;
|
||||||
if ((res= subselect->select_transformer(thd, this)) !=
|
if ((res= subselect->select_transformer(this)) !=
|
||||||
Item_subselect::OK)
|
Item_subselect::OK)
|
||||||
DBUG_RETURN((res == Item_subselect::ERROR));
|
DBUG_RETURN((res == Item_subselect::ERROR));
|
||||||
}
|
}
|
||||||
|
@ -291,16 +291,7 @@ int st_select_lex_unit::exec()
|
|||||||
setup_table
|
setup_table
|
||||||
*/
|
*/
|
||||||
DBUG_PRINT("SUBS", ("shared %s", table_list->real_name));
|
DBUG_PRINT("SUBS", ("shared %s", table_list->real_name));
|
||||||
TABLE *table= table_list->table;
|
setup_table_map(table_list->table, table_list, 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res= sl->join->optimize();
|
res= sl->join->optimize();
|
||||||
|
Reference in New Issue
Block a user