MDEV-17017 Explain for query using derived table specified with
a table value constructor shows wrong number of rows This is another attempt to fix this bug. The previous patch did not take into account that a transformation for ALL/ANY subqueries could be applied to the materialized table that wrapped the table value constructor used as a specification of the subselect used an ALL/ANY subquery. In this case the result of the derived table used a sink of the class select_subselect rather than of the class select_unit. Thus the previous fix could cause memory overwrites when running EXPLAIN for queries with table value constructors in ALL/ANY subselects.
This commit is contained in:
parent
a290b807e8
commit
497d86276f
@ -1123,5 +1123,3 @@ PREPARE stmt FROM "SELECT * FROM (VALUES(1 + 1,2,'abc')) t";
|
||||
EXECUTE stmt;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
|
||||
|
@ -4956,7 +4956,8 @@ protected:
|
||||
SELECT_LEX_UNIT *unit;
|
||||
/* Something used only by the parser: */
|
||||
public:
|
||||
select_result(THD *thd_arg): select_result_sink(thd_arg) {}
|
||||
ha_rows est_records; /* estimated number of records in the result */
|
||||
select_result(THD *thd_arg): select_result_sink(thd_arg), est_records(0) {}
|
||||
void set_unit(SELECT_LEX_UNIT *unit_arg) { unit= unit_arg; }
|
||||
virtual ~select_result() {};
|
||||
/**
|
||||
@ -5528,7 +5529,6 @@ public:
|
||||
TMP_TABLE_PARAM tmp_table_param;
|
||||
int write_err; /* Error code from the last send_data->ha_write_row call. */
|
||||
TABLE *table;
|
||||
ha_rows records;
|
||||
|
||||
select_unit(THD *thd_arg):
|
||||
select_result_interceptor(thd_arg),
|
||||
@ -5566,7 +5566,6 @@ public:
|
||||
curr_sel= UINT_MAX;
|
||||
step= UNION_TYPE;
|
||||
write_err= 0;
|
||||
records= 0;
|
||||
}
|
||||
void change_select();
|
||||
};
|
||||
|
@ -4678,18 +4678,18 @@ void SELECT_LEX::increase_derived_records(ha_rows records)
|
||||
return;
|
||||
}
|
||||
|
||||
select_unit *result= (select_unit*)unit->result;
|
||||
select_result *result= unit->result;
|
||||
switch (linkage)
|
||||
{
|
||||
case INTERSECT_TYPE:
|
||||
// result of intersect can't be more then one of components
|
||||
set_if_smaller(result->records, records);
|
||||
set_if_smaller(result->est_records, records);
|
||||
case EXCEPT_TYPE:
|
||||
// in worse case none of record will be removed
|
||||
break;
|
||||
default:
|
||||
// usual UNION
|
||||
result->records+= records;
|
||||
result->est_records+= records;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -8334,7 +8334,7 @@ int TABLE_LIST::fetch_number_of_rows()
|
||||
}
|
||||
if (is_materialized_derived() && !fill_me)
|
||||
{
|
||||
table->file->stats.records= ((select_unit*)(get_unit()->result))->records;
|
||||
table->file->stats.records= get_unit()->result->est_records;
|
||||
set_if_bigger(table->file->stats.records, 2);
|
||||
table->used_stat_records= table->file->stats.records;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user