diff options
-rw-r--r-- | mysql-test/suite/roles/definer.result | 1 | ||||
-rw-r--r-- | mysql-test/suite/roles/definer.test | 1 | ||||
-rw-r--r-- | plugin/handler_socket/handlersocket/database.cpp | 2 | ||||
-rw-r--r-- | sql/parse_file.cc | 62 | ||||
-rw-r--r-- | sql/parse_file.h | 26 | ||||
-rw-r--r-- | sql/sql_admin.cc | 2 | ||||
-rw-r--r-- | sql/sql_base.cc | 122 | ||||
-rw-r--r-- | sql/sql_base.h | 16 | ||||
-rw-r--r-- | sql/sql_insert.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.h | 4 | ||||
-rw-r--r-- | sql/sql_show.cc | 8 | ||||
-rw-r--r-- | sql/sql_table.cc | 4 | ||||
-rw-r--r-- | sql/sql_trigger.cc | 23 | ||||
-rw-r--r-- | sql/sql_view.cc | 48 | ||||
-rw-r--r-- | sql/sql_view.h | 4 | ||||
-rw-r--r-- | sql/table.cc | 21 | ||||
-rw-r--r-- | sql/table.h | 8 |
17 files changed, 141 insertions, 213 deletions
diff --git a/mysql-test/suite/roles/definer.result b/mysql-test/suite/roles/definer.result index 0010853be78..a2d84244c38 100644 --- a/mysql-test/suite/roles/definer.result +++ b/mysql-test/suite/roles/definer.result @@ -86,6 +86,7 @@ Warnings: Note 1449 The user specified as a definer ('role4'@'') does not exist select * from test.v5; ERROR HY000: The user specified as a definer ('role4'@'') does not exist +flush tables; show create view test.v5; View Create View character_set_client collation_connection v5 CREATE ALGORITHM=UNDEFINED DEFINER=`role4`@`%` SQL SECURITY DEFINER VIEW `test`.`v5` AS select (`mysqltest1`.`t1`.`a` + `mysqltest1`.`t1`.`b`) AS `a+b`,`mysqltest1`.`t1`.`c` AS `c` from `mysqltest1`.`t1` latin1 latin1_swedish_ci diff --git a/mysql-test/suite/roles/definer.test b/mysql-test/suite/roles/definer.test index 3c069105c8c..995c36a8511 100644 --- a/mysql-test/suite/roles/definer.test +++ b/mysql-test/suite/roles/definer.test @@ -115,6 +115,7 @@ open(F, '>', $f) or die "open(>$f): $!"; syswrite F, $_ or die "syswrite($f): $!" EOF +flush tables; show create view test.v5; select * from test.v5; drop user role4; diff --git a/plugin/handler_socket/handlersocket/database.cpp b/plugin/handler_socket/handlersocket/database.cpp index 2d9785df6e2..36feeaecf07 100644 --- a/plugin/handler_socket/handlersocket/database.cpp +++ b/plugin/handler_socket/handlersocket/database.cpp @@ -1016,7 +1016,7 @@ dbcontext::cmd_open(dbcallback_i& cb, const cmd_open_args& arg) tables.mdl_request.init(MDL_key::TABLE, arg.dbn, arg.tbl, for_write_flag ? MDL_SHARED_WRITE : MDL_SHARED_READ, MDL_TRANSACTION); Open_table_context ot_act(thd, 0); - if (!open_table(thd, &tables, thd->mem_root, &ot_act)) { + if (!open_table(thd, &tables, &ot_act)) { table = tables.table; } #else diff --git a/sql/parse_file.cc b/sql/parse_file.cc index ee031c1bbc2..b815c264b5b 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -404,7 +404,7 @@ sql_parse_prepare(const LEX_STRING *file_name, MEM_ROOT *mem_root, { MY_STAT stat_info; size_t len; - char *end, *sign; + char *buff, *end, *sign; File_parser *parser; File file; DBUG_ENTER("sql_parse_prepare"); @@ -426,7 +426,7 @@ sql_parse_prepare(const LEX_STRING *file_name, MEM_ROOT *mem_root, DBUG_RETURN(0); } - if (!(parser->buff= (char*) alloc_root(mem_root, (size_t)(stat_info.st_size+1)))) + if (!(buff= (char*) alloc_root(mem_root, (size_t)(stat_info.st_size+1)))) { DBUG_RETURN(0); } @@ -437,9 +437,8 @@ sql_parse_prepare(const LEX_STRING *file_name, MEM_ROOT *mem_root, DBUG_RETURN(0); } - if ((len= mysql_file_read(file, (uchar *)parser->buff, - stat_info.st_size, MYF(MY_WME))) == - MY_FILE_ERROR) + if ((len= mysql_file_read(file, (uchar *)buff, stat_info.st_size, + MYF(MY_WME))) == MY_FILE_ERROR) { mysql_file_close(file, MYF(MY_WME)); DBUG_RETURN(0); @@ -450,20 +449,20 @@ sql_parse_prepare(const LEX_STRING *file_name, MEM_ROOT *mem_root, DBUG_RETURN(0); } - end= parser->end= parser->buff + len; + end= buff + len; *end= '\0'; // barrier for more simple parsing // 7 = 5 (TYPE=) + 1 (letter at least of type name) + 1 ('\n') if (len < 7 || - parser->buff[0] != 'T' || - parser->buff[1] != 'Y' || - parser->buff[2] != 'P' || - parser->buff[3] != 'E' || - parser->buff[4] != '=') + buff[0] != 'T' || + buff[1] != 'Y' || + buff[2] != 'P' || + buff[3] != 'E' || + buff[4] != '=') goto frm_error; // skip signature; - parser->file_type.str= sign= parser->buff + 5; + parser->file_type.str= sign= buff + 5; while (*sign >= 'A' && *sign <= 'Z' && sign < end) sign++; if (*sign != '\n') @@ -472,6 +471,7 @@ sql_parse_prepare(const LEX_STRING *file_name, MEM_ROOT *mem_root, // EOS for file signature just for safety *sign= '\0'; + parser->end= end; parser->start= sign + 1; parser->content_ok= 1; @@ -504,11 +504,12 @@ frm_error: */ -static char * -parse_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str) +static const char * +parse_string(const char *ptr, const char *end, MEM_ROOT *mem_root, + LEX_STRING *str) { // get string length - char *eol= strchr(ptr, '\n'); + const char *eol= strchr(ptr, '\n'); if (eol >= end) return 0; @@ -535,7 +536,7 @@ parse_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str) */ my_bool -read_escaped_string(char *ptr, char *eol, LEX_STRING *str) +read_escaped_string(const char *ptr, const char *eol, LEX_STRING *str) { char *write_pos= str->str; @@ -595,10 +596,11 @@ read_escaped_string(char *ptr, char *eol, LEX_STRING *str) */ -char * -parse_escaped_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str) +const char * +parse_escaped_string(const char *ptr, const char *end, MEM_ROOT *mem_root, + LEX_STRING *str) { - char *eol= strchr(ptr, '\n'); + const char *eol= strchr(ptr, '\n'); if (eol == 0 || eol >= end || !(str->str= (char*) alloc_root(mem_root, (eol - ptr) + 1)) || @@ -624,11 +626,11 @@ parse_escaped_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str) \# pointer on symbol after string */ -static char * -parse_quoted_escaped_string(char *ptr, char *end, +static const char * +parse_quoted_escaped_string(const char *ptr, const char *end, MEM_ROOT *mem_root, LEX_STRING *str) { - char *eol; + const char *eol; uint result_len= 0; bool escaped= 0; @@ -665,7 +667,7 @@ parse_quoted_escaped_string(char *ptr, char *end, @param[in] mem_root MEM_ROOT for parameters allocation */ -bool get_file_options_ulllist(char *&ptr, char *end, char *line, +bool get_file_options_ulllist(const char *&ptr, const char *end, const char *line, uchar* base, File_option *parameter, MEM_ROOT *mem_root) { @@ -676,7 +678,7 @@ bool get_file_options_ulllist(char *&ptr, char *end, char *line, while (ptr < end) { int not_used; - char *num_end= end; + char *num_end= const_cast<char *>(end); if (!(num= (ulonglong*)alloc_root(mem_root, sizeof(ulonglong))) || nlist->push_back(num, mem_root)) goto nlist_err; @@ -731,18 +733,18 @@ nlist_err: my_bool File_parser::parse(uchar* base, MEM_ROOT *mem_root, struct File_option *parameters, uint required, - Unknown_key_hook *hook) + Unknown_key_hook *hook) const { uint first_param= 0, found= 0; - char *ptr= start; - char *eol; + const char *ptr= start; + const char *eol; LEX_STRING *str; List<LEX_STRING> *list; DBUG_ENTER("File_parser::parse"); while (ptr < end && found < required) { - char *line= ptr; + const char *line= ptr; if (*ptr == '#') { // it is comment @@ -940,9 +942,9 @@ list_err: */ bool -File_parser_dummy_hook::process_unknown_string(char *&unknown_key, +File_parser_dummy_hook::process_unknown_string(const char *&unknown_key, uchar* base, MEM_ROOT *mem_root, - char *end) + const char *end) { DBUG_ENTER("file_parser_dummy_hook::process_unknown_string"); DBUG_PRINT("info", ("Unknown key: '%60s'", unknown_key)); diff --git a/sql/parse_file.h b/sql/parse_file.h index 2a0266e98b7..e4756e6c8af 100644 --- a/sql/parse_file.h +++ b/sql/parse_file.h @@ -58,8 +58,8 @@ class Unknown_key_hook public: Unknown_key_hook() {} /* Remove gcc warning */ virtual ~Unknown_key_hook() {} /* Remove gcc warning */ - virtual bool process_unknown_string(char *&unknown_key, uchar* base, - MEM_ROOT *mem_root, char *end)= 0; + virtual bool process_unknown_string(const char *&unknown_key, uchar* base, + MEM_ROOT *mem_root, const char *end)= 0; }; @@ -69,18 +69,20 @@ class File_parser_dummy_hook: public Unknown_key_hook { public: File_parser_dummy_hook() {} /* Remove gcc warning */ - virtual bool process_unknown_string(char *&unknown_key, uchar* base, - MEM_ROOT *mem_root, char *end); + virtual bool process_unknown_string(const char *&unknown_key, uchar* base, + MEM_ROOT *mem_root, const char *end); }; extern File_parser_dummy_hook file_parser_dummy_hook; -bool get_file_options_ulllist(char *&ptr, char *end, char *line, - uchar* base, File_option *parameter, +bool get_file_options_ulllist(const char *&ptr, const char *end, + const char *line, uchar* base, + File_option *parameter, MEM_ROOT *mem_root); -char * -parse_escaped_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str); +const char * +parse_escaped_string(const char *ptr, const char *end, MEM_ROOT *mem_root, + LEX_STRING *str); class File_parser; File_parser *sql_parse_prepare(const LEX_STRING *file_name, @@ -96,18 +98,18 @@ my_bool rename_in_schema_file(THD *thd, class File_parser: public Sql_alloc { - char *buff, *start, *end; + char *start, *end; LEX_STRING file_type; bool content_ok; public: - File_parser() :buff(0), start(0), end(0), content_ok(0) + File_parser() :start(0), end(0), content_ok(0) { file_type.str= 0; file_type.length= 0; } bool ok() { return content_ok; } - LEX_STRING *type() { return &file_type; } + const LEX_STRING *type() const { return &file_type; } my_bool parse(uchar* base, MEM_ROOT *mem_root, struct File_option *parameters, uint required, - Unknown_key_hook *hook); + Unknown_key_hook *hook) const; friend File_parser *sql_parse_prepare(const LEX_STRING *file_name, MEM_ROOT *mem_root, diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index fa8a195b8fc..031f875ddb7 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -250,7 +250,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, Now we should be able to open the partially repaired table to finish the repair in the handler later on. */ - if (open_table(thd, table_list, thd->mem_root, &ot_ctx)) + if (open_table(thd, table_list, &ot_ctx)) { error= send_check_errmsg(thd, table_list, "repair", "Failed to open partially repaired table"); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4d22f7f88d3..9ab72442dcd 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -27,7 +27,6 @@ // mysql_lock_have_duplicate #include "sql_show.h" // append_identifier #include "strfunc.h" // find_type -#include "parse_file.h" // sql_parse_prepare, File_parser #include "sql_view.h" // mysql_make_view, VIEW_ANY_ACL #include "sql_parse.h" // check_table_access #include "sql_insert.h" // kill_delayed_threads @@ -2075,8 +2074,6 @@ open_table_get_mdl_lock(THD *thd, Open_table_context *ot_ctx, @param thd Thread context. @param table_list Open first table in list. - @param mem_root Temporary MEM_ROOT to be used for - parsing .FRMs for views. @param ot_ctx Context with flags which modify how open works and which is used to recover from a failed open_table() attempt. @@ -2105,8 +2102,7 @@ open_table_get_mdl_lock(THD *thd, Open_table_context *ot_ctx, TABLE_LIST::view is set for views). */ -bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, - Open_table_context *ot_ctx) +bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx) { TABLE *table; const char *key; @@ -2242,7 +2238,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (dd_frm_is_view(thd, path)) { if (!tdc_open_view(thd, table_list, alias, key, key_length, - mem_root, CHECK_METADATA_VERSION)) + CHECK_METADATA_VERSION)) { DBUG_ASSERT(table_list->view != 0); DBUG_RETURN(FALSE); // VIEW @@ -2416,14 +2412,10 @@ retry_share: goto err_lock; /* Open view */ - if (open_new_frm(thd, share, alias, - (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | - HA_GET_INDEX | HA_TRY_READ_ONLY), - READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, - thd->open_options, - 0, table_list, mem_root)) + if (mysql_make_view(thd, share, table_list, false)) goto err_lock; + /* TODO: Don't free this */ tdc_release_share(share); @@ -2981,7 +2973,7 @@ Locked_tables_list::reopen_tables(THD *thd) continue; /* Links into thd->open_tables upon success */ - if (open_table(thd, table_list, thd->mem_root, &ot_ctx)) + if (open_table(thd, table_list, &ot_ctx)) { unlink_all_closed_tables(thd, 0, reopen_count); DBUG_RETURN(TRUE); @@ -3220,7 +3212,6 @@ check_and_update_routine_version(THD *thd, Sroutine_hash_entry *rt, @param alias Alias name @param cache_key Key for table definition cache @param cache_key_length Length of cache_key - @param mem_root Memory to be used for .frm parsing. @param flags Flags which modify how we open the view @todo This function is needed for special handling of views under @@ -3231,7 +3222,7 @@ check_and_update_routine_version(THD *thd, Sroutine_hash_entry *rt, bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, const char *cache_key, uint cache_key_length, - MEM_ROOT *mem_root, uint flags) + uint flags) { TABLE not_used; TABLE_SHARE *share; @@ -3258,12 +3249,7 @@ bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, goto ret; } - err= open_new_frm(thd, share, alias, - (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | - HA_GET_INDEX | HA_TRY_READ_ONLY), - READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD | flags, - thd->open_options, ¬_used, table_list, mem_root); - + err= mysql_make_view(thd, share, table_list, (flags & OPEN_VIEW_NO_PARSE)); ret: tdc_release_share(share); @@ -3800,8 +3786,6 @@ open_and_process_routine(THD *thd, Query_tables_list *prelocking_ctx, this statement has already been built. @param[in] ot_ctx Context used to recover from a failed open_table() attempt. - @param[in] new_frm_mem Temporary MEM_ROOT to be used for - parsing .FRMs for views. @retval FALSE Success. @retval TRUE Error, reported unless there is a chance to recover from it. @@ -3812,8 +3796,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables, uint *counter, uint flags, Prelocking_strategy *prelocking_strategy, bool has_prelocking_list, - Open_table_context *ot_ctx, - MEM_ROOT *new_frm_mem) + Open_table_context *ot_ctx) { bool error= FALSE; bool safe_to_ignore_table= FALSE; @@ -3945,7 +3928,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables, error= open_temporary_table(thd, tables); if (!error && !tables->table) - error= open_table(thd, tables, new_frm_mem, ot_ctx); + error= open_table(thd, tables, ot_ctx); thd->pop_internal_handler(); safe_to_ignore_table= no_such_table_handler.safely_trapped_errors(); @@ -3963,7 +3946,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables, error= open_temporary_table(thd, tables); if (!error && !tables->table) - error= open_table(thd, tables, new_frm_mem, ot_ctx); + error= open_table(thd, tables, ot_ctx); thd->pop_internal_handler(); safe_to_ignore_table= repair_mrg_table_handler.safely_trapped_errors(); @@ -3981,11 +3964,9 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables, } if (!error && !tables->table) - error= open_table(thd, tables, new_frm_mem, ot_ctx); + error= open_table(thd, tables, ot_ctx); } - free_root(new_frm_mem, MYF(MY_KEEP_PREALLOC)); - if (error) { if (! ot_ctx->can_recover_from_failed_open() && safe_to_ignore_table) @@ -4409,7 +4390,6 @@ bool open_tables(THD *thd, const DDL_options_st &options, TABLE_LIST *tables; Open_table_context ot_ctx(thd, flags); bool error= FALSE; - MEM_ROOT new_frm_mem; bool some_routine_modifies_data= FALSE; bool has_prelocking_list; DBUG_ENTER("open_tables"); @@ -4422,13 +4402,6 @@ bool open_tables(THD *thd, const DDL_options_st &options, DBUG_RETURN(true); } - /* - Initialize temporary MEM_ROOT for new .FRM parsing. Do not alloctaate - anything yet, to avoid penalty for statements which don't use views - and thus new .FRM format. - */ - init_sql_alloc(&new_frm_mem, 8024, 0, MYF(0)); - thd->current_tablenr= 0; restart: /* @@ -4516,8 +4489,7 @@ restart: { error= open_and_process_table(thd, thd->lex, tables, counter, flags, prelocking_strategy, - has_prelocking_list, &ot_ctx, - &new_frm_mem); + has_prelocking_list, &ot_ctx); if (error) { @@ -4684,8 +4656,6 @@ error: THD_STAGE_INFO(thd, stage_after_opening_tables); thd_proc_info(thd, 0); - free_root(&new_frm_mem, MYF(0)); // Free pre-alloced block - if (error && *table_to_open) { (*table_to_open)->table= NULL; @@ -5079,7 +5049,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type, /* This function can't properly handle requests for such metadata locks. */ DBUG_ASSERT(table_list->mdl_request.type < MDL_SHARED_UPGRADABLE); - while ((error= open_table(thd, table_list, thd->mem_root, &ot_ctx)) && + while ((error= open_table(thd, table_list, &ot_ctx)) && ot_ctx.can_recover_from_failed_open()) { /* @@ -9150,72 +9120,6 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order) } -/* - open new .frm format table - - SYNOPSIS - open_new_frm() - THD thread handler - path path to .frm file (without extension) - alias alias for table - db database - table_name name of table - db_stat open flags (for example ->OPEN_KEYFILE|HA_OPEN_RNDFILE..) - can be 0 (example in ha_example_table) - prgflag READ_ALL etc.. - ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc.. - outparam result table - table_desc TABLE_LIST descriptor - mem_root temporary MEM_ROOT for parsing -*/ - -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) -{ - LEX_STRING pathstr; - File_parser *parser; - char path[FN_REFLEN+1]; - DBUG_ENTER("open_new_frm"); - - /* Create path with extension */ - pathstr.length= (uint) (strxnmov(path, sizeof(path) - 1, - share->normalized_path.str, - reg_ext, - NullS) - path); - pathstr.str= path; - - if ((parser= sql_parse_prepare(&pathstr, mem_root, 1))) - { - if (is_equal(&view_type, parser->type())) - { - if (table_desc == 0 || table_desc->required_type == FRMTYPE_TABLE) - { - my_error(ER_WRONG_OBJECT, MYF(0), share->db.str, share->table_name.str, - "BASE TABLE"); - goto err; - } - if (mysql_make_view(thd, parser, table_desc, - (prgflag & OPEN_VIEW_NO_PARSE))) - goto err; - status_var_increment(thd->status_var.opened_views); - } - else - { - /* only VIEWs are supported now */ - my_error(ER_FRM_UNKNOWN_TYPE, MYF(0), share->path.str, parser->type()->str); - goto err; - } - DBUG_RETURN(0); - } - -err: - DBUG_RETURN(1); -} - - bool is_equal(const LEX_STRING *a, const LEX_STRING *b) { return a->length == b->length && !strncmp(a->str, b->str, a->length); diff --git a/sql/sql_base.h b/sql/sql_base.h index 211aaee72b2..0e492fa8cf7 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -117,13 +117,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update, MYSQL_OPEN_GET_NEW_TABLE |\ MYSQL_OPEN_HAS_MDL_LOCK) -bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, - Open_table_context *ot_ctx); - -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 open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx); bool get_key_map_from_key_list(key_map *map, TABLE *table, List<String> *index_list); @@ -308,16 +302,14 @@ void close_all_tables_for_name(THD *thd, TABLE_SHARE *share, TABLE *skip_table); OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild); bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, - const char *cache_key, uint cache_key_length, - MEM_ROOT *mem_root, uint flags); + const char *cache_key, uint cache_key_length, uint flags); static inline bool tdc_open_view(THD *thd, TABLE_LIST *table_list, - const char *alias, MEM_ROOT *mem_root, - uint flags) + const char *alias, uint flags) { const char *key; uint key_length= get_table_def_key(table_list, &key); - return tdc_open_view(thd, table_list, alias, key, key_length, mem_root, flags); + return tdc_open_view(thd, table_list, alias, key, key_length, flags); } TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db, diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 9f4d5218b99..b21f2a51a5b 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -3966,7 +3966,7 @@ static TABLE *create_table_from_items(THD *thd, Here we open the destination table, on which we already have an exclusive metadata lock. */ - if (open_table(thd, create_table, thd->mem_root, &ot_ctx)) + if (open_table(thd, create_table, &ot_ctx)) { quick_rm_table(thd, create_info->db_type, create_table->db, table_case_name(create_info, create_table->table_name), diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 46d667cda8c..2588ba1d8fd 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -542,8 +542,8 @@ public: friend class st_select_lex_unit; friend bool mysql_new_select(LEX *lex, bool move_down); - friend bool mysql_make_view(THD *thd, File_parser *parser, - TABLE_LIST *table, uint flags); + friend bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, + bool open_view_no_parse); friend bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list); friend bool mysql_derived_merge(THD *thd, LEX *lex, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index d3648378cc6..10647a7905c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -28,6 +28,7 @@ #include "sql_table.h" // filename_to_tablename, // primary_key_name, // build_table_filename +#include "sql_view.h" #include "repl_failsafe.h" #include "sql_parse.h" // check_access, check_table_access #include "sql_partition.h" // partition_element @@ -4371,12 +4372,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, goto end_share; } - 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)) + if (mysql_make_view(thd, share, &table_list, true)) goto end_share; table_list.view= (LEX*) share->is_view; res= schema_table->process_table(thd, &table_list, table, diff --git a/sql/sql_table.cc b/sql/sql_table.cc index e9a1ae981dc..4eace56eb13 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5436,7 +5436,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, lock on this table. The table will be closed by close_thread_table() at the end of this branch. */ - open_res= open_table(thd, table, thd->mem_root, &ot_ctx); + open_res= open_table(thd, table, &ot_ctx); /* Restore */ table->open_strategy= save_open_strategy; if (open_res) @@ -7059,7 +7059,7 @@ static bool mysql_inplace_alter_table(THD *thd, } table_list->mdl_request.ticket= mdl_ticket; - if (open_table(thd, table_list, thd->mem_root, &ot_ctx)) + if (open_table(thd, table_list, &ot_ctx)) DBUG_RETURN(true); /* diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 41e0ffe2df6..54a68da28c9 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -286,8 +286,8 @@ public: Handle_old_incorrect_sql_modes_hook(char *file_path) :path(file_path) {}; - virtual bool process_unknown_string(char *&unknown_key, uchar* base, - MEM_ROOT *mem_root, char *end); + virtual bool process_unknown_string(const char *&unknown_key, uchar* base, + MEM_ROOT *mem_root, const char *end); }; @@ -298,8 +298,8 @@ public: LEX_STRING *trigger_table_arg) :path(file_path), trigger_table_value(trigger_table_arg) {}; - virtual bool process_unknown_string(char *&unknown_key, uchar* base, - MEM_ROOT *mem_root, char *end); + virtual bool process_unknown_string(const char *&unknown_key, uchar* base, + MEM_ROOT *mem_root, const char *end); private: char *path; LEX_STRING *trigger_table_value; @@ -2316,10 +2316,9 @@ void Table_triggers_list::set_parse_error_message(char *error_message) #define INVALID_SQL_MODES_LENGTH 13 bool -Handle_old_incorrect_sql_modes_hook::process_unknown_string(char *&unknown_key, - uchar* base, - MEM_ROOT *mem_root, - char *end) +Handle_old_incorrect_sql_modes_hook:: +process_unknown_string(const char *&unknown_key, uchar* base, + MEM_ROOT *mem_root, const char *end) { DBUG_ENTER("Handle_old_incorrect_sql_modes_hook::process_unknown_string"); DBUG_PRINT("info", ("unknown key: %60s", unknown_key)); @@ -2328,7 +2327,7 @@ Handle_old_incorrect_sql_modes_hook::process_unknown_string(char *&unknown_key, unknown_key[INVALID_SQL_MODES_LENGTH] == '=' && !memcmp(unknown_key, STRING_WITH_LEN("sql_modes"))) { - char *ptr= unknown_key + INVALID_SQL_MODES_LENGTH + 1; + const char *ptr= unknown_key + INVALID_SQL_MODES_LENGTH + 1; DBUG_PRINT("info", ("sql_modes affected by BUG#14090 detected")); push_warning_printf(current_thd, @@ -2359,8 +2358,8 @@ Handle_old_incorrect_sql_modes_hook::process_unknown_string(char *&unknown_key, */ bool Handle_old_incorrect_trigger_table_hook:: -process_unknown_string(char *&unknown_key, uchar* base, MEM_ROOT *mem_root, - char *end) +process_unknown_string(const char *&unknown_key, uchar* base, + MEM_ROOT *mem_root, const char *end) { DBUG_ENTER("Handle_old_incorrect_trigger_table_hook::process_unknown_string"); DBUG_PRINT("info", ("unknown key: %60s", unknown_key)); @@ -2369,7 +2368,7 @@ process_unknown_string(char *&unknown_key, uchar* base, MEM_ROOT *mem_root, unknown_key[INVALID_TRIGGER_TABLE_LENGTH] == '=' && !memcmp(unknown_key, STRING_WITH_LEN("trigger_table"))) { - char *ptr= unknown_key + INVALID_TRIGGER_TABLE_LENGTH + 1; + const char *ptr= unknown_key + INVALID_TRIGGER_TABLE_LENGTH + 1; DBUG_PRINT("info", ("trigger_table affected by BUG#15921 detected")); push_warning_printf(current_thd, diff --git a/sql/sql_view.cc b/sql/sql_view.cc index d5f19677d9d..1c64698d983 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -215,8 +215,7 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view) TABLE_LIST decoy; memcpy (&decoy, view, sizeof (TABLE_LIST)); - if (tdc_open_view(thd, &decoy, decoy.alias, thd->mem_root, - OPEN_VIEW_NO_PARSE)) + if (tdc_open_view(thd, &decoy, decoy.alias, OPEN_VIEW_NO_PARSE)) return TRUE; if (!lex->definer) @@ -1038,22 +1037,19 @@ err: -/* +/** read VIEW .frm and create structures - SYNOPSIS - mysql_make_view() - thd Thread handler - parser parser object - table TABLE_LIST structure for filling - flags flags - RETURN - 0 ok - 1 error -*/ + @param[in] thd Thread handler + @param[in] share Share object of view + @param[in] table TABLE_LIST structure for filling + @param[in] open_view_no_parse Flag to indicate open view but + do not parse. -bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, - uint flags) + @return false-in case of success, true-in case of error. +*/ +bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, + bool open_view_no_parse) { SELECT_LEX *end, *UNINIT_VAR(view_select); LEX *old_lex, *lex; @@ -1065,6 +1061,13 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, DBUG_ENTER("mysql_make_view"); DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name)); + if (table->required_type == FRMTYPE_TABLE) + { + my_error(ER_WRONG_OBJECT, MYF(0), share->db.str, share->table_name.str, + "BASE TABLE"); + DBUG_RETURN(true); + } + if (table->view) { /* @@ -1137,12 +1140,14 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, table->definer.user.length= table->definer.host.length= 0; /* - TODO: when VIEWs will be stored in cache, table mem_root should - be used here + TODO: when VIEWs will be stored in cache (not only parser), + table mem_root should be used here */ - if ((result= parser->parse((uchar*)table, thd->mem_root, - view_parameters, required_view_parameters, - &file_parser_dummy_hook))) + DBUG_ASSERT(share->view_def != NULL); + if ((result= share->view_def->parse((uchar*)table, thd->mem_root, + view_parameters, + required_view_parameters, + &file_parser_dummy_hook))) goto end; /* @@ -1174,7 +1179,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, */ table->view_creation_ctx= View_creation_ctx::create(thd, table); - if (flags & OPEN_VIEW_NO_PARSE) + if (open_view_no_parse) { if (arena) thd->restore_active_arena(arena, &backup); @@ -1613,6 +1618,7 @@ end: if (arena) thd->restore_active_arena(arena, &backup); thd->lex= old_lex; + status_var_increment(thd->status_var.opened_views); DBUG_RETURN(result); err: diff --git a/sql/sql_view.h b/sql/sql_view.h index abe95c63e6e..60c7bb504be 100644 --- a/sql/sql_view.h +++ b/sql/sql_view.h @@ -34,8 +34,8 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view, bool mysql_create_view(THD *thd, TABLE_LIST *view, enum_view_create_mode mode); -bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, - uint flags); +bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, + bool open_view_no_parse); bool mysql_drop_view(THD *thd, TABLE_LIST *view, enum_drop_mode drop_mode); diff --git a/sql/table.cc b/sql/table.cc index 33695e730b0..f8e9a424bf9 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -40,6 +40,7 @@ #include "sql_statistics.h" #include "discover.h" #include "mdl.h" // MDL_wait_for_graph_visitor +#include "sql_view.h" /* INFORMATION_SCHEMA name */ LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")}; @@ -558,13 +559,15 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) uchar head[FRM_HEADER_SIZE]; char path[FN_REFLEN]; size_t frmlen, read_length; + uint length; DBUG_ENTER("open_table_def"); DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s'", share->db.str, share->table_name.str, share->normalized_path.str)); share->error= OPEN_FRM_OPEN_ERROR; - strxmov(path, share->normalized_path.str, reg_ext, NullS); + length=(uint) (strxmov(path, share->normalized_path.str, reg_ext, NullS) - + path); if (flags & GTS_FORCE_DISCOVERY) { DBUG_ASSERT(flags & GTS_TABLE); @@ -595,7 +598,21 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) if (memcmp(head, STRING_WITH_LEN("TYPE=VIEW\n")) == 0) { share->is_view= 1; - share->error= flags & GTS_VIEW ? OPEN_FRM_OK : OPEN_FRM_NOT_A_TABLE; + if (flags & GTS_VIEW) + { + LEX_STRING pathstr= { path, length }; + /* + Create view file parser and hold it in TABLE_SHARE member + view_def. + */ + share->view_def= sql_parse_prepare(&pathstr, &share->mem_root, true); + if (!share->view_def) + share->error= OPEN_FRM_ERROR_ALREADY_ISSUED; + else + share->error= OPEN_FRM_OK; + } + else + share->error= OPEN_FRM_NOT_A_TABLE; goto err; } if (!is_binary_frm_header(head)) diff --git a/sql/table.h b/sql/table.h index ba829167ab9..f64718473b4 100644 --- a/sql/table.h +++ b/sql/table.h @@ -30,6 +30,7 @@ #include "mysql_com.h" /* enum_field_types */ #include "thr_lock.h" /* thr_lock_type */ #include "filesort_utils.h" +#include "parse_file.h" /* Structs that defines the TABLE */ @@ -730,6 +731,13 @@ struct TABLE_SHARE */ ulong incompatible_version; + /** + For shares representing views File_parser object with view + definition read from .FRM file. + */ + const File_parser *view_def; + + /* Cache for row-based replication table share checks that does not need to be repeated. Possible values are: -1 when cache value is |