Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
6a839ff4
Commit
6a839ff4
authored
Apr 09, 2013
by
Sergei Golubchik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
handlerton::discover_table_existence() method
parent
93411518
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
133 additions
and
67 deletions
+133
-67
sql/handler.cc
sql/handler.cc
+97
-0
sql/handler.h
sql/handler.h
+23
-0
sql/sql_base.cc
sql/sql_base.cc
+3
-55
sql/sql_base.h
sql/sql_base.h
+1
-8
sql/sql_db.cc
sql/sql_db.cc
+1
-1
sql/sql_table.cc
sql/sql_table.cc
+8
-3
No files found.
sql/handler.cc
View file @
6a839ff4
...
...
@@ -383,6 +383,11 @@ static int ha_finish_errors(void)
return
0
;
}
volatile
int32
need_full_discover_for_existence
=
0
;
static
int
full_discover_for_existence
(
handlerton
*
,
const
char
*
,
const
char
*
)
{
return
1
;
}
static
int
ext_based_existence
(
handlerton
*
,
const
char
*
,
const
char
*
)
{
return
1
;
}
int
ha_finalize_handlerton
(
st_plugin_int
*
plugin
)
{
...
...
@@ -433,6 +438,9 @@ int ha_finalize_handlerton(st_plugin_int *plugin)
hton2plugin
[
hton
->
slot
]
=
NULL
;
}
if
(
hton
->
discover_table_existence
==
full_discover_for_existence
)
my_atomic_add32
(
&
need_full_discover_for_existence
,
-
1
);
if
(
hton
->
discover_table_names
)
my_atomic_add32
(
&
engines_with_discover_table_names
,
-
1
);
...
...
@@ -486,6 +494,18 @@ int ha_initialize_handlerton(st_plugin_int *plugin)
hton
->
discover
&&
hton
->
tablefile_extensions
[
0
])
hton
->
discover_table_names
=
hton_ext_based_table_discovery
;
// default discover_table_existence implementation
if
(
!
hton
->
discover_table_existence
&&
hton
->
discover
)
{
if
(
hton
->
tablefile_extensions
[
0
])
hton
->
discover_table_existence
=
ext_based_existence
;
else
{
hton
->
discover_table_existence
=
full_discover_for_existence
;
my_atomic_add32
(
&
need_full_discover_for_existence
,
1
);
}
}
/*
the switch below and hton->state should be removed when
command-line options for plugins will be implemented
...
...
@@ -4377,6 +4397,83 @@ int ha_discover(THD *thd, const char *db, const char *name,
DBUG_RETURN
(
error
);
}
/**
Check if a given table exists, without doing a full discover, if possible
*/
static
my_bool
file_ext_exists
(
char
*
path
,
size_t
path_len
,
const
char
*
ext
)
{
strmake
(
path
+
path_len
,
ext
,
FN_REFLEN
-
path_len
);
return
!
access
(
path
,
F_OK
);
}
struct
st_discover_existence_args
{
char
*
path
;
size_t
path_len
;
const
char
*
db
,
*
table_name
;
};
static
my_bool
discover_existence
(
THD
*
thd
,
plugin_ref
plugin
,
void
*
arg
)
{
st_discover_existence_args
*
args
=
(
st_discover_existence_args
*
)
arg
;
handlerton
*
ht
=
plugin_data
(
plugin
,
handlerton
*
);
if
(
ht
->
state
!=
SHOW_OPTION_YES
||
!
ht
->
discover_table_existence
)
return
FALSE
;
if
(
ht
->
discover_table_existence
==
ext_based_existence
)
return
file_ext_exists
(
args
->
path
,
args
->
path_len
,
ht
->
tablefile_extensions
[
0
]);
return
ht
->
discover_table_existence
(
ht
,
args
->
db
,
args
->
table_name
);
}
bool
ha_table_exists
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
)
{
DBUG_ENTER
(
"ha_discover_table_existence"
);
if
(
need_full_discover_for_existence
)
{
enum
open_frm_error
err
;
TABLE_LIST
table
;
DBUG_ASSERT
(
0
);
TABLE_SHARE
*
share
=
get_table_share
(
thd
,
db
,
table_name
,
FRM_READ_TABLE_ONLY
,
&
err
);
if
(
share
)
{
mysql_mutex_lock
(
&
LOCK_open
);
release_table_share
(
share
);
mysql_mutex_unlock
(
&
LOCK_open
);
DBUG_RETURN
(
TRUE
);
}
DBUG_RETURN
(
FALSE
);
}
mysql_mutex_lock
(
&
LOCK_open
);
TABLE_SHARE
*
share
=
get_cached_table_share
(
db
,
table_name
);
mysql_mutex_unlock
(
&
LOCK_open
);
if
(
share
)
DBUG_RETURN
(
TRUE
);
char
path
[
FN_REFLEN
+
1
];
size_t
path_len
=
build_table_filename
(
path
,
sizeof
(
path
)
-
1
,
db
,
table_name
,
""
,
0
);
if
(
file_ext_exists
(
path
,
path_len
,
reg_ext
))
DBUG_RETURN
(
TRUE
);
st_discover_existence_args
args
=
{
path
,
path_len
,
db
,
table_name
};
if
(
plugin_foreach
(
thd
,
discover_existence
,
MYSQL_STORAGE_ENGINE_PLUGIN
,
&
args
))
DBUG_RETURN
(
TRUE
);
DBUG_RETURN
(
FALSE
);
}
/**
Discover all table names in a given database
...
...
sql/handler.h
View file @
6a839ff4
...
...
@@ -1136,6 +1136,27 @@ struct handlerton
*/
int
(
*
discover_table_names
)(
handlerton
*
hton
,
LEX_STRING
*
db
,
MY_DIR
*
dir
,
discovered_list
*
result
);
/*
This is a method that allows to server to check if a table exists without
an overhead of the complete discovery.
By default (if not implemented by the engine, but the discovery_table() is
implemented) it will try to perform a file-based discovery:
- if tablefile_extensions[0] is not null this will look for a file name
with the tablefile_extensions[0] extension.
- if tablefile_extensions[0] is null, this will resort to discover_table().
Note that resorting to discover_table() is slow and the engine
should probably implement its own discover_table_existence() method,
if its tablefile_extensions[0] is null.
Returns 1 if the table exists and 0 if it does not.
*/
int
(
*
discover_table_existence
)(
handlerton
*
hton
,
const
char
*
db
,
const
char
*
table_name
);
};
...
...
@@ -3072,6 +3093,8 @@ int ha_discover(THD* thd, const char* dbname, const char* name,
uchar
**
frmblob
,
size_t
*
frmlen
);
int
ha_discover_table_names
(
THD
*
thd
,
LEX_STRING
*
db
,
MY_DIR
*
dirp
,
handlerton
::
discovered_list
*
result
);
bool
ha_table_exists
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
);
#ifdef MYSQL_SERVER
extern
volatile
int32
engines_with_discover_table_names
;
#endif
...
...
sql/sql_base.cc
View file @
6a839ff4
...
...
@@ -771,7 +771,7 @@ void release_table_share(TABLE_SHARE *share)
# TABLE_SHARE for table
*/
static
TABLE_SHARE
*
get_cached_table_share
(
const
char
*
db
,
const
char
*
table_name
)
TABLE_SHARE
*
get_cached_table_share
(
const
char
*
db
,
const
char
*
table_name
)
{
char
key
[
SAFE_NAME_LEN
*
2
+
2
];
uint
key_length
;
...
...
@@ -2337,58 +2337,6 @@ void drop_open_table(THD *thd, TABLE *table, const char *db_name,
}
/**
Check that table exists in table definition cache, on disk
or in some storage engine.
@param thd Thread context
@param db database name
@param table_name table name
@param path (optional) path to the frm file
@note This function acquires LOCK_open internally.
@note If there is no .FRM file for the table but it exists in one
of engines (e.g. it was created on another node of NDB cluster)
this function will fetch and create proper .FRM file for it.
@retval TRUE Some error occurred
@retval FALSE No error. 'exists' out parameter set accordingly.
*/
bool
table_exists
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
,
const
char
*
path
)
{
char
path_buf
[
FN_REFLEN
+
1
];
TABLE_SHARE
*
share
;
DBUG_ENTER
(
"table_exists"
);
mysql_mutex_lock
(
&
LOCK_open
);
share
=
get_cached_table_share
(
db
,
table_name
);
mysql_mutex_unlock
(
&
LOCK_open
);
if
(
share
)
DBUG_RETURN
(
TRUE
);
if
(
!
path
)
{
build_table_filename
(
path_buf
,
sizeof
(
path_buf
)
-
1
,
db
,
table_name
,
reg_ext
,
0
);
path
=
path_buf
;
}
if
(
!
access
(
path
,
F_OK
))
DBUG_RETURN
(
TRUE
);
/* .FRM file doesn't exist. Try to discover it */
uchar
*
frmblob
=
NULL
;
size_t
frmlen
;
bool
exists
=
!
ha_discover
(
thd
,
db
,
table_name
,
&
frmblob
,
&
frmlen
);
my_free
(
frmblob
);
DBUG_RETURN
(
exists
);
}
/**
An error handler which converts, if possible, ER_LOCK_DEADLOCK error
that can occur when we are trying to acquire a metadata lock to
...
...
@@ -2926,7 +2874,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
if
(
table_list
->
open_strategy
==
TABLE_LIST
::
OPEN_IF_EXISTS
)
{
if
(
!
table_exists
(
thd
,
table_list
))
if
(
!
ha_table_exists
(
thd
,
table_list
->
db
,
table_list
->
table_name
))
DBUG_RETURN
(
FALSE
);
/* Table exists. Let us try to open it. */
...
...
@@ -4705,7 +4653,7 @@ lock_table_names(THD *thd,
We come here in the case of lock timeout when executing CREATE TABLE.
Verify that table does exist (it usually does, as we got a lock conflict)
*/
if
(
table_exists
(
thd
,
tables_start
))
if
(
ha_table_exists
(
thd
,
tables_start
->
db
,
tables_start
->
table_name
))
{
if
(
thd
->
lex
->
create_info
.
options
&
HA_LEX_CREATE_IF_NOT_EXISTS
)
{
...
...
sql/sql_base.h
View file @
6a839ff4
...
...
@@ -113,7 +113,7 @@ TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name,
enum
open_frm_error
*
error
,
my_hash_value_type
hash_value
);
void
release_table_share
(
TABLE_SHARE
*
share
);
TABLE_SHARE
*
get_cached_table_share
(
const
char
*
db
,
const
char
*
table_name
);
// convenience helper: call get_table_share() without precomputed hash_value
static
inline
TABLE_SHARE
*
get_table_share
(
THD
*
thd
,
const
char
*
db
,
...
...
@@ -369,13 +369,6 @@ TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db,
bool
no_error
);
void
mark_tmp_table_for_reuse
(
TABLE
*
table
);
bool
table_exists
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
,
const
char
*
path
);
static
inline
bool
table_exists
(
THD
*
thd
,
TABLE_LIST
*
table
)
{
return
table_exists
(
thd
,
table
->
db
,
table
->
table_name
,
NULL
);
}
int
update_virtual_fields
(
THD
*
thd
,
TABLE
*
table
,
enum
enum_vcol_update_mode
vcol_update_mode
=
VCOL_UPDATE_FOR_READ
);
int
dynamic_column_error_message
(
enum_dyncol_func_result
rc
);
...
...
sql/sql_db.cc
View file @
6a839ff4
...
...
@@ -937,7 +937,7 @@ update_binlog:
char
quoted_name
[
FN_REFLEN
+
3
];
// Only write drop table to the binlog for tables that no longer exist.
if
(
table_exists
(
thd
,
tbl
))
if
(
ha_table_exists
(
thd
,
tbl
->
db
,
tbl
->
table_name
))
continue
;
my_snprintf
(
quoted_name
,
sizeof
(
quoted_name
),
"%`s"
,
tbl
->
table_name
);
...
...
sql/sql_table.cc
View file @
6a839ff4
...
...
@@ -2279,8 +2279,9 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
}
DEBUG_SYNC
(
thd
,
"rm_table_no_locks_before_delete_table"
);
error
=
0
;
if
(
drop_temporary
||
!
table_exists
(
thd
,
db
,
alias
,
path
)
||
(
!
drop_view
&&
dd_frm_type
(
thd
,
path
,
&
frm_db_type
)
!=
FRMTYPE_TABLE
))
if
(
!
table
->
internal_tmp_table
&&
(
drop_temporary
||
!
ha_table_exists
(
thd
,
db
,
alias
)
||
(
!
drop_view
&&
dd_frm_type
(
thd
,
path
,
&
frm_db_type
)
!=
FRMTYPE_TABLE
)))
{
/*
One of the following cases happened:
...
...
@@ -2288,6 +2289,10 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
. "DROP" but table was not found on disk and table can't be
created from engine.
. ./sql/datadict.cc +32 /Alfranio - TODO: We need to test this.
Table->internal_tmp_table is set when one of the #sql-xxx files
was left in the datadir after a crash during ALTER TABLE.
See Bug#30152.
*/
if
(
if_exists
)
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_NOTE
,
...
...
@@ -4317,7 +4322,7 @@ bool mysql_create_table_no_lock(THD *thd,
if
(
!
internal_tmp_table
&&
!
(
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
))
{
if
(
table_exists
(
thd
,
db
,
table_name
,
path
))
if
(
ha_table_exists
(
thd
,
db
,
table_name
))
{
if
(
create_info
->
options
&
HA_LEX_CREATE_IF_NOT_EXISTS
)
goto
warn
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment