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
48ee575e
Commit
48ee575e
authored
Aug 21, 2000
by
monty@donna.mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merge of last changes
parent
d79b0cc9
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
208 additions
and
59 deletions
+208
-59
sql/ChangeLog
sql/ChangeLog
+4
-0
sql/mysql_priv.h
sql/mysql_priv.h
+12
-0
sql/sql_parse.cc
sql/sql_parse.cc
+60
-59
sql/sql_rename.cc
sql/sql_rename.cc
+132
-0
No files found.
sql/ChangeLog
View file @
48ee575e
2000-08-21 Michael Widenius <monty@mysql.com>
* Added RENAME TABLE.
2000-08-20 Michael Widenius <monty@mysql.com>
* Added memory as inline functions to THD to get them a bit faster
...
...
sql/mysql_priv.h
View file @
48ee575e
...
...
@@ -217,6 +217,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags);
int
mysql_rm_table
(
THD
*
thd
,
TABLE_LIST
*
tables
,
my_bool
if_exists
);
int
quick_rm_table
(
enum
db_type
base
,
const
char
*
db
,
const
char
*
table_name
);
bool
mysql_rename_tables
(
THD
*
thd
,
TABLE_LIST
*
table_list
);
bool
mysql_change_db
(
THD
*
thd
,
const
char
*
name
);
void
mysql_parse
(
THD
*
thd
,
char
*
inBuf
,
uint
length
);
void
mysql_init_select
(
LEX
*
lex
);
...
...
@@ -293,6 +294,11 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name,
List
<
Alter_column
>
&
alter_list
,
bool
drop_primary
,
enum
enum_duplicates
handle_duplicates
);
bool
mysql_rename_table
(
enum
db_type
base
,
const
char
*
old_db
,
const
char
*
old_name
,
const
char
*
new_db
,
const
char
*
new_name
);
bool
close_cached_table
(
THD
*
thd
,
TABLE
*
table
);
int
mysql_create_index
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Key
>
&
keys
);
int
mysql_drop_index
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
...
...
@@ -316,6 +322,7 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh);
void
close_old_data_files
(
THD
*
thd
,
TABLE
*
table
,
bool
abort_locks
);
bool
close_data_tables
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
);
bool
wait_for_tables
(
THD
*
thd
);
bool
table_is_used
(
TABLE
*
table
);
bool
drop_locked_tables
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
);
void
abort_locked_tables
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
);
Field
*
find_field_in_tables
(
THD
*
thd
,
Item_field
*
item
,
TABLE_LIST
*
tables
);
...
...
@@ -488,6 +495,11 @@ void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table);
void
mysql_lock_abort
(
THD
*
thd
,
TABLE
*
table
);
MYSQL_LOCK
*
mysql_lock_merge
(
MYSQL_LOCK
*
a
,
MYSQL_LOCK
*
b
);
/* Lock based on name */
int
lock_table_name
(
THD
*
thd
,
TABLE_LIST
*
table_list
);
void
unlock_table_name
(
THD
*
thd
,
TABLE_LIST
*
table_list
);
bool
wait_for_locked_table_names
(
THD
*
thd
,
TABLE_LIST
*
table_list
);
extern
int
flush_master_info
(
MASTER_INFO
*
mi
);
/* old unireg functions */
...
...
sql/sql_parse.cc
View file @
48ee575e
...
...
@@ -39,7 +39,7 @@ extern "C" int gethostname(char *name, int namelen);
#endif
static
bool
check_table_access
(
THD
*
thd
,
uint
want_access
,
TABLE_LIST
*
tables
);
static
bool
check_
lock_tables
(
THD
*
thd
,
TABLE_LIST
*
tables
);
static
bool
check_
db_used
(
THD
*
thd
,
TABLE_LIST
*
tables
);
static
bool
check_dup
(
THD
*
thd
,
const
char
*
db
,
const
char
*
name
,
TABLE_LIST
*
tables
);
static
void
mysql_init_query
(
THD
*
thd
);
...
...
@@ -387,7 +387,6 @@ pthread_handler_decl(handle_one_connection,arg)
goto
end_thread
;
}
thd
->
alloc
.
free
=
thd
->
alloc
.
used
=
0
;
if
(
thd
->
max_join_size
==
HA_POS_ERROR
)
thd
->
options
|=
OPTION_BIG_SELECTS
;
if
(
thd
->
client_capabilities
&
CLIENT_COMPRESS
)
...
...
@@ -395,7 +394,7 @@ pthread_handler_decl(handle_one_connection,arg)
if
(
thd
->
options
&
OPTION_ANSI_MODE
)
thd
->
client_capabilities
|=
CLIENT_IGNORE_SPACE
;
thd
->
proc_info
=
0
;
thd
->
proc_info
=
0
;
// Remove 'login'
thd
->
version
=
refresh_version
;
thd
->
set_time
();
while
(
!
net
->
error
&&
net
->
vio
!=
0
&&
!
thd
->
killed
)
...
...
@@ -436,7 +435,7 @@ int handle_bootstrap(THD *thd,FILE *file)
if
(
init_thr_lock
()
||
my_pthread_setspecific_ptr
(
THR_THD
,
thd
)
||
my_pthread_setspecific_ptr
(
THR_MALLOC
,
&
thd
->
alloc
)
||
my_pthread_setspecific_ptr
(
THR_MALLOC
,
&
thd
->
mem_root
)
||
my_pthread_setspecific_ptr
(
THR_NET
,
&
thd
->
net
))
{
close_connection
(
&
thd
->
net
,
ER_OUT_OF_RESOURCES
);
...
...
@@ -450,7 +449,6 @@ int handle_bootstrap(THD *thd,FILE *file)
VOID
(
pthread_sigmask
(
SIG_UNBLOCK
,
&
set
,
&
thd
->
block_signals
));
#endif
thd
->
alloc
.
free
=
thd
->
alloc
.
used
=
0
;
if
(
thd
->
max_join_size
==
(
ulong
)
~
0L
)
thd
->
options
|=
OPTION_BIG_SELECTS
;
...
...
@@ -464,9 +462,9 @@ int handle_bootstrap(THD *thd,FILE *file)
while
(
length
&&
(
isspace
(
buff
[
length
-
1
])
||
buff
[
length
-
1
]
==
';'
))
length
--
;
buff
[
length
]
=
0
;
init_sql_alloc
(
&
thd
->
alloc
,
8192
);
init_sql_alloc
(
&
thd
->
mem_root
,
8192
);
thd
->
current_tablenr
=
0
;
thd
->
query
=
sql_
memdup
(
buff
,
length
+
1
);
thd
->
query
=
thd
->
memdup
(
buff
,
length
+
1
);
thd
->
query_id
=
query_id
++
;
mysql_parse
(
thd
,
thd
->
query
,
length
);
close_thread_tables
(
thd
);
// Free tables
...
...
@@ -474,7 +472,7 @@ int handle_bootstrap(THD *thd,FILE *file)
{
DBUG_RETURN
(
-
1
);
}
free_root
(
&
thd
->
alloc
);
free_root
(
&
thd
->
mem_root
);
}
DBUG_RETURN
(
0
);
}
...
...
@@ -542,7 +540,7 @@ bool do_command(THD *thd)
enum
enum_server_command
command
;
DBUG_ENTER
(
"do_command"
);
init_sql_alloc
(
&
thd
->
alloc
,
8192
);
init_sql_alloc
(
&
thd
->
mem_root
,
8192
);
net
=
&
thd
->
net
;
thd
->
current_tablenr
=
0
;
...
...
@@ -642,7 +640,7 @@ bool do_command(THD *thd)
packet_length
--
;
}
*
pos
=
0
;
if
(
!
(
thd
->
query
=
(
char
*
)
sql_
memdup
((
gptr
)
(
packet
+
1
),
packet_length
)))
if
(
!
(
thd
->
query
=
(
char
*
)
thd
->
memdup
((
gptr
)
(
packet
+
1
),
packet_length
)))
break
;
thd
->
packet
.
shrink
(
net_buffer_length
);
// Reclaim some memory
if
(
!
(
specialflag
&
SPECIAL_NO_PRIOR
))
...
...
@@ -670,8 +668,8 @@ bool do_command(THD *thd)
break
;
}
thd
->
free_list
=
0
;
table_list
.
name
=
table_list
.
real_name
=
sql_
strdup
(
packet
+
1
);
thd
->
query
=
fields
=
sql_
strdup
(
strend
(
packet
+
1
)
+
1
);
table_list
.
name
=
table_list
.
real_name
=
thd
->
strdup
(
packet
+
1
);
thd
->
query
=
fields
=
thd
->
strdup
(
strend
(
packet
+
1
)
+
1
);
mysql_log
.
write
(
command
,
"%s %s"
,
table_list
.
real_name
,
fields
);
remove_escape
(
table_list
.
real_name
);
// This can't have wildcards
...
...
@@ -693,7 +691,7 @@ bool do_command(THD *thd)
case
COM_CREATE_DB
:
{
char
*
db
=
sql_
strdup
(
packet
+
1
);
char
*
db
=
thd
->
strdup
(
packet
+
1
);
if
(
check_access
(
thd
,
CREATE_ACL
,
db
,
0
,
1
))
break
;
mysql_log
.
write
(
command
,
packet
+
1
);
...
...
@@ -702,7 +700,7 @@ bool do_command(THD *thd)
}
case
COM_DROP_DB
:
{
char
*
db
=
sql_
strdup
(
packet
+
1
);
char
*
db
=
thd
->
strdup
(
packet
+
1
);
if
(
check_access
(
thd
,
DROP_ACL
,
db
,
0
,
1
))
break
;
mysql_log
.
write
(
command
,
db
);
...
...
@@ -719,7 +717,7 @@ bool do_command(THD *thd)
ushort
flags
;
pos
=
uint4korr
(
packet
+
1
);
flags
=
uint2korr
(
packet
+
5
);
mysql_binlog_send
(
thd
,
sql_
strdup
(
packet
+
7
),
pos
,
flags
);
mysql_binlog_send
(
thd
,
thd
->
strdup
(
packet
+
7
),
pos
,
flags
);
break
;
}
case
COM_REFRESH
:
...
...
@@ -746,7 +744,7 @@ bool do_command(THD *thd)
send_eof
(
net
);
// This is for 'quit request'
close_connection
(
net
);
close_thread_tables
(
thd
);
// Free before kill
free_root
(
&
thd
->
alloc
);
free_root
(
&
thd
->
mem_root
);
kill_mysql
();
error
=
TRUE
;
break
;
...
...
@@ -827,7 +825,7 @@ bool do_command(THD *thd)
thread_running
--
;
VOID
(
pthread_mutex_unlock
(
&
LOCK_thread_count
));
thd
->
packet
.
shrink
(
net_buffer_length
);
// Reclaim some memory
free_root
(
&
thd
->
alloc
);
free_root
(
&
thd
->
mem_root
);
DBUG_RETURN
(
error
);
}
...
...
@@ -945,7 +943,7 @@ mysql_execute_command(void)
}
case
SQLCOM_SHOW_MASTER_STAT
:
{
if
(
check_access
(
thd
,
PROCESS_ACL
,
any_db
))
if
(
check_access
(
thd
,
PROCESS_ACL
,
any_db
))
goto
error
;
res
=
show_binlog_info
(
thd
);
break
;
...
...
@@ -1132,51 +1130,49 @@ mysql_execute_command(void)
break
;
}
#endif
case
SQLCOM_RENAME_TABLE
:
if
(
check_db_used
(
thd
,
tables
)
||
check_table_access
(
thd
,
ALTER_ACL
,
tables
))
goto
error
;
if
(
mysql_rename_tables
(
thd
,
tables
))
res
=
-
1
;
break
;
case
SQLCOM_SHOW_CREATE
:
#ifdef DONT_ALLOW_SHOW_COMMANDS
send_error
(
&
thd
->
net
,
ER_NOT_ALLOWED_COMMAND
);
/* purecov: inspected */
DBUG_VOID_RETURN
;
#else
{
if
(
!
tables
->
db
)
tables
->
db
=
thd
->
db
;
if
(
!
tables
->
db
)
{
send_error
(
&
thd
->
net
,
ER_NO_DB_ERROR
);
/* purecov: inspected */
goto
error
;
/* purecov: inspected */
}
if
(
check_db_used
(
thd
,
tables
)
||
check_access
(
thd
,
SELECT_ACL
|
EXTRA_ACL
,
tables
->
db
,
&
tables
->
grant
.
privilege
))
goto
error
;
res
=
mysqld_show_create
(
thd
,
tables
);
break
;
}
#endif
case
SQLCOM_REPAIR
:
{
if
(
!
tables
->
db
)
tables
->
db
=
thd
->
db
;
if
(
check_access
(
thd
,
SELECT_ACL
|
INSERT_ACL
,
tables
->
db
,
&
tables
->
grant
.
privilege
))
if
(
check_table_access
(
thd
,
SELECT_ACL
|
INSERT_ACL
,
tables
))
goto
error
;
/* purecov: inspected */
if
(
grant_option
&&
check_grant
(
thd
,
SELECT_ACL
|
INSERT_ACL
,
tables
))
goto
error
;
res
=
mysql_repair_table
(
thd
,
tables
,
&
lex
->
check_opt
);
break
;
}
case
SQLCOM_CHECK
:
{
if
(
!
tables
->
db
)
tables
->
db
=
thd
->
db
;
if
(
check_access
(
thd
,
SELECT_ACL
,
tables
->
db
,
&
tables
->
grant
.
privilege
))
if
(
check_db_used
(
thd
,
tables
)
||
check_table_access
(
thd
,
SELECT_ACL
|
EXTRA_ACL
,
tables
))
goto
error
;
/* purecov: inspected */
if
(
grant_option
&&
check_grant
(
thd
,
SELECT_ACL
,
tables
))
goto
error
;
res
=
mysql_check_table
(
thd
,
tables
,
&
lex
->
check_opt
);
break
;
}
case
SQLCOM_ANALYZE
:
{
if
(
!
tables
->
db
)
tables
->
db
=
thd
->
db
;
if
(
check_access
(
thd
,
SELECT_ACL
|
INSERT_ACL
,
tables
->
db
,
&
tables
->
grant
.
privilege
))
if
(
check_db_used
(
thd
,
tables
)
||
check_table_access
(
thd
,
SELECT_ACL
|
INSERT_ACL
,
tables
))
goto
error
;
/* purecov: inspected */
if
(
grant_option
&&
check_grant
(
thd
,
SELECT_ACL
|
INSERT_ACL
,
tables
))
goto
error
;
res
=
mysql_analyze_table
(
thd
,
tables
);
break
;
}
...
...
@@ -1515,7 +1511,7 @@ mysql_execute_command(void)
thd
->
locked_tables
=
0
;
// Will be automaticly closed
close_thread_tables
(
thd
);
}
if
(
check_
lock_tables
(
thd
,
tables
))
if
(
check_
db_used
(
thd
,
tables
))
goto
error
;
thd
->
in_lock_tables
=
1
;
if
(
!
(
res
=
open_and_lock_tables
(
thd
,
tables
)))
...
...
@@ -1749,7 +1745,7 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables)
{
if
((
thd
->
master_access
&
want_access
)
==
want_access
&&
thd
->
db
)
tables
->
grant
.
privilege
=
want_access
;
else
if
(
tables
->
db
)
else
if
(
tables
->
db
&&
tables
->
db
==
thd
->
db
)
{
if
(
found
&&
!
grant_option
)
// db already checked
tables
->
grant
.
privilege
=
found_access
;
...
...
@@ -1758,6 +1754,7 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables)
if
(
check_access
(
thd
,
want_access
,
tables
->
db
,
&
tables
->
grant
.
privilege
))
return
TRUE
;
// Access denied
found_access
=
tables
->
grant
.
privilege
;
found
=
1
;
}
}
else
if
(
check_access
(
thd
,
want_access
,
tables
->
db
,
&
tables
->
grant
.
privilege
))
...
...
@@ -1769,7 +1766,7 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables)
}
static
bool
check_
lock_tables
(
THD
*
thd
,
TABLE_LIST
*
tables
)
static
bool
check_
db_used
(
THD
*
thd
,
TABLE_LIST
*
tables
)
{
for
(;
tables
;
tables
=
tables
->
next
)
{
...
...
@@ -2274,21 +2271,24 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
if
(
lower_case_table_names
)
casedn_str
(
table
->
table
.
str
);
#endif
if
(
!
(
ptr
=
(
TABLE_LIST
*
)
sql_
calloc
(
sizeof
(
TABLE_LIST
))))
if
(
!
(
ptr
=
(
TABLE_LIST
*
)
thd
->
calloc
(
sizeof
(
TABLE_LIST
))))
DBUG_RETURN
(
0
);
/* purecov: inspected */
ptr
->
db
=
table
->
db
.
str
;
ptr
->
real_name
=
table
->
table
.
str
;
ptr
->
name
=
alias_str
;
ptr
->
lock_type
=
flags
;
if
(
use_index
)
ptr
->
use_index
=
(
List
<
String
>
*
)
sql_
memdup
((
gptr
)
use_index
,
ptr
->
use_index
=
(
List
<
String
>
*
)
thd
->
memdup
((
gptr
)
use_index
,
sizeof
(
*
use_index
));
if
(
ignore_index
)
ptr
->
ignore_index
=
(
List
<
String
>
*
)
sql_
memdup
((
gptr
)
ignore_index
,
ptr
->
ignore_index
=
(
List
<
String
>
*
)
thd
->
memdup
((
gptr
)
ignore_index
,
sizeof
(
*
ignore_index
));
/* check that used name is unique */
current_db
=
thd
->
db
?
thd
->
db
:
""
;
if
(
flags
!=
TL_IGNORE
)
{
for
(
TABLE_LIST
*
tables
=
(
TABLE_LIST
*
)
thd
->
lex
.
table_list
.
first
;
tables
;
tables
=
tables
->
next
)
{
...
...
@@ -2300,6 +2300,7 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
DBUG_RETURN
(
0
);
/* purecov: tested */
}
}
}
link_in_list
(
&
thd
->
lex
.
table_list
,(
byte
*
)
ptr
,(
byte
**
)
&
ptr
->
next
);
DBUG_RETURN
(
ptr
);
}
...
...
sql/sql_rename.cc
0 → 100644
View file @
48ee575e
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Atomic rename of table; RENAME TABLE t1 to t2, tmp to t1 [,...]
*/
#include "mysql_priv.h"
static
TABLE_LIST
*
mysql_rename_tables
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
bool
skip_error
);
/*
Every second entry in the table_list is the original name and every
second entry is the new name.
*/
bool
mysql_rename_tables
(
THD
*
thd
,
TABLE_LIST
*
table_list
)
{
bool
error
=
1
,
got_all_locks
=
1
;
db_type
table_type
;
TABLE_LIST
*
lock_table
,
*
ren_table
=
0
,
*
new_table
;
DBUG_ENTER
(
"mysql_rename_tables"
);
/* Avoid problems with a rename on a table that we have locked or
if the user is trying to to do this in a transcation context */
if
(
thd
->
locked_tables
||
thd
->
active_transaction
())
{
my_error
(
ER_LOCK_OR_ACTIVE_TRANSACTION
,
MYF
(
0
));
DBUG_RETURN
(
1
);
}
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
for
(
lock_table
=
table_list
;
lock_table
;
lock_table
=
lock_table
->
next
)
{
int
got_lock
;
if
((
got_lock
=
lock_table_name
(
thd
,
lock_table
))
<
0
)
goto
end
;
if
(
got_lock
)
got_all_locks
=
0
;
}
if
(
!
got_all_locks
&&
wait_for_locked_table_names
(
thd
,
table_list
))
goto
end
;
if
(
!
(
ren_table
=
mysql_rename_tables
(
thd
,
table_list
,
0
)))
error
=
0
;
end:
if
(
ren_table
)
{
/* Rename didn't succeed; rename back the tables in reverse order */
TABLE_LIST
*
prev
=
0
,
*
table
;
/*
Reverse the table list ; Note that we need to handle the case that
every second entry must stay in place in respect to the previous
*/
while
(
table_list
)
{
TABLE_LIST
*
next
=
table_list
->
next
->
next
;
table_list
->
next
->
next
=
prev
;
prev
=
table_list
;
table_list
=
next
;
}
table_list
=
prev
;
/* Find the last renamed table */
for
(
table
=
table_list
;
table
->
next
!=
ren_table
;
table
=
table
->
next
->
next
)
;
table
=
table
->
next
->
next
;
// Skipp error table
/* Revert to old names */
mysql_rename_tables
(
thd
,
table
,
1
);
/* Note that lock_table == 0 here, so the unlock loop will work */
}
if
(
!
error
)
{
mysql_update_log
.
write
(
thd
->
query
,
thd
->
query_length
);
Query_log_event
qinfo
(
thd
,
thd
->
query
);
mysql_bin_log
.
write
(
&
qinfo
);
}
for
(
TABLE_LIST
*
table
=
table_list
;
table
!=
lock_table
;
table
=
table
->
next
)
unlock_table_name
(
thd
,
table
);
pthread_cond_broadcast
(
&
COND_refresh
);
pthread_mutex_unlock
(
&
LOCK_open
);
DBUG_RETURN
(
error
);
}
/*
Rename all tables in list; Return pointer to wrong entry if something goes
wrong.
*/
static
TABLE_LIST
*
mysql_rename_tables
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
bool
skip_error
)
{
TABLE_LIST
*
ren_table
;
for
(
ren_table
=
table_list
;
ren_table
;
ren_table
=
ren_table
->
next
)
{
db_type
table_type
;
char
name
[
FN_REFLEN
];
TABLE_LIST
*
new_table
=
ren_table
->
next
;
sprintf
(
name
,
"%s/%s/%s%s"
,
mysql_data_home
,
ren_table
->
db
,
ren_table
->
name
,
reg_ext
);
if
((
table_type
=
get_table_type
(
name
))
==
DB_TYPE_UNKNOWN
||
mysql_rename_table
(
table_type
,
ren_table
->
db
,
ren_table
->
name
,
new_table
->
db
,
new_table
->
name
))
{
if
(
!
skip_error
)
return
ren_table
;
}
}
return
0
;
}
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