1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

MDEV-7671: Cache VIEW definitions in the TDC

(changes of backported patch are very small: strlen removed, error processing fixed, view open statistics added)
This commit is contained in:
Oleksandr Byelkin
2015-03-10 10:24:20 +01:00
parent 3aa1a600bb
commit 80f03abcca
17 changed files with 141 additions and 213 deletions

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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));

View File

@ -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,

View File

@ -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");

View File

@ -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);

View File

@ -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,

View File

@ -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),

View File

@ -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,

View File

@ -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,

View File

@ -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);
/*

View File

@ -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,

View File

@ -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:

View File

@ -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);

View File

@ -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))

View File

@ -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