Commit b2ffb29a authored by unknown's avatar unknown

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


mysql-test/r/subselect.result:
  test of created with subselect fields
mysql-test/t/subselect.test:
  test of created with subselect fields
sql/item.cc:
  fixed length of fields created in fubselect
  fixed resolving fields of reduced in derived table subselect
sql/item_subselect.cc:
  improving of fields list creation in derived tables and unions
sql/mysql_priv.h:
  improving of fields list creation in derived tables and unions
sql/sql_derived.cc:
  improving of fields list creation in derived tables and unions
sql/sql_lex.h:
  improving of fields list creation in derived tables and unions
sql/sql_parse.cc:
  improving of fields list creation in derived tables and unions
sql/sql_prepare.cc:
  improving of fields list creation in derived tables and unions
sql/sql_select.cc:
  improving of fields list creation in derived tables and unions
sql/sql_select.h:
  improving of fields list creation in derived tables and unions
sql/sql_union.cc:
  improving of fields list creation in derived tables and unions
sql/sql_update.cc:
  improving of fields list creation in derived tables and unions
parent b343de72
......@@ -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;
......@@ -559,3 +559,17 @@ EXISTS(SELECT * FROM t3 WHERE numeropost=topic));
select * from t1;
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;
......
......@@ -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))
if (setup_tables(first_table) ||
setup_wild(thd, first_table, sl->item_list, 0, sl->with_wild))
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))
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