MDEV-32113: utf8mb3_key_col=utf8mb4_value cannot be used for ref
Attempt of Implementation of Variant #1.
When the optimizer sees a condition in one of forms:
CONVERT(tbl.mb3col USING utf8mb4_general_ci) = tbl2.mb4col
CONVERT(tbl.mb3col USING utf8mb4_general_ci) = mb4expr
it will rewrite the first variant into
CONVERT(mb3col USING utf8mb4_general_ci)=mb4col // the original cond
AND
mb3col= CONVERT_NARROW(mb4col USING utf8mb3_general_ci)
the second variant is just rewritten into:
mb3col = CONVERT_NARROW(mb4expr)
Here CONVERT_NARROW is a special variant of Item_func_conv_charset that
converts UTF8MB4 into MB3 by replacing all non-BMP character with the
MY_CS_REPLACEMENT_CHARACTER (It is not supported by the parser. One
can only see it EXPLAIN or Optimizer trace).
Unlike Approach #1, We only needed to support narrowing conversion in
one place: class String_copier. It uses my_convert_fix() which now
accepts an extra argument: a custom decoder (my_charset_conv_mb_wc)
function.
The rewrite can inject CONVERT_NARROW() in addition to CONVERT(). In
order to avoid extra CPU overhead at run time, added a concept of
"equivalent extra items". An item can be marked as "equivalent extra
item". Plan generation functions in make_cond_for_table() will not
attach such items to any part of the query plan. They are assumed to
be guaranteed to be true.
d0a872c...
by
Dmitry Shulga <email address hidden>
MDEV-14959: Fixed memory leak relating with view and IS
Fixed memory leak taken place on executing a prepared statement or
a stored routine that querying a view and this view constructed
on an information schema table. For example,
Lets consider the following definition of the view 'v1'
CREATE VIEW v1 AS SELECT table_name FROM information_schema.views
ORDER BY table_name;
Querying this view in PS mode result in hit of assert.
PREPARE stmt FROM "SELECT * FROM v1";
EXECUTE stmt;
EXECUTE stmt; (*)
Running the statement marked with (*) leads to a crash in case
server build with mode to control allocation of a memory from SP/PS
memory root on the second and following executions of PS/SP.
The reason of leaking the memory is that a memory allocated on
processing of FRM file for the view requested from a PS/PS memory
root meaning that this memory be released only when a stored routine
be evicted from SP-cache or a prepared statement be deallocated
that typically happens on termination of a user session.
To fix the issue switch to a memory root specially created for
allocation of short-lived objects that requested on parsing FRM.
be02356...
by
Dmitry Shulga <email address hidden>
MDEV-14959: Fixed memory leak happened on re-parsing a view that substitutes a table
In case a table accessed by a PS/SP is dropped after the first execution of
PS/SP and a view created with the same name as a table just dropped then
the second execution of PS/SP leads to allocation of a memory on SP/PS
memory root already marked as read only on first execution.
For example, the following test case:
CREATE TABLE t1 (a INT);
PREPARE stmt FROM "INSERT INTO t1 VALUES (1)";
EXECUTE stmt;
DROP TABLE t1;
CREATE VIEW t1 S SELECT 1;
--error ER_NON_INSERTABLE_TABLE
EXECUTE stmt; # (*)
DROP VIEW t1;
will hit assert on running the statement 'EXECUTE stmt' marked with (*)
when allocation of a memory be performed on parsing the view.
Memory allocation is requested inside the function mysql_make_view
when a view definition being parsed. In order to avoid an assertion
failure, call of the function mysql_make_view() must be moved after
invocation of the function check_and_update_table_version().
It will result in re-preparing the whole PS statement or current
SP instruction that will free currently allocated items and reset
read_only flag for the memory root.
1d502a2...
by
Dmitry Shulga <email address hidden>
MDEV-14959: Fixed possible memory leaks that could happen on running PS/SP depending on a trigger
Moved call of the function check_and_update_table_version() just
before the place where the function extend_table_list() is invoked
in order to avoid allocation of memory on a PS/SP memory root
marked as read only. It happens by the reason that the function
extend_table_list() invokes sp_add_used_routine() to add a trigger
created for the table in time frame between execution the statement
EXECUTE `stmt_id` .
For example, the following test case
create table t1 (a int);
prepare stmt from "insert into t1 (a) value (1)";
execute stmt;
create trigger t1_bi before insert on t1 for each row
set @message= new.a;
execute stmt; # (*)
adds the trigger t1_bi to a list of used routines that involves
allocation of a memory on PS memory root that has been already marked
as read only on first run of the statement 'execute stmt'.
In result, when the statement marked with (*) is executed it results in
assert hit.
To fix the issue call the function check_and_update_table_version()
before invocation of extend_table_list() to force re-compilation of
PS/SP that resets read-only flag of its memory root.