Commit acda3d79 authored by unknown's avatar unknown

fixed memory overrun (bug 380)


mysql-test/r/func_group.result:
  new tests
mysql-test/t/func_group.test:
  new tests
sql/item.cc:
  count items in select list
sql/item_subselect.cc:
  use number of item in select list for array creation
sql/item_sum.cc:
  with_sum_func now is boolean
sql/sql_derived.cc:
  use number of item in select list for array creation
sql/sql_lex.cc:
  create_refs changed with parsing_place enum variable
sql/sql_lex.h:
  added items in select list counter
  create_refs changed with parsing_place enum variable
  with_sum_func now is boolean
sql/sql_select.cc:
  use number of item in select list for array creation
sql/sql_union.cc:
  use number of item in select list for array creation
sql/sql_yacc.yy:
  create_refs changed with parsing_place enum variable
parent ddabd51c
......@@ -561,4 +561,13 @@ select concat(min(t1.a1),min(t2.a4)) from t1, t2 where t2.a4 <> 'AME';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 3 NULL 14 Using index
1 SIMPLE t2 index NULL k2 4 NULL 6 Using where; Using index
drop table if exists t1, t2;
drop table t1, t2;
create table t1 (USR_ID integer not null, MAX_REQ integer not null, constraint PK_SEA_USER primary key (USR_ID)) type=InnoDB;
insert into t1 values (1, 3);
select count(*) + MAX_REQ - MAX_REQ + MAX_REQ - MAX_REQ + MAX_REQ - MAX_REQ + MAX_REQ - MAX_REQ + MAX_REQ - MAX_REQ from t1 group by MAX_REQ;
count(*) + MAX_REQ - MAX_REQ + MAX_REQ - MAX_REQ + MAX_REQ - MAX_REQ + MAX_REQ - MAX_REQ + MAX_REQ - MAX_REQ
1
select Case When Count(*) < MAX_REQ Then 1 Else 0 End from t1 where t1.USR_ID = 1 group by MAX_REQ;
Case When Count(*) < MAX_REQ Then 1 Else 0 End
1
drop table t1;
......@@ -326,6 +326,11 @@ explain
select min(a4) from t1 where (a4 + 0.01) between 0.07 and 0.08;
explain
select concat(min(t1.a1),min(t2.a4)) from t1, t2 where t2.a4 <> 'AME';
drop table t1, t2;
create table t1 (USR_ID integer not null, MAX_REQ integer not null, constraint PK_SEA_USER primary key (USR_ID)) type=InnoDB;
insert into t1 values (1, 3);
select count(*) + MAX_REQ - MAX_REQ + MAX_REQ - MAX_REQ + MAX_REQ - MAX_REQ + MAX_REQ - MAX_REQ + MAX_REQ - MAX_REQ from t1 group by MAX_REQ;
select Case When Count(*) < MAX_REQ Then 1 Else 0 End from t1 where t1.USR_ID = 1 group by MAX_REQ;
drop table t1;
# Clean up
drop table if exists t1, t2;
\ No newline at end of file
......@@ -46,6 +46,8 @@ Item::Item():
next= thd->free_list; // Put in free list
thd->free_list= this;
loop_id= 0;
if (thd->lex.current_select->parsing_place == SELECT_LEX_NODE::SELECT_LIST)
thd->lex.current_select->select_items++;
}
/*
......
......@@ -492,7 +492,7 @@ void Item_in_subselect::single_value_transformer(THD *thd,
{
sl->item_list.push_back(item);
setup_ref_array(thd, &sl->ref_pointer_array,
1 + sl->with_sum_func +
1 + sl->select_items +
sl->order_list.elements + sl->group_list.elements);
// To prevent crash on Item_ref_null_helper destruction in case of error
sl->ref_pointer_array[0]= 0;
......
......@@ -57,8 +57,7 @@ Item_sum::Item_sum(THD *thd, Item_sum &item):
void Item_sum::mark_as_sum_func()
{
current_thd->lex.current_select->with_sum_func++;
with_sum_func= 1;
current_thd->lex.current_select->with_sum_func= with_sum_func= 1;
}
......
......@@ -125,7 +125,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
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 +
(item_list.elements + select_cursor->select_items +
select_cursor->order_list.elements +
select_cursor->group_list.elements)) ||
setup_fields(thd, select_cursor->ref_pointer_array, first_table, item_list,
......
......@@ -111,7 +111,8 @@ LEX *lex_start(THD *thd, uchar *buf,uint length)
lex->next_state=MY_LEX_START;
lex->end_of_query=(lex->ptr=buf)+length;
lex->yylineno = 1;
lex->select_lex.create_refs=lex->in_comment=0;
lex->select_lex.parsing_place= SELECT_LEX_NODE::NO_MATTER;
lex->in_comment=0;
lex->length=0;
lex->select_lex.in_sum_expr=0;
lex->select_lex.expr_list.empty();
......@@ -973,8 +974,9 @@ void st_select_lex_node::init_select()
order_list.next= (byte**) &order_list.first;
select_limit= HA_POS_ERROR;
offset_limit= 0;
select_items= 0;
with_sum_func= 0;
create_refs= 0;
parsing_place= SELECT_LEX_NODE::NO_MATTER;
}
void st_select_lex_unit::init_query()
......
......@@ -77,7 +77,6 @@ enum enum_sql_command {
SQLCOM_END
};
typedef List<Item> List_item;
typedef struct st_lex_master_info
......@@ -191,6 +190,13 @@ class st_select_lex_node {
*master, *slave, /* vertical links */
*link_next, **link_prev; /* list of whole SELECT_LEX */
public:
enum enum_parsing_place
{
NO_MATTER,
IN_HAVING,
SELECT_LIST
};
ulong options;
enum sub_select_type linkage;
SQL_LIST order_list; /* ORDER clause */
......@@ -200,8 +206,9 @@ class st_select_lex_node {
// Arrays of pointers to top elements of all_fields list
Item **ref_pointer_array;
uint with_sum_func; /* sum function indicator and number of it */
bool create_refs;
uint select_items; /* number of items in select_list */
enum_parsing_place parsing_place; /* where we are parsing expression */
bool with_sum_func; /* sum function indicator */
bool dependent; /* dependent from outer select subselect */
bool uncacheable; /* result of this query can't be cached */
bool no_table_names_allowed; /* used for global order by */
......
......@@ -289,7 +289,7 @@ JOIN::prepare(Item ***rref_pointer_array,
fields_list,
&all_fields, wild_num))) ||
setup_ref_array(thd, rref_pointer_array, (fields_list.elements +
select_lex->with_sum_func +
select_lex->select_items +
og_num)) ||
setup_fields(thd, (*rref_pointer_array), tables_list, fields_list, 1,
&all_fields, 1) ||
......
......@@ -159,7 +159,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result,
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 +
(item_list.elements + select_cursor->select_items +
select_cursor->order_list.elements +
select_cursor->group_list.elements)) ||
setup_fields(thd, select_cursor->ref_pointer_array, first_table,
......
......@@ -925,8 +925,13 @@ create3:
LEX *lex=Lex;
lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
mysql_init_select(lex);
lex->current_select->parsing_place= SELECT_LEX_NODE::SELECT_LIST;
}
select_options select_item_list opt_select_from union_clause {}
select_options select_item_list
{
Select->parsing_place= SELECT_LEX_NODE::NO_MATTER;
}
opt_select_from union_clause {}
;
opt_as:
......@@ -1883,8 +1888,13 @@ select_part2:
lex->lock_option= TL_READ; /* Only for global SELECT */
if (sel->linkage != UNION_TYPE)
mysql_init_select(lex);
lex->current_select->parsing_place= SELECT_LEX_NODE::SELECT_LIST;
}
select_options select_item_list
{
Select->parsing_place= SELECT_LEX_NODE::NO_MATTER;
}
select_options select_item_list select_into select_lock_type;
select_into select_lock_type;
select_into:
opt_limit_clause {}
......@@ -2917,10 +2927,15 @@ where_clause:
having_clause:
/* empty */
| HAVING { Select->select_lex()->create_refs= 1; } expr
| HAVING
{
Select->select_lex()->parsing_place= SELECT_LEX_NODE::IN_HAVING;
}
expr
{
SELECT_LEX *sel= Select->select_lex();
sel->having= $3; sel->create_refs=0;
sel->having= $3;
sel->parsing_place= SELECT_LEX_NODE::NO_MATTER;
if ($3)
$3->top_level_item();
}
......@@ -3348,8 +3363,13 @@ insert_values:
SQLCOM_INSERT_SELECT : SQLCOM_REPLACE_SELECT);
lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
mysql_init_select(lex);
lex->current_select->parsing_place= SELECT_LEX_NODE::SELECT_LIST;
}
select_options select_item_list
{
Select->parsing_place= SELECT_LEX_NODE::NO_MATTER;
}
select_options select_item_list opt_select_from select_lock_type
opt_select_from select_lock_type
union_clause {}
;
......@@ -4030,7 +4050,10 @@ simple_ident:
ident
{
SELECT_LEX_NODE *sel=Select;
$$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field(NullS,NullS,$1.str) : (Item*) new Item_ref(NullS,NullS,$1.str);
$$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING ||
sel->get_in_sum_expr() > 0) ?
(Item*) new Item_field(NullS,NullS,$1.str) :
(Item*) new Item_ref(NullS,NullS,$1.str);
}
| ident '.' ident
{
......@@ -4043,7 +4066,10 @@ simple_ident:
ER(ER_TABLENAME_NOT_ALLOWED_HERE),
MYF(0), $1.str, thd->where);
}
$$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field(NullS,$1.str,$3.str) : (Item*) new Item_ref(NullS,$1.str,$3.str);
$$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING ||
sel->get_in_sum_expr() > 0) ?
(Item*) new Item_field(NullS,$1.str,$3.str) :
(Item*) new Item_ref(NullS,$1.str,$3.str);
}
| '.' ident '.' ident
{
......@@ -4056,7 +4082,10 @@ simple_ident:
ER(ER_TABLENAME_NOT_ALLOWED_HERE),
MYF(0), $2.str, thd->where);
}
$$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field(NullS,$2.str,$4.str) : (Item*) new Item_ref(NullS,$2.str,$4.str);
$$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING ||
sel->get_in_sum_expr() > 0) ?
(Item*) new Item_field(NullS,$2.str,$4.str) :
(Item*) new Item_ref(NullS,$2.str,$4.str);
}
| ident '.' ident '.' ident
{
......@@ -4069,7 +4098,14 @@ simple_ident:
ER(ER_TABLENAME_NOT_ALLOWED_HERE),
MYF(0), $3.str, thd->where);
}
$$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field((YYTHD->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str) : (Item*) new Item_ref((YYTHD->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str);
$$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING ||
sel->get_in_sum_expr() > 0) ?
(Item*) new Item_field((YYTHD->client_capabilities &
CLIENT_NO_SCHEMA ? NullS : $1.str),
$3.str, $5.str) :
(Item*) new Item_ref((YYTHD->client_capabilities &
CLIENT_NO_SCHEMA ? NullS : $1.str),
$3.str, $5.str);
};
......
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