diff --git a/mysql-test/main/udf.result b/mysql-test/main/udf.result index 8dc24a8dd38..53abd9c11c1 100644 --- a/mysql-test/main/udf.result +++ b/mysql-test/main/udf.result @@ -607,4 +607,68 @@ drop table t1; DROP FUNCTION avgcost; DROP FUNCTION avg2; DROP FUNCTION myfunc_double; +# +# MDEV-24507: Server Crash using UDF in WHERE clause of VIEW +# +CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB"; +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; +pk myfunc_int(a) +1 3 +3 5 +5 4 +select pk, myfunc_int(a) from t2; +pk myfunc_int(a) +2 3 +4 6 +6 4 +select pk, myfunc_int(a) from v1; +pk myfunc_int(a) +1 3 +3 5 +5 4 +2 3 +4 6 +6 4 +select pk from t1 where myfunc_int(a) > 4; +pk +3 +select pk from (select pk, a from t1) A where myfunc_int(A.a) > 4; +pk +3 +set @save_optimizer_switch = @@optimizer_switch; +set optimizer_switch = 'derived_merge=OFF'; +select pk, myfunc_int(a) from t1; +pk myfunc_int(a) +1 3 +3 5 +5 4 +select pk, myfunc_int(a) from t2; +pk myfunc_int(a) +2 3 +4 6 +6 4 +select pk, myfunc_int(a) from v1; +pk myfunc_int(a) +1 3 +3 5 +5 4 +2 3 +4 6 +6 4 +select pk from t1 where myfunc_int(a) > 4; +pk +3 +select pk from (select pk, a from t1) A where myfunc_int(A.a) > 4; +pk +3 +set optimizer_switch = @save_optimizer_switch; +drop view v1; +drop table t2; +drop table t1; +drop function myfunc_int; # End of 10.4 tests diff --git a/mysql-test/main/udf.test b/mysql-test/main/udf.test index e9823a31863..d87d446f733 100644 --- a/mysql-test/main/udf.test +++ b/mysql-test/main/udf.test @@ -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 diff --git a/sql/item_func.cc b/sql/item_func.cc index b2f2d6550f1..b3f12cec3af 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3547,6 +3547,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func, initid.const_item=func->const_item_cache; initid.decimals=func->decimals; initid.ptr=0; + not_original=0; for (uint i1= 0 ; i1 < arg_count ; i1++) buffers[i1].set_thread_specific(); diff --git a/sql/sql_udf.h b/sql/sql_udf.h index cb1954353fa..5bd2c6e5445 100644 --- a/sql/sql_udf.h +++ b/sql/sql_udf.h @@ -147,6 +147,20 @@ class udf_handler :public Sql_alloc *null_value= (my_bool) (is_null || error); } String *val_str(String *str,String *save_str); + + udf_handler(const udf_handler &orig) + { + u_d = orig.u_d; + buffers = orig.buffers; + f_args = orig.f_args; + initid = orig.initid; + num_buffer = orig.num_buffer; + error = orig.error; + is_null = orig.is_null; + initialized = orig.initialized; + args = orig.args; + not_original = true; + } };