mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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
This commit is contained in:
@ -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;
|
@ -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 @@ protected:
|
||||
*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 @@ public:
|
||||
// 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_into select_lock_type;
|
||||
select_options select_item_list
|
||||
{
|
||||
Select->parsing_place= SELECT_LEX_NODE::NO_MATTER;
|
||||
}
|
||||
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 opt_select_from select_lock_type
|
||||
select_options select_item_list
|
||||
{
|
||||
Select->parsing_place= SELECT_LEX_NODE::NO_MATTER;
|
||||
}
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user