Merge mysql.com:/nfsdisk1/lars/bkroot/mysql-4.1-rpl
into mysql.com:/nfsdisk1/lars/MERGE/mysql-4.1-merge sql/item_func.cc: Auto merged
This commit is contained in:
commit
1322c4aaef
@ -167,8 +167,7 @@ check_cpu () {
|
|||||||
touch __test.c
|
touch __test.c
|
||||||
|
|
||||||
while [ "$cpu_arg" ] ; do
|
while [ "$cpu_arg" ] ; do
|
||||||
# FIXME: echo -n isn't portable - see contortions autoconf goes through
|
printf "testing $cpu_arg ... " >&2
|
||||||
echo -n testing $cpu_arg "... " >&2
|
|
||||||
|
|
||||||
# compile check
|
# compile check
|
||||||
check_cpu_cflags=`eval echo $check_cpu_args`
|
check_cpu_cflags=`eval echo $check_cpu_args`
|
||||||
|
@ -2589,6 +2589,8 @@ static char *primary_key_fields(const char *table_name)
|
|||||||
char show_keys_buff[15 + 64 * 2 + 3];
|
char show_keys_buff[15 + 64 * 2 + 3];
|
||||||
uint result_length = 0;
|
uint result_length = 0;
|
||||||
char *result = 0;
|
char *result = 0;
|
||||||
|
char buff[NAME_LEN * 2 + 3];
|
||||||
|
char *quoted_field;
|
||||||
|
|
||||||
my_snprintf(show_keys_buff, sizeof(show_keys_buff),
|
my_snprintf(show_keys_buff, sizeof(show_keys_buff),
|
||||||
"SHOW KEYS FROM %s", table_name);
|
"SHOW KEYS FROM %s", table_name);
|
||||||
@ -2612,8 +2614,10 @@ static char *primary_key_fields(const char *table_name)
|
|||||||
{
|
{
|
||||||
/* Key is unique */
|
/* Key is unique */
|
||||||
do
|
do
|
||||||
result_length += strlen(row[4]) + 1; /* + 1 for ',' or \0 */
|
{
|
||||||
while ((row = mysql_fetch_row(res)) && atoi(row[3]) > 1);
|
quoted_field= quote_name(row[4], buff, 0);
|
||||||
|
result_length+= strlen(quoted_field) + 1; /* + 1 for ',' or \0 */
|
||||||
|
} while ((row= mysql_fetch_row(res)) && atoi(row[3]) > 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build the ORDER BY clause result */
|
/* Build the ORDER BY clause result */
|
||||||
@ -2627,9 +2631,13 @@ static char *primary_key_fields(const char *table_name)
|
|||||||
}
|
}
|
||||||
mysql_data_seek(res, 0);
|
mysql_data_seek(res, 0);
|
||||||
row = mysql_fetch_row(res);
|
row = mysql_fetch_row(res);
|
||||||
end = strmov(result, row[4]);
|
quoted_field= quote_name(row[4], buff, 0);
|
||||||
while ((row = mysql_fetch_row(res)) && atoi(row[3]) > 1)
|
end= strmov(result, quoted_field);
|
||||||
end = strxmov(end, ",", row[4], NullS);
|
while ((row= mysql_fetch_row(res)) && atoi(row[3]) > 1)
|
||||||
|
{
|
||||||
|
quoted_field= quote_name(row[4], buff, 0);
|
||||||
|
end= strxmov(end, ",", quoted_field, NullS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
@ -2990,10 +2990,14 @@ AM_CONDITIONAL(HAVE_NETWARE, test "$netware_dir" = "netware")
|
|||||||
export CC CXX CFLAGS CXXFLAGS LD LDFLAGS AR
|
export CC CXX CFLAGS CXXFLAGS LD LDFLAGS AR
|
||||||
ac_configure_args="$ac_configure_args CFLAGS='$CFLAGS' CXXFLAGS='$CXXFLAGS'"
|
ac_configure_args="$ac_configure_args CFLAGS='$CFLAGS' CXXFLAGS='$CXXFLAGS'"
|
||||||
|
|
||||||
if test "$with_server" = "yes" -o "$THREAD_SAFE_CLIENT" != "no"
|
if test "$with_server" != "no" -o "$THREAD_SAFE_CLIENT" != "no"
|
||||||
then
|
then
|
||||||
AC_DEFINE([THREAD], [1],
|
AC_DEFINE([THREAD], [1],
|
||||||
[Define if you want to have threaded code. This may be undef on client code])
|
[Define if you want to have threaded code. This may be undef on client code])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$with_server" != "no"
|
||||||
|
then
|
||||||
# Avoid _PROGRAMS names
|
# Avoid _PROGRAMS names
|
||||||
THREAD_LPROGRAMS="test_thr_alarm\$(EXEEXT) test_thr_lock\$(EXEEXT)"
|
THREAD_LPROGRAMS="test_thr_alarm\$(EXEEXT) test_thr_lock\$(EXEEXT)"
|
||||||
AC_SUBST(THREAD_LPROGRAMS)
|
AC_SUBST(THREAD_LPROGRAMS)
|
||||||
|
@ -76,7 +76,7 @@ int hp_get_new_block(HP_BLOCK *block, ulong *alloc_length)
|
|||||||
and my_default_record_cache_size we get about 1/128 unused memory.
|
and my_default_record_cache_size we get about 1/128 unused memory.
|
||||||
*/
|
*/
|
||||||
*alloc_length=sizeof(HP_PTRS)*i+block->records_in_block* block->recbuffer;
|
*alloc_length=sizeof(HP_PTRS)*i+block->records_in_block* block->recbuffer;
|
||||||
if (!(root=(HP_PTRS*) my_malloc(*alloc_length,MYF(0))))
|
if (!(root=(HP_PTRS*) my_malloc(*alloc_length,MYF(MY_WME))))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
|
@ -68,11 +68,17 @@ int heap_write(HP_INFO *info, const byte *record)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
DBUG_PRINT("info",("Duplicate key: %d", keydef - share->keydef));
|
if (my_errno == HA_ERR_FOUND_DUPP_KEY)
|
||||||
|
DBUG_PRINT("info",("Duplicate key: %d", keydef - share->keydef));
|
||||||
info->errkey= keydef - share->keydef;
|
info->errkey= keydef - share->keydef;
|
||||||
if (keydef->algorithm == HA_KEY_ALG_BTREE)
|
/*
|
||||||
|
We don't need to delete non-inserted key from rb-tree. Also, if
|
||||||
|
we got ENOMEM, the key wasn't inserted, so don't try to delete it
|
||||||
|
either. Otherwise for HASH index on HA_ERR_FOUND_DUPP_KEY the key
|
||||||
|
was inserted and we have to delete it.
|
||||||
|
*/
|
||||||
|
if (keydef->algorithm == HA_KEY_ALG_BTREE || my_errno == ENOMEM)
|
||||||
{
|
{
|
||||||
/* we don't need to delete non-inserted key from rb-tree */
|
|
||||||
keydef--;
|
keydef--;
|
||||||
}
|
}
|
||||||
while (keydef >= share->keydef)
|
while (keydef >= share->keydef)
|
||||||
|
@ -84,6 +84,42 @@
|
|||||||
#define NETWARE_SET_SCREEN_MODE(A)
|
#define NETWARE_SET_SCREEN_MODE(A)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
The macros below are used to allow build of Universal/fat binaries of
|
||||||
|
MySQL and MySQL applications under darwin.
|
||||||
|
*/
|
||||||
|
#ifdef TARGET_FAT_BINARY
|
||||||
|
# undef SIZEOF_CHARP
|
||||||
|
# undef SIZEOF_INT
|
||||||
|
# undef SIZEOF_LONG
|
||||||
|
# undef SIZEOF_LONG_LONG
|
||||||
|
# undef SIZEOF_OFF_T
|
||||||
|
# undef SIZEOF_SHORT
|
||||||
|
|
||||||
|
#if defined(__i386__)
|
||||||
|
# undef WORDS_BIGENDIAN
|
||||||
|
# define SIZEOF_CHARP 4
|
||||||
|
# define SIZEOF_INT 4
|
||||||
|
# define SIZEOF_LONG 4
|
||||||
|
# define SIZEOF_LONG_LONG 8
|
||||||
|
# define SIZEOF_OFF_T 8
|
||||||
|
# define SIZEOF_SHORT 2
|
||||||
|
|
||||||
|
#elif defined(__ppc__)
|
||||||
|
# define WORDS_BIGENDIAN
|
||||||
|
# define SIZEOF_CHARP 4
|
||||||
|
# define SIZEOF_INT 4
|
||||||
|
# define SIZEOF_LONG 4
|
||||||
|
# define SIZEOF_LONG_LONG 8
|
||||||
|
# define SIZEOF_OFF_T 8
|
||||||
|
# define SIZEOF_SHORT 2
|
||||||
|
|
||||||
|
#else
|
||||||
|
# error Building FAT binary for an unknown architecture.
|
||||||
|
#endif
|
||||||
|
#endif /* TARGET_FAT_BINARY */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The macros below are borrowed from include/linux/compiler.h in the
|
The macros below are borrowed from include/linux/compiler.h in the
|
||||||
Linux kernel. Use them to indicate the likelyhood of the truthfulness
|
Linux kernel. Use them to indicate the likelyhood of the truthfulness
|
||||||
|
@ -18,6 +18,9 @@ typedef struct hash_cell_struct hash_cell_t;
|
|||||||
|
|
||||||
typedef void* hash_node_t;
|
typedef void* hash_node_t;
|
||||||
|
|
||||||
|
/* Fix Bug #13859: symbol collision between imap/mysql */
|
||||||
|
#define hash_create hash0_create
|
||||||
|
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
Creates a hash table with >= n array cells. The actual number
|
Creates a hash table with >= n array cells. The actual number
|
||||||
of cells is chosen to be a prime number slightly bigger than n. */
|
of cells is chosen to be a prime number slightly bigger than n. */
|
||||||
|
@ -124,12 +124,34 @@ create table t1 select date_format("2004-01-19 10:10:10", "%Y-%m-%d");
|
|||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`date_format("2004-01-19 10:10:10", "%Y-%m-%d")` binary(10) default NULL
|
`date_format("2004-01-19 10:10:10", "%Y-%m-%d")` char(10) character set utf8 default NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
select * from t1;
|
select * from t1;
|
||||||
date_format("2004-01-19 10:10:10", "%Y-%m-%d")
|
date_format("2004-01-19 10:10:10", "%Y-%m-%d")
|
||||||
2004-01-19
|
2004-01-19
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
set names utf8;
|
||||||
|
set LC_TIME_NAMES='fr_FR';
|
||||||
|
create table t1 (s1 char(20) character set latin1);
|
||||||
|
insert into t1 values (date_format('2004-02-02','%M'));
|
||||||
|
select hex(s1) from t1;
|
||||||
|
hex(s1)
|
||||||
|
66E97672696572
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (s1 char(20) character set koi8r);
|
||||||
|
set LC_TIME_NAMES='ru_RU';
|
||||||
|
insert into t1 values (date_format('2004-02-02','%M'));
|
||||||
|
insert into t1 values (date_format('2004-02-02','%b'));
|
||||||
|
insert into t1 values (date_format('2004-02-02','%W'));
|
||||||
|
insert into t1 values (date_format('2004-02-02','%a'));
|
||||||
|
select hex(s1), s1 from t1;
|
||||||
|
hex(s1) s1
|
||||||
|
E6C5D7D2C1CCD1 Февраля
|
||||||
|
E6C5D7 Фев
|
||||||
|
F0CFCEC5C4C5CCD8CEC9CB Понедельник
|
||||||
|
F0CEC4 Пнд
|
||||||
|
drop table t1;
|
||||||
|
set LC_TIME_NAMES='en_US';
|
||||||
set names koi8r;
|
set names koi8r;
|
||||||
create table t1 (s1 char(1) character set utf8);
|
create table t1 (s1 char(1) character set utf8);
|
||||||
insert into t1 values (_koi8r'ÁÂ');
|
insert into t1 values (_koi8r'ÁÂ');
|
||||||
|
@ -1584,4 +1584,66 @@ CREATE TABLE `t1` (
|
|||||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||||
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
CREATE TABLE `t1` (
|
||||||
|
`a b` INT,
|
||||||
|
`c"d` INT,
|
||||||
|
`e``f` INT,
|
||||||
|
PRIMARY KEY (`a b`, `c"d`, `e``f`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
insert into t1 values (0815, 4711, 2006);
|
||||||
|
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */;
|
||||||
|
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||||
|
DROP TABLE IF EXISTS "t1";
|
||||||
|
CREATE TABLE "t1" (
|
||||||
|
"a b" int(11) NOT NULL default '0',
|
||||||
|
"c""d" int(11) NOT NULL default '0',
|
||||||
|
"e`f" int(11) NOT NULL default '0',
|
||||||
|
PRIMARY KEY ("a b","c""d","e`f")
|
||||||
|
);
|
||||||
|
|
||||||
|
LOCK TABLES "t1" WRITE;
|
||||||
|
/*!40000 ALTER TABLE "t1" DISABLE KEYS */;
|
||||||
|
INSERT INTO "t1" VALUES (815,4711,2006);
|
||||||
|
/*!40000 ALTER TABLE "t1" ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||||
|
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||||
|
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||||
|
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||||
|
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||||
|
/*!40101 SET NAMES utf8 */;
|
||||||
|
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||||
|
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||||
|
DROP TABLE IF EXISTS `t1`;
|
||||||
|
CREATE TABLE `t1` (
|
||||||
|
`a b` int(11) NOT NULL default '0',
|
||||||
|
`c"d` int(11) NOT NULL default '0',
|
||||||
|
`e``f` int(11) NOT NULL default '0',
|
||||||
|
PRIMARY KEY (`a b`,`c"d`,`e``f`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
|
||||||
|
LOCK TABLES `t1` WRITE;
|
||||||
|
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
|
||||||
|
INSERT INTO `t1` VALUES (815,4711,2006);
|
||||||
|
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||||
|
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||||
|
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||||
|
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||||
|
|
||||||
|
DROP TABLE `t1`;
|
||||||
End of 4.1 tests
|
End of 4.1 tests
|
||||||
|
@ -1035,4 +1035,71 @@ EXECUTE stmt USING @a;
|
|||||||
0 0
|
0 0
|
||||||
DEALLOCATE PREPARE stmt;
|
DEALLOCATE PREPARE stmt;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
|
CREATE TABLE t1 (i INT);
|
||||||
|
PREPARE st_19182
|
||||||
|
FROM "CREATE TABLE t2 (i INT, j INT, KEY (i), KEY(j)) SELECT i FROM t1";
|
||||||
|
EXECUTE st_19182;
|
||||||
|
DESC t2;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
j int(11) YES MUL NULL
|
||||||
|
i int(11) YES MUL NULL
|
||||||
|
DROP TABLE t2;
|
||||||
|
EXECUTE st_19182;
|
||||||
|
DESC t2;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
j int(11) YES MUL NULL
|
||||||
|
i int(11) YES MUL NULL
|
||||||
|
DEALLOCATE PREPARE st_19182;
|
||||||
|
DROP TABLE t2, t1;
|
||||||
|
drop database if exists mysqltest;
|
||||||
|
drop table if exists t1, t2;
|
||||||
|
create database mysqltest character set utf8;
|
||||||
|
prepare stmt1 from "create table mysqltest.t1 (c char(10))";
|
||||||
|
prepare stmt2 from "create table mysqltest.t2 select 'test'";
|
||||||
|
execute stmt1;
|
||||||
|
execute stmt2;
|
||||||
|
show create table mysqltest.t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c` char(10) default NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8
|
||||||
|
show create table mysqltest.t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`test` char(4) character set latin1 NOT NULL default ''
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8
|
||||||
|
drop table mysqltest.t1;
|
||||||
|
drop table mysqltest.t2;
|
||||||
|
alter database mysqltest character set latin1;
|
||||||
|
execute stmt1;
|
||||||
|
execute stmt2;
|
||||||
|
show create table mysqltest.t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c` char(10) character set utf8 default NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
show create table mysqltest.t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`test` char(4) NOT NULL default ''
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop database mysqltest;
|
||||||
|
deallocate prepare stmt1;
|
||||||
|
deallocate prepare stmt2;
|
||||||
|
execute stmt;
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c` char(10) default NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/tmp/'
|
||||||
|
drop table t1;
|
||||||
|
execute stmt;
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`c` char(10) default NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/tmp/'
|
||||||
|
drop table t1;
|
||||||
|
deallocate prepare stmt;
|
||||||
End of 4.1 tests.
|
End of 4.1 tests.
|
||||||
|
16
mysql-test/r/rpl_locale.result
Normal file
16
mysql-test/r/rpl_locale.result
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
stop slave;
|
||||||
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
|
reset master;
|
||||||
|
reset slave;
|
||||||
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
|
start slave;
|
||||||
|
create table t1 (s1 char(10));
|
||||||
|
set lc_time_names= 'de_DE';
|
||||||
|
insert into t1 values (date_format('2001-01-01','%W'));
|
||||||
|
select * from t1;
|
||||||
|
s1
|
||||||
|
Montag
|
||||||
|
select * from t1;
|
||||||
|
s1
|
||||||
|
Montag
|
||||||
|
drop table t1;
|
@ -499,6 +499,63 @@ set names latin1;
|
|||||||
select @@have_innodb;
|
select @@have_innodb;
|
||||||
@@have_innodb
|
@@have_innodb
|
||||||
#
|
#
|
||||||
|
*** Various tests with LC_TIME_NAMES
|
||||||
|
*** LC_TIME_NAMES: testing case insensitivity
|
||||||
|
set @@lc_time_names='ru_ru';
|
||||||
|
select @@lc_time_names;
|
||||||
|
@@lc_time_names
|
||||||
|
ru_RU
|
||||||
|
*** LC_TIME_NAMES: testing with a user variable
|
||||||
|
set @lc='JA_JP';
|
||||||
|
set @@lc_time_names=@lc;
|
||||||
|
select @@lc_time_names;
|
||||||
|
@@lc_time_names
|
||||||
|
ja_JP
|
||||||
|
*** LC_TIME_NAMES: testing with string expressions
|
||||||
|
set lc_time_names=concat('de','_','DE');
|
||||||
|
select @@lc_time_names;
|
||||||
|
@@lc_time_names
|
||||||
|
de_DE
|
||||||
|
set lc_time_names=concat('de','+','DE');
|
||||||
|
ERROR HY000: Unknown locale: 'de+DE'
|
||||||
|
select @@lc_time_names;
|
||||||
|
@@lc_time_names
|
||||||
|
de_DE
|
||||||
|
LC_TIME_NAMES: testing with numeric expressions
|
||||||
|
set @@lc_time_names=1+2;
|
||||||
|
select @@lc_time_names;
|
||||||
|
@@lc_time_names
|
||||||
|
sv_SE
|
||||||
|
set @@lc_time_names=1/0;
|
||||||
|
ERROR 42000: Incorrect argument type to variable 'lc_time_names'
|
||||||
|
select @@lc_time_names;
|
||||||
|
@@lc_time_names
|
||||||
|
sv_SE
|
||||||
|
set lc_time_names=en_US;
|
||||||
|
LC_TIME_NAMES: testing NULL and a negative number:
|
||||||
|
set lc_time_names=NULL;
|
||||||
|
ERROR 42000: Variable 'lc_time_names' can't be set to the value of 'NULL'
|
||||||
|
set lc_time_names=-1;
|
||||||
|
ERROR HY000: Unknown locale: '-1'
|
||||||
|
select @@lc_time_names;
|
||||||
|
@@lc_time_names
|
||||||
|
en_US
|
||||||
|
LC_TIME_NAMES: testing locale with the last ID:
|
||||||
|
set lc_time_names=108;
|
||||||
|
select @@lc_time_names;
|
||||||
|
@@lc_time_names
|
||||||
|
zh_HK
|
||||||
|
LC_TIME_NAMES: testing a number beyond the valid ID range:
|
||||||
|
set lc_time_names=109;
|
||||||
|
ERROR HY000: Unknown locale: '109'
|
||||||
|
select @@lc_time_names;
|
||||||
|
@@lc_time_names
|
||||||
|
zh_HK
|
||||||
|
LC_TIME_NAMES: testing that 0 is en_US:
|
||||||
|
set lc_time_names=0;
|
||||||
|
select @@lc_time_names;
|
||||||
|
@@lc_time_names
|
||||||
|
en_US
|
||||||
set @test = @@query_prealloc_size;
|
set @test = @@query_prealloc_size;
|
||||||
set @@query_prealloc_size = @test;
|
set @@query_prealloc_size = @test;
|
||||||
select @@query_prealloc_size = @test;
|
select @@query_prealloc_size = @test;
|
||||||
|
@ -51,5 +51,6 @@ unlock tables;
|
|||||||
connection con1;
|
connection con1;
|
||||||
reap;
|
reap;
|
||||||
drop table t5;
|
drop table t5;
|
||||||
|
--system rm $MYSQLTEST_VARDIR/tmp/t?.*
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
@ -93,6 +93,26 @@ show create table t1;
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#22646 LC_TIME_NAMES: Assignment to non-UTF8 target fails
|
||||||
|
#
|
||||||
|
set names utf8;
|
||||||
|
set LC_TIME_NAMES='fr_FR';
|
||||||
|
create table t1 (s1 char(20) character set latin1);
|
||||||
|
insert into t1 values (date_format('2004-02-02','%M'));
|
||||||
|
select hex(s1) from t1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (s1 char(20) character set koi8r);
|
||||||
|
set LC_TIME_NAMES='ru_RU';
|
||||||
|
insert into t1 values (date_format('2004-02-02','%M'));
|
||||||
|
insert into t1 values (date_format('2004-02-02','%b'));
|
||||||
|
insert into t1 values (date_format('2004-02-02','%W'));
|
||||||
|
insert into t1 values (date_format('2004-02-02','%a'));
|
||||||
|
select hex(s1), s1 from t1;
|
||||||
|
drop table t1;
|
||||||
|
set LC_TIME_NAMES='en_US';
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug #2366 Wrong utf8 behaviour when data is truncated
|
# Bug #2366 Wrong utf8 behaviour when data is truncated
|
||||||
#
|
#
|
||||||
|
@ -702,4 +702,19 @@ create table t1 (a int);
|
|||||||
--exec $MYSQL_DUMP --skip-comments --force test t1 --where='xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' 2>&1
|
--exec $MYSQL_DUMP --skip-comments --force test t1 --where='xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' 2>&1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#13926: --order-by-primary fails if PKEY contains quote character
|
||||||
|
#
|
||||||
|
CREATE TABLE `t1` (
|
||||||
|
`a b` INT,
|
||||||
|
`c"d` INT,
|
||||||
|
`e``f` INT,
|
||||||
|
PRIMARY KEY (`a b`, `c"d`, `e``f`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
insert into t1 values (0815, 4711, 2006);
|
||||||
|
|
||||||
|
--exec $MYSQL_DUMP --skip-comments --compatible=ansi --order-by-primary test t1
|
||||||
|
--exec $MYSQL_DUMP --skip-comments --order-by-primary test t1
|
||||||
|
DROP TABLE `t1`;
|
||||||
|
|
||||||
--echo End of 4.1 tests
|
--echo End of 4.1 tests
|
||||||
|
@ -1068,5 +1068,82 @@ EXECUTE stmt USING @a;
|
|||||||
DEALLOCATE PREPARE stmt;
|
DEALLOCATE PREPARE stmt;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#19182: CREATE TABLE bar (m INT) SELECT n FROM foo; doesn't work
|
||||||
|
# from stored procedure.
|
||||||
|
#
|
||||||
|
# The cause of a bug was that cached LEX::create_list was modified,
|
||||||
|
# and then together with LEX::key_list was reset.
|
||||||
|
#
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 (i INT);
|
||||||
|
|
||||||
|
PREPARE st_19182
|
||||||
|
FROM "CREATE TABLE t2 (i INT, j INT, KEY (i), KEY(j)) SELECT i FROM t1";
|
||||||
|
|
||||||
|
EXECUTE st_19182;
|
||||||
|
DESC t2;
|
||||||
|
|
||||||
|
DROP TABLE t2;
|
||||||
|
|
||||||
|
# Check that on second execution we don't loose 'j' column and the keys
|
||||||
|
# on 'i' and 'j' columns.
|
||||||
|
EXECUTE st_19182;
|
||||||
|
DESC t2;
|
||||||
|
|
||||||
|
DEALLOCATE PREPARE st_19182;
|
||||||
|
DROP TABLE t2, t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #22060 "ALTER TABLE x AUTO_INCREMENT=y in SP crashes server"
|
||||||
|
#
|
||||||
|
# Code which implemented CREATE/ALTER TABLE and CREATE DATABASE
|
||||||
|
# statement modified HA_CREATE_INFO structure in LEX, making these
|
||||||
|
# statements PS/SP-unsafe (their re-execution might have resulted
|
||||||
|
# in incorrect results).
|
||||||
|
#
|
||||||
|
--disable_warnings
|
||||||
|
drop database if exists mysqltest;
|
||||||
|
drop table if exists t1, t2;
|
||||||
|
--enable_warnings
|
||||||
|
# CREATE TABLE and CREATE TABLE ... SELECT
|
||||||
|
create database mysqltest character set utf8;
|
||||||
|
prepare stmt1 from "create table mysqltest.t1 (c char(10))";
|
||||||
|
prepare stmt2 from "create table mysqltest.t2 select 'test'";
|
||||||
|
execute stmt1;
|
||||||
|
execute stmt2;
|
||||||
|
show create table mysqltest.t1;
|
||||||
|
show create table mysqltest.t2;
|
||||||
|
drop table mysqltest.t1;
|
||||||
|
drop table mysqltest.t2;
|
||||||
|
alter database mysqltest character set latin1;
|
||||||
|
execute stmt1;
|
||||||
|
execute stmt2;
|
||||||
|
show create table mysqltest.t1;
|
||||||
|
show create table mysqltest.t2;
|
||||||
|
drop database mysqltest;
|
||||||
|
deallocate prepare stmt1;
|
||||||
|
deallocate prepare stmt2;
|
||||||
|
#
|
||||||
|
# CREATE TABLE with DATA DIRECTORY option
|
||||||
|
#
|
||||||
|
# Protect ourselves from data left in tmp/ by a previos possibly failed
|
||||||
|
# test
|
||||||
|
--system rm -f $MYSQLTEST_VARDIR/tmp/t1.*
|
||||||
|
--disable_query_log
|
||||||
|
eval prepare stmt from "create table t1 (c char(10)) data directory='$MYSQLTEST_VARDIR/tmp'";
|
||||||
|
--enable_query_log
|
||||||
|
execute stmt;
|
||||||
|
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
execute stmt;
|
||||||
|
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
deallocate prepare stmt;
|
||||||
|
#
|
||||||
--echo End of 4.1 tests.
|
--echo End of 4.1 tests.
|
||||||
|
22
mysql-test/t/rpl_locale.test
Normal file
22
mysql-test/t/rpl_locale.test
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Replication of locale variables
|
||||||
|
|
||||||
|
source include/master-slave.inc;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#22645 LC_TIME_NAMES: Statement not replicated
|
||||||
|
#
|
||||||
|
connection master;
|
||||||
|
create table t1 (s1 char(10));
|
||||||
|
set lc_time_names= 'de_DE';
|
||||||
|
insert into t1 values (date_format('2001-01-01','%W'));
|
||||||
|
select * from t1;
|
||||||
|
sync_slave_with_master;
|
||||||
|
connection slave;
|
||||||
|
select * from t1;
|
||||||
|
connection master;
|
||||||
|
drop table t1;
|
||||||
|
sync_slave_with_master;
|
||||||
|
|
||||||
|
# End of 4.1 tests
|
||||||
|
|
||||||
|
|
@ -396,6 +396,50 @@ set names latin1;
|
|||||||
--replace_column 1 #
|
--replace_column 1 #
|
||||||
select @@have_innodb;
|
select @@have_innodb;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Tests for lc_time_names
|
||||||
|
# Note, when adding new locales, please fix ID accordingly:
|
||||||
|
# - to test the last ID (currently 108)
|
||||||
|
# - and the next after the last (currently 109)
|
||||||
|
#
|
||||||
|
--echo *** Various tests with LC_TIME_NAMES
|
||||||
|
--echo *** LC_TIME_NAMES: testing case insensitivity
|
||||||
|
set @@lc_time_names='ru_ru';
|
||||||
|
select @@lc_time_names;
|
||||||
|
--echo *** LC_TIME_NAMES: testing with a user variable
|
||||||
|
set @lc='JA_JP';
|
||||||
|
set @@lc_time_names=@lc;
|
||||||
|
select @@lc_time_names;
|
||||||
|
--echo *** LC_TIME_NAMES: testing with string expressions
|
||||||
|
set lc_time_names=concat('de','_','DE');
|
||||||
|
select @@lc_time_names;
|
||||||
|
--error 1105
|
||||||
|
set lc_time_names=concat('de','+','DE');
|
||||||
|
select @@lc_time_names;
|
||||||
|
--echo LC_TIME_NAMES: testing with numeric expressions
|
||||||
|
set @@lc_time_names=1+2;
|
||||||
|
select @@lc_time_names;
|
||||||
|
--error 1232
|
||||||
|
set @@lc_time_names=1/0;
|
||||||
|
select @@lc_time_names;
|
||||||
|
set lc_time_names=en_US;
|
||||||
|
--echo LC_TIME_NAMES: testing NULL and a negative number:
|
||||||
|
--error 1231
|
||||||
|
set lc_time_names=NULL;
|
||||||
|
--error 1105
|
||||||
|
set lc_time_names=-1;
|
||||||
|
select @@lc_time_names;
|
||||||
|
--echo LC_TIME_NAMES: testing locale with the last ID:
|
||||||
|
set lc_time_names=108;
|
||||||
|
select @@lc_time_names;
|
||||||
|
--echo LC_TIME_NAMES: testing a number beyond the valid ID range:
|
||||||
|
--error 1105
|
||||||
|
set lc_time_names=109;
|
||||||
|
select @@lc_time_names;
|
||||||
|
--echo LC_TIME_NAMES: testing that 0 is en_US:
|
||||||
|
set lc_time_names=0;
|
||||||
|
select @@lc_time_names;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug #13334: query_prealloc_size default less than minimum
|
# Bug #13334: query_prealloc_size default less than minimum
|
||||||
#
|
#
|
||||||
|
@ -322,7 +322,7 @@ BASE=$BASE2
|
|||||||
#
|
#
|
||||||
|
|
||||||
if [ x"@GXX@" = x"yes" ] ; then
|
if [ x"@GXX@" = x"yes" ] ; then
|
||||||
gcclib=`@CC@ --print-libgcc-file`
|
gcclib=`@CC@ @CFLAGS@ --print-libgcc-file`
|
||||||
if [ $? -ne 0 ] ; then
|
if [ $? -ne 0 ] ; then
|
||||||
echo "Warning: Couldn't find libgcc.a!"
|
echo "Warning: Couldn't find libgcc.a!"
|
||||||
else
|
else
|
||||||
|
@ -22,6 +22,16 @@ command=".mysql.$$"
|
|||||||
trap "interrupt" 2
|
trap "interrupt" 2
|
||||||
|
|
||||||
rootpass=""
|
rootpass=""
|
||||||
|
echo_n=
|
||||||
|
echo_c=
|
||||||
|
|
||||||
|
set_echo_compat() {
|
||||||
|
case `echo "testing\c"`,`echo -n testing` in
|
||||||
|
*c*,-n*) echo_n= echo_c= ;;
|
||||||
|
*c*,*) echo_n=-n echo_c= ;;
|
||||||
|
*) echo_n= echo_c='\c' ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
prepare() {
|
prepare() {
|
||||||
touch $config $command
|
touch $config $command
|
||||||
@ -45,7 +55,7 @@ get_root_password() {
|
|||||||
status=1
|
status=1
|
||||||
while [ $status -eq 1 ]; do
|
while [ $status -eq 1 ]; do
|
||||||
stty -echo
|
stty -echo
|
||||||
echo -n "Enter current password for root (enter for none): "
|
echo $echo_n "Enter current password for root (enter for none): $echo_c"
|
||||||
read password
|
read password
|
||||||
echo
|
echo
|
||||||
stty echo
|
stty echo
|
||||||
@ -65,10 +75,10 @@ get_root_password() {
|
|||||||
|
|
||||||
set_root_password() {
|
set_root_password() {
|
||||||
stty -echo
|
stty -echo
|
||||||
echo -n "New password: "
|
echo $echo_n "New password: $echo_c"
|
||||||
read password1
|
read password1
|
||||||
echo
|
echo
|
||||||
echo -n "Re-enter new password: "
|
echo $echo_n "Re-enter new password: $echo_c"
|
||||||
read password2
|
read password2
|
||||||
echo
|
echo
|
||||||
stty echo
|
stty echo
|
||||||
@ -173,6 +183,7 @@ cleanup() {
|
|||||||
# The actual script starts here
|
# The actual script starts here
|
||||||
|
|
||||||
prepare
|
prepare
|
||||||
|
set_echo_compat
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo
|
echo
|
||||||
@ -201,11 +212,11 @@ echo "root user without the proper authorisation."
|
|||||||
echo
|
echo
|
||||||
|
|
||||||
if [ $hadpass -eq 0 ]; then
|
if [ $hadpass -eq 0 ]; then
|
||||||
echo -n "Set root password? [Y/n] "
|
echo $echo_n "Set root password? [Y/n] $echo_c"
|
||||||
else
|
else
|
||||||
echo "You already have a root password set, so you can safely answer 'n'."
|
echo "You already have a root password set, so you can safely answer 'n'."
|
||||||
echo
|
echo
|
||||||
echo -n "Change the root password? [Y/n] "
|
echo $echo_n "Change the root password? [Y/n] $echo_c"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
read reply
|
read reply
|
||||||
@ -232,7 +243,7 @@ echo "go a bit smoother. You should remove them before moving into a"
|
|||||||
echo "production environment."
|
echo "production environment."
|
||||||
echo
|
echo
|
||||||
|
|
||||||
echo -n "Remove anonymous users? [Y/n] "
|
echo $echo_n "Remove anonymous users? [Y/n] $echo_c"
|
||||||
|
|
||||||
read reply
|
read reply
|
||||||
if [ "$reply" = "n" ]; then
|
if [ "$reply" = "n" ]; then
|
||||||
@ -251,7 +262,7 @@ echo "Normally, root should only be allowed to connect from 'localhost'. This"
|
|||||||
echo "ensures that someone cannot guess at the root password from the network."
|
echo "ensures that someone cannot guess at the root password from the network."
|
||||||
echo
|
echo
|
||||||
|
|
||||||
echo -n "Disallow root login remotely? [Y/n] "
|
echo $echo_n "Disallow root login remotely? [Y/n] $echo_c"
|
||||||
read reply
|
read reply
|
||||||
if [ "$reply" = "n" ]; then
|
if [ "$reply" = "n" ]; then
|
||||||
echo " ... skipping."
|
echo " ... skipping."
|
||||||
@ -270,7 +281,7 @@ echo "access. This is also intended only for testing, and should be removed"
|
|||||||
echo "before moving into a production environment."
|
echo "before moving into a production environment."
|
||||||
echo
|
echo
|
||||||
|
|
||||||
echo -n "Remove test database and access to it? [Y/n] "
|
echo $echo_n "Remove test database and access to it? [Y/n] $echo_c"
|
||||||
read reply
|
read reply
|
||||||
if [ "$reply" = "n" ]; then
|
if [ "$reply" = "n" ]; then
|
||||||
echo " ... skipping."
|
echo " ... skipping."
|
||||||
@ -288,7 +299,7 @@ echo "Reloading the privilege tables will ensure that all changes made so far"
|
|||||||
echo "will take effect immediately."
|
echo "will take effect immediately."
|
||||||
echo
|
echo
|
||||||
|
|
||||||
echo -n "Reload privilege tables now? [Y/n] "
|
echo $echo_n "Reload privilege tables now? [Y/n] $echo_c"
|
||||||
read reply
|
read reply
|
||||||
if [ "$reply" = "n" ]; then
|
if [ "$reply" = "n" ]; then
|
||||||
echo " ... skipping."
|
echo " ... skipping."
|
||||||
|
@ -2473,8 +2473,9 @@ bool Item_func_set_user_var::update_hash(void *ptr, uint length,
|
|||||||
char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
|
char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
|
||||||
if (entry->value == pos)
|
if (entry->value == pos)
|
||||||
entry->value=0;
|
entry->value=0;
|
||||||
if (!(entry->value=(char*) my_realloc(entry->value, length,
|
entry->value= (char*) my_realloc(entry->value, length,
|
||||||
MYF(MY_ALLOW_ZERO_PTR))))
|
MYF(MY_ALLOW_ZERO_PTR | MY_WME));
|
||||||
|
if (!entry->value)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -595,16 +595,10 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
|
|||||||
uint weekday;
|
uint weekday;
|
||||||
ulong length;
|
ulong length;
|
||||||
const char *ptr, *end;
|
const char *ptr, *end;
|
||||||
MY_LOCALE *locale;
|
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
char buf[128];
|
MY_LOCALE *locale= thd->variables.lc_time_names;
|
||||||
String tmp(buf, sizeof(buf), thd->variables.character_set_results);
|
|
||||||
uint errors= 0;
|
|
||||||
|
|
||||||
tmp.length(0);
|
|
||||||
str->length(0);
|
str->length(0);
|
||||||
str->set_charset(&my_charset_bin);
|
|
||||||
locale = thd->variables.lc_time_names;
|
|
||||||
|
|
||||||
if (l_time->neg)
|
if (l_time->neg)
|
||||||
str->append("-", 1);
|
str->append("-", 1);
|
||||||
@ -618,41 +612,37 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
|
|||||||
{
|
{
|
||||||
switch (*++ptr) {
|
switch (*++ptr) {
|
||||||
case 'M':
|
case 'M':
|
||||||
if (!l_time->month)
|
if (!l_time->month)
|
||||||
return 1;
|
return 1;
|
||||||
tmp.copy(locale->month_names->type_names[l_time->month-1],
|
str->append(locale->month_names->type_names[l_time->month-1],
|
||||||
strlen(locale->month_names->type_names[l_time->month-1]),
|
strlen(locale->month_names->type_names[l_time->month-1]),
|
||||||
system_charset_info, tmp.charset(), &errors);
|
system_charset_info);
|
||||||
str->append(tmp.ptr(), tmp.length());
|
break;
|
||||||
break;
|
|
||||||
case 'b':
|
case 'b':
|
||||||
if (!l_time->month)
|
if (!l_time->month)
|
||||||
return 1;
|
return 1;
|
||||||
tmp.copy(locale->ab_month_names->type_names[l_time->month-1],
|
str->append(locale->ab_month_names->type_names[l_time->month-1],
|
||||||
strlen(locale->ab_month_names->type_names[l_time->month-1]),
|
strlen(locale->ab_month_names->type_names[l_time->month-1]),
|
||||||
system_charset_info, tmp.charset(), &errors);
|
system_charset_info);
|
||||||
str->append(tmp.ptr(), tmp.length());
|
break;
|
||||||
break;
|
|
||||||
case 'W':
|
case 'W':
|
||||||
if (type == MYSQL_TIMESTAMP_TIME)
|
if (type == MYSQL_TIMESTAMP_TIME)
|
||||||
return 1;
|
return 1;
|
||||||
weekday= calc_weekday(calc_daynr(l_time->year,l_time->month,
|
weekday= calc_weekday(calc_daynr(l_time->year,l_time->month,
|
||||||
l_time->day),0);
|
l_time->day),0);
|
||||||
tmp.copy(locale->day_names->type_names[weekday],
|
str->append(locale->day_names->type_names[weekday],
|
||||||
strlen(locale->day_names->type_names[weekday]),
|
strlen(locale->day_names->type_names[weekday]),
|
||||||
system_charset_info, tmp.charset(), &errors);
|
system_charset_info);
|
||||||
str->append(tmp.ptr(), tmp.length());
|
break;
|
||||||
break;
|
|
||||||
case 'a':
|
case 'a':
|
||||||
if (type == MYSQL_TIMESTAMP_TIME)
|
if (type == MYSQL_TIMESTAMP_TIME)
|
||||||
return 1;
|
return 1;
|
||||||
weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
|
weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
|
||||||
l_time->day),0);
|
l_time->day),0);
|
||||||
tmp.copy(locale->ab_day_names->type_names[weekday],
|
str->append(locale->ab_day_names->type_names[weekday],
|
||||||
strlen(locale->ab_day_names->type_names[weekday]),
|
strlen(locale->ab_day_names->type_names[weekday]),
|
||||||
system_charset_info, tmp.charset(), &errors);
|
system_charset_info);
|
||||||
str->append(tmp.ptr(), tmp.length());
|
break;
|
||||||
break;
|
|
||||||
case 'D':
|
case 'D':
|
||||||
if (type == MYSQL_TIMESTAMP_TIME)
|
if (type == MYSQL_TIMESTAMP_TIME)
|
||||||
return 1;
|
return 1;
|
||||||
@ -1638,8 +1628,9 @@ longlong Item_func_sec_to_time::val_int()
|
|||||||
|
|
||||||
void Item_func_date_format::fix_length_and_dec()
|
void Item_func_date_format::fix_length_and_dec()
|
||||||
{
|
{
|
||||||
|
THD* thd= current_thd;
|
||||||
decimals=0;
|
decimals=0;
|
||||||
collation.set(&my_charset_bin);
|
collation.set(thd->variables.collation_connection);
|
||||||
if (args[1]->type() == STRING_ITEM)
|
if (args[1]->type() == STRING_ITEM)
|
||||||
{ // Optimize the normal case
|
{ // Optimize the normal case
|
||||||
fixed_length=1;
|
fixed_length=1;
|
||||||
@ -1653,17 +1644,14 @@ void Item_func_date_format::fix_length_and_dec()
|
|||||||
args[1]->collation.set(
|
args[1]->collation.set(
|
||||||
get_charset_by_csname(args[1]->collation.collation->csname,
|
get_charset_by_csname(args[1]->collation.collation->csname,
|
||||||
MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE);
|
MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE);
|
||||||
/*
|
max_length= format_length(((Item_string*) args[1])->const_string()) *
|
||||||
The result is a binary string (no reason to use collation->mbmaxlen
|
collation.collation->mbmaxlen;
|
||||||
This is becasue make_date_time() only returns binary strings
|
|
||||||
*/
|
|
||||||
max_length= format_length(((Item_string*) args[1])->const_string());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fixed_length=0;
|
fixed_length=0;
|
||||||
/* The result is a binary string (no reason to use collation->mbmaxlen */
|
max_length= min(args[1]->max_length,MAX_BLOB_WIDTH) * 10 *
|
||||||
max_length=min(args[1]->max_length,MAX_BLOB_WIDTH) * 10;
|
collation.collation->mbmaxlen;
|
||||||
set_if_smaller(max_length,MAX_BLOB_WIDTH);
|
set_if_smaller(max_length,MAX_BLOB_WIDTH);
|
||||||
}
|
}
|
||||||
maybe_null=1; // If wrong date
|
maybe_null=1; // If wrong date
|
||||||
@ -1783,6 +1771,7 @@ String *Item_func_date_format::val_str(String *str)
|
|||||||
date_time_format.format.length= format->length();
|
date_time_format.format.length= format->length();
|
||||||
|
|
||||||
/* Create the result string */
|
/* Create the result string */
|
||||||
|
str->set_charset(collation.collation);
|
||||||
if (!make_date_time(&date_time_format, &l_time,
|
if (!make_date_time(&date_time_format, &l_time,
|
||||||
is_time_format ? MYSQL_TIMESTAMP_TIME :
|
is_time_format ? MYSQL_TIMESTAMP_TIME :
|
||||||
MYSQL_TIMESTAMP_DATE,
|
MYSQL_TIMESTAMP_DATE,
|
||||||
|
15
sql/log.cc
15
sql/log.cc
@ -1350,6 +1350,21 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u",
|
|||||||
if (e.write(file))
|
if (e.write(file))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
Use the same ONE_SHOT trick for making replication of lc_time_names.
|
||||||
|
*/
|
||||||
|
if (thd->variables.lc_time_names->number) // Not en_US
|
||||||
|
{
|
||||||
|
char buf[32];
|
||||||
|
uint length= my_snprintf(buf, sizeof(buf),
|
||||||
|
"SET ONE_SHOT LC_TIME_NAMES=%u",
|
||||||
|
(uint) thd->variables.lc_time_names->number);
|
||||||
|
Query_log_event e(thd, buf, length, 0, FALSE);
|
||||||
|
e.set_log_pos(this);
|
||||||
|
e.error_code= 0; // This statement cannot fail (see [1]).
|
||||||
|
if (e.write(file))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (thd->last_insert_id_used)
|
if (thd->last_insert_id_used)
|
||||||
|
@ -71,6 +71,7 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
|
|||||||
|
|
||||||
typedef struct my_locale_st
|
typedef struct my_locale_st
|
||||||
{
|
{
|
||||||
|
uint number;
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *description;
|
const char *description;
|
||||||
const bool is_ascii;
|
const bool is_ascii;
|
||||||
@ -84,6 +85,7 @@ extern MY_LOCALE my_locale_en_US;
|
|||||||
extern MY_LOCALE *my_locales[];
|
extern MY_LOCALE *my_locales[];
|
||||||
|
|
||||||
MY_LOCALE *my_locale_by_name(const char *name);
|
MY_LOCALE *my_locale_by_name(const char *name);
|
||||||
|
MY_LOCALE *my_locale_by_number(uint number);
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
Configuration parameters
|
Configuration parameters
|
||||||
@ -563,25 +565,22 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
uint &key_count, int select_field_count);
|
uint &key_count, int select_field_count);
|
||||||
int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
||||||
HA_CREATE_INFO *create_info,
|
HA_CREATE_INFO *create_info,
|
||||||
List<create_field> &fields, List<Key> &keys,
|
Alter_info *alter_info,
|
||||||
bool tmp_table, uint select_field_count);
|
bool tmp_table, uint select_field_count);
|
||||||
|
|
||||||
TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
||||||
const char *db, const char *name,
|
const char *db, const char *name,
|
||||||
List<create_field> *extra_fields,
|
Alter_info *alter_info,
|
||||||
List<Key> *keys,
|
|
||||||
List<Item> *items,
|
List<Item> *items,
|
||||||
MYSQL_LOCK **lock);
|
MYSQL_LOCK **lock);
|
||||||
int mysql_alter_table(THD *thd, char *new_db, char *new_name,
|
int mysql_alter_table(THD *thd, char *new_db, char *new_name,
|
||||||
HA_CREATE_INFO *create_info,
|
HA_CREATE_INFO *create_info,
|
||||||
TABLE_LIST *table_list,
|
TABLE_LIST *table_list,
|
||||||
List<create_field> &fields,
|
Alter_info *alter_info,
|
||||||
List<Key> &keys,
|
|
||||||
uint order_num, ORDER *order,
|
uint order_num, ORDER *order,
|
||||||
enum enum_duplicates handle_duplicates,
|
enum enum_duplicates handle_duplicates,
|
||||||
bool ignore,
|
bool ignore);
|
||||||
ALTER_INFO *alter_info, bool do_send_ok=1);
|
int mysql_recreate_table(THD *thd, TABLE_LIST *table_list);
|
||||||
int mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok);
|
|
||||||
int mysql_create_like_table(THD *thd, TABLE_LIST *table,
|
int mysql_create_like_table(THD *thd, TABLE_LIST *table,
|
||||||
HA_CREATE_INFO *create_info,
|
HA_CREATE_INFO *create_info,
|
||||||
Table_ident *src_table);
|
Table_ident *src_table);
|
||||||
@ -590,9 +589,6 @@ bool mysql_rename_table(enum db_type base,
|
|||||||
const char * old_name,
|
const char * old_name,
|
||||||
const char *new_db,
|
const char *new_db,
|
||||||
const char * new_name);
|
const char * new_name);
|
||||||
int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys);
|
|
||||||
int mysql_drop_index(THD *thd, TABLE_LIST *table_list,
|
|
||||||
ALTER_INFO *alter_info);
|
|
||||||
int mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
|
int mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
|
||||||
TABLE_LIST *update_table_list,
|
TABLE_LIST *update_table_list,
|
||||||
Item **conds, uint order_num, ORDER *order);
|
Item **conds, uint order_num, ORDER *order);
|
||||||
@ -679,7 +675,8 @@ int get_quote_char_for_identifier(THD *thd, const char *name, uint length);
|
|||||||
void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild);
|
void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild);
|
||||||
int mysqld_dump_create_info(THD *thd, TABLE *table, int fd = -1);
|
int mysqld_dump_create_info(THD *thd, TABLE *table, int fd = -1);
|
||||||
int mysqld_show_create(THD *thd, TABLE_LIST *table_list);
|
int mysqld_show_create(THD *thd, TABLE_LIST *table_list);
|
||||||
int mysqld_show_create_db(THD *thd, char *dbname, HA_CREATE_INFO *create);
|
int mysqld_show_create_db(THD *thd, char *dbname,
|
||||||
|
const HA_CREATE_INFO *create);
|
||||||
|
|
||||||
void mysqld_list_processes(THD *thd,const char *user,bool verbose);
|
void mysqld_list_processes(THD *thd,const char *user,bool verbose);
|
||||||
int mysqld_show_status(THD *thd);
|
int mysqld_show_status(THD *thd);
|
||||||
|
@ -2570,19 +2570,38 @@ void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type)
|
|||||||
|
|
||||||
bool sys_var_thd_lc_time_names::check(THD *thd, set_var *var)
|
bool sys_var_thd_lc_time_names::check(THD *thd, set_var *var)
|
||||||
{
|
{
|
||||||
char *locale_str =var->value->str_value.c_ptr();
|
MY_LOCALE *locale_match;
|
||||||
MY_LOCALE *locale_match= my_locale_by_name(locale_str);
|
|
||||||
|
|
||||||
if(locale_match == NULL)
|
if (var->value->result_type() == INT_RESULT)
|
||||||
{
|
{
|
||||||
my_printf_error(ER_UNKNOWN_ERROR, "Unknown locale: '%s'", MYF(0), locale_str);
|
if (!(locale_match= my_locale_by_number((uint) var->value->val_int())))
|
||||||
return 1;
|
{
|
||||||
|
char buf[20];
|
||||||
|
int10_to_str((int) var->value->val_int(), buf, -10);
|
||||||
|
my_printf_error(ER_UNKNOWN_ERROR, "Unknown locale: '%s'", MYF(0), buf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else // STRING_RESULT
|
||||||
{
|
{
|
||||||
var->save_result.locale_value= locale_match;
|
char buff[6];
|
||||||
return 0;
|
String str(buff, sizeof(buff), &my_charset_latin1), *res;
|
||||||
|
if (!(res=var->value->val_str(&str)))
|
||||||
|
{
|
||||||
|
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
const char *locale_str= res->c_ptr();
|
||||||
|
if (!(locale_match= my_locale_by_name(locale_str)))
|
||||||
|
{
|
||||||
|
my_printf_error(ER_UNKNOWN_ERROR,
|
||||||
|
"Unknown locale: '%s'", MYF(0), locale_str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var->save_result.locale_value= locale_match;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -764,12 +764,16 @@ class sys_var_thd_lc_time_names :public sys_var_thd
|
|||||||
public:
|
public:
|
||||||
sys_var_thd_lc_time_names(const char *name_arg):
|
sys_var_thd_lc_time_names(const char *name_arg):
|
||||||
sys_var_thd(name_arg)
|
sys_var_thd(name_arg)
|
||||||
{}
|
{
|
||||||
|
#if MYSQL_VERSION_ID < 50000
|
||||||
|
no_support_one_shot= 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
bool check(THD *thd, set_var *var);
|
bool check(THD *thd, set_var *var);
|
||||||
SHOW_TYPE type() { return SHOW_CHAR; }
|
SHOW_TYPE type() { return SHOW_CHAR; }
|
||||||
bool check_update_type(Item_result type)
|
bool check_update_type(Item_result type)
|
||||||
{
|
{
|
||||||
return type != STRING_RESULT; /* Only accept strings */
|
return ((type != STRING_RESULT) && (type != INT_RESULT));
|
||||||
}
|
}
|
||||||
bool check_default(enum_var_type type) { return 0; }
|
bool check_default(enum_var_type type) { return 0; }
|
||||||
bool update(THD *thd, set_var *var);
|
bool update(THD *thd, set_var *var);
|
||||||
|
@ -1293,20 +1293,21 @@ class select_create: public select_insert {
|
|||||||
ORDER *group;
|
ORDER *group;
|
||||||
const char *db;
|
const char *db;
|
||||||
const char *name;
|
const char *name;
|
||||||
List<create_field> *extra_fields;
|
|
||||||
List<Key> *keys;
|
|
||||||
HA_CREATE_INFO *create_info;
|
HA_CREATE_INFO *create_info;
|
||||||
|
Alter_info *alter_info;
|
||||||
MYSQL_LOCK *lock;
|
MYSQL_LOCK *lock;
|
||||||
Field **field;
|
Field **field;
|
||||||
public:
|
public:
|
||||||
select_create(const char *db_name, const char *table_name,
|
select_create(const char *db_name, const char *table_name,
|
||||||
HA_CREATE_INFO *create_info_par,
|
HA_CREATE_INFO *create_info_arg,
|
||||||
List<create_field> &fields_par,
|
Alter_info *alter_info_arg,
|
||||||
List<Key> &keys_par,
|
List<Item> &select_fields,
|
||||||
List<Item> &select_fields,enum_duplicates duplic, bool ignore)
|
enum_duplicates duplic, bool ignore)
|
||||||
:select_insert (NULL, &select_fields, duplic, ignore), db(db_name),
|
:select_insert(NULL, &select_fields, duplic, ignore),
|
||||||
name(table_name), extra_fields(&fields_par),keys(&keys_par),
|
db(db_name), name(table_name),
|
||||||
create_info(create_info_par), lock(0)
|
create_info(create_info_arg),
|
||||||
|
alter_info(alter_info_arg),
|
||||||
|
lock(0)
|
||||||
{}
|
{}
|
||||||
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
|
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
|
||||||
void store_values(List<Item> &values);
|
void store_values(List<Item> &values);
|
||||||
|
@ -1805,7 +1805,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
|||||||
|
|
||||||
unit= u;
|
unit= u;
|
||||||
table= create_table_from_items(thd, create_info, db, name,
|
table= create_table_from_items(thd, create_info, db, name,
|
||||||
extra_fields, keys, &values, &lock);
|
alter_info, &values, &lock);
|
||||||
if (!table)
|
if (!table)
|
||||||
DBUG_RETURN(-1); // abort() deletes table
|
DBUG_RETURN(-1); // abort() deletes table
|
||||||
|
|
||||||
|
@ -1015,6 +1015,18 @@ int yylex(void *arg, void *yythd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root)
|
||||||
|
:drop_list(rhs.drop_list, mem_root),
|
||||||
|
alter_list(rhs.alter_list, mem_root),
|
||||||
|
key_list(rhs.key_list, mem_root),
|
||||||
|
create_list(rhs.create_list, mem_root),
|
||||||
|
flags(rhs.flags),
|
||||||
|
keys_onoff(rhs.keys_onoff),
|
||||||
|
tablespace_op(rhs.tablespace_op),
|
||||||
|
is_simple(rhs.is_simple)
|
||||||
|
{}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
st_select_lex structures initialisations
|
st_select_lex structures initialisations
|
||||||
*/
|
*/
|
||||||
|
@ -571,19 +571,61 @@ typedef class st_select_lex SELECT_LEX;
|
|||||||
#define ALTER_ORDER 64
|
#define ALTER_ORDER 64
|
||||||
#define ALTER_OPTIONS 128
|
#define ALTER_OPTIONS 128
|
||||||
|
|
||||||
typedef struct st_alter_info
|
/**
|
||||||
|
@brief Parsing data for CREATE or ALTER TABLE.
|
||||||
|
|
||||||
|
This structure contains a list of columns or indexes to be created,
|
||||||
|
altered or dropped.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Alter_info
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
List<Alter_drop> drop_list;
|
List<Alter_drop> drop_list;
|
||||||
List<Alter_column> alter_list;
|
List<Alter_column> alter_list;
|
||||||
|
List<Key> key_list;
|
||||||
|
List<create_field> create_list;
|
||||||
uint flags;
|
uint flags;
|
||||||
enum enum_enable_or_disable keys_onoff;
|
enum enum_enable_or_disable keys_onoff;
|
||||||
enum tablespace_op_type tablespace_op;
|
enum tablespace_op_type tablespace_op;
|
||||||
bool is_simple;
|
bool is_simple;
|
||||||
|
|
||||||
st_alter_info(){clear();}
|
Alter_info() :
|
||||||
void clear(){keys_onoff= LEAVE_AS_IS;tablespace_op= NO_TABLESPACE_OP;}
|
flags(0),
|
||||||
void reset(){drop_list.empty();alter_list.empty();clear();}
|
keys_onoff(LEAVE_AS_IS),
|
||||||
} ALTER_INFO;
|
tablespace_op(NO_TABLESPACE_OP),
|
||||||
|
is_simple(1)
|
||||||
|
{}
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
drop_list.empty();
|
||||||
|
alter_list.empty();
|
||||||
|
key_list.empty();
|
||||||
|
create_list.empty();
|
||||||
|
flags= 0;
|
||||||
|
keys_onoff= LEAVE_AS_IS;
|
||||||
|
tablespace_op= NO_TABLESPACE_OP;
|
||||||
|
is_simple= 1;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
Construct a copy of this object to be used for mysql_alter_table
|
||||||
|
and mysql_create_table. Historically, these two functions modify
|
||||||
|
their Alter_info arguments. This behaviour breaks re-execution of
|
||||||
|
prepared statements and stored procedures and is compensated by
|
||||||
|
always supplying a copy of Alter_info to these functions.
|
||||||
|
The constructed copy still shares key Key, Alter_drop, create_field
|
||||||
|
and Alter_column elements of the lists - these structures are not
|
||||||
|
modified and thus are not copied.
|
||||||
|
|
||||||
|
@note You need to use check thd->is_fatal_error for out
|
||||||
|
of memory condition after calling this function.
|
||||||
|
*/
|
||||||
|
Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root);
|
||||||
|
private:
|
||||||
|
Alter_info &operator=(const Alter_info &rhs); // not implemented
|
||||||
|
Alter_info(const Alter_info &rhs); // not implemented
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* The state of the lex parsing. This is saved in the THD struct */
|
/* The state of the lex parsing. This is saved in the THD struct */
|
||||||
|
|
||||||
@ -620,8 +662,6 @@ typedef struct st_lex
|
|||||||
List<String> interval_list;
|
List<String> interval_list;
|
||||||
List<LEX_USER> users_list;
|
List<LEX_USER> users_list;
|
||||||
List<LEX_COLUMN> columns;
|
List<LEX_COLUMN> columns;
|
||||||
List<Key> key_list;
|
|
||||||
List<create_field> create_list;
|
|
||||||
List<Item> *insert_list,field_list,value_list,update_list;
|
List<Item> *insert_list,field_list,value_list,update_list;
|
||||||
List<List_item> many_values;
|
List<List_item> many_values;
|
||||||
List<set_var_base> var_list;
|
List<set_var_base> var_list;
|
||||||
@ -654,7 +694,7 @@ typedef struct st_lex
|
|||||||
bool derived_tables;
|
bool derived_tables;
|
||||||
bool safe_to_cache_query;
|
bool safe_to_cache_query;
|
||||||
bool subqueries, ignore;
|
bool subqueries, ignore;
|
||||||
ALTER_INFO alter_info;
|
Alter_info alter_info;
|
||||||
/* Prepared statements SQL syntax:*/
|
/* Prepared statements SQL syntax:*/
|
||||||
LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */
|
LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */
|
||||||
/*
|
/*
|
||||||
|
@ -66,21 +66,24 @@ public:
|
|||||||
pointer.
|
pointer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class list_node :public Sql_alloc
|
|
||||||
|
/**
|
||||||
|
list_node - a node of a single-linked list.
|
||||||
|
@note We never call a destructor for instances of this class.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct list_node :public Sql_alloc
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
list_node *next;
|
list_node *next;
|
||||||
void *info;
|
void *info;
|
||||||
list_node(void *info_par,list_node *next_par)
|
list_node(void *info_par,list_node *next_par)
|
||||||
:next(next_par),info(info_par)
|
:next(next_par),info(info_par)
|
||||||
{}
|
{}
|
||||||
list_node() /* For end_of_list */
|
list_node() /* For end_of_list */
|
||||||
{
|
{
|
||||||
info=0;
|
info= 0;
|
||||||
next= this;
|
next= this;
|
||||||
}
|
}
|
||||||
friend class base_list;
|
|
||||||
friend class base_list_iterator;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -96,11 +99,56 @@ public:
|
|||||||
|
|
||||||
inline void empty() { elements=0; first= &end_of_list; last=&first;}
|
inline void empty() { elements=0; first= &end_of_list; last=&first;}
|
||||||
inline base_list() { empty(); }
|
inline base_list() { empty(); }
|
||||||
|
/**
|
||||||
|
This is a shallow copy constructor that implicitly passes the ownership
|
||||||
|
from the source list to the new instance. The old instance is not
|
||||||
|
updated, so both objects end up sharing the same nodes. If one of
|
||||||
|
the instances then adds or removes a node, the other becomes out of
|
||||||
|
sync ('last' pointer), while still operational. Some old code uses and
|
||||||
|
relies on this behaviour. This logic is quite tricky: please do not use
|
||||||
|
it in any new code.
|
||||||
|
*/
|
||||||
inline base_list(const base_list &tmp) :Sql_alloc()
|
inline base_list(const base_list &tmp) :Sql_alloc()
|
||||||
{
|
{
|
||||||
elements=tmp.elements;
|
elements= tmp.elements;
|
||||||
first=tmp.first;
|
first= tmp.first;
|
||||||
last=tmp.last;
|
last= elements ? tmp.last : &first;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
Construct a deep copy of the argument in memory root mem_root.
|
||||||
|
The elements themselves are copied by pointer.
|
||||||
|
*/
|
||||||
|
inline base_list(const base_list &rhs, MEM_ROOT *mem_root)
|
||||||
|
{
|
||||||
|
if (rhs.elements)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
It's okay to allocate an array of nodes at once: we never
|
||||||
|
call a destructor for list_node objects anyway.
|
||||||
|
*/
|
||||||
|
first= (list_node*) alloc_root(mem_root,
|
||||||
|
sizeof(list_node) * rhs.elements);
|
||||||
|
if (first)
|
||||||
|
{
|
||||||
|
elements= rhs.elements;
|
||||||
|
list_node *dst= first;
|
||||||
|
list_node *src= rhs.first;
|
||||||
|
for (; dst < first + elements - 1; dst++, src= src->next)
|
||||||
|
{
|
||||||
|
dst->info= src->info;
|
||||||
|
dst->next= dst + 1;
|
||||||
|
}
|
||||||
|
/* Copy the last node */
|
||||||
|
dst->info= src->info;
|
||||||
|
dst->next= &end_of_list;
|
||||||
|
/* Setup 'last' member */
|
||||||
|
last= &dst->next;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elements= 0;
|
||||||
|
first= &end_of_list;
|
||||||
|
last= &first;
|
||||||
}
|
}
|
||||||
inline base_list(bool error) { }
|
inline base_list(bool error) { }
|
||||||
inline bool push_back(void *info)
|
inline bool push_back(void *info)
|
||||||
@ -327,6 +375,8 @@ template <class T> class List :public base_list
|
|||||||
public:
|
public:
|
||||||
inline List() :base_list() {}
|
inline List() :base_list() {}
|
||||||
inline List(const List<T> &tmp) :base_list(tmp) {}
|
inline List(const List<T> &tmp) :base_list(tmp) {}
|
||||||
|
inline List(const List<T> &tmp, MEM_ROOT *mem_root) :
|
||||||
|
base_list(tmp, mem_root) {}
|
||||||
inline bool push_back(T *a) { return base_list::push_back(a); }
|
inline bool push_back(T *a) { return base_list::push_back(a); }
|
||||||
inline bool push_front(T *a) { return base_list::push_front(a); }
|
inline bool push_front(T *a) { return base_list::push_front(a); }
|
||||||
inline T* head() {return (T*) base_list::head(); }
|
inline T* head() {return (T*) base_list::head(); }
|
||||||
|
1245
sql/sql_locale.cc
1245
sql/sql_locale.cc
File diff suppressed because it is too large
Load Diff
212
sql/sql_parse.cc
212
sql/sql_parse.cc
@ -1958,6 +1958,7 @@ static void reset_one_shot_variables(THD *thd)
|
|||||||
thd->update_charset();
|
thd->update_charset();
|
||||||
thd->variables.time_zone=
|
thd->variables.time_zone=
|
||||||
global_system_variables.time_zone;
|
global_system_variables.time_zone;
|
||||||
|
thd->variables.lc_time_names= &my_locale_en_US;
|
||||||
thd->one_shot_set= 0;
|
thd->one_shot_set= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2478,19 +2479,36 @@ mysql_execute_command(THD *thd)
|
|||||||
}
|
}
|
||||||
/* Skip first table, which is the table we are creating */
|
/* Skip first table, which is the table we are creating */
|
||||||
TABLE_LIST *create_table, *create_table_local;
|
TABLE_LIST *create_table, *create_table_local;
|
||||||
|
/*
|
||||||
|
Code below (especially in mysql_create_table() and select_create
|
||||||
|
methods) may modify HA_CREATE_INFO structure in LEX, so we have to
|
||||||
|
use a copy of this structure to make execution prepared statement-
|
||||||
|
safe. A shallow copy is enough as this code won't modify any memory
|
||||||
|
referenced from this structure.
|
||||||
|
*/
|
||||||
|
HA_CREATE_INFO create_info(lex->create_info);
|
||||||
|
Alter_info alter_info(lex->alter_info, thd->mem_root);
|
||||||
|
|
||||||
|
if (thd->is_fatal_error)
|
||||||
|
{
|
||||||
|
/* out of memory when creating a copy of alter_info */
|
||||||
|
res= 1;
|
||||||
|
goto unsent_create_error;
|
||||||
|
}
|
||||||
tables= lex->unlink_first_table(tables, &create_table,
|
tables= lex->unlink_first_table(tables, &create_table,
|
||||||
&create_table_local);
|
&create_table_local);
|
||||||
|
|
||||||
if ((res= create_table_precheck(thd, tables, create_table)))
|
if ((res= create_table_precheck(thd, tables, create_table)))
|
||||||
goto unsent_create_error;
|
goto unsent_create_error;
|
||||||
|
|
||||||
|
create_info.alias= create_table->alias;
|
||||||
#ifndef HAVE_READLINK
|
#ifndef HAVE_READLINK
|
||||||
lex->create_info.data_file_name=lex->create_info.index_file_name=0;
|
create_info.data_file_name= create_info.index_file_name= NULL;
|
||||||
#else
|
#else
|
||||||
/* Fix names if symlinked tables */
|
/* Fix names if symlinked tables */
|
||||||
if (append_file_to_dir(thd, &lex->create_info.data_file_name,
|
if (append_file_to_dir(thd, &create_info.data_file_name,
|
||||||
create_table->real_name) ||
|
create_table->real_name) ||
|
||||||
append_file_to_dir(thd,&lex->create_info.index_file_name,
|
append_file_to_dir(thd, &create_info.index_file_name,
|
||||||
create_table->real_name))
|
create_table->real_name))
|
||||||
{
|
{
|
||||||
res=-1;
|
res=-1;
|
||||||
@ -2501,14 +2519,14 @@ mysql_execute_command(THD *thd)
|
|||||||
If we are using SET CHARSET without DEFAULT, add an implicite
|
If we are using SET CHARSET without DEFAULT, add an implicite
|
||||||
DEFAULT to not confuse old users. (This may change).
|
DEFAULT to not confuse old users. (This may change).
|
||||||
*/
|
*/
|
||||||
if ((lex->create_info.used_fields &
|
if ((create_info.used_fields &
|
||||||
(HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
|
(HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
|
||||||
HA_CREATE_USED_CHARSET)
|
HA_CREATE_USED_CHARSET)
|
||||||
{
|
{
|
||||||
lex->create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
|
create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
|
||||||
lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
|
create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
|
||||||
lex->create_info.default_table_charset= lex->create_info.table_charset;
|
create_info.default_table_charset= create_info.table_charset;
|
||||||
lex->create_info.table_charset= 0;
|
create_info.table_charset= 0;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
The create-select command will open and read-lock the select table
|
The create-select command will open and read-lock the select table
|
||||||
@ -2542,11 +2560,14 @@ mysql_execute_command(THD *thd)
|
|||||||
if (!(res=open_and_lock_tables(thd,tables)))
|
if (!(res=open_and_lock_tables(thd,tables)))
|
||||||
{
|
{
|
||||||
res= -1; // If error
|
res= -1; // If error
|
||||||
|
/*
|
||||||
|
select_create is currently not re-execution friendly and
|
||||||
|
needs to be created for every execution of a PS/SP.
|
||||||
|
*/
|
||||||
if ((result=new select_create(create_table->db,
|
if ((result=new select_create(create_table->db,
|
||||||
create_table->real_name,
|
create_table->real_name,
|
||||||
&lex->create_info,
|
&create_info,
|
||||||
lex->create_list,
|
&alter_info,
|
||||||
lex->key_list,
|
|
||||||
select_lex->item_list, lex->duplicates,
|
select_lex->item_list, lex->duplicates,
|
||||||
lex->ignore)))
|
lex->ignore)))
|
||||||
{
|
{
|
||||||
@ -2558,22 +2579,18 @@ mysql_execute_command(THD *thd)
|
|||||||
res=handle_select(thd, lex, result);
|
res=handle_select(thd, lex, result);
|
||||||
select_lex->resolve_mode= SELECT_LEX::NOMATTER_MODE;
|
select_lex->resolve_mode= SELECT_LEX::NOMATTER_MODE;
|
||||||
}
|
}
|
||||||
//reset for PS
|
|
||||||
lex->create_list.empty();
|
|
||||||
lex->key_list.empty();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // regular create
|
else // regular create
|
||||||
{
|
{
|
||||||
if (lex->name)
|
if (lex->name)
|
||||||
res= mysql_create_like_table(thd, create_table, &lex->create_info,
|
res= mysql_create_like_table(thd, create_table, &create_info,
|
||||||
(Table_ident *)lex->name);
|
(Table_ident *)lex->name);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res= mysql_create_table(thd,create_table->db,
|
res= mysql_create_table(thd, create_table->db,
|
||||||
create_table->real_name, &lex->create_info,
|
create_table->real_name, &create_info,
|
||||||
lex->create_list,
|
&alter_info, 0, 0);
|
||||||
lex->key_list,0,0);
|
|
||||||
}
|
}
|
||||||
if (!res)
|
if (!res)
|
||||||
send_ok(thd);
|
send_ok(thd);
|
||||||
@ -2591,15 +2608,49 @@ unsent_create_error:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_CREATE_INDEX:
|
case SQLCOM_CREATE_INDEX:
|
||||||
|
/* Fall through */
|
||||||
|
case SQLCOM_DROP_INDEX:
|
||||||
|
/*
|
||||||
|
CREATE INDEX and DROP INDEX are implemented by calling ALTER
|
||||||
|
TABLE with proper arguments. This isn't very fast but it
|
||||||
|
should work for most cases.
|
||||||
|
|
||||||
|
In the future ALTER TABLE will notice that only added
|
||||||
|
indexes and create these one by one for the existing table
|
||||||
|
without having to do a full rebuild.
|
||||||
|
|
||||||
|
One should normally create all indexes with CREATE TABLE or
|
||||||
|
ALTER TABLE.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
Alter_info alter_info(lex->alter_info, thd->mem_root);
|
||||||
|
HA_CREATE_INFO create_info;
|
||||||
|
|
||||||
|
if (thd->is_fatal_error) /* out of memory creating a copy of alter_info*/
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (check_one_table_access(thd, INDEX_ACL, tables))
|
if (check_one_table_access(thd, INDEX_ACL, tables))
|
||||||
goto error; /* purecov: inspected */
|
goto error; /* purecov: inspected */
|
||||||
thd->enable_slow_log= opt_log_slow_admin_statements;
|
thd->enable_slow_log= opt_log_slow_admin_statements;
|
||||||
if (end_active_trans(thd))
|
if (end_active_trans(thd))
|
||||||
res= -1;
|
goto error;
|
||||||
else
|
/*
|
||||||
res = mysql_create_index(thd, tables, lex->key_list);
|
Currently CREATE INDEX or DROP INDEX cause a full table rebuild
|
||||||
break;
|
and thus classify as slow administrative statements just like
|
||||||
|
ALTER TABLE.
|
||||||
|
*/
|
||||||
|
thd->enable_slow_log= opt_log_slow_admin_statements;
|
||||||
|
|
||||||
|
bzero((char*) &create_info, sizeof(create_info));
|
||||||
|
create_info.db_type= DB_TYPE_DEFAULT;
|
||||||
|
create_info.row_type= ROW_TYPE_NOT_USED;
|
||||||
|
create_info.default_table_charset= thd->variables.collation_database;
|
||||||
|
|
||||||
|
res= mysql_alter_table(thd, tables->db, tables->real_name,
|
||||||
|
&create_info, tables, &alter_info,
|
||||||
|
0, (ORDER*)0, DUP_ERROR, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
case SQLCOM_SLAVE_START:
|
case SQLCOM_SLAVE_START:
|
||||||
{
|
{
|
||||||
@ -2642,6 +2693,17 @@ unsent_create_error:
|
|||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
ulong priv=0;
|
ulong priv=0;
|
||||||
|
/*
|
||||||
|
Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
|
||||||
|
so we have to use a copy of this structure to make execution
|
||||||
|
prepared statement- safe. A shallow copy is enough as no memory
|
||||||
|
referenced from this structure will be modified.
|
||||||
|
*/
|
||||||
|
HA_CREATE_INFO create_info(lex->create_info);
|
||||||
|
Alter_info alter_info(lex->alter_info, thd->mem_root);
|
||||||
|
|
||||||
|
if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
|
||||||
|
goto error;
|
||||||
if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN))
|
if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN))
|
||||||
{
|
{
|
||||||
net_printf(thd, ER_WRONG_TABLE_NAME, lex->name);
|
net_printf(thd, ER_WRONG_TABLE_NAME, lex->name);
|
||||||
@ -2655,7 +2717,7 @@ unsent_create_error:
|
|||||||
default database if the new name is not explicitly qualified
|
default database if the new name is not explicitly qualified
|
||||||
by a database. (Bug #11493)
|
by a database. (Bug #11493)
|
||||||
*/
|
*/
|
||||||
if (lex->alter_info.flags & ALTER_RENAME)
|
if (alter_info.flags & ALTER_RENAME)
|
||||||
{
|
{
|
||||||
if (! thd->db)
|
if (! thd->db)
|
||||||
{
|
{
|
||||||
@ -2671,7 +2733,7 @@ unsent_create_error:
|
|||||||
check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0)||
|
check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0)||
|
||||||
check_merge_table_access(thd, tables->db,
|
check_merge_table_access(thd, tables->db,
|
||||||
(TABLE_LIST *)
|
(TABLE_LIST *)
|
||||||
lex->create_info.merge_list.first))
|
create_info.merge_list.first))
|
||||||
goto error; /* purecov: inspected */
|
goto error; /* purecov: inspected */
|
||||||
if (grant_option)
|
if (grant_option)
|
||||||
{
|
{
|
||||||
@ -2690,26 +2752,26 @@ unsent_create_error:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Don't yet allow changing of symlinks with ALTER TABLE */
|
/* Don't yet allow changing of symlinks with ALTER TABLE */
|
||||||
if (lex->create_info.data_file_name)
|
if (create_info.data_file_name)
|
||||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
|
||||||
"DATA DIRECTORY option ignored");
|
"DATA DIRECTORY option ignored");
|
||||||
if (lex->create_info.index_file_name)
|
if (create_info.index_file_name)
|
||||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
|
||||||
"INDEX DIRECTORY option ignored");
|
"INDEX DIRECTORY option ignored");
|
||||||
lex->create_info.data_file_name=lex->create_info.index_file_name=0;
|
create_info.data_file_name= create_info.index_file_name= NULL;
|
||||||
/* ALTER TABLE ends previous transaction */
|
/* ALTER TABLE ends previous transaction */
|
||||||
if (end_active_trans(thd))
|
if (end_active_trans(thd))
|
||||||
res= -1;
|
res= -1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
thd->enable_slow_log= opt_log_slow_admin_statements;
|
thd->enable_slow_log= opt_log_slow_admin_statements;
|
||||||
res= mysql_alter_table(thd, select_lex->db, lex->name,
|
res= mysql_alter_table(thd, select_lex->db, lex->name,
|
||||||
&lex->create_info,
|
&create_info,
|
||||||
tables, lex->create_list,
|
tables,
|
||||||
lex->key_list,
|
&alter_info,
|
||||||
select_lex->order_list.elements,
|
select_lex->order_list.elements,
|
||||||
(ORDER *) select_lex->order_list.first,
|
(ORDER *) select_lex->order_list.first,
|
||||||
lex->duplicates, lex->ignore, &lex->alter_info);
|
lex->duplicates, lex->ignore);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2846,7 +2908,7 @@ unsent_create_error:
|
|||||||
goto error; /* purecov: inspected */
|
goto error; /* purecov: inspected */
|
||||||
thd->enable_slow_log= opt_log_slow_admin_statements;
|
thd->enable_slow_log= opt_log_slow_admin_statements;
|
||||||
res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
|
res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
|
||||||
mysql_recreate_table(thd, tables, 1) :
|
mysql_recreate_table(thd, tables) :
|
||||||
mysql_optimize_table(thd, tables, &lex->check_opt);
|
mysql_optimize_table(thd, tables, &lex->check_opt);
|
||||||
/* ! we write after unlocking the table */
|
/* ! we write after unlocking the table */
|
||||||
if (!res && !lex->no_write_to_binlog)
|
if (!res && !lex->no_write_to_binlog)
|
||||||
@ -3123,14 +3185,6 @@ unsent_create_error:
|
|||||||
res= mysql_rm_table(thd,tables,lex->drop_if_exists, lex->drop_temporary);
|
res= mysql_rm_table(thd,tables,lex->drop_if_exists, lex->drop_temporary);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SQLCOM_DROP_INDEX:
|
|
||||||
if (check_one_table_access(thd, INDEX_ACL, tables))
|
|
||||||
goto error; /* purecov: inspected */
|
|
||||||
if (end_active_trans(thd))
|
|
||||||
res= -1;
|
|
||||||
else
|
|
||||||
res = mysql_drop_index(thd, tables, &lex->alter_info);
|
|
||||||
break;
|
|
||||||
case SQLCOM_SHOW_DATABASES:
|
case SQLCOM_SHOW_DATABASES:
|
||||||
#if defined(DONT_ALLOW_SHOW_COMMANDS)
|
#if defined(DONT_ALLOW_SHOW_COMMANDS)
|
||||||
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
|
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
|
||||||
@ -3363,6 +3417,12 @@ purposes internal to the MySQL server", MYF(0));
|
|||||||
break;
|
break;
|
||||||
case SQLCOM_CREATE_DB:
|
case SQLCOM_CREATE_DB:
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
As mysql_create_db() may modify HA_CREATE_INFO structure passed to
|
||||||
|
it, we need to use a copy of LEX::create_info to make execution
|
||||||
|
prepared statement- safe.
|
||||||
|
*/
|
||||||
|
HA_CREATE_INFO create_info(lex->create_info);
|
||||||
if (end_active_trans(thd))
|
if (end_active_trans(thd))
|
||||||
{
|
{
|
||||||
res= -1;
|
res= -1;
|
||||||
@ -3393,7 +3453,7 @@ purposes internal to the MySQL server", MYF(0));
|
|||||||
if (check_access(thd,CREATE_ACL,lex->name,0,1,0))
|
if (check_access(thd,CREATE_ACL,lex->name,0,1,0))
|
||||||
break;
|
break;
|
||||||
res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias : lex->name),
|
res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias : lex->name),
|
||||||
&lex->create_info, 0);
|
&create_info, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_DROP_DB:
|
case SQLCOM_DROP_DB:
|
||||||
@ -4443,15 +4503,17 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
|
|||||||
if (type_modifier & PRI_KEY_FLAG)
|
if (type_modifier & PRI_KEY_FLAG)
|
||||||
{
|
{
|
||||||
lex->col_list.push_back(new key_part_spec(field_name,0));
|
lex->col_list.push_back(new key_part_spec(field_name,0));
|
||||||
lex->key_list.push_back(new Key(Key::PRIMARY, NullS, HA_KEY_ALG_UNDEF,
|
lex->alter_info.key_list.push_back(new Key(Key::PRIMARY, NullS,
|
||||||
0, lex->col_list));
|
HA_KEY_ALG_UNDEF, 0,
|
||||||
|
lex->col_list));
|
||||||
lex->col_list.empty();
|
lex->col_list.empty();
|
||||||
}
|
}
|
||||||
if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
|
if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
|
||||||
{
|
{
|
||||||
lex->col_list.push_back(new key_part_spec(field_name,0));
|
lex->col_list.push_back(new key_part_spec(field_name,0));
|
||||||
lex->key_list.push_back(new Key(Key::UNIQUE, NullS, HA_KEY_ALG_UNDEF, 0,
|
lex->alter_info.key_list.push_back(new Key(Key::UNIQUE, NullS,
|
||||||
lex->col_list));
|
HA_KEY_ALG_UNDEF, 0,
|
||||||
|
lex->col_list));
|
||||||
lex->col_list.empty();
|
lex->col_list.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4778,7 +4840,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
|
|||||||
new_field->sql_type,
|
new_field->sql_type,
|
||||||
new_field->length);
|
new_field->length);
|
||||||
new_field->char_length= new_field->length;
|
new_field->char_length= new_field->length;
|
||||||
lex->create_list.push_back(new_field);
|
lex->alter_info.create_list.push_back(new_field);
|
||||||
lex->last_field=new_field;
|
lex->last_field=new_field;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
@ -5458,57 +5520,6 @@ Item * all_any_subquery_creator(Item *left_expr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
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.
|
|
||||||
|
|
||||||
In the future ALTER TABLE will notice that only added indexes
|
|
||||||
and create these one by one for the existing table without having to do
|
|
||||||
a full rebuild.
|
|
||||||
|
|
||||||
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;
|
|
||||||
ALTER_INFO alter_info;
|
|
||||||
alter_info.flags= ALTER_ADD_INDEX;
|
|
||||||
alter_info.is_simple= 0;
|
|
||||||
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;
|
|
||||||
create_info.row_type= ROW_TYPE_NOT_USED;
|
|
||||||
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
|
|
||||||
&create_info, table_list,
|
|
||||||
fields, keys, 0, (ORDER*)0,
|
|
||||||
DUP_ERROR, 0, &alter_info));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info)
|
|
||||||
{
|
|
||||||
List<create_field> fields;
|
|
||||||
List<Key> keys;
|
|
||||||
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;
|
|
||||||
create_info.row_type= ROW_TYPE_NOT_USED;
|
|
||||||
alter_info->clear();
|
|
||||||
alter_info->flags= ALTER_DROP_INDEX;
|
|
||||||
alter_info->is_simple= 0;
|
|
||||||
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
|
|
||||||
&create_info, table_list,
|
|
||||||
fields, keys, 0, (ORDER*)0,
|
|
||||||
DUP_ERROR, 0, alter_info));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Multi update query pre-check
|
Multi update query pre-check
|
||||||
|
|
||||||
@ -5791,7 +5802,6 @@ int create_table_precheck(THD *thd, TABLE_LIST *tables,
|
|||||||
|
|
||||||
want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ?
|
want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ?
|
||||||
CREATE_TMP_ACL : CREATE_ACL);
|
CREATE_TMP_ACL : CREATE_ACL);
|
||||||
lex->create_info.alias= create_table->alias;
|
|
||||||
if (check_access(thd, want_priv, create_table->db,
|
if (check_access(thd, want_priv, create_table->db,
|
||||||
&create_table->grant.privilege, 0, 0) ||
|
&create_table->grant.privilege, 0, 0) ||
|
||||||
check_merge_table_access(thd, create_table->db,
|
check_merge_table_access(thd, create_table->db,
|
||||||
|
@ -845,7 +845,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int mysqld_show_create_db(THD *thd, char *dbname,
|
int mysqld_show_create_db(THD *thd, char *dbname,
|
||||||
HA_CREATE_INFO *create_info)
|
const HA_CREATE_INFO *create_info)
|
||||||
{
|
{
|
||||||
int length;
|
int length;
|
||||||
char path[FN_REFLEN];
|
char path[FN_REFLEN];
|
||||||
|
375
sql/sql_table.cc
375
sql/sql_table.cc
@ -456,8 +456,7 @@ void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
|
|||||||
mysql_prepare_table()
|
mysql_prepare_table()
|
||||||
thd Thread object
|
thd Thread object
|
||||||
create_info Create information (like MAX_ROWS)
|
create_info Create information (like MAX_ROWS)
|
||||||
fields List of fields to create
|
alter_info List of columns and indexes to create
|
||||||
keys List of keys to create
|
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
Prepares the table and key structures for table creation.
|
Prepares the table and key structures for table creation.
|
||||||
@ -468,8 +467,8 @@ void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
||||||
List<create_field> &fields,
|
Alter_info *alter_info,
|
||||||
List<Key> &keys, bool tmp_table, uint &db_options,
|
bool tmp_table, uint &db_options,
|
||||||
handler *file, KEY *&key_info_buffer,
|
handler *file, KEY *&key_info_buffer,
|
||||||
uint *key_count, int select_field_count)
|
uint *key_count, int select_field_count)
|
||||||
{
|
{
|
||||||
@ -482,10 +481,11 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
int timestamps= 0, timestamps_with_niladic= 0;
|
int timestamps= 0, timestamps_with_niladic= 0;
|
||||||
int field_no,dup_no;
|
int field_no,dup_no;
|
||||||
int select_field_pos,auto_increment=0;
|
int select_field_pos,auto_increment=0;
|
||||||
|
List_iterator<create_field> it(alter_info->create_list);
|
||||||
|
List_iterator<create_field> it2(alter_info->create_list);
|
||||||
DBUG_ENTER("mysql_prepare_table");
|
DBUG_ENTER("mysql_prepare_table");
|
||||||
|
|
||||||
List_iterator<create_field> it(fields),it2(fields);
|
select_field_pos= alter_info->create_list.elements - select_field_count;
|
||||||
select_field_pos=fields.elements - select_field_count;
|
|
||||||
null_fields=blob_columns=0;
|
null_fields=blob_columns=0;
|
||||||
|
|
||||||
for (field_no=0; (sql_field=it++) ; field_no++)
|
for (field_no=0; (sql_field=it++) ; field_no++)
|
||||||
@ -883,7 +883,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
|
|
||||||
/* Create keys */
|
/* Create keys */
|
||||||
|
|
||||||
List_iterator<Key> key_iterator(keys), key_iterator2(keys);
|
List_iterator<Key> key_iterator(alter_info->key_list);
|
||||||
|
List_iterator<Key> key_iterator2(alter_info->key_list);
|
||||||
uint key_parts=0, fk_key_count=0;
|
uint key_parts=0, fk_key_count=0;
|
||||||
bool primary_key=0,unique_key=0;
|
bool primary_key=0,unique_key=0;
|
||||||
Key *key, *key2;
|
Key *key, *key2;
|
||||||
@ -1333,23 +1334,27 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
mysql_create_table()
|
mysql_create_table()
|
||||||
thd Thread object
|
thd Thread object
|
||||||
db Database
|
db Database
|
||||||
table_name Table name
|
table_name Table name
|
||||||
create_info Create information (like MAX_ROWS)
|
create_info [in/out] Create information (like MAX_ROWS)
|
||||||
fields List of fields to create
|
alter_info [in/out] List of columns and indexes to create
|
||||||
keys List of keys to create
|
tmp_table Set to 1 if this is an internal temporary table
|
||||||
tmp_table Set to 1 if this is an internal temporary table
|
(From ALTER TABLE)
|
||||||
(From ALTER TABLE)
|
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
If one creates a temporary table, this is automaticly opened
|
If one creates a temporary table, this is automatically opened
|
||||||
|
|
||||||
no_log is needed for the case of CREATE ... SELECT,
|
no_log is needed for the case of CREATE ... SELECT,
|
||||||
as the logging will be done later in sql_insert.cc
|
as the logging will be done later in sql_insert.cc
|
||||||
select_field_count is also used for CREATE ... SELECT,
|
select_field_count is also used for CREATE ... SELECT,
|
||||||
and must be zero for standard create of table.
|
and must be zero for standard create of table.
|
||||||
|
|
||||||
|
Note that structures passed as 'create_info' and 'alter_info' parameters
|
||||||
|
may be modified by this function. It is responsibility of the caller to
|
||||||
|
make a copy of create_info in order to provide correct execution in
|
||||||
|
prepared statements/stored routines.
|
||||||
|
|
||||||
RETURN VALUES
|
RETURN VALUES
|
||||||
0 ok
|
0 ok
|
||||||
-1 error
|
-1 error
|
||||||
@ -1357,8 +1362,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
|
|
||||||
int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
||||||
HA_CREATE_INFO *create_info,
|
HA_CREATE_INFO *create_info,
|
||||||
List<create_field> &fields,
|
Alter_info *alter_info,
|
||||||
List<Key> &keys,bool tmp_table,
|
bool tmp_table,
|
||||||
uint select_field_count)
|
uint select_field_count)
|
||||||
{
|
{
|
||||||
char path[FN_REFLEN];
|
char path[FN_REFLEN];
|
||||||
@ -1371,7 +1376,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
|||||||
DBUG_ENTER("mysql_create_table");
|
DBUG_ENTER("mysql_create_table");
|
||||||
|
|
||||||
/* Check for duplicate fields and check type of table to create */
|
/* Check for duplicate fields and check type of table to create */
|
||||||
if (!fields.elements)
|
if (!alter_info->create_list.elements)
|
||||||
{
|
{
|
||||||
my_error(ER_TABLE_MUST_HAVE_COLUMNS,MYF(0));
|
my_error(ER_TABLE_MUST_HAVE_COLUMNS,MYF(0));
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
@ -1423,10 +1428,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
|||||||
create_info->default_table_charset= db_info.default_table_charset;
|
create_info->default_table_charset= db_info.default_table_charset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mysql_prepare_table(thd, create_info, fields,
|
if (mysql_prepare_table(thd, create_info, alter_info, tmp_table,
|
||||||
keys, tmp_table, db_options, file,
|
db_options, file,
|
||||||
key_info_buffer, &key_count,
|
key_info_buffer, &key_count,
|
||||||
select_field_count))
|
select_field_count))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
|
|
||||||
/* Check if table exists */
|
/* Check if table exists */
|
||||||
@ -1503,8 +1508,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
|||||||
create_info->table_options=db_options;
|
create_info->table_options=db_options;
|
||||||
|
|
||||||
if (rea_create_table(thd, path, db, table_name,
|
if (rea_create_table(thd, path, db, table_name,
|
||||||
create_info, fields, key_count,
|
create_info, alter_info->create_list,
|
||||||
key_info_buffer))
|
key_count, key_info_buffer))
|
||||||
goto end;
|
goto end;
|
||||||
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
|
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
|
||||||
{
|
{
|
||||||
@ -1592,8 +1597,7 @@ make_unique_key_name(const char *field_name,KEY *start,KEY *end)
|
|||||||
|
|
||||||
TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
||||||
const char *db, const char *name,
|
const char *db, const char *name,
|
||||||
List<create_field> *extra_fields,
|
Alter_info *alter_info,
|
||||||
List<Key> *keys,
|
|
||||||
List<Item> *items,
|
List<Item> *items,
|
||||||
MYSQL_LOCK **lock)
|
MYSQL_LOCK **lock)
|
||||||
{
|
{
|
||||||
@ -1627,7 +1631,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
((Item_field *)item)->field :
|
((Item_field *)item)->field :
|
||||||
(Field*) 0))))
|
(Field*) 0))))
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
extra_fields->push_back(cr_field);
|
alter_info->create_list.push_back(cr_field);
|
||||||
}
|
}
|
||||||
/* create and lock table */
|
/* create and lock table */
|
||||||
/* QQ: create and open should be done atomic ! */
|
/* QQ: create and open should be done atomic ! */
|
||||||
@ -1641,8 +1645,8 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
open_table().
|
open_table().
|
||||||
*/
|
*/
|
||||||
tmp_disable_binlog(thd);
|
tmp_disable_binlog(thd);
|
||||||
if (!mysql_create_table(thd,db,name,create_info,*extra_fields,
|
if (!mysql_create_table(thd, db, name, create_info, alter_info,
|
||||||
*keys,0,select_field_count))
|
0, select_field_count))
|
||||||
{
|
{
|
||||||
if (!(table=open_table(thd,db,name,name,(bool*) 0)))
|
if (!(table=open_table(thd,db,name,name,(bool*) 0)))
|
||||||
quick_rm_table(create_info->db_type,db,table_case_name(create_info,name));
|
quick_rm_table(create_info->db_type,db,table_case_name(create_info,name));
|
||||||
@ -2146,6 +2150,7 @@ send_result_message:
|
|||||||
|
|
||||||
case HA_ADMIN_TRY_ALTER:
|
case HA_ADMIN_TRY_ALTER:
|
||||||
{
|
{
|
||||||
|
my_bool save_no_send_ok= thd->net.no_send_ok;
|
||||||
/*
|
/*
|
||||||
This is currently used only by InnoDB. ha_innobase::optimize() answers
|
This is currently used only by InnoDB. ha_innobase::optimize() answers
|
||||||
"try with alter", so here we close the table, do an ALTER TABLE,
|
"try with alter", so here we close the table, do an ALTER TABLE,
|
||||||
@ -2155,7 +2160,9 @@ send_result_message:
|
|||||||
TABLE_LIST *save_next= table->next;
|
TABLE_LIST *save_next= table->next;
|
||||||
table->next= 0;
|
table->next= 0;
|
||||||
tmp_disable_binlog(thd); // binlogging is done by caller if wanted
|
tmp_disable_binlog(thd); // binlogging is done by caller if wanted
|
||||||
result_code= mysql_recreate_table(thd, table, 0);
|
thd->net.no_send_ok= TRUE;
|
||||||
|
result_code= mysql_recreate_table(thd, table);
|
||||||
|
thd->net.no_send_ok= save_no_send_ok;
|
||||||
reenable_binlog(thd);
|
reenable_binlog(thd);
|
||||||
close_thread_tables(thd);
|
close_thread_tables(thd);
|
||||||
if (!result_code) // recreation went ok
|
if (!result_code) // recreation went ok
|
||||||
@ -2635,206 +2642,6 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef NOT_USED
|
|
||||||
/*
|
|
||||||
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_indexes(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+1];
|
|
||||||
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)||
|
|
||||||
build_table_path(path, sizeof(path), table_list->db,
|
|
||||||
(lower_case_table_names == 2) ?
|
|
||||||
table_list->alias : table_list->real_name,
|
|
||||||
reg_ext) == 0 ||
|
|
||||||
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_indexes(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)||
|
|
||||||
build_table_path(path, sizeof(path), table_list->db,
|
|
||||||
(lower_case_table_names == 2) ?
|
|
||||||
table_list->alias : table_list->real_name,
|
|
||||||
reg_ext) == 0 ||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
#endif /* NOT_USED */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2887,15 +2694,21 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Alter table
|
Alter table
|
||||||
|
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
The structures passed as 'create_info' and 'alter_info' parameters may
|
||||||
|
be modified by this function. It is responsibility of the caller to make
|
||||||
|
a copy of create_info in order to provide correct execution in prepared
|
||||||
|
statements/stored routines.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||||
HA_CREATE_INFO *create_info,
|
HA_CREATE_INFO *create_info,
|
||||||
TABLE_LIST *table_list,
|
TABLE_LIST *table_list,
|
||||||
List<create_field> &fields, List<Key> &keys,
|
Alter_info *alter_info,
|
||||||
uint order_num, ORDER *order,
|
uint order_num, ORDER *order,
|
||||||
enum enum_duplicates handle_duplicates, bool ignore,
|
enum enum_duplicates handle_duplicates, bool ignore)
|
||||||
ALTER_INFO *alter_info, bool do_send_ok)
|
|
||||||
{
|
{
|
||||||
TABLE *table,*new_table;
|
TABLE *table,*new_table;
|
||||||
int error;
|
int error;
|
||||||
@ -3064,8 +2877,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
|
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
|
||||||
mysql_bin_log.write(&qinfo);
|
mysql_bin_log.write(&qinfo);
|
||||||
}
|
}
|
||||||
if (do_send_ok)
|
send_ok(thd);
|
||||||
send_ok(thd);
|
|
||||||
}
|
}
|
||||||
else if (error > 0)
|
else if (error > 0)
|
||||||
{
|
{
|
||||||
@ -3091,10 +2903,9 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
|
|
||||||
restore_record(table,default_values); // Empty record for DEFAULT
|
restore_record(table,default_values); // Empty record for DEFAULT
|
||||||
List_iterator<Alter_drop> drop_it(alter_info->drop_list);
|
List_iterator<Alter_drop> drop_it(alter_info->drop_list);
|
||||||
List_iterator<create_field> def_it(fields);
|
List_iterator<create_field> def_it(alter_info->create_list);
|
||||||
List_iterator<Alter_column> alter_it(alter_info->alter_list);
|
List_iterator<Alter_column> alter_it(alter_info->alter_list);
|
||||||
List<create_field> create_list; // Add new fields here
|
Alter_info new_info; // Add new columns and indexes here
|
||||||
List<Key> key_list; // Add new keys here
|
|
||||||
create_field *def;
|
create_field *def;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3140,13 +2951,13 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
def->field=field;
|
def->field=field;
|
||||||
if (!def->after)
|
if (!def->after)
|
||||||
{
|
{
|
||||||
create_list.push_back(def);
|
new_info.create_list.push_back(def);
|
||||||
def_it.remove();
|
def_it.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // Use old field value
|
{ // Use old field value
|
||||||
create_list.push_back(def=new create_field(field,field));
|
new_info.create_list.push_back(def= new create_field(field, field));
|
||||||
alter_it.rewind(); // Change default if ALTER
|
alter_it.rewind(); // Change default if ALTER
|
||||||
Alter_column *alter;
|
Alter_column *alter;
|
||||||
while ((alter=alter_it++))
|
while ((alter=alter_it++))
|
||||||
@ -3167,7 +2978,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
def_it.rewind();
|
def_it.rewind();
|
||||||
List_iterator<create_field> find_it(create_list);
|
List_iterator<create_field> find_it(new_info.create_list);
|
||||||
while ((def=def_it++)) // Add new columns
|
while ((def=def_it++)) // Add new columns
|
||||||
{
|
{
|
||||||
if (def->change && ! def->field)
|
if (def->change && ! def->field)
|
||||||
@ -3176,9 +2987,9 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
if (!def->after)
|
if (!def->after)
|
||||||
create_list.push_back(def);
|
new_info.create_list.push_back(def);
|
||||||
else if (def->after == first_keyword)
|
else if (def->after == first_keyword)
|
||||||
create_list.push_front(def);
|
new_info.create_list.push_front(def);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
create_field *find;
|
create_field *find;
|
||||||
@ -3202,7 +3013,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
table_name);
|
table_name);
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
if (!create_list.elements)
|
if (!new_info.create_list.elements)
|
||||||
{
|
{
|
||||||
my_error(ER_CANT_REMOVE_ALL_FIELDS,MYF(0));
|
my_error(ER_CANT_REMOVE_ALL_FIELDS,MYF(0));
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
@ -3213,8 +3024,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
for which some fields exists.
|
for which some fields exists.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
List_iterator<Key> key_it(keys);
|
List_iterator<Key> key_it(alter_info->key_list);
|
||||||
List_iterator<create_field> field_it(create_list);
|
List_iterator<create_field> field_it(new_info.create_list);
|
||||||
List<key_part_spec> key_parts;
|
List<key_part_spec> key_parts;
|
||||||
|
|
||||||
KEY *key_info=table->key_info;
|
KEY *key_info=table->key_info;
|
||||||
@ -3272,24 +3083,37 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
key_part_length));
|
key_part_length));
|
||||||
}
|
}
|
||||||
if (key_parts.elements)
|
if (key_parts.elements)
|
||||||
key_list.push_back(new Key(key_info->flags & HA_SPATIAL ? Key::SPATIAL :
|
{
|
||||||
(key_info->flags & HA_NOSAME ?
|
Key *key;
|
||||||
(!my_strcasecmp(system_charset_info,
|
enum Key::Keytype key_type;
|
||||||
key_name, primary_key_name) ?
|
|
||||||
Key::PRIMARY : Key::UNIQUE) :
|
if (key_info->flags & HA_SPATIAL)
|
||||||
(key_info->flags & HA_FULLTEXT ?
|
key_type= Key::SPATIAL;
|
||||||
Key::FULLTEXT : Key::MULTIPLE)),
|
else if (key_info->flags & HA_NOSAME)
|
||||||
key_name,
|
{
|
||||||
key_info->algorithm,
|
if (! my_strcasecmp(system_charset_info, key_name, primary_key_name))
|
||||||
test(key_info->flags & HA_GENERATED_KEY),
|
key_type= Key::PRIMARY;
|
||||||
key_parts));
|
else
|
||||||
|
key_type= Key::UNIQUE;
|
||||||
|
}
|
||||||
|
else if (key_info->flags & HA_FULLTEXT)
|
||||||
|
key_type= Key::FULLTEXT;
|
||||||
|
else
|
||||||
|
key_type= Key::MULTIPLE;
|
||||||
|
|
||||||
|
key= new Key(key_type, key_name,
|
||||||
|
key_info->algorithm,
|
||||||
|
test(key_info->flags & HA_GENERATED_KEY),
|
||||||
|
key_parts);
|
||||||
|
new_info.key_list.push_back(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Key *key;
|
Key *key;
|
||||||
while ((key=key_it++)) // Add new keys
|
while ((key=key_it++)) // Add new keys
|
||||||
{
|
{
|
||||||
if (key->type != Key::FOREIGN_KEY)
|
if (key->type != Key::FOREIGN_KEY)
|
||||||
key_list.push_back(key);
|
new_info.key_list.push_back(key);
|
||||||
if (key->name &&
|
if (key->name &&
|
||||||
!my_strcasecmp(system_charset_info,key->name,primary_key_name))
|
!my_strcasecmp(system_charset_info,key->name,primary_key_name))
|
||||||
{
|
{
|
||||||
@ -3393,7 +3217,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
/* We don't log the statement, it will be logged later. */
|
/* We don't log the statement, it will be logged later. */
|
||||||
tmp_disable_binlog(thd);
|
tmp_disable_binlog(thd);
|
||||||
error= mysql_create_table(thd, new_db, tmp_name,
|
error= mysql_create_table(thd, new_db, tmp_name,
|
||||||
create_info,create_list,key_list,1,0);
|
create_info, &new_info, 1, 0);
|
||||||
reenable_binlog(thd);
|
reenable_binlog(thd);
|
||||||
if (error)
|
if (error)
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
@ -3422,10 +3246,10 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
next_insert_id=thd->next_insert_id; // Remember for loggin
|
next_insert_id=thd->next_insert_id; // Remember for loggin
|
||||||
copied=deleted=0;
|
copied=deleted=0;
|
||||||
if (!new_table->is_view)
|
if (!new_table->is_view)
|
||||||
error=copy_data_between_tables(table,new_table,create_list,
|
error= copy_data_between_tables(table, new_table, new_info.create_list,
|
||||||
handle_duplicates, ignore,
|
handle_duplicates, ignore,
|
||||||
order_num, order, &copied, &deleted,
|
order_num, order, &copied, &deleted,
|
||||||
alter_info->keys_onoff);
|
alter_info->keys_onoff);
|
||||||
/*
|
/*
|
||||||
No need to have call to alter_table_manage_keys() in the else because
|
No need to have call to alter_table_manage_keys() in the else because
|
||||||
in 4.1 we always copy data, except for views. In 5.0 it could happen
|
in 4.1 we always copy data, except for views. In 5.0 it could happen
|
||||||
@ -3637,8 +3461,7 @@ end_temporary:
|
|||||||
my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
|
my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
|
||||||
(ulong) (copied + deleted), (ulong) deleted,
|
(ulong) (copied + deleted), (ulong) deleted,
|
||||||
(ulong) thd->cuted_fields);
|
(ulong) thd->cuted_fields);
|
||||||
if (do_send_ok)
|
send_ok(thd, copied + deleted, 0L, tmp_name);
|
||||||
send_ok(thd,copied+deleted,0L,tmp_name);
|
|
||||||
thd->some_tables_deleted=0;
|
thd->some_tables_deleted=0;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
@ -3828,30 +3651,26 @@ copy_data_between_tables(TABLE *from,TABLE *to,
|
|||||||
mysql_recreate_table()
|
mysql_recreate_table()
|
||||||
thd Thread handler
|
thd Thread handler
|
||||||
tables Tables to recreate
|
tables Tables to recreate
|
||||||
do_send_ok If we should send_ok() or leave it to caller
|
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
Like mysql_alter_table().
|
Like mysql_alter_table().
|
||||||
*/
|
*/
|
||||||
int mysql_recreate_table(THD *thd, TABLE_LIST *table_list,
|
int mysql_recreate_table(THD *thd, TABLE_LIST *table_list)
|
||||||
bool do_send_ok)
|
|
||||||
{
|
{
|
||||||
DBUG_ENTER("mysql_recreate_table");
|
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
HA_CREATE_INFO create_info;
|
HA_CREATE_INFO create_info;
|
||||||
lex->create_list.empty();
|
Alter_info alter_info;
|
||||||
lex->key_list.empty();
|
|
||||||
lex->col_list.empty();
|
DBUG_ENTER("mysql_recreate_table");
|
||||||
lex->alter_info.reset();
|
|
||||||
lex->alter_info.is_simple= 0; // Force full recreate
|
|
||||||
bzero((char*) &create_info,sizeof(create_info));
|
bzero((char*) &create_info,sizeof(create_info));
|
||||||
create_info.db_type=DB_TYPE_DEFAULT;
|
create_info.db_type=DB_TYPE_DEFAULT;
|
||||||
create_info.row_type=ROW_TYPE_DEFAULT;
|
create_info.row_type=ROW_TYPE_DEFAULT;
|
||||||
create_info.default_table_charset=default_charset_info;
|
create_info.default_table_charset=default_charset_info;
|
||||||
|
alter_info.is_simple= 0; // Force full recreate
|
||||||
DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info,
|
DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info,
|
||||||
table_list, lex->create_list,
|
table_list, &alter_info,
|
||||||
lex->key_list, 0, (ORDER *) 0,
|
0, (ORDER *) 0, DUP_ERROR, 0));
|
||||||
DUP_ERROR, 0, &lex->alter_info, do_send_ok));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1021,8 +1021,7 @@ create:
|
|||||||
TL_READ_NO_INSERT:
|
TL_READ_NO_INSERT:
|
||||||
TL_READ)))
|
TL_READ)))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
lex->create_list.empty();
|
lex->alter_info.reset();
|
||||||
lex->key_list.empty();
|
|
||||||
lex->col_list.empty();
|
lex->col_list.empty();
|
||||||
lex->change=NullS;
|
lex->change=NullS;
|
||||||
bzero((char*) &lex->create_info,sizeof(lex->create_info));
|
bzero((char*) &lex->create_info,sizeof(lex->create_info));
|
||||||
@ -1040,16 +1039,18 @@ create:
|
|||||||
if (!lex->current_select->add_table_to_list(lex->thd, $7, NULL,
|
if (!lex->current_select->add_table_to_list(lex->thd, $7, NULL,
|
||||||
TL_OPTION_UPDATING))
|
TL_OPTION_UPDATING))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
lex->create_list.empty();
|
lex->alter_info.reset();
|
||||||
lex->key_list.empty();
|
lex->alter_info.is_simple= 0;
|
||||||
|
lex->alter_info.flags= ALTER_ADD_INDEX;
|
||||||
lex->col_list.empty();
|
lex->col_list.empty();
|
||||||
lex->change=NullS;
|
lex->change=NullS;
|
||||||
}
|
}
|
||||||
'(' key_list ')'
|
'(' key_list ')'
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
|
Key *key= new Key($2, $4.str, $5, 0, lex->col_list);
|
||||||
|
|
||||||
lex->key_list.push_back(new Key($2,$4.str, $5, 0, lex->col_list));
|
lex->alter_info.key_list.push_back(key);
|
||||||
lex->col_list.empty();
|
lex->col_list.empty();
|
||||||
}
|
}
|
||||||
| CREATE DATABASE opt_if_not_exists ident
|
| CREATE DATABASE opt_if_not_exists ident
|
||||||
@ -1305,29 +1306,34 @@ key_def:
|
|||||||
key_type opt_ident key_alg '(' key_list ')'
|
key_type opt_ident key_alg '(' key_list ')'
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->key_list.push_back(new Key($1,$2, $3, 0, lex->col_list));
|
Key *key= new Key($1, $2, $3, 0, lex->col_list);
|
||||||
|
lex->alter_info.key_list.push_back(key);
|
||||||
|
|
||||||
lex->col_list.empty(); /* Alloced by sql_alloc */
|
lex->col_list.empty(); /* Alloced by sql_alloc */
|
||||||
}
|
}
|
||||||
| opt_constraint constraint_key_type opt_ident key_alg '(' key_list ')'
|
| opt_constraint constraint_key_type opt_ident key_alg '(' key_list ')'
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
const char *key_name= $3 ? $3:$1;
|
const char *key_name= $3 ? $3:$1;
|
||||||
lex->key_list.push_back(new Key($2, key_name, $4, 0,
|
Key *key= new Key($2, key_name, $4, 0, lex->col_list);
|
||||||
lex->col_list));
|
lex->alter_info.key_list.push_back(key);
|
||||||
lex->col_list.empty(); /* Alloced by sql_alloc */
|
lex->col_list.empty(); /* Alloced by sql_alloc */
|
||||||
}
|
}
|
||||||
| opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
|
| opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->key_list.push_back(new foreign_key($4 ? $4:$1, lex->col_list,
|
const char *key_name= $4 ? $4 : $1;
|
||||||
$8,
|
Key *key= new foreign_key(key_name, lex->col_list,
|
||||||
lex->ref_list,
|
$8,
|
||||||
lex->fk_delete_opt,
|
lex->ref_list,
|
||||||
lex->fk_update_opt,
|
lex->fk_delete_opt,
|
||||||
lex->fk_match_option));
|
lex->fk_update_opt,
|
||||||
lex->key_list.push_back(new Key(Key::MULTIPLE, $4 ? $4 : $1,
|
lex->fk_match_option);
|
||||||
HA_KEY_ALG_UNDEF, 1,
|
lex->alter_info.key_list.push_back(key);
|
||||||
lex->col_list));
|
key= new Key(Key::MULTIPLE, key_name,
|
||||||
|
HA_KEY_ALG_UNDEF, 1,
|
||||||
|
lex->col_list);
|
||||||
|
lex->alter_info.key_list.push_back(key);
|
||||||
lex->col_list.empty(); /* Alloced by sql_alloc */
|
lex->col_list.empty(); /* Alloced by sql_alloc */
|
||||||
}
|
}
|
||||||
| constraint opt_check_constraint
|
| constraint opt_check_constraint
|
||||||
@ -1850,8 +1856,6 @@ alter:
|
|||||||
if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
|
if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
|
||||||
TL_OPTION_UPDATING))
|
TL_OPTION_UPDATING))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
lex->create_list.empty();
|
|
||||||
lex->key_list.empty();
|
|
||||||
lex->col_list.empty();
|
lex->col_list.empty();
|
||||||
lex->select_lex.init_order();
|
lex->select_lex.init_order();
|
||||||
lex->select_lex.db=lex->name=0;
|
lex->select_lex.db=lex->name=0;
|
||||||
@ -1859,9 +1863,7 @@ alter:
|
|||||||
lex->create_info.db_type= DB_TYPE_DEFAULT;
|
lex->create_info.db_type= DB_TYPE_DEFAULT;
|
||||||
lex->create_info.default_table_charset= NULL;
|
lex->create_info.default_table_charset= NULL;
|
||||||
lex->create_info.row_type= ROW_TYPE_NOT_USED;
|
lex->create_info.row_type= ROW_TYPE_NOT_USED;
|
||||||
lex->alter_info.reset();
|
lex->alter_info.reset();
|
||||||
lex->alter_info.is_simple= 1;
|
|
||||||
lex->alter_info.flags= 0;
|
|
||||||
}
|
}
|
||||||
alter_list
|
alter_list
|
||||||
{}
|
{}
|
||||||
@ -4030,7 +4032,9 @@ drop:
|
|||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->sql_command= SQLCOM_DROP_INDEX;
|
lex->sql_command= SQLCOM_DROP_INDEX;
|
||||||
lex->alter_info.drop_list.empty();
|
lex->alter_info.reset();
|
||||||
|
lex->alter_info.is_simple= 0;
|
||||||
|
lex->alter_info.flags= ALTER_DROP_INDEX;
|
||||||
lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY,
|
lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY,
|
||||||
$3.str));
|
$3.str));
|
||||||
if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL,
|
if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL,
|
||||||
|
@ -340,7 +340,7 @@ install -m 644 libmysqld/libmysqld.a $RBR%{_libdir}/mysql/
|
|||||||
# Include libgcc.a in the devel subpackage (BUG 4921)
|
# Include libgcc.a in the devel subpackage (BUG 4921)
|
||||||
if expr "$CC" : ".*gcc.*" > /dev/null ;
|
if expr "$CC" : ".*gcc.*" > /dev/null ;
|
||||||
then
|
then
|
||||||
libgcc=`$CC --print-libgcc-file`
|
libgcc=`$CC $CFLAGS --print-libgcc-file`
|
||||||
if [ -f $libgcc ]
|
if [ -f $libgcc ]
|
||||||
then
|
then
|
||||||
%define have_libgcc 1
|
%define have_libgcc 1
|
||||||
@ -726,6 +726,11 @@ fi
|
|||||||
# itself - note that they must be ordered by date (important when
|
# itself - note that they must be ordered by date (important when
|
||||||
# merging BK trees)
|
# merging BK trees)
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Jan 05 2007 Kent Boortz <kent@mysql.com>
|
||||||
|
|
||||||
|
- Add CFLAGS to gcc call with --print-libgcc-file, to make sure the
|
||||||
|
correct "libgcc.a" path is returned for the 32/64 bit architecture.
|
||||||
|
|
||||||
* Thu Dec 14 2006 Joerg Bruehe <joerg@mysql.com>
|
* Thu Dec 14 2006 Joerg Bruehe <joerg@mysql.com>
|
||||||
|
|
||||||
- Include the new man pages for "my_print_defaults" and "mysql_tzinfo_to_sql"
|
- Include the new man pages for "my_print_defaults" and "mysql_tzinfo_to_sql"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user