Mysql – confusing error when providing a user defined function with an invalid enum value

mysql-8.0

I have a function thats called GET_TRANSLATION and it can return different results based on different select queries based on the enum value it is provided. Here is the full code:

CREATE FUNCTION GET_TRANSLATION(preferredLanguageId BIGINT, backupLanguageId BIGINT, entityId BIGINT, translationSubject ENUM('CROP_NAME', 'CROP_VARIETY_NAME', 'JOURNAL_TITLE', 'SOIL_TYPE', 'COUNTRY', 'PROVINCE', 'PLACE'))
RETURNS VARCHAR(255) DETERMINISTIC
BEGIN
    CASE
        WHEN translationSubject = 'CROP_NAME' THEN
            RETURN (SELECT COALESCE((SELECT s.translatedName FROM CropNameTranslation s WHERE s.language_id = preferredLanguageId AND s.parent_id = entityId AND s.approved = TRUE LIMIT 1),
            (SELECT s.translatedName FROM CropNameTranslation s WHERE s.language_id = backupLanguageId AND s.parent_id = entityId AND s.approved = TRUE LIMIT 1), (SELECT s.translatedName FROM CropNameTranslation s WHERE s.parent_id = entityId AND s.approved = TRUE LIMIT 1)));
        WHEN translationSubject = 'CROP_VARIETY_NAME' THEN
            RETURN (SELECT COALESCE((SELECT s.translatedName FROM CropVarietyName s WHERE s.language_id = preferredLanguageId AND s.parent_id = entityId AND s.approved = TRUE LIMIT 1),
            (SELECT s.translatedName FROM CropVarietyName s WHERE s.language_id = backupLanguageId AND s.parent_id = entityId AND s.approved = TRUE LIMIT 1), (SELECT s.translatedName FROM CropVarietyName s WHERE s.parent_id = entityId AND s.approved = TRUE LIMIT 1)));
        WHEN translationSubject = 'JOURNAL_TITLE' THEN
            RETURN (SELECT COALESCE((SELECT s.title FROM JournalTitleAndContent s WHERE s.language_id = preferredLanguageId AND s.journal_id = entityId LIMIT 1),
            (SELECT s.title FROM JournalTitleAndContent s WHERE s.language_id = backupLanguageId AND s.journal_id = entityId LIMIT 1), (SELECT s.title FROM JournalTitleAndContent s WHERE s.journal_id = entityId LIMIT 1)));
        WHEN translationSubject = 'SOIL_TYPE' THEN
            RETURN (SELECT COALESCE((SELECT s.translatedName FROM SoilTypeNameTranslation s WHERE s.language_id = preferredLanguageId AND s.soiltypedetails_id = entityId LIMIT 1),
            (SELECT s.translatedName FROM SoilTypeNameTranslation s WHERE s.language_id = backupLanguageId AND s.soiltypedetails_id = entityId LIMIT 1), (SELECT s.translatedName FROM SoilTypeNameTranslation s WHERE s.soiltypedetails_id = entityId LIMIT 1)));
        WHEN translationSubject = 'COUNTRY' THEN
            RETURN (SELECT COALESCE((SELECT ct.translatedName FROM countryNameTranslation ct WHERE ct.parent_id = entityId AND ct.language_id = preferredLanguageId LIMIT 1),
            (SELECT ct.translatedName FROM countryNameTranslation ct WHERE ct.parent_id = entityId AND ct.language_id = backupLanguageId LIMIT 1), (SELECT ct.translatedName FROM countryNameTranslation ct WHERE ct.parent_id = entityId LIMIT 1)));
        WHEN translationSubject = 'PROVINCE' THEN
            RETURN (SELECT COALESCE((SELECT ct.translatedName FROM provinceNameTranslation ct WHERE ct.parent_id = entityId AND ct.language_id = preferredLanguageId LIMIT 1),
            (SELECT ct.translatedName FROM provinceNameTranslation ct WHERE ct.parent_id = entityId AND ct.language_id = backupLanguageId LIMIT 1), (SELECT ct.translatedName FROM provinceNameTranslation ct WHERE ct.parent_id = entityId LIMIT 1)));
        WHEN translationSubject = 'PLACE' THEN
            RETURN (SELECT COALESCE((SELECT ct.translatedName FROM placeNameTranslation ct WHERE ct.parent_id = entityId AND ct.language_id = preferredLanguageId LIMIT 1),
            (SELECT ct.translatedName FROM placeNameTranslation ct WHERE ct.parent_id = entityId AND ct.language_id = backupLanguageId LIMIT 1), (SELECT ct.translatedName FROM placeNameTranslation ct WHERE ct.parent_id = entityId LIMIT 1)));
        ELSE SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Invalid enumType!';
    END CASE;
END

I used this function in a larger select query. IE SELECT c.scientificName, GET_TRANSLATION(@languageId, 1, j.soiltype_details_id, 'CROP') as soilType FROM journal j;

I mistakenly gave it the input CROP instead of CROP_NAME. Now it should have gone in the else part of the CASE structure and return an error with the message invalid enumType. However, What i really get is the error Error Code: 1265. Data truncated for column 'translationSubject' at row 1.

My question is; why doesn't it trigger the error that i defined for invalid enum types and why does it treat translationSubjectas a column that is "truncated" ? This error is completely out of place because the cause is merely a wrong enum value.

Could anyone explain this behavior to me?

Thank you

EDIT:

I just tried changing SIGNAL to RESIGNAL and removing the SQLSTATE parameter. Furthermore I've added

DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
        RESIGNAL;
    END;

to GET_TRANSLATION but the same error persists.

Best Answer

If you change the parameter to text:

DELIMITER //
CREATE FUNCTION GET_TRANSLATION(translationSubject TEXT)
RETURNS VARCHAR(255) DETERMINISTIC
BEGIN
    CASE WHEN translationSubject = 'CROP_NAME' THEN
             RETURN 'dummy';
         ELSE 
             SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Invalid enumType!';
    END CASE;
END //
DELIMITER;

it will behave as you expect

SELECT GET_TRANSLATION('CROP_NAME');
'dummy'

SELECT GET_TRANSLATION('CROP');
Query Error: Error: ER_SIGNAL_EXCEPTION: Invalid enumType!

If you use an enum, the error occurs before the function body is evaluated