diff options
author | Vladislav Vaintroub <vvaintroub@mysql.com> | 2010-01-22 12:50:33 +0100 |
---|---|---|
committer | Vladislav Vaintroub <vvaintroub@mysql.com> | 2010-01-22 12:50:33 +0100 |
commit | cb5b0d4ffa964b2808dfb42b64f53b4b9e2d9bc1 (patch) | |
tree | 16e166d97e758468adaf6e8c29470666e9910f4e /sql | |
parent | 68c66c645a76608438e33259be85f3ca4b244ed8 (diff) | |
parent | 08bcd2d8f67dcacd36abd2592fa2a59321abe7c2 (diff) | |
download | mariadb-git-cb5b0d4ffa964b2808dfb42b64f53b4b9e2d9bc1.tar.gz |
merge
Diffstat (limited to 'sql')
-rw-r--r-- | sql/handler.h | 1 | ||||
-rw-r--r-- | sql/mysql_priv.h | 4 | ||||
-rw-r--r-- | sql/mysqld.cc | 15 | ||||
-rw-r--r-- | sql/share/errmsg.txt | 2 | ||||
-rw-r--r-- | sql/sp.cc | 200 | ||||
-rw-r--r-- | sql/sp.h | 32 | ||||
-rw-r--r-- | sql/sp_head.h | 1 | ||||
-rw-r--r-- | sql/sql_base.cc | 6 | ||||
-rw-r--r-- | sql/sql_show.cc | 877 | ||||
-rw-r--r-- | sql/sql_trigger.cc | 25 | ||||
-rw-r--r-- | sql/sql_view.cc | 17 | ||||
-rw-r--r-- | sql/unireg.h | 5 |
12 files changed, 825 insertions, 360 deletions
diff --git a/sql/handler.h b/sql/handler.h index 711cc823f96..f4064b51de9 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -555,6 +555,7 @@ enum enum_schema_tables SCH_GLOBAL_VARIABLES, SCH_KEY_COLUMN_USAGE, SCH_OPEN_TABLES, + SCH_PARAMETERS, SCH_PARTITIONS, SCH_PLUGINS, SCH_PROCESSLIST, diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index dc119013302..4d5490e8219 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1319,6 +1319,10 @@ thr_lock_type read_lock_type_for_table(THD *thd, TABLE *table); void close_data_files_and_morph_locks(THD *thd, const char *db, const char *table_name); void close_handle_and_leave_table_as_lock(TABLE *table); +bool open_new_frm(THD *thd, TABLE_SHARE *share, const char *alias, + uint db_stat, uint prgflag, + uint ha_open_flags, TABLE *outparam, + TABLE_LIST *table_desc, MEM_ROOT *mem_root); bool wait_for_tables(THD *thd); bool table_is_used(TABLE *table, bool wait_for_name_lock); TABLE *drop_locked_tables(THD *thd,const char *db, const char *table_name); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5826bfb925c..276ec02a042 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3345,6 +3345,16 @@ static int init_common_variables() strmov(fn_ext(pidfile_name),".pid"); // Add proper extension /* + The default-storage-engine entry in my_long_options should have a + non-null default value. It was earlier intialized as + (longlong)"MyISAM" in my_long_options but this triggered a + compiler error in the Sun Studio 12 compiler. As a work-around we + set the def_value member to 0 in my_long_options and initialize it + to the correct value here. + */ + default_storage_engine="MyISAM"; + + /* Add server status variables to the dynamic list of status variables that is shown by SHOW STATUS. Later, in plugin_init, and mysql_install_plugin @@ -5961,9 +5971,12 @@ struct my_option my_long_options[]= {"default-collation", 0, "Set the default collation (deprecated option, use --collation-server instead).", (uchar**) &default_collation_name, (uchar**) &default_collation_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + /* default-storage-engine should have "MyISAM" as def_value. Instead + of initializing it here it is done in init_common_variables() due + to a compiler bug in Sun Studio compiler. */ {"default-storage-engine", 0, "The default storage engine for new tables", (uchar**) &default_storage_engine, 0, 0, GET_STR, REQUIRED_ARG, - (longlong)"MyISAM", 0, 0, 0, 0, 0 }, + 0, 0, 0, 0, 0, 0 }, {"default-time-zone", 0, "Set the default time zone.", (uchar**) &default_tz_name, (uchar**) &default_tz_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 0d108fc019f..4ee0cf9d758 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -6235,8 +6235,6 @@ ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS ER_MESSAGE_AND_STATEMENT eng "%s Statement: %s" -ER_SLAVE_IGNORE_SERVER_IDS - eng "The requested server id %d clashes with the slave startup option --replicate-same-server-id" ER_DEBUG_SYNC_TIMEOUT eng "debug sync point wait timed out" ger "Debug Sync Point Wartezeit überschritten" diff --git a/sql/sp.cc b/sql/sp.cc index 11ae2646f14..9d3527dc4e6 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -31,7 +31,9 @@ create_string(THD *thd, String *buf, const char *body, ulong bodylen, st_sp_chistics *chistics, const LEX_STRING *definer_user, - const LEX_STRING *definer_host); + const LEX_STRING *definer_host, + ulong sql_mode); + static int db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, ulong sql_mode, const char *params, const char *returns, @@ -39,37 +41,6 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, const char *definer, longlong created, longlong modified, Stored_program_creation_ctx *creation_ctx); -/* - * - * DB storage of Stored PROCEDUREs and FUNCTIONs - * - */ - -enum -{ - MYSQL_PROC_FIELD_DB = 0, - MYSQL_PROC_FIELD_NAME, - MYSQL_PROC_MYSQL_TYPE, - MYSQL_PROC_FIELD_SPECIFIC_NAME, - MYSQL_PROC_FIELD_LANGUAGE, - MYSQL_PROC_FIELD_ACCESS, - MYSQL_PROC_FIELD_DETERMINISTIC, - MYSQL_PROC_FIELD_SECURITY_TYPE, - MYSQL_PROC_FIELD_PARAM_LIST, - MYSQL_PROC_FIELD_RETURNS, - MYSQL_PROC_FIELD_BODY, - MYSQL_PROC_FIELD_DEFINER, - MYSQL_PROC_FIELD_CREATED, - MYSQL_PROC_FIELD_MODIFIED, - MYSQL_PROC_FIELD_SQL_MODE, - MYSQL_PROC_FIELD_COMMENT, - MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT, - MYSQL_PROC_FIELD_COLLATION_CONNECTION, - MYSQL_PROC_FIELD_DB_COLLATION, - MYSQL_PROC_FIELD_BODY_UTF8, - MYSQL_PROC_FIELD_COUNT -}; - static const TABLE_FIELD_TYPE proc_table_fields[MYSQL_PROC_FIELD_COUNT] = { @@ -716,6 +687,55 @@ Silence_deprecated_warning::handle_condition( } +/** + @brief The function parses input strings and returns SP stucture. + + @param[in] thd Thread handler + @param[in] defstr CREATE... string + @param[in] sql_mode SQL mode + @param[in] creation_ctx Creation context of stored routines + + @return Pointer on sp_head struct + @retval # Pointer on sp_head struct + @retval 0 error +*/ + +static sp_head *sp_compile(THD *thd, String *defstr, ulong sql_mode, + Stored_program_creation_ctx *creation_ctx) +{ + sp_head *sp; + ulong old_sql_mode= thd->variables.sql_mode; + ha_rows old_select_limit= thd->variables.select_limit; + sp_rcontext *old_spcont= thd->spcont; + Silence_deprecated_warning warning_handler; + + thd->variables.sql_mode= sql_mode; + thd->variables.select_limit= HA_POS_ERROR; + + Parser_state parser_state(thd, defstr->c_ptr(), defstr->length()); + lex_start(thd); + thd->push_internal_handler(&warning_handler); + thd->spcont= 0; + + if (parse_sql(thd, & parser_state, creation_ctx) || thd->lex == NULL) + { + sp= thd->lex->sphead; + delete sp; + sp= 0; + } + else + { + sp= thd->lex->sphead; + } + + thd->pop_internal_handler(); + thd->spcont= old_spcont; + thd->variables.sql_mode= old_sql_mode; + thd->variables.select_limit= old_select_limit; + return sp; +} + + static int db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, ulong sql_mode, const char *params, const char *returns, @@ -729,11 +749,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, LEX_STRING saved_cur_db_name= { saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) }; bool cur_db_changed; - ulong old_sql_mode= thd->variables.sql_mode; - ha_rows old_select_limit= thd->variables.select_limit; - sp_rcontext *old_spcont= thd->spcont; - Silence_deprecated_warning warning_handler; - + char definer_user_name_holder[USERNAME_LENGTH + 1]; LEX_STRING definer_user_name= { definer_user_name_holder, USERNAME_LENGTH }; @@ -741,10 +757,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, char definer_host_name_holder[HOSTNAME_LENGTH + 1]; LEX_STRING definer_host_name= { definer_host_name_holder, HOSTNAME_LENGTH }; - int ret; - - thd->variables.sql_mode= sql_mode; - thd->variables.select_limit= HA_POS_ERROR; + int ret= 0; thd->lex= &newlex; newlex.current_select= NULL; @@ -768,7 +781,8 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, params, strlen(params), returns, strlen(returns), body, strlen(body), - &chistics, &definer_user_name, &definer_host_name)) + &chistics, &definer_user_name, &definer_host_name, + sql_mode)) { ret= SP_INTERNAL_ERROR; goto end; @@ -787,17 +801,8 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, goto end; } - thd->spcont= NULL; - { - Parser_state parser_state(thd, defstr.c_ptr(), defstr.length()); - - lex_start(thd); - - thd->push_internal_handler(&warning_handler); - ret= parse_sql(thd, & parser_state, creation_ctx) || newlex.sphead == NULL; - thd->pop_internal_handler(); - + *sphp= sp_compile(thd, &defstr, sql_mode, creation_ctx); /* Force switching back to the saved current database (if changed), because it may be NULL. In this case, mysql_change_db() would @@ -806,19 +811,16 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, if (cur_db_changed && mysql_change_db(thd, &saved_cur_db_name, TRUE)) { - delete newlex.sphead; ret= SP_INTERNAL_ERROR; goto end; } - if (ret) + if (!*sphp) { - delete newlex.sphead; ret= SP_PARSE_ERROR; goto end; } - *sphp= newlex.sphead; (*sphp)->set_definer(&definer_user_name, &definer_host_name); (*sphp)->set_info(created, modified, &chistics, sql_mode); (*sphp)->set_creation_ctx(creation_ctx); @@ -836,9 +838,6 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, end: lex_end(thd->lex); - thd->spcont= old_spcont; - thd->variables.sql_mode= old_sql_mode; - thd->variables.select_limit= old_select_limit; thd->lex= old_lex; return ret; } @@ -1110,7 +1109,8 @@ sp_create_routine(THD *thd, int type, sp_head *sp) retstr.c_ptr(), retstr.length(), sp->m_body.str, sp->m_body.length, sp->m_chistics, &(thd->lex->definer->user), - &(thd->lex->definer->host))) + &(thd->lex->definer->host), + saved_mode)) { ret= SP_INTERNAL_ERROR; goto done; @@ -2071,6 +2071,7 @@ sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex, Returns TRUE on success, FALSE on (alloc) failure. */ static bool + create_string(THD *thd, String *buf, int type, const char *db, ulong dblen, @@ -2080,14 +2081,17 @@ create_string(THD *thd, String *buf, const char *body, ulong bodylen, st_sp_chistics *chistics, const LEX_STRING *definer_user, - const LEX_STRING *definer_host) + const LEX_STRING *definer_host, + ulong sql_mode) { + ulong old_sql_mode= thd->variables.sql_mode; /* Make some room to begin with */ if (buf->alloc(100 + dblen + 1 + namelen + paramslen + returnslen + bodylen + chistics->comment.length + 10 /* length of " DEFINER= "*/ + USER_HOST_BUFF_SIZE)) return FALSE; + thd->variables.sql_mode= sql_mode; buf->append(STRING_WITH_LEN("CREATE ")); append_definer(thd, buf, definer_user, definer_host); if (type == TYPE_ENUM_FUNCTION) @@ -2135,5 +2139,79 @@ create_string(THD *thd, String *buf, buf->append('\n'); } buf->append(body, bodylen); + thd->variables.sql_mode= old_sql_mode; return TRUE; } + + +/** + @brief The function loads sp_head struct for information schema purposes + (used for I_S ROUTINES & PARAMETERS tables). + + @param[in] thd thread handler + @param[in] proc_table mysql.proc table structurte + @param[in] db database name + @param[in] name sp name + @param[in] sql_mode SQL mode + @param[in] type Routine type + @param[in] returns 'returns' string + @param[in] params parameters definition string + @param[out] free_sp_head returns 1 if we need to free sp_head struct + otherwise returns 0 + + @return Pointer on sp_head struct + @retval # Pointer on sp_head struct + @retval 0 error +*/ + +sp_head * +sp_load_for_information_schema(THD *thd, TABLE *proc_table, String *db, + String *name, ulong sql_mode, int type, + const char *returns, const char *params, + bool *free_sp_head) +{ + const char *sp_body; + String defstr; + struct st_sp_chistics sp_chistics; + const LEX_STRING definer_user= {(char*)STRING_WITH_LEN("")}; + const LEX_STRING definer_host= {(char*)STRING_WITH_LEN("")}; + LEX_STRING sp_db_str; + LEX_STRING sp_name_str; + sp_head *sp; + sp_cache **spc= ((type == TYPE_ENUM_PROCEDURE) ? + &thd->sp_proc_cache : &thd->sp_func_cache); + sp_db_str.str= db->c_ptr(); + sp_db_str.length= db->length(); + sp_name_str.str= name->c_ptr(); + sp_name_str.length= name->length(); + sp_name sp_name_obj(sp_db_str, sp_name_str, true); + sp_name_obj.init_qname(thd); + *free_sp_head= 0; + if ((sp= sp_cache_lookup(spc, &sp_name_obj))) + { + return sp; + } + + LEX *old_lex= thd->lex, newlex; + Stored_program_creation_ctx *creation_ctx= + Stored_routine_creation_ctx::load_from_db(thd, &sp_name_obj, proc_table); + sp_body= (type == TYPE_ENUM_FUNCTION ? "RETURN NULL" : "BEGIN END"); + bzero((char*) &sp_chistics, sizeof(sp_chistics)); + defstr.set_charset(creation_ctx->get_client_cs()); + if (!create_string(thd, &defstr, type, + sp_db_str.str, sp_db_str.length, + sp_name_obj.m_name.str, sp_name_obj.m_name.length, + params, strlen(params), + returns, strlen(returns), + sp_body, strlen(sp_body), + &sp_chistics, &definer_user, &definer_host, sql_mode)) + return 0; + + thd->lex= &newlex; + newlex.current_select= NULL; + sp= sp_compile(thd, &defstr, sql_mode, creation_ctx); + *free_sp_head= 1; + lex_end(thd->lex); + thd->lex= old_lex; + return sp; +} @@ -34,6 +34,32 @@ #define SP_BODY_TOO_LONG -10 #define SP_FLD_STORE_FAILED -11 +/* DB storage of Stored PROCEDUREs and FUNCTIONs */ +enum +{ + MYSQL_PROC_FIELD_DB = 0, + MYSQL_PROC_FIELD_NAME, + MYSQL_PROC_MYSQL_TYPE, + MYSQL_PROC_FIELD_SPECIFIC_NAME, + MYSQL_PROC_FIELD_LANGUAGE, + MYSQL_PROC_FIELD_ACCESS, + MYSQL_PROC_FIELD_DETERMINISTIC, + MYSQL_PROC_FIELD_SECURITY_TYPE, + MYSQL_PROC_FIELD_PARAM_LIST, + MYSQL_PROC_FIELD_RETURNS, + MYSQL_PROC_FIELD_BODY, + MYSQL_PROC_FIELD_DEFINER, + MYSQL_PROC_FIELD_CREATED, + MYSQL_PROC_FIELD_MODIFIED, + MYSQL_PROC_FIELD_SQL_MODE, + MYSQL_PROC_FIELD_COMMENT, + MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT, + MYSQL_PROC_FIELD_COLLATION_CONNECTION, + MYSQL_PROC_FIELD_DB_COLLATION, + MYSQL_PROC_FIELD_BODY_UTF8, + MYSQL_PROC_FIELD_COUNT +}; + /* Drop all routines in database 'db' */ int sp_drop_db_routines(THD *thd, char *db); @@ -86,4 +112,10 @@ extern "C" uchar* sp_sroutine_key(const uchar *ptr, size_t *plen, */ TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup); +sp_head * +sp_load_for_information_schema(THD *thd, TABLE *proc_table, String *db, + String *name, ulong sql_mode, int type, + const char *returns, const char *params, + bool *free_sp_head); + #endif /* _SP_H_ */ diff --git a/sql/sp_head.h b/sql/sp_head.h index 138d0a2f506..fd02c799975 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -477,6 +477,7 @@ public: DBUG_VOID_RETURN; } + sp_pcontext *get_parse_context() { return m_pcont; } private: diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 59a9605d471..eb59600b360 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -107,10 +107,6 @@ static int open_unireg_entry(THD *thd, TABLE *entry, TABLE_LIST *table_list, char *cache_key, uint cache_key_length, MEM_ROOT *mem_root, uint flags); static void free_cache_entry(TABLE *entry); -static bool open_new_frm(THD *thd, TABLE_SHARE *share, const char *alias, - uint db_stat, uint prgflag, - uint ha_open_flags, TABLE *outparam, - TABLE_LIST *table_desc, MEM_ROOT *mem_root); static void close_old_data_files(THD *thd, TABLE *table, bool morph_locks, bool send_refresh); static bool @@ -8505,7 +8501,7 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order) mem_root temporary MEM_ROOT for parsing */ -static bool +bool open_new_frm(THD *thd, TABLE_SHARE *share, const char *alias, uint db_stat, uint prgflag, uint ha_open_flags, TABLE *outparam, TABLE_LIST *table_desc, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 9e34c1f2d17..f8df7eb518f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -22,6 +22,7 @@ #include "repl_failsafe.h" #include "sp.h" #include "sp_head.h" +#include "sp_pcontext.h" #include "set_var.h" #include "sql_trigger.h" #include "authors.h" @@ -999,20 +1000,21 @@ static void append_directory(THD *thd, String *packet, const char *dir_type, #define LIST_PROCESS_HOST_LEN 64 -static bool get_field_default_value(THD *thd, TABLE *table, +static bool get_field_default_value(THD *thd, Field *timestamp_field, Field *field, String *def_value, bool quoted) { bool has_default; bool has_now_default; enum enum_field_types field_type= field->type(); - /* + + /* We are using CURRENT_TIMESTAMP instead of NOW because it is more standard */ - has_now_default= table->timestamp_field == field && - field->unireg_check != Field::TIMESTAMP_UN_FIELD; - + has_now_default= (timestamp_field == field && + field->unireg_check != Field::TIMESTAMP_UN_FIELD); + has_default= (field_type != FIELD_TYPE_BLOB && !(field->flags & NO_DEFAULT_VALUE_FLAG) && field->unireg_check != Field::NEXT_NUMBER && @@ -1065,6 +1067,7 @@ static bool get_field_default_value(THD *thd, TABLE *table, return has_default; } + /* Build a CREATE TABLE statement for a table. @@ -1214,7 +1217,8 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, packet->append(STRING_WITH_LEN(" NULL")); } - if (get_field_default_value(thd, table, field, &def_value, 1)) + if (get_field_default_value(thd, table->timestamp_field, + field, &def_value, 1)) { packet->append(STRING_WITH_LEN(" DEFAULT ")); packet->append(def_value.ptr(), def_value.length(), system_charset_info); @@ -3074,17 +3078,18 @@ uint get_table_open_method(TABLE_LIST *tables, open_tables function for this table */ -static int fill_schema_table_from_frm(THD *thd,TABLE *table, - ST_SCHEMA_TABLE *schema_table, +static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, + ST_SCHEMA_TABLE *schema_table, LEX_STRING *db_name, LEX_STRING *table_name, enum enum_schema_tables schema_table_idx) { + TABLE *table= tables->table; TABLE_SHARE *share; TABLE tbl; TABLE_LIST table_list; uint res= 0; - int error; + int not_used; char key[MAX_DBKEY_LENGTH]; uint key_length; char db_name_buff[NAME_LEN + 1], table_name_buff[NAME_LEN + 1]; @@ -3112,61 +3117,85 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table, table_list.db= db_name->str; } + if (schema_table->i_s_requested_object & OPEN_TRIGGER_ONLY) + { + init_sql_alloc(&tbl.mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); + if (!Table_triggers_list::check_n_load(thd, db_name->str, + table_name->str, &tbl, 1)) + { + table_list.table= &tbl; + res= schema_table->process_table(thd, &table_list, table, + res, db_name, table_name); + delete tbl.triggers; + } + free_root(&tbl.mem_root, MYF(0)); + goto end; + } + key_length= create_table_def_key(thd, key, &table_list, 0); mysql_mutex_lock(&LOCK_open); share= get_table_share(thd, &table_list, key, - key_length, OPEN_VIEW, &error); + key_length, OPEN_VIEW, ¬_used); if (!share) { res= 0; - goto err; + goto end_unlock; } - + if (share->is_view) { if (schema_table->i_s_requested_object & OPEN_TABLE_ONLY) { /* skip view processing */ res= 0; - goto err1; + goto end_share; } else if (schema_table->i_s_requested_object & OPEN_VIEW_FULL) { /* - tell get_all_tables() to fall back to + tell get_all_tables() to fall back to open_normal_and_derived_tables() */ res= 1; - goto err1; + goto end_share; } } - if (share->is_view || - !open_table_from_share(thd, share, table_name->str, 0, - (READ_KEYINFO | COMPUTE_TYPES | - EXTRA_RECORD | OPEN_FRM_FILE_ONLY), - thd->open_options, &tbl, FALSE)) + if (share->is_view) + { + if (open_new_frm(thd, share, table_name->str, + (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | + HA_GET_INDEX | HA_TRY_READ_ONLY), + READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD | + OPEN_VIEW_NO_PARSE, + thd->open_options, &tbl, &table_list, thd->mem_root)) + goto end_share; + table_list.view= (LEX*) share->is_view; + res= schema_table->process_table(thd, &table_list, table, + res, db_name, table_name); + goto end_share; + } + { tbl.s= share; table_list.table= &tbl; table_list.view= (LEX*) share->is_view; res= schema_table->process_table(thd, &table_list, table, res, db_name, table_name); - closefrm(&tbl, true); - goto err; } -err1: +end_share: release_table_share(share, RELEASE_NORMAL); -err: - mysql_mutex_unlock(&LOCK_open); +end_unlock: + mysql_mutex_unlock(&LOCK_open); + +end: thd->clear_error(); return res; } - /** @brief Fill I_S tables whose data are retrieved from frm files and storage engine @@ -3223,6 +3252,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) */ thd->reset_n_backup_open_tables_state(&open_tables_state_backup); + schema_table_idx= get_schema_table_idx(schema_table); + tables->table_open_method= table_open_method= + get_table_open_method(tables, schema_table, schema_table_idx); + DBUG_PRINT("open_method", ("%d", tables->table_open_method)); /* this branch processes SHOW FIELDS, SHOW INDEXES commands. see sql_parse.cc, prepare_schema_table() function where @@ -3235,7 +3268,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) goto err; } - schema_table_idx= get_schema_table_idx(schema_table); if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals)) { error= 0; @@ -3273,9 +3305,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) else partial_cond= make_cond_for_info_schema(cond, tables); - tables->table_open_method= table_open_method= - get_table_open_method(tables, schema_table, schema_table_idx); - if (lex->describe) { /* EXPLAIN SELECT */ @@ -3342,10 +3371,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) } else { - if (!(table_open_method & ~OPEN_FRM_ONLY) && + if (!(table_open_method & ~OPEN_FRM_ONLY) && !with_i_schema) { - if (!fill_schema_table_from_frm(thd, table, schema_table, db_name, + if (!fill_schema_table_from_frm(thd, tables, schema_table, db_name, table_name, schema_table_idx)) continue; } @@ -3721,6 +3750,128 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, } +/** + @brief Store field characteristics into appropriate I_S table columns + + @param[in] table I_S table + @param[in] field processed field + @param[in] cs I_S table charset + @param[in] offset offset from beginning of table + to DATE_TYPE column in I_S table + + @return void +*/ + +void store_column_type(TABLE *table, Field *field, CHARSET_INFO *cs, + uint offset) +{ + bool is_blob; + int decimals, field_length; + const char *tmp_buff; + char column_type_buff[MAX_FIELD_WIDTH]; + String column_type(column_type_buff, sizeof(column_type_buff), cs); + + field->sql_type(column_type); + /* DTD_IDENTIFIER column */ + table->field[offset + 7]->store(column_type.ptr(), column_type.length(), cs); + table->field[offset + 7]->set_notnull(); + /* + DATA_TYPE column: + MySQL column type has the following format: + base_type [(dimension)] [unsigned] [zerofill]. + For DATA_TYPE column we extract only base type. + */ + tmp_buff= strchr(column_type.ptr(), '('); + if (!tmp_buff) + /* + if there is no dimention part then check the presence of + [unsigned] [zerofill] attributes and cut them of if exist. + */ + tmp_buff= strchr(column_type.ptr(), ' '); + table->field[offset]->store(column_type.ptr(), + (tmp_buff ? tmp_buff - column_type.ptr() : + column_type.length()), cs); + + is_blob= (field->type() == MYSQL_TYPE_BLOB); + if (field->has_charset() || is_blob || + field->real_type() == MYSQL_TYPE_VARCHAR || // For varbinary type + field->real_type() == MYSQL_TYPE_STRING) // For binary type + { + uint32 octet_max_length= field->max_display_length(); + if (is_blob && octet_max_length != (uint32) 4294967295U) + octet_max_length /= field->charset()->mbmaxlen; + longlong char_max_len= is_blob ? + (longlong) octet_max_length / field->charset()->mbminlen : + (longlong) octet_max_length / field->charset()->mbmaxlen; + /* CHARACTER_MAXIMUM_LENGTH column*/ + table->field[offset + 1]->store(char_max_len, TRUE); + table->field[offset + 1]->set_notnull(); + /* CHARACTER_OCTET_LENGTH column */ + table->field[offset + 2]->store((longlong) octet_max_length, TRUE); + table->field[offset + 2]->set_notnull(); + } + + /* + Calculate field_length and decimals. + They are set to -1 if they should not be set (we should return NULL) + */ + + decimals= field->decimals(); + switch (field->type()) { + case MYSQL_TYPE_NEWDECIMAL: + field_length= ((Field_new_decimal*) field)->precision; + break; + case MYSQL_TYPE_DECIMAL: + field_length= field->field_length - (decimals ? 2 : 1); + break; + case MYSQL_TYPE_TINY: + case MYSQL_TYPE_SHORT: + case MYSQL_TYPE_LONG: + case MYSQL_TYPE_LONGLONG: + case MYSQL_TYPE_INT24: + field_length= field->max_display_length() - 1; + break; + case MYSQL_TYPE_BIT: + field_length= field->max_display_length(); + decimals= -1; // return NULL + break; + case MYSQL_TYPE_FLOAT: + case MYSQL_TYPE_DOUBLE: + field_length= field->field_length; + if (decimals == NOT_FIXED_DEC) + decimals= -1; // return NULL + break; + default: + field_length= decimals= -1; + break; + } + + /* NUMERIC_PRECISION column */ + if (field_length >= 0) + { + table->field[offset + 3]->store((longlong) field_length, TRUE); + table->field[offset + 3]->set_notnull(); + } + /* NUMERIC_SCALE column */ + if (decimals >= 0) + { + table->field[offset + 4]->store((longlong) decimals, TRUE); + table->field[offset + 4]->set_notnull(); + } + if (field->has_charset()) + { + /* CHARACTER_SET_NAME column*/ + tmp_buff= field->charset()->csname; + table->field[offset + 5]->store(tmp_buff, strlen(tmp_buff), cs); + table->field[offset + 5]->set_notnull(); + /* COLLATION_NAME column */ + tmp_buff= field->charset()->name; + table->field[offset + 6]->store(tmp_buff, strlen(tmp_buff), cs); + table->field[offset + 6]->set_notnull(); + } +} + + static int get_schema_column_record(THD *thd, TABLE_LIST *tables, TABLE *table, bool res, LEX_STRING *db_name, @@ -3730,7 +3881,8 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, const char *wild= lex->wild ? lex->wild->ptr() : NullS; CHARSET_INFO *cs= system_charset_info; TABLE *show_table; - Field **ptr,*field; + TABLE_SHARE *show_table_share; + Field **ptr, *field, *timestamp_field; int count; DBUG_ENTER("get_schema_column_record"); @@ -3741,7 +3893,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, /* I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS rather than in SHOW COLUMNS - */ + */ if (thd->is_error()) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, thd->stmt_da->sql_errno(), thd->stmt_da->message()); @@ -3752,37 +3904,62 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, } show_table= tables->table; + show_table_share= show_table->s; count= 0; - restore_record(show_table, s->default_values); - show_table->use_all_columns(); // Required for default - for (ptr= show_table->field; (field= *ptr) ; ptr++) + if (tables->view || tables->schema_table) + { + ptr= show_table->field; + timestamp_field= show_table->timestamp_field; + show_table->use_all_columns(); // Required for default + } + else + { + ptr= show_table_share->field; + timestamp_field= show_table_share->timestamp_field; + /* + read_set may be inited in case of + temporary table + */ + if (!show_table->read_set) + { + /* to satisfy 'field->val_str' ASSERTs */ + uchar *bitmaps; + uint bitmap_size= show_table_share->column_bitmap_size; + if (!(bitmaps= (uchar*) alloc_root(thd->mem_root, bitmap_size))) + DBUG_RETURN(0); + bitmap_init(&show_table->def_read_set, + (my_bitmap_map*) bitmaps, show_table_share->fields, FALSE); + bitmap_set_all(&show_table->def_read_set); + show_table->read_set= &show_table->def_read_set; + } + bitmap_set_all(show_table->read_set); + } + + for (; (field= *ptr) ; ptr++) { - const char *tmp_buff; uchar *pos; - bool is_blob; - uint flags=field->flags; char tmp[MAX_FIELD_WIDTH]; String type(tmp,sizeof(tmp), system_charset_info); char *end; - int decimals, field_length; + + /* to satisfy 'field->val_str' ASSERTs */ + field->table= show_table; + show_table->in_use= thd; if (wild && wild[0] && wild_case_compare(system_charset_info, field->field_name,wild)) continue; - flags= field->flags; count++; /* Get default row, with all NULL fields set to NULL */ restore_record(table, s->default_values); #ifndef NO_EMBEDDED_ACCESS_CHECKS uint col_access; - check_access(thd, SELECT_ACL, db_name->str, - &tables->grant.privilege, - &tables->grant.m_internal, - FALSE, FALSE); - col_access= get_column_grant(thd, &tables->grant, + check_access(thd,SELECT_ACL, db_name->str, + &tables->grant.privilege, 0, 0, test(tables->schema_table)); + col_access= get_column_grant(thd, &tables->grant, db_name->str, table_name->str, field->field_name) & COL_ACLS; if (!tables->schema_table && !col_access) @@ -3807,104 +3984,16 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, table->field[4]->store((longlong) count, TRUE); field->sql_type(type); table->field[14]->store(type.ptr(), type.length(), cs); - /* - MySQL column type has the following format: - base_type [(dimension)] [unsigned] [zerofill]. - For DATA_TYPE column we extract only base type. - */ - tmp_buff= strchr(type.ptr(), '('); - if (!tmp_buff) - /* - if there is no dimention part then check the presence of - [unsigned] [zerofill] attributes and cut them of if exist. - */ - tmp_buff= strchr(type.ptr(), ' '); - table->field[7]->store(type.ptr(), - (tmp_buff ? tmp_buff - type.ptr() : - type.length()), cs); - if (get_field_default_value(thd, show_table, field, &type, 0)) + if (get_field_default_value(thd, timestamp_field, field, &type, 0)) { table->field[5]->store(type.ptr(), type.length(), cs); table->field[5]->set_notnull(); } - pos=(uchar*) ((flags & NOT_NULL_FLAG) ? "NO" : "YES"); + pos=(uchar*) ((field->flags & NOT_NULL_FLAG) ? "NO" : "YES"); table->field[6]->store((const char*) pos, strlen((const char*) pos), cs); - is_blob= (field->type() == MYSQL_TYPE_BLOB); - if (field->has_charset() || is_blob || - field->real_type() == MYSQL_TYPE_VARCHAR || // For varbinary type - field->real_type() == MYSQL_TYPE_STRING) // For binary type - { - uint32 octet_max_length= field->max_display_length(); - if (is_blob && octet_max_length != (uint32) 4294967295U) - octet_max_length /= field->charset()->mbmaxlen; - longlong char_max_len= is_blob ? - (longlong) octet_max_length / field->charset()->mbminlen : - (longlong) octet_max_length / field->charset()->mbmaxlen; - table->field[8]->store(char_max_len, TRUE); - table->field[8]->set_notnull(); - table->field[9]->store((longlong) octet_max_length, TRUE); - table->field[9]->set_notnull(); - } - - /* - Calculate field_length and decimals. - They are set to -1 if they should not be set (we should return NULL) - */ - - decimals= field->decimals(); - switch (field->type()) { - case MYSQL_TYPE_NEWDECIMAL: - field_length= ((Field_new_decimal*) field)->precision; - break; - case MYSQL_TYPE_DECIMAL: - field_length= field->field_length - (decimals ? 2 : 1); - break; - case MYSQL_TYPE_TINY: - case MYSQL_TYPE_SHORT: - case MYSQL_TYPE_LONG: - case MYSQL_TYPE_LONGLONG: - case MYSQL_TYPE_INT24: - field_length= field->max_display_length() - 1; - break; - case MYSQL_TYPE_BIT: - field_length= field->max_display_length(); - decimals= -1; // return NULL - break; - case MYSQL_TYPE_FLOAT: - case MYSQL_TYPE_DOUBLE: - field_length= field->field_length; - if (decimals == NOT_FIXED_DEC) - decimals= -1; // return NULL - break; - default: - field_length= decimals= -1; - break; - } - - if (field_length >= 0) - { - table->field[10]->store((longlong) field_length, TRUE); - table->field[10]->set_notnull(); - } - if (decimals >= 0) - { - table->field[11]->store((longlong) decimals, TRUE); - table->field[11]->set_notnull(); - } - - if (field->has_charset()) - { - pos=(uchar*) field->charset()->csname; - table->field[12]->store((const char*) pos, - strlen((const char*) pos), cs); - table->field[12]->set_notnull(); - pos=(uchar*) field->charset()->name; - table->field[13]->store((const char*) pos, - strlen((const char*) pos), cs); - table->field[13]->set_notnull(); - } + store_column_type(table, field, cs, 7); pos=(uchar*) ((field->flags & PRI_KEY_FLAG) ? "PRI" : (field->flags & UNIQUE_KEY_FLAG) ? "UNI" : (field->flags & MULTIPLE_KEY_FLAG) ? "MUL":""); @@ -3914,7 +4003,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, end= tmp; if (field->unireg_check == Field::NEXT_NUMBER) table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs); - if (show_table->timestamp_field == field && + if (timestamp_field == field && field->unireg_check != Field::TIMESTAMP_DN_FIELD) table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"), cs); @@ -3927,7 +4016,6 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, } - int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond) { CHARSET_INFO **cs; @@ -4116,6 +4204,169 @@ int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond) } +/** + @brief Store record into I_S.PARAMETERS table + + @param[in] thd thread handler + @param[in] table I_S table + @param[in] proc_table 'mysql.proc' table + @param[in] wild wild string, not used for now, + will be useful + if we add 'SHOW PARAMETERs' + @param[in] full_access if 1 user has privileges on the routine + @param[in] sp_user user in 'user@host' format + + @return Operation status + @retval 0 ok + @retval 1 error +*/ + +bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table, + const char *wild, bool full_access, + const char *sp_user) +{ + TABLE_SHARE share; + TABLE tbl; + CHARSET_INFO *cs= system_charset_info; + char params_buff[MAX_FIELD_WIDTH], returns_buff[MAX_FIELD_WIDTH], + sp_db_buff[NAME_LEN], sp_name_buff[NAME_LEN], path[FN_REFLEN], + definer_buff[USERNAME_LENGTH + HOSTNAME_LENGTH + 1]; + String params(params_buff, sizeof(params_buff), cs); + String returns(returns_buff, sizeof(returns_buff), cs); + String sp_db(sp_db_buff, sizeof(sp_db_buff), cs); + String sp_name(sp_name_buff, sizeof(sp_name_buff), cs); + String definer(definer_buff, sizeof(definer_buff), cs); + sp_head *sp; + uint routine_type; + bool free_sp_head; + DBUG_ENTER("store_schema_params"); + + bzero((char*) &tbl, sizeof(TABLE)); + (void) build_table_filename(path, sizeof(path), "", "", "", 0); + init_tmp_table_share(thd, &share, "", 0, "", path); + + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_DB], &sp_db); + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_NAME], &sp_name); + get_field(thd->mem_root,proc_table->field[MYSQL_PROC_FIELD_DEFINER],&definer); + routine_type= (uint) proc_table->field[MYSQL_PROC_MYSQL_TYPE]->val_int(); + + if (!full_access) + full_access= !strcmp(sp_user, definer.ptr()); + if (!full_access && + check_some_routine_access(thd, sp_db.ptr(),sp_name.ptr(), + routine_type == TYPE_ENUM_PROCEDURE)) + DBUG_RETURN(0); + + params.length(0); + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_PARAM_LIST], + ¶ms); + returns.length(0); + if (routine_type == TYPE_ENUM_FUNCTION) + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_RETURNS], + &returns); + + sp= sp_load_for_information_schema(thd, proc_table, &sp_db, &sp_name, + (ulong) proc_table-> + field[MYSQL_PROC_FIELD_SQL_MODE]->val_int(), + routine_type, + returns.c_ptr_safe(), + params.c_ptr_safe(), + &free_sp_head); + + if (sp) + { + Field *field; + Create_field *field_def; + String tmp_string; + if (routine_type == TYPE_ENUM_FUNCTION) + { + restore_record(table, s->default_values); + table->field[0]->store(STRING_WITH_LEN("def"), cs); + table->field[1]->store(sp_db.ptr(), sp_db.length(), cs); + table->field[2]->store(sp_name.ptr(), sp_name.length(), cs); + table->field[3]->store((longlong) 0, TRUE); + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_MYSQL_TYPE], + &tmp_string); + table->field[14]->store(tmp_string.ptr(), tmp_string.length(), cs); + field_def= &sp->m_return_field_def; + field= make_field(&share, (uchar*) 0, field_def->length, + (uchar*) "", 0, field_def->pack_flag, + field_def->sql_type, field_def->charset, + field_def->geom_type, Field::NONE, + field_def->interval, ""); + + field->table= &tbl; + tbl.in_use= thd; + store_column_type(table, field, cs, 6); + if (schema_table_store_record(thd, table)) + { + free_table_share(&share); + if (free_sp_head) + delete sp; + DBUG_RETURN(1); + } + } + + sp_pcontext *spcont= sp->get_parse_context(); + uint params= spcont->context_var_count(); + for (uint i= 0 ; i < params ; i++) + { + const char *tmp_buff; + sp_variable_t *spvar= spcont->find_variable(i); + field_def= &spvar->field_def; + switch (spvar->mode) { + case sp_param_in: + tmp_buff= "IN"; + break; + case sp_param_out: + tmp_buff= "OUT"; + break; + case sp_param_inout: + tmp_buff= "INOUT"; + break; + default: + tmp_buff= ""; + break; + } + + restore_record(table, s->default_values); + table->field[0]->store(STRING_WITH_LEN("def"), cs); + table->field[1]->store(sp_db.ptr(), sp_db.length(), cs); + table->field[2]->store(sp_name.ptr(), sp_name.length(), cs); + table->field[3]->store((longlong) i + 1, TRUE); + table->field[4]->store(tmp_buff, strlen(tmp_buff), cs); + table->field[4]->set_notnull(); + table->field[5]->store(spvar->name.str, spvar->name.length, cs); + table->field[5]->set_notnull(); + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_MYSQL_TYPE], + &tmp_string); + table->field[14]->store(tmp_string.ptr(), tmp_string.length(), cs); + + field= make_field(&share, (uchar*) 0, field_def->length, + (uchar*) "", 0, field_def->pack_flag, + field_def->sql_type, field_def->charset, + field_def->geom_type, Field::NONE, + field_def->interval, spvar->name.str); + + field->table= &tbl; + tbl.in_use= thd; + store_column_type(table, field, cs, 6); + if (schema_table_store_record(thd, table)) + { + free_table_share(&share); + if (free_sp_head) + delete sp; + DBUG_RETURN(1); + } + } + if (free_sp_head) + delete sp; + } + free_table_share(&share); + DBUG_RETURN(0); +} + + bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, const char *wild, bool full_access, const char *sp_user) { @@ -4124,75 +4375,131 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, MYSQL_TIME time; LEX *lex= thd->lex; CHARSET_INFO *cs= system_charset_info; - get_field(thd->mem_root, proc_table->field[0], &sp_db); - get_field(thd->mem_root, proc_table->field[1], &sp_name); - get_field(thd->mem_root, proc_table->field[11], &definer); + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_DB], &sp_db); + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_NAME], &sp_name); + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_DEFINER],&definer); if (!full_access) full_access= !strcmp(sp_user, definer.ptr()); - if (!full_access && check_some_routine_access(thd, sp_db.ptr(), - sp_name.ptr(), - proc_table->field[2]-> - val_int() == - TYPE_ENUM_PROCEDURE)) + if (!full_access && + check_some_routine_access(thd, sp_db.ptr(), sp_name.ptr(), + proc_table->field[MYSQL_PROC_MYSQL_TYPE]-> + val_int() == TYPE_ENUM_PROCEDURE)) return 0; if ((lex->sql_command == SQLCOM_SHOW_STATUS_PROC && - proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE) || + proc_table->field[MYSQL_PROC_MYSQL_TYPE]->val_int() == + TYPE_ENUM_PROCEDURE) || (lex->sql_command == SQLCOM_SHOW_STATUS_FUNC && - proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION) || + proc_table->field[MYSQL_PROC_MYSQL_TYPE]->val_int() == + TYPE_ENUM_FUNCTION) || (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0) { restore_record(table, s->default_values); if (!wild || !wild[0] || !wild_compare(sp_name.ptr(), wild, 0)) { - int enum_idx= (int) proc_table->field[5]->val_int(); + int enum_idx= (int) proc_table->field[MYSQL_PROC_FIELD_ACCESS]->val_int(); table->field[3]->store(sp_name.ptr(), sp_name.length(), cs); - get_field(thd->mem_root, proc_table->field[3], &tmp_string); + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_SPECIFIC_NAME], + &tmp_string); table->field[0]->store(tmp_string.ptr(), tmp_string.length(), cs); table->field[1]->store(STRING_WITH_LEN("def"), cs); table->field[2]->store(sp_db.ptr(), sp_db.length(), cs); - get_field(thd->mem_root, proc_table->field[2], &tmp_string); + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_MYSQL_TYPE], + &tmp_string); table->field[4]->store(tmp_string.ptr(), tmp_string.length(), cs); - if (proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION) + if (proc_table->field[MYSQL_PROC_MYSQL_TYPE]->val_int() == + TYPE_ENUM_FUNCTION) { - get_field(thd->mem_root, proc_table->field[9], &tmp_string); - table->field[5]->store(tmp_string.ptr(), tmp_string.length(), cs); - table->field[5]->set_notnull(); + sp_head *sp; + bool free_sp_head; + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_RETURNS], + &tmp_string); + + sp= sp_load_for_information_schema(thd, proc_table, &sp_db, &sp_name, + (ulong) proc_table-> + field[MYSQL_PROC_FIELD_SQL_MODE]-> + val_int(), + TYPE_ENUM_FUNCTION, + tmp_string.c_ptr_safe(), + "", &free_sp_head); + + if (sp) + { + char path[FN_REFLEN]; + TABLE_SHARE share; + TABLE tbl; + Field *field; + Create_field *field_def= &sp->m_return_field_def; + + bzero((char*) &tbl, sizeof(TABLE)); + (void) build_table_filename(path, sizeof(path), "", "", "", 0); + init_tmp_table_share(thd, &share, "", 0, "", path); + field= make_field(&share, (uchar*) 0, field_def->length, + (uchar*) "", 0, field_def->pack_flag, + field_def->sql_type, field_def->charset, + field_def->geom_type, Field::NONE, + field_def->interval, ""); + + field->table= &tbl; + tbl.in_use= thd; + store_column_type(table, field, cs, 5); + free_table_share(&share); + if (free_sp_head) + delete sp; + } } + if (full_access) { - get_field(thd->mem_root, proc_table->field[19], &tmp_string); - table->field[7]->store(tmp_string.ptr(), tmp_string.length(), cs); - table->field[7]->set_notnull(); + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_BODY_UTF8], + &tmp_string); + table->field[14]->store(tmp_string.ptr(), tmp_string.length(), cs); + table->field[14]->set_notnull(); } - table->field[6]->store(STRING_WITH_LEN("SQL"), cs); - table->field[10]->store(STRING_WITH_LEN("SQL"), cs); - get_field(thd->mem_root, proc_table->field[6], &tmp_string); - table->field[11]->store(tmp_string.ptr(), tmp_string.length(), cs); - table->field[12]->store(sp_data_access_name[enum_idx].str, + table->field[13]->store(STRING_WITH_LEN("SQL"), cs); + table->field[17]->store(STRING_WITH_LEN("SQL"), cs); + + + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_DETERMINISTIC], + &tmp_string); + table->field[18]->store(tmp_string.ptr(), tmp_string.length(), cs); + table->field[19]->store(sp_data_access_name[enum_idx].str, sp_data_access_name[enum_idx].length , cs); - get_field(thd->mem_root, proc_table->field[7], &tmp_string); - table->field[14]->store(tmp_string.ptr(), tmp_string.length(), cs); + + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_SECURITY_TYPE], + &tmp_string); + table->field[21]->store(tmp_string.ptr(), tmp_string.length(), cs); bzero((char *)&time, sizeof(time)); - ((Field_timestamp *) proc_table->field[12])->get_time(&time); - table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); + ((Field_timestamp *) proc_table->field[MYSQL_PROC_FIELD_CREATED])-> + get_time(&time); + table->field[22]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); bzero((char *)&time, sizeof(time)); - ((Field_timestamp *) proc_table->field[13])->get_time(&time); - table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); - get_field(thd->mem_root, proc_table->field[14], &tmp_string); - table->field[17]->store(tmp_string.ptr(), tmp_string.length(), cs); - get_field(thd->mem_root, proc_table->field[15], &tmp_string); - table->field[18]->store(tmp_string.ptr(), tmp_string.length(), cs); - table->field[19]->store(definer.ptr(), definer.length(), cs); + ((Field_timestamp *) proc_table->field[MYSQL_PROC_FIELD_MODIFIED])-> + get_time(&time); + table->field[23]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); - get_field(thd->mem_root, proc_table->field[16], &tmp_string); - table->field[20]->store(tmp_string.ptr(), tmp_string.length(), cs); + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_SQL_MODE], + &tmp_string); + table->field[24]->store(tmp_string.ptr(), tmp_string.length(), cs); - get_field(thd->mem_root, proc_table->field[17], &tmp_string); - table->field[21]->store(tmp_string.ptr(), tmp_string.length(), cs); + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_COMMENT], + &tmp_string); + table->field[25]->store(tmp_string.ptr(), tmp_string.length(), cs); + table->field[26]->store(definer.ptr(), definer.length(), cs); - get_field(thd->mem_root, proc_table->field[18], &tmp_string); - table->field[22]->store(tmp_string.ptr(), tmp_string.length(), cs); + get_field(thd->mem_root, + proc_table->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT], + &tmp_string); + table->field[27]->store(tmp_string.ptr(), tmp_string.length(), cs); + + get_field(thd->mem_root, + proc_table->field[ MYSQL_PROC_FIELD_COLLATION_CONNECTION], + &tmp_string); + table->field[28]->store(tmp_string.ptr(), tmp_string.length(), cs); + + get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_DB_COLLATION], + &tmp_string); + table->field[29]->store(tmp_string.ptr(), tmp_string.length(), cs); return schema_table_store_record(thd, table); } @@ -4211,6 +4518,8 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond) bool full_access; char definer[USER_HOST_BUFF_SIZE]; Open_tables_state open_tables_state_backup; + enum enum_schema_tables schema_table_idx= + get_schema_table_idx(tables->schema_table); DBUG_ENTER("fill_schema_proc"); strxmov(definer, thd->security_ctx->priv_user, "@", @@ -4234,14 +4543,19 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond) res= (res == HA_ERR_END_OF_FILE) ? 0 : 1; goto err; } - if (store_schema_proc(thd, table, proc_table, wild, full_access, definer)) + + if (schema_table_idx == SCH_PROCEDURES ? + store_schema_proc(thd, table, proc_table, wild, full_access, definer) : + store_schema_params(thd, table, proc_table, wild, full_access, definer)) { res= 1; goto err; } while (!proc_table->file->index_next(proc_table->record[0])) { - if (store_schema_proc(thd, table, proc_table, wild, full_access, definer)) + if (schema_table_idx == SCH_PROCEDURES ? + store_schema_proc(thd, table, proc_table, wild, full_access, definer): + store_schema_params(thd, table, proc_table, wild, full_access, definer)) { res= 1; goto err; @@ -4356,24 +4670,15 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables, LEX_STRING *table_name) { CHARSET_INFO *cs= system_charset_info; - DBUG_ENTER("get_schema_views_record"); - LEX_STRING *tmp_db_name, *tmp_table_name; char definer[USER_HOST_BUFF_SIZE]; uint definer_len; bool updatable_view; - /* - if SELECT FROM I_S.VIEWS uses only fields - which have OPEN_FRM_ONLY flag then 'tables' - structure is zeroed and only tables->view is set. - (see fill_schema_table_from_frm() function). - So we should disable other fields filling. - */ - bool only_share= !tables->definer.user.str; + DBUG_ENTER("get_schema_views_record"); if (tables->view) { Security_context *sctx= thd->security_ctx; - if (!only_share && !tables->allowed_show) + if (!tables->allowed_show) { if (!my_strcasecmp(system_charset_info, tables->definer.user.str, sctx->priv_user) && @@ -4391,47 +4696,42 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables, TABLE_LIST table_list; uint view_access; memset(&table_list, 0, sizeof(table_list)); - table_list.db= tables->view_db.str; - table_list.table_name= tables->view_name.str; + table_list.db= tables->db; + table_list.table_name= tables->table_name; table_list.grant.privilege= thd->col_access; view_access= get_table_grant(thd, &table_list); - if ((view_access & (SHOW_VIEW_ACL|SELECT_ACL)) == - (SHOW_VIEW_ACL|SELECT_ACL)) - tables->allowed_show= TRUE; + if ((view_access & (SHOW_VIEW_ACL|SELECT_ACL)) == + (SHOW_VIEW_ACL|SELECT_ACL)) + tables->allowed_show= TRUE; } } #endif } restore_record(table, s->default_values); - tmp_db_name= &tables->view_db; - tmp_table_name= &tables->view_name; - if (only_share) - { - tmp_db_name= db_name; - tmp_table_name= table_name; - } table->field[0]->store(STRING_WITH_LEN("def"), cs); - table->field[1]->store(tmp_db_name->str, tmp_db_name->length, cs); - table->field[2]->store(tmp_table_name->str, tmp_table_name->length, cs); - if (!only_share) + table->field[1]->store(db_name->str, db_name->length, cs); + table->field[2]->store(table_name->str, table_name->length, cs); + + if (tables->allowed_show) { - if (tables->allowed_show) - { - table->field[3]->store(tables->view_body_utf8.str, - tables->view_body_utf8.length, - cs); - } + table->field[3]->store(tables->view_body_utf8.str, + tables->view_body_utf8.length, + cs); + } - if (tables->with_check != VIEW_CHECK_NONE) - { - if (tables->with_check == VIEW_CHECK_LOCAL) - table->field[4]->store(STRING_WITH_LEN("LOCAL"), cs); - else - table->field[4]->store(STRING_WITH_LEN("CASCADED"), cs); - } + if (tables->with_check != VIEW_CHECK_NONE) + { + if (tables->with_check == VIEW_CHECK_LOCAL) + table->field[4]->store(STRING_WITH_LEN("LOCAL"), cs); else - table->field[4]->store(STRING_WITH_LEN("NONE"), cs); + table->field[4]->store(STRING_WITH_LEN("CASCADED"), cs); + } + else + table->field[4]->store(STRING_WITH_LEN("NONE"), cs); + if (table->pos_in_table_list->table_open_method & + OPEN_FULL_TABLE) + { updatable_view= 0; if (tables->algorithm != VIEW_ALGORITHM_TMPTABLE) { @@ -4465,31 +4765,33 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables, table->field[5]->store(STRING_WITH_LEN("YES"), cs); else table->field[5]->store(STRING_WITH_LEN("NO"), cs); - definer_len= (strxmov(definer, tables->definer.user.str, "@", - tables->definer.host.str, NullS) - definer); - table->field[6]->store(definer, definer_len, cs); - if (tables->view_suid) - table->field[7]->store(STRING_WITH_LEN("DEFINER"), cs); - else - table->field[7]->store(STRING_WITH_LEN("INVOKER"), cs); + } - table->field[8]->store(tables->view_creation_ctx->get_client_cs()->csname, - strlen(tables->view_creation_ctx-> - get_client_cs()->csname), cs); + definer_len= (strxmov(definer, tables->definer.user.str, "@", + tables->definer.host.str, NullS) - definer); + table->field[6]->store(definer, definer_len, cs); + if (tables->view_suid) + table->field[7]->store(STRING_WITH_LEN("DEFINER"), cs); + else + table->field[7]->store(STRING_WITH_LEN("INVOKER"), cs); + + table->field[8]->store(tables->view_creation_ctx->get_client_cs()->csname, + strlen(tables->view_creation_ctx-> + get_client_cs()->csname), cs); + + table->field[9]->store(tables->view_creation_ctx-> + get_connection_cl()->name, + strlen(tables->view_creation_ctx-> + get_connection_cl()->name), cs); - table->field[9]->store(tables->view_creation_ctx-> - get_connection_cl()->name, - strlen(tables->view_creation_ctx-> - get_connection_cl()->name), cs); - } if (schema_table_store_record(thd, table)) DBUG_RETURN(1); if (res && thd->is_error()) - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, thd->stmt_da->sql_errno(), thd->stmt_da->message()); } - if (res) + if (res) thd->clear_error(); DBUG_RETURN(0); } @@ -5995,7 +6297,7 @@ int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) int make_proc_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) { - int fields_arr[]= {2, 3, 4, 19, 16, 15, 14, 18, 20, 21, 22, -1}; + int fields_arr[]= {2, 3, 4, 26, 23, 22, 21, 25, 27, 28, 29, -1}; int *field_num= fields_arr; ST_FIELD_INFO *field_info; Name_resolution_context *context= &thd->lex->select_lex.context; @@ -6447,7 +6749,14 @@ ST_FIELD_INFO proc_fields_info[]= {"ROUTINE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name", SKIP_OPEN_TABLE}, {"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE}, - {"DTD_IDENTIFIER", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"DATA_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"CHARACTER_MAXIMUM_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, SKIP_OPEN_TABLE}, + {"CHARACTER_OCTET_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, SKIP_OPEN_TABLE}, + {"NUMERIC_PRECISION", 21 , MYSQL_TYPE_LONG, 0, 1, 0, SKIP_OPEN_TABLE}, + {"NUMERIC_SCALE", 21 , MYSQL_TYPE_LONG, 0, 1, 0, SKIP_OPEN_TABLE}, + {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, + {"DTD_IDENTIFIER", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, {"ROUTINE_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, {"ROUTINE_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, {"EXTERNAL_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, @@ -6505,15 +6814,15 @@ ST_FIELD_INFO view_fields_info[]= {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, - {"VIEW_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, - {"CHECK_OPTION", 8, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"VIEW_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, + {"CHECK_OPTION", 8, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, {"IS_UPDATABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, - {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, - {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, + {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0, - OPEN_FULL_TABLE}, + OPEN_FRM_ONLY}, {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0, - OPEN_FULL_TABLE}, + OPEN_FRM_ONLY}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; @@ -6628,38 +6937,38 @@ ST_FIELD_INFO open_tables_fields_info[]= ST_FIELD_INFO triggers_fields_info[]= { - {"TRIGGER_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, - {"TRIGGER_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"TRIGGER_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, + {"TRIGGER_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, {"TRIGGER_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Trigger", - OPEN_FULL_TABLE}, - {"EVENT_MANIPULATION", 6, MYSQL_TYPE_STRING, 0, 0, "Event", OPEN_FULL_TABLE}, + OPEN_FRM_ONLY}, + {"EVENT_MANIPULATION", 6, MYSQL_TYPE_STRING, 0, 0, "Event", OPEN_FRM_ONLY}, {"EVENT_OBJECT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 0, 0, - OPEN_FULL_TABLE}, + OPEN_FRM_ONLY}, {"EVENT_OBJECT_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, - OPEN_FULL_TABLE}, + OPEN_FRM_ONLY}, {"EVENT_OBJECT_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", - OPEN_FULL_TABLE}, - {"ACTION_ORDER", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE}, - {"ACTION_CONDITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE}, + OPEN_FRM_ONLY}, + {"ACTION_ORDER", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, OPEN_FRM_ONLY}, + {"ACTION_CONDITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY}, {"ACTION_STATEMENT", 65535, MYSQL_TYPE_STRING, 0, 0, "Statement", - OPEN_FULL_TABLE}, - {"ACTION_ORIENTATION", 9, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, - {"ACTION_TIMING", 6, MYSQL_TYPE_STRING, 0, 0, "Timing", OPEN_FULL_TABLE}, + OPEN_FRM_ONLY}, + {"ACTION_ORIENTATION", 9, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, + {"ACTION_TIMING", 6, MYSQL_TYPE_STRING, 0, 0, "Timing", OPEN_FRM_ONLY}, {"ACTION_REFERENCE_OLD_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, - OPEN_FULL_TABLE}, + OPEN_FRM_ONLY}, {"ACTION_REFERENCE_NEW_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, - OPEN_FULL_TABLE}, - {"ACTION_REFERENCE_OLD_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, - {"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, - {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 1, "Created", OPEN_FULL_TABLE}, - {"SQL_MODE", 32*256, MYSQL_TYPE_STRING, 0, 0, "sql_mode", OPEN_FULL_TABLE}, - {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", OPEN_FULL_TABLE}, + OPEN_FRM_ONLY}, + {"ACTION_REFERENCE_OLD_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, + {"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, + {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 1, "Created", OPEN_FRM_ONLY}, + {"SQL_MODE", 32*256, MYSQL_TYPE_STRING, 0, 0, "sql_mode", OPEN_FRM_ONLY}, + {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", OPEN_FRM_ONLY}, {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, - "character_set_client", OPEN_FULL_TABLE}, + "character_set_client", OPEN_FRM_ONLY}, {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, - "collation_connection", OPEN_FULL_TABLE}, + "collation_connection", OPEN_FRM_ONLY}, {"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, - "Database Collation", OPEN_FULL_TABLE}, + "Database Collation", OPEN_FRM_ONLY}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; @@ -6838,6 +7147,28 @@ ST_FIELD_INFO referential_constraints_fields_info[]= }; +ST_FIELD_INFO parameters_fields_info[]= +{ + {"SPECIFIC_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"SPECIFIC_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, + OPEN_FULL_TABLE}, + {"SPECIFIC_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 0, 0, OPEN_FULL_TABLE}, + {"PARAMETER_MODE", 5, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE}, + {"PARAMETER_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE}, + {"DATA_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"CHARACTER_MAXIMUM_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE}, + {"CHARACTER_OCTET_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE}, + {"NUMERIC_PRECISION", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE}, + {"NUMERIC_SCALE", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE}, + {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE}, + {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE}, + {"DTD_IDENTIFIER", 65535, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE} +}; + + ST_FIELD_INFO tablespaces_fields_info[]= { {"TABLESPACE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, @@ -6901,6 +7232,8 @@ ST_SCHEMA_TABLE schema_tables[]= OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, {"OPEN_TABLES", open_tables_fields_info, create_schema_table, fill_open_tables, make_old_format, 0, -1, -1, 1, 0}, + {"PARAMETERS", parameters_fields_info, create_schema_table, + fill_schema_proc, 0, 0, -1, -1, 0, 0}, {"PARTITIONS", partitions_fields_info, create_schema_table, get_all_tables, 0, get_schema_partitions_record, 1, 2, 0, OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, @@ -6943,7 +7276,7 @@ ST_SCHEMA_TABLE schema_tables[]= fill_schema_table_privileges, 0, 0, -1, -1, 0, 0}, {"TRIGGERS", triggers_fields_info, create_schema_table, get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0, - OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, + OPEN_TRIGGER_ONLY|OPTIMIZE_I_S_TABLE}, {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, fill_schema_user_privileges, 0, 0, -1, -1, 0, 0}, {"VARIABLES", variables_fields_info, create_schema_table, fill_variables, diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 6f0602cedfd..ee530a74b50 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -1198,12 +1198,13 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, DBUG_RETURN(1); // EOM } - - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_TRG_NO_CREATION_CTX, - ER(ER_TRG_NO_CREATION_CTX), - (const char*) db, - (const char*) table_name); + + if (!thd->no_warnings_for_error) + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRG_NO_CREATION_CTX, + ER(ER_TRG_NO_CREATION_CTX), + (const char*) db, + (const char*) table_name); if (!(trg_client_cs_name= alloc_lex_string(&table->mem_root)) || !(trg_connection_cl_name= alloc_lex_string(&table->mem_root)) || @@ -1332,12 +1333,12 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, MySQL, which does not support triggers definers. We should emit warning here. */ - - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_TRG_NO_DEFINER, ER(ER_TRG_NO_DEFINER), - (const char*) db, - (const char*) lex.sphead->m_name.str); - + if (!thd->no_warnings_for_error) + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRG_NO_DEFINER, ER(ER_TRG_NO_DEFINER), + (const char*) db, + (const char*) lex.sphead->m_name.str); + /* Set definer to the '' to correct displaying in the information schema. diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 6f824750737..31e4a45ce4f 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1123,8 +1123,18 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, table->db, table->table_name); get_default_definer(thd, &table->definer); } + + /* + Initialize view definition context by character set names loaded from + the view definition file. Use UTF8 character set if view definition + file is of old version and does not contain the character set names. + */ + table->view_creation_ctx= View_creation_ctx::create(thd, table); + if (flags & OPEN_VIEW_NO_PARSE) { + if (arena) + thd->restore_active_arena(arena, &backup); DBUG_RETURN(FALSE); } @@ -1139,13 +1149,6 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, /*TODO: md5 test here and warning if it is differ */ - /* - Initialize view definition context by character set names loaded from - the view definition file. Use UTF8 character set if view definition - file is of old version and does not contain the character set names. - */ - - table->view_creation_ctx= View_creation_ctx::create(thd, table); /* TODO: TABLE mem root should be used here when VIEW will be stored in diff --git a/sql/unireg.h b/sql/unireg.h index 3b39532d29d..def4fb12b39 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -194,6 +194,11 @@ */ #define OPTIMIZE_I_S_TABLE OPEN_VIEW_FULL*2 +/* + The flag means that we need to process trigger files only. +*/ +#define OPEN_TRIGGER_ONLY OPTIMIZE_I_S_TABLE*2 + #define SC_INFO_LENGTH 4 /* Form format constant */ #define TE_INFO_LENGTH 3 #define MTYP_NOEMPTY_BIT 128 |