Commit 214036a7 authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

improving of fields list creation in derived tables and unions

fixed length of fields created in fubselect
fixed resolving fields of reduced in derived table subselect
parent fd2e3175
......@@ -951,3 +951,37 @@ select * from t1;
mot topic date pseudo
joce 1 0000-00-00 joce
drop table t1, t2, t3;
SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
a (SELECT a)
1 1
CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT 1)) a;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` bigint(1) NOT NULL default '0',
`(SELECT 1)` bigint(1) NOT NULL default '0'
) TYPE=MyISAM CHARSET=latin1
drop table t1;
CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` bigint(1) NOT NULL default '0',
`(SELECT a)` bigint(1) NOT NULL default '0'
) TYPE=MyISAM CHARSET=latin1
drop table t1;
CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` bigint(1) NOT NULL default '0',
`(SELECT a+0)` bigint(17) NOT NULL default '0'
) TYPE=MyISAM CHARSET=latin1
drop table t1;
CREATE TABLE t1 SELECT (SELECT 1 as a UNION SELECT 1+1 limit 1,1) as a;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` bigint(17) NOT NULL default '0'
) TYPE=MyISAM CHARSET=latin1
drop table t1;
......@@ -558,4 +558,18 @@ DELETE FROM t1 WHERE topic IN (SELECT DISTINCT topic FROM t2 WHERE NOT
EXISTS(SELECT * FROM t3 WHERE numeropost=topic));
select * from t1;
drop table t1, t2, t3;
\ No newline at end of file
drop table t1, t2, t3;
SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT 1)) a;
SHOW CREATE TABLE t1;
drop table t1;
CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
SHOW CREATE TABLE t1;
drop table t1;
CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a;
SHOW CREATE TABLE t1;
drop table t1;
CREATE TABLE t1 SELECT (SELECT 1 as a UNION SELECT 1+1 limit 1,1) as a;
SHOW CREATE TABLE t1;
drop table t1;
......@@ -633,7 +633,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
uint counter= 0;
// 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)
if (outer_resolving ||
cursel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE)
for (SELECT_LEX *sl=(outer_resolving?cursel:cursel->outer_select());
sl;
sl= sl->outer_select())
......@@ -1184,10 +1185,6 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
}
ref= thd->lex.current_select->ref_pointer_array + counter-1;
}
max_length= (*ref)->max_length;
maybe_null= (*ref)->maybe_null;
decimals= (*ref)->decimals;
}
if (((*ref)->with_sum_func &&
......@@ -1202,6 +1199,9 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
"forward reference in item list"));
return 1;
}
max_length= (*ref)->max_length;
maybe_null= (*ref)->maybe_null;
decimals= (*ref)->decimals;
fixed= 1;
if (ref && (*ref)->check_cols(1))
return 1;
......
......@@ -161,7 +161,7 @@ void Item_singlerow_subselect::select_transformer(THD *thd,
select_lex->item_list.elements == 1 &&
// TODO: mark subselect items from item list separately
!(select_lex->item_list.head()->type() == FIELD_ITEM ||
select_lex->item_list.head()->type() == REF_ITEM)
select_lex->item_list.head()->type() == REF_ITEM)
)
{
......@@ -693,7 +693,7 @@ int subselect_single_select_engine::prepare()
(ORDER*) select_lex->group_list.first,
select_lex->having,
(ORDER*) 0, select_lex,
select_lex->master_unit(), 0))
select_lex->master_unit(), 0, 0))
return 1;
thd->lex.current_select= save_select;
return 0;
......@@ -701,7 +701,7 @@ int subselect_single_select_engine::prepare()
int subselect_union_engine::prepare()
{
return unit->prepare(thd, result);
return unit->prepare(thd, result, 0);
}
static Item_result set_row(SELECT_LEX *select_lex, Item * item,
......
......@@ -403,7 +403,8 @@ int mysql_select(THD *thd, Item ***rref_pointer_array,
COND *conds, uint og_num, ORDER *order, ORDER *group,
Item *having, ORDER *proc_param, ulong select_type,
select_result *result, SELECT_LEX_UNIT *unit,
SELECT_LEX *select_lex, bool fake_select_lex);
SELECT_LEX *select_lex, bool fake_select_lex,
bool tables_OK);
void free_ulderlayed_joins(THD *thd, SELECT_LEX *select);
void fix_tables_pointers(SELECT_LEX *select_lex);
void fix_tables_pointers(SELECT_LEX_UNIT *select_lex);
......@@ -411,7 +412,8 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit,
select_result *result);
int mysql_explain_select(THD *thd, SELECT_LEX *sl, char const *type,
select_result *result);
int mysql_union(THD *thd, LEX *lex,select_result *result,SELECT_LEX_UNIT *unit);
int mysql_union(THD *thd, LEX *lex, select_result *result,
SELECT_LEX_UNIT *unit, bool tables_OK);
int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t);
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
Item_result_field ***copy_func, Field **from_field,
......
......@@ -106,17 +106,22 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
fix_tables_pointers(unit);
}
Item *item;
List_iterator<Item> it(sl->item_list);
while ((item= it++))
item_list.push_back(item);
lex->current_select= sl;
TABLE_LIST *first_table= (TABLE_LIST*) sl->table_list.first;
if (setup_wild(thd, first_table, item_list, 0, sl->with_wild) ||
setup_fields(thd, 0, first_table, item_list, 0, 0, 1))
if (setup_tables(first_table) ||
setup_wild(thd, first_table, sl->item_list, 0, sl->with_wild))
{
res= -1;
goto exit;
}
item_list= sl->item_list;
sl->with_wild= 0;
if (setup_ref_array(thd, &sl->ref_pointer_array,
(item_list.elements + sl->with_sum_func +
sl->order_list.elements + sl->group_list.elements)) ||
setup_fields(thd, sl->ref_pointer_array, first_table, item_list,
0, 0, 1))
{
res= -1;
goto exit;
......@@ -145,7 +150,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
sl->options&= ~OPTION_FOUND_ROWS;
if (is_union)
res= mysql_union(thd, lex, derived_result, unit);
res= mysql_union(thd, lex, derived_result, unit, 1);
else
res= mysql_select(thd, &sl->ref_pointer_array,
(TABLE_LIST*) sl->table_list.first,
......@@ -156,7 +161,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
(ORDER *) sl->group_list.first,
sl->having, (ORDER*) NULL,
sl->options | thd->options | SELECT_NO_UNLOCK,
derived_result, unit, sl, 0);
derived_result, unit, sl, 0, 1);
if (!res)
{
......
......@@ -312,7 +312,7 @@ public:
void exclude_level();
/* UNION methods */
int prepare(THD *thd, select_result *result);
int prepare(THD *thd, select_result *result, bool tables_OK);
int exec();
int cleanup();
......
......@@ -2387,7 +2387,7 @@ mysql_execute_command(THD *thd)
(ORDER *)NULL,
select_lex->options | thd->options |
SELECT_NO_JOIN_CACHE,
result, unit, select_lex, 0);
result, unit, select_lex, 0, 0);
if (thd->net.report_error)
res= -1;
delete result;
......
......@@ -568,7 +568,7 @@ static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables,
if (join->prepare(&select_lex->ref_pointer_array, tables,
wild_num, conds, og_num, order, group, having, proc,
select_lex, unit, 0))
select_lex, unit, 0, 0))
DBUG_RETURN(1);
/*
......
......@@ -169,7 +169,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
register SELECT_LEX *select_lex = &lex->select_lex;
fix_tables_pointers(lex->all_selects_list);
if (select_lex->next_select())
res=mysql_union(thd,lex,result,&lex->unit);
res=mysql_union(thd, lex, result, &lex->unit, 0);
else
res= mysql_select(thd, &select_lex->ref_pointer_array,
(TABLE_LIST*) select_lex->table_list.first,
......@@ -182,7 +182,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
select_lex->having,
(ORDER*) lex->proc_list.first,
select_lex->options | thd->options,
result, &(lex->unit), &(lex->select_lex), 0);
result, &(lex->unit), &(lex->select_lex), 0, 0);
if (res && result)
result->abort();
......@@ -267,7 +267,8 @@ JOIN::prepare(Item ***rref_pointer_array,
ORDER *order_init, ORDER *group_init,
Item *having_init,
ORDER *proc_param_init, SELECT_LEX *select,
SELECT_LEX_UNIT *unit, bool fake_select_lex)
SELECT_LEX_UNIT *unit,
bool fake_select_lex, bool tables_OK)
{
DBUG_ENTER("JOIN::prepare");
......@@ -284,8 +285,9 @@ JOIN::prepare(Item ***rref_pointer_array,
/* Check that all tables, fields, conds and order are ok */
if (setup_tables(tables_list) ||
setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
if ((tables_OK?0:(setup_tables(tables_list) ||
setup_wild(thd, tables_list, fields_list,
&all_fields, wild_num))) ||
setup_ref_array(thd, rref_pointer_array, (fields_list.elements +
select_lex->with_sum_func +
og_num)) ||
......@@ -1296,7 +1298,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
COND *conds, uint og_num, ORDER *order, ORDER *group,
Item *having, ORDER *proc_param, ulong select_options,
select_result *result, SELECT_LEX_UNIT *unit,
SELECT_LEX *select_lex, bool fake_select_lex)
SELECT_LEX *select_lex, bool fake_select_lex, bool tables_OK)
{
int err;
bool free_join= 1;
......@@ -1323,7 +1325,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
if (join->prepare(rref_pointer_array, tables, wild_num,
conds, og_num, order, group, having, proc_param,
select_lex, unit, fake_select_lex))
select_lex, unit, fake_select_lex, tables_OK))
{
DBUG_RETURN(-1);
}
......@@ -8065,7 +8067,7 @@ int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type,
select_lex->having,
(ORDER*) thd->lex.proc_list.first,
select_lex->options | thd->options | SELECT_DESCRIBE,
result, unit, select_lex, 0);
result, unit, select_lex, 0, 0);
DBUG_RETURN(res);
}
......
......@@ -256,7 +256,7 @@ class JOIN :public Sql_alloc
int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num,
COND *conds, uint og_num, ORDER *order, ORDER *group,
Item *having, ORDER *proc_param, SELECT_LEX *select,
SELECT_LEX_UNIT *unit, bool fake_select_lex);
SELECT_LEX_UNIT *unit, bool fake_select_lex, bool tables_OK);
int optimize();
int reinit();
void exec();
......
......@@ -24,11 +24,12 @@
#include "mysql_priv.h"
#include "sql_select.h"
int mysql_union(THD *thd, LEX *lex, select_result *result,SELECT_LEX_UNIT *unit)
int mysql_union(THD *thd, LEX *lex, select_result *result,
SELECT_LEX_UNIT *unit, bool tables_OK)
{
DBUG_ENTER("mysql_union");
int res= 0;
if (!(res= unit->prepare(thd, result)))
if (!(res= unit->prepare(thd, result, tables_OK)))
res= unit->exec();
res|= unit->cleanup();
DBUG_RETURN(res);
......@@ -107,7 +108,8 @@ bool select_union::flush()
return 0;
}
int st_select_lex_unit::prepare(THD *thd, select_result *result)
int st_select_lex_unit::prepare(THD *thd, select_result *result,
bool tables_OK)
{
DBUG_ENTER("st_select_lex_unit::prepare");
......@@ -121,7 +123,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result)
SELECT_LEX_NODE *lex_select_save= thd->lex.current_select;
SELECT_LEX *sl;
thd->lex.current_select=first_select();
thd->lex.current_select= sl= first_select();
/* Global option */
if (((void*)(global_parameters)) == ((void*)this))
{
......@@ -130,20 +132,28 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result)
if (found_rows_for_union)
first_select()->options ^= OPTION_FOUND_ROWS;
}
item_list.empty();
if (tables_OK)
{
Item *item;
List_iterator<Item> it(first_select()->item_list);
item_list= sl->item_list;
}
else
{
item_list.empty();
TABLE_LIST *first_table= (TABLE_LIST*) first_select()->table_list.first;
/* Create a list of items that will be in the result set */
while ((item= it++))
if (item_list.push_back(item))
goto err;
if (setup_wild(thd, first_table, item_list, 0,
first_select()->with_wild) ||
setup_fields(thd, 0, first_table, item_list, 0, 0, 1))
if (setup_tables(first_table) ||
setup_wild(thd, first_table, sl->item_list, 0, sl->with_wild))
goto err;
item_list= sl->item_list;
sl->with_wild= 0;
if (setup_ref_array(thd, &sl->ref_pointer_array,
(item_list.elements + sl->with_sum_func +
sl->order_list.elements + sl->group_list.elements)) ||
setup_fields(thd, sl->ref_pointer_array, first_table, item_list,
0, 0, 1))
goto err;
tables_OK= 1;
}
bzero((char*) &tmp_table_param,sizeof(tmp_table_param));
......@@ -191,11 +201,25 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result)
(ORDER*) sl->group_list.first,
sl->having,
(ORDER*) NULL,
sl, this, 0);
sl, this, 0, tables_OK);
tables_OK= 0;
if (res | thd->fatal_error)
goto err;
}
item_list.empty();
thd->lex.current_select= lex_select_save;
{
List_iterator<Item> it(first_select()->item_list);
Field **field;
for (field= table->field; *field; field++)
{
(void) it++;
if (item_list.push_back(new Item_field(*field)))
DBUG_RETURN(-1);
}
}
DBUG_RETURN(res | thd->fatal_error);
err:
thd->lex.current_select= lex_select_save;
......@@ -260,9 +284,6 @@ int st_select_lex_unit::exec()
thd->lex.current_select = first_select();
res =-1;
{
/* Create a list of fields in the temporary table */
List_iterator<Item> it(item_list);
Field **field;
#if 0
List<Item_func_match> ftfunc_list;
ftfunc_list.empty();
......@@ -272,11 +293,6 @@ int st_select_lex_unit::exec()
thd->lex.select_lex.ftfunc_list= &empty_list;
#endif
for (field=table->field ; *field ; field++)
{
(void) it++;
(void) it.replace(new Item_field(*field));
}
if (!thd->fatal_error) // Check if EOM
{
SELECT_LEX *sl=thd->lex.current_select->master_unit()->first_select();
......@@ -292,7 +308,7 @@ int st_select_lex_unit::exec()
global_parameters->order_list.elements,
(ORDER*)global_parameters->order_list.first,
(ORDER*) NULL, NULL, (ORDER*) NULL,
thd->options, result, this, first_select(), 1);
thd->options, result, this, first_select(), 1, 0);
if (found_rows_for_union && !res)
thd->limit_found_rows = (ulonglong)table->file->records;
}
......
......@@ -428,7 +428,7 @@ int mysql_multi_update(THD *thd,
conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL,
(ORDER *)NULL,
options | SELECT_NO_JOIN_CACHE,
result, unit, select_lex, 0);
result, unit, select_lex, 0, 0);
delete result;
DBUG_RETURN(res);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment