diff --git a/mysql-test/main/sp-row.result b/mysql-test/main/sp-row.result index 36a371d8c04..48b33eebc7a 100644 --- a/mysql-test/main/sp-row.result +++ b/mysql-test/main/sp-row.result @@ -2313,3 +2313,44 @@ SELECT 1 LIKE 2 ESCAPE a; END; $$ ERROR 21000: Operand should contain 1 column(s) +# Start of 10.6 tests +# +# MDEV-36179 Assertion `0' failed in virtual bool Type_handler_row::Item_save_in_value(THD*, Item*, st_value*) const +# +CREATE PROCEDURE p0 (IN a ROW(a INT,b INT)) +BEGIN +SET a=ROW(0,0); +END; +/ +PREPARE s0 FROM 'CALL p0(?)'; +EXECUTE s0 USING @a; +ERROR HY000: Illegal parameter data type row for operation 'EXECUTE ... USING ?' +DROP PROCEDURE p0; +CREATE PROCEDURE p0 (INOUT a ROW(a INT,b INT)) +BEGIN +SET a=ROW(0,0); +END; +/ +PREPARE s0 FROM 'CALL p0(?)'; +EXECUTE s0 USING @a; +ERROR HY000: Illegal parameter data type row for operation 'EXECUTE ... USING ?' +DROP PROCEDURE p0; +CREATE PROCEDURE p0 (OUT a ROW(a INT,b INT)) +BEGIN +SET a=ROW(0,0); +END; +/ +PREPARE s0 FROM 'CALL p0(?)'; +EXECUTE s0 USING @a; +ERROR HY000: Illegal parameter data type row for operation 'EXECUTE ... USING ?' +DROP PROCEDURE p0; +CREATE FUNCTION f0(a ROW(a INT,b INT)) RETURNS BOOLEAN +BEGIN +RETURN FALSE; +END; +/ +PREPARE s0 FROM 'SELECT f0(?)'; +EXECUTE s0 USING @a; +ERROR HY000: Illegal parameter data type row for operation 'EXECUTE ... USING ?' +DROP FUNCTION f0; +# End of 10.6 tests diff --git a/mysql-test/main/sp-row.test b/mysql-test/main/sp-row.test index 527ff9455bd..f6bad0011d1 100644 --- a/mysql-test/main/sp-row.test +++ b/mysql-test/main/sp-row.test @@ -1544,3 +1544,64 @@ BEGIN NOT ATOMIC END; $$ DELIMITER ;$$ + + +--echo # Start of 10.6 tests + + +--echo # +--echo # MDEV-36179 Assertion `0' failed in virtual bool Type_handler_row::Item_save_in_value(THD*, Item*, st_value*) const +--echo # + +DELIMITER /; +CREATE PROCEDURE p0 (IN a ROW(a INT,b INT)) +BEGIN + SET a=ROW(0,0); +END; +/ +DELIMITER ;/ +PREPARE s0 FROM 'CALL p0(?)'; +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +EXECUTE s0 USING @a; +DROP PROCEDURE p0; + + +DELIMITER /; +CREATE PROCEDURE p0 (INOUT a ROW(a INT,b INT)) +BEGIN + SET a=ROW(0,0); +END; +/ +DELIMITER ;/ +PREPARE s0 FROM 'CALL p0(?)'; +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +EXECUTE s0 USING @a; +DROP PROCEDURE p0; + + +DELIMITER /; +CREATE PROCEDURE p0 (OUT a ROW(a INT,b INT)) +BEGIN + SET a=ROW(0,0); +END; +/ +DELIMITER ;/ +PREPARE s0 FROM 'CALL p0(?)'; +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +EXECUTE s0 USING @a; +DROP PROCEDURE p0; + + +DELIMITER /; +CREATE FUNCTION f0(a ROW(a INT,b INT)) RETURNS BOOLEAN +BEGIN + RETURN FALSE; +END; +/ +DELIMITER ;/ +PREPARE s0 FROM 'SELECT f0(?)'; +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +EXECUTE s0 USING @a; +DROP FUNCTION f0; + +--echo # End of 10.6 tests diff --git a/sql/sp_head.cc b/sql/sp_head.cc index dcd46a55e13..926da91ae0b 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2114,6 +2114,27 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, /* Arguments must be fixed in Item_func_sp::fix_fields */ DBUG_ASSERT(argp[arg_no]->fixed()); + sp_variable *spvar= m_pcont->find_variable(arg_no); + + if (!spvar) + continue; + + /* + When you get a merge conflict, please move this code + into bind_input_param(). This also applies to the similar + code in execute_procedure(). + */ + if (!spvar->field_def.type_handler()->is_scalar_type() && + dynamic_cast(argp[arg_no])) + { + // Item_param cannot store values of non-scalar data types yet + my_error(ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION, MYF(0), + spvar->field_def.type_handler()->name().ptr(), + "EXECUTE ... USING ?"); + err_status= true; + goto err_with_cleanup; + } + if ((err_status= (*func_ctx)->set_parameter(thd, arg_no, &(argp[arg_no])))) goto err_with_cleanup; } @@ -2359,11 +2380,27 @@ sp_head::execute_procedure(THD *thd, List *args) if (!arg_item) break; + /* + When you get a merge conflict, please move this code + into bind_input_param(). This also applies to the similar + code in execute_function(). + */ sp_variable *spvar= m_pcont->find_variable(i); if (!spvar) continue; + if (!spvar->field_def.type_handler()->is_scalar_type() && + dynamic_cast(arg_item)) + { + // Item_param cannot store values of non-scalar data types yet + my_error(ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION, MYF(0), + spvar->field_def.type_handler()->name().ptr(), + "EXECUTE ... USING ?"); + err_status= true; + break; + } + if (spvar->mode != sp_variable::MODE_IN) { Settable_routine_parameter *srp=