mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-24507: Server Crash using UDF in WHERE clause of VIEW
These changes are submitted under the BSD 3-clause License. The original ticket describes a server crash when using a UDF in the WHERE clause of a view. The crash also happens when using a UDF in the WHERE clause of a SELECT that uses a sub-query in the FROM clause. When the UDF does not have a _deinit function the server crashes in udf_handler::cleanup (sql/item_func.cc:3467). When the UDF has both an _init and a _deinit function but _init does not allocate memory for initid->ptr the server crashes in udf_handler::cleanup (sql/item_func.cc:3467). When the UDF has both an _init and a _deinit function and allocates/deallocates memory for initid->ptr the server crashes in the memory deallocation of the _deinit function. The sequence of events seen are: 1. A UDF, U, is created for the query. 2. The UDF _init function is called using U->initid. 3. U is cloned for the sub-query using the [default|implicit] copy constructor, resulting in V. 4. The UDF _init function is called using V->initid. U->initid and V->initid are the same value. 5. The UDF function is called. 6. The UDF _deinit function is called using U->initid. If any memory was allocated for initid->ptr it is deallocated here. 7. udf_handler::cleanup deletes the U->buffers String array. 8. The UDF _deinit function is called using V->initid. If any memory was allocated for initid->ptr it was previously deallocated and _deinit crashes the server. 9. udf_handler::cleanup deletes the V->buffers String array. V->buffers was the same values as U->buffers which was already deallocated. The server crashes. The solution is to create a[n explicit] copy constructor for udf_handler which sets not_original to true. Later, not_original is set back to false (0) after udf_handler::fix_fields has set up a new value for initid->ptr.
This commit is contained in:
@ -647,4 +647,38 @@ DROP FUNCTION avgcost;
|
||||
DROP FUNCTION avg2;
|
||||
DROP FUNCTION myfunc_double;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-24507: Server Crash using UDF in WHERE clause of VIEW
|
||||
--echo #
|
||||
|
||||
--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
|
||||
eval CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "$UDF_EXAMPLE_SO";
|
||||
|
||||
create table t1(pk int primary key, a varchar(20));
|
||||
create table t2(pk int primary key, a varchar(20));
|
||||
create view v1 as select pk, a from t1 union select pk, a from t2;
|
||||
|
||||
insert into t1 values (1, "One"), (3, "Three"), (5, "Five");
|
||||
insert into t2 values (2, "Dos"), (4, "Quatro"), (6, "Seis");
|
||||
|
||||
select pk, myfunc_int(a) from t1;
|
||||
select pk, myfunc_int(a) from t2;
|
||||
select pk, myfunc_int(a) from v1;
|
||||
select pk from t1 where myfunc_int(a) > 4;
|
||||
select pk from (select pk, a from t1) A where myfunc_int(A.a) > 4;
|
||||
|
||||
set @save_optimizer_switch = @@optimizer_switch;
|
||||
set optimizer_switch = 'derived_merge=OFF';
|
||||
select pk, myfunc_int(a) from t1;
|
||||
select pk, myfunc_int(a) from t2;
|
||||
select pk, myfunc_int(a) from v1;
|
||||
select pk from t1 where myfunc_int(a) > 4;
|
||||
select pk from (select pk, a from t1) A where myfunc_int(A.a) > 4;
|
||||
|
||||
set optimizer_switch = @save_optimizer_switch;
|
||||
drop view v1;
|
||||
drop table t2;
|
||||
drop table t1;
|
||||
drop function myfunc_int;
|
||||
|
||||
--echo # End of 10.4 tests
|
||||
|
Reference in New Issue
Block a user