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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
2b3ae933
Commit
2b3ae933
authored
May 23, 2007
by
dlenev@mockturtle.local
Browse files
Options
Browse Files
Download
Plain Diff
Merge bk-internal.mysql.com:/home/bk/mysql-5.1-runtime
into mockturtle.local:/home/dlenev/src/mysql-5.1-like-2
parents
0eaa6152
8e8f4c05
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
364 additions
and
141 deletions
+364
-141
mysql-test/r/create-big.result
mysql-test/r/create-big.result
+83
-0
mysql-test/r/create.result
mysql-test/r/create.result
+1
-1
mysql-test/r/grant2.result
mysql-test/r/grant2.result
+23
-0
mysql-test/t/create-big.test
mysql-test/t/create-big.test
+128
-4
mysql-test/t/create.test
mysql-test/t/create.test
+1
-1
mysql-test/t/disabled.def
mysql-test/t/disabled.def
+0
-1
mysql-test/t/grant2.test
mysql-test/t/grant2.test
+41
-0
sql/handler.h
sql/handler.h
+1
-0
sql/mysql_priv.h
sql/mysql_priv.h
+2
-3
sql/sql_lex.h
sql/sql_lex.h
+0
-1
sql/sql_parse.cc
sql/sql_parse.cc
+29
-9
sql/sql_partition.cc
sql/sql_partition.cc
+6
-11
sql/sql_table.cc
sql/sql_table.cc
+45
-92
sql/sql_yacc.yy
sql/sql_yacc.yy
+4
-18
No files found.
mysql-test/r/create
_select
-big.result
→
mysql-test/r/create-big.result
View file @
2b3ae933
...
...
@@ -162,3 +162,86 @@ t1 CREATE TABLE `t1` (
`j` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1, t2, t3;
drop table if exists t1,t2;
create table t1 (i int);
set session debug="+d,sleep_create_like_before_check_if_exists";
reset master;
create table t2 like t1;;
insert into t1 values (1);
drop table t1;
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`i` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t2;
show binlog events in 'master-bin.000001' from 106;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `test`; insert into t1 values (1)
master-bin.000001 # Query 1 # use `test`; create table t2 like t1
master-bin.000001 # Query 1 # use `test`; drop table t1
master-bin.000001 # Query 1 # use `test`; drop table t2
create table t1 (i int);
set session debug="-d,sleep_create_like_before_check_if_exists:+d,sleep_create_like_before_copy";
create table t2 like t1;;
create table if not exists t2 (j int);
Warnings:
Note 1050 Table 't2' already exists
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`i` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t2;
reset master;
create table t2 like t1;;
drop table t1;
drop table t2;
show binlog events in 'master-bin.000001' from 106;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `test`; create table t2 like t1
master-bin.000001 # Query 1 # use `test`; drop table t1
master-bin.000001 # Query 1 # use `test`; drop table t2
create table t1 (i int);
set session debug="-d,sleep_create_like_before_copy:+d,sleep_create_like_before_ha_create";
reset master;
create table t2 like t1;;
insert into t2 values (1);
drop table t2;
create table t2 like t1;;
drop table t2;
create table t2 like t1;;
drop table t1;
drop table t2;
show binlog events in 'master-bin.000001' from 106;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `test`; create table t2 like t1
master-bin.000001 # Query 1 # use `test`; insert into t2 values (1)
master-bin.000001 # Query 1 # use `test`; drop table t2
master-bin.000001 # Query 1 # use `test`; create table t2 like t1
master-bin.000001 # Query 1 # use `test`; drop table t2
master-bin.000001 # Query 1 # use `test`; create table t2 like t1
master-bin.000001 # Query 1 # use `test`; drop table t1
master-bin.000001 # Query 1 # use `test`; drop table t2
create table t1 (i int);
set session debug="-d,sleep_create_like_before_ha_create:+d,sleep_create_like_before_binlogging";
reset master;
create table t2 like t1;;
insert into t2 values (1);
drop table t2;
create table t2 like t1;;
drop table t2;
create table t2 like t1;;
drop table t1;
drop table t2;
show binlog events in 'master-bin.000001' from 106;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `test`; create table t2 like t1
master-bin.000001 # Query 1 # use `test`; insert into t2 values (1)
master-bin.000001 # Query 1 # use `test`; drop table t2
master-bin.000001 # Query 1 # use `test`; create table t2 like t1
master-bin.000001 # Query 1 # use `test`; drop table t2
master-bin.000001 # Query 1 # use `test`; create table t2 like t1
master-bin.000001 # Query 1 # use `test`; drop table t1
master-bin.000001 # Query 1 # use `test`; drop table t2
set session debug="-d,sleep_create_like_before_binlogging";
mysql-test/r/create.result
View file @
2b3ae933
...
...
@@ -371,7 +371,7 @@ ERROR 42S01: Table 't3' already exists
create table non_existing_database.t1 like t1;
ERROR 42000: Unknown database 'non_existing_database'
create table t3 like non_existing_table;
ERROR 42S02:
Unknown table 'non_existing_table'
ERROR 42S02:
Table 'test.non_existing_table' doesn't exist
create temporary table t3 like t1;
ERROR 42S01: Table 't3' already exists
drop table t1, t2, t3;
...
...
mysql-test/r/grant2.result
View file @
2b3ae933
...
...
@@ -381,3 +381,26 @@ drop table t2;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM `a@`@localhost;
drop user `a@`@localhost;
SET GLOBAL log_bin_trust_function_creators = 0;
drop database if exists mysqltest_1;
drop database if exists mysqltest_2;
drop user mysqltest_u1@localhost;
create database mysqltest_1;
create database mysqltest_2;
grant all on mysqltest_1.* to mysqltest_u1@localhost;
use mysqltest_2;
create table t1 (i int);
show create table mysqltest_2.t1;
ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1'
create table t1 like mysqltest_2.t1;
ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1'
grant select on mysqltest_2.t1 to mysqltest_u1@localhost;
show create table mysqltest_2.t1;
Table Create Table
t1 CREATE TABLE `t1` (
`i` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
create table t1 like mysqltest_2.t1;
use test;
drop database mysqltest_1;
drop database mysqltest_2;
drop user mysqltest_u1@localhost;
mysql-test/t/create
_select
-big.test
→
mysql-test/t/create-big.test
View file @
2b3ae933
# Tests for various aspects of CREATE TABLE ... SELECT implementation
# Tests for various concurrency-related aspects of CREATE TABLE ... SELECT
# and CREATE TABLE like implementation.
#
# Note that we don't test general CREATE TABLE ... SELECT functionality here as
# it is already covered by create.test. We are more interested in extreme cases.
# Note that we don't test general CREATE TABLE ... SELECT/LIKE functionality
# here as it is already covered by create.test. We are more interested in
# extreme cases.
#
# This test takes rather long time so let us run it only in --big-test mode
--
source
include
/
big_test
.
inc
# We are using some debug-only features in this test
--
source
include
/
have_debug
.
inc
# Some of tests below also use binlog to check that statements are
# executed and logged in correct order
--
source
include
/
have_binlog_format_mixed_or_statement
.
inc
# Create auxilliary connections
connect
(
addconroot1
,
localhost
,
root
,,);
...
...
@@ -20,7 +25,7 @@ drop table if exists t1,t2,t3,t4,t5;
#
# Tests for concurrency problems
.
# Tests for concurrency problems
in CREATE TABLE ... SELECT
#
# We introduce delays between various stages of table creation
# and check that other statements dealing with this table cannot
...
...
@@ -266,3 +271,122 @@ connection default;
select
*
from
t1
;
show
create
table
t1
;
drop
table
t1
,
t2
,
t3
;
# Tests for possible concurrency issues with CREATE TABLE ... LIKE
#
# Bug #18950 "create table like does not obtain LOCK_open"
# Bug #23667 "CREATE TABLE LIKE is not isolated from alteration by other
# connections"
#
# Again the idea of this test is that we introduce artificial delays on
# various stages of table creation and check that concurrent statements
# for tables from CREATE TABLE ... LIKE are not interfering.
--
disable_warnings
drop
table
if
exists
t1
,
t2
;
--
enable_warnings
# What happens if some statements sneak in right after we have
# opened source table ?
create
table
t1
(
i
int
);
set
session
debug
=
"+d,sleep_create_like_before_check_if_exists"
;
# Reset binlog to have clear start
reset
master
;
--
send
create
table
t2
like
t1
;
connection
addconroot1
;
--
sleep
2
# DML on source table should be allowed to run concurrently
insert
into
t1
values
(
1
);
# And DDL should wait
drop
table
t1
;
connection
default
;
--
reap
show
create
table
t2
;
drop
table
t2
;
# Let us check that statements were executed/binlogged in correct order
--
replace_column
2
# 5 #
show
binlog
events
in
'master-bin.000001'
from
106
;
# Now let us check the gap between check for target table
# existance and copying of .frm file.
create
table
t1
(
i
int
);
set
session
debug
=
"-d,sleep_create_like_before_check_if_exists:+d,sleep_create_like_before_copy"
;
# It should be impossible to create target table concurrently
--
send
create
table
t2
like
t1
;
connection
addconroot1
;
--
sleep
2
create
table
if
not
exists
t2
(
j
int
);
connection
default
;
--
reap
show
create
table
t2
;
drop
table
t2
;
# And concurrent DDL on the source table should be still disallowed
reset
master
;
--
send
create
table
t2
like
t1
;
connection
addconroot1
;
--
sleep
2
drop
table
t1
;
connection
default
;
--
reap
drop
table
t2
;
--
replace_column
2
# 5 #
show
binlog
events
in
'master-bin.000001'
from
106
;
# And now he gap between copying of .frm file and ha_create_table() call.
create
table
t1
(
i
int
);
set
session
debug
=
"-d,sleep_create_like_before_copy:+d,sleep_create_like_before_ha_create"
;
# Both DML and DDL on target table should wait till operation completes
reset
master
;
--
send
create
table
t2
like
t1
;
connection
addconroot1
;
--
sleep
2
insert
into
t2
values
(
1
);
connection
default
;
--
reap
drop
table
t2
;
--
send
create
table
t2
like
t1
;
connection
addconroot1
;
--
sleep
2
drop
table
t2
;
connection
default
;
--
reap
# Concurrent DDL on the source table still waits
--
send
create
table
t2
like
t1
;
connection
addconroot1
;
--
sleep
2
drop
table
t1
;
connection
default
;
--
reap
drop
table
t2
;
--
replace_column
2
# 5 #
show
binlog
events
in
'master-bin.000001'
from
106
;
# Finally we check the gap between ha_create_table() and binlogging
create
table
t1
(
i
int
);
set
session
debug
=
"-d,sleep_create_like_before_ha_create:+d,sleep_create_like_before_binlogging"
;
reset
master
;
--
send
create
table
t2
like
t1
;
connection
addconroot1
;
--
sleep
2
insert
into
t2
values
(
1
);
connection
default
;
--
reap
drop
table
t2
;
--
send
create
table
t2
like
t1
;
connection
addconroot1
;
--
sleep
2
drop
table
t2
;
connection
default
;
--
reap
--
send
create
table
t2
like
t1
;
connection
addconroot1
;
--
sleep
2
drop
table
t1
;
connection
default
;
--
reap
drop
table
t2
;
--
replace_column
2
# 5 #
show
binlog
events
in
'master-bin.000001'
from
106
;
set
session
debug
=
"-d,sleep_create_like_before_binlogging"
;
mysql-test/t/create.test
View file @
2b3ae933
...
...
@@ -306,7 +306,7 @@ create table t3 like t1;
create
table
t3
like
mysqltest
.
t3
;
--
error
1049
create
table
non_existing_database
.
t1
like
t1
;
--
error
1051
--
error
ER_NO_SUCH_TABLE
create
table
t3
like
non_existing_table
;
--
error
1050
create
temporary
table
t3
like
t1
;
...
...
mysql-test/t/disabled.def
View file @
2b3ae933
...
...
@@ -30,7 +30,6 @@ rpl_ddl : BUG#26418 2007-03-01 mleich Slave out of sync after C
rpl_ndb_innodb2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement
rpl_ndb_myisam2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement
rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly
synchronization : Bug#24529 Test 'synchronization' fails on Mac pushbuild; Also on Linux 64 bit.
# the below testcase have been reworked to avoid the bug, test contains comment, keep bug open
#ndb_binlog_ddl_multi : BUG#18976 2006-04-10 kent CRBR: multiple binlog, second binlog may miss schema log events
...
...
mysql-test/t/grant2.test
View file @
2b3ae933
...
...
@@ -513,3 +513,44 @@ REVOKE ALL PRIVILEGES, GRANT OPTION FROM `a@`@localhost;
drop
user
`a@`
@
localhost
;
SET
GLOBAL
log_bin_trust_function_creators
=
0
;
#
# Bug#25578 "CREATE TABLE LIKE does not require any privileges on source table"
#
--
disable_warnings
drop
database
if
exists
mysqltest_1
;
drop
database
if
exists
mysqltest_2
;
--
enable_warnings
--
error
0
,
ER_CANNOT_USER
drop
user
mysqltest_u1
@
localhost
;
create
database
mysqltest_1
;
create
database
mysqltest_2
;
grant
all
on
mysqltest_1
.*
to
mysqltest_u1
@
localhost
;
use
mysqltest_2
;
create
table
t1
(
i
int
);
# Connect as user with all rights on mysqltest_1 but with no rights on mysqltest_2.
connect
(
user1
,
localhost
,
mysqltest_u1
,,
mysqltest_1
);
connection
user1
;
# As expected error is emitted
--
error
ER_TABLEACCESS_DENIED_ERROR
show
create
table
mysqltest_2
.
t1
;
# This should emit error as well
--
error
ER_TABLEACCESS_DENIED_ERROR
create
table
t1
like
mysqltest_2
.
t1
;
# Now let us check that SELECT privilege on the source is enough
connection
default
;
grant
select
on
mysqltest_2
.
t1
to
mysqltest_u1
@
localhost
;
connection
user1
;
show
create
table
mysqltest_2
.
t1
;
create
table
t1
like
mysqltest_2
.
t1
;
# Clean-up
connection
default
;
use
test
;
drop
database
mysqltest_1
;
drop
database
mysqltest_2
;
drop
user
mysqltest_u1
@
localhost
;
sql/handler.h
View file @
2b3ae933
...
...
@@ -223,6 +223,7 @@
#define HA_LEX_CREATE_TMP_TABLE 1
#define HA_LEX_CREATE_IF_NOT_EXISTS 2
#define HA_LEX_CREATE_TABLE_LIKE 4
#define HA_OPTION_NO_CHECKSUM (1L << 17)
#define HA_OPTION_NO_DELAY_KEY_WRITE (1L << 18)
#define HA_MAX_REC_LENGTH 65535
...
...
sql/mysql_priv.h
View file @
2b3ae933
...
...
@@ -978,9 +978,8 @@ bool mysql_alter_table(THD *thd, char *new_db, char *new_name,
uint
order_num
,
ORDER
*
order
,
bool
ignore
,
ALTER_INFO
*
alter_info
,
bool
do_send_ok
);
bool
mysql_recreate_table
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
bool
do_send_ok
);
bool
mysql_create_like_table
(
THD
*
thd
,
TABLE_LIST
*
table
,
HA_CREATE_INFO
*
create_info
,
Table_ident
*
src_table
);
bool
mysql_create_like_table
(
THD
*
thd
,
TABLE_LIST
*
table
,
TABLE_LIST
*
src_table
,
HA_CREATE_INFO
*
create_info
);
bool
mysql_rename_table
(
handlerton
*
base
,
const
char
*
old_db
,
const
char
*
old_name
,
const
char
*
new_db
,
const
char
*
new_name
,
uint
flags
);
...
...
sql/sql_lex.h
View file @
2b3ae933
...
...
@@ -1066,7 +1066,6 @@ typedef struct st_lex : public Query_tables_list
char
*
length
,
*
dec
,
*
change
;
LEX_STRING
name
;
Table_ident
*
like_name
;
char
*
help_arg
;
char
*
backup_dir
;
/* For RESTORE/BACKUP */
char
*
to_log
;
/* For PURGE MASTER LOGS TO */
...
...
sql/sql_parse.cc
View file @
2b3ae933
...
...
@@ -39,6 +39,7 @@
"FUNCTION" : "PROCEDURE")
static
bool
execute_sqlcom_select
(
THD
*
thd
,
TABLE_LIST
*
all_tables
);
static
bool
check_show_create_table_access
(
THD
*
thd
,
TABLE_LIST
*
table
);
const
char
*
any_db
=
"*any*"
;
// Special symbol for check_access
...
...
@@ -2231,9 +2232,9 @@ mysql_execute_command(THD *thd)
if
(
lex
->
create_info
.
options
&
HA_LEX_CREATE_TMP_TABLE
)
thd
->
options
|=
OPTION_KEEP_LOG
;
/* regular create */
if
(
lex
->
like_name
)
res
=
mysql_create_like_table
(
thd
,
create_table
,
&
lex
->
create_info
,
lex
->
like_name
);
if
(
lex
->
create_info
.
options
&
HA_LEX_CREATE_TABLE_LIKE
)
res
=
mysql_create_like_table
(
thd
,
create_table
,
select_tables
,
&
lex
->
create_info
);
else
{
res
=
mysql_create_table
(
thd
,
create_table
->
db
,
...
...
@@ -2423,12 +2424,7 @@ mysql_execute_command(THD *thd)
/* Ignore temporary tables if this is "SHOW CREATE VIEW" */
if
(
lex
->
only_view
)
first_table
->
skip_temporary
=
1
;
if
(
check_access
(
thd
,
SELECT_ACL
|
EXTRA_ACL
,
first_table
->
db
,
&
first_table
->
grant
.
privilege
,
0
,
0
,
test
(
first_table
->
schema_table
)))
goto
error
;
if
(
grant_option
&&
check_grant
(
thd
,
SELECT_ACL
,
all_tables
,
2
,
UINT_MAX
,
0
))
if
(
check_show_create_table_access
(
thd
,
first_table
))
goto
error
;
res
=
mysqld_show_create
(
thd
,
first_table
);
break
;
...
...
@@ -6845,6 +6841,25 @@ bool insert_precheck(THD *thd, TABLE_LIST *tables)
}
/**
@brief Check privileges for SHOW CREATE TABLE statement.
@param thd Thread context
@param table Target table
@retval TRUE Failure
@retval FALSE Success
*/
static
bool
check_show_create_table_access
(
THD
*
thd
,
TABLE_LIST
*
table
)
{
return
check_access
(
thd
,
SELECT_ACL
|
EXTRA_ACL
,
table
->
db
,
&
table
->
grant
.
privilege
,
0
,
0
,
test
(
table
->
schema_table
))
||
grant_option
&&
check_grant
(
thd
,
SELECT_ACL
,
table
,
2
,
UINT_MAX
,
0
);
}
/*
CREATE TABLE query pre-check
...
...
@@ -6910,6 +6925,11 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
if
(
tables
&&
check_table_access
(
thd
,
SELECT_ACL
,
tables
,
0
))
goto
err
;
}
else
if
(
lex
->
create_info
.
options
&
HA_LEX_CREATE_TABLE_LIKE
)
{
if
(
check_show_create_table_access
(
thd
,
tables
))
goto
err
;
}
error
=
FALSE
;
err:
...
...
sql/sql_partition.cc
View file @
2b3ae933
...
...
@@ -3776,20 +3776,15 @@ bool mysql_unpack_partition(THD *thd,
ha_legacy_type
(
default_db_type
)));
if
(
is_create_table_ind
&&
old_lex
->
sql_command
==
SQLCOM_CREATE_TABLE
)
{
if
(
old_lex
->
like_name
)
if
(
old_lex
->
create_info
.
options
&
HA_LEX_CREATE_TABLE_LIKE
)
{
/*
This code is executed when we
do a CREATE TABLE t1 LIKE t2
old_lex->
like_name contains the t2 and the table we are opening has
name t1.
This code is executed when we
create table in CREATE TABLE t1 LIKE t2.
old_lex->
query_tables contains table list element for t2 and the table
we are opening has
name t1.
*/
Table_ident
*
table_ident
=
old_lex
->
like_name
;
char
*
src_db
=
table_ident
->
db
.
str
?
table_ident
->
db
.
str
:
thd
->
db
;
char
*
src_table
=
table_ident
->
table
.
str
;
char
buf
[
FN_REFLEN
];
build_table_filename
(
buf
,
sizeof
(
buf
),
src_db
,
src_table
,
""
,
0
);
if
(
partition_default_handling
(
table
,
part_info
,
FALSE
,
buf
))
if
(
partition_default_handling
(
table
,
part_info
,
FALSE
,
old_lex
->
query_tables
->
table
->
s
->
path
.
str
))
{
result
=
TRUE
;
goto
end
;
...
...
sql/sql_table.cc
View file @
2b3ae933
...
...
@@ -4665,114 +4665,51 @@ bool mysql_preload_keys(THD* thd, TABLE_LIST* tables)
SYNOPSIS
mysql_create_like_table()
thd Thread object
table Table list (one table only)
table Table list element for target table
src_table Table list element for source table
create_info Create info
table_ident Src table_ident
RETURN VALUES
FALSE OK
TRUE error
*/
bool
mysql_create_like_table
(
THD
*
thd
,
TABLE_LIST
*
table
,
HA_CREATE_INFO
*
lex_create_info
,
Table_ident
*
table_ident
)
bool
mysql_create_like_table
(
THD
*
thd
,
TABLE_LIST
*
table
,
TABLE_LIST
*
src_table
,
HA_CREATE_INFO
*
lex_create_info
)
{
TABLE
*
tmp_table
,
*
name_lock
=
0
;
TABLE
*
name_lock
=
0
;
char
src_path
[
FN_REFLEN
],
dst_path
[
FN_REFLEN
];
char
src_table_name_buff
[
FN_REFLEN
],
src_db_name_buff
[
FN_REFLEN
];
uint
dst_path_length
;
char
*
db
=
table
->
db
;
char
*
table_name
=
table
->
table_name
;
char
*
src_db
;
char
*
src_table
=
table_ident
->
table
.
str
;
int
err
;
bool
res
=
TRUE
;
enum
legacy_db_type
not_used
;
uint
not_used
;
HA_CREATE_INFO
*
create_info
;
#ifdef WITH_PARTITION_STORAGE_ENGINE
char
tmp_path
[
FN_REFLEN
];
#endif
char
ts_name
[
FN_LEN
];
TABLE_LIST
src_tables_list
;
DBUG_ENTER
(
"mysql_create_like_table"
);
if
(
!
(
create_info
=
copy_create_info
(
lex_create_info
)))
{
DBUG_RETURN
(
TRUE
);
}
DBUG_ASSERT
(
table_ident
->
db
.
str
);
/* Must be set in the parser */
src_db
=
table_ident
->
db
.
str
;
/* CREATE TABLE ... LIKE is not allowed for views. */
src_table
->
required_type
=
FRMTYPE_TABLE
;
/*
Validate the source table
By opening source table we guarantee that it exists and no concurrent
DDL operation will mess with it. Later we also take an exclusive
name-lock on target table name, which makes copying of .frm file,
call to ha_create_table() and binlogging atomic against concurrent DML
and DDL operations on target table. Thus by holding both these "locks"
we ensure that our statement is properly isolated from all concurrent
operations which matter.
*/
if
(
check_string_char_length
(
&
table_ident
->
table
,
""
,
NAME_CHAR_LEN
,
system_charset_info
,
1
)
||
(
table_ident
->
table
.
length
&&
check_table_name
(
src_table
,
table_ident
->
table
.
length
)))
{
my_error
(
ER_WRONG_TABLE_NAME
,
MYF
(
0
),
src_table
);
DBUG_RETURN
(
TRUE
);
}
if
(
!
src_db
||
check_db_name
(
&
table_ident
->
db
))
{
my_error
(
ER_WRONG_DB_NAME
,
MYF
(
0
),
src_db
?
src_db
:
"NULL"
);
DBUG_RETURN
(
-
1
);
}
if
((
tmp_table
=
find_temporary_table
(
thd
,
src_db
,
src_table
)))
strxmov
(
src_path
,
tmp_table
->
s
->
path
.
str
,
reg_ext
,
NullS
);
else
{
build_table_filename
(
src_path
,
sizeof
(
src_path
),
src_db
,
src_table
,
reg_ext
,
0
);
/* Resolve symlinks (for windows) */
unpack_filename
(
src_path
,
src_path
);
if
(
lower_case_table_names
)
my_casedn_str
(
files_charset_info
,
src_path
);
if
(
access
(
src_path
,
F_OK
))
{
my_error
(
ER_BAD_TABLE_ERROR
,
MYF
(
0
),
src_table
);
goto
err
;
}
}
/*
create like should be not allowed for Views, Triggers, ...
*/
if
(
mysql_frm_type
(
thd
,
src_path
,
&
not_used
)
!=
FRMTYPE_TABLE
)
{
my_error
(
ER_WRONG_OBJECT
,
MYF
(
0
),
src_db
,
src_table
,
"BASE TABLE"
);
goto
err
;
}
if
(
lower_case_table_names
)
{
if
(
src_db
)
{
strmake
(
src_db_name_buff
,
src_db
,
min
(
sizeof
(
src_db_name_buff
)
-
1
,
table_ident
->
db
.
length
));
my_casedn_str
(
files_charset_info
,
src_db_name_buff
);
src_db
=
src_db_name_buff
;
}
if
(
src_table
)
{
strmake
(
src_table_name_buff
,
src_table
,
min
(
sizeof
(
src_table_name_buff
)
-
1
,
table_ident
->
table
.
length
));
my_casedn_str
(
files_charset_info
,
src_table_name_buff
);
src_table
=
src_table_name_buff
;
}
}
bzero
((
gptr
)
&
src_tables_list
,
sizeof
(
src_tables_list
));
src_tables_list
.
db
=
src_db
;
src_tables_list
.
db_length
=
table_ident
->
db
.
length
;
src_tables_list
.
lock_type
=
TL_READ
;
src_tables_list
.
table_name
=
src_table
;
src_tables_list
.
alias
=
src_table
;
if
(
simple_open_n_lock_tables
(
thd
,
&
src_tables_list
))
if
(
open_tables
(
thd
,
&
src_table
,
&
not_used
,
0
))
DBUG_RETURN
(
TRUE
);
/*
...
...
@@ -4781,17 +4718,19 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
Add something to get possible tablespace info from src table,
it can get valid tablespace name only for disk-base ndb table
*/
if
((
src_table
s_list
.
table
->
file
->
get_tablespace_name
(
thd
,
ts_name
,
FN_LEN
)))
if
((
src_table
->
table
->
file
->
get_tablespace_name
(
thd
,
ts_name
,
FN_LEN
)))
{
create_info
->
tablespace
=
ts_name
;
create_info
->
storage_media
=
HA_SM_DISK
;
}
/*
Validate the destination table
strxmov
(
src_path
,
src_table
->
table
->
s
->
path
.
str
,
reg_ext
,
NullS
);
skip the destination table name checking as this is already
validated.
DBUG_EXECUTE_IF
(
"sleep_create_like_before_check_if_exists"
,
my_sleep
(
6000000
););
/*
Check that destination tables does not exist. Note that its name
was already checked when it was added to the table list.
*/
if
(
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
)
{
...
...
@@ -4812,15 +4751,29 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
goto
table_exists
;
}
DBUG_EXECUTE_IF
(
"sleep_create_like_before_copy"
,
my_sleep
(
6000000
););
/*
Create a new table by copying from source table
Altough exclusive name-lock on target table protects us from concurrent
DML and DDL operations on it we still want to wrap .FRM creation and call
to ha_create_table() in critical section protected by LOCK_open in order
to provide minimal atomicity against operations which disregard name-locks,
like I_S implementation, for example. This is a temporary and should not
be copied. Instead we should fix our code to always honor name-locks.
Also some engines (e.g. NDB cluster) require that LOCK_open should be held
during the call to ha_create_table(). See bug #28614 for more info.
*/
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
if
(
my_copy
(
src_path
,
dst_path
,
MYF
(
MY_DONT_OVERWRITE_FILE
)))
{
if
(
my_errno
==
ENOENT
)
my_error
(
ER_BAD_DB_ERROR
,
MYF
(
0
),
db
);
else
my_error
(
ER_CANT_CREATE_FILE
,
MYF
(
0
),
dst_path
,
my_errno
);
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
goto
err
;
}
...
...
@@ -4842,10 +4795,12 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
strmov
(
src_path
,
tmp_path
);
my_copy
(
src_path
,
dst_path
,
MYF
(
MY_DONT_OVERWRITE_FILE
));
#endif
DBUG_EXECUTE_IF
(
"sleep_create_like_before_ha_create"
,
my_sleep
(
6000000
););
dst_path
[
dst_path_length
-
reg_ext_length
]
=
'\0'
;
// Remove .frm
pthread_mutex_lock
(
&
LOCK_open
);
err
=
ha_create_table
(
thd
,
dst_path
,
db
,
table_name
,
create_info
,
1
);
pthread_mutex_unlock
(
&
LOCK_open
);
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
)
);
if
(
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
)
{
if
(
err
||
!
open_temporary_table
(
thd
,
dst_path
,
db
,
table_name
,
1
))
...
...
@@ -4862,6 +4817,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
goto
err
;
/* purecov: inspected */
}
DBUG_EXECUTE_IF
(
"sleep_create_like_before_binlogging"
,
my_sleep
(
6000000
););
/*
We have to write the query before we unlock the tables.
*/
...
...
@@ -4881,14 +4838,10 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
3 temporary normal Nothing
4 temporary temporary Nothing
==== ========= ========= ==============================
The variable 'tmp_table' below is used to see if the source
table is a temporary table: if it is set, then the source table
was a temporary table and we can take apropriate actions.
*/
if
(
!
(
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
))
{
if
(
tmp_table
)
// Case 2
if
(
src_table
->
table
->
s
->
tmp_table
)
// Case 2
{
char
buf
[
2048
];
String
query
(
buf
,
sizeof
(
buf
),
system_charset_info
);
...
...
sql/sql_yacc.yy
View file @
2b3ae933
...
...
@@ -1579,7 +1579,6 @@ create:
lex->create_info.default_table_charset= NULL;
lex->name.str= 0;
lex->name.length= 0;
lex->like_name= 0;
}
create2
{
...
...
@@ -3603,27 +3602,15 @@ create2:
create3 {}
| LIKE table_ident
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
if (!(lex->like_name= $2))
Lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE;
if (!Lex->select_lex.add_table_to_list(YYTHD, $2, NULL, 0, TL_READ))
MYSQL_YYABORT;
if ($2->db.str == NULL &&
thd->copy_db_to(&($2->db.str), &($2->db.length)))
{
MYSQL_YYABORT;
}
}
| '(' LIKE table_ident ')'
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
if (!(lex->like_name= $3))
Lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE;
if (!Lex->select_lex.add_table_to_list(YYTHD, $3, NULL, 0, TL_READ))
MYSQL_YYABORT;
if ($3->db.str == NULL &&
thd->copy_db_to(&($3->db.str), &($3->db.length)))
{
MYSQL_YYABORT;
}
}
;
...
...
@@ -5112,7 +5099,6 @@ alter:
lex->key_list.empty();
lex->col_list.empty();
lex->select_lex.init_order();
lex->like_name= 0;
lex->select_lex.db=
((TABLE_LIST*) lex->select_lex.table_list.first)->db;
bzero((char*) &lex->create_info,sizeof(lex->create_info));
...
...
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