code cleanup
fixed subselect error handling bug fixed subselect UNION ALL bug fixed thd->lex.select restoring explain UNION subselect bug mysql-test/r/subselect.result: test for: subselect UNION ALL bug subselect error handling bug explain UNION subselect bug mysql-test/t/subselect.test: test for: subselect UNION ALL bug subselect error handling bug explain UNION subselect bug sql/sql_lex.cc: fixed subselect UNION ALL bug sql/sql_lex.h: fixed subselect UNION ALL bug sql/sql_parse.cc: fixed subselect UNION ALL bug sql/sql_select.cc: fixed subselect error handling bug fixed explain UNION subselect bug sql/sql_union.cc: fixed thd->lex.select restoring code cleanup fixed subselect error handling bug fixed subselect UNION ALL bug sql/sql_yacc.yy: fixed subselect UNION ALL bug
This commit is contained in:
parent
9e82940496
commit
c37bbf06bb
@ -204,4 +204,16 @@ date
|
|||||||
SELECT (SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03');
|
SELECT (SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03');
|
||||||
(SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03')
|
(SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03')
|
||||||
2002-08-03
|
2002-08-03
|
||||||
|
SELECT 1 FROM searchconthardwarefr3 WHERE 1=(SELECT 1 UNION SELECT 1) UNION ALL SELECT 1;
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
SELECT 1 FROM searchconthardwarefr3 WHERE 1=(SELECT 1 UNION ALL SELECT 1) UNION SELECT 1;
|
||||||
|
Subselect returns more than 1 record
|
||||||
|
EXPLAIN SELECT 1 FROM searchconthardwarefr3 WHERE 1=(SELECT 1 UNION SELECT 1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY searchconthardwarefr3 index NULL topic 3 NULL 2 Using index
|
||||||
|
2 SUBSELECT No tables used
|
||||||
|
3 UNION No tables used
|
||||||
drop table searchconthardwarefr3;
|
drop table searchconthardwarefr3;
|
||||||
|
@ -110,4 +110,8 @@ EXPLAIN SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03';
|
|||||||
EXPLAIN SELECT (SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03');
|
EXPLAIN SELECT (SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03');
|
||||||
SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03';
|
SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03';
|
||||||
SELECT (SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03');
|
SELECT (SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03');
|
||||||
|
SELECT 1 FROM searchconthardwarefr3 WHERE 1=(SELECT 1 UNION SELECT 1) UNION ALL SELECT 1;
|
||||||
|
-- error 1240
|
||||||
|
SELECT 1 FROM searchconthardwarefr3 WHERE 1=(SELECT 1 UNION ALL SELECT 1) UNION SELECT 1;
|
||||||
|
EXPLAIN SELECT 1 FROM searchconthardwarefr3 WHERE 1=(SELECT 1 UNION SELECT 1);
|
||||||
drop table searchconthardwarefr3;
|
drop table searchconthardwarefr3;
|
@ -944,6 +944,7 @@ void st_select_lex_unit::init_query()
|
|||||||
global_parameters= this;
|
global_parameters= this;
|
||||||
select_limit_cnt= HA_POS_ERROR;
|
select_limit_cnt= HA_POS_ERROR;
|
||||||
offset_limit_cnt= 0;
|
offset_limit_cnt= 0;
|
||||||
|
union_option= 0;
|
||||||
prepared= optimized= 0;
|
prepared= optimized= 0;
|
||||||
item= 0;
|
item= 0;
|
||||||
}
|
}
|
||||||
|
@ -240,6 +240,7 @@ public:
|
|||||||
bool depended; /* depended from outer select subselect */
|
bool depended; /* depended from outer select subselect */
|
||||||
/* not NULL if union used in subselect, point to subselect item */
|
/* not NULL if union used in subselect, point to subselect item */
|
||||||
Item_subselect *item;
|
Item_subselect *item;
|
||||||
|
uint union_option;
|
||||||
|
|
||||||
void init_query();
|
void init_query();
|
||||||
bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result);
|
bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result);
|
||||||
@ -373,7 +374,7 @@ typedef struct st_lex
|
|||||||
enum ha_rkey_function ha_rkey_mode;
|
enum ha_rkey_function ha_rkey_mode;
|
||||||
enum enum_enable_or_disable alter_keys_onoff;
|
enum enum_enable_or_disable alter_keys_onoff;
|
||||||
enum enum_var_type option_type;
|
enum enum_var_type option_type;
|
||||||
uint grant, grant_tot_col, which_columns, union_option;
|
uint grant, grant_tot_col, which_columns;
|
||||||
uint fk_delete_opt, fk_update_opt, fk_match_option;
|
uint fk_delete_opt, fk_update_opt, fk_match_option;
|
||||||
uint param_count;
|
uint param_count;
|
||||||
bool drop_primary, drop_if_exists, local_file, olap;
|
bool drop_primary, drop_if_exists, local_file, olap;
|
||||||
|
@ -2904,7 +2904,6 @@ mysql_init_query(THD *thd)
|
|||||||
thd->select_number= thd->lex.select_lex.select_number= 1;
|
thd->select_number= thd->lex.select_lex.select_number= 1;
|
||||||
thd->lex.value_list.empty();
|
thd->lex.value_list.empty();
|
||||||
thd->free_list= 0;
|
thd->free_list= 0;
|
||||||
thd->lex.union_option= 0;
|
|
||||||
thd->lex.select= &thd->lex.select_lex;
|
thd->lex.select= &thd->lex.select_lex;
|
||||||
thd->lex.olap=thd->lex.describe=0;
|
thd->lex.olap=thd->lex.describe=0;
|
||||||
thd->lex.select->olap= UNSPECIFIED_OLAP_TYPE;
|
thd->lex.select->olap= UNSPECIFIED_OLAP_TYPE;
|
||||||
|
@ -371,7 +371,7 @@ JOIN::optimize()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
conds=optimize_cond(conds,&cond_value);
|
conds=optimize_cond(conds,&cond_value);
|
||||||
if (thd->fatal_error) // Out of memory
|
if (thd->fatal_error || thd->net.report_error)
|
||||||
{
|
{
|
||||||
delete procedure;
|
delete procedure;
|
||||||
error = 0;
|
error = 0;
|
||||||
@ -7251,16 +7251,18 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
|||||||
select_result *result=join->result;
|
select_result *result=join->result;
|
||||||
Item *item_null= new Item_null();
|
Item *item_null= new Item_null();
|
||||||
DBUG_ENTER("select_describe");
|
DBUG_ENTER("select_describe");
|
||||||
|
DBUG_PRINT("info", ("Select 0x%lx, type %s, message %s",
|
||||||
|
(ulong)join->select_lex, join->select_lex->type,
|
||||||
|
message));
|
||||||
/* Don't log this into the slow query log */
|
/* Don't log this into the slow query log */
|
||||||
select_lex->options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED);
|
select_lex->options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED);
|
||||||
join->unit->offset_limit_cnt= 0;
|
join->unit->offset_limit_cnt= 0;
|
||||||
|
|
||||||
if (message)
|
if (message)
|
||||||
{
|
{
|
||||||
item_list.push_back(new Item_int((int32) thd->lex.select->select_number));
|
item_list.push_back(new Item_int((int32) join->select_lex->select_number));
|
||||||
item_list.push_back(new Item_string(thd->lex.select->type,
|
item_list.push_back(new Item_string(join->select_lex->type,
|
||||||
strlen(thd->lex.select->type),
|
strlen(join->select_lex->type),
|
||||||
default_charset_info));
|
default_charset_info));
|
||||||
Item *empty= new Item_empty_string("",0);
|
Item *empty= new Item_empty_string("",0);
|
||||||
for (uint i=0 ; i < 7; i++)
|
for (uint i=0 ; i < 7; i++)
|
||||||
@ -7285,9 +7287,10 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
|||||||
tmp2.length(0);
|
tmp2.length(0);
|
||||||
|
|
||||||
item_list.empty();
|
item_list.empty();
|
||||||
item_list.push_back(new Item_int((int32) thd->lex.select->select_number));
|
item_list.push_back(new Item_int((int32)
|
||||||
item_list.push_back(new Item_string(thd->lex.select->type,
|
join->select_lex->select_number));
|
||||||
strlen(thd->lex.select->type),
|
item_list.push_back(new Item_string(join->select_lex->type,
|
||||||
|
strlen(join->select_lex->type),
|
||||||
default_charset_info));
|
default_charset_info));
|
||||||
if (tab->type == JT_ALL && tab->select && tab->select->quick)
|
if (tab->type == JT_ALL && tab->select && tab->select->quick)
|
||||||
tab->type= JT_RANGE;
|
tab->type= JT_RANGE;
|
||||||
@ -7445,6 +7448,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
|||||||
|
|
||||||
int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
|
int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
|
||||||
{
|
{
|
||||||
|
DBUG_ENTER("mysql_explain_union");
|
||||||
int res= 0;
|
int res= 0;
|
||||||
SELECT_LEX *first= unit->first_select();
|
SELECT_LEX *first= unit->first_select();
|
||||||
for (SELECT_LEX *sl= first;
|
for (SELECT_LEX *sl= first;
|
||||||
@ -7467,12 +7471,14 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
|
|||||||
}
|
}
|
||||||
if (res > 0)
|
if (res > 0)
|
||||||
res= -res; // mysql_explain_select do not report error
|
res= -res; // mysql_explain_select do not report error
|
||||||
return res;
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type,
|
int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type,
|
||||||
select_result *result)
|
select_result *result)
|
||||||
{
|
{
|
||||||
|
DBUG_ENTER("mysql_explain_select");
|
||||||
|
DBUG_PRINT("info", ("Select 0x%lx, type %s", (ulong)select_lex, type))
|
||||||
select_lex->type= type;
|
select_lex->type= type;
|
||||||
thd->lex.select= select_lex;
|
thd->lex.select= select_lex;
|
||||||
SELECT_LEX_UNIT *unit= select_lex->master_unit();
|
SELECT_LEX_UNIT *unit= select_lex->master_unit();
|
||||||
@ -7485,6 +7491,6 @@ int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type,
|
|||||||
(ORDER*) thd->lex.proc_list.first,
|
(ORDER*) thd->lex.proc_list.first,
|
||||||
select_lex->options | thd->options | SELECT_DESCRIBE,
|
select_lex->options | thd->options | SELECT_DESCRIBE,
|
||||||
result, unit, select_lex, 0);
|
result, unit, select_lex, 0);
|
||||||
return res;
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,6 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
prepared= 1;
|
prepared= 1;
|
||||||
union_result=0;
|
union_result=0;
|
||||||
describe=(first_select()->options & SELECT_DESCRIBE) ? 1 : 0;
|
|
||||||
res= 0;
|
res= 0;
|
||||||
found_rows_for_union= false;
|
found_rows_for_union= false;
|
||||||
TMP_TABLE_PARAM tmp_table_param;
|
TMP_TABLE_PARAM tmp_table_param;
|
||||||
@ -122,30 +121,11 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result)
|
|||||||
if (((void*)(global_parameters)) == ((void*)this))
|
if (((void*)(global_parameters)) == ((void*)this))
|
||||||
{
|
{
|
||||||
found_rows_for_union= first_select()->options & OPTION_FOUND_ROWS &&
|
found_rows_for_union= first_select()->options & OPTION_FOUND_ROWS &&
|
||||||
!describe && global_parameters->select_limit;
|
global_parameters->select_limit;
|
||||||
if (found_rows_for_union)
|
if (found_rows_for_union)
|
||||||
first_select()->options ^= OPTION_FOUND_ROWS;
|
first_select()->options ^= OPTION_FOUND_ROWS;
|
||||||
}
|
}
|
||||||
item_list.empty();
|
item_list.empty();
|
||||||
if (describe)
|
|
||||||
{
|
|
||||||
Item *item;
|
|
||||||
item_list.push_back(new Item_empty_string("table",NAME_LEN));
|
|
||||||
item_list.push_back(new Item_empty_string("type",10));
|
|
||||||
item_list.push_back(item=new Item_empty_string("possible_keys",
|
|
||||||
NAME_LEN*MAX_KEY));
|
|
||||||
item->maybe_null=1;
|
|
||||||
item_list.push_back(item=new Item_empty_string("key",NAME_LEN));
|
|
||||||
item->maybe_null=1;
|
|
||||||
item_list.push_back(item=new Item_int("key_len",0,3));
|
|
||||||
item->maybe_null=1;
|
|
||||||
item_list.push_back(item=new Item_empty_string("ref",
|
|
||||||
NAME_LEN*MAX_REF_PARTS));
|
|
||||||
item->maybe_null=1;
|
|
||||||
item_list.push_back(new Item_real("rows",0.0,0,10));
|
|
||||||
item_list.push_back(new Item_empty_string("Extra",255));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
Item *item;
|
Item *item;
|
||||||
List_iterator<Item> it(first_select()->item_list);
|
List_iterator<Item> it(first_select()->item_list);
|
||||||
@ -162,8 +142,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result)
|
|||||||
bzero((char*) &tmp_table_param,sizeof(tmp_table_param));
|
bzero((char*) &tmp_table_param,sizeof(tmp_table_param));
|
||||||
tmp_table_param.field_count=item_list.elements;
|
tmp_table_param.field_count=item_list.elements;
|
||||||
if (!(table= create_tmp_table(thd, &tmp_table_param, item_list,
|
if (!(table= create_tmp_table(thd, &tmp_table_param, item_list,
|
||||||
(ORDER*) 0, !describe &
|
(ORDER*) 0, !union_option,
|
||||||
!thd->lex.union_option,
|
|
||||||
1, 0,
|
1, 0,
|
||||||
(first_select()->options | thd->options |
|
(first_select()->options | thd->options |
|
||||||
TMP_TABLE_ALL_COLUMNS),
|
TMP_TABLE_ALL_COLUMNS),
|
||||||
@ -179,7 +158,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result)
|
|||||||
if (!(union_result=new select_union(table)))
|
if (!(union_result=new select_union(table)))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
union_result->save_time_stamp=!describe;
|
union_result->save_time_stamp=1;
|
||||||
union_result->tmp_table_param=&tmp_table_param;
|
union_result->tmp_table_param=&tmp_table_param;
|
||||||
|
|
||||||
// prepare selects
|
// prepare selects
|
||||||
@ -187,8 +166,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result)
|
|||||||
for (sl= first_select(); sl; sl= sl->next_select())
|
for (sl= first_select(); sl; sl= sl->next_select())
|
||||||
{
|
{
|
||||||
JOIN *join= new JOIN(thd, sl->item_list,
|
JOIN *join= new JOIN(thd, sl->item_list,
|
||||||
sl->options | thd->options | SELECT_NO_UNLOCK |
|
sl->options | thd->options | SELECT_NO_UNLOCK,
|
||||||
((describe) ? SELECT_DESCRIBE : 0),
|
|
||||||
union_result);
|
union_result);
|
||||||
joins.push_back(new JOIN_P(join));
|
joins.push_back(new JOIN_P(join));
|
||||||
thd->lex.select=sl;
|
thd->lex.select=sl;
|
||||||
@ -220,11 +198,12 @@ err:
|
|||||||
int st_select_lex_unit::exec()
|
int st_select_lex_unit::exec()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("st_select_lex_unit::exec");
|
DBUG_ENTER("st_select_lex_unit::exec");
|
||||||
|
SELECT_LEX *lex_select_save= thd->lex.select;
|
||||||
|
|
||||||
if(depended || !item || !item->assigned())
|
if(depended || !item || !item->assigned())
|
||||||
{
|
{
|
||||||
if (optimized && item && item->assigned())
|
if (optimized && item && item->assigned())
|
||||||
item->assigned(0); // We will reinit & rexecute unit
|
item->assigned(0); // We will reinit & rexecute unit
|
||||||
SELECT_LEX *lex_select_save= thd->lex.select;
|
|
||||||
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
|
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
|
||||||
{
|
{
|
||||||
thd->lex.select=sl;
|
thd->lex.select=sl;
|
||||||
@ -236,27 +215,28 @@ int st_select_lex_unit::exec()
|
|||||||
sl->options&= ~OPTION_FOUND_ROWS;
|
sl->options&= ~OPTION_FOUND_ROWS;
|
||||||
|
|
||||||
if (!optimized)
|
if (!optimized)
|
||||||
sl->join->optimize();
|
res= sl->join->optimize();
|
||||||
else
|
else
|
||||||
sl->join->reinit();
|
res= sl->join->reinit();
|
||||||
|
|
||||||
sl->join->exec();
|
|
||||||
res= sl->join->error;
|
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
sl->join->exec();
|
||||||
|
res= sl->join->error;
|
||||||
|
}
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
thd->lex.select= lex_select_save;
|
thd->lex.select= lex_select_save;
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
thd->lex.select= lex_select_save;
|
|
||||||
optimized= 1;
|
optimized= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (union_result->flush())
|
if (union_result->flush())
|
||||||
{
|
{
|
||||||
res= 1; // Error is already sent
|
thd->lex.select= lex_select_save;
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send result to 'result' */
|
/* Send result to 'result' */
|
||||||
@ -289,12 +269,8 @@ int st_select_lex_unit::exec()
|
|||||||
select_limit_cnt= HA_POS_ERROR; // no limit
|
select_limit_cnt= HA_POS_ERROR; // no limit
|
||||||
if (select_limit_cnt == HA_POS_ERROR)
|
if (select_limit_cnt == HA_POS_ERROR)
|
||||||
thd->options&= ~OPTION_FOUND_ROWS;
|
thd->options&= ~OPTION_FOUND_ROWS;
|
||||||
if (describe)
|
|
||||||
select_limit_cnt= HA_POS_ERROR; // no limit
|
|
||||||
res= mysql_select(thd,&result_table_list,
|
res= mysql_select(thd,&result_table_list,
|
||||||
item_list, NULL,
|
item_list, NULL,
|
||||||
(describe) ?
|
|
||||||
0:
|
|
||||||
(ORDER*)global_parameters->order_list.first,
|
(ORDER*)global_parameters->order_list.first,
|
||||||
(ORDER*) NULL, NULL, (ORDER*) NULL,
|
(ORDER*) NULL, NULL, (ORDER*) NULL,
|
||||||
thd->options, result, this, first_select(), 1);
|
thd->options, result, this, first_select(), 1);
|
||||||
@ -303,6 +279,7 @@ int st_select_lex_unit::exec()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
thd->lex.select_lex.ftfunc_list= &thd->lex.select_lex.ftfunc_list_alloc;
|
thd->lex.select_lex.ftfunc_list= &thd->lex.select_lex.ftfunc_list_alloc;
|
||||||
|
thd->lex.select= lex_select_save;
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4150,7 +4150,7 @@ optional_order_or_limit:
|
|||||||
|
|
||||||
union_option:
|
union_option:
|
||||||
/* empty */ {}
|
/* empty */ {}
|
||||||
| ALL {Lex->union_option=1;};
|
| ALL {Select->master_unit()->union_option= 1;};
|
||||||
|
|
||||||
singleval_subselect:
|
singleval_subselect:
|
||||||
subselect_start singleval_subselect_init
|
subselect_start singleval_subselect_init
|
||||||
|
Loading…
x
Reference in New Issue
Block a user