Merge mysql.com:/nfsdisk1/lars/bkroot/mysql-4.1-rpl

into  mysql.com:/nfsdisk1/lars/MERGE/mysql-4.1-merge
parents 0004fa3c bbaf3275
...@@ -167,8 +167,7 @@ check_cpu () { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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") ...@@ -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) ...@@ -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) ...@@ -68,11 +68,17 @@ int heap_write(HP_INFO *info, const byte *record)
DBUG_RETURN(0); DBUG_RETURN(0);
err: err:
if (my_errno == HA_ERR_FOUND_DUPP_KEY)
DBUG_PRINT("info",("Duplicate key: %d", keydef - share->keydef)); 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 @@ ...@@ -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; ...@@ -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"); ...@@ -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` ( ...@@ -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; ...@@ -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.
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; ...@@ -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; ...@@ -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; ...@@ -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); ...@@ -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; ...@@ -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.
# 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; ...@@ -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 ...@@ -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.$$" ...@@ -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() { ...@@ -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() { ...@@ -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() { ...@@ -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." ...@@ -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" ...@@ -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" ...@@ -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" ...@@ -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" ...@@ -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, ...@@ -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, ...@@ -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);
...@@ -620,38 +614,34 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, ...@@ -620,38 +614,34 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
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)
...@@ -1638,8 +1628,9 @@ longlong Item_func_sec_to_time::val_int() ...@@ -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() ...@@ -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) ...@@ -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,
......
...@@ -1350,6 +1350,21 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u", ...@@ -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; ...@@ -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; ...@@ -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, ...@@ -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, ...@@ -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); ...@@ -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) ...@@ -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())))
{
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; return 1;
} }
else }
else // STRING_RESULT
{ {
char buff[6];
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; var->save_result.locale_value= locale_match;
return 0; return 0;
}
} }
......
...@@ -764,12 +764,16 @@ class sys_var_thd_lc_time_names :public sys_var_thd ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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; ...@@ -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 ...@@ -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 ...@@ -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,9 +66,14 @@ public: ...@@ -66,9 +66,14 @@ 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)
...@@ -76,11 +81,9 @@ public: ...@@ -76,11 +81,9 @@ public:
{} {}
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: ...@@ -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 ...@@ -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(); }
......
This diff is collapsed.
This diff is collapsed.
...@@ -845,7 +845,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) ...@@ -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];
......
This diff is collapsed.
...@@ -1021,8 +1021,7 @@ create: ...@@ -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: ...@@ -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: ...@@ -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;
Key *key= new foreign_key(key_name, lex->col_list,
$8, $8,
lex->ref_list, lex->ref_list,
lex->fk_delete_opt, lex->fk_delete_opt,
lex->fk_update_opt, lex->fk_update_opt,
lex->fk_match_option)); lex->fk_match_option);
lex->key_list.push_back(new Key(Key::MULTIPLE, $4 ? $4 : $1, lex->alter_info.key_list.push_back(key);
key= new Key(Key::MULTIPLE, key_name,
HA_KEY_ALG_UNDEF, 1, HA_KEY_ALG_UNDEF, 1,
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 */
} }
| constraint opt_check_constraint | constraint opt_check_constraint
...@@ -1850,8 +1856,6 @@ alter: ...@@ -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;
...@@ -1860,8 +1864,6 @@ alter: ...@@ -1860,8 +1864,6 @@ alter:
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: ...@@ -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/ ...@@ -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 ...@@ -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"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment