three bug fixes and major code cleanup
This commit is contained in:
parent
b2eb6eabf1
commit
ffa8a47b6d
@ -230,3 +230,7 @@ id_master id text1 text2
|
||||
1 3 NULL bar3
|
||||
1 4 foo4 bar4
|
||||
drop table if exists t1,t2;
|
||||
(SELECT 1,3) UNION (SELECT 2,1) ORDER BY (SELECT 2);
|
||||
1 3
|
||||
1 3
|
||||
2 1
|
||||
|
@ -124,3 +124,4 @@ INSERT INTO t2 (id, id_master, text1, text2) VALUES("4", "1",
|
||||
SELECT 1 AS id_master, 1 AS id, NULL AS text1, 'ABCDE' AS text2 UNION SELECT id_master, t2.id, text1, text2 FROM t1 LEFT JOIN t2 ON t1.id = t2.id_master;
|
||||
SELECT 1 AS id_master, 1 AS id, 'ABCDE' AS text1, 'ABCDE' AS text2 UNION SELECT id_master, t2.id, text1, text2 FROM t1 LEFT JOIN t2 ON t1.id = t2.id_master;
|
||||
drop table if exists t1,t2;
|
||||
(SELECT 1,3) UNION (SELECT 2,1) ORDER BY (SELECT 2);
|
||||
|
@ -684,7 +684,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, 0))
|
||||
select_lex->master_unit(), 0))
|
||||
return 1;
|
||||
thd->lex.current_select= save_select;
|
||||
return 0;
|
||||
|
@ -405,8 +405,7 @@ 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,
|
||||
bool tables_and_fields_initied);
|
||||
SELECT_LEX *select_lex, bool tables_and_fields_initied);
|
||||
void free_underlaid_joins(THD *thd, SELECT_LEX *select);
|
||||
void fix_tables_pointers(SELECT_LEX *select_lex);
|
||||
void fix_tables_pointers(SELECT_LEX_UNIT *select_lex);
|
||||
|
@ -172,7 +172,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
|
||||
(ORDER *) select_cursor->group_list.first,
|
||||
select_cursor->having, (ORDER*) NULL,
|
||||
select_cursor->options | thd->options | SELECT_NO_UNLOCK,
|
||||
derived_result, unit, select_cursor, 0, 1);
|
||||
derived_result, unit, select_cursor, 1);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
|
@ -311,6 +311,11 @@ public:
|
||||
st_select_lex_unit* master_unit();
|
||||
st_select_lex* outer_select();
|
||||
st_select_lex* first_select() { return (st_select_lex*) slave; }
|
||||
st_select_lex* first_select_in_union()
|
||||
{
|
||||
return (slave && slave->linkage == GLOBAL_OPTIONS_TYPE) ?
|
||||
(st_select_lex*) slave->next : (st_select_lex*) slave;
|
||||
}
|
||||
st_select_lex_unit* next_unit() { return (st_select_lex_unit*) next; }
|
||||
void exclude_level();
|
||||
|
||||
@ -404,6 +409,13 @@ public:
|
||||
}
|
||||
|
||||
friend void mysql_init_query(THD *thd);
|
||||
void make_empty_select(st_select_lex *last_select)
|
||||
{
|
||||
select_number=INT_MAX;
|
||||
init_query();
|
||||
init_select();
|
||||
include_neighbour(last_select);
|
||||
}
|
||||
};
|
||||
typedef class st_select_lex SELECT_LEX;
|
||||
|
||||
|
@ -2433,7 +2433,7 @@ mysql_execute_command(THD *thd)
|
||||
(ORDER *)NULL,
|
||||
select_lex->options | thd->options |
|
||||
SELECT_NO_JOIN_CACHE,
|
||||
result, unit, select_lex, 0, 0);
|
||||
result, unit, select_lex, 0);
|
||||
if (thd->net.report_error)
|
||||
res= -1;
|
||||
delete result;
|
||||
|
@ -567,7 +567,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, 0))
|
||||
select_lex, unit, 0))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
/*
|
||||
|
@ -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, 0);
|
||||
result, &(lex->unit), &(lex->select_lex), 0);
|
||||
if (res && result)
|
||||
result->abort();
|
||||
|
||||
@ -268,7 +268,7 @@ JOIN::prepare(Item ***rref_pointer_array,
|
||||
Item *having_init,
|
||||
ORDER *proc_param_init, SELECT_LEX *select,
|
||||
SELECT_LEX_UNIT *unit,
|
||||
bool fake_select_lex, bool tables_and_fields_initied)
|
||||
bool tables_and_fields_initied)
|
||||
{
|
||||
DBUG_ENTER("JOIN::prepare");
|
||||
|
||||
@ -279,8 +279,7 @@ JOIN::prepare(Item ***rref_pointer_array,
|
||||
proc_param= proc_param_init;
|
||||
tables_list= tables_init;
|
||||
select_lex= select;
|
||||
if (!fake_select_lex)
|
||||
select_lex->join= this;
|
||||
select_lex->join= this;
|
||||
union_part= (unit->first_select()->next_select() != 0);
|
||||
|
||||
/* Check that all tables, fields, conds and order are ok */
|
||||
@ -1261,7 +1260,6 @@ int
|
||||
JOIN::cleanup(THD *thd)
|
||||
{
|
||||
DBUG_ENTER("JOIN::cleanup");
|
||||
|
||||
select_lex->join= 0;
|
||||
|
||||
if (tmp_join)
|
||||
@ -1292,15 +1290,14 @@ 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,
|
||||
bool tables_and_fields_initied)
|
||||
SELECT_LEX *select_lex, bool tables_and_fields_initied)
|
||||
{
|
||||
int err;
|
||||
bool free_join= 1;
|
||||
DBUG_ENTER("mysql_select");
|
||||
|
||||
JOIN *join;
|
||||
if (!fake_select_lex && select_lex->join != 0)
|
||||
if (select_lex->join != 0)
|
||||
{
|
||||
//here is EXPLAIN of subselect or derived table
|
||||
join= select_lex->join;
|
||||
@ -1320,8 +1317,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,
|
||||
tables_and_fields_initied))
|
||||
select_lex, unit, tables_and_fields_initied))
|
||||
{
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
@ -1350,7 +1346,7 @@ err:
|
||||
thd->limit_found_rows= curr_join->send_records;
|
||||
thd->examined_row_count= curr_join->examined_rows;
|
||||
thd->proc_info="end";
|
||||
err= (fake_select_lex ? curr_join->error : join->cleanup(thd));
|
||||
err= join->cleanup(thd);
|
||||
if (thd->net.report_error)
|
||||
err= -1;
|
||||
delete join;
|
||||
@ -7086,15 +7082,16 @@ find_order_in_list(THD *thd, Item **ref_pointer_array,
|
||||
TABLE_LIST *tables,ORDER *order, List<Item> &fields,
|
||||
List<Item> &all_fields)
|
||||
{
|
||||
if ((*order->item)->type() == Item::INT_ITEM)
|
||||
Item *itemptr=*order->item;
|
||||
if (itemptr->type() == Item::INT_ITEM)
|
||||
{ /* Order by position */
|
||||
Item *item=0;
|
||||
|
||||
uint count= (uint) ((Item_int*) (*order->item))->value;
|
||||
uint count= (uint) ((Item_int*)itemptr)->value;
|
||||
if (count > fields.elements)
|
||||
{
|
||||
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),
|
||||
MYF(0),(*order->item)->full_name(),
|
||||
MYF(0),itemptr->full_name(),
|
||||
thd->where);
|
||||
return 1;
|
||||
}
|
||||
@ -7103,8 +7100,7 @@ find_order_in_list(THD *thd, Item **ref_pointer_array,
|
||||
return 0;
|
||||
}
|
||||
uint counter;
|
||||
Item **item= find_item_in_list(*order->item, fields, &counter,
|
||||
IGNORE_ERRORS);
|
||||
Item **item= find_item_in_list(itemptr, fields, &counter, IGNORE_ERRORS);
|
||||
if (item)
|
||||
{
|
||||
order->item= ref_pointer_array + counter;
|
||||
@ -8103,7 +8099,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, 0);
|
||||
result, unit, select_lex, 0);
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
|
@ -256,8 +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,
|
||||
bool tables_and_fields_initied);
|
||||
SELECT_LEX_UNIT *unit, bool tables_and_fields_initied);
|
||||
int optimize();
|
||||
int reinit();
|
||||
void exec();
|
||||
|
@ -122,9 +122,9 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result,
|
||||
this->result= result;
|
||||
t_and_f= tables_and_fields_initied;
|
||||
SELECT_LEX_NODE *lex_select_save= thd->lex.current_select;
|
||||
SELECT_LEX *sl;
|
||||
SELECT_LEX *select_cursor;
|
||||
|
||||
thd->lex.current_select= sl= first_select();
|
||||
thd->lex.current_select= select_cursor= first_select_in_union();
|
||||
/* Global option */
|
||||
if (((void*)(global_parameters)) == ((void*)this))
|
||||
{
|
||||
@ -136,26 +136,27 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result,
|
||||
if (t_and_f)
|
||||
{
|
||||
// Item list and tables will be initialized by mysql_derived
|
||||
item_list= sl->item_list;
|
||||
item_list= select_cursor->item_list;
|
||||
}
|
||||
else
|
||||
{
|
||||
item_list.empty();
|
||||
TABLE_LIST *first_table= (TABLE_LIST*) first_select()->table_list.first;
|
||||
TABLE_LIST *first_table= (TABLE_LIST*) select_cursor->table_list.first;
|
||||
|
||||
if (setup_tables(first_table) ||
|
||||
setup_wild(thd, first_table, sl->item_list, 0, sl->with_wild))
|
||||
setup_wild(thd, first_table, select_cursor->item_list, 0, select_cursor->with_wild))
|
||||
goto err;
|
||||
List_iterator<Item> it(sl->item_list);
|
||||
List_iterator<Item> it(select_cursor->item_list);
|
||||
Item *item;
|
||||
while((item=it++))
|
||||
item->maybe_null=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,
|
||||
item_list= select_cursor->item_list;
|
||||
select_cursor->with_wild= 0;
|
||||
if (setup_ref_array(thd, &select_cursor->ref_pointer_array,
|
||||
(item_list.elements + select_cursor->with_sum_func +
|
||||
select_cursor->order_list.elements +
|
||||
select_cursor->group_list.elements)) ||
|
||||
setup_fields(thd, select_cursor->ref_pointer_array, first_table, item_list,
|
||||
0, 0, 1))
|
||||
goto err;
|
||||
t_and_f= 1;
|
||||
@ -165,7 +166,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result,
|
||||
tmp_table_param.field_count=item_list.elements;
|
||||
if (!(table= create_tmp_table(thd, &tmp_table_param, item_list,
|
||||
(ORDER*) 0, !union_option,
|
||||
1, (first_select()->options | thd->options |
|
||||
1, (select_cursor->options | thd->options |
|
||||
TMP_TABLE_ALL_COLUMNS),
|
||||
HA_POS_ERROR)))
|
||||
goto err;
|
||||
@ -181,9 +182,16 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result,
|
||||
|
||||
union_result->not_describe=1;
|
||||
union_result->tmp_table_param=&tmp_table_param;
|
||||
|
||||
/*
|
||||
the following piece of code is placed here solely for the purpose of
|
||||
getting correct results with EXPLAIN when UNION is withing a sub-select
|
||||
or derived table ...
|
||||
*/
|
||||
|
||||
if (thd->lex.describe)
|
||||
{
|
||||
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
|
||||
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
|
||||
{
|
||||
JOIN *join= new JOIN(thd, sl->item_list,
|
||||
sl->options | thd->options | SELECT_NO_UNLOCK,
|
||||
@ -206,16 +214,17 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result,
|
||||
(ORDER*) sl->group_list.first,
|
||||
sl->having,
|
||||
(ORDER*) NULL,
|
||||
sl, this, 0, t_and_f);
|
||||
sl, this, t_and_f);
|
||||
t_and_f= 0;
|
||||
if (res | thd->is_fatal_error)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
item_list.empty();
|
||||
thd->lex.current_select= lex_select_save;
|
||||
{
|
||||
List_iterator<Item> it(first_select()->item_list);
|
||||
List_iterator<Item> it(select_cursor->item_list);
|
||||
Field **field;
|
||||
|
||||
for (field= table->field; *field; field++)
|
||||
@ -236,7 +245,8 @@ int st_select_lex_unit::exec()
|
||||
{
|
||||
DBUG_ENTER("st_select_lex_unit::exec");
|
||||
SELECT_LEX_NODE *lex_select_save= thd->lex.current_select;
|
||||
|
||||
SELECT_LEX *select_cursor=first_select_in_union(), *last_select;
|
||||
|
||||
if (executed && !(dependent || uncacheable))
|
||||
DBUG_RETURN(0);
|
||||
executed= 1;
|
||||
@ -249,8 +259,9 @@ int st_select_lex_unit::exec()
|
||||
item->reset();
|
||||
table->file->delete_all_rows();
|
||||
}
|
||||
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
|
||||
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
|
||||
{
|
||||
last_select=sl;
|
||||
if (optimized)
|
||||
res= sl->join->reinit();
|
||||
else
|
||||
@ -276,7 +287,7 @@ int st_select_lex_unit::exec()
|
||||
(ORDER*) sl->group_list.first,
|
||||
sl->having,
|
||||
(ORDER*) NULL,
|
||||
sl, this, 0, t_and_f);
|
||||
sl, this, t_and_f);
|
||||
t_and_f=0;
|
||||
if (res | thd->is_fatal_error)
|
||||
{
|
||||
@ -307,7 +318,7 @@ int st_select_lex_unit::exec()
|
||||
/* Send result to 'result' */
|
||||
|
||||
// to correct ORDER BY reference resolving
|
||||
thd->lex.current_select = first_select();
|
||||
thd->lex.current_select = select_cursor;
|
||||
res =-1;
|
||||
{
|
||||
#if 0
|
||||
@ -321,9 +332,10 @@ int st_select_lex_unit::exec()
|
||||
|
||||
if (!thd->is_fatal_error) // Check if EOM
|
||||
{
|
||||
SELECT_LEX *sl=thd->lex.current_select->master_unit()->first_select();
|
||||
offset_limit_cnt= (sl->braces) ? global_parameters->offset_limit : 0;
|
||||
select_limit_cnt= (sl->braces) ? global_parameters->select_limit+
|
||||
SELECT_LEX *fake_select = new SELECT_LEX();
|
||||
fake_select->make_empty_select(last_select);
|
||||
offset_limit_cnt= (select_cursor->braces) ? global_parameters->offset_limit : 0;
|
||||
select_limit_cnt= (select_cursor->braces) ? global_parameters->select_limit+
|
||||
global_parameters->offset_limit : HA_POS_ERROR;
|
||||
if (select_limit_cnt < global_parameters->select_limit)
|
||||
select_limit_cnt= HA_POS_ERROR; // no limit
|
||||
@ -334,9 +346,11 @@ 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, 0);
|
||||
thd->options, result, this, fake_select, 0);
|
||||
if (found_rows_for_union && !res)
|
||||
thd->limit_found_rows = (ulonglong)table->file->records;
|
||||
fake_select->exclude();
|
||||
delete fake_select;
|
||||
}
|
||||
}
|
||||
thd->lex.select_lex.ftfunc_list= &thd->lex.select_lex.ftfunc_list_alloc;
|
||||
@ -357,7 +371,7 @@ int st_select_lex_unit::cleanup()
|
||||
free_tmp_table(thd, table);
|
||||
table= 0; // Safety
|
||||
}
|
||||
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
|
||||
for (SELECT_LEX *sl= first_select_in_union(); sl; sl= sl->next_select())
|
||||
{
|
||||
JOIN *join;
|
||||
if ((join= sl->join))
|
||||
|
@ -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, 0);
|
||||
result, unit, select_lex, 0);
|
||||
delete result;
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user