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;
|
END;
|
||||||
$$
|
$$
|
||||||
ERROR 21000: Operand should contain 1 column(s)
|
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;
|
END;
|
||||||
$$
|
$$
|
||||||
DELIMITER ;$$
|
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 */
|
/* Arguments must be fixed in Item_func_sp::fix_fields */
|
||||||
DBUG_ASSERT(argp[arg_no]->fixed());
|
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]))))
|
if ((err_status= (*func_ctx)->set_parameter(thd, arg_no, &(argp[arg_no]))))
|
||||||
goto err_with_cleanup;
|
goto err_with_cleanup;
|
||||||
}
|
}
|
||||||
@@ -2359,11 +2380,27 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
|
|||||||
if (!arg_item)
|
if (!arg_item)
|
||||||
break;
|
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);
|
sp_variable *spvar= m_pcont->find_variable(i);
|
||||||
|
|
||||||
if (!spvar)
|
if (!spvar)
|
||||||
continue;
|
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)
|
if (spvar->mode != sp_variable::MODE_IN)
|
||||||
{
|
{
|
||||||
Settable_routine_parameter *srp=
|
Settable_routine_parameter *srp=
|
||||||
|
Reference in New Issue
Block a user