summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/item.cc46
-rw-r--r--sql/item.h8
-rw-r--r--sql/item_cmpfunc.cc16
-rw-r--r--sql/item_cmpfunc.h7
-rw-r--r--sql/item_func.cc17
-rw-r--r--sql/item_func.h7
-rw-r--r--sql/item_row.cc6
-rw-r--r--sql/item_row.h1
-rw-r--r--sql/item_strfunc.h15
-rw-r--r--sql/item_subselect.cc66
-rw-r--r--sql/item_subselect.h14
-rw-r--r--sql/mysql_priv.h21
-rw-r--r--sql/sql_base.cc13
-rw-r--r--sql/sql_lex.cc23
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_union.cc11
17 files changed, 93 insertions, 182 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 703118fb65c..5a3016953bf 100644
--- a/sql/item.cc
+++ b/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;
}
diff --git a/sql/item.h b/sql/item.h
index f5f04b7eb96..7220db0cd5e 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -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)
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 7c4ab46e30d..3c7b68a1adf 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -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);
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index cab3ede6032..da6fcc9a84b 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -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();
};
diff --git a/sql/item_func.cc b/sql/item_func.cc
index d7237f55522..fc1ea7410e4 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -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()
{
diff --git a/sql/item_func.h b/sql/item_func.h
index 9ba5bea8b87..096e5779f5e 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -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();
};
diff --git a/sql/item_row.cc b/sql/item_row.cc
index cf745e21e45..0eaad42873e 100644
--- a/sql/item_row.cc
+++ b/sql/item_row.cc
@@ -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();
-}
diff --git a/sql/item_row.h b/sql/item_row.h
index 4f674d8a561..867225ae953 100644
--- a/sql/item_row.h
+++ b/sql/item_row.h
@@ -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]; }
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 6cc6d730627..0c1cb5a2739 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -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();
- }
};
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 7bbd5bb7f83..01cebb5fc60 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -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,
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 1efdf23d1fc..bf165289cff 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -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
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index aca84f1bcb3..07005a8e140 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -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;
+}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 641ab46e5e0..2fa88e9cfc8 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -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,
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 797aa808187..9b372f6eeda 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -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
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index e8b44d50295..a48aa5721e4 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -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:
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 8c96976c841..ca0f673954e 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -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));
}
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 616f54d7109..79e1e9843a8 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -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();