Commit 7e4da9b3 authored by Oleksandr Byelkin's avatar Oleksandr Byelkin

DEV-8632 Segmentation fault on INSERT

View/derived fields should be taken into account when we build ref_pointer_array constructed.

DBUG_ASSERTs added to avoid memory overrun.
parent 5d754fce
......@@ -5479,6 +5479,39 @@ UPDATE t1, t2 SET a = 1 WHERE a IN ( SELECT 0 FROM v3 );
EXECUTE stmt;
DROP TABLE t1, t2, t3;
DROP VIEW v3;
#
# MDEV-8632: Segmentation fault on INSERT
#
CREATE TABLE `t1` (
`id` int(10) unsigned NOT NULL,
`r` float NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
create view v1 as select id, if(r=r,1,2) as d from t1;
create view v2 as
select id,
d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d as p
from v1;
insert into t1 (id, r)
select id,p from
(
select id,
d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d as p
from (
select id, if(r=r,1,2) as d
from t1
) a
) b
on duplicate key update r=p;
insert into t1 (id, r)
select id,p from v2
on duplicate key update r=p;
prepare stmt from "insert into t1 (id, r) select id,p from v2 on duplicate key update r=p";
execute stmt;
execute stmt;
deallocate prepare stmt;
drop view v1,v2;
drop table `t1`;
# -----------------------------------------------------------------
# -- End of 5.5 tests.
# -----------------------------------------------------------------
......
......@@ -5445,6 +5445,41 @@ EXECUTE stmt;
DROP TABLE t1, t2, t3;
DROP VIEW v3;
--echo #
--echo # MDEV-8632: Segmentation fault on INSERT
--echo #
CREATE TABLE `t1` (
`id` int(10) unsigned NOT NULL,
`r` float NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
create view v1 as select id, if(r=r,1,2) as d from t1;
create view v2 as
select id,
d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d as p
from v1;
insert into t1 (id, r)
select id,p from
(
select id,
d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d+d as p
from (
select id, if(r=r,1,2) as d
from t1
) a
) b
on duplicate key update r=p;
insert into t1 (id, r)
select id,p from v2
on duplicate key update r=p;
prepare stmt from "insert into t1 (id, r) select id,p from v2 on duplicate key update r=p";
execute stmt;
execute stmt;
deallocate prepare stmt;
drop view v1,v2;
drop table `t1`;
--echo # -----------------------------------------------------------------
--echo # -- End of 5.5 tests.
--echo # -----------------------------------------------------------------
......
......@@ -1891,6 +1891,8 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array,
*/
Item_aggregate_ref *item_ref;
uint el= fields.elements;
DBUG_ASSERT(fields.elements <=
thd->lex->current_select->ref_pointer_array_size);
/*
If this is an item_ref, get the original item
This is a safety measure if this is called for things that is
......@@ -6719,6 +6721,7 @@ Item *Item_field::update_value_transformer(uchar *select_arg)
{
List<Item> *all_fields= &select->join->all_fields;
Item **ref_pointer_array= select->ref_pointer_array;
DBUG_ASSERT(all_fields->elements <= select->ref_pointer_array_size);
int el= all_fields->elements;
Item_ref *ref;
......
......@@ -427,6 +427,7 @@ fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
if (ref_pointer_array && !ref->found_in_select_list)
{
int el= all_fields.elements;
DBUG_ASSERT(all_fields.elements <= select->ref_pointer_array_size);
ref_pointer_array[el]= item;
/* Add the field item to the select list of the current select. */
all_fields.push_front(item);
......@@ -832,6 +833,7 @@ JOIN::prepare(Item ***rref_pointer_array,
{
Item_field *field= new Item_field(thd, *(Item_field**)ord->item);
int el= all_fields.elements;
DBUG_ASSERT(all_fields.elements <= select_lex->ref_pointer_array_size);
ref_pointer_array[el]= field;
all_fields.push_front(field);
ord->item= ref_pointer_array + el;
......@@ -20596,6 +20598,8 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
return TRUE; /* Wrong field. */
uint el= all_fields.elements;
DBUG_ASSERT(all_fields.elements <=
thd->lex->current_select->ref_pointer_array_size);
all_fields.push_front(order_item); /* Add new field to field list. */
ref_pointer_array[el]= order_item;
/*
......@@ -20855,6 +20859,8 @@ create_distinct_group(THD *thd, Item **ref_pointer_array,
*/
Item_field *new_item= new Item_field(thd, (Item_field*)item);
int el= all_fields.elements;
DBUG_ASSERT(all_fields.elements <=
thd->lex->current_select->ref_pointer_array_size);
orig_ref_pointer_array[el]= new_item;
all_fields.push_front(new_item);
ord->item= orig_ref_pointer_array + el;
......
......@@ -1520,6 +1520,11 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
*/
lex->sql_command= old_lex->sql_command;
lex->duplicates= old_lex->duplicates;
/* Fields in this view can be used in upper select in case of merge. */
if (table->select_lex)
table->select_lex->select_n_where_fields+=
lex->select_lex.select_n_where_fields;
}
/*
This method has a dependency on the proper lock type being set,
......
......@@ -9872,6 +9872,15 @@ table_factor:
sel->add_joined_table($$);
lex->pop_context();
lex->nest_level--;
/*
Fields in derived table can be used in upper select in
case of merge. We do not add HAVING fields because we do
not merge such derived. We do not add union because
also do not merge them
*/
if (!sel->next_select())
$2->select_n_where_fields+=
sel->select_n_where_fields;
}
/*else if (($3->select_lex &&
$3->select_lex->master_unit()->is_union() &&
......
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