diff options
-rw-r--r-- | mysql-test/r/sp.result | 51 | ||||
-rw-r--r-- | mysql-test/t/sp.test | 70 | ||||
-rw-r--r-- | scripts/mysql_system_tables.sql | 2 | ||||
-rw-r--r-- | scripts/mysql_system_tables_fix.sql | 1 | ||||
-rw-r--r-- | sql/share/errmsg.txt | 3 | ||||
-rw-r--r-- | sql/sp.cc | 131 | ||||
-rw-r--r-- | sql/sp.h | 1 | ||||
-rw-r--r-- | sql/sql_parse.cc | 3 |
8 files changed, 222 insertions, 40 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 0c6b4034e91..412f6b94fa2 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6860,4 +6860,55 @@ DROP FUNCTION f2; DROP VIEW v1; DROP VIEW v2; +# +# - Bug#24923: prepare. +# + +DROP FUNCTION IF EXISTS f1; + +# +# - Bug#24923: create required objects. +# + +CREATE FUNCTION f1(p INT) +RETURNS ENUM ('Very_long_enum_element_identifier', +'Another_very_long_enum_element_identifier') +BEGIN +CASE p +WHEN 1 THEN +RETURN 'Very_long_enum_element_identifier'; +ELSE +RETURN 'Another_very_long_enum_element_identifier'; +END CASE; +END| + +# +# - Bug#24923: check. +# + +SELECT f1(1); +f1(1) +Very_long_enum_element_identifier + +SELECT f1(2); +f1(2) +Another_very_long_enum_element_identifier + +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +f1 CREATE DEFINER=`root`@`localhost` FUNCTION `f1`(p INT) RETURNS enum('Very_long_enum_element_identifier','Another_very_long_enum_element_identifier') CHARSET latin1 +BEGIN +CASE p +WHEN 1 THEN +RETURN 'Very_long_enum_element_identifier'; +ELSE +RETURN 'Another_very_long_enum_element_identifier'; +END CASE; +END latin1 latin1_swedish_ci latin1_swedish_ci +# +# - Bug#24923: cleanup. +# + +DROP FUNCTION f1; + End of 5.1 tests diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 7d0a6a7b2d8..004e1c4ddd2 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -7986,4 +7986,74 @@ DROP VIEW v2; ########################################################################### +# +# Bug#24923: Functions with ENUM issues. +# + +########################################################################### + +--echo # +--echo # - Bug#24923: prepare. +--echo # + +--echo + +--disable_warnings +DROP FUNCTION IF EXISTS f1; +--enable_warnings + +--echo + +--echo # +--echo # - Bug#24923: create required objects. +--echo # + +--echo + +delimiter |; + +CREATE FUNCTION f1(p INT) + RETURNS ENUM ('Very_long_enum_element_identifier', + 'Another_very_long_enum_element_identifier') + BEGIN + CASE p + WHEN 1 THEN + RETURN 'Very_long_enum_element_identifier'; + ELSE + RETURN 'Another_very_long_enum_element_identifier'; + END CASE; + END| + +delimiter ;| + +--echo + +--echo # +--echo # - Bug#24923: check. +--echo # + +--echo + +SELECT f1(1); + +--echo + +SELECT f1(2); + +--echo + +SHOW CREATE FUNCTION f1; + +--echo # +--echo # - Bug#24923: cleanup. +--echo # + +--echo + +DROP FUNCTION f1; + +--echo + +########################################################################### + --echo End of 5.1 tests diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index f7b23e4e7ae..927cbe81ff9 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -60,7 +60,7 @@ CREATE TABLE IF NOT EXISTS time_zone_transition_type ( Time_zone_id int unsign CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=MyISAM CHARACTER SET utf8 comment='Leap seconds information for time zones'; -CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns char(64) DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures'; +CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures'; CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges'; diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index 78e6a0ceb57..a43964bf09a 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -344,6 +344,7 @@ ALTER TABLE proc MODIFY name char(64) DEFAULT '' NOT NULL, 'MODIFIES_SQL_DATA' ) DEFAULT 'CONTAINS_SQL' NOT NULL, MODIFY body longblob NOT NULL, + MODIFY returns longblob NOT NULL, MODIFY sql_mode set('REAL_AS_FLOAT', 'PIPES_AS_CONCAT', diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 30cf85f3181..8fad09eb221 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -6109,3 +6109,6 @@ ER_EVENT_INVALID_CREATION_CTX ER_TRG_CANT_OPEN_TABLE eng "Cannot open table for trigger `%-.64s`.`%-.64s`" + +ER_CANT_CREATE_SROUTINE + eng "Cannot create stored routine `%-.64s`. Check warnings" diff --git a/sql/sp.cc b/sql/sp.cc index 9077862e2f6..1b5d8ca87b8 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -682,6 +682,10 @@ sp_create_routine(THD *thd, int type, sp_head *sp) CHARSET_INFO *db_cs= get_default_db_collation(thd, sp->m_db.str); + enum_check_fields saved_count_cuted_fields; + + bool store_failed= FALSE; + DBUG_ENTER("sp_create_routine"); DBUG_PRINT("enter", ("type: %d name: %.*s",type, (int) sp->m_name.length, sp->m_name.str)); @@ -696,6 +700,9 @@ sp_create_routine(THD *thd, int type, sp_head *sp) */ thd->clear_current_stmt_binlog_row_based(); + saved_count_cuted_fields= thd->count_cuted_fields; + thd->count_cuted_fields= CHECK_FIELD_WARN; + if (!(table= open_proc_table_for_update(thd))) ret= SP_OPEN_TABLE_FAILED; else @@ -725,43 +732,77 @@ sp_create_routine(THD *thd, int type, sp_head *sp) ret= SP_BODY_TOO_LONG; goto done; } - table->field[MYSQL_PROC_FIELD_DB]-> - store(sp->m_db.str, sp->m_db.length, system_charset_info); - table->field[MYSQL_PROC_FIELD_NAME]-> - store(sp->m_name.str, sp->m_name.length, system_charset_info); - table->field[MYSQL_PROC_MYSQL_TYPE]-> - store((longlong)type, TRUE); - table->field[MYSQL_PROC_FIELD_SPECIFIC_NAME]-> - store(sp->m_name.str, sp->m_name.length, system_charset_info); + + store_failed= + table->field[MYSQL_PROC_FIELD_DB]-> + store(sp->m_db.str, sp->m_db.length, system_charset_info); + + store_failed= store_failed || + table->field[MYSQL_PROC_FIELD_NAME]-> + store(sp->m_name.str, sp->m_name.length, system_charset_info); + + store_failed= store_failed || + table->field[MYSQL_PROC_MYSQL_TYPE]-> + store((longlong)type, TRUE); + + store_failed= store_failed || + table->field[MYSQL_PROC_FIELD_SPECIFIC_NAME]-> + store(sp->m_name.str, sp->m_name.length, system_charset_info); + if (sp->m_chistics->daccess != SP_DEFAULT_ACCESS) - table->field[MYSQL_PROC_FIELD_ACCESS]-> - store((longlong)sp->m_chistics->daccess, TRUE); - table->field[MYSQL_PROC_FIELD_DETERMINISTIC]-> - store((longlong)(sp->m_chistics->detistic ? 1 : 2), TRUE); + { + store_failed= store_failed || + table->field[MYSQL_PROC_FIELD_ACCESS]-> + store((longlong)sp->m_chistics->daccess, TRUE); + } + + store_failed= store_failed || + table->field[MYSQL_PROC_FIELD_DETERMINISTIC]-> + store((longlong)(sp->m_chistics->detistic ? 1 : 2), TRUE); + if (sp->m_chistics->suid != SP_IS_DEFAULT_SUID) - table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]-> - store((longlong)sp->m_chistics->suid, TRUE); - table->field[MYSQL_PROC_FIELD_PARAM_LIST]-> - store(sp->m_params.str, sp->m_params.length, system_charset_info); + { + store_failed= store_failed || + table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]-> + store((longlong)sp->m_chistics->suid, TRUE); + } + + store_failed= store_failed || + table->field[MYSQL_PROC_FIELD_PARAM_LIST]-> + store(sp->m_params.str, sp->m_params.length, system_charset_info); + if (sp->m_type == TYPE_ENUM_FUNCTION) { String retstr(64); sp_returns_type(thd, retstr, sp); - table->field[MYSQL_PROC_FIELD_RETURNS]-> - store(retstr.ptr(), retstr.length(), system_charset_info); + + store_failed= store_failed || + table->field[MYSQL_PROC_FIELD_RETURNS]-> + store(retstr.ptr(), retstr.length(), system_charset_info); } - table->field[MYSQL_PROC_FIELD_BODY]-> - store(sp->m_body.str, sp->m_body.length, system_charset_info); - table->field[MYSQL_PROC_FIELD_DEFINER]-> - store(definer, (uint)strlen(definer), system_charset_info); + + store_failed= store_failed || + table->field[MYSQL_PROC_FIELD_BODY]-> + store(sp->m_body.str, sp->m_body.length, system_charset_info); + + store_failed= store_failed || + table->field[MYSQL_PROC_FIELD_DEFINER]-> + store(definer, (uint)strlen(definer), system_charset_info); + ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_CREATED])->set_time(); ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time(); - table->field[MYSQL_PROC_FIELD_SQL_MODE]-> - store((longlong)thd->variables.sql_mode, TRUE); + + store_failed= store_failed || + table->field[MYSQL_PROC_FIELD_SQL_MODE]-> + store((longlong)thd->variables.sql_mode, TRUE); + if (sp->m_chistics->comment.str) - table->field[MYSQL_PROC_FIELD_COMMENT]-> - store(sp->m_chistics->comment.str, sp->m_chistics->comment.length, - system_charset_info); + { + store_failed= store_failed || + table->field[MYSQL_PROC_FIELD_COMMENT]-> + store(sp->m_chistics->comment.str, sp->m_chistics->comment.length, + system_charset_info); + } if ((sp->m_type == TYPE_ENUM_FUNCTION) && !trust_function_creators && mysql_bin_log.is_open()) @@ -794,24 +835,34 @@ sp_create_routine(THD *thd, int type, sp_head *sp) } table->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT]->set_notnull(); - table->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT]->store( - thd->charset()->csname, - strlen(thd->charset()->csname), - system_charset_info); + store_failed= store_failed || + table->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT]->store( + thd->charset()->csname, + strlen(thd->charset()->csname), + system_charset_info); table->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION]->set_notnull(); - table->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION]->store( - thd->variables.collation_connection->name, - strlen(thd->variables.collation_connection->name), - system_charset_info); + store_failed= store_failed || + table->field[MYSQL_PROC_FIELD_COLLATION_CONNECTION]->store( + thd->variables.collation_connection->name, + strlen(thd->variables.collation_connection->name), + system_charset_info); table->field[MYSQL_PROC_FIELD_DB_COLLATION]->set_notnull(); - table->field[MYSQL_PROC_FIELD_DB_COLLATION]->store( - db_cs->name, strlen(db_cs->name), system_charset_info); + store_failed= store_failed || + table->field[MYSQL_PROC_FIELD_DB_COLLATION]->store( + db_cs->name, strlen(db_cs->name), system_charset_info); table->field[MYSQL_PROC_FIELD_BODY_UTF8]->set_notnull(); - table->field[MYSQL_PROC_FIELD_BODY_UTF8]->store( - sp->m_body_utf8.str, sp->m_body_utf8.length, system_charset_info); + store_failed= store_failed || + table->field[MYSQL_PROC_FIELD_BODY_UTF8]->store( + sp->m_body_utf8.str, sp->m_body_utf8.length, system_charset_info); + + if (store_failed) + { + ret= SP_FLD_STORE_FAILED; + goto done; + } ret= SP_OK; if (table->file->ha_write_row(table->record[0])) @@ -842,6 +893,8 @@ sp_create_routine(THD *thd, int type, sp_head *sp) } done: + thd->count_cuted_fields= saved_count_cuted_fields; + close_thread_tables(thd); DBUG_RETURN(ret); } @@ -29,6 +29,7 @@ #define SP_NO_DB_ERROR -8 #define SP_BAD_IDENTIFIER -9 #define SP_BODY_TOO_LONG -10 +#define SP_FLD_STORE_FAILED -11 /* Drop all routines in database 'db' */ int diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b04822c4fc9..4856332631a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3812,6 +3812,9 @@ end_with_restore_list: case SP_BODY_TOO_LONG: my_error(ER_TOO_LONG_BODY, MYF(0), name); break; + case SP_FLD_STORE_FAILED: + my_error(ER_CANT_CREATE_SROUTINE, MYF(0), name); + break; default: my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name); break; |