mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-36179 Assertion `0' failed in virtual bool Type_handler_row::Item_save_in_value(THD*, Item*, st_value*) const
sp_head::execute_procedure() and sp_head::execute_function() did not check that Item_param could be passed as an actual parameter to a ROW type formal parameter of a stored routine. Example: CREATE PROCEDURE p0(OUT a ROW(a INT,b INT)) ...; PREPARE s0 'CALL p0(?)'; EXECUTE p0 USING @a; In case of passing a user variable as an OUT parameter it led to a crash after executing routine instructions, when copying formal OUT parameters to the bound actual parameters. Fix: Check cases when Item_param is being bound to a ROW type formal parameter. Raise an error if so. The new check is done for all parameter modes: IN, OUT, INOUT, for a consistent error message. The new check is done before executing the routine instructions.
This commit is contained in:
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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<Item_param*>(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<Item> *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<Item_param*>(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=
|
||||
|
Reference in New Issue
Block a user