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
4de7e18b
Commit
4de7e18b
authored
Apr 07, 2004
by
ingo@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Hand-resolved auto merge
parents
61fd95d1
376f2526
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
1057 additions
and
597 deletions
+1057
-597
.bzrignore
.bzrignore
+3
-2
sql/handler.h
sql/handler.h
+28
-0
sql/mysql_priv.h
sql/mysql_priv.h
+25
-1
sql/sql_base.cc
sql/sql_base.cc
+0
-39
sql/sql_lex.h
sql/sql_lex.h
+9
-0
sql/sql_parse.cc
sql/sql_parse.cc
+2
-1
sql/sql_table.cc
sql/sql_table.cc
+907
-538
sql/sql_yacc.yy
sql/sql_yacc.yy
+60
-10
sql/unireg.cc
sql/unireg.cc
+23
-6
No files found.
.bzrignore
View file @
4de7e18b
...
...
@@ -250,6 +250,7 @@ client/thimble
client/thread_test
client_test
cmd-line-utils/libedit/common.h
cmd-line-utils/libedit/makelist
comon.h
config.cache
config.h
...
...
@@ -300,6 +301,7 @@ innobase/ib_config.h
innobase/ib_config.h.in
innobase/stamp-h1
insert_test
install
isam/isamchk
isam/isamlog
isam/pack_isam
...
...
@@ -504,6 +506,7 @@ mysys/main.cc
mysys/ste5KbMa
mysys/test_charset
mysys/test_dir
mysys/test_gethwaddr
mysys/test_io_cache
mysys/test_thr_alarm
mysys/test_thr_lock
...
...
@@ -646,5 +649,3 @@ vio/test-ssl
vio/test-sslclient
vio/test-sslserver
vio/viotest-ssl
mysys/test_gethwaddr
cmd-line-utils/libedit/makelist
sql/handler.h
View file @
4de7e18b
...
...
@@ -90,6 +90,20 @@
#define HA_NOT_READ_PREFIX_LAST 32
/* No support for index_read_last() */
#define HA_KEY_READ_ONLY 64
/* Support HA_EXTRA_KEYREAD */
/*
Bits in index_ddl_flags(KEY *wanted_index)
for what ddl you can do with index
If none is set, the wanted type of index is not supported
by the handler at all. See WorkLog 1563.
*/
#define HA_DDL_SUPPORT 1
/* Supported by handler */
#define HA_DDL_WITH_LOCK 2
/* Can create/drop with locked table */
#define HA_DDL_ONLINE 4
/* Can create/drop without lock */
/* Return value for ddl methods */
#define HA_DDL_NOT_IMPLEMENTED -1
/*
Parameters for open() (in register form->filestat)
HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED
...
...
@@ -355,6 +369,20 @@ public:
{
return
(
HA_READ_NEXT
|
HA_READ_PREV
|
HA_READ_ORDER
|
HA_KEY_READ_ONLY
);
}
virtual
ulong
index_ddl_flags
(
KEY
*
wanted_index
)
const
{
return
(
HA_DDL_SUPPORT
);
}
virtual
int
add_index
(
TABLE
*
table
,
KEY
*
key_info
,
uint
num_of_keys
)
{
my_error
(
ER_NOT_SUPPORTED_YET
,
MYF
(
0
),
"online add index"
);
return
(
HA_DDL_NOT_IMPLEMENTED
);
}
virtual
int
drop_index
(
TABLE
*
table
,
uint
*
key_num
,
uint
num_of_keys
)
{
my_error
(
ER_NOT_SUPPORTED_YET
,
MYF
(
0
),
"online drop index"
);
return
(
HA_DDL_NOT_IMPLEMENTED
);
}
virtual
uint
max_record_length
()
const
=
0
;
virtual
uint
max_keys
()
const
=
0
;
virtual
uint
max_key_parts
()
const
=
0
;
...
...
sql/mysql_priv.h
View file @
4de7e18b
...
...
@@ -488,6 +488,11 @@ int mysql_handle_derived(LEX *lex);
Field
*
create_tmp_field
(
THD
*
thd
,
TABLE
*
table
,
Item
*
item
,
Item
::
Type
type
,
Item
***
copy_func
,
Field
**
from_field
,
bool
group
,
bool
modify_item
);
int
mysql_prepare_table
(
THD
*
thd
,
HA_CREATE_INFO
*
create_info
,
List
<
create_field
>
&
fields
,
List
<
Key
>
&
keys
,
uint
&
db_options
,
handler
*
file
,
KEY
*&
key_info_buffer
,
uint
&
key_count
,
int
select_field_count
);
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
,
...
...
@@ -504,7 +509,19 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name,
List
<
create_field
>
&
fields
,
List
<
Key
>
&
keys
,
List
<
Alter_drop
>
&
drop_list
,
List
<
Alter_column
>
&
alter_list
,
uint
order_num
,
ORDER
*
order
,
uint
order_num
,
ORDER
*
order
,
int
alter_flags
,
enum
enum_duplicates
handle_duplicates
,
enum
enum_enable_or_disable
keys_onoff
=
LEAVE_AS_IS
,
enum
tablespace_op_type
tablespace_op
=
NO_TABLESPACE_OP
,
bool
simple_alter
=
0
);
int
real_alter_table
(
THD
*
thd
,
char
*
new_db
,
char
*
new_name
,
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
,
uint
order_num
,
ORDER
*
order
,
int
alter_flags
,
enum
enum_duplicates
handle_duplicates
,
enum
enum_enable_or_disable
keys_onoff
=
LEAVE_AS_IS
,
enum
tablespace_op_type
tablespace_op
=
NO_TABLESPACE_OP
,
...
...
@@ -520,6 +537,10 @@ bool mysql_rename_table(enum db_type base,
int
mysql_create_index
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Key
>
&
keys
);
int
mysql_drop_index
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Alter_drop
>
&
drop_list
);
int
mysql_add_column
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
create_field
>
&
fields
);
int
mysql_drop_column
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Alter_drop
>
&
drop_list
);
int
mysql_update
(
THD
*
thd
,
TABLE_LIST
*
tables
,
List
<
Item
>
&
fields
,
List
<
Item
>
&
values
,
COND
*
conds
,
uint
order_num
,
ORDER
*
order
,
ha_rows
limit
,
...
...
@@ -923,6 +944,9 @@ void unlock_table_names(THD *thd, TABLE_LIST *table_list,
void
unireg_init
(
ulong
options
);
void
unireg_end
(
void
);
int
mysql_create_frm
(
THD
*
thd
,
my_string
file_name
,
HA_CREATE_INFO
*
create_info
,
List
<
create_field
>
&
create_field
,
uint
key_count
,
KEY
*
key_info
,
handler
*
db_type
);
int
rea_create_table
(
THD
*
thd
,
my_string
file_name
,
HA_CREATE_INFO
*
create_info
,
List
<
create_field
>
&
create_field
,
uint
key_count
,
KEY
*
key_info
);
...
...
sql/sql_base.cc
View file @
4de7e18b
...
...
@@ -2604,45 +2604,6 @@ static void mysql_rm_tmp_tables(void)
}
/*
CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with
the proper arguments. This isn't very fast but it should work for most
cases.
One should normally create all indexes with CREATE TABLE or ALTER TABLE.
*/
int
mysql_create_index
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Key
>
&
keys
)
{
List
<
create_field
>
fields
;
List
<
Alter_drop
>
drop
;
List
<
Alter_column
>
alter
;
HA_CREATE_INFO
create_info
;
DBUG_ENTER
(
"mysql_create_index"
);
bzero
((
char
*
)
&
create_info
,
sizeof
(
create_info
));
create_info
.
db_type
=
DB_TYPE_DEFAULT
;
create_info
.
default_table_charset
=
thd
->
variables
.
collation_database
;
DBUG_RETURN
(
mysql_alter_table
(
thd
,
table_list
->
db
,
table_list
->
real_name
,
&
create_info
,
table_list
,
fields
,
keys
,
drop
,
alter
,
0
,
(
ORDER
*
)
0
,
DUP_ERROR
));
}
int
mysql_drop_index
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Alter_drop
>
&
drop
)
{
List
<
create_field
>
fields
;
List
<
Key
>
keys
;
List
<
Alter_column
>
alter
;
HA_CREATE_INFO
create_info
;
DBUG_ENTER
(
"mysql_drop_index"
);
bzero
((
char
*
)
&
create_info
,
sizeof
(
create_info
));
create_info
.
db_type
=
DB_TYPE_DEFAULT
;
create_info
.
default_table_charset
=
thd
->
variables
.
collation_database
;
DBUG_RETURN
(
mysql_alter_table
(
thd
,
table_list
->
db
,
table_list
->
real_name
,
&
create_info
,
table_list
,
fields
,
keys
,
drop
,
alter
,
0
,
(
ORDER
*
)
0
,
DUP_ERROR
));
}
/*****************************************************************************
unireg support functions
...
...
sql/sql_lex.h
View file @
4de7e18b
...
...
@@ -509,6 +509,14 @@ public:
};
typedef
class
st_select_lex
SELECT_LEX
;
#define ALTER_ADD_COLUMN 1
#define ALTER_DROP_COLUMN 2
#define ALTER_CHANGE_COLUMN 4
#define ALTER_ADD_INDEX 8
#define ALTER_DROP_INDEX 16
#define ALTER_RENAME 32
#define ALTER_ORDER 64
#define ALTER_OPTIONS 128
/* The state of the lex parsing. This is saved in the THD struct */
...
...
@@ -578,6 +586,7 @@ typedef struct st_lex
uint
grant
,
grant_tot_col
,
which_columns
;
uint
fk_delete_opt
,
fk_update_opt
,
fk_match_option
;
uint
slave_thd_opt
;
uint
alter_flags
;
uint8
describe
;
bool
drop_if_exists
,
drop_temporary
,
local_file
;
bool
in_comment
,
ignore_space
,
verbose
,
simple_alter
,
no_write_to_binlog
;
...
...
sql/sql_parse.cc
View file @
4de7e18b
...
...
@@ -2391,6 +2391,7 @@ unsent_create_error:
lex
->
key_list
,
lex
->
drop_list
,
lex
->
alter_list
,
select_lex
->
order_list
.
elements
,
(
ORDER
*
)
select_lex
->
order_list
.
first
,
lex
->
alter_flags
,
lex
->
duplicates
,
lex
->
alter_keys_onoff
,
lex
->
tablespace_op
,
...
...
@@ -2541,7 +2542,7 @@ unsent_create_error:
res
=
mysql_alter_table
(
thd
,
NullS
,
NullS
,
&
create_info
,
tables
,
lex
->
create_list
,
lex
->
key_list
,
lex
->
drop_list
,
lex
->
alter_list
,
0
,
(
ORDER
*
)
0
,
0
,
(
ORDER
*
)
0
,
0
,
DUP_ERROR
);
}
else
...
...
sql/sql_table.cc
View file @
4de7e18b
...
...
@@ -289,11 +289,15 @@ int quick_rm_table(enum db_type base,const char *db,
{
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
;
}
...
...
@@ -385,85 +389,45 @@ void check_duplicates_in_interval(const char *set_or_name,
}
/*
Create a table
Preparation for table creation
SYNOPSIS
mysql_
creat
e_table()
mysql_
prepar
e_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.
DESCRIPTION
If one creates a temporary table, this is automaticly opened
no_log is needed for the case of CREATE ... SELECT,
as the logging will be done later in sql_insert.cc
select_field_count is also used for CREATE ... SELECT,
and must be zero for standard create of table.
Prepares the table and key structures for table creation.
RETURN VALUES
0 ok
-1 error
*/
int
mysql_create_table
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
,
HA_CREATE_INFO
*
create_info
,
int
mysql_prepare_table
(
THD
*
thd
,
HA_CREATE_INFO
*
create_info
,
List
<
create_field
>
&
fields
,
List
<
Key
>
&
keys
,
bool
tmp_table
,
bool
no_log
,
uint
select_field_count
)
List
<
Key
>
&
keys
,
bool
tmp_table
,
uint
&
db_options
,
handler
*
file
,
KEY
*&
key_info_buffer
,
uint
&
key_count
,
int
select_field_count
)
{
char
path
[
FN_REFLEN
];
const
char
*
key_name
,
*
alias
;
const
char
*
key_name
;
create_field
*
sql_field
,
*
dup_field
;
int
error
=
-
1
;
uint
db_options
,
field
,
null_fields
,
blob_columns
;
uint
field
,
null_fields
,
blob_columns
;
ulong
pos
;
KEY
*
key_info
,
*
key_info_buffer
;
KEY
*
key_info
;
KEY_PART_INFO
*
key_part_info
;
int
auto_increment
=
0
;
int
timestamps
=
0
,
timestamps_with_niladic
=
0
;
handler
*
file
;
int
field_no
,
dup_no
;
enum
db_type
new_db_type
;
DBUG_ENTER
(
"mysql_
creat
e_table"
);
int
select_field_pos
,
auto_increment
=
0
;
DBUG_ENTER
(
"mysql_
prepar
e_table"
);
/* Check for duplicate fields and check type of table to create */
if
(
!
fields
.
elements
)
{
my_error
(
ER_TABLE_MUST_HAVE_COLUMNS
,
MYF
(
0
));
DBUG_RETURN
(
-
1
);
}
List_iterator
<
create_field
>
it
(
fields
),
it2
(
fields
);
int
select_field_pos
=
fields
.
elements
-
select_field_count
;
select_field_pos
=
fields
.
elements
-
select_field_count
;
null_fields
=
blob_columns
=
0
;
if
((
new_db_type
=
ha_checktype
(
create_info
->
db_type
))
!=
create_info
->
db_type
)
{
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
);
}
db_options
=
create_info
->
table_options
;
if
(
create_info
->
row_type
==
ROW_TYPE_DYNAMIC
)
db_options
|=
HA_OPTION_PACK_RECORD
;
alias
=
table_case_name
(
create_info
,
table_name
);
file
=
get_new_handler
((
TABLE
*
)
0
,
create_info
->
db_type
);
if
((
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
)
&&
(
file
->
table_flags
()
&
HA_NO_TEMP_TABLES
))
{
my_error
(
ER_ILLEGAL_HA
,
MYF
(
0
),
table_name
);
DBUG_RETURN
(
-
1
);
}
for
(
field_no
=
0
;
(
sql_field
=
it
++
)
;
field_no
++
)
{
...
...
@@ -681,13 +645,14 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
/* Create keys */
List_iterator
<
Key
>
key_iterator
(
keys
);
uint
key_parts
=
0
,
key_count
=
0
,
fk_key_count
=
0
;
uint
key_parts
=
0
,
fk_key_count
=
0
;
List
<
Key
>
keys_in_order
;
// Add new keys here
bool
primary_key
=
0
,
unique_key
=
0
;
Key
*
key
;
uint
tmp
,
key_number
;
/* Calculate number of key segements */
key_count
=
0
;
while
((
key
=
key_iterator
++
))
{
...
...
@@ -944,7 +909,9 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
{
/* 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
);
}
...
...
@@ -981,7 +948,9 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
{
/* 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
);
}
...
...
@@ -1061,15 +1030,100 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
/* Sort keys in optimized order */
qsort
((
gptr
)
key_info_buffer
,
key_count
,
sizeof
(
KEY
),
(
qsort_cmp
)
sort_keys
);
DBUG_RETURN
(
0
);
}
/*
Create a table
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.
DESCRIPTION
If one creates a temporary table, this is automaticly opened
no_log is needed for the case of CREATE ... SELECT,
as the logging will be done later in sql_insert.cc
select_field_count is also used for CREATE ... SELECT,
and must be zero for standard create of table.
RETURN VALUES
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
,
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
;
DBUG_ENTER
(
"mysql_create_table"
);
/* Check for duplicate fields and check type of table to create */
if
(
!
fields
.
elements
)
{
my_error
(
ER_TABLE_MUST_HAVE_COLUMNS
,
MYF
(
0
));
DBUG_RETURN
(
-
1
);
}
if
((
new_db_type
=
ha_checktype
(
create_info
->
db_type
))
!=
create_info
->
db_type
)
{
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
);
}
db_options
=
create_info
->
table_options
;
if
(
create_info
->
row_type
==
ROW_TYPE_DYNAMIC
)
db_options
|=
HA_OPTION_PACK_RECORD
;
alias
=
table_case_name
(
create_info
,
table_name
);
file
=
get_new_handler
((
TABLE
*
)
0
,
create_info
->
db_type
);
if
((
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
)
&&
(
file
->
table_flags
()
&
HA_NO_TEMP_TABLES
))
{
my_error
(
ER_ILLEGAL_HA
,
MYF
(
0
),
table_name
);
DBUG_RETURN
(
-
1
);
}
if
(
mysql_prepare_table
(
thd
,
create_info
,
fields
,
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
)
...
...
@@ -1163,17 +1217,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
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
;
}
/****************************************************************************
...
...
@@ -1271,8 +1331,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
);
...
...
@@ -1407,7 +1471,9 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
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
);
...
...
@@ -1491,7 +1557,12 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
if
(
!
my_stat
(
from
,
&
stat_info
,
MYF
(
0
)))
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
)
...
...
@@ -1626,7 +1697,9 @@ 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
...
...
@@ -1948,8 +2021,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
...
...
@@ -2007,7 +2083,9 @@ table_exists:
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
);
res
=
0
;
...
...
@@ -2118,19 +2196,307 @@ err:
DBUG_RETURN
(
error
);
}
/*
CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with
the proper arguments. This isn't very fast but it should work for most
cases.
One should normally create all indexes with CREATE TABLE or ALTER TABLE.
*/
int
mysql_create_index
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Key
>
&
keys
)
{
List
<
create_field
>
fields
;
List
<
Alter_drop
>
drop
;
List
<
Alter_column
>
alter
;
HA_CREATE_INFO
create_info
;
int
rc
;
uint
idx
;
uint
db_options
;
uint
key_count
;
TABLE
*
table
;
Field
**
f_ptr
;
KEY
*
key_info_buffer
;
char
path
[
FN_REFLEN
];
DBUG_ENTER
(
"mysql_create_index"
);
/*
Try to use online generation of index.
This requires that all indexes can be created online.
Otherwise, the old alter table procedure is executed.
Open the table to have access to the correct table handler.
*/
if
(
!
(
table
=
open_ltable
(
thd
,
table_list
,
TL_WRITE_ALLOW_READ
)))
DBUG_RETURN
(
-
1
);
/*
The add_index method takes an array of KEY structs for the new indexes.
Preparing a new table structure generates this array.
It needs a list with all fields of the table, which does not need to
be correct in every respect. The field names are important.
*/
for
(
f_ptr
=
table
->
field
;
*
f_ptr
;
f_ptr
++
)
{
create_field
*
c_fld
=
new
create_field
(
*
f_ptr
,
*
f_ptr
);
c_fld
->
unireg_check
=
Field
::
NONE
;
/*avoid multiple auto_increments*/
fields
.
push_back
(
c_fld
);
}
bzero
((
char
*
)
&
create_info
,
sizeof
(
create_info
));
create_info
.
db_type
=
DB_TYPE_DEFAULT
;
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
))
DBUG_RETURN
(
-
1
);
/*
Check if all keys can be generated with the add_index method.
If anyone cannot, then take the old way.
*/
for
(
idx
=
0
;
idx
<
key_count
;
idx
++
)
{
DBUG_PRINT
(
"info"
,
(
"creating index %s"
,
key_info_buffer
[
idx
].
name
));
if
(
!
(
table
->
file
->
index_ddl_flags
(
key_info_buffer
+
idx
)
&
(
HA_DDL_ONLINE
|
HA_DDL_WITH_LOCK
)))
break
;
}
if
((
idx
<
key_count
)
||
!
key_count
)
{
/* Re-initialize the create_info, which was changed by prepare table. */
bzero
((
char
*
)
&
create_info
,
sizeof
(
create_info
));
create_info
.
db_type
=
DB_TYPE_DEFAULT
;
create_info
.
default_table_charset
=
thd
->
variables
.
collation_database
;
/* Cleanup the fields list. We do not want to create existing fields. */
fields
.
delete_elements
();
if
(
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_INDEX
,
DUP_ERROR
))
/*don't need to free((gptr) key_info_buffer);*/
DBUG_RETURN
(
-
1
);
}
else
{
if
(
table
->
file
->
add_index
(
table
,
key_info_buffer
,
key_count
)
||
(
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
))
/*don't need to free((gptr) key_info_buffer);*/
DBUG_RETURN
(
-
1
);
}
/*don't need to free((gptr) key_info_buffer);*/
DBUG_RETURN
(
0
);
}
int
mysql_drop_index
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Alter_drop
>
&
drop
)
{
List
<
create_field
>
fields
;
List
<
Key
>
keys
;
List
<
Alter_column
>
alter
;
HA_CREATE_INFO
create_info
;
uint
idx
;
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
];
DBUG_ENTER
(
"mysql_drop_index"
);
/*
Try to use online generation of index.
This requires that all indexes can be created online.
Otherwise, the old alter table procedure is executed.
Open the table to have access to the correct table handler.
*/
if
(
!
(
table
=
open_ltable
(
thd
,
table_list
,
TL_WRITE_ALLOW_READ
)))
DBUG_RETURN
(
-
1
);
/*
The drop_index method takes an array of key numbers.
It cannot get more entries than keys in the table.
*/
key_numbers
=
(
uint
*
)
thd
->
alloc
(
sizeof
(
uint
*
)
*
table
->
keys
);
key_count
=
0
;
/*
Get the number of each key and check if it can be created online.
*/
List_iterator
<
Alter_drop
>
drop_it
(
drop
);
Alter_drop
*
drop_key
;
while
((
drop_key
=
drop_it
++
))
{
/* Find the key in the table. */
key_info
=
table
->
key_info
;
for
(
idx
=
0
;
idx
<
table
->
keys
;
idx
++
,
key_info
++
)
{
if
(
!
my_strcasecmp
(
system_charset_info
,
key_info
->
name
,
drop_key
->
name
))
break
;
}
if
(
idx
>=
table
->
keys
)
{
my_error
(
ER_CANT_DROP_FIELD_OR_KEY
,
MYF
(
0
),
drop_key
->
name
);
/*don't need to free((gptr) key_numbers);*/
DBUG_RETURN
(
-
1
);
}
/*
Check if the key can be generated with the add_index method.
If anyone cannot, then take the old way.
*/
DBUG_PRINT
(
"info"
,
(
"dropping index %s"
,
table
->
key_info
[
idx
].
name
));
if
(
!
(
table
->
file
->
index_ddl_flags
(
table
->
key_info
+
idx
)
&
(
HA_DDL_ONLINE
|
HA_DDL_WITH_LOCK
)))
break
;
key_numbers
[
key_count
++
]
=
idx
;
}
bzero
((
char
*
)
&
create_info
,
sizeof
(
create_info
));
create_info
.
db_type
=
DB_TYPE_DEFAULT
;
create_info
.
default_table_charset
=
thd
->
variables
.
collation_database
;
if
((
drop_key
)
||
(
drop
.
elements
<=
0
))
{
if
(
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_INDEX
,
DUP_ERROR
))
/*don't need to free((gptr) key_numbers);*/
DBUG_RETURN
(
-
1
);
}
else
{
db_options
=
0
;
if
(
table
->
file
->
drop_index
(
table
,
key_numbers
,
key_count
)
||
mysql_prepare_table
(
thd
,
&
create_info
,
fields
,
keys
,
/*tmp_table*/
0
,
db_options
,
table
->
file
,
key_info_buffer
,
key_count
,
/*select_field_count*/
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
))
/*don't need to free((gptr) key_numbers);*/
DBUG_RETURN
(
-
1
);
}
/*don't need to free((gptr) key_numbers);*/
DBUG_RETURN
(
0
);
}
int
mysql_add_column
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
create_field
>
&
fields
)
{
List
<
Alter_drop
>
drop
;
List
<
Key
>
keys
;
List
<
Alter_column
>
alter
;
HA_CREATE_INFO
create_info
;
DBUG_ENTER
(
"mysql_add_column"
);
bzero
((
char
*
)
&
create_info
,
sizeof
(
create_info
));
create_info
.
db_type
=
DB_TYPE_DEFAULT
;
create_info
.
default_table_charset
=
thd
->
variables
.
collation_database
;
TABLE
*
table
;
if
(
!
(
table
=
open_ltable
(
thd
,
table_list
,
TL_WRITE_ALLOW_READ
)))
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
));
}
int
mysql_drop_column
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Alter_drop
>
&
drop
)
{
List
<
create_field
>
fields
;
List
<
Key
>
keys
;
List
<
Alter_column
>
alter
;
HA_CREATE_INFO
create_info
;
DBUG_ENTER
(
"mysql_drop_column"
);
bzero
((
char
*
)
&
create_info
,
sizeof
(
create_info
));
create_info
.
db_type
=
DB_TYPE_DEFAULT
;
create_info
.
default_table_charset
=
thd
->
variables
.
collation_database
;
TABLE
*
table
;
if
(
!
(
table
=
open_ltable
(
thd
,
table_list
,
TL_WRITE_ALLOW_READ
)))
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
));
}
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
,
uint
order_num
,
ORDER
*
order
,
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
,
bool
simple_alter
)
{
DBUG_ENTER
(
"mysql_alter_table"
);
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
));
if
(
alter_flags
==
ALTER_ADD_INDEX
)
DBUG_RETURN
(
mysql_create_index
(
thd
,
table_list
,
keys
));
if
(
alter_flags
==
ALTER_DROP_INDEX
)
DBUG_RETURN
(
mysql_drop_index
(
thd
,
table_list
,
drop_list
));
if
(
alter_flags
==
ALTER_ADD_COLUMN
)
DBUG_RETURN
(
mysql_add_column
(
thd
,
table_list
,
fields
));
if
(
alter_flags
==
ALTER_DROP_COLUMN
)
DBUG_RETURN
(
mysql_drop_column
(
thd
,
table_list
,
drop_list
));
TABLE
*
table
;
if
(
!
(
table
=
open_ltable
(
thd
,
table_list
,
TL_WRITE_ALLOW_READ
)))
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
));
}
int
real_alter_table
(
THD
*
thd
,
char
*
new_db
,
char
*
new_name
,
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
,
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
,
bool
simple_alter
)
{
TABLE
*
table
,
*
new_table
;
TABLE
*
new_table
;
int
error
;
char
tmp_name
[
80
],
old_name
[
32
],
new_name_buff
[
FN_REFLEN
];
char
new_alias_buff
[
FN_REFLEN
],
*
table_name
,
*
db
,
*
new_alias
,
*
alias
;
...
...
@@ -2139,7 +2505,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
ulonglong
next_insert_id
;
uint
db_create_options
,
used_fields
;
enum
db_type
old_db_type
,
new_db_type
;
DBUG_ENTER
(
"
mysq
l_alter_table"
);
DBUG_ENTER
(
"
rea
l_alter_table"
);
thd
->
proc_info
=
"init"
;
table_name
=
table_list
->
real_name
;
...
...
@@ -2152,15 +2518,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
used_fields
=
create_info
->
used_fields
;
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
));
if
(
!
(
table
=
open_ltable
(
thd
,
table_list
,
TL_WRITE_ALLOW_READ
)))
DBUG_RETURN
(
-
1
);
/* Check that we are not trying to rename to an existing table */
if
(
new_name
)
{
...
...
@@ -2355,6 +2712,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
if
(
def
)
{
// Field is changed
def
->
field
=
field
;
if
(
def
->
sql_type
==
FIELD_TYPE_TIMESTAMP
)
use_timestamp
=
1
;
if
(
!
def
->
after
)
{
create_list
.
push_back
(
def
);
...
...
@@ -2364,6 +2723,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
else
{
// Use old field value
create_list
.
push_back
(
def
=
new
create_field
(
field
,
field
));
if
(
def
->
sql_type
==
FIELD_TYPE_TIMESTAMP
)
use_timestamp
=
1
;
alter_it
.
rewind
();
// Change default if ALTER
Alter_column
*
alter
;
while
((
alter
=
alter_it
++
))
...
...
@@ -2526,8 +2887,9 @@ int mysql_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
;
...
...
@@ -2606,7 +2968,9 @@ int mysql_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
);
}
...
...
@@ -2689,8 +3053,9 @@ int mysql_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
))
...
...
@@ -2813,7 +3178,9 @@ int mysql_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
)
...
...
@@ -2831,8 +3198,10 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
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
);
...
...
sql/sql_yacc.yy
View file @
4de7e18b
...
...
@@ -1439,10 +1439,29 @@ attribute:
{ Lex->on_update_value= new Item_func_now_local(); }
| AUTO_INC { Lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG; }
| SERIAL_SYM DEFAULT VALUE_SYM
{ Lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG; }
| opt_primary KEY_SYM { Lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG; }
| UNIQUE_SYM { Lex->type|= UNIQUE_FLAG; }
| UNIQUE_SYM KEY_SYM { Lex->type|= UNIQUE_KEY_FLAG; }
{
LEX *lex=Lex;
lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG;
lex->alter_flags|= ALTER_ADD_INDEX;
}
| opt_primary KEY_SYM
{
LEX *lex=Lex;
lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG;
lex->alter_flags|= ALTER_ADD_INDEX;
}
| UNIQUE_SYM
{
LEX *lex=Lex;
lex->type|= UNIQUE_FLAG;
lex->alter_flags|= ALTER_ADD_INDEX;
}
| UNIQUE_SYM KEY_SYM
{
LEX *lex=Lex;
lex->type|= UNIQUE_KEY_FLAG;
lex->alter_flags|= ALTER_ADD_INDEX;
}
| COMMENT_SYM TEXT_STRING_sys { Lex->comment= &$2; }
| BINARY { Lex->type|= BINCMP_FLAG; }
| COLLATE_SYM collation_name
...
...
@@ -1700,6 +1719,7 @@ alter:
lex->alter_keys_onoff=LEAVE_AS_IS;
lex->tablespace_op=NO_TABLESPACE_OP;
lex->simple_alter=1;
lex->alter_flags=0;
}
alter_list
{}
...
...
@@ -1718,16 +1738,28 @@ alter_list:
| alter_list ',' alter_list_item;
add_column:
ADD opt_column { Lex->change=0; };
ADD opt_column
{
LEX *lex=Lex;
lex->change=0;
lex->alter_flags|= ALTER_ADD_COLUMN;
};
alter_list_item:
add_column column_def opt_place { Lex->simple_alter=0; }
| ADD key_def { Lex->simple_alter=0; }
| ADD key_def
{
LEX *lex=Lex;
lex->simple_alter=0;
lex->alter_flags|= ALTER_ADD_INDEX;
}
| add_column '(' field_list ')' { Lex->simple_alter=0; }
| CHANGE opt_column field_ident
{
LEX *lex=Lex;
lex->change= $3.str; lex->simple_alter=0;
lex->change= $3.str;
lex->simple_alter=0;
lex->alter_flags|= ALTER_CHANGE_COLUMN;
}
field_spec opt_place
| MODIFY_SYM opt_column field_ident
...
...
@@ -1738,6 +1770,7 @@ alter_list_item:
lex->comment=0;
lex->charset= NULL;
lex->simple_alter=0;
lex->alter_flags|= ALTER_CHANGE_COLUMN;
}
type opt_attribute
{
...
...
@@ -1756,7 +1789,9 @@ alter_list_item:
{
LEX *lex=Lex;
lex->drop_list.push_back(new Alter_drop(Alter_drop::COLUMN,
$3.str)); lex->simple_alter=0;
$3.str));
lex->simple_alter=0;
lex->alter_flags|= ALTER_DROP_COLUMN;
}
| DROP FOREIGN KEY_SYM opt_ident { Lex->simple_alter=0; }
| DROP PRIMARY_SYM KEY_SYM
...
...
@@ -1765,6 +1800,7 @@ alter_list_item:
lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
primary_key_name));
lex->simple_alter=0;
lex->alter_flags|= ALTER_DROP_INDEX;
}
| DROP key_or_index field_ident
{
...
...
@@ -1772,6 +1808,7 @@ alter_list_item:
lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
$3.str));
lex->simple_alter=0;
lex->alter_flags|= ALTER_DROP_INDEX;
}
| DISABLE_SYM KEYS { Lex->alter_keys_onoff=DISABLE; }
| ENABLE_SYM KEYS { Lex->alter_keys_onoff=ENABLE; }
...
...
@@ -1780,18 +1817,21 @@ alter_list_item:
LEX *lex=Lex;
lex->alter_list.push_back(new Alter_column($3.str,$6));
lex->simple_alter=0;
lex->alter_flags|= ALTER_CHANGE_COLUMN;
}
| ALTER opt_column field_ident DROP DEFAULT
{
LEX *lex=Lex;
lex->alter_list.push_back(new Alter_column($3.str,(Item*) 0));
lex->simple_alter=0;
lex->alter_flags|= ALTER_CHANGE_COLUMN;
}
| RENAME opt_to table_ident
{
LEX *lex=Lex;
lex->select_lex.db=$3->db.str;
lex->name= $3->table.str;
lex->alter_flags|= ALTER_RENAME;
}
| CONVERT_SYM TO_SYM charset charset_name_or_default opt_collate
{
...
...
@@ -1814,8 +1854,18 @@ alter_list_item:
HA_CREATE_USED_DEFAULT_CHARSET);
lex->simple_alter= 0;
}
| create_table_options_space_separated { Lex->simple_alter=0; }
| order_clause { Lex->simple_alter=0; };
| create_table_options_space_separated
{
LEX *lex=Lex;
lex->simple_alter=0;
lex->alter_flags|= ALTER_OPTIONS;
}
| order_clause
{
LEX *lex=Lex;
lex->simple_alter=0;
lex->alter_flags|= ALTER_ORDER;
};
opt_column:
/* empty */ {}
...
...
sql/unireg.cc
View file @
4de7e18b
...
...
@@ -47,10 +47,11 @@ static bool make_empty_rec(int file, enum db_type table_type,
uint
reclength
,
uint
null_fields
);
int
rea_create_table
(
THD
*
thd
,
my_string
file_name
,
int
mysql_create_frm
(
THD
*
thd
,
my_string
file_name
,
HA_CREATE_INFO
*
create_info
,
List
<
create_field
>
&
create_fields
,
uint
keys
,
KEY
*
key_info
)
uint
keys
,
KEY
*
key_info
,
handler
*
db_file
)
{
uint
reclength
,
info_length
,
screens
,
key_info_length
,
maxlength
,
null_fields
;
File
file
;
...
...
@@ -58,12 +59,12 @@ int rea_create_table(THD *thd, my_string file_name,
uchar
fileinfo
[
64
],
forminfo
[
288
],
*
keybuff
;
TYPELIB
formnames
;
uchar
*
screen_buff
;
handler
*
db_file
;
DBUG_ENTER
(
"rea_create_table"
);
formnames
.
type_names
=
0
;
if
(
!
(
screen_buff
=
pack_screens
(
create_fields
,
&
info_length
,
&
screens
,
0
)))
DBUG_RETURN
(
1
);
if
(
db_file
==
NULL
)
db_file
=
get_new_handler
((
TABLE
*
)
0
,
create_info
->
db_type
);
if
(
pack_header
(
forminfo
,
create_info
->
db_type
,
create_fields
,
info_length
,
screens
,
create_info
->
table_options
,
db_file
))
...
...
@@ -155,8 +156,7 @@ int rea_create_table(THD *thd, my_string file_name,
if
(
opt_sync_frm
&&
!
(
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
)
&&
my_sync
(
file
,
MYF
(
MY_WME
)))
goto
err2
;
if
(
my_close
(
file
,
MYF
(
MY_WME
))
||
ha_create_table
(
file_name
,
create_info
,
0
))
if
(
my_close
(
file
,
MYF
(
MY_WME
)))
goto
err3
;
DBUG_RETURN
(
0
);
...
...
@@ -166,6 +166,23 @@ err:
err2:
VOID
(
my_close
(
file
,
MYF
(
MY_WME
)));
err3:
DBUG_RETURN
(
1
);
}
/* mysql_create_frm */
int
rea_create_table
(
THD
*
thd
,
my_string
file_name
,
HA_CREATE_INFO
*
create_info
,
List
<
create_field
>
&
create_fields
,
uint
keys
,
KEY
*
key_info
)
{
DBUG_ENTER
(
"rea_create_table"
);
if
(
mysql_create_frm
(
thd
,
file_name
,
create_info
,
create_fields
,
keys
,
key_info
,
NULL
)
||
ha_create_table
(
file_name
,
create_info
,
0
))
goto
err
;
DBUG_RETURN
(
0
);
err:
my_delete
(
file_name
,
MYF
(
0
));
DBUG_RETURN
(
1
);
}
/* rea_create_table */
...
...
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