summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/roles/definer.result1
-rw-r--r--mysql-test/suite/roles/definer.test1
-rw-r--r--plugin/handler_socket/handlersocket/database.cpp2
-rw-r--r--sql/parse_file.cc62
-rw-r--r--sql/parse_file.h26
-rw-r--r--sql/sql_admin.cc2
-rw-r--r--sql/sql_base.cc122
-rw-r--r--sql/sql_base.h16
-rw-r--r--sql/sql_insert.cc2
-rw-r--r--sql/sql_lex.h4
-rw-r--r--sql/sql_show.cc8
-rw-r--r--sql/sql_table.cc4
-rw-r--r--sql/sql_trigger.cc23
-rw-r--r--sql/sql_view.cc48
-rw-r--r--sql/sql_view.h4
-rw-r--r--sql/table.cc21
-rw-r--r--sql/table.h8
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, &not_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