Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
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";
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
int
copy_data_between_tables
(
TABLE
*
from
,
TABLE
*
to
,
List
<
create_field
>
&
create
,
enum
enum_duplicates
handle_duplicates
,
List
<
create_field
>
&
create
,
enum
enum_duplicates
handle_duplicates
,
uint
order_num
,
ORDER
*
order
,
ha_rows
*
copied
,
ha_rows
*
deleted
);
ha_rows
*
copied
,
ha_rows
*
deleted
);
/*
delete (drop) tables.
SYNOPSIS
mysql_rm_table()
thd
Thread handle
tables
List of tables to delete
if_exists
If 1, don't give error if one table doesn't exists
thd
Thread handle
tables
List of tables to delete
if_exists
If 1, don't give error if one table doesn't exists
NOTES
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,
Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set.
RETURN
0
ok. In this case ok packet is sent to user
-1
Error (Error message given but not sent to user)
0
ok. In this case ok packet is 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
,
my_bool
drop_temporary
)
my_bool
drop_temporary
)
{
int
error
=
0
;
DBUG_ENTER
(
"mysql_rm_table"
);
...
...
@@ -79,7 +79,7 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
if
(
thd
->
global_read_lock
)
{
my_error
(
ER_TABLE_NOT_LOCKED_FOR_WRITE
,
MYF
(
0
),
tables
->
real_name
);
tables
->
real_name
);
error
=
1
;
goto
err
;
}
...
...
@@ -111,23 +111,23 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
SYNOPSIS
mysql_rm_table_part2_with_lock()
thd
Thread handle
tables
List of tables to delete
if_exists
If 1, don't give error if one table doesn't exists
dont_log_query
Don't write query to log files
thd
Thread handle
tables
List of tables to delete
if_exists
If 1, don't give error if one table doesn't exists
dont_log_query
Don't write query to log files
NOTES
Works like documented in mysql_rm_table(), but don't check
global_read_lock and don't send_ok packet to server.
RETURN
0
ok
1
error
0
ok
1
error
*/
int
mysql_rm_table_part2_with_lock
(
THD
*
thd
,
TABLE_LIST
*
tables
,
bool
if_exists
,
bool
drop_temporary
,
bool
dont_log_query
)
TABLE_LIST
*
tables
,
bool
if_exists
,
bool
drop_temporary
,
bool
dont_log_query
)
{
int
error
;
thd
->
mysys_var
->
current_mutex
=
&
LOCK_open
;
...
...
@@ -135,7 +135,7 @@ int mysql_rm_table_part2_with_lock(THD *thd,
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
error
=
mysql_rm_table_part2
(
thd
,
tables
,
if_exists
,
drop_temporary
,
dont_log_query
);
dont_log_query
);
pthread_mutex_unlock
(
&
LOCK_open
);
...
...
@@ -152,12 +152,12 @@ int mysql_rm_table_part2_with_lock(THD *thd,
SYNOPSIS
mysql_rm_table_part2()
thd
Thread handler
tables
Tables to drop
if_exists
If set, don't give an error if table doesn't exists.
In this case we give an warning of level 'NOTE'
drop_temporary
Only drop temporary tables
dont_log_query
Don't log the query
thd
Thread handler
tables
Tables to drop
if_exists
If set, don't give an error if table doesn't exists.
In this case we give an warning of level 'NOTE'
drop_temporary
Only drop temporary tables
dont_log_query
Don't log the query
TODO:
When logging to the binary log, we should log
...
...
@@ -170,16 +170,16 @@ int mysql_rm_table_part2_with_lock(THD *thd,
not all.
RETURN
0
ok
1
Error
-1
Thread was killed
0
ok
1
Error
-1
Thread was killed
*/
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
;
char
path
[
FN_REFLEN
],
*
alias
;
char
path
[
FN_REFLEN
],
*
alias
;
String
wrong_tables
;
int
error
;
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,
if
(
!
close_temporary_table
(
thd
,
db
,
table
->
real_name
))
{
tmp_table_deleted
=
1
;
continue
;
// removed temporary table
continue
;
// removed temporary table
}
error
=
0
;
...
...
@@ -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
);
while
(
remove_table_from_cache
(
thd
,
db
,
table
->
real_name
)
&&
!
thd
->
killed
)
{
dropping_tables
++
;
(
void
)
pthread_cond_wait
(
&
COND_refresh
,
&
LOCK_open
);
dropping_tables
--
;
dropping_tables
++
;
(
void
)
pthread_cond_wait
(
&
COND_refresh
,
&
LOCK_open
);
dropping_tables
--
;
}
drop_locked_tables
(
thd
,
db
,
table
->
real_name
);
if
(
thd
->
killed
)
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
alias
=
(
lower_case_table_names
==
2
)
?
table
->
alias
:
table
->
real_name
;
/* remove form file and isam files */
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,
if
(
drop_temporary
||
access
(
path
,
F_OK
))
{
if
(
if_exists
)
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_NOTE
,
ER_BAD_TABLE_ERROR
,
ER
(
ER_BAD_TABLE_ERROR
),
table
->
real_name
);
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_NOTE
,
ER_BAD_TABLE_ERROR
,
ER
(
ER_BAD_TABLE_ERROR
),
table
->
real_name
);
else
error
=
1
;
}
...
...
@@ -229,27 +229,27 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
{
char
*
end
;
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
);
if
(
error
==
ENOENT
&&
if_exists
)
error
=
0
;
error
=
0
;
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
;
}
if
(
!
error
||
error
==
ENOENT
)
{
/* Delete the table definition file */
strmov
(
end
,
reg_ext
);
if
(
!
(
error
=
my_delete
(
path
,
MYF
(
MY_WME
))))
some_tables_deleted
=
1
;
/* Delete the table definition file */
strmov
(
end
,
reg_ext
);
if
(
!
(
error
=
my_delete
(
path
,
MYF
(
MY_WME
))))
some_tables_deleted
=
1
;
}
}
if
(
error
)
{
if
(
wrong_tables
.
length
())
wrong_tables
.
append
(
','
);
wrong_tables
.
append
(
','
);
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,
if
(
mysql_bin_log
.
is_open
())
{
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
tmp_table_deleted
&&
!
some_tables_deleted
);
mysql_bin_log
.
write
(
&
qinfo
);
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
tmp_table_deleted
&&
!
some_tables_deleted
);
mysql_bin_log
.
write
(
&
qinfo
);
}
}
}
...
...
@@ -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
,
const
char
*
table_name
)
const
char
*
table_name
)
{
char
path
[
FN_REFLEN
];
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
);
if
(
my_delete
(
path
,
MYF
(
0
)))
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
);
return
ha_delete_table
(
base
,
path
)
||
error
;
}
...
...
@@ -327,7 +331,7 @@ static int sort_keys(KEY *a, KEY *b)
return
1
;
}
else
if
(
b
->
flags
&
HA_NOSAME
)
return
1
;
// Prefer b
return
1
;
// Prefer b
if
((
a
->
flags
^
b
->
flags
)
&
HA_FULLTEXT
)
{
...
...
@@ -338,8 +342,8 @@ static int sort_keys(KEY *a, KEY *b)
the original key position.
*/
return
((
a
->
usable_key_parts
<
b
->
usable_key_parts
)
?
-
1
:
(
a
->
usable_key_parts
>
b
->
usable_key_parts
)
?
1
:
0
);
(
a
->
usable_key_parts
>
b
->
usable_key_parts
)
?
1
:
0
);
}
/*
...
...
@@ -360,7 +364,7 @@ static int sort_keys(KEY *a, KEY *b)
*/
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
;
const
char
**
old_type_names
=
typelib
->
type_names
;
...
...
@@ -375,9 +379,9 @@ void check_duplicates_in_interval(const char *set_or_name,
if
(
find_type
((
char
*
)
*
cur_value
,
typelib
,
1
))
{
push_warning_printf
(
current_thd
,
MYSQL_ERROR
::
WARN_LEVEL_NOTE
,
ER_DUPLICATED_VALUE_IN_TYPE
,
ER
(
ER_DUPLICATED_VALUE_IN_TYPE
),
name
,
*
cur_value
,
set_or_name
);
ER_DUPLICATED_VALUE_IN_TYPE
,
ER
(
ER_DUPLICATED_VALUE_IN_TYPE
),
name
,
*
cur_value
,
set_or_name
);
}
}
typelib
->
count
=
old_count
;
...
...
@@ -389,33 +393,33 @@ void check_duplicates_in_interval(const char *set_or_name,
SYNOPSIS
mysql_prepare_table()
thd
Thread object
create_info
Create information (like MAX_ROWS)
fields
List of fields to create
keys
List of keys to create
thd
Thread object
create_info
Create information (like MAX_ROWS)
fields
List of fields to create
keys
List of keys to create
DESCRIPTION
Prepares the table and key structures for table creation.
RETURN VALUES
0
ok
-1
error
0
ok
-1
error
*/
int
mysql_prepare_table
(
THD
*
thd
,
HA_CREATE_INFO
*
create_info
,
List
<
create_field
>
&
fields
,
List
<
Key
>
&
keys
,
bool
tmp_table
,
uint
&
db_options
,
handler
*
file
,
KEY
*&
key_info_buffer
,
uint
&
key_count
,
int
select_field_count
)
List
<
create_field
>
&
fields
,
List
<
Key
>
&
keys
,
bool
tmp_table
,
uint
&
db_options
,
handler
*
file
,
KEY
*&
key_info_buffer
,
uint
&
key_count
,
int
select_field_count
)
{
const
char
*
key_name
;
create_field
*
sql_field
,
*
dup_field
;
uint
field
,
null_fields
,
blob_columns
;
ulong
pos
;
KEY
*
key_info
;
const
char
*
key_name
;
create_field
*
sql_field
,
*
dup_field
;
uint
field
,
null_fields
,
blob_columns
;
ulong
pos
;
KEY
*
key_info
;
KEY_PART_INFO
*
key_part_info
;
int
field_no
,
dup_no
;
int
select_field_pos
,
auto_increment
=
0
;
int
select_field_pos
,
auto_increment
=
0
;
DBUG_ENTER
(
"mysql_prepare_table"
);
List_iterator
<
create_field
>
it
(
fields
),
it2
(
fields
);
...
...
@@ -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 */
if
((
sql_field
->
flags
&
BLOB_FLAG
)
||
sql_field
->
sql_type
==
FIELD_TYPE_VAR_STRING
&&
create_info
->
row_type
!=
ROW_TYPE_FIXED
)
sql_field
->
sql_type
==
FIELD_TYPE_VAR_STRING
&&
create_info
->
row_type
!=
ROW_TYPE_FIXED
)
{
db_options
|=
HA_OPTION_PACK_RECORD
;
}
...
...
@@ -459,10 +463,10 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
sql_field
->
field_name
,
dup_field
->
field_name
)
==
0
)
{
/*
If this was a CREATE ... SELECT statement, accept a field
redefinition if we are changing a field in the SELECT part
*/
/*
If this was a CREATE ... SELECT statement, accept a field
redefinition if we are changing a field in the SELECT part
*/
if
(
field_no
<
select_field_pos
||
dup_no
>=
select_field_pos
)
{
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,
}
else
{
/* Field redefined */
sql_field
->
sql_type
=
dup_field
->
sql_type
;
sql_field
->
charset
=
(
dup_field
->
charset
?
dup_field
->
charset
:
create_info
->
default_table_charset
);
sql_field
->
length
=
dup_field
->
length
;
sql_field
->
pack_length
=
dup_field
->
pack_length
;
sql_field
->
create_length_to_internal_length
();
sql_field
->
decimals
=
dup_field
->
decimals
;
sql_field
->
flags
=
dup_field
->
flags
;
sql_field
->
unireg_check
=
dup_field
->
unireg_check
;
it2
.
remove
();
// Remove first (create) definition
select_field_pos
--
;
break
;
/* Field redefined */
sql_field
->
sql_type
=
dup_field
->
sql_type
;
sql_field
->
charset
=
(
dup_field
->
charset
?
dup_field
->
charset
:
create_info
->
default_table_charset
);
sql_field
->
length
=
dup_field
->
length
;
sql_field
->
pack_length
=
dup_field
->
pack_length
;
sql_field
->
create_length_to_internal_length
();
sql_field
->
decimals
=
dup_field
->
decimals
;
sql_field
->
flags
=
dup_field
->
flags
;
sql_field
->
unireg_check
=
dup_field
->
unireg_check
;
it2
.
remove
();
// Remove first (create) definition
select_field_pos
--
;
break
;
}
}
}
...
...
@@ -505,11 +509,11 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
case
FIELD_TYPE_TINY_BLOB
:
case
FIELD_TYPE_LONG_BLOB
:
sql_field
->
pack_flag
=
FIELDFLAG_BLOB
|
pack_length_to_packflag
(
sql_field
->
pack_length
-
portable_sizeof_char_ptr
);
pack_length_to_packflag
(
sql_field
->
pack_length
-
portable_sizeof_char_ptr
);
if
(
sql_field
->
charset
->
state
&
MY_CS_BINSORT
)
sql_field
->
pack_flag
|=
FIELDFLAG_BINARY
;
sql_field
->
length
=
8
;
// Unireg field length
sql_field
->
pack_flag
|=
FIELDFLAG_BINARY
;
sql_field
->
length
=
8
;
// Unireg field length
sql_field
->
unireg_check
=
Field
::
BLOB_FIELD
;
blob_columns
++
;
break
;
...
...
@@ -517,49 +521,49 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
#ifdef HAVE_SPATIAL
if
(
!
(
file
->
table_flags
()
&
HA_HAS_GEOMETRY
))
{
my_printf_error
(
ER_CHECK_NOT_IMPLEMENTED
,
ER
(
ER_CHECK_NOT_IMPLEMENTED
),
MYF
(
0
),
"GEOMETRY"
);
DBUG_RETURN
(
-
1
);
my_printf_error
(
ER_CHECK_NOT_IMPLEMENTED
,
ER
(
ER_CHECK_NOT_IMPLEMENTED
),
MYF
(
0
),
"GEOMETRY"
);
DBUG_RETURN
(
-
1
);
}
sql_field
->
pack_flag
=
FIELDFLAG_GEOM
|
pack_length_to_packflag
(
sql_field
->
pack_length
-
portable_sizeof_char_ptr
);
pack_length_to_packflag
(
sql_field
->
pack_length
-
portable_sizeof_char_ptr
);
if
(
sql_field
->
charset
->
state
&
MY_CS_BINSORT
)
sql_field
->
pack_flag
|=
FIELDFLAG_BINARY
;
sql_field
->
length
=
8
;
// Unireg field length
sql_field
->
pack_flag
|=
FIELDFLAG_BINARY
;
sql_field
->
length
=
8
;
// Unireg field length
sql_field
->
unireg_check
=
Field
::
BLOB_FIELD
;
blob_columns
++
;
break
;
#else
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
);
#endif
/*HAVE_SPATIAL*/
case
FIELD_TYPE_VAR_STRING
:
case
FIELD_TYPE_STRING
:
sql_field
->
pack_flag
=
0
;
if
(
sql_field
->
charset
->
state
&
MY_CS_BINSORT
)
sql_field
->
pack_flag
|=
FIELDFLAG_BINARY
;
sql_field
->
pack_flag
|=
FIELDFLAG_BINARY
;
break
;
case
FIELD_TYPE_ENUM
:
sql_field
->
pack_flag
=
pack_length_to_packflag
(
sql_field
->
pack_length
)
|
FIELDFLAG_INTERVAL
;
FIELDFLAG_INTERVAL
;
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
;
check_duplicates_in_interval
(
"ENUM"
,
sql_field
->
field_name
,
sql_field
->
interval
);
sql_field
->
interval
);
break
;
case
FIELD_TYPE_SET
:
sql_field
->
pack_flag
=
pack_length_to_packflag
(
sql_field
->
pack_length
)
|
FIELDFLAG_BITFIELD
;
FIELDFLAG_BITFIELD
;
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
;
check_duplicates_in_interval
(
"SET"
,
sql_field
->
field_name
,
sql_field
->
interval
);
sql_field
->
interval
);
break
;
case
FIELD_TYPE_DATE
:
// Rest of string types
case
FIELD_TYPE_DATE
:
// Rest of string types
case
FIELD_TYPE_NEWDATE
:
case
FIELD_TYPE_TIME
:
case
FIELD_TYPE_DATETIME
:
...
...
@@ -571,12 +575,12 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
/* fall through */
default:
sql_field
->
pack_flag
=
(
FIELDFLAG_NUMBER
|
(
sql_field
->
flags
&
UNSIGNED_FLAG
?
0
:
FIELDFLAG_DECIMAL
)
|
(
sql_field
->
flags
&
ZEROFILL_FLAG
?
FIELDFLAG_ZEROFILL
:
0
)
|
f_settype
((
uint
)
sql_field
->
sql_type
)
|
(
sql_field
->
decimals
<<
FIELDFLAG_DEC_SHIFT
));
(
sql_field
->
flags
&
UNSIGNED_FLAG
?
0
:
FIELDFLAG_DECIMAL
)
|
(
sql_field
->
flags
&
ZEROFILL_FLAG
?
FIELDFLAG_ZEROFILL
:
0
)
|
f_settype
((
uint
)
sql_field
->
sql_type
)
|
(
sql_field
->
decimals
<<
FIELDFLAG_DEC_SHIFT
));
break
;
}
if
(
!
(
sql_field
->
flags
&
NOT_NULL_FLAG
))
...
...
@@ -608,7 +612,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
List_iterator
<
Key
>
key_iterator
(
keys
);
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
;
Key
*
key
;
uint
tmp
,
key_number
;
...
...
@@ -623,12 +627,12 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
fk_key_count
++
;
foreign_key
*
fk_key
=
(
foreign_key
*
)
key
;
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
:
"foreign key without name"
,
ER
(
ER_KEY_REF_DO_NOT_MATCH_TABLE_REF
));
DBUG_RETURN
(
-
1
);
my_error
(
ER_WRONG_FK_DEF
,
MYF
(
0
),
fk_key
->
name
?
fk_key
->
name
:
"foreign key without name"
,
ER
(
ER_KEY_REF_DO_NOT_MATCH_TABLE_REF
));
DBUG_RETURN
(
-
1
);
}
continue
;
}
...
...
@@ -646,7 +650,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
}
key_parts
+=
key
->
columns
.
elements
;
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
);
DBUG_RETURN
(
-
1
);
...
...
@@ -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_part_info
=
(
KEY_PART_INFO
*
)
sql_calloc
(
sizeof
(
KEY_PART_INFO
)
*
key_parts
);
if
(
!
key_info_buffer
||
!
key_part_info
)
DBUG_RETURN
(
-
1
);
// Out of memory
DBUG_RETURN
(
-
1
);
// Out of memory
key_iterator
.
rewind
();
key_number
=
0
;
...
...
@@ -683,12 +687,12 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
key_info
->
flags
=
HA_SPATIAL
;
break
;
#else
my_printf_error
(
ER_FEATURE_DISABLED
,
ER
(
ER_FEATURE_DISABLED
),
MYF
(
0
),
sym_group_geom
.
name
,
sym_group_geom
.
needed_define
);
DBUG_RETURN
(
-
1
);
my_printf_error
(
ER_FEATURE_DISABLED
,
ER
(
ER_FEATURE_DISABLED
),
MYF
(
0
),
sym_group_geom
.
name
,
sym_group_geom
.
needed_define
);
DBUG_RETURN
(
-
1
);
#endif
case
Key
:
:
FOREIGN_KEY
:
key_number
--
;
// Skip this key
key_number
--
;
// Skip this key
continue
;
default:
key_info
->
flags
=
HA_NOSAME
;
...
...
@@ -731,17 +735,17 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
#ifdef HAVE_RTREE_KEYS
if
((
key_info
->
key_parts
&
1
)
==
1
)
{
my_printf_error
(
ER_WRONG_ARGUMENTS
,
ER
(
ER_WRONG_ARGUMENTS
),
MYF
(
0
),
"RTREE INDEX"
);
DBUG_RETURN
(
-
1
);
my_printf_error
(
ER_WRONG_ARGUMENTS
,
ER
(
ER_WRONG_ARGUMENTS
),
MYF
(
0
),
"RTREE INDEX"
);
DBUG_RETURN
(
-
1
);
}
/* TODO: To be deleted */
my_printf_error
(
ER_NOT_SUPPORTED_YET
,
ER
(
ER_NOT_SUPPORTED_YET
),
MYF
(
0
),
"RTREE INDEX"
);
MYF
(
0
),
"RTREE INDEX"
);
DBUG_RETURN
(
-
1
);
#else
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
);
#endif
}
...
...
@@ -753,16 +757,16 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
it
.
rewind
();
field
=
0
;
while
((
sql_field
=
it
++
)
&&
my_strcasecmp
(
system_charset_info
,
my_strcasecmp
(
system_charset_info
,
column
->
field_name
,
sql_field
->
field_name
))
field
++
;
field
++
;
if
(
!
sql_field
)
{
my_printf_error
(
ER_KEY_COLUMN_DOES_NOT_EXITS
,
ER
(
ER_KEY_COLUMN_DOES_NOT_EXITS
),
MYF
(
0
),
column
->
field_name
);
DBUG_RETURN
(
-
1
);
my_printf_error
(
ER_KEY_COLUMN_DOES_NOT_EXITS
,
ER
(
ER_KEY_COLUMN_DOES_NOT_EXITS
),
MYF
(
0
),
column
->
field_name
);
DBUG_RETURN
(
-
1
);
}
/* 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.
...
...
@@ -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
(
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,
uint
length
=
sql_field
->
pack_length
;
if
(
column
->
length
)
{
if
(
f_is_blob
(
sql_field
->
pack_flag
))
{
if
((
length
=
column
->
length
)
>
file
->
max_key_length
()
||
length
>
file
->
max_key_part_length
())
if
(
f_is_blob
(
sql_field
->
pack_flag
))
{
if
((
length
=
column
->
length
)
>
file
->
max_key_length
()
||
length
>
file
->
max_key_part_length
())
{
length
=
min
(
file
->
max_key_length
(),
file
->
max_key_part_length
());
if
(
key
->
type
==
Key
::
MULTIPLE
)
{
/* not a critical problem */
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
,
ER_TOO_LONG_KEY
,
warn_buff
);
}
...
...
@@ -881,8 +887,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN
(
-
1
);
}
}
}
else
if
(
!
f_is_geom
(
sql_field
->
pack_flag
)
&&
}
else
if
(
!
f_is_geom
(
sql_field
->
pack_flag
)
&&
(
column
->
length
>
length
||
((
f_is_packed
(
sql_field
->
pack_flag
)
||
((
file
->
table_flags
()
&
HA_NO_PREFIX_CHAR_KEYS
)
&&
...
...
@@ -897,9 +903,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
}
else
if
(
length
==
0
)
{
my_printf_error
(
ER_WRONG_KEY_COLUMN
,
ER
(
ER_WRONG_KEY_COLUMN
),
MYF
(
0
),
column
->
field_name
);
DBUG_RETURN
(
-
1
);
my_printf_error
(
ER_WRONG_KEY_COLUMN
,
ER
(
ER_WRONG_KEY_COLUMN
),
MYF
(
0
),
column
->
field_name
);
DBUG_RETURN
(
-
1
);
}
if
(
length
>
file
->
max_key_part_length
())
{
...
...
@@ -908,7 +914,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
{
/* not a critical problem */
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
,
ER_TOO_LONG_KEY
,
warn_buff
);
}
...
...
@@ -921,15 +929,15 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
key_part_info
->
length
=
(
uint16
)
length
;
/* Use packed keys for long strings on the first column */
if
(
!
(
db_options
&
HA_OPTION_NO_PACK_KEYS
)
&&
(
length
>=
KEY_DEFAULT_PACK_LENGTH
&&
(
sql_field
->
sql_type
==
FIELD_TYPE_STRING
||
sql_field
->
sql_type
==
FIELD_TYPE_VAR_STRING
||
sql_field
->
pack_flag
&
FIELDFLAG_BLOB
)))
(
length
>=
KEY_DEFAULT_PACK_LENGTH
&&
(
sql_field
->
sql_type
==
FIELD_TYPE_STRING
||
sql_field
->
sql_type
==
FIELD_TYPE_VAR_STRING
||
sql_field
->
pack_flag
&
FIELDFLAG_BLOB
)))
{
if
(
column_nr
==
0
&&
(
sql_field
->
pack_flag
&
FIELDFLAG_BLOB
))
key_info
->
flags
|=
HA_BINARY_PACK_KEY
;
else
key_info
->
flags
|=
HA_PACK_KEY
;
if
(
column_nr
==
0
&&
(
sql_field
->
pack_flag
&
FIELDFLAG_BLOB
))
key_info
->
flags
|=
HA_BINARY_PACK_KEY
;
else
key_info
->
flags
|=
HA_PACK_KEY
;
}
key_length
+=
length
;
key_part_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) */
if
(
column_nr
==
0
)
{
if
(
key
->
type
==
Key
::
PRIMARY
)
{
if
(
primary_key
)
{
my_error
(
ER_MULTIPLE_PRI_KEY
,
MYF
(
0
));
DBUG_RETURN
(
-
1
);
}
key_name
=
primary_key_name
;
primary_key
=
1
;
}
else
if
(
!
(
key_name
=
key
->
name
))
key_name
=
make_unique_key_name
(
sql_field
->
field_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
);
DBUG_RETURN
(
-
1
);
}
key_info
->
name
=
(
char
*
)
key_name
;
if
(
key
->
type
==
Key
::
PRIMARY
)
{
if
(
primary_key
)
{
my_error
(
ER_MULTIPLE_PRI_KEY
,
MYF
(
0
));
DBUG_RETURN
(
-
1
);
}
key_name
=
primary_key_name
;
primary_key
=
1
;
}
else
if
(
!
(
key_name
=
key
->
name
))
key_name
=
make_unique_key_name
(
sql_field
->
field_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
);
DBUG_RETURN
(
-
1
);
}
key_info
->
name
=
(
char
*
)
key_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,
SYNOPSIS
mysql_create_table()
thd
Thread object
db
Database
table_name
Table name
create_info
Create information (like MAX_ROWS)
fields
List of fields to create
keys
List of keys to create
tmp_table
Set to 1 if this is an internal temporary table
(From ALTER TABLE)
no_log
Don't log the query to binary log.
thd
Thread object
db
Database
table_name
Table name
create_info
Create information (like MAX_ROWS)
fields
List of fields to create
keys
List of keys to create
tmp_table
Set to 1 if this is an internal temporary table
(From ALTER TABLE)
no_log
Don't log the query to binary log.
DESCRIPTION
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,
and must be zero for standard create of table.
RETURN VALUES
0
ok
-1
error
0
ok
-1
error
*/
int
mysql_create_table
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
,
HA_CREATE_INFO
*
create_info
,
List
<
create_field
>
&
fields
,
List
<
Key
>
&
keys
,
bool
tmp_table
,
bool
no_log
,
HA_CREATE_INFO
*
create_info
,
List
<
create_field
>
&
fields
,
List
<
Key
>
&
keys
,
bool
tmp_table
,
bool
no_log
,
uint
select_field_count
)
{
char
path
[
FN_REFLEN
];
const
char
*
alias
;
int
error
=
-
1
;
uint
db_options
,
key_count
;
KEY
*
key_info_buffer
;
handler
*
file
;
enum
db_type
new_db_type
;
char
path
[
FN_REFLEN
];
const
char
*
alias
;
int
error
=
-
1
;
uint
db_options
,
key_count
;
KEY
*
key_info_buffer
;
handler
*
file
;
enum
db_type
new_db_type
;
DBUG_ENTER
(
"mysql_create_table"
);
/* 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,
{
create_info
->
db_type
=
new_db_type
;
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_WARN_USING_OTHER_HANDLER
,
ER
(
ER_WARN_USING_OTHER_HANDLER
),
ha_get_storage_engine
(
new_db_type
),
table_name
);
ER_WARN_USING_OTHER_HANDLER
,
ER
(
ER_WARN_USING_OTHER_HANDLER
),
ha_get_storage_engine
(
new_db_type
),
table_name
);
}
db_options
=
create_info
->
table_options
;
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,
}
if
(
mysql_prepare_table
(
thd
,
create_info
,
fields
,
keys
,
tmp_table
,
db_options
,
file
,
key_info_buffer
,
key_count
,
select_field_count
))
keys
,
tmp_table
,
db_options
,
file
,
key_info_buffer
,
key_count
,
select_field_count
))
DBUG_RETURN
(
-
1
);
/* Check if table exists */
if
(
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
)
{
sprintf
(
path
,
"%s%s%lx_%lx_%x%s"
,
mysql_tmpdir
,
tmp_file_prefix
,
current_pid
,
thd
->
thread_id
,
thd
->
tmp_table
++
,
reg_ext
);
if
(
snprintf
(
path
,
sizeof
(
path
),
"%s%s%lx_%lx_%x%s"
,
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
;
}
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
);
/* Check if table already exists */
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,
{
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
);
}
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,
{
if
(
create_info
->
options
&
HA_LEX_CREATE_IF_NOT_EXISTS
)
{
create_info
->
table_existed
=
1
;
// Mark that table existed
error
=
0
;
create_info
->
table_existed
=
1
;
// Mark that table existed
error
=
0
;
}
else
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,
}
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
)
create_info
->
data_file_name
=
create_info
->
index_file_name
=
0
;
create_info
->
table_options
=
db_options
;
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); */
goto
end
;
...
...
@@ -1140,8 +1152,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
{
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
test
(
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
));
test
(
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
));
mysql_bin_log
.
write
(
&
qinfo
);
}
}
...
...
@@ -1171,17 +1183,23 @@ static char *
make_unique_key_name
(
const
char
*
field_name
,
KEY
*
start
,
KEY
*
end
)
{
char
buff
[
MAX_FIELD_NAME
],
*
buff_end
;
int
remain
;
if
(
!
check_if_keyname_exists
(
field_name
,
start
,
end
)
&&
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
);
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
))
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)
****************************************************************************/
TABLE
*
create_table_from_items
(
THD
*
thd
,
HA_CREATE_INFO
*
create_info
,
const
char
*
db
,
const
char
*
name
,
List
<
create_field
>
*
extra_fields
,
List
<
Key
>
*
keys
,
List
<
Item
>
*
items
,
MYSQL_LOCK
**
lock
)
const
char
*
db
,
const
char
*
name
,
List
<
create_field
>
*
extra_fields
,
List
<
Key
>
*
keys
,
List
<
Item
>
*
items
,
MYSQL_LOCK
**
lock
)
{
TABLE
tmp_table
;
// Used during 'create_field()'
TABLE
tmp_table
;
// Used during 'create_field()'
TABLE
*
table
;
tmp_table
.
table_name
=
0
;
uint
select_field_count
=
items
->
elements
;
...
...
@@ -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
.
blob_ptr_size
=
portable_sizeof_char_ptr
;
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
++
))
{
...
...
@@ -1219,18 +1237,18 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
field
=
item
->
tmp_table_field
(
&
tmp_table
);
else
field
=
create_tmp_field
(
thd
,
&
tmp_table
,
item
,
item
->
type
(),
(
Item
***
)
0
,
&
tmp_field
,
0
,
0
);
(
Item
***
)
0
,
&
tmp_field
,
0
,
0
);
if
(
!
field
||
!
(
cr_field
=
new
create_field
(
field
,(
item
->
type
()
==
Item
::
FIELD_ITEM
?
((
Item_field
*
)
item
)
->
field
:
(
Field
*
)
0
))))
!
(
cr_field
=
new
create_field
(
field
,(
item
->
type
()
==
Item
::
FIELD_ITEM
?
((
Item_field
*
)
item
)
->
field
:
(
Field
*
)
0
))))
DBUG_RETURN
(
0
);
extra_fields
->
push_back
(
cr_field
);
}
/* create and lock table */
/* QQ: This should be done atomic ! */
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
);
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,
bool
mysql_rename_table
(
enum
db_type
base
,
const
char
*
old_db
,
const
char
*
old_name
,
const
char
*
new_db
,
const
char
*
new_name
)
const
char
*
old_db
,
const
char
*
old_name
,
const
char
*
new_db
,
const
char
*
new_name
)
{
char
from
[
FN_REFLEN
],
to
[
FN_REFLEN
];
char
tmp_from
[
NAME_LEN
+
1
],
tmp_to
[
NAME_LEN
+
1
];
...
...
@@ -1279,8 +1297,12 @@ mysql_rename_table(enum db_type base,
my_casedn_str
(
system_charset_info
,
tmp_to
);
new_name
=
tmp_to
;
}
(
void
)
sprintf
(
from
,
"%s/%s/%s"
,
mysql_data_home
,
old_db
,
old_name
);
(
void
)
sprintf
(
to
,
"%s/%s/%s"
,
mysql_data_home
,
new_db
,
new_name
);
if
(
snprintf
(
from
,
sizeof
(
from
),
"%s/%s/%s"
,
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
(
to
,
to
,
""
,
""
,
4
);
...
...
@@ -1305,10 +1327,10 @@ mysql_rename_table(enum db_type base,
SYNOPSIS
wait_while_table_is_used()
thd
Thread handler
table
Table to remove from cache
function
HA_EXTRA_PREPARE_FOR_DELETE if table is to be deleted
HA_EXTRA_FORCE_REOPEN if table is not be used
thd
Thread handler
table
Table to remove from cache
function
HA_EXTRA_PREPARE_FOR_DELETE if table is to be deleted
HA_EXTRA_FORCE_REOPEN if table is not be used
NOTES
When returning, the table will be unusable for other threads until
the table is closed.
...
...
@@ -1319,7 +1341,7 @@ mysql_rename_table(enum db_type base,
*/
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_ENTER
(
"wait_while_table_is_used"
);
...
...
@@ -1327,11 +1349,11 @@ static void wait_while_table_is_used(THD *thd,TABLE *table,
VOID
(
table
->
file
->
extra
(
function
));
/* 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 */
while
(
remove_table_from_cache
(
thd
,
table
->
table_cache_key
,
table
->
real_name
))
table
->
real_name
))
{
dropping_tables
++
;
(
void
)
pthread_cond_wait
(
&
COND_refresh
,
&
LOCK_open
);
...
...
@@ -1345,8 +1367,8 @@ static void wait_while_table_is_used(THD *thd,TABLE *table,
SYNOPSIS
close_cached_table()
thd
Thread handler
table
Table to remove from cache
thd
Thread handler
table
Table to remove from cache
NOTES
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)
if
(
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 */
thd
->
open_tables
=
unlink_open_table
(
thd
,
thd
->
open_tables
,
table
);
...
...
@@ -1377,7 +1399,7 @@ static bool close_cached_table(THD *thd, TABLE *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
;
...
...
@@ -1394,15 +1416,15 @@ static int send_check_errmsg(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"
);
if
(
table
->
table
)
// do not overwrite existing tables on restore
{
DBUG_RETURN
(
send_check_errmsg
(
thd
,
table
,
"restore"
,
"table exists, will not overwrite on restore"
));
"table exists, will not overwrite on restore"
));
}
else
{
...
...
@@ -1412,23 +1434,25 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
char
*
db
=
thd
->
db
?
thd
->
db
:
table
->
db
;
if
(
fn_format_relative_to_data_home
(
src_path
,
table_name
,
backup_dir
,
reg_ext
))
reg_ext
))
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
))
DBUG_RETURN
(
-
1
);
if
(
my_copy
(
src_path
,
fn_format
(
dst_path
,
dst_path
,
""
,
reg_ext
,
4
),
MYF
(
MY_WME
)))
fn_format
(
dst_path
,
dst_path
,
""
,
reg_ext
,
4
),
MYF
(
MY_WME
)))
{
pthread_mutex_lock
(
&
LOCK_open
);
unlock_table_name
(
thd
,
table
);
pthread_mutex_unlock
(
&
LOCK_open
);
DBUG_RETURN
(
send_check_errmsg
(
thd
,
table
,
"restore"
,
"Failed copying .frm file"
));
"Failed copying .frm file"
));
}
if
(
mysql_truncate
(
thd
,
table
,
1
))
{
...
...
@@ -1436,7 +1460,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
unlock_table_name
(
thd
,
table
);
pthread_mutex_unlock
(
&
LOCK_open
);
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,
static
int
prepare_for_repair
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
HA_CHECK_OPT
*
check_opt
)
HA_CHECK_OPT
*
check_opt
)
{
int
error
=
0
;
TABLE
tmp_table
,
*
table
;
...
...
@@ -1464,13 +1488,13 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
if
(
!
(
check_opt
->
sql_flags
&
TT_USEFRM
))
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
];
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
))
DBUG_RETURN
(
0
);
// Can't open frm file
DBUG_RETURN
(
0
);
// Can't open frm file
table
=
&
tmp_table
;
}
...
...
@@ -1493,13 +1517,18 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
like ISAM or MyISAM
*/
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
)))
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
(
table_list
->
table
)
...
...
@@ -1519,7 +1548,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
unlock_table_name
(
thd
,
table_list
);
pthread_mutex_unlock
(
&
LOCK_open
);
error
=
send_check_errmsg
(
thd
,
table_list
,
"repair"
,
"Failed renaming data file"
);
"Failed renaming data file"
);
goto
end
;
}
if
(
mysql_truncate
(
thd
,
table_list
,
1
))
...
...
@@ -1528,7 +1557,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
unlock_table_name
(
thd
,
table_list
);
pthread_mutex_unlock
(
&
LOCK_open
);
error
=
send_check_errmsg
(
thd
,
table_list
,
"repair"
,
"Failed generating table from .frm file"
);
"Failed generating table from .frm file"
);
goto
end
;
}
if
(
my_rename
(
tmp
,
from
,
MYF
(
MY_WME
)))
...
...
@@ -1537,7 +1566,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
unlock_table_name
(
thd
,
table_list
);
pthread_mutex_unlock
(
&
LOCK_open
);
error
=
send_check_errmsg
(
thd
,
table_list
,
"repair"
,
"Failed restoring .MYD file"
);
"Failed restoring .MYD file"
);
goto
end
;
}
...
...
@@ -1554,21 +1583,21 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
end:
if
(
table
==
&
tmp_table
)
closefrm
(
table
);
// Free allocated memory
closefrm
(
table
);
// Free allocated memory
DBUG_RETURN
(
error
);
}
static
int
mysql_admin_table
(
THD
*
thd
,
TABLE_LIST
*
tables
,
HA_CHECK_OPT
*
check_opt
,
const
char
*
operator_name
,
thr_lock_type
lock_type
,
bool
open_for_modify
,
uint
extra_open_options
,
int
(
*
prepare_func
)(
THD
*
,
TABLE_LIST
*
,
HA_CHECK_OPT
*
),
int
(
handler
::*
operator_func
)
(
THD
*
,
HA_CHECK_OPT
*
))
HA_CHECK_OPT
*
check_opt
,
const
char
*
operator_name
,
thr_lock_type
lock_type
,
bool
open_for_modify
,
uint
extra_open_options
,
int
(
*
prepare_func
)(
THD
*
,
TABLE_LIST
*
,
HA_CHECK_OPT
*
),
int
(
handler
::*
operator_func
)
(
THD
*
,
HA_CHECK_OPT
*
))
{
TABLE_LIST
*
table
;
List
<
Item
>
field_list
;
...
...
@@ -1619,11 +1648,11 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
protocol
->
store
(
operator_name
,
system_charset_info
);
protocol
->
store
(
"error"
,
5
,
system_charset_info
);
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
);
thd
->
net
.
last_error
[
0
]
=
0
;
if
(
protocol
->
write
())
goto
err
;
goto
err
;
continue
;
}
table
->
table
->
pos_in_table_list
=
table
;
...
...
@@ -1634,12 +1663,14 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
protocol
->
store
(
table_name
,
system_charset_info
);
protocol
->
store
(
operator_name
,
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
);
close_thread_tables
(
thd
);
table
->
table
=
0
;
// For query cache
table
->
table
=
0
;
// For query cache
if
(
protocol
->
write
())
goto
err
;
goto
err
;
continue
;
}
...
...
@@ -1648,20 +1679,20 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
{
pthread_mutex_lock
(
&
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
);
while
(
remove_table_from_cache
(
thd
,
table
->
table
->
table_cache_key
,
table
->
table
->
real_name
)
&&
!
thd
->
killed
)
table
->
table
->
real_name
)
&&
!
thd
->
killed
)
{
dropping_tables
++
;
(
void
)
pthread_cond_wait
(
&
COND_refresh
,
&
LOCK_open
);
dropping_tables
--
;
dropping_tables
++
;
(
void
)
pthread_cond_wait
(
&
COND_refresh
,
&
LOCK_open
);
dropping_tables
--
;
}
thd
->
exit_cond
(
old_message
);
pthread_mutex_unlock
(
&
LOCK_open
);
if
(
thd
->
killed
)
goto
err
;
goto
err
;
open_for_modify
=
0
;
}
...
...
@@ -1678,7 +1709,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
{
char
buf
[
ERRMSGSIZE
+
20
];
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
(
buf
,
length
,
system_charset_info
);
}
...
...
@@ -1710,26 +1741,26 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
protocol
->
store
(
"Invalid argument"
,
16
,
system_charset_info
);
break
;
default:
// Probably HA_ADMIN_INTERNAL_ERROR
default:
// Probably HA_ADMIN_INTERNAL_ERROR
protocol
->
store
(
"error"
,
5
,
system_charset_info
);
protocol
->
store
(
"Unknown - internal error during operation"
,
41
,
system_charset_info
);
,
system_charset_info
);
fatal_error
=
1
;
break
;
}
if
(
fatal_error
)
table
->
table
->
version
=
0
;
// Force close of table
table
->
table
->
version
=
0
;
// Force close of table
else
if
(
open_for_modify
)
{
pthread_mutex_lock
(
&
LOCK_open
);
remove_table_from_cache
(
thd
,
table
->
table
->
table_cache_key
,
table
->
table
->
real_name
);
table
->
table
->
real_name
);
pthread_mutex_unlock
(
&
LOCK_open
);
/* May be something modified consequently we have to invalidate cache */
query_cache_invalidate3
(
thd
,
table
->
table
,
0
);
}
close_thread_tables
(
thd
);
table
->
table
=
0
;
// For query cache
table
->
table
=
0
;
// For query cache
if
(
protocol
->
write
())
goto
err
;
}
...
...
@@ -1737,7 +1768,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
send_eof
(
thd
);
DBUG_RETURN
(
0
);
err:
close_thread_tables
(
thd
);
// Shouldn't be needed
close_thread_tables
(
thd
);
// Shouldn't be needed
if
(
table
)
table
->
table
=
0
;
DBUG_RETURN
(
-
1
);
...
...
@@ -1748,8 +1779,8 @@ int mysql_backup_table(THD* thd, TABLE_LIST* table_list)
{
DBUG_ENTER
(
"mysql_backup_table"
);
DBUG_RETURN
(
mysql_admin_table
(
thd
,
table_list
,
0
,
"backup"
,
TL_READ
,
0
,
0
,
0
,
&
handler
::
backup
));
"backup"
,
TL_READ
,
0
,
0
,
0
,
&
handler
::
backup
));
}
...
...
@@ -1757,9 +1788,9 @@ int mysql_restore_table(THD* thd, TABLE_LIST* table_list)
{
DBUG_ENTER
(
"mysql_restore_table"
);
DBUG_RETURN
(
mysql_admin_table
(
thd
,
table_list
,
0
,
"restore"
,
TL_WRITE
,
1
,
0
,
"restore"
,
TL_WRITE
,
1
,
0
,
&
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)
{
DBUG_ENTER
(
"mysql_repair_table"
);
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
,
&
handler
::
repair
));
&
handler
::
repair
));
}
...
...
@@ -1777,8 +1808,8 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
{
DBUG_ENTER
(
"mysql_optimize_table"
);
DBUG_RETURN
(
mysql_admin_table
(
thd
,
tables
,
check_opt
,
"optimize"
,
TL_WRITE
,
1
,
0
,
0
,
&
handler
::
optimize
));
"optimize"
,
TL_WRITE
,
1
,
0
,
0
,
&
handler
::
optimize
));
}
...
...
@@ -1787,16 +1818,16 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
SYNOPSIS
mysql_assign_to_keycache()
thd
Thread object
thd
Thread object
tables Table list (one table only)
RETURN VALUES
0
ok
-1
error
0
ok
-1
error
*/
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
;
KEY_CACHE
*
key_cache
;
...
...
@@ -1813,7 +1844,7 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
pthread_mutex_unlock
(
&
LOCK_global_system_variables
);
check_opt
.
key_cache
=
key_cache
;
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
));
}
...
...
@@ -1823,7 +1854,7 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
SYNOPSIS
reassign_keycache_tables()
thd
Thread object
thd
Thread object
src_cache Reference to the key cache to clean up
dest_cache New key cache
...
...
@@ -1840,7 +1871,7 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
to it for a while after this function returns.
RETURN VALUES
0
ok
0
ok
*/
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
->
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_change_key_cache
(
src_cache
,
dst_cache
);
DBUG_RETURN
(
0
);
...
...
@@ -1862,20 +1893,20 @@ int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache,
SYNOPSIS
mysql_preload_keys()
thd
Thread object
thd
Thread object
tables Table list (one table only)
RETURN VALUES
0
ok
-1
error
0
ok
-1
error
*/
int
mysql_preload_keys
(
THD
*
thd
,
TABLE_LIST
*
tables
)
{
DBUG_ENTER
(
"mysql_preload_keys"
);
DBUG_RETURN
(
mysql_admin_table
(
thd
,
tables
,
0
,
"preload_keys"
,
TL_READ
,
0
,
0
,
0
,
&
handler
::
preload_keys
));
"preload_keys"
,
TL_READ
,
0
,
0
,
0
,
&
handler
::
preload_keys
));
}
...
...
@@ -1884,14 +1915,14 @@ int mysql_preload_keys(THD* thd, TABLE_LIST* tables)
SYNOPSIS
mysql_create_like_table()
thd
Thread object
thd
Thread object
table Table list (one table only)
create_info Create info
table_ident Src table_ident
RETURN VALUES
0
ok
-1
error
0
ok
-1
error
*/
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
))
goto
table_exists
;
sprintf
(
dst_path
,
"%s%s%lx_%lx_%x%s"
,
mysql_tmpdir
,
tmp_file_prefix
,
current_pid
,
thd
->
thread_id
,
thd
->
tmp_table
++
,
reg_ext
);
if
(
snprintf
(
dst_path
,
sizeof
(
dst_path
),
"%s%s%lx_%lx_%x%s"
,
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
;
}
else
...
...
@@ -1990,8 +2024,8 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
{
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
test
(
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
));
test
(
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
));
mysql_bin_log
.
write
(
&
qinfo
);
}
DBUG_RETURN
(
0
);
...
...
@@ -2000,7 +2034,9 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
if
(
create_info
->
options
&
HA_LEX_CREATE_IF_NOT_EXISTS
)
{
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
,
ER_TABLE_EXISTS_ERROR
,
warn_buff
);
DBUG_RETURN
(
0
);
...
...
@@ -2020,8 +2056,8 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
DBUG_ENTER
(
"mysql_analyze_table"
);
DBUG_RETURN
(
mysql_admin_table
(
thd
,
tables
,
check_opt
,
"analyze"
,
lock_type
,
1
,
0
,
0
,
&
handler
::
analyze
));
"analyze"
,
lock_type
,
1
,
0
,
0
,
&
handler
::
analyze
));
}
...
...
@@ -2035,15 +2071,15 @@ int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
DBUG_ENTER
(
"mysql_check_table"
);
DBUG_RETURN
(
mysql_admin_table
(
thd
,
tables
,
check_opt
,
"check"
,
lock_type
,
0
,
HA_OPEN_FOR_REPAIR
,
0
,
&
handler
::
check
));
"check"
,
lock_type
,
0
,
HA_OPEN_FOR_REPAIR
,
0
,
&
handler
::
check
));
}
/* table_list should contain just one table */
int
mysql_discard_or_import_tablespace
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
enum
tablespace_op_type
tablespace_op
)
TABLE_LIST
*
table_list
,
enum
tablespace_op_type
tablespace_op
)
{
TABLE
*
table
;
my_bool
discard
;
...
...
@@ -2061,8 +2097,8 @@ int mysql_discard_or_import_tablespace(THD *thd,
discard
=
FALSE
;
thd
->
tablespace_op
=
TRUE
;
/* we set this flag so that ha_innobase::open
and ::external_lock() do not complain when we
lock the table */
and ::external_lock() do not complain when we
lock the table */
mysql_ha_closeall
(
thd
,
table_list
);
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)
HA_CREATE_INFO
create_info
;
int
rc
;
uint
idx
;
uint
db_options
;
uint
db_options
;
uint
key_count
;
TABLE
*
table
;
Field
**
f_ptr
;
KEY
*
key_info_buffer
;
char
path
[
FN_REFLEN
];
char
path
[
FN_REFLEN
];
DBUG_ENTER
(
"mysql_create_index"
);
/*
...
...
@@ -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
;
db_options
=
0
;
if
(
mysql_prepare_table
(
thd
,
&
create_info
,
fields
,
keys
,
/*tmp_table*/
0
,
db_options
,
table
->
file
,
key_info_buffer
,
key_count
,
/*select_field_count*/
0
))
keys
,
/*tmp_table*/
0
,
db_options
,
table
->
file
,
key_info_buffer
,
key_count
,
/*select_field_count*/
0
))
DBUG_RETURN
(
-
1
);
/*
...
...
@@ -2170,7 +2206,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
(
HA_DDL_ONLINE
|
HA_DDL_WITH_LOCK
)))
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. */
bzero
((
char
*
)
&
create_info
,
sizeof
(
create_info
));
...
...
@@ -2188,9 +2224,10 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
else
{
if
(
table
->
file
->
add_index
(
table
,
key_info_buffer
,
key_count
)
||
((
void
)
sprintf
(
path
,
"%s/%s/%s%s"
,
mysql_data_home
,
table_list
->
db
,
(
lower_case_table_names
==
2
)
?
table_list
->
alias
:
table_list
->
real_name
,
reg_ext
),
0
)
||
(
snprintf
(
path
,
sizeof
(
path
),
"%s/%s/%s%s"
,
mysql_data_home
,
table_list
->
db
,
(
lower_case_table_names
==
2
)
?
table_list
->
alias
:
table_list
->
real_name
,
reg_ext
)
>=
(
int
)
sizeof
(
path
))
||
!
unpack_filename
(
path
,
path
)
||
mysql_create_frm
(
thd
,
path
,
&
create_info
,
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)
List
<
Alter_column
>
alter
;
HA_CREATE_INFO
create_info
;
uint
idx
;
uint
db_options
;
uint
db_options
;
uint
key_count
;
uint
*
key_numbers
;
TABLE
*
table
;
Field
**
f_ptr
;
KEY
*
key_info
;
KEY
*
key_info_buffer
;
char
path
[
FN_REFLEN
];
char
path
[
FN_REFLEN
];
DBUG_ENTER
(
"mysql_drop_index"
);
/*
...
...
@@ -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
++
)
{
if
(
!
my_strcasecmp
(
system_charset_info
,
key_info
->
name
,
drop_key
->
name
))
break
;
break
;
}
if
(
idx
>=
table
->
keys
)
{
...
...
@@ -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
,
key_info_buffer
,
key_count
,
/*select_field_count*/
0
)
||
((
void
)
sprintf
(
path
,
"%s/%s/%s%s"
,
mysql_data_home
,
table_list
->
db
,
(
lower_case_table_names
==
2
)
?
table_list
->
alias
:
table_list
->
real_name
,
reg_ext
),
0
)
||
(
snprintf
(
path
,
sizeof
(
path
),
"%s/%s/%s%s"
,
mysql_data_home
,
table_list
->
db
,
(
lower_case_table_names
==
2
)
?
table_list
->
alias
:
table_list
->
real_name
,
reg_ext
)
>=
(
int
)
sizeof
(
path
))
||
!
unpack_filename
(
path
,
path
)
||
mysql_create_frm
(
thd
,
path
,
&
create_info
,
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)
}
int
mysql_add_column
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
create_field
>
&
fields
)
List
<
create_field
>
&
fields
)
{
List
<
Alter_drop
>
drop
;
List
<
Key
>
keys
;
...
...
@@ -2319,9 +2357,9 @@ int mysql_add_column(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
real_alter_table
(
thd
,
table_list
->
db
,
table_list
->
real_name
,
&
create_info
,
table_list
,
table
,
fields
,
keys
,
drop
,
alter
,
0
,
(
ORDER
*
)
0
,
ALTER_ADD_COLUMN
,
DUP_ERROR
));
&
create_info
,
table_list
,
table
,
fields
,
keys
,
drop
,
alter
,
0
,
(
ORDER
*
)
0
,
ALTER_ADD_COLUMN
,
DUP_ERROR
));
}
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
(
real_alter_table
(
thd
,
table_list
->
db
,
table_list
->
real_name
,
&
create_info
,
table_list
,
table
,
fields
,
keys
,
drop
,
alter
,
0
,
(
ORDER
*
)
0
,
ALTER_DROP_COLUMN
,
DUP_ERROR
));
&
create_info
,
table_list
,
table
,
fields
,
keys
,
drop
,
alter
,
0
,
(
ORDER
*
)
0
,
ALTER_DROP_COLUMN
,
DUP_ERROR
));
}
int
mysql_alter_table
(
THD
*
thd
,
char
*
new_db
,
char
*
new_name
,
HA_CREATE_INFO
*
create_info
,
TABLE_LIST
*
table_list
,
List
<
create_field
>
&
fields
,
List
<
Key
>
&
keys
,
List
<
Alter_drop
>
&
drop_list
,
List
<
Alter_column
>
&
alter_list
,
HA_CREATE_INFO
*
create_info
,
TABLE_LIST
*
table_list
,
List
<
create_field
>
&
fields
,
List
<
Key
>
&
keys
,
List
<
Alter_drop
>
&
drop_list
,
List
<
Alter_column
>
&
alter_list
,
uint
order_num
,
ORDER
*
order
,
int
alter_flags
,
enum
enum_duplicates
handle_duplicates
,
enum
enum_enable_or_disable
keys_onoff
,
enum
tablespace_op_type
tablespace_op
,
enum
enum_duplicates
handle_duplicates
,
enum
enum_enable_or_disable
keys_onoff
,
enum
tablespace_op_type
tablespace_op
,
bool
simple_alter
)
{
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
);
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
if
(
tablespace_op
!=
NO_TABLESPACE_OP
)
DBUG_RETURN
(
mysql_discard_or_import_tablespace
(
thd
,
table_list
,
tablespace_op
));
tablespace_op
));
if
(
alter_flags
==
ALTER_ADD_INDEX
)
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,
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
real_alter_table
(
thd
,
new_db
,
new_name
,
create_info
,
table_list
,
table
,
fields
,
keys
,
drop_list
,
alter_list
,
order_num
,
order
,
alter_flags
,
handle_duplicates
,
keys_onoff
,
tablespace_op
,
simple_alter
));
create_info
,
table_list
,
table
,
fields
,
keys
,
drop_list
,
alter_list
,
order_num
,
order
,
alter_flags
,
handle_duplicates
,
keys_onoff
,
tablespace_op
,
simple_alter
));
}
int
real_alter_table
(
THD
*
thd
,
char
*
new_db
,
char
*
new_name
,
HA_CREATE_INFO
*
create_info
,
TABLE_LIST
*
table_list
,
HA_CREATE_INFO
*
create_info
,
TABLE_LIST
*
table_list
,
TABLE
*
table
,
List
<
create_field
>
&
fields
,
List
<
Key
>
&
keys
,
List
<
Alter_drop
>
&
drop_list
,
List
<
Alter_column
>
&
alter_list
,
List
<
create_field
>
&
fields
,
List
<
Key
>
&
keys
,
List
<
Alter_drop
>
&
drop_list
,
List
<
Alter_column
>
&
alter_list
,
uint
order_num
,
ORDER
*
order
,
int
alter_flags
,
enum
enum_duplicates
handle_duplicates
,
enum
enum_enable_or_disable
keys_onoff
,
enum
tablespace_op_type
tablespace_op
,
enum
enum_duplicates
handle_duplicates
,
enum
enum_enable_or_disable
keys_onoff
,
enum
tablespace_op_type
tablespace_op
,
bool
simple_alter
)
{
TABLE
*
new_table
;
...
...
@@ -2440,13 +2472,13 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
if
(
lower_case_table_names
!=
2
)
{
my_casedn_str
(
system_charset_info
,
new_name_buff
);
new_alias
=
new_name
;
// Create lower case table name
my_casedn_str
(
system_charset_info
,
new_name_buff
);
new_alias
=
new_name
;
// Create lower case table name
}
my_casedn_str
(
system_charset_info
,
new_name
);
}
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
...
...
@@ -2458,21 +2490,21 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
if
(
table
->
tmp_table
)
{
if
(
find_temporary_table
(
thd
,
new_db
,
new_name_buff
))
{
my_error
(
ER_TABLE_EXISTS_ERROR
,
MYF
(
0
),
new_name_buff
);
DBUG_RETURN
(
-
1
);
}
if
(
find_temporary_table
(
thd
,
new_db
,
new_name_buff
))
{
my_error
(
ER_TABLE_EXISTS_ERROR
,
MYF
(
0
),
new_name_buff
);
DBUG_RETURN
(
-
1
);
}
}
else
{
if
(
!
access
(
fn_format
(
new_name_buff
,
new_name_buff
,
new_db
,
reg_ext
,
0
),
F_OK
))
{
/* Table will be closed in do_command() */
my_error
(
ER_TABLE_EXISTS_ERROR
,
MYF
(
0
),
new_alias
);
DBUG_RETURN
(
-
1
);
}
if
(
!
access
(
fn_format
(
new_name_buff
,
new_name_buff
,
new_db
,
reg_ext
,
0
),
F_OK
))
{
/* Table will be closed in do_command() */
my_error
(
ER_TABLE_EXISTS_ERROR
,
MYF
(
0
),
new_alias
);
DBUG_RETURN
(
-
1
);
}
}
}
}
...
...
@@ -2487,10 +2519,10 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
create_info
->
db_type
=
new_db_type
;
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_WARN_USING_OTHER_HANDLER
,
ER
(
ER_WARN_USING_OTHER_HANDLER
),
ha_get_storage_engine
(
new_db_type
),
new_name
);
ER_WARN_USING_OTHER_HANDLER
,
ER
(
ER_WARN_USING_OTHER_HANDLER
),
ha_get_storage_engine
(
new_db_type
),
new_name
);
}
if
(
create_info
->
row_type
==
ROW_TYPE_NOT_USED
)
create_info
->
row_type
=
table
->
row_type
;
...
...
@@ -2515,7 +2547,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
*
fn_ext
(
new_name
)
=
0
;
close_cached_table
(
thd
,
table
);
if
(
mysql_rename_table
(
old_db_type
,
db
,
table_name
,
new_db
,
new_alias
))
error
=
-
1
;
error
=
-
1
;
}
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
}
...
...
@@ -2524,28 +2556,28 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
switch
(
keys_onoff
)
{
case
LEAVE_AS_IS
:
break
;
break
;
case
ENABLE
:
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
wait_while_table_is_used
(
thd
,
table
,
HA_EXTRA_FORCE_REOPEN
);
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
error
=
table
->
file
->
activate_all_index
(
thd
);
/* COND_refresh will be signaled in close_thread_tables() */
break
;
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
wait_while_table_is_used
(
thd
,
table
,
HA_EXTRA_FORCE_REOPEN
);
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
error
=
table
->
file
->
activate_all_index
(
thd
);
/* COND_refresh will be signaled in close_thread_tables() */
break
;
case
DISABLE
:
if
(
table
->
db_type
==
DB_TYPE_MYISAM
)
{
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
wait_while_table_is_used
(
thd
,
table
,
HA_EXTRA_FORCE_REOPEN
);
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
table
->
file
->
deactivate_non_unique_index
(
HA_POS_ERROR
);
/* COND_refresh will be signaled in close_thread_tables() */
}
else
push_warning_printf
(
current_thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_ILLEGAL_HA
,
ER
(
ER_ILLEGAL_HA
),
table
->
table_name
);
break
;
if
(
table
->
db_type
==
DB_TYPE_MYISAM
)
{
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
wait_while_table_is_used
(
thd
,
table
,
HA_EXTRA_FORCE_REOPEN
);
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
table
->
file
->
deactivate_non_unique_index
(
HA_POS_ERROR
);
/* COND_refresh will be signaled in close_thread_tables() */
}
else
push_warning_printf
(
current_thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_ILLEGAL_HA
,
ER
(
ER_ILLEGAL_HA
),
table
->
table_name
);
break
;
}
}
if
(
!
error
)
...
...
@@ -2554,12 +2586,12 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
if
(
mysql_bin_log
.
is_open
())
{
thd
->
clear_error
();
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
0
);
mysql_bin_log
.
write
(
&
qinfo
);
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
0
);
mysql_bin_log
.
write
(
&
qinfo
);
}
send_ok
(
thd
);
}
table_list
->
table
=
0
;
// For query cache
table_list
->
table
=
0
;
// For query cache
query_cache_invalidate3
(
thd
,
table_list
,
0
);
DBUG_RETURN
(
error
);
}
...
...
@@ -2576,12 +2608,12 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
if
(
!
(
used_fields
&
HA_CREATE_USED_DEFAULT_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
<
create_field
>
def_it
(
fields
);
List_iterator
<
Alter_column
>
alter_it
(
alter_list
);
List
<
create_field
>
create_list
;
// Add new fields here
List
<
Key
>
key_list
;
// Add new keys here
List
<
create_field
>
create_list
;
// Add new fields here
List
<
Key
>
key_list
;
// Add new keys here
create_field
*
def
;
/*
...
...
@@ -2597,16 +2629,16 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
while
((
drop
=
drop_it
++
))
{
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 */
if
(
MTYP_TYPENR
(
field
->
unireg_check
)
==
Field
::
NEXT_NUMBER
&&
!
(
used_fields
&
HA_CREATE_USED_AUTO
))
{
create_info
->
auto_increment_value
=
0
;
create_info
->
used_fields
|=
HA_CREATE_USED_AUTO
;
}
break
;
/* Reset auto_increment value if it was dropped */
if
(
MTYP_TYPENR
(
field
->
unireg_check
)
==
Field
::
NEXT_NUMBER
&&
!
(
used_fields
&
HA_CREATE_USED_AUTO
))
{
create_info
->
auto_increment_value
=
0
;
create_info
->
used_fields
|=
HA_CREATE_USED_AUTO
;
}
break
;
}
}
if
(
drop
)
...
...
@@ -2620,31 +2652,31 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
if
(
def
->
change
&&
!
my_strcasecmp
(
system_charset_info
,
field
->
field_name
,
def
->
change
))
break
;
break
;
}
if
(
def
)
{
// Field is changed
{
// Field is changed
def
->
field
=
field
;
if
(
def
->
sql_type
==
FIELD_TYPE_TIMESTAMP
)
use_timestamp
=
1
;
use_timestamp
=
1
;
if
(
!
def
->
after
)
{
create_list
.
push_back
(
def
);
def_it
.
remove
();
create_list
.
push_back
(
def
);
def_it
.
remove
();
}
}
else
{
// Use old field value
{
// Use old field value
create_list
.
push_back
(
def
=
new
create_field
(
field
,
field
));
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
;
while
((
alter
=
alter_it
++
))
{
if
(
!
my_strcasecmp
(
system_charset_info
,
field
->
field_name
,
alter
->
name
))
break
;
if
(
!
my_strcasecmp
(
system_charset_info
,
field
->
field_name
,
alter
->
name
))
break
;
}
if
(
alter
)
{
...
...
@@ -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
);
DBUG_RETURN
(
-
1
);
}
def
->
def
=
alter
->
def
;
// Use new default
alter_it
.
remove
();
def
->
def
=
alter
->
def
;
// Use new default
alter_it
.
remove
();
}
}
}
def_it
.
rewind
();
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
)
{
...
...
@@ -2675,17 +2707,17 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
{
create_field
*
find
;
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
))
break
;
if
(
!
my_strcasecmp
(
system_charset_info
,
def
->
after
,
find
->
field_name
))
break
;
}
if
(
!
find
)
{
my_error
(
ER_BAD_FIELD_ERROR
,
MYF
(
0
),
def
->
after
,
table_name
);
DBUG_RETURN
(
-
1
);
my_error
(
ER_BAD_FIELD_ERROR
,
MYF
(
0
),
def
->
after
,
table_name
);
DBUG_RETURN
(
-
1
);
}
find_it
.
after
(
def
);
// Put element after this
find_it
.
after
(
def
);
// Put element after this
}
}
if
(
alter_list
.
elements
)
...
...
@@ -2717,8 +2749,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
while
((
drop
=
drop_it
++
))
{
if
(
drop
->
type
==
Alter_drop
::
KEY
&&
!
my_strcasecmp
(
system_charset_info
,
key_name
,
drop
->
name
))
break
;
!
my_strcasecmp
(
system_charset_info
,
key_name
,
drop
->
name
))
break
;
}
if
(
drop
)
{
...
...
@@ -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
++
)
{
if
(
!
key_part
->
field
)
continue
;
// Wrong field (from UNIREG)
continue
;
// Wrong field (from UNIREG)
const
char
*
key_part_name
=
key_part
->
field
->
field_name
;
create_field
*
cfield
;
field_it
.
rewind
();
while
((
cfield
=
field_it
++
))
{
if
(
cfield
->
change
)
{
if
(
!
my_strcasecmp
(
system_charset_info
,
key_part_name
,
cfield
->
change
))
break
;
}
else
if
(
!
my_strcasecmp
(
system_charset_info
,
if
(
cfield
->
change
)
{
if
(
!
my_strcasecmp
(
system_charset_info
,
key_part_name
,
cfield
->
change
))
break
;
}
else
if
(
!
my_strcasecmp
(
system_charset_info
,
key_part_name
,
cfield
->
field_name
))
break
;
break
;
}
if
(
!
cfield
)
continue
;
// Field is removed
continue
;
// Field is removed
uint
key_part_length
=
key_part
->
length
;
if
(
cfield
->
field
)
// Not new field
{
// Check if sub key
if
(
cfield
->
field
->
type
()
!=
FIELD_TYPE_BLOB
&&
(
cfield
->
field
->
pack_length
()
==
key_part_length
||
cfield
->
length
<=
key_part_length
/
key_part
->
field
->
charset
()
->
mbmaxlen
))
key_part_length
=
0
;
// Use whole field
if
(
cfield
->
field
)
// Not new field
{
// Check if sub key
if
(
cfield
->
field
->
type
()
!=
FIELD_TYPE_BLOB
&&
(
cfield
->
field
->
pack_length
()
==
key_part_length
||
cfield
->
length
<=
key_part_length
/
key_part
->
field
->
charset
()
->
mbmaxlen
))
key_part_length
=
0
;
// Use whole field
}
key_part_length
/=
key_part
->
field
->
charset
()
->
mbmaxlen
;
key_parts
.
push_back
(
new
key_part_spec
(
cfield
->
field_name
,
key_part_length
));
key_part_length
));
}
if
(
key_parts
.
elements
)
key_list
.
push_back
(
new
Key
(
key_info
->
flags
&
HA_SPATIAL
?
Key
::
SPATIAL
:
(
key_info
->
flags
&
HA_NOSAME
?
(
!
my_strcasecmp
(
system_charset_info
,
(
!
my_strcasecmp
(
system_charset_info
,
key_name
,
primary_key_name
)
?
Key
::
PRIMARY
:
Key
::
UNIQUE
)
:
(
key_info
->
flags
&
HA_FULLTEXT
?
Key
::
FULLTEXT
:
Key
::
MULTIPLE
)),
key_name
,
Key
::
PRIMARY
:
Key
::
UNIQUE
)
:
(
key_info
->
flags
&
HA_FULLTEXT
?
Key
::
FULLTEXT
:
Key
::
MULTIPLE
)),
key_name
,
key_info
->
algorithm
,
key_parts
));
key_parts
));
}
{
Key
*
key
;
while
((
key
=
key_it
++
))
// Add new keys
while
((
key
=
key_it
++
))
// Add new keys
{
if
(
key
->
type
!=
Key
::
FOREIGN_KEY
)
key_list
.
push_back
(
key
);
key_list
.
push_back
(
key
);
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
);
DBUG_RETURN
(
-
1
);
my_error
(
ER_WRONG_NAME_FOR_INDEX
,
MYF
(
0
),
key
->
name
);
DBUG_RETURN
(
-
1
);
}
}
}
...
...
@@ -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
);
(
void
)
sprintf
(
tmp_name
,
"%s-%lx_%lx"
,
tmp_file_prefix
,
current_pid
,
thd
->
thread_id
);
if
(
snprintf
(
tmp_name
,
sizeof
(
tmp_name
),
"%s-%lx_%lx"
,
tmp_file_prefix
,
current_pid
,
thd
->
thread_id
)
>=
(
int
)
sizeof
(
tmp_name
))
goto
err
;
create_info
->
db_type
=
new_db_type
;
if
(
!
create_info
->
comment
)
create_info
->
comment
=
table
->
comment
;
...
...
@@ -2818,7 +2851,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
if
(
create_info
->
table_options
&
(
HA_OPTION_DELAY_KEY_WRITE
|
HA_OPTION_NO_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
;
if
(
table
->
tmp_table
)
...
...
@@ -2849,31 +2882,31 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
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
)
{
/* Fix index_file_name to have 'tmp_name' as basename */
strmov
(
index_file
,
tmp_name
);
create_info
->
index_file_name
=
fn_same
(
index_file
,
create_info
->
index_file_name
,
1
);
create_info
->
index_file_name
,
1
);
}
if
(
create_info
->
data_file_name
)
{
/* Fix data_file_name to have 'tmp_name' as basename */
strmov
(
data_file
,
tmp_name
);
create_info
->
data_file_name
=
fn_same
(
data_file
,
create_info
->
data_file_name
,
1
);
create_info
->
data_file_name
,
1
);
}
}
else
create_info
->
data_file_name
=
create_info
->
index_file_name
=
0
;
if
((
error
=
mysql_create_table
(
thd
,
new_db
,
tmp_name
,
create_info
,
create_list
,
key_list
,
1
,
1
,
0
)))
// no logging
create_info
,
create_list
,
key_list
,
1
,
1
,
0
)))
// no logging
DBUG_RETURN
(
error
);
if
(
table
->
tmp_table
)
...
...
@@ -2881,7 +2914,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
else
{
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
);
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,
if
(
use_timestamp
)
new_table
->
time_stamp
=
0
;
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
->
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
;
if
(
!
new_table
->
is_view
)
error
=
copy_data_between_tables
(
table
,
new_table
,
create_list
,
handle_duplicates
,
order_num
,
order
,
&
copied
,
&
deleted
);
thd
->
last_insert_id
=
next_insert_id
;
// Needed for correct log
handle_duplicates
,
order_num
,
order
,
&
copied
,
&
deleted
);
thd
->
last_insert_id
=
next_insert_id
;
// Needed for correct log
thd
->
count_cuted_fields
=
CHECK_FIELD_IGNORE
;
new_table
->
time_stamp
=
save_time_stamp
;
...
...
@@ -2914,8 +2949,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
if
(
error
)
{
/*
The following function call will free the new_table pointer,
in close_temporary_table(), so we can safely directly jump to err
The following function call will free the new_table pointer,
in close_temporary_table(), so we can safely directly jump to err
*/
close_temporary_table
(
thd
,
new_db
,
tmp_name
);
goto
err
;
...
...
@@ -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 */
close_temporary_table
(
thd
,
table
->
table_cache_key
,
table_name
);
if
(
rename_temporary_table
(
thd
,
new_table
,
new_db
,
new_alias
))
{
// Fatal error
{
// Fatal error
close_temporary_table
(
thd
,
new_db
,
tmp_name
);
my_free
((
gptr
)
new_table
,
MYF
(
0
));
goto
err
;
...
...
@@ -2944,7 +2979,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
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
));
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
if
(
error
)
...
...
@@ -2961,8 +2996,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
*/
thd
->
proc_info
=
"rename result table"
;
sprintf
(
old_name
,
"%s2-%lx-%lx"
,
tmp_file_prefix
,
current_pid
,
thd
->
thread_id
);
if
(
snprintf
(
old_name
,
sizeof
(
old_name
),
"%s2-%lx-%lx"
,
tmp_file_prefix
,
current_pid
,
thd
->
thread_id
)
>=
(
int
)
sizeof
(
old_name
))
goto
err
;
if
(
new_name
!=
table_name
||
new_db
!=
db
)
{
if
(
!
access
(
new_name_buff
,
F_OK
))
...
...
@@ -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
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
))
{
// Aborted
{
// Aborted
VOID
(
quick_rm_table
(
new_db_type
,
new_db
,
tmp_name
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
goto
err
;
}
table
=
0
;
// Marker that table is closed
table
=
0
;
// Marker that table is closed
}
#if (!defined( __WIN__) && !defined( __EMX__) && !defined( OS2))
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
...
...
@@ -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
));
}
else
if
(
mysql_rename_table
(
new_db_type
,
new_db
,
tmp_name
,
new_db
,
new_alias
))
{
// Try to get everything back
new_alias
))
{
// Try to get everything back
error
=
1
;
VOID
(
quick_rm_table
(
new_db_type
,
new_db
,
new_alias
));
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,
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
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
...
...
@@ -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
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
));
if
(
close_data_tables
(
thd
,
db
,
table_name
)
||
reopen_tables
(
thd
,
1
,
0
))
{
// This shouldn't happen
reopen_tables
(
thd
,
1
,
0
))
{
// This shouldn't happen
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
));
goto
err
;
}
...
...
@@ -3085,7 +3121,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
shutdown.
*/
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
);
table
=
open_temporary_table
(
thd
,
path
,
new_db
,
tmp_name
,
0
);
if
(
table
)
...
...
@@ -3095,16 +3133,18 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
}
else
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
();
}
#endif
table_list
->
table
=
0
;
// For query cache
table_list
->
table
=
0
;
// For query cache
query_cache_invalidate3
(
thd
,
table_list
,
0
);
end_temporary:
sprintf
(
tmp_name
,
ER
(
ER_INSERT_INFO
),
(
ulong
)
(
copied
+
deleted
),
(
ulong
)
deleted
,
(
ulong
)
thd
->
cuted_fields
);
if
(
snprintf
(
tmp_name
,
sizeof
(
tmp_name
),
ER
(
ER_INSERT_INFO
),
(
ulong
)
(
copied
+
deleted
),
(
ulong
)
deleted
,
(
ulong
)
thd
->
cuted_fields
)
>=
(
int
)
sizeof
(
tmp_name
))
goto
err
;
send_ok
(
thd
,
copied
+
deleted
,
0L
,
tmp_name
);
thd
->
some_tables_deleted
=
0
;
DBUG_RETURN
(
0
);
...
...
@@ -3117,9 +3157,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
static
int
copy_data_between_tables
(
TABLE
*
from
,
TABLE
*
to
,
List
<
create_field
>
&
create
,
enum
enum_duplicates
handle_duplicates
,
enum
enum_duplicates
handle_duplicates
,
uint
order_num
,
ORDER
*
order
,
ha_rows
*
copied
,
ha_rows
*
copied
,
ha_rows
*
deleted
)
{
int
error
;
...
...
@@ -3137,7 +3177,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
DBUG_ENTER
(
"copy_data_between_tables"
);
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
->
extra
(
HA_EXTRA_WRITE_CACHE
);
...
...
@@ -3163,12 +3203,12 @@ copy_data_between_tables(TABLE *from,TABLE *to,
bzero
((
char
*
)
&
tables
,
sizeof
(
tables
));
tables
.
table
=
from
;
tables
.
alias
=
tables
.
real_name
=
from
->
real_name
;
tables
.
db
=
from
->
table_cache_key
;
tables
.
db
=
from
->
table_cache_key
;
error
=
1
;
if
(
thd
->
lex
->
select_lex
.
setup_ref_array
(
thd
,
order_num
)
||
setup_order
(
thd
,
thd
->
lex
->
select_lex
.
ref_pointer_array
,
&
tables
,
fields
,
all_fields
,
order
)
||
setup_order
(
thd
,
thd
->
lex
->
select_lex
.
ref_pointer_array
,
&
tables
,
fields
,
all_fields
,
order
)
||
!
(
sortorder
=
make_unireg_sortorder
(
order
,
&
length
))
||
(
from
->
sort
.
found_records
=
filesort
(
thd
,
from
,
sortorder
,
length
,
(
SQL_SELECT
*
)
0
,
HA_POS_ERROR
,
...
...
@@ -3209,12 +3249,12 @@ copy_data_between_tables(TABLE *from,TABLE *to,
if
((
error
=
to
->
file
->
write_row
((
byte
*
)
to
->
record
[
0
])))
{
if
((
handle_duplicates
!=
DUP_IGNORE
&&
handle_duplicates
!=
DUP_REPLACE
)
||
(
error
!=
HA_ERR_FOUND_DUPP_KEY
&&
error
!=
HA_ERR_FOUND_DUPP_UNIQUE
))
handle_duplicates
!=
DUP_REPLACE
)
||
(
error
!=
HA_ERR_FOUND_DUPP_KEY
&&
error
!=
HA_ERR_FOUND_DUPP_UNIQUE
))
{
to
->
file
->
print_error
(
error
,
MYF
(
0
));
break
;
to
->
file
->
print_error
(
error
,
MYF
(
0
));
break
;
}
delete_count
++
;
}
...
...
@@ -3223,7 +3263,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
}
end_read_record
(
&
info
);
free_io_cache
(
from
);
delete
[]
copy
;
// This is never 0
delete
[]
copy
;
// This is never 0
uint
tmp_error
;
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)
strxmov
(
table_name
,
table
->
db
,
"."
,
table
->
real_name
,
NullS
);
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
->
store
(
table_name
,
system_charset_info
);
...
...
@@ -3295,7 +3335,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
!
(
check_opt
->
flags
&
T_EXTEND
))
protocol
->
store
((
ulonglong
)
t
->
file
->
checksum
());
else
if
(
!
(
t
->
file
->
table_flags
()
&
HA_HAS_CHECKSUM
)
&&
(
check_opt
->
flags
&
T_QUICK
))
(
check_opt
->
flags
&
T_QUICK
))
protocol
->
store_null
();
else
{
...
...
@@ -3316,7 +3356,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
ha_checksum
row_crc
=
0
;
if
(
t
->
record
[
0
]
!=
(
byte
*
)
t
->
field
[
0
]
->
ptr
)
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
++
)
{
...
...
@@ -3329,7 +3369,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
}
else
row_crc
=
my_checksum
(
row_crc
,
(
byte
*
)
f
->
ptr
,
f
->
pack_length
());
f
->
pack_length
());
}
crc
+=
row_crc
;
...
...
@@ -3339,7 +3379,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
}
thd
->
clear_error
();
close_thread_tables
(
thd
);
table
->
table
=
0
;
// For query cache
table
->
table
=
0
;
// For query cache
}
if
(
protocol
->
write
())
goto
err
;
...
...
@@ -3349,7 +3389,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
DBUG_RETURN
(
0
);
err:
close_thread_tables
(
thd
);
// Shouldn't be needed
close_thread_tables
(
thd
);
// Shouldn't be needed
if
(
table
)
table
->
table
=
0
;
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