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
ce816b35
Commit
ce816b35
authored
Apr 07, 2004
by
ingo@mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Worklog#1563 - Support of on-line CREATE/DROP INDEX.
Corrected minor problems of the preceding changeset 1.1705.
parent
85ec87a0
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
591 additions
and
551 deletions
+591
-551
sql/sql_table.cc
sql/sql_table.cc
+591
-551
No files found.
sql/sql_table.cc
View file @
ce816b35
...
@@ -34,19 +34,19 @@ const char *primary_key_name= "PRIMARY";
...
@@ -34,19 +34,19 @@ const char *primary_key_name= "PRIMARY";
static
bool
check_if_keyname_exists
(
const
char
*
name
,
KEY
*
start
,
KEY
*
end
);
static
bool
check_if_keyname_exists
(
const
char
*
name
,
KEY
*
start
,
KEY
*
end
);
static
char
*
make_unique_key_name
(
const
char
*
field_name
,
KEY
*
start
,
KEY
*
end
);
static
char
*
make_unique_key_name
(
const
char
*
field_name
,
KEY
*
start
,
KEY
*
end
);
static
int
copy_data_between_tables
(
TABLE
*
from
,
TABLE
*
to
,
static
int
copy_data_between_tables
(
TABLE
*
from
,
TABLE
*
to
,
List
<
create_field
>
&
create
,
List
<
create_field
>
&
create
,
enum
enum_duplicates
handle_duplicates
,
enum
enum_duplicates
handle_duplicates
,
uint
order_num
,
ORDER
*
order
,
uint
order_num
,
ORDER
*
order
,
ha_rows
*
copied
,
ha_rows
*
deleted
);
ha_rows
*
copied
,
ha_rows
*
deleted
);
/*
/*
delete (drop) tables.
delete (drop) tables.
SYNOPSIS
SYNOPSIS
mysql_rm_table()
mysql_rm_table()
thd
Thread handle
thd
Thread handle
tables
List of tables to delete
tables
List of tables to delete
if_exists
If 1, don't give error if one table doesn't exists
if_exists
If 1, don't give error if one table doesn't exists
NOTES
NOTES
Will delete all tables that can be deleted and give a compact error
Will delete all tables that can be deleted and give a compact error
...
@@ -57,13 +57,13 @@ static int copy_data_between_tables(TABLE *from,TABLE *to,
...
@@ -57,13 +57,13 @@ static int copy_data_between_tables(TABLE *from,TABLE *to,
Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set.
Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set.
RETURN
RETURN
0
ok. In this case ok packet is sent to user
0
ok. In this case ok packet is sent to user
-1
Error (Error message given but not sent to user)
-1
Error (Error message given but not sent to user)
*/
*/
int
mysql_rm_table
(
THD
*
thd
,
TABLE_LIST
*
tables
,
my_bool
if_exists
,
int
mysql_rm_table
(
THD
*
thd
,
TABLE_LIST
*
tables
,
my_bool
if_exists
,
my_bool
drop_temporary
)
my_bool
drop_temporary
)
{
{
int
error
=
0
;
int
error
=
0
;
DBUG_ENTER
(
"mysql_rm_table"
);
DBUG_ENTER
(
"mysql_rm_table"
);
...
@@ -79,7 +79,7 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
...
@@ -79,7 +79,7 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
if
(
thd
->
global_read_lock
)
if
(
thd
->
global_read_lock
)
{
{
my_error
(
ER_TABLE_NOT_LOCKED_FOR_WRITE
,
MYF
(
0
),
my_error
(
ER_TABLE_NOT_LOCKED_FOR_WRITE
,
MYF
(
0
),
tables
->
real_name
);
tables
->
real_name
);
error
=
1
;
error
=
1
;
goto
err
;
goto
err
;
}
}
...
@@ -111,23 +111,23 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
...
@@ -111,23 +111,23 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
SYNOPSIS
SYNOPSIS
mysql_rm_table_part2_with_lock()
mysql_rm_table_part2_with_lock()
thd
Thread handle
thd
Thread handle
tables
List of tables to delete
tables
List of tables to delete
if_exists
If 1, don't give error if one table doesn't exists
if_exists
If 1, don't give error if one table doesn't exists
dont_log_query
Don't write query to log files
dont_log_query
Don't write query to log files
NOTES
NOTES
Works like documented in mysql_rm_table(), but don't check
Works like documented in mysql_rm_table(), but don't check
global_read_lock and don't send_ok packet to server.
global_read_lock and don't send_ok packet to server.
RETURN
RETURN
0
ok
0
ok
1
error
1
error
*/
*/
int
mysql_rm_table_part2_with_lock
(
THD
*
thd
,
int
mysql_rm_table_part2_with_lock
(
THD
*
thd
,
TABLE_LIST
*
tables
,
bool
if_exists
,
TABLE_LIST
*
tables
,
bool
if_exists
,
bool
drop_temporary
,
bool
dont_log_query
)
bool
drop_temporary
,
bool
dont_log_query
)
{
{
int
error
;
int
error
;
thd
->
mysys_var
->
current_mutex
=
&
LOCK_open
;
thd
->
mysys_var
->
current_mutex
=
&
LOCK_open
;
...
@@ -135,7 +135,7 @@ int mysql_rm_table_part2_with_lock(THD *thd,
...
@@ -135,7 +135,7 @@ int mysql_rm_table_part2_with_lock(THD *thd,
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
error
=
mysql_rm_table_part2
(
thd
,
tables
,
if_exists
,
drop_temporary
,
error
=
mysql_rm_table_part2
(
thd
,
tables
,
if_exists
,
drop_temporary
,
dont_log_query
);
dont_log_query
);
pthread_mutex_unlock
(
&
LOCK_open
);
pthread_mutex_unlock
(
&
LOCK_open
);
...
@@ -152,12 +152,12 @@ int mysql_rm_table_part2_with_lock(THD *thd,
...
@@ -152,12 +152,12 @@ int mysql_rm_table_part2_with_lock(THD *thd,
SYNOPSIS
SYNOPSIS
mysql_rm_table_part2()
mysql_rm_table_part2()
thd
Thread handler
thd
Thread handler
tables
Tables to drop
tables
Tables to drop
if_exists
If set, don't give an error if table doesn't exists.
if_exists
If set, don't give an error if table doesn't exists.
In this case we give an warning of level 'NOTE'
In this case we give an warning of level 'NOTE'
drop_temporary
Only drop temporary tables
drop_temporary
Only drop temporary tables
dont_log_query
Don't log the query
dont_log_query
Don't log the query
TODO:
TODO:
When logging to the binary log, we should log
When logging to the binary log, we should log
...
@@ -170,16 +170,16 @@ int mysql_rm_table_part2_with_lock(THD *thd,
...
@@ -170,16 +170,16 @@ int mysql_rm_table_part2_with_lock(THD *thd,
not all.
not all.
RETURN
RETURN
0
ok
0
ok
1
Error
1
Error
-1
Thread was killed
-1
Thread was killed
*/
*/
int
mysql_rm_table_part2
(
THD
*
thd
,
TABLE_LIST
*
tables
,
bool
if_exists
,
int
mysql_rm_table_part2
(
THD
*
thd
,
TABLE_LIST
*
tables
,
bool
if_exists
,
bool
drop_temporary
,
bool
dont_log_query
)
bool
drop_temporary
,
bool
dont_log_query
)
{
{
TABLE_LIST
*
table
;
TABLE_LIST
*
table
;
char
path
[
FN_REFLEN
],
*
alias
;
char
path
[
FN_REFLEN
],
*
alias
;
String
wrong_tables
;
String
wrong_tables
;
int
error
;
int
error
;
bool
some_tables_deleted
=
0
,
tmp_table_deleted
=
0
,
foreign_key_error
=
0
;
bool
some_tables_deleted
=
0
,
tmp_table_deleted
=
0
,
foreign_key_error
=
0
;
...
@@ -195,7 +195,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
...
@@ -195,7 +195,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
if
(
!
close_temporary_table
(
thd
,
db
,
table
->
real_name
))
if
(
!
close_temporary_table
(
thd
,
db
,
table
->
real_name
))
{
{
tmp_table_deleted
=
1
;
tmp_table_deleted
=
1
;
continue
;
// removed temporary table
continue
;
// removed temporary table
}
}
error
=
0
;
error
=
0
;
...
@@ -204,13 +204,13 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
...
@@ -204,13 +204,13 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
abort_locked_tables
(
thd
,
db
,
table
->
real_name
);
abort_locked_tables
(
thd
,
db
,
table
->
real_name
);
while
(
remove_table_from_cache
(
thd
,
db
,
table
->
real_name
)
&&
!
thd
->
killed
)
while
(
remove_table_from_cache
(
thd
,
db
,
table
->
real_name
)
&&
!
thd
->
killed
)
{
{
dropping_tables
++
;
dropping_tables
++
;
(
void
)
pthread_cond_wait
(
&
COND_refresh
,
&
LOCK_open
);
(
void
)
pthread_cond_wait
(
&
COND_refresh
,
&
LOCK_open
);
dropping_tables
--
;
dropping_tables
--
;
}
}
drop_locked_tables
(
thd
,
db
,
table
->
real_name
);
drop_locked_tables
(
thd
,
db
,
table
->
real_name
);
if
(
thd
->
killed
)
if
(
thd
->
killed
)
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
alias
=
(
lower_case_table_names
==
2
)
?
table
->
alias
:
table
->
real_name
;
alias
=
(
lower_case_table_names
==
2
)
?
table
->
alias
:
table
->
real_name
;
/* remove form file and isam files */
/* remove form file and isam files */
strxmov
(
path
,
mysql_data_home
,
"/"
,
db
,
"/"
,
alias
,
reg_ext
,
NullS
);
strxmov
(
path
,
mysql_data_home
,
"/"
,
db
,
"/"
,
alias
,
reg_ext
,
NullS
);
...
@@ -219,9 +219,9 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
...
@@ -219,9 +219,9 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
if
(
drop_temporary
||
access
(
path
,
F_OK
))
if
(
drop_temporary
||
access
(
path
,
F_OK
))
{
{
if
(
if_exists
)
if
(
if_exists
)
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_NOTE
,
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_NOTE
,
ER_BAD_TABLE_ERROR
,
ER
(
ER_BAD_TABLE_ERROR
),
ER_BAD_TABLE_ERROR
,
ER
(
ER_BAD_TABLE_ERROR
),
table
->
real_name
);
table
->
real_name
);
else
else
error
=
1
;
error
=
1
;
}
}
...
@@ -229,27 +229,27 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
...
@@ -229,27 +229,27 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
{
{
char
*
end
;
char
*
end
;
db_type
table_type
=
get_table_type
(
path
);
db_type
table_type
=
get_table_type
(
path
);
*
(
end
=
fn_ext
(
path
))
=
0
;
// Remove extension for delete
*
(
end
=
fn_ext
(
path
))
=
0
;
// Remove extension for delete
error
=
ha_delete_table
(
table_type
,
path
);
error
=
ha_delete_table
(
table_type
,
path
);
if
(
error
==
ENOENT
&&
if_exists
)
if
(
error
==
ENOENT
&&
if_exists
)
error
=
0
;
error
=
0
;
if
(
error
==
HA_ERR_ROW_IS_REFERENCED
)
if
(
error
==
HA_ERR_ROW_IS_REFERENCED
)
{
{
/* the table is referenced by a foreign key constraint */
/* the table is referenced by a foreign key constraint */
foreign_key_error
=
1
;
foreign_key_error
=
1
;
}
}
if
(
!
error
||
error
==
ENOENT
)
if
(
!
error
||
error
==
ENOENT
)
{
{
/* Delete the table definition file */
/* Delete the table definition file */
strmov
(
end
,
reg_ext
);
strmov
(
end
,
reg_ext
);
if
(
!
(
error
=
my_delete
(
path
,
MYF
(
MY_WME
))))
if
(
!
(
error
=
my_delete
(
path
,
MYF
(
MY_WME
))))
some_tables_deleted
=
1
;
some_tables_deleted
=
1
;
}
}
}
}
if
(
error
)
if
(
error
)
{
{
if
(
wrong_tables
.
length
())
if
(
wrong_tables
.
length
())
wrong_tables
.
append
(
','
);
wrong_tables
.
append
(
','
);
wrong_tables
.
append
(
String
(
table
->
real_name
,
system_charset_info
));
wrong_tables
.
append
(
String
(
table
->
real_name
,
system_charset_info
));
}
}
}
}
...
@@ -263,9 +263,9 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
...
@@ -263,9 +263,9 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
if
(
mysql_bin_log
.
is_open
())
if
(
mysql_bin_log
.
is_open
())
{
{
thd
->
clear_error
();
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
tmp_table_deleted
&&
!
some_tables_deleted
);
tmp_table_deleted
&&
!
some_tables_deleted
);
mysql_bin_log
.
write
(
&
qinfo
);
mysql_bin_log
.
write
(
&
qinfo
);
}
}
}
}
}
}
...
@@ -285,15 +285,19 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
...
@@ -285,15 +285,19 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
int
quick_rm_table
(
enum
db_type
base
,
const
char
*
db
,
int
quick_rm_table
(
enum
db_type
base
,
const
char
*
db
,
const
char
*
table_name
)
const
char
*
table_name
)
{
{
char
path
[
FN_REFLEN
];
char
path
[
FN_REFLEN
];
int
error
=
0
;
int
error
=
0
;
(
void
)
sprintf
(
path
,
"%s/%s/%s%s"
,
mysql_data_home
,
db
,
table_name
,
reg_ext
);
if
(
snprintf
(
path
,
sizeof
(
path
),
"%s/%s/%s%s"
,
mysql_data_home
,
db
,
table_name
,
reg_ext
)
>=
(
int
)
sizeof
(
path
))
return
1
;
unpack_filename
(
path
,
path
);
unpack_filename
(
path
,
path
);
if
(
my_delete
(
path
,
MYF
(
0
)))
if
(
my_delete
(
path
,
MYF
(
0
)))
error
=
1
;
/* purecov: inspected */
error
=
1
;
/* purecov: inspected */
sprintf
(
path
,
"%s/%s/%s"
,
mysql_data_home
,
db
,
table_name
);
if
(
snprintf
(
path
,
sizeof
(
path
),
"%s/%s/%s"
,
mysql_data_home
,
db
,
table_name
)
>=
(
int
)
sizeof
(
path
))
return
1
;
unpack_filename
(
path
,
path
);
unpack_filename
(
path
,
path
);
return
ha_delete_table
(
base
,
path
)
||
error
;
return
ha_delete_table
(
base
,
path
)
||
error
;
}
}
...
@@ -327,7 +331,7 @@ static int sort_keys(KEY *a, KEY *b)
...
@@ -327,7 +331,7 @@ static int sort_keys(KEY *a, KEY *b)
return
1
;
return
1
;
}
}
else
if
(
b
->
flags
&
HA_NOSAME
)
else
if
(
b
->
flags
&
HA_NOSAME
)
return
1
;
// Prefer b
return
1
;
// Prefer b
if
((
a
->
flags
^
b
->
flags
)
&
HA_FULLTEXT
)
if
((
a
->
flags
^
b
->
flags
)
&
HA_FULLTEXT
)
{
{
...
@@ -338,8 +342,8 @@ static int sort_keys(KEY *a, KEY *b)
...
@@ -338,8 +342,8 @@ static int sort_keys(KEY *a, KEY *b)
the original key position.
the original key position.
*/
*/
return
((
a
->
usable_key_parts
<
b
->
usable_key_parts
)
?
-
1
:
return
((
a
->
usable_key_parts
<
b
->
usable_key_parts
)
?
-
1
:
(
a
->
usable_key_parts
>
b
->
usable_key_parts
)
?
1
:
(
a
->
usable_key_parts
>
b
->
usable_key_parts
)
?
1
:
0
);
0
);
}
}
/*
/*
...
@@ -360,7 +364,7 @@ static int sort_keys(KEY *a, KEY *b)
...
@@ -360,7 +364,7 @@ static int sort_keys(KEY *a, KEY *b)
*/
*/
void
check_duplicates_in_interval
(
const
char
*
set_or_name
,
void
check_duplicates_in_interval
(
const
char
*
set_or_name
,
const
char
*
name
,
TYPELIB
*
typelib
)
const
char
*
name
,
TYPELIB
*
typelib
)
{
{
unsigned
int
old_count
=
typelib
->
count
;
unsigned
int
old_count
=
typelib
->
count
;
const
char
**
old_type_names
=
typelib
->
type_names
;
const
char
**
old_type_names
=
typelib
->
type_names
;
...
@@ -375,9 +379,9 @@ void check_duplicates_in_interval(const char *set_or_name,
...
@@ -375,9 +379,9 @@ void check_duplicates_in_interval(const char *set_or_name,
if
(
find_type
((
char
*
)
*
cur_value
,
typelib
,
1
))
if
(
find_type
((
char
*
)
*
cur_value
,
typelib
,
1
))
{
{
push_warning_printf
(
current_thd
,
MYSQL_ERROR
::
WARN_LEVEL_NOTE
,
push_warning_printf
(
current_thd
,
MYSQL_ERROR
::
WARN_LEVEL_NOTE
,
ER_DUPLICATED_VALUE_IN_TYPE
,
ER_DUPLICATED_VALUE_IN_TYPE
,
ER
(
ER_DUPLICATED_VALUE_IN_TYPE
),
ER
(
ER_DUPLICATED_VALUE_IN_TYPE
),
name
,
*
cur_value
,
set_or_name
);
name
,
*
cur_value
,
set_or_name
);
}
}
}
}
typelib
->
count
=
old_count
;
typelib
->
count
=
old_count
;
...
@@ -389,33 +393,33 @@ void check_duplicates_in_interval(const char *set_or_name,
...
@@ -389,33 +393,33 @@ void check_duplicates_in_interval(const char *set_or_name,
SYNOPSIS
SYNOPSIS
mysql_prepare_table()
mysql_prepare_table()
thd
Thread object
thd
Thread object
create_info
Create information (like MAX_ROWS)
create_info
Create information (like MAX_ROWS)
fields
List of fields to create
fields
List of fields to create
keys
List of keys to create
keys
List of keys to create
DESCRIPTION
DESCRIPTION
Prepares the table and key structures for table creation.
Prepares the table and key structures for table creation.
RETURN VALUES
RETURN VALUES
0
ok
0
ok
-1
error
-1
error
*/
*/
int
mysql_prepare_table
(
THD
*
thd
,
HA_CREATE_INFO
*
create_info
,
int
mysql_prepare_table
(
THD
*
thd
,
HA_CREATE_INFO
*
create_info
,
List
<
create_field
>
&
fields
,
List
<
create_field
>
&
fields
,
List
<
Key
>
&
keys
,
bool
tmp_table
,
uint
&
db_options
,
List
<
Key
>
&
keys
,
bool
tmp_table
,
uint
&
db_options
,
handler
*
file
,
KEY
*&
key_info_buffer
,
handler
*
file
,
KEY
*&
key_info_buffer
,
uint
&
key_count
,
int
select_field_count
)
uint
&
key_count
,
int
select_field_count
)
{
{
const
char
*
key_name
;
const
char
*
key_name
;
create_field
*
sql_field
,
*
dup_field
;
create_field
*
sql_field
,
*
dup_field
;
uint
field
,
null_fields
,
blob_columns
;
uint
field
,
null_fields
,
blob_columns
;
ulong
pos
;
ulong
pos
;
KEY
*
key_info
;
KEY
*
key_info
;
KEY_PART_INFO
*
key_part_info
;
KEY_PART_INFO
*
key_part_info
;
int
field_no
,
dup_no
;
int
field_no
,
dup_no
;
int
select_field_pos
,
auto_increment
=
0
;
int
select_field_pos
,
auto_increment
=
0
;
DBUG_ENTER
(
"mysql_prepare_table"
);
DBUG_ENTER
(
"mysql_prepare_table"
);
List_iterator
<
create_field
>
it
(
fields
),
it2
(
fields
);
List_iterator
<
create_field
>
it
(
fields
),
it2
(
fields
);
...
@@ -438,8 +442,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -438,8 +442,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
/* Don't pack keys in old tables if the user has requested this */
/* Don't pack keys in old tables if the user has requested this */
if
((
sql_field
->
flags
&
BLOB_FLAG
)
||
if
((
sql_field
->
flags
&
BLOB_FLAG
)
||
sql_field
->
sql_type
==
FIELD_TYPE_VAR_STRING
&&
sql_field
->
sql_type
==
FIELD_TYPE_VAR_STRING
&&
create_info
->
row_type
!=
ROW_TYPE_FIXED
)
create_info
->
row_type
!=
ROW_TYPE_FIXED
)
{
{
db_options
|=
HA_OPTION_PACK_RECORD
;
db_options
|=
HA_OPTION_PACK_RECORD
;
}
}
...
@@ -459,10 +463,10 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -459,10 +463,10 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
sql_field
->
field_name
,
sql_field
->
field_name
,
dup_field
->
field_name
)
==
0
)
dup_field
->
field_name
)
==
0
)
{
{
/*
/*
If this was a CREATE ... SELECT statement, accept a field
If this was a CREATE ... SELECT statement, accept a field
redefinition if we are changing a field in the SELECT part
redefinition if we are changing a field in the SELECT part
*/
*/
if
(
field_no
<
select_field_pos
||
dup_no
>=
select_field_pos
)
if
(
field_no
<
select_field_pos
||
dup_no
>=
select_field_pos
)
{
{
my_error
(
ER_DUP_FIELDNAME
,
MYF
(
0
),
sql_field
->
field_name
);
my_error
(
ER_DUP_FIELDNAME
,
MYF
(
0
),
sql_field
->
field_name
);
...
@@ -470,20 +474,20 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -470,20 +474,20 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
}
}
else
else
{
{
/* Field redefined */
/* Field redefined */
sql_field
->
sql_type
=
dup_field
->
sql_type
;
sql_field
->
sql_type
=
dup_field
->
sql_type
;
sql_field
->
charset
=
(
dup_field
->
charset
?
sql_field
->
charset
=
(
dup_field
->
charset
?
dup_field
->
charset
:
dup_field
->
charset
:
create_info
->
default_table_charset
);
create_info
->
default_table_charset
);
sql_field
->
length
=
dup_field
->
length
;
sql_field
->
length
=
dup_field
->
length
;
sql_field
->
pack_length
=
dup_field
->
pack_length
;
sql_field
->
pack_length
=
dup_field
->
pack_length
;
sql_field
->
create_length_to_internal_length
();
sql_field
->
create_length_to_internal_length
();
sql_field
->
decimals
=
dup_field
->
decimals
;
sql_field
->
decimals
=
dup_field
->
decimals
;
sql_field
->
flags
=
dup_field
->
flags
;
sql_field
->
flags
=
dup_field
->
flags
;
sql_field
->
unireg_check
=
dup_field
->
unireg_check
;
sql_field
->
unireg_check
=
dup_field
->
unireg_check
;
it2
.
remove
();
// Remove first (create) definition
it2
.
remove
();
// Remove first (create) definition
select_field_pos
--
;
select_field_pos
--
;
break
;
break
;
}
}
}
}
}
}
...
@@ -505,11 +509,11 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -505,11 +509,11 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
case
FIELD_TYPE_TINY_BLOB
:
case
FIELD_TYPE_TINY_BLOB
:
case
FIELD_TYPE_LONG_BLOB
:
case
FIELD_TYPE_LONG_BLOB
:
sql_field
->
pack_flag
=
FIELDFLAG_BLOB
|
sql_field
->
pack_flag
=
FIELDFLAG_BLOB
|
pack_length_to_packflag
(
sql_field
->
pack_length
-
pack_length_to_packflag
(
sql_field
->
pack_length
-
portable_sizeof_char_ptr
);
portable_sizeof_char_ptr
);
if
(
sql_field
->
charset
->
state
&
MY_CS_BINSORT
)
if
(
sql_field
->
charset
->
state
&
MY_CS_BINSORT
)
sql_field
->
pack_flag
|=
FIELDFLAG_BINARY
;
sql_field
->
pack_flag
|=
FIELDFLAG_BINARY
;
sql_field
->
length
=
8
;
// Unireg field length
sql_field
->
length
=
8
;
// Unireg field length
sql_field
->
unireg_check
=
Field
::
BLOB_FIELD
;
sql_field
->
unireg_check
=
Field
::
BLOB_FIELD
;
blob_columns
++
;
blob_columns
++
;
break
;
break
;
...
@@ -517,49 +521,49 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -517,49 +521,49 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
#ifdef HAVE_SPATIAL
#ifdef HAVE_SPATIAL
if
(
!
(
file
->
table_flags
()
&
HA_HAS_GEOMETRY
))
if
(
!
(
file
->
table_flags
()
&
HA_HAS_GEOMETRY
))
{
{
my_printf_error
(
ER_CHECK_NOT_IMPLEMENTED
,
ER
(
ER_CHECK_NOT_IMPLEMENTED
),
my_printf_error
(
ER_CHECK_NOT_IMPLEMENTED
,
ER
(
ER_CHECK_NOT_IMPLEMENTED
),
MYF
(
0
),
"GEOMETRY"
);
MYF
(
0
),
"GEOMETRY"
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
sql_field
->
pack_flag
=
FIELDFLAG_GEOM
|
sql_field
->
pack_flag
=
FIELDFLAG_GEOM
|
pack_length_to_packflag
(
sql_field
->
pack_length
-
pack_length_to_packflag
(
sql_field
->
pack_length
-
portable_sizeof_char_ptr
);
portable_sizeof_char_ptr
);
if
(
sql_field
->
charset
->
state
&
MY_CS_BINSORT
)
if
(
sql_field
->
charset
->
state
&
MY_CS_BINSORT
)
sql_field
->
pack_flag
|=
FIELDFLAG_BINARY
;
sql_field
->
pack_flag
|=
FIELDFLAG_BINARY
;
sql_field
->
length
=
8
;
// Unireg field length
sql_field
->
length
=
8
;
// Unireg field length
sql_field
->
unireg_check
=
Field
::
BLOB_FIELD
;
sql_field
->
unireg_check
=
Field
::
BLOB_FIELD
;
blob_columns
++
;
blob_columns
++
;
break
;
break
;
#else
#else
my_printf_error
(
ER_FEATURE_DISABLED
,
ER
(
ER_FEATURE_DISABLED
),
MYF
(
0
),
my_printf_error
(
ER_FEATURE_DISABLED
,
ER
(
ER_FEATURE_DISABLED
),
MYF
(
0
),
sym_group_geom
.
name
,
sym_group_geom
.
needed_define
);
sym_group_geom
.
name
,
sym_group_geom
.
needed_define
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
#endif
/*HAVE_SPATIAL*/
#endif
/*HAVE_SPATIAL*/
case
FIELD_TYPE_VAR_STRING
:
case
FIELD_TYPE_VAR_STRING
:
case
FIELD_TYPE_STRING
:
case
FIELD_TYPE_STRING
:
sql_field
->
pack_flag
=
0
;
sql_field
->
pack_flag
=
0
;
if
(
sql_field
->
charset
->
state
&
MY_CS_BINSORT
)
if
(
sql_field
->
charset
->
state
&
MY_CS_BINSORT
)
sql_field
->
pack_flag
|=
FIELDFLAG_BINARY
;
sql_field
->
pack_flag
|=
FIELDFLAG_BINARY
;
break
;
break
;
case
FIELD_TYPE_ENUM
:
case
FIELD_TYPE_ENUM
:
sql_field
->
pack_flag
=
pack_length_to_packflag
(
sql_field
->
pack_length
)
|
sql_field
->
pack_flag
=
pack_length_to_packflag
(
sql_field
->
pack_length
)
|
FIELDFLAG_INTERVAL
;
FIELDFLAG_INTERVAL
;
if
(
sql_field
->
charset
->
state
&
MY_CS_BINSORT
)
if
(
sql_field
->
charset
->
state
&
MY_CS_BINSORT
)
sql_field
->
pack_flag
|=
FIELDFLAG_BINARY
;
sql_field
->
pack_flag
|=
FIELDFLAG_BINARY
;
sql_field
->
unireg_check
=
Field
::
INTERVAL_FIELD
;
sql_field
->
unireg_check
=
Field
::
INTERVAL_FIELD
;
check_duplicates_in_interval
(
"ENUM"
,
sql_field
->
field_name
,
check_duplicates_in_interval
(
"ENUM"
,
sql_field
->
field_name
,
sql_field
->
interval
);
sql_field
->
interval
);
break
;
break
;
case
FIELD_TYPE_SET
:
case
FIELD_TYPE_SET
:
sql_field
->
pack_flag
=
pack_length_to_packflag
(
sql_field
->
pack_length
)
|
sql_field
->
pack_flag
=
pack_length_to_packflag
(
sql_field
->
pack_length
)
|
FIELDFLAG_BITFIELD
;
FIELDFLAG_BITFIELD
;
if
(
sql_field
->
charset
->
state
&
MY_CS_BINSORT
)
if
(
sql_field
->
charset
->
state
&
MY_CS_BINSORT
)
sql_field
->
pack_flag
|=
FIELDFLAG_BINARY
;
sql_field
->
pack_flag
|=
FIELDFLAG_BINARY
;
sql_field
->
unireg_check
=
Field
::
BIT_FIELD
;
sql_field
->
unireg_check
=
Field
::
BIT_FIELD
;
check_duplicates_in_interval
(
"SET"
,
sql_field
->
field_name
,
check_duplicates_in_interval
(
"SET"
,
sql_field
->
field_name
,
sql_field
->
interval
);
sql_field
->
interval
);
break
;
break
;
case
FIELD_TYPE_DATE
:
// Rest of string types
case
FIELD_TYPE_DATE
:
// Rest of string types
case
FIELD_TYPE_NEWDATE
:
case
FIELD_TYPE_NEWDATE
:
case
FIELD_TYPE_TIME
:
case
FIELD_TYPE_TIME
:
case
FIELD_TYPE_DATETIME
:
case
FIELD_TYPE_DATETIME
:
...
@@ -571,12 +575,12 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -571,12 +575,12 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
/* fall through */
/* fall through */
default:
default:
sql_field
->
pack_flag
=
(
FIELDFLAG_NUMBER
|
sql_field
->
pack_flag
=
(
FIELDFLAG_NUMBER
|
(
sql_field
->
flags
&
UNSIGNED_FLAG
?
0
:
(
sql_field
->
flags
&
UNSIGNED_FLAG
?
0
:
FIELDFLAG_DECIMAL
)
|
FIELDFLAG_DECIMAL
)
|
(
sql_field
->
flags
&
ZEROFILL_FLAG
?
(
sql_field
->
flags
&
ZEROFILL_FLAG
?
FIELDFLAG_ZEROFILL
:
0
)
|
FIELDFLAG_ZEROFILL
:
0
)
|
f_settype
((
uint
)
sql_field
->
sql_type
)
|
f_settype
((
uint
)
sql_field
->
sql_type
)
|
(
sql_field
->
decimals
<<
FIELDFLAG_DEC_SHIFT
));
(
sql_field
->
decimals
<<
FIELDFLAG_DEC_SHIFT
));
break
;
break
;
}
}
if
(
!
(
sql_field
->
flags
&
NOT_NULL_FLAG
))
if
(
!
(
sql_field
->
flags
&
NOT_NULL_FLAG
))
...
@@ -608,7 +612,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -608,7 +612,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
List_iterator
<
Key
>
key_iterator
(
keys
);
List_iterator
<
Key
>
key_iterator
(
keys
);
uint
key_parts
=
0
,
fk_key_count
=
0
;
uint
key_parts
=
0
,
fk_key_count
=
0
;
List
<
Key
>
keys_in_order
;
// Add new keys here
List
<
Key
>
keys_in_order
;
// Add new keys here
bool
primary_key
=
0
,
unique_key
=
0
;
bool
primary_key
=
0
,
unique_key
=
0
;
Key
*
key
;
Key
*
key
;
uint
tmp
,
key_number
;
uint
tmp
,
key_number
;
...
@@ -623,12 +627,12 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -623,12 +627,12 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
fk_key_count
++
;
fk_key_count
++
;
foreign_key
*
fk_key
=
(
foreign_key
*
)
key
;
foreign_key
*
fk_key
=
(
foreign_key
*
)
key
;
if
(
fk_key
->
ref_columns
.
elements
&&
if
(
fk_key
->
ref_columns
.
elements
&&
fk_key
->
ref_columns
.
elements
!=
fk_key
->
columns
.
elements
)
fk_key
->
ref_columns
.
elements
!=
fk_key
->
columns
.
elements
)
{
{
my_error
(
ER_WRONG_FK_DEF
,
MYF
(
0
),
fk_key
->
name
?
fk_key
->
name
:
my_error
(
ER_WRONG_FK_DEF
,
MYF
(
0
),
fk_key
->
name
?
fk_key
->
name
:
"foreign key without name"
,
"foreign key without name"
,
ER
(
ER_KEY_REF_DO_NOT_MATCH_TABLE_REF
));
ER
(
ER_KEY_REF_DO_NOT_MATCH_TABLE_REF
));
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
continue
;
continue
;
}
}
...
@@ -646,7 +650,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -646,7 +650,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
}
}
key_parts
+=
key
->
columns
.
elements
;
key_parts
+=
key
->
columns
.
elements
;
if
(
key
->
name
&&
!
tmp_table
&&
if
(
key
->
name
&&
!
tmp_table
&&
!
my_strcasecmp
(
system_charset_info
,
key
->
name
,
primary_key_name
))
!
my_strcasecmp
(
system_charset_info
,
key
->
name
,
primary_key_name
))
{
{
my_error
(
ER_WRONG_NAME_FOR_INDEX
,
MYF
(
0
),
key
->
name
);
my_error
(
ER_WRONG_NAME_FOR_INDEX
,
MYF
(
0
),
key
->
name
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
...
@@ -662,7 +666,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -662,7 +666,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
key_info_buffer
=
key_info
=
(
KEY
*
)
sql_calloc
(
sizeof
(
KEY
)
*
key_count
);
key_info_buffer
=
key_info
=
(
KEY
*
)
sql_calloc
(
sizeof
(
KEY
)
*
key_count
);
key_part_info
=
(
KEY_PART_INFO
*
)
sql_calloc
(
sizeof
(
KEY_PART_INFO
)
*
key_parts
);
key_part_info
=
(
KEY_PART_INFO
*
)
sql_calloc
(
sizeof
(
KEY_PART_INFO
)
*
key_parts
);
if
(
!
key_info_buffer
||
!
key_part_info
)
if
(
!
key_info_buffer
||
!
key_part_info
)
DBUG_RETURN
(
-
1
);
// Out of memory
DBUG_RETURN
(
-
1
);
// Out of memory
key_iterator
.
rewind
();
key_iterator
.
rewind
();
key_number
=
0
;
key_number
=
0
;
...
@@ -683,12 +687,12 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -683,12 +687,12 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
key_info
->
flags
=
HA_SPATIAL
;
key_info
->
flags
=
HA_SPATIAL
;
break
;
break
;
#else
#else
my_printf_error
(
ER_FEATURE_DISABLED
,
ER
(
ER_FEATURE_DISABLED
),
MYF
(
0
),
my_printf_error
(
ER_FEATURE_DISABLED
,
ER
(
ER_FEATURE_DISABLED
),
MYF
(
0
),
sym_group_geom
.
name
,
sym_group_geom
.
needed_define
);
sym_group_geom
.
name
,
sym_group_geom
.
needed_define
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
#endif
#endif
case
Key
:
:
FOREIGN_KEY
:
case
Key
:
:
FOREIGN_KEY
:
key_number
--
;
// Skip this key
key_number
--
;
// Skip this key
continue
;
continue
;
default:
default:
key_info
->
flags
=
HA_NOSAME
;
key_info
->
flags
=
HA_NOSAME
;
...
@@ -731,17 +735,17 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -731,17 +735,17 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
#ifdef HAVE_RTREE_KEYS
#ifdef HAVE_RTREE_KEYS
if
((
key_info
->
key_parts
&
1
)
==
1
)
if
((
key_info
->
key_parts
&
1
)
==
1
)
{
{
my_printf_error
(
ER_WRONG_ARGUMENTS
,
my_printf_error
(
ER_WRONG_ARGUMENTS
,
ER
(
ER_WRONG_ARGUMENTS
),
MYF
(
0
),
"RTREE INDEX"
);
ER
(
ER_WRONG_ARGUMENTS
),
MYF
(
0
),
"RTREE INDEX"
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
/* TODO: To be deleted */
/* TODO: To be deleted */
my_printf_error
(
ER_NOT_SUPPORTED_YET
,
ER
(
ER_NOT_SUPPORTED_YET
),
my_printf_error
(
ER_NOT_SUPPORTED_YET
,
ER
(
ER_NOT_SUPPORTED_YET
),
MYF
(
0
),
"RTREE INDEX"
);
MYF
(
0
),
"RTREE INDEX"
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
#else
#else
my_printf_error
(
ER_FEATURE_DISABLED
,
ER
(
ER_FEATURE_DISABLED
),
MYF
(
0
),
my_printf_error
(
ER_FEATURE_DISABLED
,
ER
(
ER_FEATURE_DISABLED
),
MYF
(
0
),
sym_group_rtree
.
name
,
sym_group_rtree
.
needed_define
);
sym_group_rtree
.
name
,
sym_group_rtree
.
needed_define
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
#endif
#endif
}
}
...
@@ -753,16 +757,16 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -753,16 +757,16 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
it
.
rewind
();
it
.
rewind
();
field
=
0
;
field
=
0
;
while
((
sql_field
=
it
++
)
&&
while
((
sql_field
=
it
++
)
&&
my_strcasecmp
(
system_charset_info
,
my_strcasecmp
(
system_charset_info
,
column
->
field_name
,
column
->
field_name
,
sql_field
->
field_name
))
sql_field
->
field_name
))
field
++
;
field
++
;
if
(
!
sql_field
)
if
(
!
sql_field
)
{
{
my_printf_error
(
ER_KEY_COLUMN_DOES_NOT_EXITS
,
my_printf_error
(
ER_KEY_COLUMN_DOES_NOT_EXITS
,
ER
(
ER_KEY_COLUMN_DOES_NOT_EXITS
),
MYF
(
0
),
ER
(
ER_KEY_COLUMN_DOES_NOT_EXITS
),
MYF
(
0
),
column
->
field_name
);
column
->
field_name
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
/* for fulltext keys keyseg length is 1 for blobs (it's ignored in
/* for fulltext keys keyseg length is 1 for blobs (it's ignored in
ft code anyway, and 0 (set to column width later) for char's.
ft code anyway, and 0 (set to column width later) for char's.
...
@@ -851,7 +855,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -851,7 +855,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
if
(
MTYP_TYPENR
(
sql_field
->
unireg_check
)
==
Field
::
NEXT_NUMBER
)
if
(
MTYP_TYPENR
(
sql_field
->
unireg_check
)
==
Field
::
NEXT_NUMBER
)
{
{
if
(
column_nr
==
0
||
(
file
->
table_flags
()
&
HA_AUTO_PART_KEY
))
if
(
column_nr
==
0
||
(
file
->
table_flags
()
&
HA_AUTO_PART_KEY
))
auto_increment
--
;
// Field is used
auto_increment
--
;
// Field is used
}
}
}
}
...
@@ -861,17 +865,19 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -861,17 +865,19 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
uint
length
=
sql_field
->
pack_length
;
uint
length
=
sql_field
->
pack_length
;
if
(
column
->
length
)
if
(
column
->
length
)
{
{
if
(
f_is_blob
(
sql_field
->
pack_flag
))
if
(
f_is_blob
(
sql_field
->
pack_flag
))
{
{
if
((
length
=
column
->
length
)
>
file
->
max_key_length
()
||
if
((
length
=
column
->
length
)
>
file
->
max_key_length
()
||
length
>
file
->
max_key_part_length
())
length
>
file
->
max_key_part_length
())
{
{
length
=
min
(
file
->
max_key_length
(),
file
->
max_key_part_length
());
length
=
min
(
file
->
max_key_length
(),
file
->
max_key_part_length
());
if
(
key
->
type
==
Key
::
MULTIPLE
)
if
(
key
->
type
==
Key
::
MULTIPLE
)
{
{
/* not a critical problem */
/* not a critical problem */
char
warn_buff
[
MYSQL_ERRMSG_SIZE
];
char
warn_buff
[
MYSQL_ERRMSG_SIZE
];
sprintf
(
warn_buff
,
ER
(
ER_TOO_LONG_KEY
),
length
);
if
(
snprintf
(
warn_buff
,
sizeof
(
warn_buff
),
ER
(
ER_TOO_LONG_KEY
),
length
)
>=
(
int
)
sizeof
(
warn_buff
))
DBUG_RETURN
(
-
1
);
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_TOO_LONG_KEY
,
warn_buff
);
ER_TOO_LONG_KEY
,
warn_buff
);
}
}
...
@@ -881,8 +887,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -881,8 +887,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
}
}
}
}
else
if
(
!
f_is_geom
(
sql_field
->
pack_flag
)
&&
else
if
(
!
f_is_geom
(
sql_field
->
pack_flag
)
&&
(
column
->
length
>
length
||
(
column
->
length
>
length
||
((
f_is_packed
(
sql_field
->
pack_flag
)
||
((
f_is_packed
(
sql_field
->
pack_flag
)
||
((
file
->
table_flags
()
&
HA_NO_PREFIX_CHAR_KEYS
)
&&
((
file
->
table_flags
()
&
HA_NO_PREFIX_CHAR_KEYS
)
&&
...
@@ -897,9 +903,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -897,9 +903,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
}
}
else
if
(
length
==
0
)
else
if
(
length
==
0
)
{
{
my_printf_error
(
ER_WRONG_KEY_COLUMN
,
ER
(
ER_WRONG_KEY_COLUMN
),
MYF
(
0
),
my_printf_error
(
ER_WRONG_KEY_COLUMN
,
ER
(
ER_WRONG_KEY_COLUMN
),
MYF
(
0
),
column
->
field_name
);
column
->
field_name
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
if
(
length
>
file
->
max_key_part_length
())
if
(
length
>
file
->
max_key_part_length
())
{
{
...
@@ -908,7 +914,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -908,7 +914,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
{
{
/* not a critical problem */
/* not a critical problem */
char
warn_buff
[
MYSQL_ERRMSG_SIZE
];
char
warn_buff
[
MYSQL_ERRMSG_SIZE
];
sprintf
(
warn_buff
,
ER
(
ER_TOO_LONG_KEY
),
length
);
if
(
snprintf
(
warn_buff
,
sizeof
(
warn_buff
),
ER
(
ER_TOO_LONG_KEY
),
length
)
>=
(
int
)
sizeof
(
warn_buff
))
DBUG_RETURN
(
-
1
);
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_TOO_LONG_KEY
,
warn_buff
);
ER_TOO_LONG_KEY
,
warn_buff
);
}
}
...
@@ -921,15 +929,15 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -921,15 +929,15 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
key_part_info
->
length
=
(
uint16
)
length
;
key_part_info
->
length
=
(
uint16
)
length
;
/* Use packed keys for long strings on the first column */
/* Use packed keys for long strings on the first column */
if
(
!
(
db_options
&
HA_OPTION_NO_PACK_KEYS
)
&&
if
(
!
(
db_options
&
HA_OPTION_NO_PACK_KEYS
)
&&
(
length
>=
KEY_DEFAULT_PACK_LENGTH
&&
(
length
>=
KEY_DEFAULT_PACK_LENGTH
&&
(
sql_field
->
sql_type
==
FIELD_TYPE_STRING
||
(
sql_field
->
sql_type
==
FIELD_TYPE_STRING
||
sql_field
->
sql_type
==
FIELD_TYPE_VAR_STRING
||
sql_field
->
sql_type
==
FIELD_TYPE_VAR_STRING
||
sql_field
->
pack_flag
&
FIELDFLAG_BLOB
)))
sql_field
->
pack_flag
&
FIELDFLAG_BLOB
)))
{
{
if
(
column_nr
==
0
&&
(
sql_field
->
pack_flag
&
FIELDFLAG_BLOB
))
if
(
column_nr
==
0
&&
(
sql_field
->
pack_flag
&
FIELDFLAG_BLOB
))
key_info
->
flags
|=
HA_BINARY_PACK_KEY
;
key_info
->
flags
|=
HA_BINARY_PACK_KEY
;
else
else
key_info
->
flags
|=
HA_PACK_KEY
;
key_info
->
flags
|=
HA_PACK_KEY
;
}
}
key_length
+=
length
;
key_length
+=
length
;
key_part_info
++
;
key_part_info
++
;
...
@@ -937,25 +945,25 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -937,25 +945,25 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
/* Create the key name based on the first column (if not given) */
/* Create the key name based on the first column (if not given) */
if
(
column_nr
==
0
)
if
(
column_nr
==
0
)
{
{
if
(
key
->
type
==
Key
::
PRIMARY
)
if
(
key
->
type
==
Key
::
PRIMARY
)
{
{
if
(
primary_key
)
if
(
primary_key
)
{
{
my_error
(
ER_MULTIPLE_PRI_KEY
,
MYF
(
0
));
my_error
(
ER_MULTIPLE_PRI_KEY
,
MYF
(
0
));
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
key_name
=
primary_key_name
;
key_name
=
primary_key_name
;
primary_key
=
1
;
primary_key
=
1
;
}
}
else
if
(
!
(
key_name
=
key
->
name
))
else
if
(
!
(
key_name
=
key
->
name
))
key_name
=
make_unique_key_name
(
sql_field
->
field_name
,
key_name
=
make_unique_key_name
(
sql_field
->
field_name
,
key_info_buffer
,
key_info
);
key_info_buffer
,
key_info
);
if
(
check_if_keyname_exists
(
key_name
,
key_info_buffer
,
key_info
))
if
(
check_if_keyname_exists
(
key_name
,
key_info_buffer
,
key_info
))
{
{
my_error
(
ER_DUP_KEYNAME
,
MYF
(
0
),
key_name
);
my_error
(
ER_DUP_KEYNAME
,
MYF
(
0
),
key_name
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
key_info
->
name
=
(
char
*
)
key_name
;
key_info
->
name
=
(
char
*
)
key_name
;
}
}
}
}
if
(
!
key_info
->
name
||
check_column_name
(
key_info
->
name
))
if
(
!
key_info
->
name
||
check_column_name
(
key_info
->
name
))
...
@@ -996,15 +1004,15 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -996,15 +1004,15 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
SYNOPSIS
SYNOPSIS
mysql_create_table()
mysql_create_table()
thd
Thread object
thd
Thread object
db
Database
db
Database
table_name
Table name
table_name
Table name
create_info
Create information (like MAX_ROWS)
create_info
Create information (like MAX_ROWS)
fields
List of fields to create
fields
List of fields to create
keys
List of keys to create
keys
List of keys to create
tmp_table
Set to 1 if this is an internal temporary table
tmp_table
Set to 1 if this is an internal temporary table
(From ALTER TABLE)
(From ALTER TABLE)
no_log
Don't log the query to binary log.
no_log
Don't log the query to binary log.
DESCRIPTION
DESCRIPTION
If one creates a temporary table, this is automaticly opened
If one creates a temporary table, this is automaticly opened
...
@@ -1015,23 +1023,23 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -1015,23 +1023,23 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
and must be zero for standard create of table.
and must be zero for standard create of table.
RETURN VALUES
RETURN VALUES
0
ok
0
ok
-1
error
-1
error
*/
*/
int
mysql_create_table
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
,
int
mysql_create_table
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
,
HA_CREATE_INFO
*
create_info
,
HA_CREATE_INFO
*
create_info
,
List
<
create_field
>
&
fields
,
List
<
create_field
>
&
fields
,
List
<
Key
>
&
keys
,
bool
tmp_table
,
bool
no_log
,
List
<
Key
>
&
keys
,
bool
tmp_table
,
bool
no_log
,
uint
select_field_count
)
uint
select_field_count
)
{
{
char
path
[
FN_REFLEN
];
char
path
[
FN_REFLEN
];
const
char
*
alias
;
const
char
*
alias
;
int
error
=
-
1
;
int
error
=
-
1
;
uint
db_options
,
key_count
;
uint
db_options
,
key_count
;
KEY
*
key_info_buffer
;
KEY
*
key_info_buffer
;
handler
*
file
;
handler
*
file
;
enum
db_type
new_db_type
;
enum
db_type
new_db_type
;
DBUG_ENTER
(
"mysql_create_table"
);
DBUG_ENTER
(
"mysql_create_table"
);
/* Check for duplicate fields and check type of table to create */
/* Check for duplicate fields and check type of table to create */
...
@@ -1045,10 +1053,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
...
@@ -1045,10 +1053,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
{
{
create_info
->
db_type
=
new_db_type
;
create_info
->
db_type
=
new_db_type
;
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_WARN_USING_OTHER_HANDLER
,
ER_WARN_USING_OTHER_HANDLER
,
ER
(
ER_WARN_USING_OTHER_HANDLER
),
ER
(
ER_WARN_USING_OTHER_HANDLER
),
ha_get_storage_engine
(
new_db_type
),
ha_get_storage_engine
(
new_db_type
),
table_name
);
table_name
);
}
}
db_options
=
create_info
->
table_options
;
db_options
=
create_info
->
table_options
;
if
(
create_info
->
row_type
==
ROW_TYPE_DYNAMIC
)
if
(
create_info
->
row_type
==
ROW_TYPE_DYNAMIC
)
...
@@ -1064,20 +1072,24 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
...
@@ -1064,20 +1072,24 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
}
}
if
(
mysql_prepare_table
(
thd
,
create_info
,
fields
,
if
(
mysql_prepare_table
(
thd
,
create_info
,
fields
,
keys
,
tmp_table
,
db_options
,
file
,
keys
,
tmp_table
,
db_options
,
file
,
key_info_buffer
,
key_count
,
key_info_buffer
,
key_count
,
select_field_count
))
select_field_count
))
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
/* Check if table exists */
/* Check if table exists */
if
(
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
)
if
(
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
)
{
{
sprintf
(
path
,
"%s%s%lx_%lx_%x%s"
,
mysql_tmpdir
,
tmp_file_prefix
,
if
(
snprintf
(
path
,
sizeof
(
path
),
"%s%s%lx_%lx_%x%s"
,
current_pid
,
thd
->
thread_id
,
thd
->
tmp_table
++
,
reg_ext
);
mysql_tmpdir
,
tmp_file_prefix
,
current_pid
,
thd
->
thread_id
,
thd
->
tmp_table
++
,
reg_ext
)
>=
(
int
)
sizeof
(
path
))
DBUG_RETURN
(
-
1
);
create_info
->
table_options
|=
HA_CREATE_DELAY_KEY_WRITE
;
create_info
->
table_options
|=
HA_CREATE_DELAY_KEY_WRITE
;
}
}
else
else
(
void
)
sprintf
(
path
,
"%s/%s/%s%s"
,
mysql_data_home
,
db
,
alias
,
reg_ext
);
if
(
snprintf
(
path
,
sizeof
(
path
),
"%s/%s/%s%s"
,
mysql_data_home
,
db
,
alias
,
reg_ext
)
>=
(
int
)
sizeof
(
path
))
DBUG_RETURN
(
-
1
);
unpack_filename
(
path
,
path
);
unpack_filename
(
path
,
path
);
/* Check if table already exists */
/* Check if table already exists */
if
((
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
)
if
((
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
)
...
@@ -1085,7 +1097,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
...
@@ -1085,7 +1097,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
{
{
if
(
create_info
->
options
&
HA_LEX_CREATE_IF_NOT_EXISTS
)
if
(
create_info
->
options
&
HA_LEX_CREATE_IF_NOT_EXISTS
)
{
{
create_info
->
table_existed
=
1
;
// Mark that table existed
create_info
->
table_existed
=
1
;
// Mark that table existed
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
my_error
(
ER_TABLE_EXISTS_ERROR
,
MYF
(
0
),
alias
);
my_error
(
ER_TABLE_EXISTS_ERROR
,
MYF
(
0
),
alias
);
...
@@ -1100,8 +1112,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
...
@@ -1100,8 +1112,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
{
{
if
(
create_info
->
options
&
HA_LEX_CREATE_IF_NOT_EXISTS
)
if
(
create_info
->
options
&
HA_LEX_CREATE_IF_NOT_EXISTS
)
{
{
create_info
->
table_existed
=
1
;
// Mark that table existed
create_info
->
table_existed
=
1
;
// Mark that table existed
error
=
0
;
error
=
0
;
}
}
else
else
my_error
(
ER_TABLE_EXISTS_ERROR
,
MYF
(
0
),
table_name
);
my_error
(
ER_TABLE_EXISTS_ERROR
,
MYF
(
0
),
table_name
);
...
@@ -1110,14 +1122,14 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
...
@@ -1110,14 +1122,14 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
}
}
thd
->
proc_info
=
"creating table"
;
thd
->
proc_info
=
"creating table"
;
create_info
->
table_existed
=
0
;
// Mark that table is created
create_info
->
table_existed
=
0
;
// Mark that table is created
if
(
thd
->
variables
.
sql_mode
&
MODE_NO_DIR_IN_CREATE
)
if
(
thd
->
variables
.
sql_mode
&
MODE_NO_DIR_IN_CREATE
)
create_info
->
data_file_name
=
create_info
->
index_file_name
=
0
;
create_info
->
data_file_name
=
create_info
->
index_file_name
=
0
;
create_info
->
table_options
=
db_options
;
create_info
->
table_options
=
db_options
;
if
(
rea_create_table
(
thd
,
path
,
create_info
,
fields
,
key_count
,
if
(
rea_create_table
(
thd
,
path
,
create_info
,
fields
,
key_count
,
key_info_buffer
))
key_info_buffer
))
{
{
/* my_error(ER_CANT_CREATE_TABLE,MYF(0),table_name,my_errno); */
/* my_error(ER_CANT_CREATE_TABLE,MYF(0),table_name,my_errno); */
goto
end
;
goto
end
;
...
@@ -1140,8 +1152,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
...
@@ -1140,8 +1152,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
{
{
thd
->
clear_error
();
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
test
(
create_info
->
options
&
test
(
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
));
HA_LEX_CREATE_TMP_TABLE
));
mysql_bin_log
.
write
(
&
qinfo
);
mysql_bin_log
.
write
(
&
qinfo
);
}
}
}
}
...
@@ -1171,17 +1183,23 @@ static char *
...
@@ -1171,17 +1183,23 @@ static char *
make_unique_key_name
(
const
char
*
field_name
,
KEY
*
start
,
KEY
*
end
)
make_unique_key_name
(
const
char
*
field_name
,
KEY
*
start
,
KEY
*
end
)
{
{
char
buff
[
MAX_FIELD_NAME
],
*
buff_end
;
char
buff
[
MAX_FIELD_NAME
],
*
buff_end
;
int
remain
;
if
(
!
check_if_keyname_exists
(
field_name
,
start
,
end
)
&&
if
(
!
check_if_keyname_exists
(
field_name
,
start
,
end
)
&&
my_strcasecmp
(
system_charset_info
,
field_name
,
primary_key_name
))
my_strcasecmp
(
system_charset_info
,
field_name
,
primary_key_name
))
return
(
char
*
)
field_name
;
// Use fieldname
return
(
char
*
)
field_name
;
// Use fieldname
buff_end
=
strmake
(
buff
,
field_name
,
MAX_FIELD_NAME
-
4
);
buff_end
=
strmake
(
buff
,
field_name
,
MAX_FIELD_NAME
-
4
);
for
(
uint
i
=
2
;
;
i
++
)
/*ingo 2004-04-07 only 3 chars + '\0' left, so need to limit to 2 digit*/
for
(
uint
i
=
2
;
i
<
100
;
i
++
)
{
{
sprintf
(
buff_end
,
"_%d"
,
i
);
remain
=
(
int
)
sizeof
(
buff
)
-
(
buff_end
-
buff
);
if
(
snprintf
(
buff_end
,
remain
,
"_%d"
,
i
)
>=
remain
)
return
NULL
;
if
(
!
check_if_keyname_exists
(
buff
,
start
,
end
))
if
(
!
check_if_keyname_exists
(
buff
,
start
,
end
))
return
sql_strdup
(
buff
);
return
sql_strdup
(
buff
);
}
}
/*ingo 2004-04-07 dedicated return is inevitable*/
return
NULL
;
}
}
/****************************************************************************
/****************************************************************************
...
@@ -1189,13 +1207,13 @@ make_unique_key_name(const char *field_name,KEY *start,KEY *end)
...
@@ -1189,13 +1207,13 @@ make_unique_key_name(const char *field_name,KEY *start,KEY *end)
****************************************************************************/
****************************************************************************/
TABLE
*
create_table_from_items
(
THD
*
thd
,
HA_CREATE_INFO
*
create_info
,
TABLE
*
create_table_from_items
(
THD
*
thd
,
HA_CREATE_INFO
*
create_info
,
const
char
*
db
,
const
char
*
name
,
const
char
*
db
,
const
char
*
name
,
List
<
create_field
>
*
extra_fields
,
List
<
create_field
>
*
extra_fields
,
List
<
Key
>
*
keys
,
List
<
Key
>
*
keys
,
List
<
Item
>
*
items
,
List
<
Item
>
*
items
,
MYSQL_LOCK
**
lock
)
MYSQL_LOCK
**
lock
)
{
{
TABLE
tmp_table
;
// Used during 'create_field()'
TABLE
tmp_table
;
// Used during 'create_field()'
TABLE
*
table
;
TABLE
*
table
;
tmp_table
.
table_name
=
0
;
tmp_table
.
table_name
=
0
;
uint
select_field_count
=
items
->
elements
;
uint
select_field_count
=
items
->
elements
;
...
@@ -1209,7 +1227,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -1209,7 +1227,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
tmp_table
.
null_row
=
tmp_table
.
maybe_null
=
0
;
tmp_table
.
null_row
=
tmp_table
.
maybe_null
=
0
;
tmp_table
.
blob_ptr_size
=
portable_sizeof_char_ptr
;
tmp_table
.
blob_ptr_size
=
portable_sizeof_char_ptr
;
tmp_table
.
db_low_byte_first
=
test
(
create_info
->
db_type
==
DB_TYPE_MYISAM
||
tmp_table
.
db_low_byte_first
=
test
(
create_info
->
db_type
==
DB_TYPE_MYISAM
||
create_info
->
db_type
==
DB_TYPE_HEAP
);
create_info
->
db_type
==
DB_TYPE_HEAP
);
while
((
item
=
it
++
))
while
((
item
=
it
++
))
{
{
...
@@ -1219,18 +1237,18 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -1219,18 +1237,18 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
field
=
item
->
tmp_table_field
(
&
tmp_table
);
field
=
item
->
tmp_table_field
(
&
tmp_table
);
else
else
field
=
create_tmp_field
(
thd
,
&
tmp_table
,
item
,
item
->
type
(),
field
=
create_tmp_field
(
thd
,
&
tmp_table
,
item
,
item
->
type
(),
(
Item
***
)
0
,
&
tmp_field
,
0
,
0
);
(
Item
***
)
0
,
&
tmp_field
,
0
,
0
);
if
(
!
field
||
if
(
!
field
||
!
(
cr_field
=
new
create_field
(
field
,(
item
->
type
()
==
Item
::
FIELD_ITEM
?
!
(
cr_field
=
new
create_field
(
field
,(
item
->
type
()
==
Item
::
FIELD_ITEM
?
((
Item_field
*
)
item
)
->
field
:
((
Item_field
*
)
item
)
->
field
:
(
Field
*
)
0
))))
(
Field
*
)
0
))))
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
extra_fields
->
push_back
(
cr_field
);
extra_fields
->
push_back
(
cr_field
);
}
}
/* create and lock table */
/* create and lock table */
/* QQ: This should be done atomic ! */
/* QQ: This should be done atomic ! */
if
(
mysql_create_table
(
thd
,
db
,
name
,
create_info
,
*
extra_fields
,
if
(
mysql_create_table
(
thd
,
db
,
name
,
create_info
,
*
extra_fields
,
*
keys
,
0
,
1
,
select_field_count
))
// no logging
*
keys
,
0
,
1
,
select_field_count
))
// no logging
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
if
(
!
(
table
=
open_table
(
thd
,
db
,
name
,
name
,(
bool
*
)
0
)))
if
(
!
(
table
=
open_table
(
thd
,
db
,
name
,
name
,(
bool
*
)
0
)))
{
{
...
@@ -1257,10 +1275,10 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
...
@@ -1257,10 +1275,10 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
bool
bool
mysql_rename_table
(
enum
db_type
base
,
mysql_rename_table
(
enum
db_type
base
,
const
char
*
old_db
,
const
char
*
old_db
,
const
char
*
old_name
,
const
char
*
old_name
,
const
char
*
new_db
,
const
char
*
new_db
,
const
char
*
new_name
)
const
char
*
new_name
)
{
{
char
from
[
FN_REFLEN
],
to
[
FN_REFLEN
];
char
from
[
FN_REFLEN
],
to
[
FN_REFLEN
];
char
tmp_from
[
NAME_LEN
+
1
],
tmp_to
[
NAME_LEN
+
1
];
char
tmp_from
[
NAME_LEN
+
1
],
tmp_to
[
NAME_LEN
+
1
];
...
@@ -1279,8 +1297,12 @@ mysql_rename_table(enum db_type base,
...
@@ -1279,8 +1297,12 @@ mysql_rename_table(enum db_type base,
my_casedn_str
(
system_charset_info
,
tmp_to
);
my_casedn_str
(
system_charset_info
,
tmp_to
);
new_name
=
tmp_to
;
new_name
=
tmp_to
;
}
}
(
void
)
sprintf
(
from
,
"%s/%s/%s"
,
mysql_data_home
,
old_db
,
old_name
);
if
(
snprintf
(
from
,
sizeof
(
from
),
"%s/%s/%s"
,
(
void
)
sprintf
(
to
,
"%s/%s/%s"
,
mysql_data_home
,
new_db
,
new_name
);
mysql_data_home
,
old_db
,
old_name
)
>=
(
int
)
sizeof
(
from
))
DBUG_RETURN
(
1
);
if
(
snprintf
(
to
,
sizeof
(
to
),
"%s/%s/%s"
,
mysql_data_home
,
new_db
,
new_name
)
>=
(
int
)
sizeof
(
to
))
DBUG_RETURN
(
1
);
fn_format
(
from
,
from
,
""
,
""
,
4
);
fn_format
(
from
,
from
,
""
,
""
,
4
);
fn_format
(
to
,
to
,
""
,
""
,
4
);
fn_format
(
to
,
to
,
""
,
""
,
4
);
...
@@ -1305,10 +1327,10 @@ mysql_rename_table(enum db_type base,
...
@@ -1305,10 +1327,10 @@ mysql_rename_table(enum db_type base,
SYNOPSIS
SYNOPSIS
wait_while_table_is_used()
wait_while_table_is_used()
thd
Thread handler
thd
Thread handler
table
Table to remove from cache
table
Table to remove from cache
function
HA_EXTRA_PREPARE_FOR_DELETE if table is to be deleted
function
HA_EXTRA_PREPARE_FOR_DELETE if table is to be deleted
HA_EXTRA_FORCE_REOPEN if table is not be used
HA_EXTRA_FORCE_REOPEN if table is not be used
NOTES
NOTES
When returning, the table will be unusable for other threads until
When returning, the table will be unusable for other threads until
the table is closed.
the table is closed.
...
@@ -1319,7 +1341,7 @@ mysql_rename_table(enum db_type base,
...
@@ -1319,7 +1341,7 @@ mysql_rename_table(enum db_type base,
*/
*/
static
void
wait_while_table_is_used
(
THD
*
thd
,
TABLE
*
table
,
static
void
wait_while_table_is_used
(
THD
*
thd
,
TABLE
*
table
,
enum
ha_extra_function
function
)
enum
ha_extra_function
function
)
{
{
DBUG_PRINT
(
"enter"
,(
"table: %s"
,
table
->
real_name
));
DBUG_PRINT
(
"enter"
,(
"table: %s"
,
table
->
real_name
));
DBUG_ENTER
(
"wait_while_table_is_used"
);
DBUG_ENTER
(
"wait_while_table_is_used"
);
...
@@ -1327,11 +1349,11 @@ static void wait_while_table_is_used(THD *thd,TABLE *table,
...
@@ -1327,11 +1349,11 @@ static void wait_while_table_is_used(THD *thd,TABLE *table,
VOID
(
table
->
file
->
extra
(
function
));
VOID
(
table
->
file
->
extra
(
function
));
/* Mark all tables that are in use as 'old' */
/* Mark all tables that are in use as 'old' */
mysql_lock_abort
(
thd
,
table
);
// end threads waiting on lock
mysql_lock_abort
(
thd
,
table
);
// end threads waiting on lock
/* Wait until all there are no other threads that has this table open */
/* Wait until all there are no other threads that has this table open */
while
(
remove_table_from_cache
(
thd
,
table
->
table_cache_key
,
while
(
remove_table_from_cache
(
thd
,
table
->
table_cache_key
,
table
->
real_name
))
table
->
real_name
))
{
{
dropping_tables
++
;
dropping_tables
++
;
(
void
)
pthread_cond_wait
(
&
COND_refresh
,
&
LOCK_open
);
(
void
)
pthread_cond_wait
(
&
COND_refresh
,
&
LOCK_open
);
...
@@ -1345,8 +1367,8 @@ static void wait_while_table_is_used(THD *thd,TABLE *table,
...
@@ -1345,8 +1367,8 @@ static void wait_while_table_is_used(THD *thd,TABLE *table,
SYNOPSIS
SYNOPSIS
close_cached_table()
close_cached_table()
thd
Thread handler
thd
Thread handler
table
Table to remove from cache
table
Table to remove from cache
NOTES
NOTES
Function ends by signaling threads waiting for the table to try to
Function ends by signaling threads waiting for the table to try to
...
@@ -1366,7 +1388,7 @@ static bool close_cached_table(THD *thd, TABLE *table)
...
@@ -1366,7 +1388,7 @@ static bool close_cached_table(THD *thd, TABLE *table)
if
(
thd
->
lock
)
if
(
thd
->
lock
)
{
{
mysql_unlock_tables
(
thd
,
thd
->
lock
);
mysql_unlock_tables
(
thd
,
thd
->
lock
);
thd
->
lock
=
0
;
// Start locked threads
thd
->
lock
=
0
;
// Start locked threads
}
}
/* Close all copies of 'table'. This also frees all LOCK TABLES lock */
/* Close all copies of 'table'. This also frees all LOCK TABLES lock */
thd
->
open_tables
=
unlink_open_table
(
thd
,
thd
->
open_tables
,
table
);
thd
->
open_tables
=
unlink_open_table
(
thd
,
thd
->
open_tables
,
table
);
...
@@ -1377,7 +1399,7 @@ static bool close_cached_table(THD *thd, TABLE *table)
...
@@ -1377,7 +1399,7 @@ static bool close_cached_table(THD *thd, TABLE *table)
}
}
static
int
send_check_errmsg
(
THD
*
thd
,
TABLE_LIST
*
table
,
static
int
send_check_errmsg
(
THD
*
thd
,
TABLE_LIST
*
table
,
const
char
*
operator_name
,
const
char
*
errmsg
)
const
char
*
operator_name
,
const
char
*
errmsg
)
{
{
Protocol
*
protocol
=
thd
->
protocol
;
Protocol
*
protocol
=
thd
->
protocol
;
...
@@ -1394,15 +1416,15 @@ static int send_check_errmsg(THD *thd, TABLE_LIST* table,
...
@@ -1394,15 +1416,15 @@ static int send_check_errmsg(THD *thd, TABLE_LIST* table,
static
int
prepare_for_restore
(
THD
*
thd
,
TABLE_LIST
*
table
,
static
int
prepare_for_restore
(
THD
*
thd
,
TABLE_LIST
*
table
,
HA_CHECK_OPT
*
check_opt
)
HA_CHECK_OPT
*
check_opt
)
{
{
DBUG_ENTER
(
"prepare_for_restore"
);
DBUG_ENTER
(
"prepare_for_restore"
);
if
(
table
->
table
)
// do not overwrite existing tables on restore
if
(
table
->
table
)
// do not overwrite existing tables on restore
{
{
DBUG_RETURN
(
send_check_errmsg
(
thd
,
table
,
"restore"
,
DBUG_RETURN
(
send_check_errmsg
(
thd
,
table
,
"restore"
,
"table exists, will not overwrite on restore"
"table exists, will not overwrite on restore"
));
));
}
}
else
else
{
{
...
@@ -1412,23 +1434,25 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
...
@@ -1412,23 +1434,25 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
char
*
db
=
thd
->
db
?
thd
->
db
:
table
->
db
;
char
*
db
=
thd
->
db
?
thd
->
db
:
table
->
db
;
if
(
fn_format_relative_to_data_home
(
src_path
,
table_name
,
backup_dir
,
if
(
fn_format_relative_to_data_home
(
src_path
,
table_name
,
backup_dir
,
reg_ext
))
reg_ext
))
DBUG_RETURN
(
-
1
);
// protect buffer overflow
DBUG_RETURN
(
-
1
);
// protect buffer overflow
sprintf
(
dst_path
,
"%s/%s/%s"
,
mysql_real_data_home
,
db
,
table_name
);
if
(
snprintf
(
dst_path
,
sizeof
(
dst_path
),
"%s/%s/%s"
,
mysql_real_data_home
,
db
,
table_name
)
>=
(
int
)
sizeof
(
dst_path
))
DBUG_RETURN
(
-
1
);
if
(
lock_and_wait_for_table_name
(
thd
,
table
))
if
(
lock_and_wait_for_table_name
(
thd
,
table
))
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
if
(
my_copy
(
src_path
,
if
(
my_copy
(
src_path
,
fn_format
(
dst_path
,
dst_path
,
""
,
reg_ext
,
4
),
fn_format
(
dst_path
,
dst_path
,
""
,
reg_ext
,
4
),
MYF
(
MY_WME
)))
MYF
(
MY_WME
)))
{
{
pthread_mutex_lock
(
&
LOCK_open
);
pthread_mutex_lock
(
&
LOCK_open
);
unlock_table_name
(
thd
,
table
);
unlock_table_name
(
thd
,
table
);
pthread_mutex_unlock
(
&
LOCK_open
);
pthread_mutex_unlock
(
&
LOCK_open
);
DBUG_RETURN
(
send_check_errmsg
(
thd
,
table
,
"restore"
,
DBUG_RETURN
(
send_check_errmsg
(
thd
,
table
,
"restore"
,
"Failed copying .frm file"
));
"Failed copying .frm file"
));
}
}
if
(
mysql_truncate
(
thd
,
table
,
1
))
if
(
mysql_truncate
(
thd
,
table
,
1
))
{
{
...
@@ -1436,7 +1460,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
...
@@ -1436,7 +1460,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
unlock_table_name
(
thd
,
table
);
unlock_table_name
(
thd
,
table
);
pthread_mutex_unlock
(
&
LOCK_open
);
pthread_mutex_unlock
(
&
LOCK_open
);
DBUG_RETURN
(
send_check_errmsg
(
thd
,
table
,
"restore"
,
DBUG_RETURN
(
send_check_errmsg
(
thd
,
table
,
"restore"
,
"Failed generating table from .frm file"
));
"Failed generating table from .frm file"
));
}
}
}
}
...
@@ -1455,7 +1479,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
...
@@ -1455,7 +1479,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
static
int
prepare_for_repair
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
static
int
prepare_for_repair
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
HA_CHECK_OPT
*
check_opt
)
HA_CHECK_OPT
*
check_opt
)
{
{
int
error
=
0
;
int
error
=
0
;
TABLE
tmp_table
,
*
table
;
TABLE
tmp_table
,
*
table
;
...
@@ -1464,13 +1488,13 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
...
@@ -1464,13 +1488,13 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
if
(
!
(
check_opt
->
sql_flags
&
TT_USEFRM
))
if
(
!
(
check_opt
->
sql_flags
&
TT_USEFRM
))
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
if
(
!
(
table
=
table_list
->
table
))
/* if open_ltable failed */
if
(
!
(
table
=
table_list
->
table
))
/* if open_ltable failed */
{
{
char
name
[
FN_REFLEN
];
char
name
[
FN_REFLEN
];
strxmov
(
name
,
mysql_data_home
,
"/"
,
table_list
->
db
,
"/"
,
strxmov
(
name
,
mysql_data_home
,
"/"
,
table_list
->
db
,
"/"
,
table_list
->
real_name
,
NullS
);
table_list
->
real_name
,
NullS
);
if
(
openfrm
(
name
,
""
,
0
,
0
,
0
,
&
tmp_table
))
if
(
openfrm
(
name
,
""
,
0
,
0
,
0
,
&
tmp_table
))
DBUG_RETURN
(
0
);
// Can't open frm file
DBUG_RETURN
(
0
);
// Can't open frm file
table
=
&
tmp_table
;
table
=
&
tmp_table
;
}
}
...
@@ -1493,13 +1517,18 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
...
@@ -1493,13 +1517,18 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
like ISAM or MyISAM
like ISAM or MyISAM
*/
*/
if
(
!
ext
[
0
]
||
!
ext
[
1
])
if
(
!
ext
[
0
]
||
!
ext
[
1
])
goto
end
;
// No data file
goto
end
;
// No data file
strxmov
(
from
,
table
->
path
,
ext
[
1
],
NullS
);
// Name of data file
strxmov
(
from
,
table
->
path
,
ext
[
1
],
NullS
);
// Name of data file
if
(
!
my_stat
(
from
,
&
stat_info
,
MYF
(
0
)))
if
(
!
my_stat
(
from
,
&
stat_info
,
MYF
(
0
)))
goto
end
;
// Can't use USE_FRM flag
goto
end
;
// Can't use USE_FRM flag
sprintf
(
tmp
,
"%s-%lx_%lx"
,
from
,
current_pid
,
thd
->
thread_id
);
if
(
snprintf
(
tmp
,
sizeof
(
tmp
),
"%s-%lx_%lx"
,
from
,
current_pid
,
thd
->
thread_id
)
>=
(
int
)
sizeof
(
tmp
))
{
error
=
-
1
;
goto
end
;
}
/* If we could open the table, close it */
/* If we could open the table, close it */
if
(
table_list
->
table
)
if
(
table_list
->
table
)
...
@@ -1519,7 +1548,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
...
@@ -1519,7 +1548,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
unlock_table_name
(
thd
,
table_list
);
unlock_table_name
(
thd
,
table_list
);
pthread_mutex_unlock
(
&
LOCK_open
);
pthread_mutex_unlock
(
&
LOCK_open
);
error
=
send_check_errmsg
(
thd
,
table_list
,
"repair"
,
error
=
send_check_errmsg
(
thd
,
table_list
,
"repair"
,
"Failed renaming data file"
);
"Failed renaming data file"
);
goto
end
;
goto
end
;
}
}
if
(
mysql_truncate
(
thd
,
table_list
,
1
))
if
(
mysql_truncate
(
thd
,
table_list
,
1
))
...
@@ -1528,7 +1557,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
...
@@ -1528,7 +1557,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
unlock_table_name
(
thd
,
table_list
);
unlock_table_name
(
thd
,
table_list
);
pthread_mutex_unlock
(
&
LOCK_open
);
pthread_mutex_unlock
(
&
LOCK_open
);
error
=
send_check_errmsg
(
thd
,
table_list
,
"repair"
,
error
=
send_check_errmsg
(
thd
,
table_list
,
"repair"
,
"Failed generating table from .frm file"
);
"Failed generating table from .frm file"
);
goto
end
;
goto
end
;
}
}
if
(
my_rename
(
tmp
,
from
,
MYF
(
MY_WME
)))
if
(
my_rename
(
tmp
,
from
,
MYF
(
MY_WME
)))
...
@@ -1537,7 +1566,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
...
@@ -1537,7 +1566,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
unlock_table_name
(
thd
,
table_list
);
unlock_table_name
(
thd
,
table_list
);
pthread_mutex_unlock
(
&
LOCK_open
);
pthread_mutex_unlock
(
&
LOCK_open
);
error
=
send_check_errmsg
(
thd
,
table_list
,
"repair"
,
error
=
send_check_errmsg
(
thd
,
table_list
,
"repair"
,
"Failed restoring .MYD file"
);
"Failed restoring .MYD file"
);
goto
end
;
goto
end
;
}
}
...
@@ -1554,21 +1583,21 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
...
@@ -1554,21 +1583,21 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
end:
end:
if
(
table
==
&
tmp_table
)
if
(
table
==
&
tmp_table
)
closefrm
(
table
);
// Free allocated memory
closefrm
(
table
);
// Free allocated memory
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
}
}
static
int
mysql_admin_table
(
THD
*
thd
,
TABLE_LIST
*
tables
,
static
int
mysql_admin_table
(
THD
*
thd
,
TABLE_LIST
*
tables
,
HA_CHECK_OPT
*
check_opt
,
HA_CHECK_OPT
*
check_opt
,
const
char
*
operator_name
,
const
char
*
operator_name
,
thr_lock_type
lock_type
,
thr_lock_type
lock_type
,
bool
open_for_modify
,
bool
open_for_modify
,
uint
extra_open_options
,
uint
extra_open_options
,
int
(
*
prepare_func
)(
THD
*
,
TABLE_LIST
*
,
int
(
*
prepare_func
)(
THD
*
,
TABLE_LIST
*
,
HA_CHECK_OPT
*
),
HA_CHECK_OPT
*
),
int
(
handler
::*
operator_func
)
int
(
handler
::*
operator_func
)
(
THD
*
,
HA_CHECK_OPT
*
))
(
THD
*
,
HA_CHECK_OPT
*
))
{
{
TABLE_LIST
*
table
;
TABLE_LIST
*
table
;
List
<
Item
>
field_list
;
List
<
Item
>
field_list
;
...
@@ -1619,11 +1648,11 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
...
@@ -1619,11 +1648,11 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
protocol
->
store
(
operator_name
,
system_charset_info
);
protocol
->
store
(
operator_name
,
system_charset_info
);
protocol
->
store
(
"error"
,
5
,
system_charset_info
);
protocol
->
store
(
"error"
,
5
,
system_charset_info
);
if
(
!
(
err_msg
=
thd
->
net
.
last_error
))
if
(
!
(
err_msg
=
thd
->
net
.
last_error
))
err_msg
=
ER
(
ER_CHECK_NO_SUCH_TABLE
);
err_msg
=
ER
(
ER_CHECK_NO_SUCH_TABLE
);
protocol
->
store
(
err_msg
,
system_charset_info
);
protocol
->
store
(
err_msg
,
system_charset_info
);
thd
->
net
.
last_error
[
0
]
=
0
;
thd
->
net
.
last_error
[
0
]
=
0
;
if
(
protocol
->
write
())
if
(
protocol
->
write
())
goto
err
;
goto
err
;
continue
;
continue
;
}
}
table
->
table
->
pos_in_table_list
=
table
;
table
->
table
->
pos_in_table_list
=
table
;
...
@@ -1634,12 +1663,14 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
...
@@ -1634,12 +1663,14 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
protocol
->
store
(
table_name
,
system_charset_info
);
protocol
->
store
(
table_name
,
system_charset_info
);
protocol
->
store
(
operator_name
,
system_charset_info
);
protocol
->
store
(
operator_name
,
system_charset_info
);
protocol
->
store
(
"error"
,
5
,
system_charset_info
);
protocol
->
store
(
"error"
,
5
,
system_charset_info
);
sprintf
(
buff
,
ER
(
ER_OPEN_AS_READONLY
),
table_name
);
if
(
snprintf
(
buff
,
sizeof
(
buff
),
ER
(
ER_OPEN_AS_READONLY
),
table_name
)
>=
(
int
)
sizeof
(
buff
))
goto
err
;
protocol
->
store
(
buff
,
system_charset_info
);
protocol
->
store
(
buff
,
system_charset_info
);
close_thread_tables
(
thd
);
close_thread_tables
(
thd
);
table
->
table
=
0
;
// For query cache
table
->
table
=
0
;
// For query cache
if
(
protocol
->
write
())
if
(
protocol
->
write
())
goto
err
;
goto
err
;
continue
;
continue
;
}
}
...
@@ -1648,20 +1679,20 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
...
@@ -1648,20 +1679,20 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
{
{
pthread_mutex_lock
(
&
LOCK_open
);
pthread_mutex_lock
(
&
LOCK_open
);
const
char
*
old_message
=
thd
->
enter_cond
(
&
COND_refresh
,
&
LOCK_open
,
const
char
*
old_message
=
thd
->
enter_cond
(
&
COND_refresh
,
&
LOCK_open
,
"Waiting to get writelock"
);
"Waiting to get writelock"
);
mysql_lock_abort
(
thd
,
table
->
table
);
mysql_lock_abort
(
thd
,
table
->
table
);
while
(
remove_table_from_cache
(
thd
,
table
->
table
->
table_cache_key
,
while
(
remove_table_from_cache
(
thd
,
table
->
table
->
table_cache_key
,
table
->
table
->
real_name
)
&&
table
->
table
->
real_name
)
&&
!
thd
->
killed
)
!
thd
->
killed
)
{
{
dropping_tables
++
;
dropping_tables
++
;
(
void
)
pthread_cond_wait
(
&
COND_refresh
,
&
LOCK_open
);
(
void
)
pthread_cond_wait
(
&
COND_refresh
,
&
LOCK_open
);
dropping_tables
--
;
dropping_tables
--
;
}
}
thd
->
exit_cond
(
old_message
);
thd
->
exit_cond
(
old_message
);
pthread_mutex_unlock
(
&
LOCK_open
);
pthread_mutex_unlock
(
&
LOCK_open
);
if
(
thd
->
killed
)
if
(
thd
->
killed
)
goto
err
;
goto
err
;
open_for_modify
=
0
;
open_for_modify
=
0
;
}
}
...
@@ -1678,7 +1709,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
...
@@ -1678,7 +1709,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
{
{
char
buf
[
ERRMSGSIZE
+
20
];
char
buf
[
ERRMSGSIZE
+
20
];
uint
length
=
my_snprintf
(
buf
,
ERRMSGSIZE
,
uint
length
=
my_snprintf
(
buf
,
ERRMSGSIZE
,
ER
(
ER_CHECK_NOT_IMPLEMENTED
),
operator_name
);
ER
(
ER_CHECK_NOT_IMPLEMENTED
),
operator_name
);
protocol
->
store
(
"error"
,
5
,
system_charset_info
);
protocol
->
store
(
"error"
,
5
,
system_charset_info
);
protocol
->
store
(
buf
,
length
,
system_charset_info
);
protocol
->
store
(
buf
,
length
,
system_charset_info
);
}
}
...
@@ -1710,26 +1741,26 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
...
@@ -1710,26 +1741,26 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
protocol
->
store
(
"Invalid argument"
,
16
,
system_charset_info
);
protocol
->
store
(
"Invalid argument"
,
16
,
system_charset_info
);
break
;
break
;
default:
// Probably HA_ADMIN_INTERNAL_ERROR
default:
// Probably HA_ADMIN_INTERNAL_ERROR
protocol
->
store
(
"error"
,
5
,
system_charset_info
);
protocol
->
store
(
"error"
,
5
,
system_charset_info
);
protocol
->
store
(
"Unknown - internal error during operation"
,
41
protocol
->
store
(
"Unknown - internal error during operation"
,
41
,
system_charset_info
);
,
system_charset_info
);
fatal_error
=
1
;
fatal_error
=
1
;
break
;
break
;
}
}
if
(
fatal_error
)
if
(
fatal_error
)
table
->
table
->
version
=
0
;
// Force close of table
table
->
table
->
version
=
0
;
// Force close of table
else
if
(
open_for_modify
)
else
if
(
open_for_modify
)
{
{
pthread_mutex_lock
(
&
LOCK_open
);
pthread_mutex_lock
(
&
LOCK_open
);
remove_table_from_cache
(
thd
,
table
->
table
->
table_cache_key
,
remove_table_from_cache
(
thd
,
table
->
table
->
table_cache_key
,
table
->
table
->
real_name
);
table
->
table
->
real_name
);
pthread_mutex_unlock
(
&
LOCK_open
);
pthread_mutex_unlock
(
&
LOCK_open
);
/* May be something modified consequently we have to invalidate cache */
/* May be something modified consequently we have to invalidate cache */
query_cache_invalidate3
(
thd
,
table
->
table
,
0
);
query_cache_invalidate3
(
thd
,
table
->
table
,
0
);
}
}
close_thread_tables
(
thd
);
close_thread_tables
(
thd
);
table
->
table
=
0
;
// For query cache
table
->
table
=
0
;
// For query cache
if
(
protocol
->
write
())
if
(
protocol
->
write
())
goto
err
;
goto
err
;
}
}
...
@@ -1737,7 +1768,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
...
@@ -1737,7 +1768,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
send_eof
(
thd
);
send_eof
(
thd
);
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
err:
err:
close_thread_tables
(
thd
);
// Shouldn't be needed
close_thread_tables
(
thd
);
// Shouldn't be needed
if
(
table
)
if
(
table
)
table
->
table
=
0
;
table
->
table
=
0
;
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
...
@@ -1748,8 +1779,8 @@ int mysql_backup_table(THD* thd, TABLE_LIST* table_list)
...
@@ -1748,8 +1779,8 @@ int mysql_backup_table(THD* thd, TABLE_LIST* table_list)
{
{
DBUG_ENTER
(
"mysql_backup_table"
);
DBUG_ENTER
(
"mysql_backup_table"
);
DBUG_RETURN
(
mysql_admin_table
(
thd
,
table_list
,
0
,
DBUG_RETURN
(
mysql_admin_table
(
thd
,
table_list
,
0
,
"backup"
,
TL_READ
,
0
,
0
,
0
,
"backup"
,
TL_READ
,
0
,
0
,
0
,
&
handler
::
backup
));
&
handler
::
backup
));
}
}
...
@@ -1757,9 +1788,9 @@ int mysql_restore_table(THD* thd, TABLE_LIST* table_list)
...
@@ -1757,9 +1788,9 @@ int mysql_restore_table(THD* thd, TABLE_LIST* table_list)
{
{
DBUG_ENTER
(
"mysql_restore_table"
);
DBUG_ENTER
(
"mysql_restore_table"
);
DBUG_RETURN
(
mysql_admin_table
(
thd
,
table_list
,
0
,
DBUG_RETURN
(
mysql_admin_table
(
thd
,
table_list
,
0
,
"restore"
,
TL_WRITE
,
1
,
0
,
"restore"
,
TL_WRITE
,
1
,
0
,
&
prepare_for_restore
,
&
prepare_for_restore
,
&
handler
::
restore
));
&
handler
::
restore
));
}
}
...
@@ -1767,9 +1798,9 @@ int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
...
@@ -1767,9 +1798,9 @@ int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
{
{
DBUG_ENTER
(
"mysql_repair_table"
);
DBUG_ENTER
(
"mysql_repair_table"
);
DBUG_RETURN
(
mysql_admin_table
(
thd
,
tables
,
check_opt
,
DBUG_RETURN
(
mysql_admin_table
(
thd
,
tables
,
check_opt
,
"repair"
,
TL_WRITE
,
1
,
HA_OPEN_FOR_REPAIR
,
"repair"
,
TL_WRITE
,
1
,
HA_OPEN_FOR_REPAIR
,
&
prepare_for_repair
,
&
prepare_for_repair
,
&
handler
::
repair
));
&
handler
::
repair
));
}
}
...
@@ -1777,8 +1808,8 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
...
@@ -1777,8 +1808,8 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
{
{
DBUG_ENTER
(
"mysql_optimize_table"
);
DBUG_ENTER
(
"mysql_optimize_table"
);
DBUG_RETURN
(
mysql_admin_table
(
thd
,
tables
,
check_opt
,
DBUG_RETURN
(
mysql_admin_table
(
thd
,
tables
,
check_opt
,
"optimize"
,
TL_WRITE
,
1
,
0
,
0
,
"optimize"
,
TL_WRITE
,
1
,
0
,
0
,
&
handler
::
optimize
));
&
handler
::
optimize
));
}
}
...
@@ -1787,16 +1818,16 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
...
@@ -1787,16 +1818,16 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
SYNOPSIS
SYNOPSIS
mysql_assign_to_keycache()
mysql_assign_to_keycache()
thd
Thread object
thd
Thread object
tables Table list (one table only)
tables Table list (one table only)
RETURN VALUES
RETURN VALUES
0
ok
0
ok
-1
error
-1
error
*/
*/
int
mysql_assign_to_keycache
(
THD
*
thd
,
TABLE_LIST
*
tables
,
int
mysql_assign_to_keycache
(
THD
*
thd
,
TABLE_LIST
*
tables
,
LEX_STRING
*
key_cache_name
)
LEX_STRING
*
key_cache_name
)
{
{
HA_CHECK_OPT
check_opt
;
HA_CHECK_OPT
check_opt
;
KEY_CACHE
*
key_cache
;
KEY_CACHE
*
key_cache
;
...
@@ -1813,7 +1844,7 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
...
@@ -1813,7 +1844,7 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
pthread_mutex_unlock
(
&
LOCK_global_system_variables
);
pthread_mutex_unlock
(
&
LOCK_global_system_variables
);
check_opt
.
key_cache
=
key_cache
;
check_opt
.
key_cache
=
key_cache
;
DBUG_RETURN
(
mysql_admin_table
(
thd
,
tables
,
&
check_opt
,
DBUG_RETURN
(
mysql_admin_table
(
thd
,
tables
,
&
check_opt
,
"assign_to_keycache"
,
TL_READ_NO_INSERT
,
0
,
"assign_to_keycache"
,
TL_READ_NO_INSERT
,
0
,
0
,
0
,
&
handler
::
assign_to_keycache
));
0
,
0
,
&
handler
::
assign_to_keycache
));
}
}
...
@@ -1823,7 +1854,7 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
...
@@ -1823,7 +1854,7 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
SYNOPSIS
SYNOPSIS
reassign_keycache_tables()
reassign_keycache_tables()
thd
Thread object
thd
Thread object
src_cache Reference to the key cache to clean up
src_cache Reference to the key cache to clean up
dest_cache New key cache
dest_cache New key cache
...
@@ -1840,7 +1871,7 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
...
@@ -1840,7 +1871,7 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
to it for a while after this function returns.
to it for a while after this function returns.
RETURN VALUES
RETURN VALUES
0
ok
0
ok
*/
*/
int
reassign_keycache_tables
(
THD
*
thd
,
KEY_CACHE
*
src_cache
,
int
reassign_keycache_tables
(
THD
*
thd
,
KEY_CACHE
*
src_cache
,
...
@@ -1850,7 +1881,7 @@ int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache,
...
@@ -1850,7 +1881,7 @@ int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache,
DBUG_ASSERT
(
src_cache
!=
dst_cache
);
DBUG_ASSERT
(
src_cache
!=
dst_cache
);
DBUG_ASSERT
(
src_cache
->
in_init
);
DBUG_ASSERT
(
src_cache
->
in_init
);
src_cache
->
param_buff_size
=
0
;
// Free key cache
src_cache
->
param_buff_size
=
0
;
// Free key cache
ha_resize_key_cache
(
src_cache
);
ha_resize_key_cache
(
src_cache
);
ha_change_key_cache
(
src_cache
,
dst_cache
);
ha_change_key_cache
(
src_cache
,
dst_cache
);
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
...
@@ -1862,20 +1893,20 @@ int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache,
...
@@ -1862,20 +1893,20 @@ int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache,
SYNOPSIS
SYNOPSIS
mysql_preload_keys()
mysql_preload_keys()
thd
Thread object
thd
Thread object
tables Table list (one table only)
tables Table list (one table only)
RETURN VALUES
RETURN VALUES
0
ok
0
ok
-1
error
-1
error
*/
*/
int
mysql_preload_keys
(
THD
*
thd
,
TABLE_LIST
*
tables
)
int
mysql_preload_keys
(
THD
*
thd
,
TABLE_LIST
*
tables
)
{
{
DBUG_ENTER
(
"mysql_preload_keys"
);
DBUG_ENTER
(
"mysql_preload_keys"
);
DBUG_RETURN
(
mysql_admin_table
(
thd
,
tables
,
0
,
DBUG_RETURN
(
mysql_admin_table
(
thd
,
tables
,
0
,
"preload_keys"
,
TL_READ
,
0
,
0
,
0
,
"preload_keys"
,
TL_READ
,
0
,
0
,
0
,
&
handler
::
preload_keys
));
&
handler
::
preload_keys
));
}
}
...
@@ -1884,14 +1915,14 @@ int mysql_preload_keys(THD* thd, TABLE_LIST* tables)
...
@@ -1884,14 +1915,14 @@ int mysql_preload_keys(THD* thd, TABLE_LIST* tables)
SYNOPSIS
SYNOPSIS
mysql_create_like_table()
mysql_create_like_table()
thd
Thread object
thd
Thread object
table Table list (one table only)
table Table list (one table only)
create_info Create info
create_info Create info
table_ident Src table_ident
table_ident Src table_ident
RETURN VALUES
RETURN VALUES
0
ok
0
ok
-1
error
-1
error
*/
*/
int
mysql_create_like_table
(
THD
*
thd
,
TABLE_LIST
*
table
,
int
mysql_create_like_table
(
THD
*
thd
,
TABLE_LIST
*
table
,
...
@@ -1942,8 +1973,11 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
...
@@ -1942,8 +1973,11 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
{
{
if
(
find_temporary_table
(
thd
,
db
,
table_name
))
if
(
find_temporary_table
(
thd
,
db
,
table_name
))
goto
table_exists
;
goto
table_exists
;
sprintf
(
dst_path
,
"%s%s%lx_%lx_%x%s"
,
mysql_tmpdir
,
tmp_file_prefix
,
if
(
snprintf
(
dst_path
,
sizeof
(
dst_path
),
"%s%s%lx_%lx_%x%s"
,
current_pid
,
thd
->
thread_id
,
thd
->
tmp_table
++
,
reg_ext
);
mysql_tmpdir
,
tmp_file_prefix
,
current_pid
,
thd
->
thread_id
,
thd
->
tmp_table
++
,
reg_ext
)
>=
(
int
)
sizeof
(
dst_path
))
DBUG_RETURN
(
-
1
);
create_info
->
table_options
|=
HA_CREATE_DELAY_KEY_WRITE
;
create_info
->
table_options
|=
HA_CREATE_DELAY_KEY_WRITE
;
}
}
else
else
...
@@ -1990,8 +2024,8 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
...
@@ -1990,8 +2024,8 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
{
{
thd
->
clear_error
();
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
test
(
create_info
->
options
&
test
(
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
));
HA_LEX_CREATE_TMP_TABLE
));
mysql_bin_log
.
write
(
&
qinfo
);
mysql_bin_log
.
write
(
&
qinfo
);
}
}
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
...
@@ -2000,7 +2034,9 @@ table_exists:
...
@@ -2000,7 +2034,9 @@ table_exists:
if
(
create_info
->
options
&
HA_LEX_CREATE_IF_NOT_EXISTS
)
if
(
create_info
->
options
&
HA_LEX_CREATE_IF_NOT_EXISTS
)
{
{
char
warn_buff
[
MYSQL_ERRMSG_SIZE
];
char
warn_buff
[
MYSQL_ERRMSG_SIZE
];
sprintf
(
warn_buff
,
ER
(
ER_TABLE_EXISTS_ERROR
),
table_name
);
if
(
snprintf
(
warn_buff
,
sizeof
(
warn_buff
),
ER
(
ER_TABLE_EXISTS_ERROR
),
table_name
)
>=
(
int
)
sizeof
(
warn_buff
))
DBUG_RETURN
(
-
1
);
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_TABLE_EXISTS_ERROR
,
warn_buff
);
ER_TABLE_EXISTS_ERROR
,
warn_buff
);
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
...
@@ -2020,8 +2056,8 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
...
@@ -2020,8 +2056,8 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
DBUG_ENTER
(
"mysql_analyze_table"
);
DBUG_ENTER
(
"mysql_analyze_table"
);
DBUG_RETURN
(
mysql_admin_table
(
thd
,
tables
,
check_opt
,
DBUG_RETURN
(
mysql_admin_table
(
thd
,
tables
,
check_opt
,
"analyze"
,
lock_type
,
1
,
0
,
0
,
"analyze"
,
lock_type
,
1
,
0
,
0
,
&
handler
::
analyze
));
&
handler
::
analyze
));
}
}
...
@@ -2035,15 +2071,15 @@ int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
...
@@ -2035,15 +2071,15 @@ int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
DBUG_ENTER
(
"mysql_check_table"
);
DBUG_ENTER
(
"mysql_check_table"
);
DBUG_RETURN
(
mysql_admin_table
(
thd
,
tables
,
check_opt
,
DBUG_RETURN
(
mysql_admin_table
(
thd
,
tables
,
check_opt
,
"check"
,
lock_type
,
"check"
,
lock_type
,
0
,
HA_OPEN_FOR_REPAIR
,
0
,
0
,
HA_OPEN_FOR_REPAIR
,
0
,
&
handler
::
check
));
&
handler
::
check
));
}
}
/* table_list should contain just one table */
/* table_list should contain just one table */
int
mysql_discard_or_import_tablespace
(
THD
*
thd
,
int
mysql_discard_or_import_tablespace
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
TABLE_LIST
*
table_list
,
enum
tablespace_op_type
tablespace_op
)
enum
tablespace_op_type
tablespace_op
)
{
{
TABLE
*
table
;
TABLE
*
table
;
my_bool
discard
;
my_bool
discard
;
...
@@ -2061,8 +2097,8 @@ int mysql_discard_or_import_tablespace(THD *thd,
...
@@ -2061,8 +2097,8 @@ int mysql_discard_or_import_tablespace(THD *thd,
discard
=
FALSE
;
discard
=
FALSE
;
thd
->
tablespace_op
=
TRUE
;
/* we set this flag so that ha_innobase::open
thd
->
tablespace_op
=
TRUE
;
/* we set this flag so that ha_innobase::open
and ::external_lock() do not complain when we
and ::external_lock() do not complain when we
lock the table */
lock the table */
mysql_ha_closeall
(
thd
,
table_list
);
mysql_ha_closeall
(
thd
,
table_list
);
if
(
!
(
table
=
open_ltable
(
thd
,
table_list
,
TL_WRITE
)))
if
(
!
(
table
=
open_ltable
(
thd
,
table_list
,
TL_WRITE
)))
...
@@ -2119,12 +2155,12 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
...
@@ -2119,12 +2155,12 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
HA_CREATE_INFO
create_info
;
HA_CREATE_INFO
create_info
;
int
rc
;
int
rc
;
uint
idx
;
uint
idx
;
uint
db_options
;
uint
db_options
;
uint
key_count
;
uint
key_count
;
TABLE
*
table
;
TABLE
*
table
;
Field
**
f_ptr
;
Field
**
f_ptr
;
KEY
*
key_info_buffer
;
KEY
*
key_info_buffer
;
char
path
[
FN_REFLEN
];
char
path
[
FN_REFLEN
];
DBUG_ENTER
(
"mysql_create_index"
);
DBUG_ENTER
(
"mysql_create_index"
);
/*
/*
...
@@ -2154,9 +2190,9 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
...
@@ -2154,9 +2190,9 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
create_info
.
default_table_charset
=
thd
->
variables
.
collation_database
;
create_info
.
default_table_charset
=
thd
->
variables
.
collation_database
;
db_options
=
0
;
db_options
=
0
;
if
(
mysql_prepare_table
(
thd
,
&
create_info
,
fields
,
if
(
mysql_prepare_table
(
thd
,
&
create_info
,
fields
,
keys
,
/*tmp_table*/
0
,
db_options
,
table
->
file
,
keys
,
/*tmp_table*/
0
,
db_options
,
table
->
file
,
key_info_buffer
,
key_count
,
key_info_buffer
,
key_count
,
/*select_field_count*/
0
))
/*select_field_count*/
0
))
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
/*
/*
...
@@ -2170,7 +2206,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
...
@@ -2170,7 +2206,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
(
HA_DDL_ONLINE
|
HA_DDL_WITH_LOCK
)))
(
HA_DDL_ONLINE
|
HA_DDL_WITH_LOCK
)))
break
;
break
;
}
}
if
((
idx
<
key_count
)
||
(
key_count
<=
0
)
)
if
((
idx
<
key_count
)
||
!
key_count
)
{
{
/* Re-initialize the create_info, which was changed by prepare table. */
/* Re-initialize the create_info, which was changed by prepare table. */
bzero
((
char
*
)
&
create_info
,
sizeof
(
create_info
));
bzero
((
char
*
)
&
create_info
,
sizeof
(
create_info
));
...
@@ -2188,9 +2224,10 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
...
@@ -2188,9 +2224,10 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
else
else
{
{
if
(
table
->
file
->
add_index
(
table
,
key_info_buffer
,
key_count
)
||
if
(
table
->
file
->
add_index
(
table
,
key_info_buffer
,
key_count
)
||
((
void
)
sprintf
(
path
,
"%s/%s/%s%s"
,
mysql_data_home
,
table_list
->
db
,
(
snprintf
(
path
,
sizeof
(
path
),
"%s/%s/%s%s"
,
mysql_data_home
,
(
lower_case_table_names
==
2
)
?
table_list
->
alias
:
table_list
->
db
,
(
lower_case_table_names
==
2
)
?
table_list
->
real_name
,
reg_ext
),
0
)
||
table_list
->
alias
:
table_list
->
real_name
,
reg_ext
)
>=
(
int
)
sizeof
(
path
))
||
!
unpack_filename
(
path
,
path
)
||
!
unpack_filename
(
path
,
path
)
||
mysql_create_frm
(
thd
,
path
,
&
create_info
,
mysql_create_frm
(
thd
,
path
,
&
create_info
,
fields
,
key_count
,
key_info_buffer
,
table
->
file
))
fields
,
key_count
,
key_info_buffer
,
table
->
file
))
...
@@ -2210,14 +2247,14 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
...
@@ -2210,14 +2247,14 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
List
<
Alter_column
>
alter
;
List
<
Alter_column
>
alter
;
HA_CREATE_INFO
create_info
;
HA_CREATE_INFO
create_info
;
uint
idx
;
uint
idx
;
uint
db_options
;
uint
db_options
;
uint
key_count
;
uint
key_count
;
uint
*
key_numbers
;
uint
*
key_numbers
;
TABLE
*
table
;
TABLE
*
table
;
Field
**
f_ptr
;
Field
**
f_ptr
;
KEY
*
key_info
;
KEY
*
key_info
;
KEY
*
key_info_buffer
;
KEY
*
key_info_buffer
;
char
path
[
FN_REFLEN
];
char
path
[
FN_REFLEN
];
DBUG_ENTER
(
"mysql_drop_index"
);
DBUG_ENTER
(
"mysql_drop_index"
);
/*
/*
...
@@ -2249,7 +2286,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
...
@@ -2249,7 +2286,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
for
(
idx
=
0
;
idx
<
table
->
keys
;
idx
++
,
key_info
++
)
for
(
idx
=
0
;
idx
<
table
->
keys
;
idx
++
,
key_info
++
)
{
{
if
(
!
my_strcasecmp
(
system_charset_info
,
key_info
->
name
,
drop_key
->
name
))
if
(
!
my_strcasecmp
(
system_charset_info
,
key_info
->
name
,
drop_key
->
name
))
break
;
break
;
}
}
if
(
idx
>=
table
->
keys
)
if
(
idx
>=
table
->
keys
)
{
{
...
@@ -2289,9 +2326,10 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
...
@@ -2289,9 +2326,10 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
keys
,
/*tmp_table*/
0
,
db_options
,
table
->
file
,
keys
,
/*tmp_table*/
0
,
db_options
,
table
->
file
,
key_info_buffer
,
key_count
,
key_info_buffer
,
key_count
,
/*select_field_count*/
0
)
||
/*select_field_count*/
0
)
||
((
void
)
sprintf
(
path
,
"%s/%s/%s%s"
,
mysql_data_home
,
table_list
->
db
,
(
snprintf
(
path
,
sizeof
(
path
),
"%s/%s/%s%s"
,
mysql_data_home
,
(
lower_case_table_names
==
2
)
?
table_list
->
alias
:
table_list
->
db
,
(
lower_case_table_names
==
2
)
?
table_list
->
real_name
,
reg_ext
),
0
)
||
table_list
->
alias
:
table_list
->
real_name
,
reg_ext
)
>=
(
int
)
sizeof
(
path
))
||
!
unpack_filename
(
path
,
path
)
||
!
unpack_filename
(
path
,
path
)
||
mysql_create_frm
(
thd
,
path
,
&
create_info
,
mysql_create_frm
(
thd
,
path
,
&
create_info
,
fields
,
key_count
,
key_info_buffer
,
table
->
file
))
fields
,
key_count
,
key_info_buffer
,
table
->
file
))
...
@@ -2304,7 +2342,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
...
@@ -2304,7 +2342,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
}
}
int
mysql_add_column
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
int
mysql_add_column
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
create_field
>
&
fields
)
List
<
create_field
>
&
fields
)
{
{
List
<
Alter_drop
>
drop
;
List
<
Alter_drop
>
drop
;
List
<
Key
>
keys
;
List
<
Key
>
keys
;
...
@@ -2319,9 +2357,9 @@ int mysql_add_column(THD *thd, TABLE_LIST *table_list,
...
@@ -2319,9 +2357,9 @@ int mysql_add_column(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
real_alter_table
(
thd
,
table_list
->
db
,
table_list
->
real_name
,
DBUG_RETURN
(
real_alter_table
(
thd
,
table_list
->
db
,
table_list
->
real_name
,
&
create_info
,
table_list
,
table
,
&
create_info
,
table_list
,
table
,
fields
,
keys
,
drop
,
alter
,
0
,
(
ORDER
*
)
0
,
fields
,
keys
,
drop
,
alter
,
0
,
(
ORDER
*
)
0
,
ALTER_ADD_COLUMN
,
DUP_ERROR
));
ALTER_ADD_COLUMN
,
DUP_ERROR
));
}
}
int
mysql_drop_column
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Alter_drop
>
&
drop
)
int
mysql_drop_column
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Alter_drop
>
&
drop
)
...
@@ -2339,37 +2377,31 @@ int mysql_drop_column(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
...
@@ -2339,37 +2377,31 @@ int mysql_drop_column(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
real_alter_table
(
thd
,
table_list
->
db
,
table_list
->
real_name
,
DBUG_RETURN
(
real_alter_table
(
thd
,
table_list
->
db
,
table_list
->
real_name
,
&
create_info
,
table_list
,
table
,
&
create_info
,
table_list
,
table
,
fields
,
keys
,
drop
,
alter
,
0
,
(
ORDER
*
)
0
,
fields
,
keys
,
drop
,
alter
,
0
,
(
ORDER
*
)
0
,
ALTER_DROP_COLUMN
,
DUP_ERROR
));
ALTER_DROP_COLUMN
,
DUP_ERROR
));
}
}
int
mysql_alter_table
(
THD
*
thd
,
char
*
new_db
,
char
*
new_name
,
int
mysql_alter_table
(
THD
*
thd
,
char
*
new_db
,
char
*
new_name
,
HA_CREATE_INFO
*
create_info
,
HA_CREATE_INFO
*
create_info
,
TABLE_LIST
*
table_list
,
TABLE_LIST
*
table_list
,
List
<
create_field
>
&
fields
,
List
<
create_field
>
&
fields
,
List
<
Key
>
&
keys
,
List
<
Alter_drop
>
&
drop_list
,
List
<
Key
>
&
keys
,
List
<
Alter_drop
>
&
drop_list
,
List
<
Alter_column
>
&
alter_list
,
List
<
Alter_column
>
&
alter_list
,
uint
order_num
,
ORDER
*
order
,
int
alter_flags
,
uint
order_num
,
ORDER
*
order
,
int
alter_flags
,
enum
enum_duplicates
handle_duplicates
,
enum
enum_duplicates
handle_duplicates
,
enum
enum_enable_or_disable
keys_onoff
,
enum
enum_enable_or_disable
keys_onoff
,
enum
tablespace_op_type
tablespace_op
,
enum
tablespace_op_type
tablespace_op
,
bool
simple_alter
)
bool
simple_alter
)
{
{
DBUG_ENTER
(
"mysql_alter_table"
);
DBUG_ENTER
(
"mysql_alter_table"
);
/* !!!!!!!! WARNING: This comment must be removed after a decision !!!!!!!!!
I'm not sure if the next two commands are at the right place here.
I guess that closing all is necessary before table dropping which is
part of alter table, but may be harmful before online DDLs.
So I would put both behind the DDL branches right before open_ltable.
!!!!!!!! WARNING: This comment must be removed after a decision !!!!!! */
mysql_ha_closeall
(
thd
,
table_list
);
mysql_ha_closeall
(
thd
,
table_list
);
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
if
(
tablespace_op
!=
NO_TABLESPACE_OP
)
if
(
tablespace_op
!=
NO_TABLESPACE_OP
)
DBUG_RETURN
(
mysql_discard_or_import_tablespace
(
thd
,
table_list
,
DBUG_RETURN
(
mysql_discard_or_import_tablespace
(
thd
,
table_list
,
tablespace_op
));
tablespace_op
));
if
(
alter_flags
==
ALTER_ADD_INDEX
)
if
(
alter_flags
==
ALTER_ADD_INDEX
)
DBUG_RETURN
(
mysql_create_index
(
thd
,
table_list
,
keys
));
DBUG_RETURN
(
mysql_create_index
(
thd
,
table_list
,
keys
));
...
@@ -2388,24 +2420,24 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2388,24 +2420,24 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
real_alter_table
(
thd
,
new_db
,
new_name
,
DBUG_RETURN
(
real_alter_table
(
thd
,
new_db
,
new_name
,
create_info
,
table_list
,
table
,
fields
,
create_info
,
table_list
,
table
,
fields
,
keys
,
drop_list
,
alter_list
,
keys
,
drop_list
,
alter_list
,
order_num
,
order
,
alter_flags
,
order_num
,
order
,
alter_flags
,
handle_duplicates
,
keys_onoff
,
handle_duplicates
,
keys_onoff
,
tablespace_op
,
simple_alter
));
tablespace_op
,
simple_alter
));
}
}
int
real_alter_table
(
THD
*
thd
,
char
*
new_db
,
char
*
new_name
,
int
real_alter_table
(
THD
*
thd
,
char
*
new_db
,
char
*
new_name
,
HA_CREATE_INFO
*
create_info
,
HA_CREATE_INFO
*
create_info
,
TABLE_LIST
*
table_list
,
TABLE_LIST
*
table_list
,
TABLE
*
table
,
TABLE
*
table
,
List
<
create_field
>
&
fields
,
List
<
create_field
>
&
fields
,
List
<
Key
>
&
keys
,
List
<
Alter_drop
>
&
drop_list
,
List
<
Key
>
&
keys
,
List
<
Alter_drop
>
&
drop_list
,
List
<
Alter_column
>
&
alter_list
,
List
<
Alter_column
>
&
alter_list
,
uint
order_num
,
ORDER
*
order
,
int
alter_flags
,
uint
order_num
,
ORDER
*
order
,
int
alter_flags
,
enum
enum_duplicates
handle_duplicates
,
enum
enum_duplicates
handle_duplicates
,
enum
enum_enable_or_disable
keys_onoff
,
enum
enum_enable_or_disable
keys_onoff
,
enum
tablespace_op_type
tablespace_op
,
enum
tablespace_op_type
tablespace_op
,
bool
simple_alter
)
bool
simple_alter
)
{
{
TABLE
*
new_table
;
TABLE
*
new_table
;
...
@@ -2440,13 +2472,13 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2440,13 +2472,13 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
{
if
(
lower_case_table_names
!=
2
)
if
(
lower_case_table_names
!=
2
)
{
{
my_casedn_str
(
system_charset_info
,
new_name_buff
);
my_casedn_str
(
system_charset_info
,
new_name_buff
);
new_alias
=
new_name
;
// Create lower case table name
new_alias
=
new_name
;
// Create lower case table name
}
}
my_casedn_str
(
system_charset_info
,
new_name
);
my_casedn_str
(
system_charset_info
,
new_name
);
}
}
if
(
new_db
==
db
&&
if
(
new_db
==
db
&&
!
my_strcasecmp
(
table_alias_charset
,
new_name_buff
,
table_name
))
!
my_strcasecmp
(
table_alias_charset
,
new_name_buff
,
table_name
))
{
{
/*
/*
Source and destination table names are equal: make later check
Source and destination table names are equal: make later check
...
@@ -2458,21 +2490,21 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2458,21 +2490,21 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
{
if
(
table
->
tmp_table
)
if
(
table
->
tmp_table
)
{
{
if
(
find_temporary_table
(
thd
,
new_db
,
new_name_buff
))
if
(
find_temporary_table
(
thd
,
new_db
,
new_name_buff
))
{
{
my_error
(
ER_TABLE_EXISTS_ERROR
,
MYF
(
0
),
new_name_buff
);
my_error
(
ER_TABLE_EXISTS_ERROR
,
MYF
(
0
),
new_name_buff
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
}
}
else
else
{
{
if
(
!
access
(
fn_format
(
new_name_buff
,
new_name_buff
,
new_db
,
reg_ext
,
0
),
if
(
!
access
(
fn_format
(
new_name_buff
,
new_name_buff
,
new_db
,
reg_ext
,
0
),
F_OK
))
F_OK
))
{
{
/* Table will be closed in do_command() */
/* Table will be closed in do_command() */
my_error
(
ER_TABLE_EXISTS_ERROR
,
MYF
(
0
),
new_alias
);
my_error
(
ER_TABLE_EXISTS_ERROR
,
MYF
(
0
),
new_alias
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
}
}
}
}
}
}
...
@@ -2487,10 +2519,10 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2487,10 +2519,10 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
{
create_info
->
db_type
=
new_db_type
;
create_info
->
db_type
=
new_db_type
;
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_WARN_USING_OTHER_HANDLER
,
ER_WARN_USING_OTHER_HANDLER
,
ER
(
ER_WARN_USING_OTHER_HANDLER
),
ER
(
ER_WARN_USING_OTHER_HANDLER
),
ha_get_storage_engine
(
new_db_type
),
ha_get_storage_engine
(
new_db_type
),
new_name
);
new_name
);
}
}
if
(
create_info
->
row_type
==
ROW_TYPE_NOT_USED
)
if
(
create_info
->
row_type
==
ROW_TYPE_NOT_USED
)
create_info
->
row_type
=
table
->
row_type
;
create_info
->
row_type
=
table
->
row_type
;
...
@@ -2515,7 +2547,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2515,7 +2547,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
*
fn_ext
(
new_name
)
=
0
;
*
fn_ext
(
new_name
)
=
0
;
close_cached_table
(
thd
,
table
);
close_cached_table
(
thd
,
table
);
if
(
mysql_rename_table
(
old_db_type
,
db
,
table_name
,
new_db
,
new_alias
))
if
(
mysql_rename_table
(
old_db_type
,
db
,
table_name
,
new_db
,
new_alias
))
error
=
-
1
;
error
=
-
1
;
}
}
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
}
}
...
@@ -2524,28 +2556,28 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2524,28 +2556,28 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
{
switch
(
keys_onoff
)
{
switch
(
keys_onoff
)
{
case
LEAVE_AS_IS
:
case
LEAVE_AS_IS
:
break
;
break
;
case
ENABLE
:
case
ENABLE
:
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
wait_while_table_is_used
(
thd
,
table
,
HA_EXTRA_FORCE_REOPEN
);
wait_while_table_is_used
(
thd
,
table
,
HA_EXTRA_FORCE_REOPEN
);
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
error
=
table
->
file
->
activate_all_index
(
thd
);
error
=
table
->
file
->
activate_all_index
(
thd
);
/* COND_refresh will be signaled in close_thread_tables() */
/* COND_refresh will be signaled in close_thread_tables() */
break
;
break
;
case
DISABLE
:
case
DISABLE
:
if
(
table
->
db_type
==
DB_TYPE_MYISAM
)
if
(
table
->
db_type
==
DB_TYPE_MYISAM
)
{
{
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
wait_while_table_is_used
(
thd
,
table
,
HA_EXTRA_FORCE_REOPEN
);
wait_while_table_is_used
(
thd
,
table
,
HA_EXTRA_FORCE_REOPEN
);
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
table
->
file
->
deactivate_non_unique_index
(
HA_POS_ERROR
);
table
->
file
->
deactivate_non_unique_index
(
HA_POS_ERROR
);
/* COND_refresh will be signaled in close_thread_tables() */
/* COND_refresh will be signaled in close_thread_tables() */
}
}
else
else
push_warning_printf
(
current_thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
push_warning_printf
(
current_thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_ILLEGAL_HA
,
ER_ILLEGAL_HA
,
ER
(
ER_ILLEGAL_HA
),
table
->
table_name
);
ER
(
ER_ILLEGAL_HA
),
table
->
table_name
);
break
;
break
;
}
}
}
}
if
(
!
error
)
if
(
!
error
)
...
@@ -2554,12 +2586,12 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2554,12 +2586,12 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
if
(
mysql_bin_log
.
is_open
())
if
(
mysql_bin_log
.
is_open
())
{
{
thd
->
clear_error
();
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
0
);
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
0
);
mysql_bin_log
.
write
(
&
qinfo
);
mysql_bin_log
.
write
(
&
qinfo
);
}
}
send_ok
(
thd
);
send_ok
(
thd
);
}
}
table_list
->
table
=
0
;
// For query cache
table_list
->
table
=
0
;
// For query cache
query_cache_invalidate3
(
thd
,
table_list
,
0
);
query_cache_invalidate3
(
thd
,
table_list
,
0
);
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
}
}
...
@@ -2576,12 +2608,12 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2576,12 +2608,12 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
if
(
!
(
used_fields
&
HA_CREATE_USED_DEFAULT_CHARSET
))
if
(
!
(
used_fields
&
HA_CREATE_USED_DEFAULT_CHARSET
))
create_info
->
default_table_charset
=
table
->
table_charset
;
create_info
->
default_table_charset
=
table
->
table_charset
;
restore_record
(
table
,
default_values
);
// Empty record for DEFAULT
restore_record
(
table
,
default_values
);
// Empty record for DEFAULT
List_iterator
<
Alter_drop
>
drop_it
(
drop_list
);
List_iterator
<
Alter_drop
>
drop_it
(
drop_list
);
List_iterator
<
create_field
>
def_it
(
fields
);
List_iterator
<
create_field
>
def_it
(
fields
);
List_iterator
<
Alter_column
>
alter_it
(
alter_list
);
List_iterator
<
Alter_column
>
alter_it
(
alter_list
);
List
<
create_field
>
create_list
;
// Add new fields here
List
<
create_field
>
create_list
;
// Add new fields here
List
<
Key
>
key_list
;
// Add new keys here
List
<
Key
>
key_list
;
// Add new keys here
create_field
*
def
;
create_field
*
def
;
/*
/*
...
@@ -2597,16 +2629,16 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2597,16 +2629,16 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
while
((
drop
=
drop_it
++
))
while
((
drop
=
drop_it
++
))
{
{
if
(
drop
->
type
==
Alter_drop
::
COLUMN
&&
if
(
drop
->
type
==
Alter_drop
::
COLUMN
&&
!
my_strcasecmp
(
system_charset_info
,
field
->
field_name
,
drop
->
name
))
!
my_strcasecmp
(
system_charset_info
,
field
->
field_name
,
drop
->
name
))
{
{
/* Reset auto_increment value if it was dropped */
/* Reset auto_increment value if it was dropped */
if
(
MTYP_TYPENR
(
field
->
unireg_check
)
==
Field
::
NEXT_NUMBER
&&
if
(
MTYP_TYPENR
(
field
->
unireg_check
)
==
Field
::
NEXT_NUMBER
&&
!
(
used_fields
&
HA_CREATE_USED_AUTO
))
!
(
used_fields
&
HA_CREATE_USED_AUTO
))
{
{
create_info
->
auto_increment_value
=
0
;
create_info
->
auto_increment_value
=
0
;
create_info
->
used_fields
|=
HA_CREATE_USED_AUTO
;
create_info
->
used_fields
|=
HA_CREATE_USED_AUTO
;
}
}
break
;
break
;
}
}
}
}
if
(
drop
)
if
(
drop
)
...
@@ -2620,31 +2652,31 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2620,31 +2652,31 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
{
if
(
def
->
change
&&
if
(
def
->
change
&&
!
my_strcasecmp
(
system_charset_info
,
field
->
field_name
,
def
->
change
))
!
my_strcasecmp
(
system_charset_info
,
field
->
field_name
,
def
->
change
))
break
;
break
;
}
}
if
(
def
)
if
(
def
)
{
// Field is changed
{
// Field is changed
def
->
field
=
field
;
def
->
field
=
field
;
if
(
def
->
sql_type
==
FIELD_TYPE_TIMESTAMP
)
if
(
def
->
sql_type
==
FIELD_TYPE_TIMESTAMP
)
use_timestamp
=
1
;
use_timestamp
=
1
;
if
(
!
def
->
after
)
if
(
!
def
->
after
)
{
{
create_list
.
push_back
(
def
);
create_list
.
push_back
(
def
);
def_it
.
remove
();
def_it
.
remove
();
}
}
}
}
else
else
{
// Use old field value
{
// Use old field value
create_list
.
push_back
(
def
=
new
create_field
(
field
,
field
));
create_list
.
push_back
(
def
=
new
create_field
(
field
,
field
));
if
(
def
->
sql_type
==
FIELD_TYPE_TIMESTAMP
)
if
(
def
->
sql_type
==
FIELD_TYPE_TIMESTAMP
)
use_timestamp
=
1
;
use_timestamp
=
1
;
alter_it
.
rewind
();
// Change default if ALTER
alter_it
.
rewind
();
// Change default if ALTER
Alter_column
*
alter
;
Alter_column
*
alter
;
while
((
alter
=
alter_it
++
))
while
((
alter
=
alter_it
++
))
{
{
if
(
!
my_strcasecmp
(
system_charset_info
,
field
->
field_name
,
alter
->
name
))
if
(
!
my_strcasecmp
(
system_charset_info
,
field
->
field_name
,
alter
->
name
))
break
;
break
;
}
}
if
(
alter
)
if
(
alter
)
{
{
...
@@ -2653,14 +2685,14 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2653,14 +2685,14 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
my_error
(
ER_BLOB_CANT_HAVE_DEFAULT
,
MYF
(
0
),
def
->
change
);
my_error
(
ER_BLOB_CANT_HAVE_DEFAULT
,
MYF
(
0
),
def
->
change
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
def
->
def
=
alter
->
def
;
// Use new default
def
->
def
=
alter
->
def
;
// Use new default
alter_it
.
remove
();
alter_it
.
remove
();
}
}
}
}
}
}
def_it
.
rewind
();
def_it
.
rewind
();
List_iterator
<
create_field
>
find_it
(
create_list
);
List_iterator
<
create_field
>
find_it
(
create_list
);
while
((
def
=
def_it
++
))
// Add new columns
while
((
def
=
def_it
++
))
// Add new columns
{
{
if
(
def
->
change
&&
!
def
->
field
)
if
(
def
->
change
&&
!
def
->
field
)
{
{
...
@@ -2675,17 +2707,17 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2675,17 +2707,17 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
{
create_field
*
find
;
create_field
*
find
;
find_it
.
rewind
();
find_it
.
rewind
();
while
((
find
=
find_it
++
))
// Add new columns
while
((
find
=
find_it
++
))
// Add new columns
{
{
if
(
!
my_strcasecmp
(
system_charset_info
,
def
->
after
,
find
->
field_name
))
if
(
!
my_strcasecmp
(
system_charset_info
,
def
->
after
,
find
->
field_name
))
break
;
break
;
}
}
if
(
!
find
)
if
(
!
find
)
{
{
my_error
(
ER_BAD_FIELD_ERROR
,
MYF
(
0
),
def
->
after
,
table_name
);
my_error
(
ER_BAD_FIELD_ERROR
,
MYF
(
0
),
def
->
after
,
table_name
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
find_it
.
after
(
def
);
// Put element after this
find_it
.
after
(
def
);
// Put element after this
}
}
}
}
if
(
alter_list
.
elements
)
if
(
alter_list
.
elements
)
...
@@ -2717,8 +2749,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2717,8 +2749,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
while
((
drop
=
drop_it
++
))
while
((
drop
=
drop_it
++
))
{
{
if
(
drop
->
type
==
Alter_drop
::
KEY
&&
if
(
drop
->
type
==
Alter_drop
::
KEY
&&
!
my_strcasecmp
(
system_charset_info
,
key_name
,
drop
->
name
))
!
my_strcasecmp
(
system_charset_info
,
key_name
,
drop
->
name
))
break
;
break
;
}
}
if
(
drop
)
if
(
drop
)
{
{
...
@@ -2731,60 +2763,60 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2731,60 +2763,60 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
for
(
uint
j
=
0
;
j
<
key_info
->
key_parts
;
j
++
,
key_part
++
)
for
(
uint
j
=
0
;
j
<
key_info
->
key_parts
;
j
++
,
key_part
++
)
{
{
if
(
!
key_part
->
field
)
if
(
!
key_part
->
field
)
continue
;
// Wrong field (from UNIREG)
continue
;
// Wrong field (from UNIREG)
const
char
*
key_part_name
=
key_part
->
field
->
field_name
;
const
char
*
key_part_name
=
key_part
->
field
->
field_name
;
create_field
*
cfield
;
create_field
*
cfield
;
field_it
.
rewind
();
field_it
.
rewind
();
while
((
cfield
=
field_it
++
))
while
((
cfield
=
field_it
++
))
{
{
if
(
cfield
->
change
)
if
(
cfield
->
change
)
{
{
if
(
!
my_strcasecmp
(
system_charset_info
,
key_part_name
,
if
(
!
my_strcasecmp
(
system_charset_info
,
key_part_name
,
cfield
->
change
))
cfield
->
change
))
break
;
break
;
}
}
else
if
(
!
my_strcasecmp
(
system_charset_info
,
else
if
(
!
my_strcasecmp
(
system_charset_info
,
key_part_name
,
cfield
->
field_name
))
key_part_name
,
cfield
->
field_name
))
break
;
break
;
}
}
if
(
!
cfield
)
if
(
!
cfield
)
continue
;
// Field is removed
continue
;
// Field is removed
uint
key_part_length
=
key_part
->
length
;
uint
key_part_length
=
key_part
->
length
;
if
(
cfield
->
field
)
// Not new field
if
(
cfield
->
field
)
// Not new field
{
// Check if sub key
{
// Check if sub key
if
(
cfield
->
field
->
type
()
!=
FIELD_TYPE_BLOB
&&
if
(
cfield
->
field
->
type
()
!=
FIELD_TYPE_BLOB
&&
(
cfield
->
field
->
pack_length
()
==
key_part_length
||
(
cfield
->
field
->
pack_length
()
==
key_part_length
||
cfield
->
length
<=
key_part_length
/
cfield
->
length
<=
key_part_length
/
key_part
->
field
->
charset
()
->
mbmaxlen
))
key_part
->
field
->
charset
()
->
mbmaxlen
))
key_part_length
=
0
;
// Use whole field
key_part_length
=
0
;
// Use whole field
}
}
key_part_length
/=
key_part
->
field
->
charset
()
->
mbmaxlen
;
key_part_length
/=
key_part
->
field
->
charset
()
->
mbmaxlen
;
key_parts
.
push_back
(
new
key_part_spec
(
cfield
->
field_name
,
key_parts
.
push_back
(
new
key_part_spec
(
cfield
->
field_name
,
key_part_length
));
key_part_length
));
}
}
if
(
key_parts
.
elements
)
if
(
key_parts
.
elements
)
key_list
.
push_back
(
new
Key
(
key_info
->
flags
&
HA_SPATIAL
?
Key
::
SPATIAL
:
key_list
.
push_back
(
new
Key
(
key_info
->
flags
&
HA_SPATIAL
?
Key
::
SPATIAL
:
(
key_info
->
flags
&
HA_NOSAME
?
(
key_info
->
flags
&
HA_NOSAME
?
(
!
my_strcasecmp
(
system_charset_info
,
(
!
my_strcasecmp
(
system_charset_info
,
key_name
,
primary_key_name
)
?
key_name
,
primary_key_name
)
?
Key
::
PRIMARY
:
Key
::
UNIQUE
)
:
Key
::
PRIMARY
:
Key
::
UNIQUE
)
:
(
key_info
->
flags
&
HA_FULLTEXT
?
(
key_info
->
flags
&
HA_FULLTEXT
?
Key
::
FULLTEXT
:
Key
::
MULTIPLE
)),
Key
::
FULLTEXT
:
Key
::
MULTIPLE
)),
key_name
,
key_name
,
key_info
->
algorithm
,
key_info
->
algorithm
,
key_parts
));
key_parts
));
}
}
{
{
Key
*
key
;
Key
*
key
;
while
((
key
=
key_it
++
))
// Add new keys
while
((
key
=
key_it
++
))
// Add new keys
{
{
if
(
key
->
type
!=
Key
::
FOREIGN_KEY
)
if
(
key
->
type
!=
Key
::
FOREIGN_KEY
)
key_list
.
push_back
(
key
);
key_list
.
push_back
(
key
);
if
(
key
->
name
&&
if
(
key
->
name
&&
!
my_strcasecmp
(
system_charset_info
,
key
->
name
,
primary_key_name
))
!
my_strcasecmp
(
system_charset_info
,
key
->
name
,
primary_key_name
))
{
{
my_error
(
ER_WRONG_NAME_FOR_INDEX
,
MYF
(
0
),
key
->
name
);
my_error
(
ER_WRONG_NAME_FOR_INDEX
,
MYF
(
0
),
key
->
name
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
}
}
}
}
...
@@ -2801,8 +2833,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2801,8 +2833,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
}
}
db_create_options
=
table
->
db_create_options
&
~
(
HA_OPTION_PACK_RECORD
);
db_create_options
=
table
->
db_create_options
&
~
(
HA_OPTION_PACK_RECORD
);
(
void
)
sprintf
(
tmp_name
,
"%s-%lx_%lx"
,
tmp_file_prefix
,
current_pid
,
if
(
snprintf
(
tmp_name
,
sizeof
(
tmp_name
),
"%s-%lx_%lx"
,
tmp_file_prefix
,
thd
->
thread_id
);
current_pid
,
thd
->
thread_id
)
>=
(
int
)
sizeof
(
tmp_name
))
goto
err
;
create_info
->
db_type
=
new_db_type
;
create_info
->
db_type
=
new_db_type
;
if
(
!
create_info
->
comment
)
if
(
!
create_info
->
comment
)
create_info
->
comment
=
table
->
comment
;
create_info
->
comment
=
table
->
comment
;
...
@@ -2818,7 +2851,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2818,7 +2851,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
if
(
create_info
->
table_options
&
if
(
create_info
->
table_options
&
(
HA_OPTION_DELAY_KEY_WRITE
|
HA_OPTION_NO_DELAY_KEY_WRITE
))
(
HA_OPTION_DELAY_KEY_WRITE
|
HA_OPTION_NO_DELAY_KEY_WRITE
))
db_create_options
&=
~
(
HA_OPTION_DELAY_KEY_WRITE
|
db_create_options
&=
~
(
HA_OPTION_DELAY_KEY_WRITE
|
HA_OPTION_NO_DELAY_KEY_WRITE
);
HA_OPTION_NO_DELAY_KEY_WRITE
);
create_info
->
table_options
|=
db_create_options
;
create_info
->
table_options
|=
db_create_options
;
if
(
table
->
tmp_table
)
if
(
table
->
tmp_table
)
...
@@ -2849,31 +2882,31 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2849,31 +2882,31 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
Remove old table and symlinks.
Remove old table and symlinks.
*/
*/
if
(
!
strcmp
(
db
,
new_db
))
// Ignore symlink if db changed
if
(
!
strcmp
(
db
,
new_db
))
// Ignore symlink if db changed
{
{
if
(
create_info
->
index_file_name
)
if
(
create_info
->
index_file_name
)
{
{
/* Fix index_file_name to have 'tmp_name' as basename */
/* Fix index_file_name to have 'tmp_name' as basename */
strmov
(
index_file
,
tmp_name
);
strmov
(
index_file
,
tmp_name
);
create_info
->
index_file_name
=
fn_same
(
index_file
,
create_info
->
index_file_name
=
fn_same
(
index_file
,
create_info
->
index_file_name
,
create_info
->
index_file_name
,
1
);
1
);
}
}
if
(
create_info
->
data_file_name
)
if
(
create_info
->
data_file_name
)
{
{
/* Fix data_file_name to have 'tmp_name' as basename */
/* Fix data_file_name to have 'tmp_name' as basename */
strmov
(
data_file
,
tmp_name
);
strmov
(
data_file
,
tmp_name
);
create_info
->
data_file_name
=
fn_same
(
data_file
,
create_info
->
data_file_name
=
fn_same
(
data_file
,
create_info
->
data_file_name
,
create_info
->
data_file_name
,
1
);
1
);
}
}
}
}
else
else
create_info
->
data_file_name
=
create_info
->
index_file_name
=
0
;
create_info
->
data_file_name
=
create_info
->
index_file_name
=
0
;
if
((
error
=
mysql_create_table
(
thd
,
new_db
,
tmp_name
,
if
((
error
=
mysql_create_table
(
thd
,
new_db
,
tmp_name
,
create_info
,
create_info
,
create_list
,
key_list
,
1
,
1
,
0
)))
// no logging
create_list
,
key_list
,
1
,
1
,
0
)))
// no logging
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
if
(
table
->
tmp_table
)
if
(
table
->
tmp_table
)
...
@@ -2881,7 +2914,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2881,7 +2914,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
else
else
{
{
char
path
[
FN_REFLEN
];
char
path
[
FN_REFLEN
];
(
void
)
sprintf
(
path
,
"%s/%s/%s"
,
mysql_data_home
,
new_db
,
tmp_name
);
if
(
snprintf
(
path
,
sizeof
(
path
),
"%s/%s/%s"
,
mysql_data_home
,
new_db
,
tmp_name
)
>=
(
int
)
sizeof
(
path
))
goto
err
;
fn_format
(
path
,
path
,
""
,
""
,
4
);
fn_format
(
path
,
path
,
""
,
""
,
4
);
new_table
=
open_temporary_table
(
thd
,
path
,
new_db
,
tmp_name
,
0
);
new_table
=
open_temporary_table
(
thd
,
path
,
new_db
,
tmp_name
,
0
);
}
}
...
@@ -2895,16 +2930,16 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2895,16 +2930,16 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
if
(
use_timestamp
)
if
(
use_timestamp
)
new_table
->
time_stamp
=
0
;
new_table
->
time_stamp
=
0
;
new_table
->
next_number_field
=
new_table
->
found_next_number_field
;
new_table
->
next_number_field
=
new_table
->
found_next_number_field
;
thd
->
count_cuted_fields
=
CHECK_FIELD_WARN
;
// calc cuted fields
thd
->
count_cuted_fields
=
CHECK_FIELD_WARN
;
// calc cuted fields
thd
->
cuted_fields
=
0L
;
thd
->
cuted_fields
=
0L
;
thd
->
proc_info
=
"copy to tmp table"
;
thd
->
proc_info
=
"copy to tmp table"
;
next_insert_id
=
thd
->
next_insert_id
;
// Remember for loggin
next_insert_id
=
thd
->
next_insert_id
;
// Remember for loggin
copied
=
deleted
=
0
;
copied
=
deleted
=
0
;
if
(
!
new_table
->
is_view
)
if
(
!
new_table
->
is_view
)
error
=
copy_data_between_tables
(
table
,
new_table
,
create_list
,
error
=
copy_data_between_tables
(
table
,
new_table
,
create_list
,
handle_duplicates
,
handle_duplicates
,
order_num
,
order
,
&
copied
,
&
deleted
);
order_num
,
order
,
&
copied
,
&
deleted
);
thd
->
last_insert_id
=
next_insert_id
;
// Needed for correct log
thd
->
last_insert_id
=
next_insert_id
;
// Needed for correct log
thd
->
count_cuted_fields
=
CHECK_FIELD_IGNORE
;
thd
->
count_cuted_fields
=
CHECK_FIELD_IGNORE
;
new_table
->
time_stamp
=
save_time_stamp
;
new_table
->
time_stamp
=
save_time_stamp
;
...
@@ -2914,8 +2949,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2914,8 +2949,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
if
(
error
)
if
(
error
)
{
{
/*
/*
The following function call will free the new_table pointer,
The following function call will free the new_table pointer,
in close_temporary_table(), so we can safely directly jump to err
in close_temporary_table(), so we can safely directly jump to err
*/
*/
close_temporary_table
(
thd
,
new_db
,
tmp_name
);
close_temporary_table
(
thd
,
new_db
,
tmp_name
);
goto
err
;
goto
err
;
...
@@ -2929,7 +2964,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2929,7 +2964,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
/* Remove link to old table and rename the new one */
/* Remove link to old table and rename the new one */
close_temporary_table
(
thd
,
table
->
table_cache_key
,
table_name
);
close_temporary_table
(
thd
,
table
->
table_cache_key
,
table_name
);
if
(
rename_temporary_table
(
thd
,
new_table
,
new_db
,
new_alias
))
if
(
rename_temporary_table
(
thd
,
new_table
,
new_db
,
new_alias
))
{
// Fatal error
{
// Fatal error
close_temporary_table
(
thd
,
new_db
,
tmp_name
);
close_temporary_table
(
thd
,
new_db
,
tmp_name
);
my_free
((
gptr
)
new_table
,
MYF
(
0
));
my_free
((
gptr
)
new_table
,
MYF
(
0
));
goto
err
;
goto
err
;
...
@@ -2944,7 +2979,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2944,7 +2979,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
goto
end_temporary
;
goto
end_temporary
;
}
}
intern_close_table
(
new_table
);
/* close temporary table */
intern_close_table
(
new_table
);
/* close temporary table */
my_free
((
gptr
)
new_table
,
MYF
(
0
));
my_free
((
gptr
)
new_table
,
MYF
(
0
));
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
if
(
error
)
if
(
error
)
...
@@ -2961,8 +2996,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2961,8 +2996,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
*/
*/
thd
->
proc_info
=
"rename result table"
;
thd
->
proc_info
=
"rename result table"
;
sprintf
(
old_name
,
"%s2-%lx-%lx"
,
tmp_file_prefix
,
current_pid
,
if
(
snprintf
(
old_name
,
sizeof
(
old_name
),
"%s2-%lx-%lx"
,
tmp_file_prefix
,
thd
->
thread_id
);
current_pid
,
thd
->
thread_id
)
>=
(
int
)
sizeof
(
old_name
))
goto
err
;
if
(
new_name
!=
table_name
||
new_db
!=
db
)
if
(
new_name
!=
table_name
||
new_db
!=
db
)
{
{
if
(
!
access
(
new_name_buff
,
F_OK
))
if
(
!
access
(
new_name_buff
,
F_OK
))
...
@@ -2983,18 +3019,18 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -2983,18 +3019,18 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
Win32 and InnoDB can't drop a table that is in use, so we must
Win32 and InnoDB can't drop a table that is in use, so we must
close the original table at before doing the rename
close the original table at before doing the rename
*/
*/
table_name
=
thd
->
strdup
(
table_name
);
// must be saved
table_name
=
thd
->
strdup
(
table_name
);
// must be saved
if
(
close_cached_table
(
thd
,
table
))
if
(
close_cached_table
(
thd
,
table
))
{
// Aborted
{
// Aborted
VOID
(
quick_rm_table
(
new_db_type
,
new_db
,
tmp_name
));
VOID
(
quick_rm_table
(
new_db_type
,
new_db
,
tmp_name
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
goto
err
;
goto
err
;
}
}
table
=
0
;
// Marker that table is closed
table
=
0
;
// Marker that table is closed
}
}
#if (!defined( __WIN__) && !defined( __EMX__) && !defined( OS2))
#if (!defined( __WIN__) && !defined( __EMX__) && !defined( OS2))
else
else
table
->
file
->
extra
(
HA_EXTRA_FORCE_REOPEN
);
// Don't use this file anymore
table
->
file
->
extra
(
HA_EXTRA_FORCE_REOPEN
);
// Don't use this file anymore
#endif
#endif
...
@@ -3005,8 +3041,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -3005,8 +3041,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
VOID
(
quick_rm_table
(
new_db_type
,
new_db
,
tmp_name
));
VOID
(
quick_rm_table
(
new_db_type
,
new_db
,
tmp_name
));
}
}
else
if
(
mysql_rename_table
(
new_db_type
,
new_db
,
tmp_name
,
new_db
,
else
if
(
mysql_rename_table
(
new_db_type
,
new_db
,
tmp_name
,
new_db
,
new_alias
))
new_alias
))
{
// Try to get everything back
{
// Try to get everything back
error
=
1
;
error
=
1
;
VOID
(
quick_rm_table
(
new_db_type
,
new_db
,
new_alias
));
VOID
(
quick_rm_table
(
new_db_type
,
new_db
,
new_alias
));
VOID
(
quick_rm_table
(
new_db_type
,
new_db
,
tmp_name
));
VOID
(
quick_rm_table
(
new_db_type
,
new_db
,
tmp_name
));
...
@@ -3023,7 +3059,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -3023,7 +3059,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
goto
err
;
goto
err
;
}
}
if
(
thd
->
lock
||
new_name
!=
table_name
)
// True if WIN32
if
(
thd
->
lock
||
new_name
!=
table_name
)
// True if WIN32
{
{
/*
/*
Not table locking or alter table with rename
Not table locking or alter table with rename
...
@@ -3044,14 +3080,14 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -3044,14 +3080,14 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
{
VOID
(
table
->
file
->
extra
(
HA_EXTRA_FORCE_REOPEN
));
// Use new file
VOID
(
table
->
file
->
extra
(
HA_EXTRA_FORCE_REOPEN
));
// Use new file
remove_table_from_cache
(
thd
,
db
,
table_name
);
// Mark all in-use copies old
remove_table_from_cache
(
thd
,
db
,
table_name
);
// Mark all in-use copies old
mysql_lock_abort
(
thd
,
table
);
// end threads waiting on lock
mysql_lock_abort
(
thd
,
table
);
// end threads waiting on lock
}
}
VOID
(
quick_rm_table
(
old_db_type
,
db
,
old_name
));
VOID
(
quick_rm_table
(
old_db_type
,
db
,
old_name
));
if
(
close_data_tables
(
thd
,
db
,
table_name
)
||
if
(
close_data_tables
(
thd
,
db
,
table_name
)
||
reopen_tables
(
thd
,
1
,
0
))
reopen_tables
(
thd
,
1
,
0
))
{
// This shouldn't happen
{
// This shouldn't happen
if
(
table
)
if
(
table
)
close_cached_table
(
thd
,
table
);
// Remove lock for table
close_cached_table
(
thd
,
table
);
// Remove lock for table
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
goto
err
;
goto
err
;
}
}
...
@@ -3085,7 +3121,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -3085,7 +3121,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
shutdown.
shutdown.
*/
*/
char
path
[
FN_REFLEN
];
char
path
[
FN_REFLEN
];
(
void
)
sprintf
(
path
,
"%s/%s/%s"
,
mysql_data_home
,
new_db
,
table_name
);
if
(
snprintf
(
path
,
sizeof
(
path
),
"%s/%s/%s"
,
mysql_data_home
,
new_db
,
table_name
)
>=
(
int
)
sizeof
(
path
))
goto
err
;
fn_format
(
path
,
path
,
""
,
""
,
4
);
fn_format
(
path
,
path
,
""
,
""
,
4
);
table
=
open_temporary_table
(
thd
,
path
,
new_db
,
tmp_name
,
0
);
table
=
open_temporary_table
(
thd
,
path
,
new_db
,
tmp_name
,
0
);
if
(
table
)
if
(
table
)
...
@@ -3095,16 +3133,18 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
...
@@ -3095,16 +3133,18 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
}
}
else
else
sql_print_error
(
"Warning: Could not open BDB table %s.%s after rename
\n
"
,
sql_print_error
(
"Warning: Could not open BDB table %s.%s after rename
\n
"
,
new_db
,
table_name
);
new_db
,
table_name
);
(
void
)
berkeley_flush_logs
();
(
void
)
berkeley_flush_logs
();
}
}
#endif
#endif
table_list
->
table
=
0
;
// For query cache
table_list
->
table
=
0
;
// For query cache
query_cache_invalidate3
(
thd
,
table_list
,
0
);
query_cache_invalidate3
(
thd
,
table_list
,
0
);
end_temporary:
end_temporary:
sprintf
(
tmp_name
,
ER
(
ER_INSERT_INFO
),
(
ulong
)
(
copied
+
deleted
),
if
(
snprintf
(
tmp_name
,
sizeof
(
tmp_name
),
ER
(
ER_INSERT_INFO
),
(
ulong
)
deleted
,
(
ulong
)
thd
->
cuted_fields
);
(
ulong
)
(
copied
+
deleted
),
(
ulong
)
deleted
,
(
ulong
)
thd
->
cuted_fields
)
>=
(
int
)
sizeof
(
tmp_name
))
goto
err
;
send_ok
(
thd
,
copied
+
deleted
,
0L
,
tmp_name
);
send_ok
(
thd
,
copied
+
deleted
,
0L
,
tmp_name
);
thd
->
some_tables_deleted
=
0
;
thd
->
some_tables_deleted
=
0
;
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
...
@@ -3117,9 +3157,9 @@ end_temporary:
...
@@ -3117,9 +3157,9 @@ end_temporary:
static
int
static
int
copy_data_between_tables
(
TABLE
*
from
,
TABLE
*
to
,
copy_data_between_tables
(
TABLE
*
from
,
TABLE
*
to
,
List
<
create_field
>
&
create
,
List
<
create_field
>
&
create
,
enum
enum_duplicates
handle_duplicates
,
enum
enum_duplicates
handle_duplicates
,
uint
order_num
,
ORDER
*
order
,
uint
order_num
,
ORDER
*
order
,
ha_rows
*
copied
,
ha_rows
*
copied
,
ha_rows
*
deleted
)
ha_rows
*
deleted
)
{
{
int
error
;
int
error
;
...
@@ -3137,7 +3177,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
...
@@ -3137,7 +3177,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
DBUG_ENTER
(
"copy_data_between_tables"
);
DBUG_ENTER
(
"copy_data_between_tables"
);
if
(
!
(
copy
=
new
Copy_field
[
to
->
fields
]))
if
(
!
(
copy
=
new
Copy_field
[
to
->
fields
]))
DBUG_RETURN
(
-
1
);
/* purecov: inspected */
DBUG_RETURN
(
-
1
);
/* purecov: inspected */
to
->
file
->
external_lock
(
thd
,
F_WRLCK
);
to
->
file
->
external_lock
(
thd
,
F_WRLCK
);
to
->
file
->
extra
(
HA_EXTRA_WRITE_CACHE
);
to
->
file
->
extra
(
HA_EXTRA_WRITE_CACHE
);
...
@@ -3163,12 +3203,12 @@ copy_data_between_tables(TABLE *from,TABLE *to,
...
@@ -3163,12 +3203,12 @@ copy_data_between_tables(TABLE *from,TABLE *to,
bzero
((
char
*
)
&
tables
,
sizeof
(
tables
));
bzero
((
char
*
)
&
tables
,
sizeof
(
tables
));
tables
.
table
=
from
;
tables
.
table
=
from
;
tables
.
alias
=
tables
.
real_name
=
from
->
real_name
;
tables
.
alias
=
tables
.
real_name
=
from
->
real_name
;
tables
.
db
=
from
->
table_cache_key
;
tables
.
db
=
from
->
table_cache_key
;
error
=
1
;
error
=
1
;
if
(
thd
->
lex
->
select_lex
.
setup_ref_array
(
thd
,
order_num
)
||
if
(
thd
->
lex
->
select_lex
.
setup_ref_array
(
thd
,
order_num
)
||
setup_order
(
thd
,
thd
->
lex
->
select_lex
.
ref_pointer_array
,
setup_order
(
thd
,
thd
->
lex
->
select_lex
.
ref_pointer_array
,
&
tables
,
fields
,
all_fields
,
order
)
||
&
tables
,
fields
,
all_fields
,
order
)
||
!
(
sortorder
=
make_unireg_sortorder
(
order
,
&
length
))
||
!
(
sortorder
=
make_unireg_sortorder
(
order
,
&
length
))
||
(
from
->
sort
.
found_records
=
filesort
(
thd
,
from
,
sortorder
,
length
,
(
from
->
sort
.
found_records
=
filesort
(
thd
,
from
,
sortorder
,
length
,
(
SQL_SELECT
*
)
0
,
HA_POS_ERROR
,
(
SQL_SELECT
*
)
0
,
HA_POS_ERROR
,
...
@@ -3209,12 +3249,12 @@ copy_data_between_tables(TABLE *from,TABLE *to,
...
@@ -3209,12 +3249,12 @@ copy_data_between_tables(TABLE *from,TABLE *to,
if
((
error
=
to
->
file
->
write_row
((
byte
*
)
to
->
record
[
0
])))
if
((
error
=
to
->
file
->
write_row
((
byte
*
)
to
->
record
[
0
])))
{
{
if
((
handle_duplicates
!=
DUP_IGNORE
&&
if
((
handle_duplicates
!=
DUP_IGNORE
&&
handle_duplicates
!=
DUP_REPLACE
)
||
handle_duplicates
!=
DUP_REPLACE
)
||
(
error
!=
HA_ERR_FOUND_DUPP_KEY
&&
(
error
!=
HA_ERR_FOUND_DUPP_KEY
&&
error
!=
HA_ERR_FOUND_DUPP_UNIQUE
))
error
!=
HA_ERR_FOUND_DUPP_UNIQUE
))
{
{
to
->
file
->
print_error
(
error
,
MYF
(
0
));
to
->
file
->
print_error
(
error
,
MYF
(
0
));
break
;
break
;
}
}
delete_count
++
;
delete_count
++
;
}
}
...
@@ -3223,7 +3263,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
...
@@ -3223,7 +3263,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
}
}
end_read_record
(
&
info
);
end_read_record
(
&
info
);
free_io_cache
(
from
);
free_io_cache
(
from
);
delete
[]
copy
;
// This is never 0
delete
[]
copy
;
// This is never 0
uint
tmp_error
;
uint
tmp_error
;
if
((
tmp_error
=
to
->
file
->
extra
(
HA_EXTRA_NO_CACHE
)))
if
((
tmp_error
=
to
->
file
->
extra
(
HA_EXTRA_NO_CACHE
)))
{
{
...
@@ -3276,7 +3316,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
...
@@ -3276,7 +3316,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
strxmov
(
table_name
,
table
->
db
,
"."
,
table
->
real_name
,
NullS
);
strxmov
(
table_name
,
table
->
db
,
"."
,
table
->
real_name
,
NullS
);
t
=
table
->
table
=
open_ltable
(
thd
,
table
,
TL_READ_NO_INSERT
);
t
=
table
->
table
=
open_ltable
(
thd
,
table
,
TL_READ_NO_INSERT
);
thd
->
clear_error
();
// these errors shouldn't get client
thd
->
clear_error
();
// these errors shouldn't get client
protocol
->
prepare_for_resend
();
protocol
->
prepare_for_resend
();
protocol
->
store
(
table_name
,
system_charset_info
);
protocol
->
store
(
table_name
,
system_charset_info
);
...
@@ -3295,7 +3335,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
...
@@ -3295,7 +3335,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
!
(
check_opt
->
flags
&
T_EXTEND
))
!
(
check_opt
->
flags
&
T_EXTEND
))
protocol
->
store
((
ulonglong
)
t
->
file
->
checksum
());
protocol
->
store
((
ulonglong
)
t
->
file
->
checksum
());
else
if
(
!
(
t
->
file
->
table_flags
()
&
HA_HAS_CHECKSUM
)
&&
else
if
(
!
(
t
->
file
->
table_flags
()
&
HA_HAS_CHECKSUM
)
&&
(
check_opt
->
flags
&
T_QUICK
))
(
check_opt
->
flags
&
T_QUICK
))
protocol
->
store_null
();
protocol
->
store_null
();
else
else
{
{
...
@@ -3316,7 +3356,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
...
@@ -3316,7 +3356,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
ha_checksum
row_crc
=
0
;
ha_checksum
row_crc
=
0
;
if
(
t
->
record
[
0
]
!=
(
byte
*
)
t
->
field
[
0
]
->
ptr
)
if
(
t
->
record
[
0
]
!=
(
byte
*
)
t
->
field
[
0
]
->
ptr
)
row_crc
=
my_checksum
(
row_crc
,
t
->
record
[
0
],
row_crc
=
my_checksum
(
row_crc
,
t
->
record
[
0
],
((
byte
*
)
t
->
field
[
0
]
->
ptr
)
-
t
->
record
[
0
]);
((
byte
*
)
t
->
field
[
0
]
->
ptr
)
-
t
->
record
[
0
]);
for
(
uint
i
=
0
;
i
<
t
->
fields
;
i
++
)
for
(
uint
i
=
0
;
i
<
t
->
fields
;
i
++
)
{
{
...
@@ -3329,7 +3369,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
...
@@ -3329,7 +3369,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
}
}
else
else
row_crc
=
my_checksum
(
row_crc
,
(
byte
*
)
f
->
ptr
,
row_crc
=
my_checksum
(
row_crc
,
(
byte
*
)
f
->
ptr
,
f
->
pack_length
());
f
->
pack_length
());
}
}
crc
+=
row_crc
;
crc
+=
row_crc
;
...
@@ -3339,7 +3379,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
...
@@ -3339,7 +3379,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
}
}
thd
->
clear_error
();
thd
->
clear_error
();
close_thread_tables
(
thd
);
close_thread_tables
(
thd
);
table
->
table
=
0
;
// For query cache
table
->
table
=
0
;
// For query cache
}
}
if
(
protocol
->
write
())
if
(
protocol
->
write
())
goto
err
;
goto
err
;
...
@@ -3349,7 +3389,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
...
@@ -3349,7 +3389,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
err:
err:
close_thread_tables
(
thd
);
// Shouldn't be needed
close_thread_tables
(
thd
);
// Shouldn't be needed
if
(
table
)
if
(
table
)
table
->
table
=
0
;
table
->
table
=
0
;
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
...
...
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