1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00
The bug caused wrong result sets for union constructs of the form
(SELECT ... ORDER BY order_list1 [LIMIT n]) ORDER BY order_list2.
For such queries order lists were concatenated and limit clause was
completely neglected.
This commit is contained in:
igor@rurik.mysql.com
2006-04-20 22:15:38 -07:00
parent bc1f457194
commit fc7514151f
7 changed files with 127 additions and 22 deletions

View File

@ -4189,23 +4189,9 @@ mysql_new_select(LEX *lex, bool move_down)
else
{
select_lex->include_neighbour(lex->current_select);
SELECT_LEX_UNIT *unit= select_lex->master_unit();
SELECT_LEX *fake= unit->fake_select_lex;
if (!fake)
{
/*
as far as we included SELECT_LEX for UNION unit should have
fake SELECT_LEX for UNION processing
*/
if (!(fake= unit->fake_select_lex= new(lex->thd->mem_root) SELECT_LEX()))
return 1;
fake->include_standalone(unit,
(SELECT_LEX_NODE**)&unit->fake_select_lex);
fake->select_number= INT_MAX;
fake->make_empty_select();
fake->linkage= GLOBAL_OPTIONS_TYPE;
fake->select_limit= HA_POS_ERROR;
}
if (!select_lex->master_unit()->fake_select_lex &&
select_lex->master_unit()->add_fake_select_lex(lex->thd))
return 1;
}
select_lex->master_unit()->global_parameters= select_lex;
@ -4975,6 +4961,60 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
}
/*
Create a fake SELECT_LEX for a unit
SYNOPSIS:
add_fake_select_lex()
thd thread handle
DESCRIPTION
The method create a fake SELECT_LEX object for a unit.
This object is created for any union construct containing a union
operation and also for any single select union construct of the form
(SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
or of the form
(SELECT ... ORDER BY LIMIT n) ORDER BY ...
NOTES
The object is used to retrieve rows from the temporary table
where the result on the union is obtained.
RETURN VALUES
1 on failure to create the object
0 on success
*/
bool st_select_lex_unit::add_fake_select_lex(THD *thd)
{
SELECT_LEX *first_sl= first_select();
DBUG_ENTER("add_fake_select_lex");
DBUG_ASSERT(!fake_select_lex);
if (!(fake_select_lex= new (thd->mem_root) SELECT_LEX()))
DBUG_RETURN(1);
fake_select_lex->include_standalone(this,
(SELECT_LEX_NODE**)&fake_select_lex);
fake_select_lex->select_number= INT_MAX;
fake_select_lex->make_empty_select();
fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
fake_select_lex->select_limit= HA_POS_ERROR;
if (!first_sl->next_select())
{
/*
This works only for
(SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m],
(SELECT ... LIMIT n) ORDER BY order_list [LIMIT m]
just before the parser starts processing order_list
*/
global_parameters= fake_select_lex;
fake_select_lex->no_table_names_allowed= 1;
thd->lex->current_select= fake_select_lex;
}
DBUG_RETURN(0);
}
void add_join_on(TABLE_LIST *b,Item *expr)
{
if (expr)