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
06115abd
Commit
06115abd
authored
May 21, 2011
by
Guilhem Bichot
Browse files
Options
Browse Files
Download
Plain Diff
merge from latest 5.1
parents
12c42b98
733893ba
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
289 additions
and
164 deletions
+289
-164
libmysqld/lib_sql.cc
libmysqld/lib_sql.cc
+26
-2
mysql-test/r/func_time.result
mysql-test/r/func_time.result
+9
-0
mysql-test/suite/rpl/r/rpl_relayspace.result
mysql-test/suite/rpl/r/rpl_relayspace.result
+4
-6
mysql-test/suite/rpl/t/rpl_relayspace.test
mysql-test/suite/rpl/t/rpl_relayspace.test
+28
-14
mysql-test/t/func_time.test
mysql-test/t/func_time.test
+7
-0
sql/item_timefunc.cc
sql/item_timefunc.cc
+7
-2
sql/mysql_priv.h
sql/mysql_priv.h
+8
-0
sql/sql_class.cc
sql/sql_class.cc
+19
-0
sql/sql_class.h
sql/sql_class.h
+1
-0
sql/sql_show.cc
sql/sql_show.cc
+180
-140
No files found.
libmysqld/lib_sql.cc
View file @
06115abd
...
@@ -51,6 +51,23 @@ extern "C" void unireg_clear(int exit_code)
...
@@ -51,6 +51,23 @@ extern "C" void unireg_clear(int exit_code)
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
/*
Wrapper error handler for embedded server to call client/server error
handler based on whether thread is in client/server context
*/
static
int
embedded_error_handler
(
uint
error
,
const
char
*
str
,
myf
MyFlags
)
{
DBUG_ENTER
(
"embedded_error_handler"
);
/*
If current_thd is NULL, it means restore_global has been called and
thread is in client context, then call client error handler else call
server error handler.
*/
DBUG_RETURN
(
current_thd
?
my_message_sql
(
error
,
str
,
MyFlags
)
:
my_message_no_curses
(
error
,
str
,
MyFlags
));
}
/*
/*
Reads error information from the MYSQL_DATA and puts
Reads error information from the MYSQL_DATA and puts
...
@@ -107,7 +124,8 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
...
@@ -107,7 +124,8 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
if
(
mysql
->
status
!=
MYSQL_STATUS_READY
)
if
(
mysql
->
status
!=
MYSQL_STATUS_READY
)
{
{
set_mysql_error
(
mysql
,
CR_COMMANDS_OUT_OF_SYNC
,
unknown_sqlstate
);
set_mysql_error
(
mysql
,
CR_COMMANDS_OUT_OF_SYNC
,
unknown_sqlstate
);
return
1
;
result
=
1
;
goto
end
;
}
}
/* Clear result variables */
/* Clear result variables */
...
@@ -147,6 +165,9 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
...
@@ -147,6 +165,9 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
thd
->
profiling
.
finish_current_query
();
thd
->
profiling
.
finish_current_query
();
#endif
#endif
end:
thd
->
restore_globals
();
return
result
;
return
result
;
}
}
...
@@ -525,7 +546,10 @@ int init_embedded_server(int argc, char **argv, char **groups)
...
@@ -525,7 +546,10 @@ int init_embedded_server(int argc, char **argv, char **groups)
return
1
;
return
1
;
}
}
error_handler_hook
=
my_message_sql
;
/*
set error_handler_hook to embedded_error_handler wrapper.
*/
error_handler_hook
=
embedded_error_handler
;
acl_error
=
0
;
acl_error
=
0
;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
#ifndef NO_EMBEDDED_ACCESS_CHECKS
...
...
mysql-test/r/func_time.result
View file @
06115abd
...
@@ -1417,4 +1417,13 @@ NULL
...
@@ -1417,4 +1417,13 @@ NULL
SELECT DATE_FORMAT('0000-00-11', '%w');
SELECT DATE_FORMAT('0000-00-11', '%w');
DATE_FORMAT('0000-00-11', '%w')
DATE_FORMAT('0000-00-11', '%w')
NULL
NULL
#
# Bug#12403504 AFTER FIX FOR #11889186 : ASSERTION FAILED: DELSUM+(INT) Y/4-TEMP > 0
#
SELECT MAKEDATE(11111111,1);
MAKEDATE(11111111,1)
NULL
SELECT WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1);
WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1)
NULL
End of 5.1 tests
End of 5.1 tests
mysql-test/suite/rpl/r/rpl_relayspace.result
View file @
06115abd
include/master-slave.inc
include/master-slave.inc
[connection master]
[connection master]
stop slave;
include/stop_slave.inc
create table t1 (a int);
create table t1 (a int);
drop table t1;
drop table t1;
create table t1 (a int);
create table t1 (a int);
...
@@ -8,10 +8,8 @@ drop table t1;
...
@@ -8,10 +8,8 @@ drop table t1;
reset slave;
reset slave;
start slave io_thread;
start slave io_thread;
include/wait_for_slave_param.inc [Slave_IO_State]
include/wait_for_slave_param.inc [Slave_IO_State]
stop slave io_thread;
include/stop_slave_io.inc
reset slave;
reset slave;
start slave;
include/start_slave.inc
select master_pos_wait('master-bin.001',200,6)=-1;
include/assert.inc [Assert that master_pos_wait does not timeout nor it returns NULL]
master_pos_wait('master-bin.001',200,6)=-1
0
include/rpl_end.inc
include/rpl_end.inc
mysql-test/suite/rpl/t/rpl_relayspace.test
View file @
06115abd
...
@@ -2,8 +2,9 @@
...
@@ -2,8 +2,9 @@
# to force the deadlock after one event.
# to force the deadlock after one event.
source
include
/
master
-
slave
.
inc
;
source
include
/
master
-
slave
.
inc
;
--
let
$master_log_file
=
query_get_value
(
SHOW
MASTER
STATUS
,
File
,
1
)
connection
slave
;
connection
slave
;
stop
slave
;
--
source
include
/
stop_slave
.
inc
connection
master
;
connection
master
;
# This will generate a master's binlog > 10 bytes
# This will generate a master's binlog > 10 bytes
create
table
t1
(
a
int
);
create
table
t1
(
a
int
);
...
@@ -19,20 +20,33 @@ let $slave_param_value= Waiting for the slave SQL thread to free enough relay lo
...
@@ -19,20 +20,33 @@ let $slave_param_value= Waiting for the slave SQL thread to free enough relay lo
source
include
/
wait_for_slave_param
.
inc
;
source
include
/
wait_for_slave_param
.
inc
;
# A bug caused the I/O thread to refuse stopping.
# A bug caused the I/O thread to refuse stopping.
stop
slave
io_thread
;
--
source
include
/
stop_slave_io
.
inc
reset
slave
;
reset
slave
;
start
slave
;
--
source
include
/
start_slave
.
inc
# The I/O thread stops filling the relay log when
# it's >10b. And the SQL thread cannot purge this relay log
# The I/O thread stops filling the relay log when it's >10b. And the
# as purge is done only when the SQL thread switches to another
# SQL thread cannot purge this relay log as purge is done only when
# relay log, which does not exist here.
# the SQL thread switches to another relay log, which does not exist
# So we should have a deadlock.
# here. So we should have a deadlock. If it is not resolved
# if it is not resolved automatically we'll detect
# automatically we'll detect it with master_pos_wait that waits for
# it with master_pos_wait that waits for farther than 1Ob;
# farther than 1Ob; it will timeout after 300 seconds (which is inline
# it will timeout after 10 seconds;
# with the default used for sync_slave_with_master and will protect us
# also the slave will probably not cooperate to shutdown
# against slow test envs); also the slave will probably not cooperate
# (as 2 threads are locked)
# to shutdown (as 2 threads are locked)
select
master_pos_wait
(
'master-bin.001'
,
200
,
6
)
=-
1
;
--
let
$outcome
=
`SELECT MASTER_POS_WAIT('$master_log_file',200,300) AS mpw;`
# master_pos_wait returns:
#
# * >= 0, the number of events the slave had to wait to advance to the
# position
#
# * -1, if there was a timeout
#
# * NULL, if an error occurred, or the SQL thread was not started,
# slave master info is not initialized, the arguments are incorrect
--
let
$assert_text
=
Assert
that
master_pos_wait
does
not
timeout
nor
it
returns
NULL
--
let
$assert_cond
=
$outcome
IS
NOT
NULL
AND
$outcome
<>
-
1
--
source
include
/
assert
.
inc
# End of 4.1 tests
# End of 4.1 tests
--
source
include
/
rpl_end
.
inc
--
source
include
/
rpl_end
.
inc
mysql-test/t/func_time.test
View file @
06115abd
...
@@ -921,4 +921,11 @@ SELECT DATE_FORMAT('0000-00-11', '%W');
...
@@ -921,4 +921,11 @@ SELECT DATE_FORMAT('0000-00-11', '%W');
SELECT
DATE_FORMAT
(
'0000-00-11'
,
'%a'
);
SELECT
DATE_FORMAT
(
'0000-00-11'
,
'%a'
);
SELECT
DATE_FORMAT
(
'0000-00-11'
,
'%w'
);
SELECT
DATE_FORMAT
(
'0000-00-11'
,
'%w'
);
--
echo
#
--
echo
# Bug#12403504 AFTER FIX FOR #11889186 : ASSERTION FAILED: DELSUM+(INT) Y/4-TEMP > 0
--
echo
#
SELECT
MAKEDATE
(
11111111
,
1
);
SELECT
WEEK
(
DATE_ADD
(
FROM_DAYS
(
1
),
INTERVAL
1
MONTH
),
1
);
--
echo
End
of
5.1
tests
--
echo
End
of
5.1
tests
sql/item_timefunc.cc
View file @
06115abd
...
@@ -1519,6 +1519,11 @@ bool Item_func_from_days::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
...
@@ -1519,6 +1519,11 @@ bool Item_func_from_days::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
return
1
;
return
1
;
bzero
(
ltime
,
sizeof
(
MYSQL_TIME
));
bzero
(
ltime
,
sizeof
(
MYSQL_TIME
));
get_date_from_daynr
((
long
)
value
,
&
ltime
->
year
,
&
ltime
->
month
,
&
ltime
->
day
);
get_date_from_daynr
((
long
)
value
,
&
ltime
->
year
,
&
ltime
->
month
,
&
ltime
->
day
);
if
((
null_value
=
(
fuzzy_date
&
TIME_NO_ZERO_DATE
)
&&
(
ltime
->
year
==
0
||
ltime
->
month
==
0
||
ltime
->
day
==
0
)))
return
TRUE
;
ltime
->
time_type
=
MYSQL_TIMESTAMP_DATE
;
ltime
->
time_type
=
MYSQL_TIMESTAMP_DATE
;
return
0
;
return
0
;
}
}
...
@@ -2697,7 +2702,7 @@ String *Item_func_makedate::val_str(String *str)
...
@@ -2697,7 +2702,7 @@ String *Item_func_makedate::val_str(String *str)
long
days
;
long
days
;
if
(
args
[
0
]
->
null_value
||
args
[
1
]
->
null_value
||
if
(
args
[
0
]
->
null_value
||
args
[
1
]
->
null_value
||
year
<
0
||
daynr
<=
0
)
year
<
0
||
year
>
9999
||
daynr
<=
0
)
goto
err
;
goto
err
;
if
(
year
<
100
)
if
(
year
<
100
)
...
@@ -2740,7 +2745,7 @@ longlong Item_func_makedate::val_int()
...
@@ -2740,7 +2745,7 @@ longlong Item_func_makedate::val_int()
long
days
;
long
days
;
if
(
args
[
0
]
->
null_value
||
args
[
1
]
->
null_value
||
if
(
args
[
0
]
->
null_value
||
args
[
1
]
->
null_value
||
year
<
0
||
daynr
<=
0
)
year
<
0
||
year
>
9999
||
daynr
<=
0
)
goto
err
;
goto
err
;
if
(
year
<
100
)
if
(
year
<
100
)
...
...
sql/mysql_priv.h
View file @
06115abd
...
@@ -670,6 +670,10 @@ enum enum_check_fields
...
@@ -670,6 +670,10 @@ enum enum_check_fields
extern
"C"
THD
*
_current_thd_noinline
();
extern
"C"
THD
*
_current_thd_noinline
();
#define _current_thd() _current_thd_noinline()
#define _current_thd() _current_thd_noinline()
#else
#else
/*
THR_THD is a key which will be used to set/get THD* for a thread,
using my_pthread_setspecific_ptr()/my_thread_getspecific_ptr().
*/
extern
pthread_key
(
THD
*
,
THR_THD
);
extern
pthread_key
(
THD
*
,
THR_THD
);
inline
THD
*
_current_thd
(
void
)
inline
THD
*
_current_thd
(
void
)
{
{
...
@@ -2022,6 +2026,10 @@ extern TABLE_LIST general_log, slow_log;
...
@@ -2022,6 +2026,10 @@ extern TABLE_LIST general_log, slow_log;
extern
FILE
*
bootstrap_file
;
extern
FILE
*
bootstrap_file
;
extern
int
bootstrap_error
;
extern
int
bootstrap_error
;
extern
FILE
*
stderror_file
;
extern
FILE
*
stderror_file
;
/*
THR_MALLOC is a key which will be used to set/get MEM_ROOT** for a thread,
using my_pthread_setspecific_ptr()/my_thread_getspecific_ptr().
*/
extern
pthread_key
(
MEM_ROOT
**
,
THR_MALLOC
);
extern
pthread_key
(
MEM_ROOT
**
,
THR_MALLOC
);
extern
pthread_mutex_t
LOCK_mysql_create_db
,
LOCK_Acl
,
LOCK_open
,
LOCK_lock_db
,
extern
pthread_mutex_t
LOCK_mysql_create_db
,
LOCK_Acl
,
LOCK_open
,
LOCK_lock_db
,
LOCK_mapped_file
,
LOCK_user_locks
,
LOCK_status
,
LOCK_mapped_file
,
LOCK_user_locks
,
LOCK_status
,
...
...
sql/sql_class.cc
View file @
06115abd
...
@@ -1195,6 +1195,25 @@ bool THD::store_globals()
...
@@ -1195,6 +1195,25 @@ bool THD::store_globals()
return
0
;
return
0
;
}
}
/*
Remove the thread specific info (THD and mem_root pointer) stored during
store_global call for this thread.
*/
bool
THD
::
restore_globals
()
{
/*
Assert that thread_stack is initialized: it's necessary to be able
to track stack overrun.
*/
DBUG_ASSERT
(
thread_stack
);
/* Undocking the thread specific data. */
my_pthread_setspecific_ptr
(
THR_THD
,
NULL
);
my_pthread_setspecific_ptr
(
THR_MALLOC
,
NULL
);
return
0
;
}
/*
/*
Cleanup after query.
Cleanup after query.
...
...
sql/sql_class.h
View file @
06115abd
...
@@ -1943,6 +1943,7 @@ public:
...
@@ -1943,6 +1943,7 @@ public:
void
cleanup
(
void
);
void
cleanup
(
void
);
void
cleanup_after_query
();
void
cleanup_after_query
();
bool
store_globals
();
bool
store_globals
();
bool
restore_globals
();
#ifdef SIGNAL_WITH_VIO_CLOSE
#ifdef SIGNAL_WITH_VIO_CLOSE
inline
void
set_active_vio
(
Vio
*
vio
)
inline
void
set_active_vio
(
Vio
*
vio
)
{
{
...
...
sql/sql_show.cc
View file @
06115abd
...
@@ -2428,12 +2428,11 @@ bool schema_table_store_record(THD *thd, TABLE *table)
...
@@ -2428,12 +2428,11 @@ bool schema_table_store_record(THD *thd, TABLE *table)
}
}
int
make_table_list
(
THD
*
thd
,
SELECT_LEX
*
sel
,
static
int
make_table_list
(
THD
*
thd
,
SELECT_LEX
*
sel
,
LEX_STRING
*
db_name
,
LEX_STRING
*
table_name
)
LEX_STRING
*
db_name
,
LEX_STRING
*
table_name
)
{
{
Table_ident
*
table_ident
;
Table_ident
*
table_ident
;
table_ident
=
new
Table_ident
(
thd
,
*
db_name
,
*
table_name
,
1
);
table_ident
=
new
Table_ident
(
thd
,
*
db_name
,
*
table_name
,
1
);
sel
->
init_query
();
if
(
!
sel
->
add_table_to_list
(
thd
,
table_ident
,
0
,
0
,
TL_READ
))
if
(
!
sel
->
add_table_to_list
(
thd
,
table_ident
,
0
,
0
,
TL_READ
))
return
1
;
return
1
;
return
0
;
return
0
;
...
@@ -3003,79 +3002,179 @@ make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
...
@@ -3003,79 +3002,179 @@ make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
/**
/**
@brief Fill I_S table for SHOW COLUMNS|INDEX commands
Fill I_S table with data obtained by performing full-blown table open.
@param[in] thd thread handler
@param thd Thread handler.
@param[in] tables TABLE_LIST for I_S table
@param is_show_fields_or_keys Indicates whether it is a legacy SHOW
@param[in] schema_table pointer to I_S structure
COLUMNS or SHOW KEYS statement.
@param[in] open_tables_state_backup pointer to Open_tables_state object
@param table TABLE object for I_S table to be filled.
which is used to save|restore original
@param schema_table I_S table description structure.
status of variables related to
@param orig_db_name Database name.
open tables state
@param orig_table_name Table name.
@param open_tables_state_backup Open_tables_state object which is used
@return Operation status
to save/restore original status of
@retval 0 success
variables related to open tables state.
@retval 1 error
@retval FALSE - Success.
@retval TRUE - Failure.
*/
*/
static
int
static
bool
fill_schema_show_cols_or_idxs
(
THD
*
thd
,
TABLE_LIST
*
tables
,
fill_schema_table_by_open
(
THD
*
thd
,
bool
is_show_fields_or_keys
,
ST_SCHEMA_TABLE
*
schema_table
,
TABLE
*
table
,
ST_SCHEMA_TABLE
*
schema_table
,
LEX_STRING
*
orig_db_name
,
LEX_STRING
*
orig_table_name
,
Open_tables_state
*
open_tables_state_backup
)
Open_tables_state
*
open_tables_state_backup
)
{
{
LEX
*
lex
=
thd
->
lex
;
Query_arena
i_s_arena
(
thd
->
mem_root
,
bool
res
;
Query_arena
::
CONVENTIONAL_EXECUTION
),
LEX_STRING
tmp_lex_string
,
tmp_lex_string1
,
*
db_name
,
*
table_name
;
backup_arena
,
*
old_arena
;
enum_sql_command
save_sql_command
=
lex
->
sql_command
;
LEX
*
old_lex
=
thd
->
lex
,
temp_lex
,
*
lex
;
TABLE_LIST
*
show_table_list
=
tables
->
schema_select_lex
->
table_list
.
first
;
LEX_STRING
db_name
,
table_name
;
TABLE
*
table
=
tables
->
table
;
TABLE_LIST
*
table_list
;
int
error
=
1
;
bool
result
=
true
;
DBUG_ENTER
(
"fill_schema_show"
);
/*
When a view is opened its structures are allocated on a permanent
statement arena and linked into the LEX tree for the current statement
(this happens even in cases when view is handled through TEMPTABLE
algorithm).
To prevent this process from unnecessary hogging of memory in the permanent
arena of our I_S query and to avoid damaging its LEX we use temporary
arena and LEX for table/view opening.
Use temporary arena instead of statement permanent arena. Also make
it active arena and save original one for successive restoring.
*/
old_arena
=
thd
->
stmt_arena
;
thd
->
stmt_arena
=
&
i_s_arena
;
thd
->
set_n_backup_active_arena
(
&
i_s_arena
,
&
backup_arena
);
/* Prepare temporary LEX. */
thd
->
lex
=
lex
=
&
temp_lex
;
lex_start
(
thd
);
/* Disable constant subquery evaluation as we won't be locking tables. */
lex
->
context_analysis_only
=
CONTEXT_ANALYSIS_ONLY_VIEW
;
/*
Some of process_table() functions rely on wildcard being passed from
old LEX (or at least being initialized).
*/
lex
->
wild
=
old_lex
->
wild
;
/*
Since make_table_list() might change database and table name passed
to it we create copies of orig_db_name and orig_table_name here.
These copies are used for make_table_list() while unaltered values
are passed to process_table() functions.
*/
if
(
!
thd
->
make_lex_string
(
&
db_name
,
orig_db_name
->
str
,
orig_db_name
->
length
,
FALSE
)
||
!
thd
->
make_lex_string
(
&
table_name
,
orig_table_name
->
str
,
orig_table_name
->
length
,
FALSE
))
goto
end
;
lex
->
all_selects_list
=
tables
->
schema_select_lex
;
/*
Create table list element for table to be open. Link it with the
temporary LEX. The latter is required to correctly open views and
produce table describing their structure.
*/
if
(
make_table_list
(
thd
,
&
lex
->
select_lex
,
&
db_name
,
&
table_name
))
goto
end
;
table_list
=
lex
->
select_lex
.
table_list
.
first
;
if
(
is_show_fields_or_keys
)
{
/*
/*
Restore thd->temporary_tables to be able to process
Restore thd->temporary_tables to be able to process
temporary tables
(only for 'show index' & 'show columns').
temporary tables
(only for 'show index' & 'show columns').
This should be changed when processing of temporary tables for
This should be changed when processing of temporary tables for
I_S tables will be done.
I_S tables will be done.
*/
*/
thd
->
temporary_tables
=
open_tables_state_backup
->
temporary_tables
;
thd
->
temporary_tables
=
open_tables_state_backup
->
temporary_tables
;
}
else
{
/*
Apply optimization flags for table opening which are relevant for
this I_S table. We can't do this for SHOW COLUMNS/KEYS because of
backward compatibility.
*/
table_list
->
i_s_requested_object
=
schema_table
->
i_s_requested_object
;
}
/*
/*
Let us set fake sql_command so views won't try to merge
Let us set fake sql_command so views won't try to merge
themselves into main statement. If we don't do this,
themselves into main statement. If we don't do this,
SELECT * from information_schema.xxxx will cause problems.
SELECT * from information_schema.xxxx will cause problems.
SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
SQLCOM_SHOW_FIELDS is used because it satisfies
'only_view_structure()'.
*/
*/
lex
->
sql_command
=
SQLCOM_SHOW_FIELDS
;
lex
->
sql_command
=
SQLCOM_SHOW_FIELDS
;
res
=
open_normal_and_derived_tables
(
thd
,
show_table_list
,
result
=
open_normal_and_derived_tables
(
thd
,
table_list
,
MYSQL_LOCK_IGNORE_FLUSH
);
MYSQL_LOCK_IGNORE_FLUSH
);
lex
->
sql_command
=
save_sql_command
;
/*
Restore old value of sql_command back as it is being looked at in
process_table() function.
*/
lex
->
sql_command
=
old_lex
->
sql_command
;
/*
XXX: show_table_list has a flag i_is_requested,
and when it's set, open_normal_and_derived_tables()
can return an error without setting an error message
in THD, which is a hack. This is why we have to
check for res, then for thd->is_error() and only then
for thd->main_da.sql_errno().
Again we don't do this for SHOW COLUMNS/KEYS because
of backward compatibility.
*/
if
(
!
is_show_fields_or_keys
&&
result
&&
thd
->
is_error
()
&&
thd
->
main_da
.
sql_errno
()
==
ER_NO_SUCH_TABLE
)
{
/*
/*
get_all_tables() returns 1 on failure and 0 on success thus
Hide error for a non-existing table.
return only these and not the result code of ::process_table()
For example, this error can occur when we use a where condition
with a db name and table, but the table does not exist.
We should use show_table_list->alias instead of
show_table_list->table_name because table_name
could be changed during opening of I_S tables. It's safe
to use alias because alias contains original table name
in this case(this part of code is used only for
'show columns' & 'show statistics' commands).
*/
*/
table_name
=
thd
->
make_lex_string
(
&
tmp_lex_string1
,
show_table_list
->
alias
,
result
=
0
;
strlen
(
show_table_list
->
alias
),
FALSE
);
thd
->
clear_error
();
if
(
!
show_table_list
->
view
)
}
db_name
=
thd
->
make_lex_string
(
&
tmp_lex_string
,
show_table_list
->
db
,
show_table_list
->
db_length
,
FALSE
);
else
else
db_name
=
&
show_table_list
->
view_db
;
{
result
=
schema_table
->
process_table
(
thd
,
table_list
,
table
,
result
,
orig_db_name
,
orig_table_name
);
}
end:
lex
->
unit
.
cleanup
();
error
=
test
(
schema_table
->
process_table
(
thd
,
show_table_list
,
/* Restore original LEX value, statement's arena and THD arena values. */
table
,
res
,
db_name
,
lex_end
(
thd
->
lex
);
table_name
));
thd
->
temporary_tables
=
0
;
if
(
i_s_arena
.
free_list
)
close_tables_for_reopen
(
thd
,
&
show_table_list
);
i_s_arena
.
free_items
();
DBUG_RETURN
(
error
);
/*
For safety reset list of open temporary tables before closing
all tables open within this Open_tables_state.
*/
thd
->
temporary_tables
=
NULL
;
close_thread_tables
(
thd
);
thd
->
lex
=
old_lex
;
thd
->
stmt_arena
=
old_arena
;
thd
->
restore_active_arena
(
&
i_s_arena
,
&
backup_arena
);
return
result
;
}
}
...
@@ -3300,11 +3399,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
...
@@ -3300,11 +3399,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
{
{
LEX
*
lex
=
thd
->
lex
;
LEX
*
lex
=
thd
->
lex
;
TABLE
*
table
=
tables
->
table
;
TABLE
*
table
=
tables
->
table
;
SELECT_LEX
*
old_all_select_lex
=
lex
->
all_selects_list
;
enum_sql_command
save_sql_command
=
lex
->
sql_command
;
SELECT_LEX
*
lsel
=
tables
->
schema_select_lex
;
SELECT_LEX
*
lsel
=
tables
->
schema_select_lex
;
ST_SCHEMA_TABLE
*
schema_table
=
tables
->
schema_table
;
ST_SCHEMA_TABLE
*
schema_table
=
tables
->
schema_table
;
SELECT_LEX
sel
;
LOOKUP_FIELD_VALUES
lookup_field_vals
;
LOOKUP_FIELD_VALUES
lookup_field_vals
;
LEX_STRING
*
db_name
,
*
table_name
;
LEX_STRING
*
db_name
,
*
table_name
;
bool
with_i_schema
;
bool
with_i_schema
;
...
@@ -3312,20 +3408,14 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
...
@@ -3312,20 +3408,14 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
List
<
LEX_STRING
>
db_names
;
List
<
LEX_STRING
>
db_names
;
List_iterator_fast
<
LEX_STRING
>
it
(
db_names
);
List_iterator_fast
<
LEX_STRING
>
it
(
db_names
);
COND
*
partial_cond
=
0
;
COND
*
partial_cond
=
0
;
uint
derived_tables
=
lex
->
derived_tables
;
int
error
=
1
;
int
error
=
1
;
Open_tables_state
open_tables_state_backup
;
Open_tables_state
open_tables_state_backup
;
uint8
save_context_analysis_only
=
lex
->
context_analysis_only
;
Query_tables_list
query_tables_list_backup
;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
#ifndef NO_EMBEDDED_ACCESS_CHECKS
Security_context
*
sctx
=
thd
->
security_ctx
;
Security_context
*
sctx
=
thd
->
security_ctx
;
#endif
#endif
uint
table_open_method
;
uint
table_open_method
;
DBUG_ENTER
(
"get_all_tables"
);
DBUG_ENTER
(
"get_all_tables"
);
lex
->
context_analysis_only
|=
CONTEXT_ANALYSIS_ONLY_VIEW
;
lex
->
reset_n_backup_query_tables_list
(
&
query_tables_list_backup
);
/*
/*
We should not introduce deadlocks even if we already have some
We should not introduce deadlocks even if we already have some
tables open and locked, since we won't lock tables which we will
tables open and locked, since we won't lock tables which we will
...
@@ -3340,7 +3430,17 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
...
@@ -3340,7 +3430,17 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
*/
*/
if
(
lsel
&&
lsel
->
table_list
.
first
)
if
(
lsel
&&
lsel
->
table_list
.
first
)
{
{
error
=
fill_schema_show_cols_or_idxs
(
thd
,
tables
,
schema_table
,
LEX_STRING
db_name
,
table_name
;
db_name
.
str
=
lsel
->
table_list
.
first
->
db
;
db_name
.
length
=
lsel
->
table_list
.
first
->
db_length
;
table_name
.
str
=
lsel
->
table_list
.
first
->
table_name
;
table_name
.
length
=
lsel
->
table_list
.
first
->
table_name_length
;
error
=
fill_schema_table_by_open
(
thd
,
TRUE
,
table
,
schema_table
,
&
db_name
,
&
table_name
,
&
open_tables_state_backup
);
&
open_tables_state_backup
);
goto
err
;
goto
err
;
}
}
...
@@ -3399,12 +3499,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
...
@@ -3399,12 +3499,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
it
.
rewind
();
/* To get access to new elements in basis list */
it
.
rewind
();
/* To get access to new elements in basis list */
while
((
db_name
=
it
++
))
while
((
db_name
=
it
++
))
{
{
LEX_STRING
orig_db_name
;
/* db_name can be changed in make_table_list() func */
if
(
!
thd
->
make_lex_string
(
&
orig_db_name
,
db_name
->
str
,
db_name
->
length
,
FALSE
))
goto
err
;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if
(
!
(
check_access
(
thd
,
SELECT_ACL
,
db_name
->
str
,
if
(
!
(
check_access
(
thd
,
SELECT_ACL
,
db_name
->
str
,
&
thd
->
col_access
,
0
,
1
,
with_i_schema
)
||
&
thd
->
col_access
,
0
,
1
,
with_i_schema
)
||
...
@@ -3466,64 +3560,14 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
...
@@ -3466,64 +3560,14 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
continue
;
continue
;
}
}
int
res
;
LEX_STRING
tmp_lex_string
;
/*
Set the parent lex of 'sel' because it is needed by
sel.init_query() which is called inside make_table_list.
*/
thd
->
no_warnings_for_error
=
1
;
thd
->
no_warnings_for_error
=
1
;
sel
.
parent_lex
=
lex
;
if
(
make_table_list
(
thd
,
&
sel
,
db_name
,
table_name
))
goto
err
;
TABLE_LIST
*
show_table_list
=
sel
.
table_list
.
first
;
lex
->
all_selects_list
=
&
sel
;
lex
->
derived_tables
=
0
;
lex
->
sql_command
=
SQLCOM_SHOW_FIELDS
;
show_table_list
->
i_s_requested_object
=
schema_table
->
i_s_requested_object
;
DEBUG_SYNC
(
thd
,
"before_open_in_get_all_tables"
);
DEBUG_SYNC
(
thd
,
"before_open_in_get_all_tables"
);
res
=
open_normal_and_derived_tables
(
thd
,
show_table_list
,
MYSQL_LOCK_IGNORE_FLUSH
);
if
(
fill_schema_table_by_open
(
thd
,
FALSE
,
lex
->
sql_command
=
save_sql_command
;
table
,
schema_table
,
/*
db_name
,
table_name
,
XXX: show_table_list has a flag i_is_requested,
&
open_tables_state_backup
))
and when it's set, open_normal_and_derived_tables()
can return an error without setting an error message
in THD, which is a hack. This is why we have to
check for res, then for thd->is_error() only then
for thd->main_da.sql_errno().
*/
if
(
res
&&
thd
->
is_error
()
&&
thd
->
main_da
.
sql_errno
()
==
ER_NO_SUCH_TABLE
)
{
/*
Hide error for not existing table.
This error can occur for example when we use
where condition with db name and table name and this
table does not exist.
*/
res
=
0
;
thd
->
clear_error
();
}
else
{
/*
We should use show_table_list->alias instead of
show_table_list->table_name because table_name
could be changed during opening of I_S tables. It's safe
to use alias because alias contains original table name
in this case.
*/
thd
->
make_lex_string
(
&
tmp_lex_string
,
show_table_list
->
alias
,
strlen
(
show_table_list
->
alias
),
FALSE
);
res
=
schema_table
->
process_table
(
thd
,
show_table_list
,
table
,
res
,
&
orig_db_name
,
&
tmp_lex_string
);
close_tables_for_reopen
(
thd
,
&
show_table_list
);
}
DBUG_ASSERT
(
!
lex
->
query_tables_own_last
);
if
(
res
)
goto
err
;
goto
err
;
}
}
}
}
...
@@ -3539,11 +3583,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
...
@@ -3539,11 +3583,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
error
=
0
;
error
=
0
;
err:
err:
thd
->
restore_backup_open_tables_state
(
&
open_tables_state_backup
);
thd
->
restore_backup_open_tables_state
(
&
open_tables_state_backup
);
lex
->
restore_backup_query_tables_list
(
&
query_tables_list_backup
);
lex
->
derived_tables
=
derived_tables
;
lex
->
all_selects_list
=
old_all_select_lex
;
lex
->
context_analysis_only
=
save_context_analysis_only
;
lex
->
sql_command
=
save_sql_command
;
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
}
}
...
...
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