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
20694fdb
Commit
20694fdb
authored
Apr 17, 2006
by
osku
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use bound literals in row_rename_table_for_mysql.
parent
05963b49
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
160 additions
and
186 deletions
+160
-186
row/row0mysql.c
row/row0mysql.c
+160
-186
No files found.
row/row0mysql.c
View file @
20694fdb
...
...
@@ -3416,6 +3416,62 @@ row_is_mysql_tmp_table_name(
return
(
strstr
(
name
,
"/@0023sql"
)
!=
NULL
);
}
/********************************************************************
Delete a single constraint. */
static
int
row_delete_constraint_low
(
/*======================*/
/* out: error code or DB_SUCCESS */
const
char
*
id
,
/* in: constraint id */
trx_t
*
trx
)
/* in: transaction handle */
{
pars_info_t
*
info
=
pars_info_create
();
pars_info_add_str_literal
(
info
,
"id"
,
id
);
return
(
que_eval_sql
(
info
,
"PROCEDURE DELETE_CONSTRAINT () IS
\n
"
"BEGIN
\n
"
"DELETE FROM SYS_FOREIGN_COLS WHERE ID = :id;
\n
"
"DELETE FROM SYS_FOREIGN WHERE ID = :id;
\n
"
"END;
\n
"
,
trx
));
}
/********************************************************************
Delete a single constraint. */
static
int
row_delete_constraint
(
/*==================*/
/* out: error code or DB_SUCCESS */
const
char
*
id
,
/* in: constraint id */
const
char
*
database_name
,
/* in: database name, with the
trailing '/' */
mem_heap_t
*
heap
,
/* in: memory heap */
trx_t
*
trx
)
/* in: transaction handle */
{
ulint
err
;
/* New format constraints have ids <databasename>/<constraintname>. */
err
=
row_delete_constraint_low
(
mem_heap_strcat
(
heap
,
database_name
,
id
),
trx
);
if
((
err
==
DB_SUCCESS
)
&&
!
strchr
(
id
,
'/'
))
{
/* Old format < 4.0.18 constraints have constraint ids
<number>_<number>. We only try deleting them if the
constraint name does not contain a '/' character, otherwise
deleting a new format constraint named 'foo/bar' from
database 'baz' would remove constraint 'bar' from database
'foo', if it existed. */
err
=
row_delete_constraint_low
(
id
,
trx
);
}
return
(
err
);
}
/*************************************************************************
Renames a table for MySQL. */
...
...
@@ -3428,100 +3484,13 @@ row_rename_table_for_mysql(
trx_t
*
trx
)
/* in: transaction handle */
{
dict_table_t
*
table
;
que_thr_t
*
thr
;
que_t
*
graph
=
NULL
;
ulint
err
;
/* We use the private SQL parser of Innobase to generate the
query graphs needed in deleting the dictionary data from system
tables in Innobase. Deleting a row from SYS_INDEXES table also
frees the file segments of the B-tree associated with the index. */
static
const
char
str1
[]
=
"PROCEDURE RENAME_TABLE_PROC () IS
\n
"
"new_table_name CHAR;
\n
"
"old_table_name CHAR;
\n
"
"gen_constr_prefix CHAR;
\n
"
"new_db_name CHAR;
\n
"
"foreign_id CHAR;
\n
"
"new_foreign_id CHAR;
\n
"
"old_db_name_len INT;
\n
"
"old_t_name_len INT;
\n
"
"new_db_name_len INT;
\n
"
"id_len INT;
\n
"
"found INT;
\n
"
"BEGIN
\n
"
"new_table_name := '"
;
static
const
char
str2
[]
=
"';
\n
old_table_name := '"
;
static
const
char
str3
[]
=
"';
\n
"
"UPDATE SYS_TABLES SET NAME = new_table_name
\n
"
"WHERE NAME = old_table_name;
\n
"
;
static
const
char
str4a1
[]
=
/* drop some constraints of tmp tables */
"DELETE FROM SYS_FOREIGN_COLS WHERE ID = '"
;
static
const
char
str4a2
[]
=
"';
\n
"
"DELETE FROM SYS_FOREIGN WHERE ID = '"
;
static
const
char
str4a3
[]
=
"';
\n
"
;
static
const
char
str4b
[]
=
/* rename all constraints */
"found := 1;
\n
"
"old_db_name_len := INSTR(old_table_name, '/') - 1;
\n
"
"new_db_name_len := INSTR(new_table_name, '/') - 1;
\n
"
"new_db_name := SUBSTR(new_table_name, 0, new_db_name_len);
\n
"
"old_t_name_len := LENGTH(old_table_name);
\n
"
"gen_constr_prefix := CONCAT(old_table_name, '_ibfk_');
\n
"
"WHILE found = 1 LOOP
\n
"
" SELECT ID INTO foreign_id
\n
"
" FROM SYS_FOREIGN
\n
"
" WHERE FOR_NAME = old_table_name
\n
"
" AND TO_BINARY(FOR_NAME) = TO_BINARY(old_table_name);
\n
"
" IF (SQL % NOTFOUND) THEN
\n
"
" found := 0;
\n
"
" ELSE
\n
"
" UPDATE SYS_FOREIGN
\n
"
" SET FOR_NAME = new_table_name
\n
"
" WHERE ID = foreign_id;
\n
"
" id_len := LENGTH(foreign_id);
\n
"
" IF (INSTR(foreign_id, '/') > 0) THEN
\n
"
" IF (INSTR(foreign_id,
\n
"
" gen_constr_prefix) > 0)
\n
"
" THEN
\n
"
" new_foreign_id :=
\n
"
" CONCAT(new_table_name,
\n
"
" SUBSTR(foreign_id, old_t_name_len,
\n
"
" id_len - old_t_name_len));
\n
"
" ELSE
\n
"
" new_foreign_id :=
\n
"
" CONCAT(new_db_name,
\n
"
" SUBSTR(foreign_id,
\n
"
" old_db_name_len,
\n
"
" id_len - old_db_name_len));
\n
"
" END IF;
\n
"
" UPDATE SYS_FOREIGN
\n
"
" SET ID = new_foreign_id
\n
"
" WHERE ID = foreign_id;
\n
"
" UPDATE SYS_FOREIGN_COLS
\n
"
" SET ID = new_foreign_id
\n
"
" WHERE ID = foreign_id;
\n
"
" END IF;
\n
"
" END IF;
\n
"
"END LOOP;
\n
"
"UPDATE SYS_FOREIGN SET REF_NAME = new_table_name
\n
"
"WHERE REF_NAME = old_table_name
\n
"
" AND TO_BINARY(REF_NAME) = TO_BINARY(old_table_name);
\n
"
;
static
const
char
str5
[]
=
"END;
\n
"
;
mem_heap_t
*
heap
=
NULL
;
const
char
**
constraints_to_drop
=
NULL
;
ulint
n_constraints_to_drop
=
0
;
ibool
recovering_temp_table
=
FALSE
;
ibool
old_is_tmp
,
new_is_tmp
;
ulint
len
;
ulint
i
;
ibool
success
;
/* length of database name; 0 if not renaming to a temporary table */
ulint
db_name_len
;
char
*
sql
;
char
*
sqlend
;
pars_info_t
*
info
=
NULL
;
ut_ad
(
trx
->
mysql_thread_id
==
os_thread_get_curr_id
());
ut_a
(
old_name
!=
NULL
);
...
...
@@ -3599,13 +3568,7 @@ row_rename_table_for_mysql(
goto
funct_exit
;
}
/* calculate the length of the SQL string */
len
=
(
sizeof
str1
)
+
(
sizeof
str2
)
+
(
sizeof
str3
)
+
(
sizeof
str5
)
-
4
+
ut_strlenq
(
new_name
,
'\''
)
+
ut_strlenq
(
old_name
,
'\''
);
if
(
new_is_tmp
)
{
db_name_len
=
dict_get_db_name_len
(
old_name
)
+
1
;
/* MySQL is doing an ALTER TABLE command and it renames the
original table to a temporary table name. We want to preserve
the original foreign key constraint definitions despite the
...
...
@@ -3615,110 +3578,124 @@ row_rename_table_for_mysql(
heap
=
mem_heap_create
(
100
);
err
=
dict_foreign_parse_drop_constraints
(
heap
,
trx
,
table
,
&
n_constraints_to_drop
,
&
constraints_to_drop
);
table
,
&
n_constraints_to_drop
,
&
constraints_to_drop
);
if
(
err
!=
DB_SUCCESS
)
{
goto
funct_exit
;
}
}
/* reserve space for all database names */
len
+=
2
*
n_constraints_to_drop
*
(
ut_strlenq
(
old_name
,
'\''
)
-
ut_strlenq
(
old_name
+
db_name_len
,
'\''
));
/* We use the private SQL parser of Innobase to generate the query
graphs needed in deleting the dictionary data from system tables in
Innobase. Deleting a row from SYS_INDEXES table also frees the file
segments of the B-tree associated with the index. */
for
(
i
=
0
;
i
<
n_constraints_to_drop
;
i
++
)
{
ulint
addlen
=
2
*
ut_strlenq
(
constraints_to_drop
[
i
],
'\''
)
+
((
sizeof
str4a1
)
+
(
sizeof
str4a2
)
+
(
sizeof
str4a3
)
-
3
);
if
(
!
strchr
(
constraints_to_drop
[
i
],
'/'
))
{
addlen
*=
2
;
}
len
+=
addlen
;
}
}
else
{
db_name_len
=
0
;
len
+=
(
sizeof
str4b
)
-
1
;
}
info
=
pars_info_create
();
sql
=
sqlend
=
mem_alloc
(
len
+
1
);
memcpy
(
sql
,
str1
,
(
sizeof
str1
)
-
1
);
sqlend
+=
(
sizeof
str1
)
-
1
;
sqlend
=
ut_strcpyq
(
sqlend
,
'\''
,
new_name
);
memcpy
(
sqlend
,
str2
,
(
sizeof
str2
)
-
1
);
sqlend
+=
(
sizeof
str2
)
-
1
;
sqlend
=
ut_strcpyq
(
sqlend
,
'\''
,
old_name
);
memcpy
(
sqlend
,
str3
,
(
sizeof
str3
)
-
1
);
sqlend
+=
(
sizeof
str3
)
-
1
;
pars_info_add_str_literal
(
info
,
"new_table_name"
,
new_name
);
pars_info_add_str_literal
(
info
,
"old_table_name"
,
old_name
);
if
(
db_name_len
)
{
/* Internally, old format < 4.0.18 constraints have as the
constraint id <number>_<number>, while new format constraints
have <databasename>/<constraintname>. */
err
=
que_eval_sql
(
info
,
"PROCEDURE RENAME_TABLE () IS
\n
"
"BEGIN
\n
"
"UPDATE SYS_TABLES SET NAME = :new_table_name
\n
"
" WHERE NAME = :old_table_name;
\n
"
"END;
\n
"
,
trx
);
for
(
i
=
0
;
i
<
n_constraints_to_drop
;
i
++
)
{
memcpy
(
sqlend
,
str4a1
,
(
sizeof
str4a1
)
-
1
);
sqlend
+=
(
sizeof
str4a1
)
-
1
;
sqlend
=
ut_memcpyq
(
sqlend
,
'\''
,
old_name
,
db_name_len
);
sqlend
=
ut_strcpyq
(
sqlend
,
'\''
,
constraints_to_drop
[
i
]);
memcpy
(
sqlend
,
str4a2
,
(
sizeof
str4a2
)
-
1
);
sqlend
+=
(
sizeof
str4a2
)
-
1
;
sqlend
=
ut_memcpyq
(
sqlend
,
'\''
,
old_name
,
db_name_len
);
sqlend
=
ut_strcpyq
(
sqlend
,
'\''
,
constraints_to_drop
[
i
]);
memcpy
(
sqlend
,
str4a3
,
(
sizeof
str4a3
)
-
1
);
sqlend
+=
(
sizeof
str4a3
)
-
1
;
if
(
!
strchr
(
constraints_to_drop
[
i
],
'/'
))
{
/* If this happens to be an old format
constraint, let us delete it. Since all new
format constraints contain '/', it does no
harm to run these DELETEs anyway. */
memcpy
(
sqlend
,
str4a1
,
(
sizeof
str4a1
)
-
1
);
sqlend
+=
(
sizeof
str4a1
)
-
1
;
sqlend
=
ut_strcpyq
(
sqlend
,
'\''
,
constraints_to_drop
[
i
]);
memcpy
(
sqlend
,
str4a2
,
(
sizeof
str4a2
)
-
1
);
sqlend
+=
(
sizeof
str4a2
)
-
1
;
sqlend
=
ut_strcpyq
(
sqlend
,
'\''
,
constraints_to_drop
[
i
]);
memcpy
(
sqlend
,
str4a3
,
(
sizeof
str4a3
)
-
1
);
sqlend
+=
(
sizeof
str4a3
)
-
1
;
}
}
}
else
{
memcpy
(
sqlend
,
str4b
,
(
sizeof
str4b
)
-
1
);
sqlend
+=
(
sizeof
str4b
)
-
1
;
}
if
(
err
!=
DB_SUCCESS
)
{
memcpy
(
sqlend
,
str5
,
sizeof
str5
)
;
sqlend
+=
sizeof
str5
;
goto
end
;
}
ut_a
(
sqlend
==
sql
+
len
+
1
);
if
(
!
new_is_tmp
)
{
/* Rename all constraints. */
graph
=
pars_sql
(
NULL
,
sql
);
info
=
pars_info_create
(
);
ut_a
(
graph
);
mem_free
(
sql
);
pars_info_add_str_literal
(
info
,
"new_table_name"
,
new_name
);
pars_info_add_str_literal
(
info
,
"old_table_name"
,
old_name
);
graph
->
trx
=
trx
;
trx
->
graph
=
NULL
;
err
=
que_eval_sql
(
info
,
"PROCEDURE RENAME_CONSTRAINT_IDS () IS
\n
"
"gen_constr_prefix CHAR;
\n
"
"new_db_name CHAR;
\n
"
"foreign_id CHAR;
\n
"
"new_foreign_id CHAR;
\n
"
"old_db_name_len INT;
\n
"
"old_t_name_len INT;
\n
"
"new_db_name_len INT;
\n
"
"id_len INT;
\n
"
"found INT;
\n
"
"BEGIN
\n
"
"found := 1;
\n
"
"old_db_name_len := INSTR(:old_table_name, '/') - 1;
\n
"
"new_db_name_len := INSTR(:new_table_name, '/') - 1;
\n
"
"new_db_name := SUBSTR(:new_table_name, 0, new_db_name_len);
\n
"
"old_t_name_len := LENGTH(:old_table_name);
\n
"
"gen_constr_prefix := CONCAT(:old_table_name, '_ibfk_');
\n
"
"WHILE found = 1 LOOP
\n
"
" SELECT ID INTO foreign_id
\n
"
" FROM SYS_FOREIGN
\n
"
" WHERE FOR_NAME = :old_table_name
\n
"
" AND TO_BINARY(FOR_NAME) = TO_BINARY(:old_table_name);
\n
"
" IF (SQL % NOTFOUND) THEN
\n
"
" found := 0;
\n
"
" ELSE
\n
"
" UPDATE SYS_FOREIGN
\n
"
" SET FOR_NAME = :new_table_name
\n
"
" WHERE ID = foreign_id;
\n
"
" id_len := LENGTH(foreign_id);
\n
"
" IF (INSTR(foreign_id, '/') > 0) THEN
\n
"
" IF (INSTR(foreign_id,
\n
"
" gen_constr_prefix) > 0)
\n
"
" THEN
\n
"
" new_foreign_id :=
\n
"
" CONCAT(:new_table_name,
\n
"
" SUBSTR(foreign_id, old_t_name_len,
\n
"
" id_len - old_t_name_len));
\n
"
" ELSE
\n
"
" new_foreign_id :=
\n
"
" CONCAT(new_db_name,
\n
"
" SUBSTR(foreign_id,
\n
"
" old_db_name_len,
\n
"
" id_len - old_db_name_len));
\n
"
" END IF;
\n
"
" UPDATE SYS_FOREIGN
\n
"
" SET ID = new_foreign_id
\n
"
" WHERE ID = foreign_id;
\n
"
" UPDATE SYS_FOREIGN_COLS
\n
"
" SET ID = new_foreign_id
\n
"
" WHERE ID = foreign_id;
\n
"
" END IF;
\n
"
" END IF;
\n
"
"END LOOP;
\n
"
"UPDATE SYS_FOREIGN SET REF_NAME = :new_table_name
\n
"
"WHERE REF_NAME = :old_table_name
\n
"
" AND TO_BINARY(REF_NAME) = TO_BINARY(:old_table_name);
\n
"
"END;
\n
"
,
trx
);
graph
->
fork_type
=
QUE_FORK_MYSQL_INTERFACE
;
}
else
if
(
n_constraints_to_drop
>
0
)
{
/* Drop some constraints of tmp tables. */
ut_a
(
thr
=
que_fork_start_command
(
graph
));
ulint
db_name_len
=
dict_get_db_name_len
(
old_name
)
+
1
;
char
*
db_name
=
mem_heap_strdupl
(
heap
,
old_name
,
db_name_len
);
ulint
i
;
que_run_threads
(
thr
);
for
(
i
=
0
;
i
<
n_constraints_to_drop
;
i
++
)
{
err
=
row_delete_constraint
(
constraints_to_drop
[
i
],
db_name
,
heap
,
trx
);
err
=
trx
->
error_state
;
if
(
err
!=
DB_SUCCESS
)
{
break
;
}
}
}
end:
if
(
err
!=
DB_SUCCESS
)
{
if
(
err
==
DB_DUPLICATE_KEY
)
{
ut_print_timestamp
(
stderr
);
...
...
@@ -3755,8 +3732,9 @@ row_rename_table_for_mysql(
/* The following call will also rename the .ibd data file if
the table is stored in a single-table tablespace */
success
=
dict_table_rename_in_cache
(
table
,
new_name
,
ibool
success
=
dict_table_rename_in_cache
(
table
,
new_name
,
!
new_is_tmp
);
if
(
!
success
)
{
trx
->
error_state
=
DB_SUCCESS
;
trx_general_rollback_for_mysql
(
trx
,
FALSE
,
NULL
);
...
...
@@ -3804,20 +3782,16 @@ row_rename_table_for_mysql(
ut_a
(
dict_table_rename_in_cache
(
table
,
old_name
,
FALSE
));
trx
->
error_state
=
DB_SUCCESS
;
trx_general_rollback_for_mysql
(
trx
,
FALSE
,
NULL
);
trx_general_rollback_for_mysql
(
trx
,
FALSE
,
NULL
);
trx
->
error_state
=
DB_SUCCESS
;
}
}
funct_exit:
if
(
!
recovering_temp_table
)
{
row_mysql_unlock_data_dictionary
(
trx
);
}
if
(
graph
)
{
que_graph_free
(
graph
);
}
if
(
UNIV_LIKELY_NULL
(
heap
))
{
mem_heap_free
(
heap
);
}
...
...
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