MDEV-36954 Improve error handling when a function-method/procedure-method is missing in stored routines

Fixing a confusing error message:

Unknown column 'assoc_array_var' in 'unknown_method'

to a clearer:

FUNCTION/PROCEDURE assoc_array_var.unknown_method does not exist
This commit is contained in:
Alexander Barkov 2025-07-28 13:11:35 +04:00 committed by Sergei Golubchik
parent ef0505484e
commit 0fbdc56ee2
6 changed files with 43 additions and 21 deletions

View File

@ -753,7 +753,7 @@ marks(0) := 62;
SELECT marks.DELETE;
END;
$$
ERROR 42S22: Unknown column 'marks' in 'DELETE'
ERROR 42000: FUNCTION marks.DELETE does not exist
DECLARE
TYPE marks_t IS TABLE OF NUMBER INDEX BY INTEGER;
marks marks_t;
@ -762,7 +762,7 @@ marks(0) := 62;
DO marks.DELETE;
END;
$$
ERROR 42S22: Unknown column 'marks' in 'DELETE'
ERROR 42000: FUNCTION marks.DELETE does not exist
DECLARE
TYPE marks_t IS TABLE OF NUMBER INDEX BY INTEGER;
marks marks_t;
@ -771,7 +771,7 @@ marks(0) := 62;
SELECT marks.DELETE(0);
END;
$$
ERROR 42S22: Unknown column 'marks' in 'DELETE'
ERROR 42000: FUNCTION marks.DELETE does not exist
DECLARE
TYPE marks_t IS TABLE OF NUMBER INDEX BY INTEGER;
marks marks_t;
@ -780,7 +780,7 @@ marks(0) := 62;
DO marks.DELETE(0);
END;
$$
ERROR 42S22: Unknown column 'marks' in 'DELETE'
ERROR 42000: FUNCTION marks.DELETE does not exist
#
# DELETE
#
@ -847,7 +847,7 @@ marks(0) := 62;
marks.COUNT;
END;
$$
ERROR 42S22: Unknown column 'marks' in 'COUNT'
ERROR 42000: PROCEDURE marks.COUNT does not exist
DECLARE
TYPE marks_t IS TABLE OF NUMBER INDEX BY INTEGER;
marks marks_t;
@ -856,7 +856,7 @@ marks(0) := 62;
marks.COUNT();
END;
$$
ERROR 42S22: Unknown column 'marks' in 'COUNT'
ERROR 42000: PROCEDURE marks.COUNT does not exist
#
# COUNT
#

View File

@ -832,7 +832,7 @@ DELIMITER ;$$
--echo #
DELIMITER $$;
--error ER_BAD_FIELD_ERROR
--error ER_SP_DOES_NOT_EXIST
DECLARE
TYPE marks_t IS TABLE OF NUMBER INDEX BY INTEGER;
marks marks_t;
@ -844,7 +844,7 @@ $$
DELIMITER ;$$
DELIMITER $$;
--error ER_BAD_FIELD_ERROR
--error ER_SP_DOES_NOT_EXIST
DECLARE
TYPE marks_t IS TABLE OF NUMBER INDEX BY INTEGER;
marks marks_t;
@ -856,7 +856,7 @@ $$
DELIMITER ;$$
DELIMITER $$;
--error ER_BAD_FIELD_ERROR
--error ER_SP_DOES_NOT_EXIST
DECLARE
TYPE marks_t IS TABLE OF NUMBER INDEX BY INTEGER;
marks marks_t;
@ -868,7 +868,7 @@ $$
DELIMITER ;$$
DELIMITER $$;
--error ER_BAD_FIELD_ERROR
--error ER_SP_DOES_NOT_EXIST
DECLARE
TYPE marks_t IS TABLE OF NUMBER INDEX BY INTEGER;
marks marks_t;
@ -950,7 +950,7 @@ DELIMITER ;$$
--echo #
DELIMITER $$;
--error ER_BAD_FIELD_ERROR
--error ER_SP_DOES_NOT_EXIST
DECLARE
TYPE marks_t IS TABLE OF NUMBER INDEX BY INTEGER;
marks marks_t;
@ -963,7 +963,7 @@ DELIMITER ;$$
DELIMITER $$;
--error ER_BAD_FIELD_ERROR
--error ER_SP_DOES_NOT_EXIST
DECLARE
TYPE marks_t IS TABLE OF NUMBER INDEX BY INTEGER;
marks marks_t;

View File

@ -2703,10 +2703,7 @@ Item *Type_handler_assoc_array::create_item_method_func(THD *thd,
}
if (!item)
{
my_error(ER_BAD_FIELD_ERROR, MYF(0), a.str, b.str);
return nullptr;
}
if (item->init_method(a, query_fragment))
return nullptr;
@ -2730,10 +2727,7 @@ Item *Type_handler_assoc_array::create_item_method_proc(THD *thd,
}
if (!item)
{
my_error(ER_BAD_FIELD_ERROR, MYF(0), a.str, b.str);
return nullptr;
}
if (item->init_method(a, query_fragment))
return nullptr;

View File

@ -8967,7 +8967,7 @@ Item *LEX::create_item_ident(THD *thd,
if (sys_a.is_null() || sys_b.is_null())
return nullptr; // EOM
return spv->type_handler()->
create_item_method(thd,
create_item_method_or_error(thd,
Type_handler::object_method_type_t::FUNCTION,
sys_a, sys_b, NULL, query_fragment);
}
@ -10154,7 +10154,7 @@ bool LEX::direct_call(THD *thd, const Qualified_ident *ident,
}
if (!(item= ident->spvar()->type_handler()->
create_item_method(thd,
create_item_method_or_error(thd,
Type_handler::object_method_type_t::PROCEDURE,
ident->part(0), ident->part(1),
args, ident->pos())))
@ -10571,7 +10571,7 @@ Item *LEX::make_item_func_or_method_call(THD *thd,
spv->type_handler()->has_methods())
{
if (Item *item= spv->type_handler()->
create_item_method(thd,
create_item_method_or_error(thd,
Type_handler::object_method_type_t::FUNCTION,
sys_a, sys_b, args, query_fragment))
{

View File

@ -282,6 +282,27 @@ Type_handler::handler_by_name_or_error(THD *thd, const LEX_CSTRING &name)
}
Item *Type_handler::create_item_method_or_error(THD *thd,
object_method_type_t type,
const Lex_ident_sys &ca,
const Lex_ident_sys &cb,
List<Item> *args,
const Lex_ident_cli_st
&query_fragment)
const
{
Item *item= create_item_method(thd, type, ca, cb, args, query_fragment);
if (item)
return item;
char err_buffer[MYSQL_ERRMSG_SIZE];
Identifier_chain2(ca, cb).make_qname(err_buffer, sizeof(err_buffer));
my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
type == object_method_type_t::FUNCTION ? "FUNCTION" : "PROCEDURE",
err_buffer);
return nullptr;
}
Type_handler_data *type_handler_data= NULL;

View File

@ -4708,6 +4708,13 @@ public:
return nullptr;
}
Item *create_item_method_or_error(THD *thd, object_method_type_t type,
const Lex_ident_sys &ca,
const Lex_ident_sys &cb,
List<Item> *args,
const Lex_ident_cli_st &query_fragment)
const;
virtual int cmp_native(const Native &a, const Native &b) const
{
MY_ASSERT_UNREACHABLE();