mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
merging
mysql-test/r/subselect.result: Auto merged sql/item.cc: Auto merged sql/mysql_priv.h: Auto merged sql/sql_base.cc: Auto merged sql/sql_derived.cc: Auto merged sql/sql_lex.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_show.cc: Auto merged sql/sql_table.cc: Auto merged
This commit is contained in:
@@ -1,13 +1,32 @@
|
||||
select (select 2);
|
||||
(select 2)
|
||||
2
|
||||
explain select (select 2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1247 Select 2 was reduced during optimisation
|
||||
SELECT (SELECT 1) UNION SELECT (SELECT 2);
|
||||
(SELECT 1)
|
||||
1
|
||||
2
|
||||
explain SELECT (SELECT 1) UNION SELECT (SELECT 2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1247 Select 2 was reduced during optimisation
|
||||
Note 1247 Select 4 was reduced during optimisation
|
||||
SELECT (SELECT (SELECT 0 UNION SELECT 0));
|
||||
(SELECT (SELECT 0 UNION SELECT 0))
|
||||
0
|
||||
explain SELECT (SELECT (SELECT 0 UNION SELECT 0));
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
3 SUBSELECT NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1247 Select 2 was reduced during optimisation
|
||||
SELECT (SELECT 1 FROM (SELECT 1) as b HAVING a=1) as a;
|
||||
Reference 'a' not supported (forward reference in item list)
|
||||
SELECT (SELECT 1 FROM (SELECT 1) as b HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) as c HAVING a=1) as b;
|
||||
@@ -20,8 +39,9 @@ Reference 'a' not supported (forward reference in item list)
|
||||
EXPLAIN SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
|
||||
3 DEPENDENT SUBSELECT NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1247 Select 3 was reduced during optimisation
|
||||
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
||||
1
|
||||
1
|
||||
@@ -629,6 +649,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t ref id id 5 const 1 Using where; Using index
|
||||
3 SUBSELECT NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1247 Select 3 was reduced during optimisation
|
||||
Note 1247 Select 2 was reduced during optimisation
|
||||
EXPLAIN SELECT * FROM t WHERE id IN (SELECT 1 UNION SELECT 3);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
@@ -752,6 +773,16 @@ NULL
|
||||
select 10.5 > ANY (SELECT * from t);
|
||||
10.5 > ANY (SELECT * from t)
|
||||
1
|
||||
explain select (select a+1) from t;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t ALL NULL NULL NULL NULL 3
|
||||
Warnings:
|
||||
Note 1247 Select 2 was reduced during optimisation
|
||||
select (select a+1) from t;
|
||||
(select a+1)
|
||||
2.5
|
||||
NULL
|
||||
4.5
|
||||
drop table t;
|
||||
create table t (a float);
|
||||
select 10.5 IN (SELECT * from t LIMIT 1);
|
||||
|
@@ -1,6 +1,9 @@
|
||||
select (select 2);
|
||||
explain select (select 2);
|
||||
SELECT (SELECT 1) UNION SELECT (SELECT 2);
|
||||
explain SELECT (SELECT 1) UNION SELECT (SELECT 2);
|
||||
SELECT (SELECT (SELECT 0 UNION SELECT 0));
|
||||
explain SELECT (SELECT (SELECT 0 UNION SELECT 0));
|
||||
-- error 1245
|
||||
SELECT (SELECT 1 FROM (SELECT 1) as b HAVING a=1) as a;
|
||||
-- error 1245
|
||||
@@ -424,6 +427,8 @@ select 1.5 > ALL (SELECT * from t);
|
||||
select 10.5 > ALL (SELECT * from t);
|
||||
select 1.5 > ANY (SELECT * from t);
|
||||
select 10.5 > ANY (SELECT * from t);
|
||||
explain select (select a+1) from t;
|
||||
select (select a+1) from t;
|
||||
drop table t;
|
||||
|
||||
#LIMIT is not supported now
|
||||
@@ -432,7 +437,9 @@ create table t (a float);
|
||||
select 10.5 IN (SELECT * from t LIMIT 1);
|
||||
-- error 1235
|
||||
select 10.5 IN (SELECT * from t LIMIT 1 UNION SELECT 1.5);
|
||||
drop table t;create table t1 (a int, b int, c varchar(10));
|
||||
drop table t;
|
||||
|
||||
create table t1 (a int, b int, c varchar(10));
|
||||
create table t2 (a int);
|
||||
insert into t1 values (1,2,'a'),(2,3,'b'),(3,4,'c');
|
||||
insert into t2 values (1),(2),(NULL);
|
||||
|
@@ -12,12 +12,14 @@ int GTextReadStream::get_next_toc_type() const
|
||||
return eostream;
|
||||
}
|
||||
|
||||
if(((*cur>='a') && (*cur<='z')) || ((*cur>='A') && (*cur<='Z')) || (*cur=='_'))
|
||||
if (((*cur>='a') && (*cur<='z')) || ((*cur>='A') && (*cur<='Z')) ||
|
||||
(*cur=='_'))
|
||||
{
|
||||
return word;
|
||||
}
|
||||
|
||||
if(((*cur>='0') && (*cur<='9')) || (*cur=='-') || (*cur=='+') || (*cur=='.'))
|
||||
if (((*cur>='0') && (*cur<='9')) || (*cur=='-') || (*cur=='+') ||
|
||||
(*cur=='.'))
|
||||
{
|
||||
return numeric;
|
||||
}
|
||||
@@ -63,8 +65,8 @@ const char *GTextReadStream::get_next_word(int *word_len)
|
||||
|
||||
++cur;
|
||||
|
||||
while(((*cur>='a') && (*cur<='z')) || ((*cur>='A') && (*cur<='Z')) || (*cur=='_') ||
|
||||
((*cur>='0') && (*cur<='9')))
|
||||
while (((*cur>='a') && (*cur<='z')) || ((*cur>='A') && (*cur<='Z')) ||
|
||||
(*cur=='_') || ((*cur>='0') && (*cur<='9')))
|
||||
{
|
||||
++cur;
|
||||
}
|
||||
|
74
sql/item.cc
74
sql/item.cc
@@ -502,18 +502,17 @@ bool Item_ref_on_list_position::fix_fields(THD *thd,
|
||||
struct st_table_list *tables,
|
||||
Item ** reference)
|
||||
{
|
||||
ref= 0;
|
||||
List_iterator<Item> li(list);
|
||||
Item *item;
|
||||
uint i= 0;
|
||||
for (; (item= li++) && i < pos; i++);
|
||||
if (i == pos)
|
||||
for (uint i= 0; (item= li++) && i < pos; i++);
|
||||
if (item)
|
||||
{
|
||||
ref= li.ref();
|
||||
return Item_ref_null_helper::fix_fields(thd, tables, reference);
|
||||
}
|
||||
else
|
||||
{
|
||||
ref= 0;
|
||||
my_error(ER_CARDINALITY_COL, MYF(0), pos);
|
||||
return 1;
|
||||
}
|
||||
@@ -546,8 +545,11 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
{
|
||||
if (!field) // If field is not checked
|
||||
{
|
||||
Field *tmp;
|
||||
if ((tmp= find_field_in_tables(thd, this, tables, 0)) == not_found_field)
|
||||
TABLE_LIST *where= 0;
|
||||
Field *tmp= (Field *)not_found_field;
|
||||
if (outer_resolving ||
|
||||
(tmp= find_field_in_tables(thd, this, tables, &where, 0)) ==
|
||||
not_found_field)
|
||||
{
|
||||
/*
|
||||
We can't find table field in table list of current select,
|
||||
@@ -564,12 +566,12 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
// Prevent using outer fields in subselects, that is not supported now
|
||||
SELECT_LEX *cursel=(SELECT_LEX *) thd->lex.current_select;
|
||||
if (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->outer_select())
|
||||
{
|
||||
if ((tmp= find_field_in_tables(thd, this,
|
||||
(last= sl)->get_table_list(),
|
||||
(last= sl)->get_table_list(), &where,
|
||||
0)) != not_found_field)
|
||||
break;
|
||||
if ((refer= find_item_in_list(this, sl->item_list,
|
||||
@@ -587,7 +589,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
else if (tmp == not_found_field && refer == (Item **)not_found_item)
|
||||
{
|
||||
// call to return error code
|
||||
find_field_in_tables(thd, this, tables, 1);
|
||||
find_field_in_tables(thd, this, tables, &where, 1);
|
||||
return -1;
|
||||
}
|
||||
else if (refer != (Item **)not_found_item)
|
||||
@@ -612,6 +614,17 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
found table as depended (of select where was found table)
|
||||
*/
|
||||
thd->lex.current_select->mark_as_dependent(last);
|
||||
if (depended_from->having_fix_field)
|
||||
{
|
||||
Item_ref *rf;
|
||||
*ref= rf= new Item_ref((where->db[0]?where->db:0),
|
||||
(char *)where->alias,
|
||||
(char *)field_name);
|
||||
if (!rf)
|
||||
return 1;
|
||||
(rf)->outer_resolving= outer_resolving;
|
||||
return rf->check_cols(1) || rf->fix_fields(thd, tables, ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!tmp)
|
||||
@@ -627,14 +640,6 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
table->used_fields++;
|
||||
table->used_keys&=field->part_of_key;
|
||||
}
|
||||
if (depended_from != 0 && depended_from->having_fix_field)
|
||||
{
|
||||
*ref= new Item_ref((char *)db_name, (char *)table_name,
|
||||
(char *)field_name);
|
||||
if (!*ref)
|
||||
return 1;
|
||||
return (*ref)->check_cols(1) || (*ref)->fix_fields(thd, tables, ref);
|
||||
}
|
||||
fixed= 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -1005,13 +1010,17 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
{
|
||||
if (!ref)
|
||||
{
|
||||
SELECT_LEX *sl= thd->lex.current_select->outer_select();
|
||||
TABLE_LIST *where= 0;
|
||||
SELECT_LEX *sl= (outer_resolving?
|
||||
thd->lex.current_select->select_lex():
|
||||
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 ((ref= find_item_in_list(this,
|
||||
if (outer_resolving ||
|
||||
(ref= find_item_in_list(this,
|
||||
*(thd->lex.current_select->get_item_list()),
|
||||
((sl &&
|
||||
thd->lex.current_select->master_unit()->
|
||||
@@ -1039,7 +1048,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
(Item **)not_found_item)
|
||||
break;
|
||||
if ((tmp= find_field_in_tables(thd, this,
|
||||
sl->get_table_list(),
|
||||
sl->get_table_list(), &where,
|
||||
0)) != not_found_field);
|
||||
if (sl->master_unit()->first_select()->linkage ==
|
||||
DERIVED_TABLE_TYPE)
|
||||
@@ -1268,29 +1277,20 @@ longlong Item_cache_str::val_int()
|
||||
|
||||
bool Item_cache_row::allocate(uint num)
|
||||
{
|
||||
n= num;
|
||||
item_count= num;
|
||||
THD *thd= current_thd;
|
||||
if (!(values= (Item_cache **) thd->calloc(sizeof(Item_cache *)*n)))
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
thd->fatal_error= 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return (!(values=
|
||||
(Item_cache **) thd->calloc(sizeof(Item_cache *)*item_count)));
|
||||
}
|
||||
|
||||
bool Item_cache_row::setup(Item * item)
|
||||
{
|
||||
if (!values && allocate(item->cols()))
|
||||
return 1;
|
||||
for(uint i= 0; i < n; i++)
|
||||
for (uint i= 0; i < item_count; i++)
|
||||
{
|
||||
if (!(values[i]= Item_cache::get_cache(item->el(i)->result_type())))
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
current_thd->fatal_error= 1;
|
||||
return 1;
|
||||
}
|
||||
values[i]->setup(item->el(i));
|
||||
}
|
||||
return 0;
|
||||
@@ -1300,7 +1300,7 @@ void Item_cache_row::store(Item * item)
|
||||
{
|
||||
null_value= 0;
|
||||
item->bring_value();
|
||||
for(uint i= 0; i < n; i++)
|
||||
for (uint i= 0; i < item_count; i++)
|
||||
{
|
||||
values[i]->store(item->el(i));
|
||||
null_value|= values[i]->null_value;
|
||||
@@ -1318,7 +1318,7 @@ void Item_cache_row::illegal_method_call(const char *method)
|
||||
|
||||
bool Item_cache_row::check_cols(uint c)
|
||||
{
|
||||
if (c != n)
|
||||
if (c != item_count)
|
||||
{
|
||||
my_error(ER_CARDINALITY_COL, MYF(0), c);
|
||||
return 1;
|
||||
@@ -1328,7 +1328,7 @@ bool Item_cache_row::check_cols(uint c)
|
||||
|
||||
bool Item_cache_row::null_inside()
|
||||
{
|
||||
for (uint i= 0; i < n; i++)
|
||||
for (uint i= 0; i < item_count; i++)
|
||||
{
|
||||
if (values[i]->cols() > 1)
|
||||
{
|
||||
@@ -1347,7 +1347,7 @@ bool Item_cache_row::null_inside()
|
||||
|
||||
void Item_cache_row::bring_value()
|
||||
{
|
||||
for (uint i= 0; i < n; i++)
|
||||
for (uint i= 0; i < item_count; i++)
|
||||
values[i]->bring_value();
|
||||
return;
|
||||
}
|
||||
|
11
sql/item.h
11
sql/item.h
@@ -96,6 +96,7 @@ public:
|
||||
CHARSET_INFO *thd_charset() const;
|
||||
CHARSET_INFO *charset() const { return str_value.charset(); };
|
||||
void set_charset(CHARSET_INFO *cs) { str_value.set_charset(cs); }
|
||||
virtual void set_outer_resolving() {}
|
||||
|
||||
// Row emulation
|
||||
virtual uint cols() { return 1; }
|
||||
@@ -117,12 +118,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)
|
||||
field_name(field_name_par), depended_from(0), outer_resolving(0)
|
||||
{ name = (char*) field_name_par; }
|
||||
const char *full_name() const;
|
||||
void set_outer_resolving() { outer_resolving= 1; }
|
||||
};
|
||||
|
||||
|
||||
@@ -728,9 +731,9 @@ public:
|
||||
class Item_cache_row: public Item_cache
|
||||
{
|
||||
Item_cache **values;
|
||||
uint n;
|
||||
uint item_count;
|
||||
public:
|
||||
Item_cache_row(): values(0), n(2) { fixed= 1; null_value= 1; }
|
||||
Item_cache_row(): values(0), item_count(2) { fixed= 1; null_value= 1; }
|
||||
|
||||
/*
|
||||
'allocate' used only in row transformer, to preallocate space for row
|
||||
@@ -765,7 +768,7 @@ public:
|
||||
};
|
||||
enum Item_result result_type() const { return ROW_RESULT; }
|
||||
|
||||
uint cols() { return n; }
|
||||
uint cols() { return item_count; }
|
||||
Item* el(uint i) { return values[i]; }
|
||||
Item** addr(uint i) { return (Item **) (values + i); }
|
||||
bool check_cols(uint c);
|
||||
|
@@ -153,12 +153,8 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
|
||||
comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
|
||||
}
|
||||
else
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
current_thd->fatal_error= 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -276,11 +272,7 @@ int Arg_comparator::compare_e_row()
|
||||
|
||||
bool Item_in_optimizer::preallocate_row()
|
||||
{
|
||||
if ((cache= Item_cache::get_cache(ROW_RESULT)))
|
||||
return 0;
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
current_thd->fatal_error= 1;
|
||||
return 1;
|
||||
return (!(cache= Item_cache::get_cache(ROW_RESULT)));
|
||||
}
|
||||
|
||||
bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables,
|
||||
@@ -296,11 +288,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables,
|
||||
used_tables_cache= args[0]->used_tables();
|
||||
const_item_cache= args[0]->const_item();
|
||||
if (!cache && !(cache= Item_cache::get_cache(args[0]->result_type())))
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
thd->fatal_error= 1;
|
||||
return 1;
|
||||
}
|
||||
cache->setup(args[0]);
|
||||
if (args[1]->fix_fields(thd, tables, args))
|
||||
return 1;
|
||||
@@ -946,6 +934,13 @@ Item_func_case::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Item_func_case::set_outer_resolving()
|
||||
{
|
||||
first_expr->set_outer_resolving();
|
||||
else_expr->set_outer_resolving();
|
||||
Item_func::set_outer_resolving();
|
||||
}
|
||||
|
||||
bool Item_func_case::check_loop(uint id)
|
||||
{
|
||||
DBUG_ENTER("Item_func_case::check_loop");
|
||||
@@ -1239,19 +1234,11 @@ void cmp_item_row::store_value(Item *item)
|
||||
item->null_value|= item->el(i)->null_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
thd->fatal_error= 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
thd->fatal_error= 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void cmp_item_row::store_value_by_template(cmp_item *t, Item *item)
|
||||
{
|
||||
@@ -1274,19 +1261,11 @@ void cmp_item_row::store_value_by_template(cmp_item *t, Item *item)
|
||||
item->null_value|= item->el(i)->null_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
current_thd->fatal_error= 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
current_thd->fatal_error= 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int cmp_item_row::cmp(Item *arg)
|
||||
{
|
||||
@@ -1523,6 +1502,15 @@ bool Item_cond::check_loop(uint id)
|
||||
DBUG_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(List<Item> &fields)
|
||||
{
|
||||
List_iterator<Item> li(list);
|
||||
|
@@ -277,6 +277,11 @@ public:
|
||||
const char *func_name() const { return "interval"; }
|
||||
void update_used_tables();
|
||||
bool check_loop(uint id);
|
||||
void set_outer_resolving()
|
||||
{
|
||||
item->set_outer_resolving();
|
||||
Item_func::set_outer_resolving();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -359,6 +364,7 @@ public:
|
||||
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
|
||||
Item *find_item(String *str);
|
||||
bool check_loop(uint id);
|
||||
void set_outer_resolving();
|
||||
};
|
||||
|
||||
|
||||
@@ -643,6 +649,11 @@ class Item_func_in :public Item_int_func
|
||||
DBUG_RETURN(item->check_loop(id));
|
||||
}
|
||||
bool nulls_in_row();
|
||||
void set_outer_resolving()
|
||||
{
|
||||
item->set_outer_resolving();
|
||||
Item_int_func::set_outer_resolving();
|
||||
}
|
||||
};
|
||||
|
||||
/* Functions used by where clause */
|
||||
@@ -784,6 +795,7 @@ public:
|
||||
friend int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
|
||||
bool check_loop(uint id);
|
||||
void top_level_item() { abort_on_null=1; }
|
||||
void set_outer_resolving();
|
||||
};
|
||||
|
||||
|
||||
|
@@ -146,6 +146,16 @@ bool Item_func::check_loop(uint id)
|
||||
DBUG_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(List<Item> &fields)
|
||||
{
|
||||
Item **arg,**arg_end;
|
||||
@@ -2356,6 +2366,15 @@ bool Item_func_match::check_loop(uint id)
|
||||
DBUG_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()
|
||||
{
|
||||
List_iterator_fast<Item> li(fields);
|
||||
|
@@ -133,6 +133,7 @@ public:
|
||||
friend class udf_handler;
|
||||
Field *tmp_table_field(TABLE *t_arg);
|
||||
bool check_loop(uint id);
|
||||
void set_outer_resolving();
|
||||
};
|
||||
|
||||
|
||||
@@ -632,6 +633,11 @@ public:
|
||||
DBUG_RETURN(1);
|
||||
DBUG_RETURN(item->check_loop(id));
|
||||
}
|
||||
void set_outer_resolving()
|
||||
{
|
||||
item->set_outer_resolving();
|
||||
Item_int_func::set_outer_resolving();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1006,6 +1012,7 @@ public:
|
||||
bool fix_index();
|
||||
void init_search(bool no_order);
|
||||
bool check_loop(uint id);
|
||||
void set_outer_resolving();
|
||||
};
|
||||
|
||||
|
||||
|
@@ -105,5 +105,20 @@ void Item_row::bring_value()
|
||||
{
|
||||
for (uint i= 0; i < arg_count; i++)
|
||||
items[i]->bring_value();
|
||||
return;
|
||||
}
|
||||
|
||||
void Item_row::set_outer_resolving()
|
||||
{
|
||||
for (uint i= 0; i < arg_count; i++)
|
||||
items[i]->set_outer_resolving();
|
||||
}
|
||||
|
||||
bool Item_row::check_loop(uint id)
|
||||
{
|
||||
if (Item::check_loop(id))
|
||||
return 1;
|
||||
for (uint i= 0; i < arg_count; i++)
|
||||
if (items[i]->check_loop(id))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@@ -64,6 +64,8 @@ public:
|
||||
bool const_item() const { return const_item_cache; };
|
||||
enum Item_result result_type() const { return ROW_RESULT; }
|
||||
void update_used_tables();
|
||||
bool check_loop(uint id);
|
||||
void set_outer_resolving();
|
||||
|
||||
uint cols() { return arg_count; }
|
||||
Item* el(uint i) { return items[i]; }
|
||||
|
@@ -116,6 +116,11 @@ public:
|
||||
DBUG_RETURN(1);
|
||||
DBUG_RETURN(separator->check_loop(id));
|
||||
}
|
||||
void set_outer_resolving()
|
||||
{
|
||||
separator->set_outer_resolving();
|
||||
Item_func::set_outer_resolving();
|
||||
}
|
||||
};
|
||||
|
||||
class Item_func_reverse :public Item_str_func
|
||||
@@ -393,6 +398,11 @@ public:
|
||||
DBUG_RETURN(1);
|
||||
DBUG_RETURN(item->check_loop(id));
|
||||
}
|
||||
void set_outer_resolving()
|
||||
{
|
||||
item->set_outer_resolving();
|
||||
Item_str_func::set_outer_resolving();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -421,6 +431,11 @@ public:
|
||||
DBUG_RETURN(1);
|
||||
DBUG_RETURN(item->check_loop(id));
|
||||
}
|
||||
void set_outer_resolving()
|
||||
{
|
||||
item->set_outer_resolving();
|
||||
Item_str_func::set_outer_resolving();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@@ -32,6 +32,11 @@ SUBSELECT TODO:
|
||||
#include "mysql_priv.h"
|
||||
#include "sql_select.h"
|
||||
|
||||
inline Item * and_items(Item* cond, Item *item)
|
||||
{
|
||||
return (cond? (new Item_cond_and(cond, item)) : item);
|
||||
}
|
||||
|
||||
Item_subselect::Item_subselect():
|
||||
Item_result_field(), engine_owner(1), value_assigned(0), substitution(0),
|
||||
have_to_be_excluded(0)
|
||||
@@ -51,7 +56,7 @@ void Item_subselect::init(THD *thd, st_select_lex *select_lex,
|
||||
DBUG_ENTER("Item_subselect::init");
|
||||
DBUG_PRINT("subs", ("select_lex 0x%xl", (ulong) select_lex));
|
||||
|
||||
select_transformer(select_lex->master_unit());
|
||||
select_transformer(thd, select_lex->master_unit());
|
||||
if (select_lex->next_select())
|
||||
engine= new subselect_union_engine(thd, select_lex->master_unit(), result,
|
||||
this);
|
||||
@@ -67,7 +72,7 @@ Item_subselect::~Item_subselect()
|
||||
delete engine;
|
||||
}
|
||||
|
||||
void Item_subselect::select_transformer(st_select_lex_unit *unit)
|
||||
void Item_subselect::select_transformer(THD *thd, st_select_lex_unit *unit)
|
||||
{
|
||||
DBUG_ENTER("Item_subselect::select_transformer");
|
||||
DBUG_VOID_RETURN;
|
||||
@@ -146,6 +151,46 @@ void Item_singlerow_subselect::reset()
|
||||
value->null_value= 1;
|
||||
}
|
||||
|
||||
void Item_singlerow_subselect::select_transformer(THD *thd,
|
||||
st_select_lex_unit *unit)
|
||||
{
|
||||
SELECT_LEX *select_lex= unit->first_select();
|
||||
|
||||
if (!select_lex->next_select() && !select_lex->table_list.elements &&
|
||||
select_lex->item_list.elements == 1)
|
||||
{
|
||||
|
||||
have_to_be_excluded= 1;
|
||||
if (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,
|
||||
ER_SELECT_REDUCED, warn_buff);
|
||||
}
|
||||
substitution= select_lex->item_list.head();
|
||||
substitution->set_outer_resolving();
|
||||
if (substitution->type() == FIELD_ITEM ||
|
||||
substitution->type() == REF_ITEM)
|
||||
name= substitution->name; // Save name for correct resolving
|
||||
|
||||
if (select_lex->where || select_lex->having)
|
||||
{
|
||||
Item *cond;
|
||||
if (!select_lex->having)
|
||||
cond= select_lex->where;
|
||||
else if (!select_lex->where)
|
||||
cond= select_lex->having;
|
||||
else
|
||||
if (!(cond= new Item_cond_and(select_lex->having, select_lex->where)))
|
||||
return;
|
||||
if (!(substitution= new Item_func_if(cond, substitution,
|
||||
new Item_null())))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Item_singlerow_subselect::store(uint i, Item *item)
|
||||
{
|
||||
row[i]->store(item);
|
||||
@@ -162,21 +207,13 @@ void Item_singlerow_subselect::fix_length_and_dec()
|
||||
{
|
||||
engine->fix_length_and_dec(row= &value);
|
||||
if (!(value= Item_cache::get_cache(engine->type())))
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
current_thd->fatal_error= 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
if (!(row= (Item_cache**)thd->alloc(sizeof(Item_cache*)*max_columns)))
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
thd->fatal_error= 1;
|
||||
return;
|
||||
}
|
||||
engine->fix_length_and_dec(row);
|
||||
value= *row;
|
||||
}
|
||||
@@ -395,7 +432,8 @@ Item_allany_subselect::Item_allany_subselect(Item_allany_subselect *item):
|
||||
func= item->func;
|
||||
}
|
||||
|
||||
void Item_in_subselect::single_value_transformer(st_select_lex_unit *unit,
|
||||
void Item_in_subselect::single_value_transformer(THD *thd,
|
||||
st_select_lex_unit *unit,
|
||||
Item *left_expr,
|
||||
compare_func_creator func)
|
||||
{
|
||||
@@ -409,10 +447,8 @@ void Item_in_subselect::single_value_transformer(st_select_lex_unit *unit,
|
||||
Item_in_optimizer *optimizer;
|
||||
substitution= optimizer= new Item_in_optimizer(left_expr, this);
|
||||
if (!optimizer)
|
||||
{
|
||||
current_thd->fatal_error= 1;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
As far as Item_ref_in_optimizer do not substitude itself on fix_fields
|
||||
we can use same item for all selects.
|
||||
@@ -449,15 +485,9 @@ void Item_in_subselect::single_value_transformer(st_select_lex_unit *unit,
|
||||
(char *)"<no matter>",
|
||||
(char*)"<result>"));
|
||||
if (sl->having || sl->with_sum_func || sl->group_list.first)
|
||||
if (sl->having)
|
||||
sl->having= new Item_cond_and(sl->having, item);
|
||||
sl->having= and_items(sl->having, item);
|
||||
else
|
||||
sl->having= item;
|
||||
else
|
||||
if (sl->where)
|
||||
sl->where= new Item_cond_and(sl->where, item);
|
||||
else
|
||||
sl->where= item;
|
||||
sl->where= and_items(sl->where, item);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -468,10 +498,7 @@ void Item_in_subselect::single_value_transformer(st_select_lex_unit *unit,
|
||||
item= (*func)(expr, new Item_asterisk_remover(this, item,
|
||||
(char *)"<no matter>",
|
||||
(char*)"<result>"));
|
||||
if (sl->where)
|
||||
sl->where= new Item_cond_and(sl->where, item);
|
||||
else
|
||||
sl->where= item;
|
||||
sl->where= and_items(sl->where, item);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -498,7 +525,6 @@ void Item_in_subselect::single_value_transformer(st_select_lex_unit *unit,
|
||||
item= (*func)(left_expr, item);
|
||||
substitution= item;
|
||||
have_to_be_excluded= 1;
|
||||
THD *thd= current_thd;
|
||||
if (thd->lex.describe)
|
||||
{
|
||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||
@@ -513,7 +539,8 @@ void Item_in_subselect::single_value_transformer(st_select_lex_unit *unit,
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void Item_in_subselect::row_value_transformer(st_select_lex_unit *unit,
|
||||
void Item_in_subselect::row_value_transformer(THD *thd,
|
||||
st_select_lex_unit *unit,
|
||||
Item *left_expr)
|
||||
{
|
||||
DBUG_ENTER("Item_in_subselect::row_value_transformer");
|
||||
@@ -527,10 +554,8 @@ void Item_in_subselect::row_value_transformer(st_select_lex_unit *unit,
|
||||
Item_in_optimizer *optimizer;
|
||||
substitution= optimizer= new Item_in_optimizer(left_expr, this);
|
||||
if (!optimizer)
|
||||
{
|
||||
current_thd->fatal_error= 1;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
unit->dependent= 1;
|
||||
uint n= left_expr->cols();
|
||||
if (optimizer->preallocate_row() || (*optimizer->get_cache())->allocate(n))
|
||||
@@ -560,40 +585,32 @@ void Item_in_subselect::row_value_transformer(st_select_lex_unit *unit,
|
||||
(char *)"<no matter>",
|
||||
(char *)"<left expr>"),
|
||||
func);
|
||||
if (!item)
|
||||
item= func;
|
||||
else
|
||||
item= new Item_cond_and(item, func);
|
||||
item= and_items(item, func);
|
||||
}
|
||||
|
||||
if (sl->having || sl->with_sum_func || sl->group_list.first ||
|
||||
!sl->table_list.elements)
|
||||
if (sl->having)
|
||||
sl->having= new Item_cond_and(sl->having, item);
|
||||
sl->having= and_items(sl->having, item);
|
||||
else
|
||||
sl->having= item;
|
||||
else
|
||||
if (sl->where)
|
||||
sl->where= new Item_cond_and(sl->where, item);
|
||||
else
|
||||
sl->where= item;
|
||||
sl->where= and_items(sl->where, item);
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
void Item_in_subselect::select_transformer(st_select_lex_unit *unit)
|
||||
void Item_in_subselect::select_transformer(THD *thd, st_select_lex_unit *unit)
|
||||
{
|
||||
if (left_expr->cols() == 1)
|
||||
single_value_transformer(unit, left_expr,
|
||||
single_value_transformer(thd, unit, left_expr,
|
||||
&Item_bool_func2::eq_creator);
|
||||
else
|
||||
row_value_transformer(unit, left_expr);
|
||||
row_value_transformer(thd, unit, left_expr);
|
||||
}
|
||||
|
||||
void Item_allany_subselect::select_transformer(st_select_lex_unit *unit)
|
||||
void Item_allany_subselect::select_transformer(THD *thd,
|
||||
st_select_lex_unit *unit)
|
||||
{
|
||||
single_value_transformer(unit, left_expr, func);
|
||||
single_value_transformer(thd, unit, left_expr, func);
|
||||
}
|
||||
|
||||
subselect_single_select_engine::subselect_single_select_engine(THD *thd,
|
||||
@@ -678,11 +695,7 @@ static Item_result set_row(SELECT_LEX *select_lex, Item * item,
|
||||
if (row)
|
||||
{
|
||||
if (!(row[i]= Item_cache::get_cache(res_type)))
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
current_thd->fatal_error= 1;
|
||||
return STRING_RESULT; // we should return something
|
||||
}
|
||||
row[i]->set_len_n_dec(sel_item->max_length, sel_item->decimals);
|
||||
}
|
||||
}
|
||||
@@ -715,7 +728,7 @@ void subselect_union_engine::fix_length_and_dec(Item_cache **row)
|
||||
mlen= len;
|
||||
if (!sel_item)
|
||||
sel_item= s_item;
|
||||
maybe_null!= s_item->maybe_null;
|
||||
maybe_null= s_item->maybe_null;
|
||||
}
|
||||
item->max_length= mlen;
|
||||
res_type= sel_item->result_type();
|
||||
@@ -723,11 +736,7 @@ void subselect_union_engine::fix_length_and_dec(Item_cache **row)
|
||||
if (row)
|
||||
{
|
||||
if (!(row[0]= Item_cache::get_cache(res_type)))
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
current_thd->fatal_error= 1;
|
||||
return;
|
||||
}
|
||||
row[0]->set_len_n_dec(mlen, sel_item->decimals);
|
||||
}
|
||||
}
|
||||
|
@@ -71,7 +71,7 @@ public:
|
||||
{
|
||||
null_value= 1;
|
||||
}
|
||||
virtual void select_transformer(st_select_lex_unit *unit);
|
||||
virtual void select_transformer(THD *thd, st_select_lex_unit *unit);
|
||||
bool assigned() { return value_assigned; }
|
||||
void assigned(bool a) { value_assigned= a; }
|
||||
enum Type type() const;
|
||||
@@ -106,6 +106,7 @@ public:
|
||||
decimals= item->decimals;
|
||||
}
|
||||
void reset();
|
||||
void select_transformer(THD *thd, st_select_lex_unit *unit);
|
||||
void store(uint i, Item* item);
|
||||
double val();
|
||||
longlong val_int ();
|
||||
@@ -172,10 +173,11 @@ public:
|
||||
null_value= 0;
|
||||
was_null= 0;
|
||||
}
|
||||
virtual void select_transformer(st_select_lex_unit *unit);
|
||||
void single_value_transformer(st_select_lex_unit *unit,
|
||||
virtual void select_transformer(THD *thd, st_select_lex_unit *unit);
|
||||
void single_value_transformer(THD *thd, st_select_lex_unit *unit,
|
||||
Item *left_expr, compare_func_creator func);
|
||||
void row_value_transformer(st_select_lex_unit *unit, Item *left_expr);
|
||||
void row_value_transformer(THD *thd, st_select_lex_unit *unit,
|
||||
Item *left_expr);
|
||||
longlong val_int();
|
||||
double val();
|
||||
String *val_str(String*);
|
||||
@@ -194,7 +196,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);
|
||||
virtual void select_transformer(st_select_lex_unit *unit);
|
||||
virtual void select_transformer(THD *thd, st_select_lex_unit *unit);
|
||||
};
|
||||
|
||||
class subselect_engine: public Sql_alloc
|
||||
|
@@ -466,7 +466,7 @@ bool drop_locked_tables(THD *thd,const char *db, const char *table_name);
|
||||
void abort_locked_tables(THD *thd,const char *db, const char *table_name);
|
||||
extern const Field *not_found_field;
|
||||
Field *find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
||||
bool report_error);
|
||||
TABLE_LIST **where, bool report_error);
|
||||
Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
|
||||
bool check_grant,bool allow_rowid);
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
@@ -2166,7 +2166,8 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
|
||||
{
|
||||
tmp= param->table->file->
|
||||
records_in_range((int) keynr, (byte*)(param->min_key + 1),
|
||||
min_key_length, (ha_rkey_function)(tmp_min_flag ^ GEOM_FLAG),
|
||||
min_key_length,
|
||||
(ha_rkey_function)(tmp_min_flag ^ GEOM_FLAG),
|
||||
(byte *)NullS, 0, HA_READ_KEY_EXACT);
|
||||
}
|
||||
else
|
||||
|
@@ -1655,6 +1655,7 @@ const Field *not_found_field= (Field*) 0x1;
|
||||
thd - pointer to current thread structure
|
||||
item - field item that should be found
|
||||
tables - tables for scaning
|
||||
where - table where field found will be returned via this parameter
|
||||
report_error - if FALSE then do not report error if item not found and
|
||||
return not_found_field;
|
||||
|
||||
@@ -1668,7 +1669,7 @@ const Field *not_found_field= (Field*) 0x1;
|
||||
|
||||
Field *
|
||||
find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
||||
bool report_error)
|
||||
TABLE_LIST **where, bool report_error)
|
||||
{
|
||||
Field *found=0;
|
||||
const char *db=item->db_name;
|
||||
@@ -1689,6 +1690,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
||||
grant_option && !thd->master_access,1);
|
||||
if (find)
|
||||
{
|
||||
(*where)= tables;
|
||||
if (find == WRONG_GRANT)
|
||||
return (Field*) 0;
|
||||
if (db || !thd->where)
|
||||
@@ -1751,6 +1753,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
||||
{
|
||||
if (field == WRONG_GRANT)
|
||||
return (Field*) 0;
|
||||
(*where)= tables;
|
||||
if (found)
|
||||
{
|
||||
if (!thd->where) // Returns first found
|
||||
|
@@ -63,6 +63,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
|
||||
TMP_TABLE_PARAM tmp_table_param;
|
||||
bool is_union=sl->next_select() && sl->next_select()->linkage == UNION_TYPE;
|
||||
DBUG_ENTER("mysql_derived");
|
||||
SELECT_LEX_NODE *save_current_select= lex->current_select;
|
||||
|
||||
|
||||
/*
|
||||
@@ -111,6 +112,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
|
||||
}
|
||||
}
|
||||
|
||||
lex->current_select= sl;
|
||||
if (setup_fields(thd,tables,item_list,0,0,1))
|
||||
{
|
||||
res=-1;
|
||||
@@ -119,7 +121,8 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
|
||||
bzero((char*) &tmp_table_param,sizeof(tmp_table_param));
|
||||
tmp_table_param.field_count=item_list.elements;
|
||||
if (!(table=create_tmp_table(thd, &tmp_table_param, item_list,
|
||||
(ORDER*) 0, is_union && !unit->union_option, 1,
|
||||
(ORDER*) 0,
|
||||
is_union && !unit->union_option, 1,
|
||||
(sl->options | thd->options |
|
||||
TMP_TABLE_ALL_COLUMNS),
|
||||
HA_POS_ERROR)))
|
||||
@@ -138,8 +141,6 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
|
||||
if (unit->select_limit_cnt == HA_POS_ERROR)
|
||||
sl->options&= ~OPTION_FOUND_ROWS;
|
||||
|
||||
SELECT_LEX_NODE *save_current_select= lex->current_select;
|
||||
lex->current_select= sl;
|
||||
if (is_union)
|
||||
res=mysql_union(thd,lex,derived_result,unit);
|
||||
else
|
||||
@@ -149,7 +150,6 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
|
||||
sl->having, (ORDER*) NULL,
|
||||
sl->options | thd->options | SELECT_NO_UNLOCK,
|
||||
derived_result, unit, sl, 0);
|
||||
lex->current_select= save_current_select;
|
||||
|
||||
if (!res)
|
||||
{
|
||||
@@ -179,6 +179,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
|
||||
if (res)
|
||||
free_tmp_table(thd,table);
|
||||
exit:
|
||||
lex->current_select= save_current_select;
|
||||
close_thread_tables(thd);
|
||||
}
|
||||
DBUG_RETURN(res);
|
||||
|
Reference in New Issue
Block a user