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