Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-4.1
into sanja.is.com.ua:/home/bell/mysql/bk/work-4.1
This commit is contained in:
commit
80d9cafa8f
@ -2128,7 +2128,7 @@ drop table t1;
|
||||
create table t1 (a1 int);
|
||||
create table t2 (b1 int);
|
||||
select * from t1 where a2 > any(select b1 from t2);
|
||||
ERROR 42S22: Unknown column 'a2' in 'scalar IN/ALL/ANY subquery'
|
||||
ERROR 42S22: Unknown column 'a2' in 'IN/ALL/ANY subquery'
|
||||
select * from t1 where a1 > any(select b1 from t2);
|
||||
a1
|
||||
drop table t1,t2;
|
||||
@ -2267,4 +2267,12 @@ pass userid parentid parentgroup childid groupname grouptypeid crse categoryid c
|
||||
1 5141 12 group2 12 group2 5 1 1 87 Oct04
|
||||
1 5141 12 group2 12 group2 5 1 2 88 Oct04
|
||||
1 5141 12 group2 12 group2 5 1 2 89 Oct04
|
||||
drop table if exists t1, t2, t3, t4, t5;
|
||||
drop table t1, t2, t3, t4, t5;
|
||||
create table t1 (a int);
|
||||
insert into t1 values (1), (2), (3);
|
||||
SELECT 1 FROM t1 WHERE (SELECT 1) in (SELECT 1);
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
drop table t1;
|
||||
|
@ -1438,8 +1438,9 @@ select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
|
||||
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx from DUAL;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test for BUG#8218
|
||||
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
categoryId int(11) NOT NULL,
|
||||
courseId int(11) NOT NULL,
|
||||
@ -1536,5 +1537,12 @@ join
|
||||
group by
|
||||
groupstuff.groupname, colhead , t2.courseid;
|
||||
|
||||
drop table if exists t1, t2, t3, t4, t5;
|
||||
drop table t1, t2, t3, t4, t5;
|
||||
|
||||
#
|
||||
# Transformation in left expression of subquery (BUG#8888)
|
||||
#
|
||||
create table t1 (a int);
|
||||
insert into t1 values (1), (2), (3);
|
||||
SELECT 1 FROM t1 WHERE (SELECT 1) in (SELECT 1);
|
||||
drop table t1;
|
||||
|
@ -542,7 +542,7 @@ bool Item_in_subselect::test_limit(SELECT_LEX_UNIT *unit)
|
||||
|
||||
Item_in_subselect::Item_in_subselect(Item * left_exp,
|
||||
st_select_lex *select_lex):
|
||||
Item_exists_subselect(), transformed(0), upper_item(0)
|
||||
Item_exists_subselect(), optimizer(0), transformed(0), upper_item(0)
|
||||
{
|
||||
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
|
||||
left_expr= left_exp;
|
||||
@ -669,18 +669,9 @@ Item_subselect::trans_res
|
||||
Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
Comp_creator *func)
|
||||
{
|
||||
const char *save_where= thd->where;
|
||||
DBUG_ENTER("Item_in_subselect::single_value_transformer");
|
||||
|
||||
if (changed)
|
||||
{
|
||||
DBUG_RETURN(RES_OK);
|
||||
}
|
||||
|
||||
SELECT_LEX *select_lex= join->select_lex;
|
||||
Item_arena *arena, backup;
|
||||
arena= thd->change_arena_if_needed(&backup);
|
||||
thd->where= "scalar IN/ALL/ANY subquery";
|
||||
|
||||
/*
|
||||
Check that the right part of the subselect contains no more than one
|
||||
@ -689,7 +680,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
if (select_lex->item_list.elements > 1)
|
||||
{
|
||||
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
|
||||
goto err;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -709,7 +700,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
if (substitution)
|
||||
{
|
||||
// It is second (third, ...) SELECT of UNION => All is done
|
||||
goto ok;
|
||||
DBUG_RETURN(RES_OK);
|
||||
}
|
||||
|
||||
Item *subs;
|
||||
@ -748,7 +739,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
reference
|
||||
*/
|
||||
if (item->fix_fields(thd, join->tables_list, 0))
|
||||
goto err;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
/* we added aggregate function => we have to change statistic */
|
||||
count_field_types(&join->tmp_table_param, join->all_fields, 0);
|
||||
|
||||
@ -764,25 +755,16 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
if (upper_item)
|
||||
upper_item->set_sub_test(item);
|
||||
}
|
||||
// left expression belong to outer select
|
||||
SELECT_LEX *current= thd->lex->current_select, *up;
|
||||
thd->lex->current_select= up= current->return_after_parsing();
|
||||
if (!left_expr->fixed &&
|
||||
left_expr->fix_fields(thd, up->get_table_list(), &left_expr))
|
||||
{
|
||||
thd->lex->current_select= current;
|
||||
goto err;
|
||||
}
|
||||
thd->lex->current_select= current;
|
||||
/* fix fields is already called for left expression */
|
||||
substitution= func->create(left_expr, subs);
|
||||
goto ok;
|
||||
DBUG_RETURN(RES_OK);
|
||||
}
|
||||
|
||||
if (!substitution)
|
||||
{
|
||||
//first call for this unit
|
||||
SELECT_LEX_UNIT *unit= select_lex->master_unit();
|
||||
substitution= optimizer= new Item_in_optimizer(left_expr, this);
|
||||
substitution= optimizer;
|
||||
|
||||
SELECT_LEX *current= thd->lex->current_select, *up;
|
||||
|
||||
@ -791,7 +773,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0))
|
||||
{
|
||||
thd->lex->current_select= current;
|
||||
goto err;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
thd->lex->current_select= current;
|
||||
|
||||
@ -835,7 +817,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
if (join->having->fix_fields(thd, join->tables_list, 0))
|
||||
{
|
||||
select_lex->having_fix_field= 0;
|
||||
goto err;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
select_lex->having_fix_field= 0;
|
||||
}
|
||||
@ -865,7 +847,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
if (join->having->fix_fields(thd, join->tables_list, 0))
|
||||
{
|
||||
select_lex->having_fix_field= 0;
|
||||
goto err;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
select_lex->having_fix_field= 0;
|
||||
item= new Item_cond_or(item,
|
||||
@ -879,7 +861,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
*/
|
||||
select_lex->where= join->conds= and_items(join->conds, item);
|
||||
if (join->conds->fix_fields(thd, join->tables_list, 0))
|
||||
goto err;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -901,7 +883,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
0))
|
||||
{
|
||||
select_lex->having_fix_field= 0;
|
||||
goto err;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
select_lex->having_fix_field= 0;
|
||||
}
|
||||
@ -919,54 +901,34 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_SELECT_REDUCED, warn_buff);
|
||||
}
|
||||
if (arena)
|
||||
thd->restore_backup_item_arena(arena, &backup);
|
||||
DBUG_RETURN(RES_REDUCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ok:
|
||||
if (arena)
|
||||
thd->restore_backup_item_arena(arena, &backup);
|
||||
thd->where= save_where;
|
||||
DBUG_RETURN(RES_OK);
|
||||
|
||||
err:
|
||||
if (arena)
|
||||
thd->restore_backup_item_arena(arena, &backup);
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
|
||||
|
||||
Item_subselect::trans_res
|
||||
Item_in_subselect::row_value_transformer(JOIN *join)
|
||||
{
|
||||
const char *save_where= thd->where;
|
||||
DBUG_ENTER("Item_in_subselect::row_value_transformer");
|
||||
|
||||
if (changed)
|
||||
{
|
||||
DBUG_RETURN(RES_OK);
|
||||
}
|
||||
Item_arena *arena, backup;
|
||||
Item *item= 0;
|
||||
SELECT_LEX *select_lex= join->select_lex;
|
||||
|
||||
thd->where= "row IN/ALL/ANY subquery";
|
||||
arena= thd->change_arena_if_needed(&backup);
|
||||
|
||||
if (select_lex->item_list.elements != left_expr->cols())
|
||||
{
|
||||
my_error(ER_OPERAND_COLUMNS, MYF(0), left_expr->cols());
|
||||
goto err;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
|
||||
if (!substitution)
|
||||
{
|
||||
//first call for this unit
|
||||
SELECT_LEX_UNIT *unit= select_lex->master_unit();
|
||||
substitution= optimizer= new Item_in_optimizer(left_expr, this);
|
||||
substitution= optimizer;
|
||||
|
||||
SELECT_LEX *current= thd->lex->current_select, *up;
|
||||
thd->lex->current_select= up= current->return_after_parsing();
|
||||
@ -974,7 +936,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
|
||||
if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0))
|
||||
{
|
||||
thd->lex->current_select= current;
|
||||
goto err;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
|
||||
// we will refer to apper level cache array => we have to save it in PS
|
||||
@ -993,7 +955,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
|
||||
DBUG_ASSERT(left_expr->fixed && select_lex->ref_pointer_array[i]->fixed);
|
||||
if (select_lex->ref_pointer_array[i]->
|
||||
check_cols(left_expr->el(i)->cols()))
|
||||
goto err;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
Item *func= new Item_ref_null_helper(this,
|
||||
select_lex->ref_pointer_array+i,
|
||||
(char *) "<no matter>",
|
||||
@ -1021,7 +983,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
|
||||
if (join->having->fix_fields(thd, join->tables_list, 0))
|
||||
{
|
||||
select_lex->having_fix_field= 0;
|
||||
goto err;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
select_lex->having_fix_field= 0;
|
||||
}
|
||||
@ -1034,27 +996,109 @@ Item_in_subselect::row_value_transformer(JOIN *join)
|
||||
*/
|
||||
select_lex->where= join->conds= and_items(join->conds, item);
|
||||
if (join->conds->fix_fields(thd, join->tables_list, 0))
|
||||
goto err;
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
if (arena)
|
||||
thd->restore_backup_item_arena(arena, &backup);
|
||||
thd->where= save_where;
|
||||
DBUG_RETURN(RES_OK);
|
||||
|
||||
err:
|
||||
if (arena)
|
||||
thd->restore_backup_item_arena(arena, &backup);
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
|
||||
|
||||
Item_subselect::trans_res
|
||||
Item_in_subselect::select_transformer(JOIN *join)
|
||||
{
|
||||
return select_in_like_transformer(join, &eq_creator);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Prepare IN/ALL/ANY/SOME subquery transformation and call appropriate
|
||||
transformation function
|
||||
|
||||
SYNOPSIS
|
||||
Item_in_subselect::select_in_like_transformer()
|
||||
join JOIN object of transforming subquery
|
||||
func creator of condition function of subquery
|
||||
|
||||
DESCRIPTION
|
||||
To decide which transformation procedure (scalar or row) applicable here
|
||||
we have to call fix_fields() for left expression to be able to call
|
||||
cols() method on it. Also this method make arena management for
|
||||
underlying transformation methods.
|
||||
|
||||
RETURN
|
||||
RES_OK OK
|
||||
RES_REDUCE OK, and current subquery was reduced during transformation
|
||||
RES_ERROR Error
|
||||
*/
|
||||
|
||||
Item_subselect::trans_res
|
||||
Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
|
||||
{
|
||||
Item_arena *arena, backup;
|
||||
SELECT_LEX *current= thd->lex->current_select, *up;
|
||||
const char *save_where= thd->where;
|
||||
Item_subselect::trans_res res= RES_ERROR;
|
||||
bool result;
|
||||
|
||||
DBUG_ENTER("Item_in_subselect::select_in_like_transformer");
|
||||
if (changed)
|
||||
{
|
||||
DBUG_RETURN(RES_OK);
|
||||
}
|
||||
|
||||
thd->where= "IN/ALL/ANY subquery";
|
||||
|
||||
/*
|
||||
In some optimisation cases we will not need this Item_in_optimizer
|
||||
object, but we can't know it here, but here we need address correct
|
||||
reference on left expresion.
|
||||
*/
|
||||
if (!optimizer)
|
||||
{
|
||||
arena= thd->change_arena_if_needed(&backup);
|
||||
result= (!(optimizer= new Item_in_optimizer(left_expr, this)));
|
||||
if (arena)
|
||||
thd->restore_backup_item_arena(arena, &backup);
|
||||
if (result)
|
||||
goto err;
|
||||
}
|
||||
|
||||
thd->lex->current_select= up= current->return_after_parsing();
|
||||
result= (!left_expr->fixed &&
|
||||
left_expr->fix_fields(thd, up->get_table_list(),
|
||||
optimizer->arguments()));
|
||||
/* fix_fields can change reference to left_expr, we need reassign it */
|
||||
left_expr= optimizer->arguments()[0];
|
||||
|
||||
thd->lex->current_select= current;
|
||||
if (result)
|
||||
goto err;
|
||||
|
||||
transformed= 1;
|
||||
arena= thd->change_arena_if_needed(&backup);
|
||||
/*
|
||||
Both transformers call fix_fields() only for Items created inside them,
|
||||
and all that items do not make permanent changes in current item arena
|
||||
which allow to us call them with changed arena (if we do not know nature
|
||||
of Item, we have to call fix_fields() for it only with original arena to
|
||||
avoid memory leack)
|
||||
*/
|
||||
if (left_expr->cols() == 1)
|
||||
return single_value_transformer(join, &eq_creator);
|
||||
return row_value_transformer(join);
|
||||
res= single_value_transformer(join, func);
|
||||
else
|
||||
{
|
||||
/* we do not support row operation for ALL/ANY/SOME */
|
||||
if (func != &eq_creator)
|
||||
{
|
||||
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
res= row_value_transformer(join);
|
||||
}
|
||||
if (arena)
|
||||
thd->restore_backup_item_arena(arena, &backup);
|
||||
err:
|
||||
thd->where= save_where;
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
|
||||
@ -1077,7 +1121,7 @@ Item_allany_subselect::select_transformer(JOIN *join)
|
||||
transformed= 1;
|
||||
if (upper_item)
|
||||
upper_item->show= 1;
|
||||
return single_value_transformer(join, func);
|
||||
return select_in_like_transformer(join, func);
|
||||
}
|
||||
|
||||
|
||||
|
@ -220,8 +220,8 @@ public:
|
||||
|
||||
Item_in_subselect(Item * left_expr, st_select_lex *select_lex);
|
||||
Item_in_subselect()
|
||||
:Item_exists_subselect(), abort_on_null(0), transformed(0), upper_item(0)
|
||||
|
||||
:Item_exists_subselect(), optimizer(0), abort_on_null(0), transformed(0),
|
||||
upper_item(0)
|
||||
{}
|
||||
|
||||
subs_type substype() { return IN_SUBS; }
|
||||
@ -232,8 +232,8 @@ public:
|
||||
was_null= 0;
|
||||
}
|
||||
trans_res select_transformer(JOIN *join);
|
||||
trans_res single_value_transformer(JOIN *join,
|
||||
Comp_creator *func);
|
||||
trans_res select_in_like_transformer(JOIN *join, Comp_creator *func);
|
||||
trans_res single_value_transformer(JOIN *join, Comp_creator *func);
|
||||
trans_res row_value_transformer(JOIN * join);
|
||||
longlong val_int();
|
||||
double val();
|
||||
|
Loading…
x
Reference in New Issue
Block a user