merge from 5.1 main

This commit is contained in:
Bjorn Munch 2011-02-24 15:07:51 +01:00
commit e58e15ff13
59 changed files with 1927 additions and 638 deletions

21
README
View File

@ -3,18 +3,29 @@ MySQL Server
This is a release of MySQL, a dual-license SQL database server.
For the avoidance of doubt, this particular copy of the software
is released under the version 2 of the GNU General Public License.
MySQL is brought to you by the MySQL team at Oracle.
MySQL is brought to you by Oracle.
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
License information can be found in the COPYING file.
MySQL FOSS License Exception
We want free and open source software applications under certain
licenses to be able to use specified GPL-licensed MySQL client
libraries despite the fact that not all such FOSS licenses are
compatible with version 2 of the GNU General Public License.
Therefore there are special exceptions to the terms and conditions
of the GPLv2 as applied to these client libraries, which are
identified and described in more detail in the FOSS License
Exception at
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
This distribution may include materials developed by third
parties. For license and attribution notices for these
materials, please refer to the documentation that accompanies
this distribution (see the Licenses for Third-Party Components
appendix). A copy of the license/notices is also reproduced
below.
this distribution (see the "Licenses for Third-Party Components"
appendix) or view the online documentation at
<http://dev.mysql.com/doc/>.
GPLv2 Disclaimer
For the avoidance of doubt, except that if any license choice
@ -38,8 +49,6 @@ Some Reference Manual sections of special interest:
chapter.
- For the new features/bugfix history, see the MySQL Change History
appendix.
- For currently known bugs, see the Errors and Common Problems
appendix.
You can browse the MySQL Reference Manual online or download it
in any of several formats at the URL given earlier in this file.

View File

@ -1131,6 +1131,8 @@ int main(int argc,char *argv[])
if (status.batch && !status.line_buff &&
!(status.line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, stdin)))
{
put_info("Can't initialize batch_readline - may be the input source is "
"a directory or a block device.", INFO_ERROR, 0);
free_defaults(defaults_argv);
my_end(0);
exit(1);

View File

@ -1134,6 +1134,9 @@ static int switch_db_collation(FILE *sql_file,
{
if (strcmp(current_db_cl_name, required_db_cl_name) != 0)
{
char quoted_db_buf[NAME_LEN * 2 + 3];
char *quoted_db_name= quote_name(db_name, quoted_db_buf, FALSE);
CHARSET_INFO *db_cl= get_charset_by_name(required_db_cl_name, MYF(0));
if (!db_cl)
@ -1141,7 +1144,7 @@ static int switch_db_collation(FILE *sql_file,
fprintf(sql_file,
"ALTER DATABASE %s CHARACTER SET %s COLLATE %s %s\n",
(const char *) db_name,
(const char *) quoted_db_name,
(const char *) db_cl->csname,
(const char *) db_cl->name,
(const char *) delimiter);
@ -1162,6 +1165,9 @@ static int restore_db_collation(FILE *sql_file,
const char *delimiter,
const char *db_cl_name)
{
char quoted_db_buf[NAME_LEN * 2 + 3];
char *quoted_db_name= quote_name(db_name, quoted_db_buf, FALSE);
CHARSET_INFO *db_cl= get_charset_by_name(db_cl_name, MYF(0));
if (!db_cl)
@ -1169,7 +1175,7 @@ static int restore_db_collation(FILE *sql_file,
fprintf(sql_file,
"ALTER DATABASE %s CHARACTER SET %s COLLATE %s %s\n",
(const char *) db_name,
(const char *) quoted_db_name,
(const char *) db_cl->csname,
(const char *) db_cl->name,
(const char *) delimiter);

View File

@ -18,6 +18,7 @@
#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <my_dir.h>
#include "my_readline.h"
static bool init_line_buffer(LINE_BUFFER *buffer,File file,ulong size,
@ -30,6 +31,15 @@ static char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length);
LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file)
{
LINE_BUFFER *line_buff;
MY_STAT input_file_stat;
#ifndef __WIN__
if (my_fstat(fileno(file), &input_file_stat, MYF(MY_WME)) ||
MY_S_ISDIR(input_file_stat.st_mode) ||
MY_S_ISBLK(input_file_stat.st_mode))
return 0;
#endif
if (!(line_buff=(LINE_BUFFER*)
my_malloc(sizeof(*line_buff),MYF(MY_WME | MY_ZEROFILL))))
return 0;

View File

@ -12,7 +12,7 @@ dnl
dnl When changing the major version number please also check the switch
dnl statement in mysqlbinlog::check_master_version(). You may also need
dnl to update version.c in ndb.
AC_INIT([MySQL Server], [5.1.56], [], [mysql])
AC_INIT([MySQL Server], [5.1.57], [], [mysql])
AC_CONFIG_SRCDIR([sql/mysqld.cc])
AC_CANONICAL_SYSTEM

View File

@ -1,3 +1,18 @@
/* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
Some useful bit functions
*/
@ -42,9 +57,12 @@ STATIC_INLINE uint my_count_bits(ulonglong v)
#endif
}
STATIC_INLINE uint my_count_bits_ushort(ushort v)
STATIC_INLINE uint my_count_bits_uint32(uint32 v)
{
return _my_bits_nbits[v];
return (uint) (uchar) (_my_bits_nbits[(uchar) v] +
_my_bits_nbits[(uchar) (v >> 8)] +
_my_bits_nbits[(uchar) (v >> 16)] +
_my_bits_nbits[(uchar) (v >> 24)]);
}
@ -104,6 +122,6 @@ extern uint32 my_round_up_to_next_power(uint32 v);
uint32 my_clear_highest_bit(uint32 v);
uint32 my_reverse_bits(uint32 key);
extern uint my_count_bits(ulonglong v);
extern uint my_count_bits_ushort(ushort v);
extern uint my_count_bits_uint32(uint32 v);
#endif /* HAVE_INLINE */
C_MODE_END

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2000 MySQL AB
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -149,9 +149,10 @@ bitmap_is_set(const MY_BITMAP *map,uint bit)
static inline my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2)
{
*(map1)->last_word_ptr|= (map1)->last_word_mask;
*(map2)->last_word_ptr|= (map2)->last_word_mask;
return memcmp((map1)->bitmap, (map2)->bitmap, 4*no_words_in_map((map1)))==0;
if (memcmp(map1->bitmap, map2->bitmap, 4*(no_words_in_map(map1)-1)) != 0)
return FALSE;
return ((*map1->last_word_ptr | map1->last_word_mask) ==
(*map2->last_word_ptr | map2->last_word_mask));
}
#define bitmap_clear_all(MAP) \

View File

@ -238,3 +238,6 @@ select a from t1 where a like "abcdefgh
a
abcdefghá
drop table t1;
set global LC_MESSAGES=convert((@@global.log_bin_trust_function_creators)
using cp1250);
ERROR HY000: Unknown system variable 'LC_MESSAGES'

View File

@ -375,6 +375,8 @@ FD FD FD D18D FD
FE FE FE D18E FE
FF FF FF D18F FF
DROP TABLE t1;
set global LC_TIME_NAMES=convert((-8388608) using cp1251);
ERROR HY000: Unknown locale: '-8388608'
#
# End of 5.1 tests
#

2
mysql-test/r/ctype_eucjpms.result Executable file → Normal file
View File

@ -9859,3 +9859,5 @@ hex(convert(_eucjpms 0xA5FE41 using ucs2))
select hex(convert(_eucjpms 0x8FABF841 using ucs2));
hex(convert(_eucjpms 0x8FABF841 using ucs2))
003F0041
set global LC_TIME_NAMES=convert((convert((0x63) using eucjpms)) using utf8);
ERROR HY000: Unknown locale: 'c'

View File

@ -724,7 +724,7 @@ utf8_general_ci utf8_general_ci
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER SET cp866 */;
USE `mysqltest1`;
ALTER DATABASE mysqltest1 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -757,8 +757,8 @@ DELIMITER ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE mysqltest1 CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE mysqltest1 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -791,7 +791,7 @@ DELIMITER ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE mysqltest1 CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;
---> Dumping mysqltest1 to ddl_i18n_koi8r.sp.mysqltest1.sql
@ -800,7 +800,7 @@ ALTER DATABASE mysqltest1 CHARACTER SET cp866 COLLATE cp866_general_ci ;
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER SET cp866 */;
USE `mysqltest2`;
ALTER DATABASE mysqltest2 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -833,8 +833,8 @@ DELIMITER ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE mysqltest2 CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE mysqltest2 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -867,7 +867,7 @@ DELIMITER ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE mysqltest2 CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;
---> Dumping mysqltest2 to ddl_i18n_koi8r.sp.mysqltest2.sql
@ -1742,7 +1742,7 @@ CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
INSERT INTO `t1` VALUES (1),(0),(1);
ALTER DATABASE mysqltest1 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -1770,8 +1770,8 @@ DELIMITER ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE mysqltest1 CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE mysqltest1 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -1799,7 +1799,7 @@ DELIMITER ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE mysqltest1 CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;
---> Dumping mysqltest1 to ddl_i18n_koi8r.triggers.mysqltest1.sql
@ -1821,7 +1821,7 @@ CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
INSERT INTO `t1` VALUES (1),(0),(1);
ALTER DATABASE mysqltest2 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -1849,8 +1849,8 @@ DELIMITER ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE mysqltest2 CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE mysqltest2 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -1878,7 +1878,7 @@ DELIMITER ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE mysqltest2 CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;
---> Dumping mysqltest2 to ddl_i18n_koi8r.triggers.mysqltest2.sql
@ -2486,7 +2486,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER
USE `mysqltest1`;
/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;
DELIMITER ;;
ALTER DATABASE mysqltest1 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
@ -2512,9 +2512,9 @@ END */ ;;
/*!50003 SET character_set_client = @saved_cs_client */ ;;
/*!50003 SET character_set_results = @saved_cs_results */ ;;
/*!50003 SET collation_connection = @saved_col_connection */ ;;
ALTER DATABASE mysqltest1 CHARACTER SET cp866 COLLATE cp866_general_ci ;;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;;
DELIMITER ;;
ALTER DATABASE mysqltest1 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
@ -2540,7 +2540,7 @@ END */ ;;
/*!50003 SET character_set_client = @saved_cs_client */ ;;
/*!50003 SET character_set_results = @saved_cs_results */ ;;
/*!50003 SET collation_connection = @saved_col_connection */ ;;
ALTER DATABASE mysqltest1 CHARACTER SET cp866 COLLATE cp866_general_ci ;;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;;
DELIMITER ;
/*!50106 SET TIME_ZONE= @save_time_zone */ ;
@ -2553,7 +2553,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER
USE `mysqltest2`;
/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;
DELIMITER ;;
ALTER DATABASE mysqltest2 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
@ -2579,9 +2579,9 @@ END */ ;;
/*!50003 SET character_set_client = @saved_cs_client */ ;;
/*!50003 SET character_set_results = @saved_cs_results */ ;;
/*!50003 SET collation_connection = @saved_col_connection */ ;;
ALTER DATABASE mysqltest2 CHARACTER SET cp866 COLLATE cp866_general_ci ;;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;;
DELIMITER ;;
ALTER DATABASE mysqltest2 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
@ -2607,7 +2607,7 @@ END */ ;;
/*!50003 SET character_set_client = @saved_cs_client */ ;;
/*!50003 SET character_set_results = @saved_cs_results */ ;;
/*!50003 SET collation_connection = @saved_col_connection */ ;;
ALTER DATABASE mysqltest2 CHARACTER SET cp866 COLLATE cp866_general_ci ;;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;;
DELIMITER ;
/*!50106 SET TIME_ZONE= @save_time_zone */ ;

View File

@ -724,7 +724,7 @@ utf8_general_ci utf8_general_ci
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER SET cp866 */;
USE `mysqltest1`;
ALTER DATABASE mysqltest1 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -757,8 +757,8 @@ DELIMITER ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE mysqltest1 CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE mysqltest1 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -791,7 +791,7 @@ DELIMITER ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE mysqltest1 CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;
---> Dumping mysqltest1 to ddl_i18n_utf8sp.mysqltest1.sql
@ -800,7 +800,7 @@ ALTER DATABASE mysqltest1 CHARACTER SET cp866 COLLATE cp866_general_ci ;
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER SET cp866 */;
USE `mysqltest2`;
ALTER DATABASE mysqltest2 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -833,8 +833,8 @@ DELIMITER ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE mysqltest2 CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE mysqltest2 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -867,7 +867,7 @@ DELIMITER ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE mysqltest2 CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;
---> Dumping mysqltest2 to ddl_i18n_utf8sp.mysqltest2.sql
@ -1742,7 +1742,7 @@ CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
INSERT INTO `t1` VALUES (1),(0),(1);
ALTER DATABASE mysqltest1 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -1770,8 +1770,8 @@ DELIMITER ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE mysqltest1 CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE mysqltest1 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -1799,7 +1799,7 @@ DELIMITER ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE mysqltest1 CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;
---> Dumping mysqltest1 to ddl_i18n_utf8triggers.mysqltest1.sql
@ -1821,7 +1821,7 @@ CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
INSERT INTO `t1` VALUES (1),(0),(1);
ALTER DATABASE mysqltest2 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -1849,8 +1849,8 @@ DELIMITER ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE mysqltest2 CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE mysqltest2 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -1878,7 +1878,7 @@ DELIMITER ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE mysqltest2 CHARACTER SET cp866 COLLATE cp866_general_ci ;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;
---> Dumping mysqltest2 to ddl_i18n_utf8triggers.mysqltest2.sql
@ -2486,7 +2486,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER
USE `mysqltest1`;
/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;
DELIMITER ;;
ALTER DATABASE mysqltest1 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
@ -2512,9 +2512,9 @@ END */ ;;
/*!50003 SET character_set_client = @saved_cs_client */ ;;
/*!50003 SET character_set_results = @saved_cs_results */ ;;
/*!50003 SET collation_connection = @saved_col_connection */ ;;
ALTER DATABASE mysqltest1 CHARACTER SET cp866 COLLATE cp866_general_ci ;;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;;
DELIMITER ;;
ALTER DATABASE mysqltest1 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
@ -2540,7 +2540,7 @@ END */ ;;
/*!50003 SET character_set_client = @saved_cs_client */ ;;
/*!50003 SET character_set_results = @saved_cs_results */ ;;
/*!50003 SET collation_connection = @saved_col_connection */ ;;
ALTER DATABASE mysqltest1 CHARACTER SET cp866 COLLATE cp866_general_ci ;;
ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ;;
DELIMITER ;
/*!50106 SET TIME_ZONE= @save_time_zone */ ;
@ -2553,7 +2553,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER
USE `mysqltest2`;
/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;
DELIMITER ;;
ALTER DATABASE mysqltest2 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
@ -2579,9 +2579,9 @@ END */ ;;
/*!50003 SET character_set_client = @saved_cs_client */ ;;
/*!50003 SET character_set_results = @saved_cs_results */ ;;
/*!50003 SET collation_connection = @saved_col_connection */ ;;
ALTER DATABASE mysqltest2 CHARACTER SET cp866 COLLATE cp866_general_ci ;;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;;
DELIMITER ;;
ALTER DATABASE mysqltest2 CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;;
@ -2607,7 +2607,7 @@ END */ ;;
/*!50003 SET character_set_client = @saved_cs_client */ ;;
/*!50003 SET character_set_results = @saved_cs_results */ ;;
/*!50003 SET collation_connection = @saved_col_connection */ ;;
ALTER DATABASE mysqltest2 CHARACTER SET cp866 COLLATE cp866_general_ci ;;
ALTER DATABASE `mysqltest2` CHARACTER SET cp866 COLLATE cp866_general_ci ;;
DELIMITER ;
/*!50106 SET TIME_ZONE= @save_time_zone */ ;

View File

@ -1034,4 +1034,12 @@ p
NULL
NULL
drop table t1;
#
# Test for bug #59888 "debug assertion when attempt to create spatial index
# on char > 31 bytes".
#
create table t1(a char(32) not null) engine=myisam;
create spatial index i on t1 (a);
ERROR HY000: Can't create table '#sql-temporary' (errno: 140)
drop table t1;
End of 5.1 tests

View File

@ -1855,4 +1855,40 @@ ON 1 WHERE t2.f1 > 1 GROUP BY t2.f1;
COUNT(*)
2
DROP TABLE t1;
#
# Bug#59839: Aggregation followed by subquery yields wrong result
#
CREATE TABLE t1 (
a INT,
b INT,
c INT,
KEY (a, b)
);
INSERT INTO t1 VALUES
( 1, 1, 1 ),
( 1, 2, 2 ),
( 1, 3, 3 ),
( 1, 4, 6 ),
( 1, 5, 5 ),
( 1, 9, 13 ),
( 2, 1, 6 ),
( 2, 2, 7 ),
( 2, 3, 8 );
EXPLAIN
SELECT a, AVG(t1.b),
(SELECT t11.c FROM t1 t11 WHERE t11.a = t1.a AND t11.b = AVG(t1.b)) AS t11c,
(SELECT t12.c FROM t1 t12 WHERE t12.a = t1.a AND t12.b = AVG(t1.b)) AS t12c
FROM t1 GROUP BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL a 10 NULL 9 Using index
3 DEPENDENT SUBQUERY t12 ref a a 10 func,func 2 Using where
2 DEPENDENT SUBQUERY t11 ref a a 10 func,func 2 Using where
SELECT a, AVG(t1.b),
(SELECT t11.c FROM t1 t11 WHERE t11.a = t1.a AND t11.b = AVG(t1.b)) AS t11c,
(SELECT t12.c FROM t1 t12 WHERE t12.a = t1.a AND t12.b = AVG(t1.b)) AS t12c
FROM t1 GROUP BY a;
a AVG(t1.b) t11c t12c
1 4.0000 6 6
2 2.0000 7 7
DROP TABLE t1;
# End of 5.1 tests

View File

@ -841,7 +841,7 @@ SET max_heap_table_size = 16384;
SET @old_myisam_data_pointer_size = @@myisam_data_pointer_size;
SET GLOBAL myisam_data_pointer_size = 2;
INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
call mtr.add_suppression("mysqld: The table '.*#sql.*' is full");
call mtr.add_suppression("mysqld.*: The table '.*#sql.*' is full");
INSERT IGNORE INTO t1 SELECT t1.a FROM t1,t1 t2,t1 t3,t1 t4,t1 t5,t1 t6,t1 t7;
Got one of the listed errors
SET GLOBAL myisam_data_pointer_size = @old_myisam_data_pointer_size;

View File

@ -4591,5 +4591,41 @@ CREATE TABLE `comment_table` (i INT COMMENT 'FIELD COMMENT') COMMENT = 'TABLE CO
</mysqldump>
DROP TABLE `comment_table`;
#
# BUG#11766310 : 59398: MYSQLDUMP 5.1 CAN'T HANDLE A DASH ("-") IN
# DATABASE NAMES IN ALTER DATABASE
#
CREATE DATABASE `test-database`;
USE `test-database`;
CREATE TABLE `test` (`c1` VARCHAR(10)) ENGINE=MYISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TRIGGER `trig` BEFORE INSERT ON `test` FOR EACH ROW BEGIN
END |
ALTER DATABASE `test-database` CHARACTER SET latin1 COLLATE latin1_swedish_ci;
ALTER DATABASE `test-database` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `test` (
`c1` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
ALTER DATABASE `test-database` CHARACTER SET latin1 COLLATE latin1_swedish_ci ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client = latin1 */ ;
/*!50003 SET character_set_results = latin1 */ ;
/*!50003 SET collation_connection = latin1_swedish_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `trig` BEFORE INSERT ON `test` FOR EACH ROW BEGIN
END */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
ALTER DATABASE `test-database` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
DROP DATABASE `test-database`;
#
# End of 5.1 tests
#

View File

@ -0,0 +1,8 @@
CREATE TABLE t(a INT)ENGINE=InnoDB;
RENAME TABLE t TO u;
DROP TABLE u;
SELECT @@innodb_fast_shutdown;
@@innodb_fast_shutdown
0
Last record of ID_IND root page (9):
1808000018050074000000000000000c5359535f464f524549474e5f434f4c53

View File

@ -0,0 +1 @@
--innodb_fast_shutdown=0

View File

@ -0,0 +1,39 @@
# Bug #60049 Verify that purge leaves no garbage in unique secondary indexes
# This test requires a fresh server start-up and a slow shutdown.
# This was a suspected bug (not a bug).
-- source include/not_embedded.inc
-- source include/have_innodb.inc
CREATE TABLE t(a INT)ENGINE=InnoDB;
RENAME TABLE t TO u;
DROP TABLE u;
SELECT @@innodb_fast_shutdown;
let $MYSQLD_DATADIR=`select @@datadir`;
# Shut down the server
-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- shutdown_server 30
-- source include/wait_until_disconnected.inc
# Check the tail of ID_IND (SYS_TABLES.ID)
let IBDATA1=$MYSQLD_DATADIR/ibdata1;
perl;
my $file = $ENV{'IBDATA1'};
open(FILE, "<$file") || die "Unable to open $file";
# Read DICT_HDR_TABLE_IDS, the root page number of ID_IND (SYS_TABLES.ID).
seek(FILE, 7*16384+38+36, 0) || die "Unable to seek $file";
die unless read(FILE, $_, 4) == 4;
my $sys_tables_id_root = unpack("N", $_);
print "Last record of ID_IND root page ($sys_tables_id_root):\n";
# This should be the last record in ID_IND. Dump it in hexadecimal.
seek(FILE, $sys_tables_id_root*16384 + 152, 0) || die "Unable to seek $file";
read(FILE, $_, 32) || die "Unable to read $file";
close(FILE);
print unpack("H*", $_), "\n";
EOF
# Restart the server.
-- exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- enable_reconnect
-- source include/wait_until_connected_again.inc

View File

@ -0,0 +1,28 @@
CREATE TABLE t1 (
t1_int INT,
t1_time TIME
) ENGINE=innodb;
CREATE TABLE t2 (
t2_int int PRIMARY KEY,
t2_int2 INT
) ENGINE=INNODB;
INSERT INTO t2 VALUES ();
Warnings:
Warning 1364 Field 't2_int' doesn't have a default value
INSERT INTO t1 VALUES ();
SELECT *
FROM t1 AS t1a
WHERE NOT EXISTS
(SELECT *
FROM t1 AS t1b
WHERE t1b.t1_int NOT IN
(SELECT t2.t2_int
FROM t2
WHERE t1b.t1_time LIKE t1b.t1_int
OR t1b.t1_time <> t2.t2_int2
AND 6=7
)
)
;
t1_int t1_time
DROP TABLE t1,t2;

View File

@ -0,0 +1,8 @@
CREATE TABLE t(a INT)ENGINE=InnoDB;
RENAME TABLE t TO u;
DROP TABLE u;
SELECT @@innodb_fast_shutdown;
@@innodb_fast_shutdown
0
Last record of ID_IND root page (9):
1808000018050074000000000000000c5359535f464f524549474e5f434f4c53

View File

@ -0,0 +1,32 @@
-- source include/have_innodb_plugin.inc
# Bug #59307 uninitialized value in rw_lock_set_writer_id_and_recursion_flag()
# when Valgrind instrumentation (UNIV_DEBUG_VALGRIND) is not enabled
CREATE TABLE t1 (
t1_int INT,
t1_time TIME
) ENGINE=innodb;
CREATE TABLE t2 (
t2_int int PRIMARY KEY,
t2_int2 INT
) ENGINE=INNODB;
INSERT INTO t2 VALUES ();
INSERT INTO t1 VALUES ();
SELECT *
FROM t1 AS t1a
WHERE NOT EXISTS
(SELECT *
FROM t1 AS t1b
WHERE t1b.t1_int NOT IN
(SELECT t2.t2_int
FROM t2
WHERE t1b.t1_time LIKE t1b.t1_int
OR t1b.t1_time <> t2.t2_int2
AND 6=7
)
)
;
DROP TABLE t1,t2;

View File

@ -0,0 +1 @@
--innodb_fast_shutdown=0

View File

@ -0,0 +1,39 @@
# Bug #60049 Verify that purge leaves no garbage in unique secondary indexes
# This test requires a fresh server start-up and a slow shutdown.
# This was a suspected bug (not a bug).
-- source include/not_embedded.inc
-- source include/have_innodb_plugin.inc
CREATE TABLE t(a INT)ENGINE=InnoDB;
RENAME TABLE t TO u;
DROP TABLE u;
SELECT @@innodb_fast_shutdown;
let $MYSQLD_DATADIR=`select @@datadir`;
# Shut down the server
-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- shutdown_server 30
-- source include/wait_until_disconnected.inc
# Check the tail of ID_IND (SYS_TABLES.ID)
let IBDATA1=$MYSQLD_DATADIR/ibdata1;
perl;
my $file = $ENV{'IBDATA1'};
open(FILE, "<$file") || die "Unable to open $file";
# Read DICT_HDR_TABLE_IDS, the root page number of ID_IND (SYS_TABLES.ID).
seek(FILE, 7*16384+38+36, 0) || die "Unable to seek $file";
die unless read(FILE, $_, 4) == 4;
my $sys_tables_id_root = unpack("N", $_);
print "Last record of ID_IND root page ($sys_tables_id_root):\n";
# This should be the last record in ID_IND. Dump it in hexadecimal.
seek(FILE, $sys_tables_id_root*16384 + 152, 0) || die "Unable to seek $file";
read(FILE, $_, 32) || die "Unable to read $file";
close(FILE);
print unpack("H*", $_), "\n";
EOF
# Restart the server.
-- exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- enable_reconnect
-- source include/wait_until_connected_again.inc

View File

@ -116,11 +116,29 @@ SELECT * FROM ```t'\"_str` WHERE c1 = '4' FOR UPDATE;
# executes before some of them, resulting in less than expected number
# of rows being selected from innodb_locks. If there is a bug and there
# are no 14 rows in innodb_locks then this test will fail with timeout.
let $count = 14;
let $table = INFORMATION_SCHEMA.INNODB_LOCKS;
-- source include/wait_until_rows_count.inc
# the above enables the query log, re-disable it
-- disable_query_log
# Notice that if we query INNODB_LOCKS more often than once per 0.1 sec
# then its contents will never change because the cache from which it is
# filled is updated only if it has not been read for 0.1 seconds. See
# CACHE_MIN_IDLE_TIME_US in trx/trx0i_s.c.
let $cnt=10;
while ($cnt)
{
let $success=`SELECT COUNT(*) = 14 FROM INFORMATION_SCHEMA.INNODB_LOCKS`;
if ($success)
{
let $cnt=0;
}
if (!$success)
{
real_sleep 0.2;
dec $cnt;
}
}
if (!$success)
{
-- echo Timeout waiting for rows in INNODB_LOCKS to appear
}
SELECT lock_mode, lock_type, lock_table, lock_index, lock_rec, lock_data
FROM INFORMATION_SCHEMA.INNODB_LOCKS ORDER BY lock_data;

View File

@ -72,3 +72,13 @@ select a from t1 where a like "abcdefgh
drop table t1;
# End of 4.1 tests
#
# Bug #48053 String::c_ptr has a race and/or does an invalid
# memory reference
# (triggered by Valgrind tests)
# (see also ctype_eucjpms.test, ctype_cp1250.test, ctype_cp1251.test)
#
--error 1193
set global LC_MESSAGES=convert((@@global.log_bin_trust_function_creators)
using cp1250);

View File

@ -55,6 +55,16 @@ drop table t1;
--source include/ctype_8bit.inc
#
# Bug #48053 String::c_ptr has a race and/or does an invalid
# memory reference
# (triggered by Valgrind tests)
# (see also ctype_eucjpms.test, ctype_cp1250.test, ctype_cp1251.test)
#
--error 1105
set global LC_TIME_NAMES=convert((-8388608) using cp1251);
--echo #
--echo # End of 5.1 tests
--echo #

View File

@ -381,3 +381,11 @@ select hex(convert(_eucjpms 0xA5FE41 using ucs2));
# the next character, which is a single byte character 0x41.
select hex(convert(_eucjpms 0x8FABF841 using ucs2));
#
# Bug #48053 String::c_ptr has a race and/or does an invalid
# memory reference
# (triggered by Valgrind tests)
# (see also ctype_eucjpms.test, ctype_cp1250.test, ctype_cp1251.test)
#
--error 1105
set global LC_TIME_NAMES=convert((convert((0x63) using eucjpms)) using utf8);

View File

@ -754,4 +754,16 @@ insert into t1 values (geomfromtext("point(1 0)"));
select * from (select polygon(t1.a) as p from t1 order by t1.a) d;
drop table t1;
--echo #
--echo # Test for bug #59888 "debug assertion when attempt to create spatial index
--echo # on char > 31 bytes".
--echo #
create table t1(a char(32) not null) engine=myisam;
--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
--error ER_CANT_CREATE_TABLE
create spatial index i on t1 (a);
drop table t1;
--echo End of 5.1 tests

View File

@ -1247,4 +1247,41 @@ ON 1 WHERE t2.f1 > 1 GROUP BY t2.f1;
DROP TABLE t1;
--echo #
--echo # Bug#59839: Aggregation followed by subquery yields wrong result
--echo #
CREATE TABLE t1 (
a INT,
b INT,
c INT,
KEY (a, b)
);
INSERT INTO t1 VALUES
( 1, 1, 1 ),
( 1, 2, 2 ),
( 1, 3, 3 ),
( 1, 4, 6 ),
( 1, 5, 5 ),
( 1, 9, 13 ),
( 2, 1, 6 ),
( 2, 2, 7 ),
( 2, 3, 8 );
EXPLAIN
SELECT a, AVG(t1.b),
(SELECT t11.c FROM t1 t11 WHERE t11.a = t1.a AND t11.b = AVG(t1.b)) AS t11c,
(SELECT t12.c FROM t1 t12 WHERE t12.a = t1.a AND t12.b = AVG(t1.b)) AS t12c
FROM t1 GROUP BY a;
SELECT a, AVG(t1.b),
(SELECT t11.c FROM t1 t11 WHERE t11.a = t1.a AND t11.b = AVG(t1.b)) AS t11c,
(SELECT t12.c FROM t1 t12 WHERE t12.a = t1.a AND t12.b = AVG(t1.b)) AS t12c
FROM t1 GROUP BY a;
DROP TABLE t1;
--echo # End of 5.1 tests

View File

@ -407,7 +407,7 @@ SET GLOBAL myisam_data_pointer_size = 2;
INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
call mtr.add_suppression("mysqld: The table '.*#sql.*' is full");
call mtr.add_suppression("mysqld.*: The table '.*#sql.*' is full");
--error ER_RECORD_FILE_FULL,ER_RECORD_FILE_FULL
INSERT IGNORE INTO t1 SELECT t1.a FROM t1,t1 t2,t1 t3,t1 t4,t1 t5,t1 t6,t1 t7;

View File

@ -2173,6 +2173,27 @@ CREATE TABLE `comment_table` (i INT COMMENT 'FIELD COMMENT') COMMENT = 'TABLE CO
--exec $MYSQL_DUMP --compact --skip-create --xml test
DROP TABLE `comment_table`;
--echo #
--echo # BUG#11766310 : 59398: MYSQLDUMP 5.1 CAN'T HANDLE A DASH ("-") IN
--echo # DATABASE NAMES IN ALTER DATABASE
--echo #
CREATE DATABASE `test-database`;
USE `test-database`;
CREATE TABLE `test` (`c1` VARCHAR(10)) ENGINE=MYISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
DELIMITER |;
CREATE TRIGGER `trig` BEFORE INSERT ON `test` FOR EACH ROW BEGIN
END |
DELIMITER ;|
ALTER DATABASE `test-database` CHARACTER SET latin1 COLLATE latin1_swedish_ci;
ALTER DATABASE `test-database` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
--exec $MYSQL_DUMP --quote-names --compact test-database
DROP DATABASE `test-database`;
--echo #
--echo # End of 5.1 tests
--echo #

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2000 MySQL AB
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -91,6 +91,7 @@ static inline void bitmap_lock(MY_BITMAP *map __attribute__((unused)))
#endif
}
static inline void bitmap_unlock(MY_BITMAP *map __attribute__((unused)))
{
#ifdef THREAD
@ -100,6 +101,46 @@ static inline void bitmap_unlock(MY_BITMAP *map __attribute__((unused)))
}
static inline uint get_first_set(uint32 value, uint word_pos)
{
uchar *byte_ptr= (uchar*)&value;
uchar byte_value;
uint byte_pos, bit_pos;
for (byte_pos=0; byte_pos < 4; byte_pos++, byte_ptr++)
{
byte_value= *byte_ptr;
if (byte_value)
{
for (bit_pos=0; ; bit_pos++)
if (byte_value & (1 << bit_pos))
return (word_pos*32) + (byte_pos*8) + bit_pos;
}
}
return MY_BIT_NONE;
}
static inline uint get_first_not_set(uint32 value, uint word_pos)
{
uchar *byte_ptr= (uchar*)&value;
uchar byte_value;
uint byte_pos, bit_pos;
for (byte_pos=0; byte_pos < 4; byte_pos++, byte_ptr++)
{
byte_value= *byte_ptr;
if (byte_value != 0xFF)
{
for (bit_pos=0; ; bit_pos++)
if (!(byte_value & (1 << bit_pos)))
return (word_pos*32) + (byte_pos*8) + bit_pos;
}
}
return MY_BIT_NONE;
}
my_bool bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits,
my_bool thread_safe __attribute__((unused)))
{
@ -259,7 +300,7 @@ void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size)
memset(m, 0xff, prefix_bytes);
m+= prefix_bytes;
if ((prefix_bits= prefix_size & 7))
*m++= (1 << prefix_bits)-1;
*(m++)= (1 << prefix_bits)-1;
if ((d= no_bytes_in_map(map)-prefix_bytes))
bzero(m, d);
}
@ -267,28 +308,43 @@ void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size)
my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size)
{
uint prefix_bits= prefix_size & 0x7, res;
uchar *m= (uchar*)map->bitmap;
uchar *end_prefix= m+prefix_size/8;
uchar *end;
DBUG_ASSERT(m && prefix_size <= map->n_bits);
end= m+no_bytes_in_map(map);
uint prefix_bits= prefix_size % 32;
my_bitmap_map *word_ptr= map->bitmap, last_word;
my_bitmap_map *end_prefix= word_ptr + prefix_size / 32;
DBUG_ASSERT(word_ptr && prefix_size <= map->n_bits);
while (m < end_prefix)
if (*m++ != 0xff)
return 0;
/* 1: Words that should be filled with 1 */
for (; word_ptr < end_prefix; word_ptr++)
if (*word_ptr != 0xFFFFFFFF)
return FALSE;
*map->last_word_ptr&= ~map->last_word_mask; /*Clear bits*/
res= 0;
if (prefix_bits && *m++ != (1 << prefix_bits)-1)
goto ret;
last_word= *map->last_word_ptr & ~map->last_word_mask;
while (m < end)
if (*m++ != 0)
goto ret;
res= 1;
ret:
return res;
/* 2: Word which contains the end of the prefix (if any) */
if (prefix_bits)
{
if (word_ptr == map->last_word_ptr)
return uint4korr((uchar*)&last_word) == (uint32)((1 << prefix_bits) - 1);
else if (uint4korr((uchar*)word_ptr) != (uint32)((1 << prefix_bits) - 1))
return FALSE;
word_ptr++;
}
/* 3: Words that should be filled with 0 */
for (; word_ptr < map->last_word_ptr; word_ptr++)
if (*word_ptr != 0)
return FALSE;
/*
We can end up here in two situations:
1) We went through the whole bitmap in step 1. This will happen if the
whole bitmap is filled with 1 and prefix_size is a multiple of 32
(i.e. the prefix does not end in the middle of a word).
In this case word_ptr will be larger than map->last_word_ptr.
2) We have gone through steps 1-3 and just need to check that also
the last word is 0.
*/
return word_ptr > map->last_word_ptr || last_word == 0;
}
@ -296,10 +352,12 @@ my_bool bitmap_is_set_all(const MY_BITMAP *map)
{
my_bitmap_map *data_ptr= map->bitmap;
my_bitmap_map *end= map->last_word_ptr;
*map->last_word_ptr |= map->last_word_mask;
for (; data_ptr <= end; data_ptr++)
for (; data_ptr < end; data_ptr++)
if (*data_ptr != 0xFFFFFFFF)
return FALSE;
if ((*map->last_word_ptr | map->last_word_mask) != 0xFFFFFFFF)
return FALSE;
return TRUE;
}
@ -307,13 +365,13 @@ my_bool bitmap_is_set_all(const MY_BITMAP *map)
my_bool bitmap_is_clear_all(const MY_BITMAP *map)
{
my_bitmap_map *data_ptr= map->bitmap;
my_bitmap_map *end;
if (*map->last_word_ptr & ~map->last_word_mask)
return FALSE;
end= map->last_word_ptr;
my_bitmap_map *end= map->last_word_ptr;
for (; data_ptr < end; data_ptr++)
if (*data_ptr)
return FALSE;
if (*map->last_word_ptr & ~map->last_word_mask)
return FALSE;
return TRUE;
}
@ -327,14 +385,14 @@ my_bool bitmap_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2)
map1->n_bits==map2->n_bits);
end= map1->last_word_ptr;
*map1->last_word_ptr &= ~map1->last_word_mask;
*map2->last_word_ptr &= ~map2->last_word_mask;
while (m1 <= end)
{
if ((*m1++) & ~(*m2++))
return 0;
}
return 1;
for (; m1 < end; m1++, m2++)
if (*m1 & ~(*m2))
return FALSE;
if ((*map1->last_word_ptr & ~map1->last_word_mask) &
~(*map2->last_word_ptr & ~map2->last_word_mask))
return FALSE;
return TRUE;
}
/* True if bitmaps has any common bits */
@ -347,14 +405,14 @@ my_bool bitmap_is_overlapping(const MY_BITMAP *map1, const MY_BITMAP *map2)
map1->n_bits==map2->n_bits);
end= map1->last_word_ptr;
*map1->last_word_ptr &= ~map1->last_word_mask;
*map2->last_word_ptr &= ~map2->last_word_mask;
while (m1 <= end)
{
if ((*m1++) & (*m2++))
return 1;
}
return 0;
for (; m1 < end; m1++, m2++)
if (*m1 & *m2)
return TRUE;
if ((*map1->last_word_ptr & ~map1->last_word_mask) &
(*map2->last_word_ptr & ~map2->last_word_mask))
return TRUE;
return FALSE;
}
@ -366,15 +424,17 @@ void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2)
DBUG_ASSERT(map->bitmap && map2->bitmap);
end= to+min(len,len2);
*map2->last_word_ptr&= ~map2->last_word_mask; /*Clear last bits in map2*/
while (to < end)
*to++ &= *from++;
for (; to < end; to++, from++)
*to &= *from;
if (len >= len2)
map->bitmap[len2 - 1] &= ~map2->last_word_mask;
if (len2 < len)
{
end+=len-len2;
while (to < end)
*to++=0;
for (; to < end; to++)
*to= 0;
}
}
@ -405,8 +465,8 @@ void bitmap_set_above(MY_BITMAP *map, uint from_byte, uint use_bit)
uchar *to= (uchar *)map->bitmap + from_byte;
uchar *end= (uchar *)map->bitmap + (map->n_bits+7)/8;
while (to < end)
*to++= use_byte;
for (; to < end; to++)
*to= use_byte;
}
@ -415,59 +475,60 @@ void bitmap_subtract(MY_BITMAP *map, const MY_BITMAP *map2)
my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end;
DBUG_ASSERT(map->bitmap && map2->bitmap &&
map->n_bits==map2->n_bits);
end= map->last_word_ptr;
while (to <= end)
*to++ &= ~(*from++);
for (; to <= end; to++, from++)
*to &= ~(*from);
}
void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2)
{
my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end;
DBUG_ASSERT(map->bitmap && map2->bitmap &&
map->n_bits==map2->n_bits);
end= map->last_word_ptr;
while (to <= end)
*to++ |= *from++;
for (; to <= end; to++, from++)
*to |= *from;
}
void bitmap_xor(MY_BITMAP *map, const MY_BITMAP *map2)
{
my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end= map->last_word_ptr;
my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end;
DBUG_ASSERT(map->bitmap && map2->bitmap &&
map->n_bits==map2->n_bits);
while (to <= end)
*to++ ^= *from++;
end= map->last_word_ptr;
for (; to <= end; to++, from++)
*to ^= *from;
}
void bitmap_invert(MY_BITMAP *map)
{
my_bitmap_map *to= map->bitmap, *end;
DBUG_ASSERT(map->bitmap);
end= map->last_word_ptr;
while (to <= end)
*to++ ^= 0xFFFFFFFF;
for (; to <= end; to++)
*to ^= 0xFFFFFFFF;
}
uint bitmap_bits_set(const MY_BITMAP *map)
{
uchar *m= (uchar*)map->bitmap;
uchar *end= m + no_bytes_in_map(map);
my_bitmap_map *data_ptr= map->bitmap;
my_bitmap_map *end= map->last_word_ptr;
uint res= 0;
DBUG_ASSERT(map->bitmap);
*map->last_word_ptr&= ~map->last_word_mask; /*Reset last bits to zero*/
while (m < end)
res+= my_count_bits_ushort(*m++);
for (; data_ptr < end; data_ptr++)
res+= my_count_bits_uint32(*data_ptr);
/*Reset last bits to zero*/
res+= my_count_bits_uint32(*map->last_word_ptr & ~map->last_word_mask);
return res;
}
@ -475,76 +536,44 @@ uint bitmap_bits_set(const MY_BITMAP *map)
void bitmap_copy(MY_BITMAP *map, const MY_BITMAP *map2)
{
my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end;
DBUG_ASSERT(map->bitmap && map2->bitmap &&
map->n_bits==map2->n_bits);
end= map->last_word_ptr;
while (to <= end)
*to++ = *from++;
for (; to <= end; to++, from++)
*to = *from;
}
uint bitmap_get_first_set(const MY_BITMAP *map)
{
uchar *byte_ptr;
uint i,j,k;
uint word_pos;
my_bitmap_map *data_ptr, *end= map->last_word_ptr;
DBUG_ASSERT(map->bitmap);
data_ptr= map->bitmap;
*map->last_word_ptr &= ~map->last_word_mask;
for (i=0; data_ptr <= end; data_ptr++, i++)
{
for (word_pos=0; data_ptr < end; data_ptr++, word_pos++)
if (*data_ptr)
{
byte_ptr= (uchar*)data_ptr;
for (j=0; ; j++, byte_ptr++)
{
if (*byte_ptr)
{
for (k=0; ; k++)
{
if (*byte_ptr & (1 << k))
return (i*32) + (j*8) + k;
}
}
}
}
}
return MY_BIT_NONE;
return get_first_set(*data_ptr, word_pos);
return get_first_set(*map->last_word_ptr & ~map->last_word_mask, word_pos);
}
uint bitmap_get_first(const MY_BITMAP *map)
{
uchar *byte_ptr;
uint i,j,k;
uint word_pos;
my_bitmap_map *data_ptr, *end= map->last_word_ptr;
DBUG_ASSERT(map->bitmap);
data_ptr= map->bitmap;
*map->last_word_ptr|= map->last_word_mask;
for (i=0; data_ptr <= end; data_ptr++, i++)
{
for (word_pos=0; data_ptr < end; data_ptr++, word_pos++)
if (*data_ptr != 0xFFFFFFFF)
{
byte_ptr= (uchar*)data_ptr;
for (j=0; ; j++, byte_ptr++)
{
if (*byte_ptr != 0xFF)
{
for (k=0; ; k++)
{
if (!(*byte_ptr & (1 << k)))
return (i*32) + (j*8) + k;
}
}
}
}
}
return MY_BIT_NONE;
return get_first_not_set(*data_ptr, word_pos);
return get_first_not_set(*map->last_word_ptr | map->last_word_mask, word_pos);
}
@ -752,375 +781,3 @@ void bitmap_lock_flip_bit(MY_BITMAP *map, uint bitmap_bit)
bitmap_unlock(map);
}
#endif
#ifdef MAIN
uint get_rand_bit(uint bitsize)
{
return (rand() % bitsize);
}
bool test_set_get_clear_bit(MY_BITMAP *map, uint bitsize)
{
uint i, test_bit;
uint no_loops= bitsize > 128 ? 128 : bitsize;
for (i=0; i < no_loops; i++)
{
test_bit= get_rand_bit(bitsize);
bitmap_set_bit(map, test_bit);
if (!bitmap_is_set(map, test_bit))
goto error1;
bitmap_clear_bit(map, test_bit);
if (bitmap_is_set(map, test_bit))
goto error2;
}
return FALSE;
error1:
printf("Error in set bit, bit %u, bitsize = %u", test_bit, bitsize);
return TRUE;
error2:
printf("Error in clear bit, bit %u, bitsize = %u", test_bit, bitsize);
return TRUE;
}
bool test_flip_bit(MY_BITMAP *map, uint bitsize)
{
uint i, test_bit;
uint no_loops= bitsize > 128 ? 128 : bitsize;
for (i=0; i < no_loops; i++)
{
test_bit= get_rand_bit(bitsize);
bitmap_flip_bit(map, test_bit);
if (!bitmap_is_set(map, test_bit))
goto error1;
bitmap_flip_bit(map, test_bit);
if (bitmap_is_set(map, test_bit))
goto error2;
}
return FALSE;
error1:
printf("Error in flip bit 1, bit %u, bitsize = %u", test_bit, bitsize);
return TRUE;
error2:
printf("Error in flip bit 2, bit %u, bitsize = %u", test_bit, bitsize);
return TRUE;
}
bool test_operators(MY_BITMAP *map __attribute__((unused)),
uint bitsize __attribute__((unused)))
{
return FALSE;
}
bool test_get_all_bits(MY_BITMAP *map, uint bitsize)
{
uint i;
bitmap_set_all(map);
if (!bitmap_is_set_all(map))
goto error1;
if (!bitmap_is_prefix(map, bitsize))
goto error5;
bitmap_clear_all(map);
if (!bitmap_is_clear_all(map))
goto error2;
if (!bitmap_is_prefix(map, 0))
goto error6;
for (i=0; i<bitsize;i++)
bitmap_set_bit(map, i);
if (!bitmap_is_set_all(map))
goto error3;
for (i=0; i<bitsize;i++)
bitmap_clear_bit(map, i);
if (!bitmap_is_clear_all(map))
goto error4;
return FALSE;
error1:
printf("Error in set_all, bitsize = %u", bitsize);
return TRUE;
error2:
printf("Error in clear_all, bitsize = %u", bitsize);
return TRUE;
error3:
printf("Error in bitmap_is_set_all, bitsize = %u", bitsize);
return TRUE;
error4:
printf("Error in bitmap_is_clear_all, bitsize = %u", bitsize);
return TRUE;
error5:
printf("Error in set_all through set_prefix, bitsize = %u", bitsize);
return TRUE;
error6:
printf("Error in clear_all through set_prefix, bitsize = %u", bitsize);
return TRUE;
}
bool test_compare_operators(MY_BITMAP *map, uint bitsize)
{
uint i, j, test_bit1, test_bit2, test_bit3,test_bit4;
uint no_loops= bitsize > 128 ? 128 : bitsize;
MY_BITMAP map2_obj, map3_obj;
MY_BITMAP *map2= &map2_obj, *map3= &map3_obj;
my_bitmap_map map2buf[1024];
my_bitmap_map map3buf[1024];
bitmap_init(&map2_obj, map2buf, bitsize, FALSE);
bitmap_init(&map3_obj, map3buf, bitsize, FALSE);
bitmap_clear_all(map2);
bitmap_clear_all(map3);
for (i=0; i < no_loops; i++)
{
test_bit1=get_rand_bit(bitsize);
bitmap_set_prefix(map, test_bit1);
test_bit2=get_rand_bit(bitsize);
bitmap_set_prefix(map2, test_bit2);
bitmap_intersect(map, map2);
test_bit3= test_bit2 < test_bit1 ? test_bit2 : test_bit1;
bitmap_set_prefix(map3, test_bit3);
if (!bitmap_cmp(map, map3))
goto error1;
bitmap_clear_all(map);
bitmap_clear_all(map2);
bitmap_clear_all(map3);
test_bit1=get_rand_bit(bitsize);
test_bit2=get_rand_bit(bitsize);
test_bit3=get_rand_bit(bitsize);
bitmap_set_prefix(map, test_bit1);
bitmap_set_prefix(map2, test_bit2);
test_bit3= test_bit2 > test_bit1 ? test_bit2 : test_bit1;
bitmap_set_prefix(map3, test_bit3);
bitmap_union(map, map2);
if (!bitmap_cmp(map, map3))
goto error2;
bitmap_clear_all(map);
bitmap_clear_all(map2);
bitmap_clear_all(map3);
test_bit1=get_rand_bit(bitsize);
test_bit2=get_rand_bit(bitsize);
test_bit3=get_rand_bit(bitsize);
bitmap_set_prefix(map, test_bit1);
bitmap_set_prefix(map2, test_bit2);
bitmap_xor(map, map2);
test_bit3= test_bit2 > test_bit1 ? test_bit2 : test_bit1;
test_bit4= test_bit2 < test_bit1 ? test_bit2 : test_bit1;
bitmap_set_prefix(map3, test_bit3);
for (j=0; j < test_bit4; j++)
bitmap_clear_bit(map3, j);
if (!bitmap_cmp(map, map3))
goto error3;
bitmap_clear_all(map);
bitmap_clear_all(map2);
bitmap_clear_all(map3);
test_bit1=get_rand_bit(bitsize);
test_bit2=get_rand_bit(bitsize);
test_bit3=get_rand_bit(bitsize);
bitmap_set_prefix(map, test_bit1);
bitmap_set_prefix(map2, test_bit2);
bitmap_subtract(map, map2);
if (test_bit2 < test_bit1)
{
bitmap_set_prefix(map3, test_bit1);
for (j=0; j < test_bit2; j++)
bitmap_clear_bit(map3, j);
}
if (!bitmap_cmp(map, map3))
goto error4;
bitmap_clear_all(map);
bitmap_clear_all(map2);
bitmap_clear_all(map3);
test_bit1=get_rand_bit(bitsize);
bitmap_set_prefix(map, test_bit1);
bitmap_invert(map);
bitmap_set_all(map3);
for (j=0; j < test_bit1; j++)
bitmap_clear_bit(map3, j);
if (!bitmap_cmp(map, map3))
goto error5;
bitmap_clear_all(map);
bitmap_clear_all(map3);
}
return FALSE;
error1:
printf("intersect error bitsize=%u,size1=%u,size2=%u", bitsize,
test_bit1,test_bit2);
return TRUE;
error2:
printf("union error bitsize=%u,size1=%u,size2=%u", bitsize,
test_bit1,test_bit2);
return TRUE;
error3:
printf("xor error bitsize=%u,size1=%u,size2=%u", bitsize,
test_bit1,test_bit2);
return TRUE;
error4:
printf("subtract error bitsize=%u,size1=%u,size2=%u", bitsize,
test_bit1,test_bit2);
return TRUE;
error5:
printf("invert error bitsize=%u,size=%u", bitsize,
test_bit1);
return TRUE;
}
bool test_count_bits_set(MY_BITMAP *map, uint bitsize)
{
uint i, bit_count=0, test_bit;
uint no_loops= bitsize > 128 ? 128 : bitsize;
for (i=0; i < no_loops; i++)
{
test_bit=get_rand_bit(bitsize);
if (!bitmap_is_set(map, test_bit))
{
bitmap_set_bit(map, test_bit);
bit_count++;
}
}
if (bit_count==0 && bitsize > 0)
goto error1;
if (bitmap_bits_set(map) != bit_count)
goto error2;
return FALSE;
error1:
printf("No bits set bitsize = %u", bitsize);
return TRUE;
error2:
printf("Wrong count of bits set, bitsize = %u", bitsize);
return TRUE;
}
bool test_get_first_bit(MY_BITMAP *map, uint bitsize)
{
uint i, test_bit;
uint no_loops= bitsize > 128 ? 128 : bitsize;
for (i=0; i < no_loops; i++)
{
test_bit=get_rand_bit(bitsize);
bitmap_set_bit(map, test_bit);
if (bitmap_get_first_set(map) != test_bit)
goto error1;
bitmap_set_all(map);
bitmap_clear_bit(map, test_bit);
if (bitmap_get_first(map) != test_bit)
goto error2;
bitmap_clear_all(map);
}
return FALSE;
error1:
printf("get_first_set error bitsize=%u,prefix_size=%u",bitsize,test_bit);
return TRUE;
error2:
printf("get_first error bitsize= %u, prefix_size= %u",bitsize,test_bit);
return TRUE;
}
bool test_get_next_bit(MY_BITMAP *map, uint bitsize)
{
uint i, j, test_bit;
uint no_loops= bitsize > 128 ? 128 : bitsize;
for (i=0; i < no_loops; i++)
{
test_bit=get_rand_bit(bitsize);
for (j=0; j < test_bit; j++)
bitmap_set_next(map);
if (!bitmap_is_prefix(map, test_bit))
goto error1;
bitmap_clear_all(map);
}
return FALSE;
error1:
printf("get_next error bitsize= %u, prefix_size= %u", bitsize,test_bit);
return TRUE;
}
bool test_prefix(MY_BITMAP *map, uint bitsize)
{
uint i, j, test_bit;
uint no_loops= bitsize > 128 ? 128 : bitsize;
for (i=0; i < no_loops; i++)
{
test_bit=get_rand_bit(bitsize);
bitmap_set_prefix(map, test_bit);
if (!bitmap_is_prefix(map, test_bit))
goto error1;
bitmap_clear_all(map);
for (j=0; j < test_bit; j++)
bitmap_set_bit(map, j);
if (!bitmap_is_prefix(map, test_bit))
goto error2;
bitmap_set_all(map);
for (j=bitsize - 1; ~(j-test_bit); j--)
bitmap_clear_bit(map, j);
if (!bitmap_is_prefix(map, test_bit))
goto error3;
bitmap_clear_all(map);
}
return FALSE;
error1:
printf("prefix1 error bitsize = %u, prefix_size = %u", bitsize,test_bit);
return TRUE;
error2:
printf("prefix2 error bitsize = %u, prefix_size = %u", bitsize,test_bit);
return TRUE;
error3:
printf("prefix3 error bitsize = %u, prefix_size = %u", bitsize,test_bit);
return TRUE;
}
bool do_test(uint bitsize)
{
MY_BITMAP map;
my_bitmap_map buf[1024];
if (bitmap_init(&map, buf, bitsize, FALSE))
{
printf("init error for bitsize %d", bitsize);
goto error;
}
if (test_set_get_clear_bit(&map,bitsize))
goto error;
bitmap_clear_all(&map);
if (test_flip_bit(&map,bitsize))
goto error;
bitmap_clear_all(&map);
if (test_operators(&map,bitsize))
goto error;
bitmap_clear_all(&map);
if (test_get_all_bits(&map, bitsize))
goto error;
bitmap_clear_all(&map);
if (test_compare_operators(&map,bitsize))
goto error;
bitmap_clear_all(&map);
if (test_count_bits_set(&map,bitsize))
goto error;
bitmap_clear_all(&map);
if (test_get_first_bit(&map,bitsize))
goto error;
bitmap_clear_all(&map);
if (test_get_next_bit(&map,bitsize))
goto error;
if (test_prefix(&map,bitsize))
goto error;
return FALSE;
error:
printf("\n");
return TRUE;
}
int main()
{
int i;
for (i= 1; i < 4096; i++)
{
printf("Start test for bitsize=%u\n",i);
if (do_test(i))
return -1;
}
printf("OK\n");
return 0;
}
/*
In directory mysys:
make test_bitmap
will build the bitmap tests and ./test_bitmap will execute it
*/
#endif

View File

@ -1019,7 +1019,11 @@ void reset_mqh(LEX_USER *lu, bool get_them);
bool check_mqh(THD *thd, uint check_command);
void time_out_user_resource_limits(THD *thd, USER_CONN *uc);
void decrease_user_connections(USER_CONN *uc);
void thd_init_client_charset(THD *thd, uint cs_number);
bool thd_init_client_charset(THD *thd, uint cs_number);
inline bool is_supported_parser_charset(CHARSET_INFO *cs)
{
return test(cs->mbminlen == 1);
}
bool setup_connection_thread_globals(THD *thd);
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);

View File

@ -1828,7 +1828,7 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
}
var->save_result.ulong_value= ((ulong)
find_set(enum_names, res->c_ptr(),
find_set(enum_names, res->c_ptr_safe(),
res->length(),
NULL,
&error, &error_len,
@ -2187,7 +2187,7 @@ bool sys_var_character_set_client::check(THD *thd, set_var *var)
if (sys_var_character_set_sv::check(thd, var))
return 1;
/* Currently, UCS-2 cannot be used as a client character set */
if (var->save_result.charset->mbminlen > 1)
if (!is_supported_parser_charset(var->save_result.charset))
{
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name,
var->save_result.charset->csname);
@ -2941,7 +2941,7 @@ bool sys_var_thd_lc_time_names::check(THD *thd, set_var *var)
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
return 1;
}
const char *locale_str= res->c_ptr();
const char *locale_str= res->c_ptr_safe();
if (!(locale_match= my_locale_by_name(locale_str)))
{
my_printf_error(ER_UNKNOWN_ERROR,

View File

@ -582,8 +582,23 @@ void reset_mqh(LEX_USER *lu, bool get_them= 0)
}
void thd_init_client_charset(THD *thd, uint cs_number)
/**
Set thread character set variables from the given ID
@param thd thread handle
@param cs_number character set and collation ID
@retval 0 OK; character_set_client, collation_connection and
character_set_results are set to the new value,
or to the default global values.
@retval 1 error, e.g. the given ID is not supported by parser.
Corresponding SQL error is sent.
*/
bool thd_init_client_charset(THD *thd, uint cs_number)
{
CHARSET_INFO *cs;
/*
Use server character set and collation if
- opt_character_set_client_handshake is not set
@ -592,10 +607,10 @@ void thd_init_client_charset(THD *thd, uint cs_number)
- client character set doesn't exists in server
*/
if (!opt_character_set_client_handshake ||
!(thd->variables.character_set_client= get_charset(cs_number, MYF(0))) ||
!(cs= get_charset(cs_number, MYF(0))) ||
!my_strcasecmp(&my_charset_latin1,
global_system_variables.character_set_client->name,
thd->variables.character_set_client->name))
cs->name))
{
thd->variables.character_set_client=
global_system_variables.character_set_client;
@ -606,10 +621,18 @@ void thd_init_client_charset(THD *thd, uint cs_number)
}
else
{
if (!is_supported_parser_charset(cs))
{
/* Disallow non-supported parser character sets: UCS2, UTF16, UTF32 */
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client",
cs->csname);
return true;
}
thd->variables.character_set_results=
thd->variables.collation_connection=
thd->variables.character_set_client;
thd->variables.character_set_client= cs;
}
return false;
}
@ -782,7 +805,8 @@ static int check_connection(THD *thd)
thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
thd->max_client_packet_length= uint4korr(net->read_pos+4);
DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
thd_init_client_charset(thd, (uint) net->read_pos[8]);
if (thd_init_client_charset(thd, (uint) net->read_pos[8]))
return 1;
thd->update_charset();
end= (char*) net->read_pos+32;
}

View File

@ -1153,13 +1153,22 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (ptr < packet_end)
{
CHARSET_INFO *cs;
if (ptr + 2 > packet_end)
{
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
break;
}
cs_number= uint2korr(ptr);
if ((cs_number= uint2korr(ptr)) &&
(cs= get_charset(cs_number, MYF(0))) &&
!is_supported_parser_charset(cs))
{
/* Disallow non-supported parser character sets: UCS2, UTF16, UTF32 */
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client",
cs->csname);
break;
}
}
/* Convert database name to utf8 */
@ -1205,7 +1214,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (cs_number)
{
thd_init_client_charset(thd, cs_number);
/*
We have checked charset earlier,
so thd_init_client_charset cannot fail.
*/
DBUG_ASSERT(!thd_init_client_charset(thd, cs_number));
thd->update_charset();
}
}

View File

@ -278,48 +278,53 @@ bool handle_select(THD *thd, LEX *lex, select_result *result,
}
/*
/**
Fix fields referenced from inner selects.
SYNOPSIS
fix_inner_refs()
thd Thread handle
all_fields List of all fields used in select
select Current select
ref_pointer_array Array of references to Items used in current select
group_list GROUP BY list (is NULL by default)
@param thd Thread handle
@param all_fields List of all fields used in select
@param select Current select
@param ref_pointer_array Array of references to Items used in current select
@param group_list GROUP BY list (is NULL by default)
DESCRIPTION
The function serves 3 purposes - adds fields referenced from inner
selects to the current select list, resolves which class to use
to access referenced item (Item_ref of Item_direct_ref) and fixes
references (Item_ref objects) to these fields.
@details
The function serves 3 purposes
If a field isn't already in the select list and the ref_pointer_array
- adds fields referenced from inner query blocks to the current select list
- Decides which class to use to reference the items (Item_ref or
Item_direct_ref)
- fixes references (Item_ref objects) to these fields.
If a field isn't already on the select list and the ref_pointer_array
is provided then it is added to the all_fields list and the pointer to
it is saved in the ref_pointer_array.
The class to access the outer field is determined by the following rules:
1. If the outer field isn't used under an aggregate function
then the Item_ref class should be used.
2. If the outer field is used under an aggregate function and this
function is aggregated in the select where the outer field was
resolved or in some more inner select then the Item_direct_ref
class should be used.
Also it should be used if we are grouping by a subquery containing
the outer field.
-#. If the outer field isn't used under an aggregate function then the
Item_ref class should be used.
-#. If the outer field is used under an aggregate function and this
function is, in turn, aggregated in the query block where the outer
field was resolved or some query nested therein, then the
Item_direct_ref class should be used. Also it should be used if we are
grouping by a subquery containing the outer field.
The resolution is done here and not at the fix_fields() stage as
it can be done only after sum functions are fixed and pulled up to
selects where they are have to be aggregated.
it can be done only after aggregate functions are fixed and pulled up to
selects where they are to be aggregated.
When the class is chosen it substitutes the original field in the
Item_outer_ref object.
After this we proceed with fixing references (Item_outer_ref objects) to
this field from inner subqueries.
RETURN
TRUE an error occured
FALSE ok
@return Status
@retval true An error occured.
@retval false OK.
*/
bool
@ -327,12 +332,11 @@ fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
Item **ref_pointer_array, ORDER *group_list)
{
Item_outer_ref *ref;
bool res= FALSE;
bool direct_ref= FALSE;
List_iterator<Item_outer_ref> ref_it(select->inner_refs_list);
while ((ref= ref_it++))
{
bool direct_ref= false;
Item *item= ref->outer_ref;
Item **item_ref= ref->ref;
Item_ref *new_ref;
@ -404,7 +408,7 @@ fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
return TRUE;
thd->used_tables|= item->used_tables();
}
return res;
return false;
}
/**

View File

@ -106,6 +106,9 @@ public:
inline const char *ptr() const { return Ptr; }
inline char *c_ptr()
{
DBUG_ASSERT(!alloced || !Ptr || !Alloced_length ||
(Alloced_length >= (str_length + 1)));
if (!Ptr || Ptr[str_length]) /* Should be safe */
(void) realloc(str_length);
return Ptr;

View File

@ -1,3 +1,15 @@
2011-02-15 The InnoDB Team
* sync/sync0rw.c, innodb_bug59307.test:
Bug#59307 Valgrind: uninitialized value in
rw_lock_set_writer_id_and_recursion_flag()
2011-02-14 The InnoDB Team
* handler/handler0alter.cc:
Bug#59749 Enabling concurrent reads while creating non-primary
unique index gives failures
2011-01-31 The InnoDB Team
* btr/btr0cur.c, include/row0upd.h,

View File

@ -42,6 +42,560 @@ Created 6/2/1994 Heikki Tuuri
#include "ibuf0ibuf.h"
#include "trx0trx.h"
#ifdef UNIV_BLOB_DEBUG
# include "srv0srv.h"
# include "ut0rbt.h"
/** TRUE when messages about index->blobs modification are enabled. */
static ibool btr_blob_dbg_msg;
/** Issue a message about an operation on index->blobs.
@param op operation
@param b the entry being subjected to the operation
@param ctx the context of the operation */
#define btr_blob_dbg_msg_issue(op, b, ctx) \
fprintf(stderr, op " %u:%u:%u->%u %s(%u,%u,%u)\n", \
(b)->ref_page_no, (b)->ref_heap_no, \
(b)->ref_field_no, (b)->blob_page_no, ctx, \
(b)->owner, (b)->always_owner, (b)->del)
/** Insert to index->blobs a reference to an off-page column.
@param index the index tree
@param b the reference
@param ctx context (for logging) */
UNIV_INTERN
void
btr_blob_dbg_rbt_insert(
/*====================*/
dict_index_t* index, /*!< in/out: index tree */
const btr_blob_dbg_t* b, /*!< in: the reference */
const char* ctx) /*!< in: context (for logging) */
{
if (btr_blob_dbg_msg) {
btr_blob_dbg_msg_issue("insert", b, ctx);
}
mutex_enter(&index->blobs_mutex);
rbt_insert(index->blobs, b, b);
mutex_exit(&index->blobs_mutex);
}
/** Remove from index->blobs a reference to an off-page column.
@param index the index tree
@param b the reference
@param ctx context (for logging) */
UNIV_INTERN
void
btr_blob_dbg_rbt_delete(
/*====================*/
dict_index_t* index, /*!< in/out: index tree */
const btr_blob_dbg_t* b, /*!< in: the reference */
const char* ctx) /*!< in: context (for logging) */
{
if (btr_blob_dbg_msg) {
btr_blob_dbg_msg_issue("delete", b, ctx);
}
mutex_enter(&index->blobs_mutex);
ut_a(rbt_delete(index->blobs, b));
mutex_exit(&index->blobs_mutex);
}
/**************************************************************//**
Comparator for items (btr_blob_dbg_t) in index->blobs.
The key in index->blobs is (ref_page_no, ref_heap_no, ref_field_no).
@return negative, 0 or positive if *a<*b, *a=*b, *a>*b */
static
int
btr_blob_dbg_cmp(
/*=============*/
const void* a, /*!< in: first btr_blob_dbg_t to compare */
const void* b) /*!< in: second btr_blob_dbg_t to compare */
{
const btr_blob_dbg_t* aa = a;
const btr_blob_dbg_t* bb = b;
ut_ad(aa != NULL);
ut_ad(bb != NULL);
if (aa->ref_page_no != bb->ref_page_no) {
return(aa->ref_page_no < bb->ref_page_no ? -1 : 1);
}
if (aa->ref_heap_no != bb->ref_heap_no) {
return(aa->ref_heap_no < bb->ref_heap_no ? -1 : 1);
}
if (aa->ref_field_no != bb->ref_field_no) {
return(aa->ref_field_no < bb->ref_field_no ? -1 : 1);
}
return(0);
}
/**************************************************************//**
Add a reference to an off-page column to the index->blobs map. */
UNIV_INTERN
void
btr_blob_dbg_add_blob(
/*==================*/
const rec_t* rec, /*!< in: clustered index record */
ulint field_no, /*!< in: off-page column number */
ulint page_no, /*!< in: start page of the column */
dict_index_t* index, /*!< in/out: index tree */
const char* ctx) /*!< in: context (for logging) */
{
btr_blob_dbg_t b;
const page_t* page = page_align(rec);
ut_a(index->blobs);
b.blob_page_no = page_no;
b.ref_page_no = page_get_page_no(page);
b.ref_heap_no = page_rec_get_heap_no(rec);
b.ref_field_no = field_no;
ut_a(b.ref_field_no >= index->n_uniq);
b.always_owner = b.owner = TRUE;
b.del = FALSE;
ut_a(!rec_get_deleted_flag(rec, page_is_comp(page)));
btr_blob_dbg_rbt_insert(index, &b, ctx);
}
/**************************************************************//**
Add to index->blobs any references to off-page columns from a record.
@return number of references added */
UNIV_INTERN
ulint
btr_blob_dbg_add_rec(
/*=================*/
const rec_t* rec, /*!< in: record */
dict_index_t* index, /*!< in/out: index */
const ulint* offsets,/*!< in: offsets */
const char* ctx) /*!< in: context (for logging) */
{
ulint count = 0;
ulint i;
btr_blob_dbg_t b;
ibool del;
ut_ad(rec_offs_validate(rec, index, offsets));
if (!rec_offs_any_extern(offsets)) {
return(0);
}
b.ref_page_no = page_get_page_no(page_align(rec));
b.ref_heap_no = page_rec_get_heap_no(rec);
del = (rec_get_deleted_flag(rec, rec_offs_comp(offsets)) != 0);
for (i = 0; i < rec_offs_n_fields(offsets); i++) {
if (rec_offs_nth_extern(offsets, i)) {
ulint len;
const byte* field_ref = rec_get_nth_field(
rec, offsets, i, &len);
ut_a(len != UNIV_SQL_NULL);
ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
field_ref += len - BTR_EXTERN_FIELD_REF_SIZE;
if (!memcmp(field_ref, field_ref_zero,
BTR_EXTERN_FIELD_REF_SIZE)) {
/* the column has not been stored yet */
continue;
}
b.ref_field_no = i;
b.blob_page_no = mach_read_from_4(
field_ref + BTR_EXTERN_PAGE_NO);
ut_a(b.ref_field_no >= index->n_uniq);
b.always_owner = b.owner
= !(field_ref[BTR_EXTERN_LEN]
& BTR_EXTERN_OWNER_FLAG);
b.del = del;
btr_blob_dbg_rbt_insert(index, &b, ctx);
count++;
}
}
return(count);
}
/**************************************************************//**
Display the references to off-page columns.
This function is to be called from a debugger,
for example when a breakpoint on ut_dbg_assertion_failed is hit. */
UNIV_INTERN
void
btr_blob_dbg_print(
/*===============*/
const dict_index_t* index) /*!< in: index tree */
{
const ib_rbt_node_t* node;
if (!index->blobs) {
return;
}
/* We intentionally do not acquire index->blobs_mutex here.
This function is to be called from a debugger, and the caller
should make sure that the index->blobs_mutex is held. */
for (node = rbt_first(index->blobs);
node != NULL; node = rbt_next(index->blobs, node)) {
const btr_blob_dbg_t* b
= rbt_value(btr_blob_dbg_t, node);
fprintf(stderr, "%u:%u:%u->%u%s%s%s\n",
b->ref_page_no, b->ref_heap_no, b->ref_field_no,
b->blob_page_no,
b->owner ? "" : "(disowned)",
b->always_owner ? "" : "(has disowned)",
b->del ? "(deleted)" : "");
}
}
/**************************************************************//**
Remove from index->blobs any references to off-page columns from a record.
@return number of references removed */
UNIV_INTERN
ulint
btr_blob_dbg_remove_rec(
/*====================*/
const rec_t* rec, /*!< in: record */
dict_index_t* index, /*!< in/out: index */
const ulint* offsets,/*!< in: offsets */
const char* ctx) /*!< in: context (for logging) */
{
ulint i;
ulint count = 0;
btr_blob_dbg_t b;
ut_ad(rec_offs_validate(rec, index, offsets));
if (!rec_offs_any_extern(offsets)) {
return(0);
}
b.ref_page_no = page_get_page_no(page_align(rec));
b.ref_heap_no = page_rec_get_heap_no(rec);
for (i = 0; i < rec_offs_n_fields(offsets); i++) {
if (rec_offs_nth_extern(offsets, i)) {
ulint len;
const byte* field_ref = rec_get_nth_field(
rec, offsets, i, &len);
ut_a(len != UNIV_SQL_NULL);
ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
field_ref += len - BTR_EXTERN_FIELD_REF_SIZE;
b.ref_field_no = i;
b.blob_page_no = mach_read_from_4(
field_ref + BTR_EXTERN_PAGE_NO);
switch (b.blob_page_no) {
case 0:
/* The column has not been stored yet.
The BLOB pointer must be all zero.
There cannot be a BLOB starting at
page 0, because page 0 is reserved for
the tablespace header. */
ut_a(!memcmp(field_ref, field_ref_zero,
BTR_EXTERN_FIELD_REF_SIZE));
/* fall through */
case FIL_NULL:
/* the column has been freed already */
continue;
}
btr_blob_dbg_rbt_delete(index, &b, ctx);
count++;
}
}
return(count);
}
/**************************************************************//**
Check that there are no references to off-page columns from or to
the given page. Invoked when freeing or clearing a page.
@return TRUE when no orphan references exist */
UNIV_INTERN
ibool
btr_blob_dbg_is_empty(
/*==================*/
dict_index_t* index, /*!< in: index */
ulint page_no) /*!< in: page number */
{
const ib_rbt_node_t* node;
ibool success = TRUE;
if (!index->blobs) {
return(success);
}
mutex_enter(&index->blobs_mutex);
for (node = rbt_first(index->blobs);
node != NULL; node = rbt_next(index->blobs, node)) {
const btr_blob_dbg_t* b
= rbt_value(btr_blob_dbg_t, node);
if (b->ref_page_no != page_no && b->blob_page_no != page_no) {
continue;
}
fprintf(stderr,
"InnoDB: orphan BLOB ref%s%s%s %u:%u:%u->%u\n",
b->owner ? "" : "(disowned)",
b->always_owner ? "" : "(has disowned)",
b->del ? "(deleted)" : "",
b->ref_page_no, b->ref_heap_no, b->ref_field_no,
b->blob_page_no);
if (b->blob_page_no != page_no || b->owner || !b->del) {
success = FALSE;
}
}
mutex_exit(&index->blobs_mutex);
return(success);
}
/**************************************************************//**
Count and process all references to off-page columns on a page.
@return number of references processed */
UNIV_INTERN
ulint
btr_blob_dbg_op(
/*============*/
const page_t* page, /*!< in: B-tree leaf page */
const rec_t* rec, /*!< in: record to start from
(NULL to process the whole page) */
dict_index_t* index, /*!< in/out: index */
const char* ctx, /*!< in: context (for logging) */
const btr_blob_dbg_op_f op) /*!< in: operation on records */
{
ulint count = 0;
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
rec_offs_init(offsets_);
ut_a(fil_page_get_type(page) == FIL_PAGE_INDEX);
ut_a(!rec || page_align(rec) == page);
if (!index->blobs || !page_is_leaf(page)
|| !dict_index_is_clust(index)) {
return(0);
}
if (rec == NULL) {
rec = page_get_infimum_rec(page);
}
do {
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
count += op(rec, index, offsets, ctx);
rec = page_rec_get_next_const(rec);
} while (!page_rec_is_supremum(rec));
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(count);
}
/**************************************************************//**
Count and add to index->blobs any references to off-page columns
from records on a page.
@return number of references added */
UNIV_INTERN
ulint
btr_blob_dbg_add(
/*=============*/
const page_t* page, /*!< in: rewritten page */
dict_index_t* index, /*!< in/out: index */
const char* ctx) /*!< in: context (for logging) */
{
btr_blob_dbg_assert_empty(index, page_get_page_no(page));
return(btr_blob_dbg_op(page, NULL, index, ctx, btr_blob_dbg_add_rec));
}
/**************************************************************//**
Count and remove from index->blobs any references to off-page columns
from records on a page.
Used when reorganizing a page, before copying the records.
@return number of references removed */
UNIV_INTERN
ulint
btr_blob_dbg_remove(
/*================*/
const page_t* page, /*!< in: b-tree page */
dict_index_t* index, /*!< in/out: index */
const char* ctx) /*!< in: context (for logging) */
{
ulint count;
count = btr_blob_dbg_op(page, NULL, index, ctx,
btr_blob_dbg_remove_rec);
/* Check that no references exist. */
btr_blob_dbg_assert_empty(index, page_get_page_no(page));
return(count);
}
/**************************************************************//**
Restore in index->blobs any references to off-page columns
Used when page reorganize fails due to compressed page overflow. */
UNIV_INTERN
void
btr_blob_dbg_restore(
/*=================*/
const page_t* npage, /*!< in: page that failed to compress */
const page_t* page, /*!< in: copy of original page */
dict_index_t* index, /*!< in/out: index */
const char* ctx) /*!< in: context (for logging) */
{
ulint removed;
ulint added;
ut_a(page_get_page_no(npage) == page_get_page_no(page));
ut_a(page_get_space_id(npage) == page_get_space_id(page));
removed = btr_blob_dbg_remove(npage, index, ctx);
added = btr_blob_dbg_add(page, index, ctx);
ut_a(added == removed);
}
/**************************************************************//**
Modify the 'deleted' flag of a record. */
UNIV_INTERN
void
btr_blob_dbg_set_deleted_flag(
/*==========================*/
const rec_t* rec, /*!< in: record */
dict_index_t* index, /*!< in/out: index */
const ulint* offsets,/*!< in: rec_get_offs(rec, index) */
ibool del) /*!< in: TRUE=deleted, FALSE=exists */
{
const ib_rbt_node_t* node;
btr_blob_dbg_t b;
btr_blob_dbg_t* c;
ulint i;
ut_ad(rec_offs_validate(rec, index, offsets));
ut_a(dict_index_is_clust(index));
ut_a(del == !!del);/* must be FALSE==0 or TRUE==1 */
if (!rec_offs_any_extern(offsets) || !index->blobs) {
return;
}
b.ref_page_no = page_get_page_no(page_align(rec));
b.ref_heap_no = page_rec_get_heap_no(rec);
for (i = 0; i < rec_offs_n_fields(offsets); i++) {
if (rec_offs_nth_extern(offsets, i)) {
ulint len;
const byte* field_ref = rec_get_nth_field(
rec, offsets, i, &len);
ut_a(len != UNIV_SQL_NULL);
ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
field_ref += len - BTR_EXTERN_FIELD_REF_SIZE;
b.ref_field_no = i;
b.blob_page_no = mach_read_from_4(
field_ref + BTR_EXTERN_PAGE_NO);
switch (b.blob_page_no) {
case 0:
ut_a(memcmp(field_ref, field_ref_zero,
BTR_EXTERN_FIELD_REF_SIZE));
/* page number 0 is for the
page allocation bitmap */
case FIL_NULL:
/* the column has been freed already */
ut_error;
}
mutex_enter(&index->blobs_mutex);
node = rbt_lookup(index->blobs, &b);
ut_a(node);
c = rbt_value(btr_blob_dbg_t, node);
/* The flag should be modified. */
c->del = del;
if (btr_blob_dbg_msg) {
b = *c;
mutex_exit(&index->blobs_mutex);
btr_blob_dbg_msg_issue("del_mk", &b, "");
} else {
mutex_exit(&index->blobs_mutex);
}
}
}
}
/**************************************************************//**
Change the ownership of an off-page column. */
UNIV_INTERN
void
btr_blob_dbg_owner(
/*===============*/
const rec_t* rec, /*!< in: record */
dict_index_t* index, /*!< in/out: index */
const ulint* offsets,/*!< in: rec_get_offs(rec, index) */
ulint i, /*!< in: ith field in rec */
ibool own) /*!< in: TRUE=owned, FALSE=disowned */
{
const ib_rbt_node_t* node;
btr_blob_dbg_t b;
const byte* field_ref;
ulint len;
ut_ad(rec_offs_validate(rec, index, offsets));
ut_a(rec_offs_nth_extern(offsets, i));
field_ref = rec_get_nth_field(rec, offsets, i, &len);
ut_a(len != UNIV_SQL_NULL);
ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
field_ref += len - BTR_EXTERN_FIELD_REF_SIZE;
b.ref_page_no = page_get_page_no(page_align(rec));
b.ref_heap_no = page_rec_get_heap_no(rec);
b.ref_field_no = i;
b.owner = !(field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG);
b.blob_page_no = mach_read_from_4(field_ref + BTR_EXTERN_PAGE_NO);
ut_a(b.owner == own);
mutex_enter(&index->blobs_mutex);
node = rbt_lookup(index->blobs, &b);
/* row_ins_clust_index_entry_by_modify() invokes
btr_cur_unmark_extern_fields() also for the newly inserted
references, which are all zero bytes until the columns are stored.
The node lookup must fail if and only if that is the case. */
ut_a(!memcmp(field_ref, field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE)
== !node);
if (node) {
btr_blob_dbg_t* c = rbt_value(btr_blob_dbg_t, node);
/* Some code sets ownership from TRUE to TRUE.
We do not allow changing ownership from FALSE to FALSE. */
ut_a(own || c->owner);
c->owner = own;
if (!own) {
c->always_owner = FALSE;
}
}
mutex_exit(&index->blobs_mutex);
}
#endif /* UNIV_BLOB_DEBUG */
/*
Latching strategy of the InnoDB B-tree
--------------------------------------
@ -296,6 +850,7 @@ btr_page_create(
page_t* page = buf_block_get_frame(block);
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
btr_blob_dbg_assert_empty(index, buf_block_get_page_no(block));
if (UNIV_LIKELY_NULL(page_zip)) {
page_create_zip(block, index, level, mtr);
@ -489,6 +1044,7 @@ btr_page_free_low(
modify clock */
buf_block_modify_clock_inc(block);
btr_blob_dbg_assert_empty(index, buf_block_get_page_no(block));
if (dict_index_is_ibuf(index)) {
@ -773,6 +1329,13 @@ btr_create(
block = buf_page_get(space, zip_size, page_no,
RW_X_LATCH, mtr);
} else {
#ifdef UNIV_BLOB_DEBUG
if ((type & DICT_CLUSTERED) && !index->blobs) {
mutex_create(&index->blobs_mutex, SYNC_ANY_LATCH);
index->blobs = rbt_create(sizeof(btr_blob_dbg_t),
btr_blob_dbg_cmp);
}
#endif /* UNIV_BLOB_DEBUG */
block = fseg_create(space, 0,
PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr);
}
@ -996,6 +1559,7 @@ btr_page_reorganize_low(
block->check_index_page_at_flush = TRUE;
#endif /* !UNIV_HOTBACKUP */
btr_blob_dbg_remove(page, index, "btr_page_reorganize");
/* Recreate the page: note that global data on page (possible
segment headers, next page-field, etc.) is preserved intact */
@ -1024,6 +1588,8 @@ btr_page_reorganize_low(
(!page_zip_compress(page_zip, page, index, NULL))) {
/* Restore the old page and exit. */
btr_blob_dbg_restore(page, temp_page, index,
"btr_page_reorganize_compress_fail");
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
/* Check that the bytes that we skip are identical. */
@ -1157,6 +1723,7 @@ btr_page_empty(
#endif /* UNIV_ZIP_DEBUG */
btr_search_drop_page_hash_index(block);
btr_blob_dbg_remove(page, index, "btr_page_empty");
/* Recreate the page: note that global data on page (possible
segment headers, next page-field, etc.) is preserved intact */
@ -2497,6 +3064,7 @@ btr_lift_page_up(
index);
}
btr_blob_dbg_remove(page, index, "btr_lift_page_up");
lock_update_copy_and_discard(father_block, block);
/* Go upward to root page, decrementing levels by one. */
@ -2758,6 +3326,7 @@ err_exit:
lock_update_merge_right(merge_block, orig_succ, block);
}
btr_blob_dbg_remove(page, index, "btr_compress");
mem_heap_free(heap);
if (!dict_index_is_clust(index) && page_is_leaf(merge_page)) {
@ -2988,6 +3557,8 @@ btr_discard_page(
block);
}
btr_blob_dbg_remove(page, index, "btr_discard_page");
/* Free the file page */
btr_page_free(index, block, mtr);

View File

@ -2572,6 +2572,7 @@ btr_cur_del_mark_set_clust_rec(
page_zip = buf_block_get_page_zip(block);
btr_blob_dbg_set_deleted_flag(rec, index, offsets, val);
btr_rec_set_deleted_flag(rec, page_zip, val);
trx = thr_get_trx(thr);
@ -3595,6 +3596,8 @@ btr_cur_set_ownership_of_extern_field(
} else {
mach_write_to_1(data + local_len + BTR_EXTERN_LEN, byte_val);
}
btr_blob_dbg_owner(rec, index, offsets, i, val);
}
/*******************************************************************//**
@ -4094,6 +4097,11 @@ btr_store_big_rec_extern_fields_func(
}
if (prev_page_no == FIL_NULL) {
btr_blob_dbg_add_blob(
rec, big_rec_vec->fields[i]
.field_no, page_no, index,
"store");
mach_write_to_4(field_ref
+ BTR_EXTERN_SPACE_ID,
space_id);
@ -4169,6 +4177,11 @@ next_zip_page:
MLOG_4BYTES, &mtr);
if (prev_page_no == FIL_NULL) {
btr_blob_dbg_add_blob(
rec, big_rec_vec->fields[i]
.field_no, page_no, index,
"store");
mlog_write_ulint(field_ref
+ BTR_EXTERN_SPACE_ID,
space_id,
@ -4337,6 +4350,37 @@ btr_free_externally_stored_field(
rec_zip_size = 0;
}
#ifdef UNIV_BLOB_DEBUG
if (!(field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG)
&& !((field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_INHERITED_FLAG)
&& (rb_ctx == RB_NORMAL || rb_ctx == RB_RECOVERY))) {
/* This off-page column will be freed.
Check that no references remain. */
btr_blob_dbg_t b;
b.blob_page_no = mach_read_from_4(
field_ref + BTR_EXTERN_PAGE_NO);
if (rec) {
/* Remove the reference from the record to the
BLOB. If the BLOB were not freed, the
reference would be removed when the record is
removed. Freeing the BLOB will overwrite the
BTR_EXTERN_PAGE_NO in the field_ref of the
record with FIL_NULL, which would make the
btr_blob_dbg information inconsistent with the
record. */
b.ref_page_no = page_get_page_no(page_align(rec));
b.ref_heap_no = page_rec_get_heap_no(rec);
b.ref_field_no = i;
btr_blob_dbg_rbt_delete(index, &b, "free");
}
btr_blob_dbg_assert_empty(index, b.blob_page_no);
}
#endif /* UNIV_BLOB_DEBUG */
for (;;) {
#ifdef UNIV_SYNC_DEBUG
buf_block_t* rec_block;

View File

@ -36,6 +36,9 @@ Created 1/8/1996 Heikki Tuuri
#ifndef UNIV_HOTBACKUP
# include "lock0lock.h"
#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_BLOB_DEBUG
# include "ut0rbt.h"
#endif /* UNIV_BLOB_DEBUG */
#define DICT_HEAP_SIZE 100 /*!< initial memory heap size when
creating a table or index object */
@ -316,6 +319,12 @@ dict_mem_index_free(
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
#ifdef UNIV_BLOB_DEBUG
if (index->blobs) {
mutex_free(&index->blobs_mutex);
rbt_free(index->blobs);
}
#endif /* UNIV_BLOB_DEBUG */
mem_heap_free(index->heap);
}

View File

@ -782,10 +782,6 @@ err_exit:
ut_ad(error == DB_SUCCESS);
/* We will need to rebuild index translation table. Set
valid index entry count in the translation table to zero */
share->idx_trans_tbl.index_count = 0;
/* Commit the data dictionary transaction in order to release
the table locks on the system tables. This means that if
MySQL crashes while creating a new primary key inside
@ -911,6 +907,14 @@ error:
}
convert_error:
if (error == DB_SUCCESS) {
/* Build index is successful. We will need to
rebuild index translation table. Reset the
index entry count in the translation table
to zero, so that translation table will be rebuilt */
share->idx_trans_tbl.index_count = 0;
}
error = convert_error_code_to_mysql(error,
innodb_table->flags,
user_thd);

View File

@ -81,6 +81,91 @@ UNIQUE definition on secondary indexes when we decide if we can use
the insert buffer to speed up inserts */
#define BTR_IGNORE_SEC_UNIQUE 2048
#ifdef UNIV_BLOB_DEBUG
# include "ut0rbt.h"
/** An index->blobs entry for keeping track of off-page column references */
struct btr_blob_dbg_struct
{
unsigned blob_page_no:32; /*!< first BLOB page number */
unsigned ref_page_no:32; /*!< referring page number */
unsigned ref_heap_no:16; /*!< referring heap number */
unsigned ref_field_no:10; /*!< referring field number */
unsigned owner:1; /*!< TRUE if BLOB owner */
unsigned always_owner:1; /*!< TRUE if always
has been the BLOB owner;
reset to TRUE on B-tree
page splits and merges */
unsigned del:1; /*!< TRUE if currently
delete-marked */
};
/**************************************************************//**
Add a reference to an off-page column to the index->blobs map. */
UNIV_INTERN
void
btr_blob_dbg_add_blob(
/*==================*/
const rec_t* rec, /*!< in: clustered index record */
ulint field_no, /*!< in: number of off-page column */
ulint page_no, /*!< in: start page of the column */
dict_index_t* index, /*!< in/out: index tree */
const char* ctx) /*!< in: context (for logging) */
__attribute__((nonnull));
/**************************************************************//**
Display the references to off-page columns.
This function is to be called from a debugger,
for example when a breakpoint on ut_dbg_assertion_failed is hit. */
UNIV_INTERN
void
btr_blob_dbg_print(
/*===============*/
const dict_index_t* index) /*!< in: index tree */
__attribute__((nonnull));
/**************************************************************//**
Check that there are no references to off-page columns from or to
the given page. Invoked when freeing or clearing a page.
@return TRUE when no orphan references exist */
UNIV_INTERN
ibool
btr_blob_dbg_is_empty(
/*==================*/
dict_index_t* index, /*!< in: index */
ulint page_no) /*!< in: page number */
__attribute__((nonnull, warn_unused_result));
/**************************************************************//**
Modify the 'deleted' flag of a record. */
UNIV_INTERN
void
btr_blob_dbg_set_deleted_flag(
/*==========================*/
const rec_t* rec, /*!< in: record */
dict_index_t* index, /*!< in/out: index */
const ulint* offsets,/*!< in: rec_get_offs(rec, index) */
ibool del) /*!< in: TRUE=deleted, FALSE=exists */
__attribute__((nonnull));
/**************************************************************//**
Change the ownership of an off-page column. */
UNIV_INTERN
void
btr_blob_dbg_owner(
/*===============*/
const rec_t* rec, /*!< in: record */
dict_index_t* index, /*!< in/out: index */
const ulint* offsets,/*!< in: rec_get_offs(rec, index) */
ulint i, /*!< in: ith field in rec */
ibool own) /*!< in: TRUE=owned, FALSE=disowned */
__attribute__((nonnull));
/** Assert that there are no BLOB references to or from the given page. */
# define btr_blob_dbg_assert_empty(index, page_no) \
ut_a(btr_blob_dbg_is_empty(index, page_no))
#else /* UNIV_BLOB_DEBUG */
# define btr_blob_dbg_add_blob(rec, field_no, page, index, ctx) ((void) 0)
# define btr_blob_dbg_set_deleted_flag(rec, index, offsets, del)((void) 0)
# define btr_blob_dbg_owner(rec, index, offsets, i, val) ((void) 0)
# define btr_blob_dbg_assert_empty(index, page_no) ((void) 0)
#endif /* UNIV_BLOB_DEBUG */
/**************************************************************//**
Gets the root node of a tree and x-latches it.
@return root page, x-latched */

View File

@ -38,6 +38,131 @@ typedef struct btr_cur_struct btr_cur_t;
/** B-tree search information for the adaptive hash index */
typedef struct btr_search_struct btr_search_t;
#ifdef UNIV_BLOB_DEBUG
# include "buf0types.h"
/** An index->blobs entry for keeping track of off-page column references */
typedef struct btr_blob_dbg_struct btr_blob_dbg_t;
/** Insert to index->blobs a reference to an off-page column.
@param index the index tree
@param b the reference
@param ctx context (for logging) */
UNIV_INTERN
void
btr_blob_dbg_rbt_insert(
/*====================*/
dict_index_t* index, /*!< in/out: index tree */
const btr_blob_dbg_t* b, /*!< in: the reference */
const char* ctx) /*!< in: context (for logging) */
__attribute__((nonnull));
/** Remove from index->blobs a reference to an off-page column.
@param index the index tree
@param b the reference
@param ctx context (for logging) */
UNIV_INTERN
void
btr_blob_dbg_rbt_delete(
/*====================*/
dict_index_t* index, /*!< in/out: index tree */
const btr_blob_dbg_t* b, /*!< in: the reference */
const char* ctx) /*!< in: context (for logging) */
__attribute__((nonnull));
/**************************************************************//**
Add to index->blobs any references to off-page columns from a record.
@return number of references added */
UNIV_INTERN
ulint
btr_blob_dbg_add_rec(
/*=================*/
const rec_t* rec, /*!< in: record */
dict_index_t* index, /*!< in/out: index */
const ulint* offsets,/*!< in: offsets */
const char* ctx) /*!< in: context (for logging) */
__attribute__((nonnull));
/**************************************************************//**
Remove from index->blobs any references to off-page columns from a record.
@return number of references removed */
UNIV_INTERN
ulint
btr_blob_dbg_remove_rec(
/*====================*/
const rec_t* rec, /*!< in: record */
dict_index_t* index, /*!< in/out: index */
const ulint* offsets,/*!< in: offsets */
const char* ctx) /*!< in: context (for logging) */
__attribute__((nonnull));
/**************************************************************//**
Count and add to index->blobs any references to off-page columns
from records on a page.
@return number of references added */
UNIV_INTERN
ulint
btr_blob_dbg_add(
/*=============*/
const page_t* page, /*!< in: rewritten page */
dict_index_t* index, /*!< in/out: index */
const char* ctx) /*!< in: context (for logging) */
__attribute__((nonnull));
/**************************************************************//**
Count and remove from index->blobs any references to off-page columns
from records on a page.
Used when reorganizing a page, before copying the records.
@return number of references removed */
UNIV_INTERN
ulint
btr_blob_dbg_remove(
/*================*/
const page_t* page, /*!< in: b-tree page */
dict_index_t* index, /*!< in/out: index */
const char* ctx) /*!< in: context (for logging) */
__attribute__((nonnull));
/**************************************************************//**
Restore in index->blobs any references to off-page columns
Used when page reorganize fails due to compressed page overflow. */
UNIV_INTERN
void
btr_blob_dbg_restore(
/*=================*/
const page_t* npage, /*!< in: page that failed to compress */
const page_t* page, /*!< in: copy of original page */
dict_index_t* index, /*!< in/out: index */
const char* ctx) /*!< in: context (for logging) */
__attribute__((nonnull));
/** Operation that processes the BLOB references of an index record
@param[in] rec record on index page
@param[in/out] index the index tree of the record
@param[in] offsets rec_get_offsets(rec,index)
@param[in] ctx context (for logging)
@return number of BLOB references processed */
typedef ulint (*btr_blob_dbg_op_f)
(const rec_t* rec,dict_index_t* index,const ulint* offsets,const char* ctx);
/**************************************************************//**
Count and process all references to off-page columns on a page.
@return number of references processed */
UNIV_INTERN
ulint
btr_blob_dbg_op(
/*============*/
const page_t* page, /*!< in: B-tree leaf page */
const rec_t* rec, /*!< in: record to start from
(NULL to process the whole page) */
dict_index_t* index, /*!< in/out: index */
const char* ctx, /*!< in: context (for logging) */
const btr_blob_dbg_op_f op) /*!< in: operation on records */
__attribute__((nonnull(1,3,4,5)));
#else /* UNIV_BLOB_DEBUG */
# define btr_blob_dbg_add_rec(rec, index, offsets, ctx) ((void) 0)
# define btr_blob_dbg_add(page, index, ctx) ((void) 0)
# define btr_blob_dbg_remove_rec(rec, index, offsets, ctx) ((void) 0)
# define btr_blob_dbg_remove(page, index, ctx) ((void) 0)
# define btr_blob_dbg_restore(npage, page, index, ctx) ((void) 0)
# define btr_blob_dbg_op(page, rec, index, ctx, op) ((void) 0)
#endif /* UNIV_BLOB_DEBUG */
/** The size of a reference to data stored on a different page.
The reference is stored at the end of the prefix of the field
in the index record. */

View File

@ -340,6 +340,13 @@ struct dict_index_struct{
index, or 0 if the index existed
when InnoDB was started up */
#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_BLOB_DEBUG
mutex_t blobs_mutex;
/*!< mutex protecting blobs */
void* blobs; /*!< map of (page_no,heap_no,field_no)
to first_blob_page_no; protected by
blobs_mutex; @see btr_blob_dbg_t */
#endif /* UNIV_BLOB_DEBUG */
#ifdef UNIV_DEBUG
ulint magic_n;/*!< magic number */
/** Value of dict_index_struct::magic_n */

View File

@ -420,7 +420,7 @@ page_zip_copy_recs(
const page_t* src, /*!< in: page */
dict_index_t* index, /*!< in: index of the B-tree */
mtr_t* mtr) /*!< in: mini-transaction */
__attribute__((nonnull(1,2,3,4)));
__attribute__((nonnull));
#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**

View File

@ -46,7 +46,7 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 1
#define INNODB_VERSION_MINOR 0
#define INNODB_VERSION_BUGFIX 15
#define INNODB_VERSION_BUGFIX 16
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
@ -194,6 +194,8 @@ this will break redo log file compatibility, but it may be useful when
debugging redo log application problems. */
#define UNIV_MEM_DEBUG /* detect memory leaks etc */
#define UNIV_IBUF_DEBUG /* debug the insert buffer */
#define UNIV_BLOB_DEBUG /* track BLOB ownership;
assumes that no BLOBs survive server restart */
#define UNIV_IBUF_COUNT_DEBUG /* debug the insert buffer;
this limits the database to IBUF_COUNT_N_SPACES and IBUF_COUNT_N_PAGES,
and the insert buffer must be empty when the database is started */

View File

@ -1149,6 +1149,8 @@ use_heap:
current_rec, index, mtr);
}
btr_blob_dbg_add_rec(insert_rec, index, offsets, "insert");
return(insert_rec);
}
@ -1195,10 +1197,12 @@ page_cur_insert_rec_zip_reorg(
}
/* Out of space: restore the page */
btr_blob_dbg_remove(page, index, "insert_zip_fail");
if (!page_zip_decompress(page_zip, page, FALSE)) {
ut_error; /* Memory corrupted? */
}
ut_ad(page_validate(page, index));
btr_blob_dbg_add(page, index, "insert_zip_fail");
return(NULL);
}
@ -1490,6 +1494,8 @@ use_heap:
page_zip_write_rec(page_zip, insert_rec, index, offsets, 1);
btr_blob_dbg_add_rec(insert_rec, index, offsets, "insert_zip_ok");
/* 9. Write log record of the insert */
if (UNIV_LIKELY(mtr != NULL)) {
page_cur_insert_rec_write_log(insert_rec, rec_size,
@ -1697,6 +1703,9 @@ page_copy_rec_list_end_to_created_page(
heap_top += rec_size;
rec_offs_make_valid(insert_rec, index, offsets);
btr_blob_dbg_add_rec(insert_rec, index, offsets, "copy_end");
page_cur_insert_rec_write_log(insert_rec, rec_size, prev_rec,
index, mtr);
prev_rec = insert_rec;
@ -1944,6 +1953,7 @@ page_cur_delete_rec(
page_dir_slot_set_n_owned(cur_dir_slot, page_zip, cur_n_owned - 1);
/* 6. Free the memory occupied by the record */
btr_blob_dbg_remove_rec(current_rec, index, offsets, "delete");
page_mem_free(page, page_zip, current_rec, index, offsets);
/* 7. Now we have decremented the number of owned records of the slot.

View File

@ -685,12 +685,16 @@ page_copy_rec_list_end(
if (UNIV_UNLIKELY
(!page_zip_reorganize(new_block, index, mtr))) {
btr_blob_dbg_remove(new_page, index,
"copy_end_reorg_fail");
if (UNIV_UNLIKELY
(!page_zip_decompress(new_page_zip,
new_page, FALSE))) {
ut_error;
}
ut_ad(page_validate(new_page, index));
btr_blob_dbg_add(new_page, index,
"copy_end_reorg_fail");
return(NULL);
} else {
/* The page was reorganized:
@ -803,12 +807,16 @@ page_copy_rec_list_start(
if (UNIV_UNLIKELY
(!page_zip_reorganize(new_block, index, mtr))) {
btr_blob_dbg_remove(new_page, index,
"copy_start_reorg_fail");
if (UNIV_UNLIKELY
(!page_zip_decompress(new_page_zip,
new_page, FALSE))) {
ut_error;
}
ut_ad(page_validate(new_page, index));
btr_blob_dbg_add(new_page, index,
"copy_start_reorg_fail");
return(NULL);
} else {
/* The page was reorganized:
@ -1080,6 +1088,9 @@ page_delete_rec_list_end(
/* Remove the record chain segment from the record chain */
page_rec_set_next(prev_rec, page_get_supremum_rec(page));
btr_blob_dbg_op(page, rec, index, "delete_end",
btr_blob_dbg_remove_rec);
/* Catenate the deleted chain segment to the page free list */
page_rec_set_next(last_rec, page_header_get_ptr(page, PAGE_FREE));

View File

@ -4451,6 +4451,8 @@ page_zip_reorganize(
/* Copy the old page to temporary space */
buf_frame_copy(temp_page, page);
btr_blob_dbg_remove(page, index, "zip_reorg");
/* Recreate the page: note that global data on page (possible
segment headers, next page-field, etc.) is preserved intact */
@ -4509,7 +4511,7 @@ page_zip_copy_recs(
mtr_t* mtr) /*!< in: mini-transaction */
{
ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
ut_ad(mtr_memo_contains_page(mtr, (page_t*) src, MTR_MEMO_PAGE_X_FIX));
ut_ad(mtr_memo_contains_page(mtr, src, MTR_MEMO_PAGE_X_FIX));
ut_ad(!dict_index_is_ibuf(index));
#ifdef UNIV_ZIP_DEBUG
/* The B-tree operations that call this function may set
@ -4579,6 +4581,7 @@ page_zip_copy_recs(
#ifdef UNIV_ZIP_DEBUG
ut_a(page_zip_validate(page_zip, page));
#endif /* UNIV_ZIP_DEBUG */
btr_blob_dbg_add(page, index, "page_zip_copy_recs");
page_zip_compress_write_log(page_zip, page, index, mtr);
}

View File

@ -498,14 +498,49 @@ row_upd_rec_in_place(
n_fields = upd_get_n_fields(update);
for (i = 0; i < n_fields; i++) {
#ifdef UNIV_BLOB_DEBUG
btr_blob_dbg_t b;
const byte* field_ref = NULL;
#endif /* UNIV_BLOB_DEBUG */
upd_field = upd_get_nth_field(update, i);
new_val = &(upd_field->new_val);
ut_ad(!dfield_is_ext(new_val) ==
!rec_offs_nth_extern(offsets, upd_field->field_no));
#ifdef UNIV_BLOB_DEBUG
if (dfield_is_ext(new_val)) {
ulint len;
field_ref = rec_get_nth_field(rec, offsets, i, &len);
ut_a(len != UNIV_SQL_NULL);
ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
field_ref += len - BTR_EXTERN_FIELD_REF_SIZE;
b.ref_page_no = page_get_page_no(page_align(rec));
b.ref_heap_no = page_rec_get_heap_no(rec);
b.ref_field_no = i;
b.blob_page_no = mach_read_from_4(
field_ref + BTR_EXTERN_PAGE_NO);
ut_a(b.ref_field_no >= index->n_uniq);
btr_blob_dbg_rbt_delete(index, &b, "upd_in_place");
}
#endif /* UNIV_BLOB_DEBUG */
rec_set_nth_field(rec, offsets, upd_field->field_no,
dfield_get_data(new_val),
dfield_get_len(new_val));
#ifdef UNIV_BLOB_DEBUG
if (dfield_is_ext(new_val)) {
b.blob_page_no = mach_read_from_4(
field_ref + BTR_EXTERN_PAGE_NO);
b.always_owner = b.owner = !(field_ref[BTR_EXTERN_LEN]
& BTR_EXTERN_OWNER_FLAG);
b.del = rec_get_deleted_flag(
rec, rec_offs_comp(offsets));
btr_blob_dbg_rbt_insert(index, &b, "upd_in_place");
}
#endif /* UNIV_BLOB_DEBUG */
}
if (UNIV_LIKELY_NULL(page_zip)) {

View File

@ -1061,6 +1061,12 @@ innobase_start_or_create_for_mysql(void)
);
#endif
#ifdef UNIV_BLOB_DEBUG
fprintf(stderr,
"InnoDB: !!!!!!!! UNIV_BLOB_DEBUG switched on !!!!!!!!!\n"
"InnoDB: Server restart may fail with UNIV_BLOB_DEBUG\n");
#endif /* UNIV_BLOB_DEBUG */
#ifdef UNIV_SYNC_DEBUG
fprintf(stderr,
"InnoDB: !!!!!!!! UNIV_SYNC_DEBUG switched on !!!!!!!!!\n");

View File

@ -260,6 +260,9 @@ rw_lock_create_func(
contains garbage at initialization and cannot be used for
recursive x-locking. */
lock->recursive = FALSE;
/* Silence Valgrind when UNIV_DEBUG_VALGRIND is not enabled. */
memset((void*) &lock->writer_thread, 0, sizeof lock->writer_thread);
UNIV_MEM_INVALID(&lock->writer_thread, sizeof lock->writer_thread);
#ifdef UNIV_SYNC_DEBUG
UT_LIST_INIT(lock->debug_list);

View File

@ -272,7 +272,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
keyseg->type != HA_KEYTYPE_VARBINARY2)
{
my_errno=HA_WRONG_CREATE_OPTION;
goto err;
goto err_no_lock;
}
}
keydef->keysegs+=sp_segs;
@ -281,7 +281,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
min_key_length_skip+=SPLEN*2*SPDIMS;
#else
my_errno= HA_ERR_UNSUPPORTED;
goto err;
goto err_no_lock;
#endif /*HAVE_SPATIAL*/
}
else if (keydef->flag & HA_FULLTEXT)
@ -297,7 +297,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
keyseg->type != HA_KEYTYPE_VARTEXT2)
{
my_errno=HA_WRONG_CREATE_OPTION;
goto err;
goto err_no_lock;
}
if (!(keyseg->flag & HA_BLOB_PART) &&
(keyseg->type == HA_KEYTYPE_VARTEXT1 ||
@ -422,7 +422,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
if (keydef->keysegs > MI_MAX_KEY_SEG)
{
my_errno=HA_WRONG_CREATE_OPTION;
goto err;
goto err_no_lock;
}
/*
key_segs may be 0 in the case when we only want to be able to
@ -447,7 +447,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
length >= MI_MAX_KEY_BUFF)
{
my_errno=HA_WRONG_CREATE_OPTION;
goto err;
goto err_no_lock;
}
set_if_bigger(max_key_block_length,keydef->block_length);
keydef->keylength= (uint16) key_length;
@ -494,7 +494,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
"indexes and/or unique constraints.",
MYF(0), name + dirname_length(name));
my_errno= HA_WRONG_CREATE_OPTION;
goto err;
goto err_no_lock;
}
bmove(share.state.header.file_version,(uchar*) myisam_file_magic,4);
@ -827,12 +827,14 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
errpos=0;
pthread_mutex_unlock(&THR_LOCK_myisam);
if (my_close(file,MYF(0)))
goto err;
goto err_no_lock;
my_free((char*) rec_per_key_part,MYF(0));
DBUG_RETURN(0);
err:
pthread_mutex_unlock(&THR_LOCK_myisam);
err_no_lock:
save_errno=my_errno;
switch (errpos) {
case 3:

View File

@ -1,4 +1,4 @@
# Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -610,7 +610,25 @@ touch $RBR%{_sysconfdir}/mysqlmanager.passwd
##############################################################################
%pre server
# This is the code running at the beginning of a RPM upgrade action,
# before replacing the old files with the new ones.
# There are users who deviate from the default file system layout.
# Check local settings to support them.
if [ -x %{_bindir}/my_print_defaults ]
then
mysql_datadir=`%{_bindir}/my_print_defaults server mysqld | grep '^--datadir=' | sed -n 's/--datadir=//p'`
PID_FILE_PATT=`%{_bindir}/my_print_defaults server mysqld | grep '^--pid-file=' | sed -n 's/--pid-file=//p'`
fi
if [ -z "$mysql_datadir" ]
then
mysql_datadir=%{mysqldatadir}
fi
if [ -z "$PID_FILE_PATT" ]
then
PID_FILE_PATT="$mysql_datadir/*.pid"
fi
# Check if we can safely upgrade. An upgrade is only safe if it's from one
# of our RPMs in the same version family.
@ -681,7 +699,7 @@ fi
# We assume that if there is exactly one ".pid" file,
# it contains the valid PID of a running MySQL server.
NR_PID_FILES=`ls $mysql_datadir/*.pid 2>/dev/null | wc -l`
NR_PID_FILES=`ls $PID_FILE_PATT 2>/dev/null | wc -l`
case $NR_PID_FILES in
0 ) SERVER_TO_START='' ;; # No "*.pid" file == no running server
1 ) SERVER_TO_START='true' ;;
@ -703,8 +721,8 @@ if [ -f $STATUS_FILE ]; then
echo "before repeating the MySQL upgrade."
exit 1
elif [ -n "$SEVERAL_PID_FILES" ] ; then
echo "Your MySQL directory '$mysql_datadir' has more than one PID file:"
ls -ld $mysql_datadir/*.pid
echo "You have more than one PID file:"
ls -ld $PID_FILE_PATT
echo "Please check which one (if any) corresponds to a running server"
echo "and delete all others before repeating the MySQL upgrade."
exit 1
@ -729,17 +747,17 @@ if [ -d $mysql_datadir ] ; then
if [ -n "$SERVER_TO_START" ] ; then
# There is only one PID file, race possibility ignored
echo "PID file:" >> $STATUS_FILE
ls -l $mysql_datadir/*.pid >> $STATUS_FILE
cat $mysql_datadir/*.pid >> $STATUS_FILE
ls -l $PID_FILE_PATT >> $STATUS_FILE
cat $PID_FILE_PATT >> $STATUS_FILE
echo >> $STATUS_FILE
echo "Server process:" >> $STATUS_FILE
ps -fp `cat $mysql_datadir/*.pid` >> $STATUS_FILE
ps -fp `cat $PID_FILE_PATT` >> $STATUS_FILE
echo >> $STATUS_FILE
echo "SERVER_TO_START=$SERVER_TO_START" >> $STATUS_FILE
else
# Take a note we checked it ...
echo "PID file:" >> $STATUS_FILE
ls -l $mysql_datadir/*.pid >> $STATUS_FILE 2>&1
ls -l $PID_FILE_PATT >> $STATUS_FILE 2>&1
fi
fi
@ -754,7 +772,20 @@ if [ -x %{_sysconfdir}/init.d/mysql ] ; then
fi
%post server
# This is the code running at the end of a RPM install or upgrade action,
# after the (new) files have been written.
# There are users who deviate from the default file system layout.
# Check local settings to support them.
if [ -x %{_bindir}/my_print_defaults ]
then
mysql_datadir=`%{_bindir}/my_print_defaults server mysqld | grep '^--datadir=' | sed -n 's/--datadir=//p'`
fi
if [ -z "$mysql_datadir" ]
then
mysql_datadir=%{mysqldatadir}
fi
NEW_VERSION=%{mysql_version}-%{release}
STATUS_FILE=$mysql_datadir/RPM_UPGRADE_MARKER
@ -1133,6 +1164,13 @@ fi
##############################################################################
%changelog
* Thu Feb 03 2011 Joerg Bruehe <joerg.bruehe@oracle.com>
- Fix bug#56581: If an installation deviates from the default file locations
("datadir" and "pid-file"), the mechanism to detect a running server (on upgrade)
should still work, and use these locations.
The problem was that the fix for bug#27072 did not check for local settings.
* Wed Nov 24 2010 Alexander Nozdrin <alexander.nozdrin@oracle.com>
- EXCEPTIONS-CLIENT has been deleted, remove it from here too.

View File

@ -18398,6 +18398,72 @@ static void test_bug47485()
}
/*
Bug#58036 client utf32, utf16, ucs2 should be disallowed, they crash server
*/
static void test_bug58036()
{
MYSQL *conn;
DBUG_ENTER("test_bug47485");
myheader("test_bug58036");
/* Part1: try to connect with ucs2 client character set */
conn= mysql_client_init(NULL);
mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2");
if (mysql_real_connect(conn, opt_host, opt_user,
opt_password, opt_db ? opt_db : "test",
opt_port, opt_unix_socket, 0))
{
if (!opt_silent)
printf("mysql_real_connect() succeeded (failure expected)\n");
mysql_close(conn);
DIE("");
}
if (!opt_silent)
printf("Got mysql_real_connect() error (expected): %s (%d)\n",
mysql_error(conn), mysql_errno(conn));
DIE_UNLESS(mysql_errno(conn) == ER_WRONG_VALUE_FOR_VAR);
mysql_close(conn);
/*
Part2:
- connect with latin1
- then change client character set to ucs2
- then try mysql_change_user()
*/
conn= mysql_client_init(NULL);
mysql_options(conn, MYSQL_SET_CHARSET_NAME, "latin1");
if (!mysql_real_connect(conn, opt_host, opt_user,
opt_password, opt_db ? opt_db : "test",
opt_port, opt_unix_socket, 0))
{
if (!opt_silent)
printf("mysql_real_connect() failed: %s (%d)\n",
mysql_error(conn), mysql_errno(conn));
mysql_close(conn);
DIE("");
}
mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2");
if (!mysql_change_user(conn, opt_user, opt_password, NULL))
{
if (!opt_silent)
printf("mysql_change_user() succedded, error expected!");
mysql_close(conn);
DIE("");
}
if (!opt_silent)
printf("Got mysql_change_user() error (expected): %s (%d)\n",
mysql_error(conn), mysql_errno(conn));
mysql_close(conn);
DBUG_VOID_RETURN;
}
/*
Read and parse arguments and MySQL options from my.cnf
*/
@ -18724,6 +18790,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug42373", test_bug42373 },
{ "test_bug54041", test_bug54041 },
{ "test_bug47485", test_bug47485 },
{ "test_bug58036", test_bug58036 },
{ 0, 0 }
};

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2006 MySQL AB
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -24,6 +24,8 @@
#include <tap.h>
#include <m_string.h>
#define MAX_TESTED_BITMAP_SIZE 1024
uint get_rand_bit(uint bitsize)
{
return (rand() % bitsize);
@ -75,12 +77,6 @@ error2:
return TRUE;
}
my_bool test_operators(MY_BITMAP *map __attribute__((unused)),
uint bitsize __attribute__((unused)))
{
return FALSE;
}
my_bool test_get_all_bits(MY_BITMAP *map, uint bitsize)
{
uint i;
@ -129,8 +125,8 @@ my_bool test_compare_operators(MY_BITMAP *map, uint bitsize)
uint no_loops= bitsize > 128 ? 128 : bitsize;
MY_BITMAP map2_obj, map3_obj;
MY_BITMAP *map2= &map2_obj, *map3= &map3_obj;
uint32 map2buf[1024];
uint32 map3buf[1024];
uint32 map2buf[MAX_TESTED_BITMAP_SIZE];
uint32 map3buf[MAX_TESTED_BITMAP_SIZE];
bitmap_init(&map2_obj, map2buf, bitsize, FALSE);
bitmap_init(&map3_obj, map3buf, bitsize, FALSE);
bitmap_clear_all(map2);
@ -257,8 +253,21 @@ error2:
my_bool test_get_first_bit(MY_BITMAP *map, uint bitsize)
{
uint i, test_bit;
uint i, test_bit= 0;
uint no_loops= bitsize > 128 ? 128 : bitsize;
bitmap_set_all(map);
for (i=0; i < bitsize; i++)
bitmap_clear_bit(map, i);
if (bitmap_get_first_set(map) != MY_BIT_NONE)
goto error1;
bitmap_clear_all(map);
for (i=0; i < bitsize; i++)
bitmap_set_bit(map, i);
if (bitmap_get_first(map) != MY_BIT_NONE)
goto error2;
bitmap_clear_all(map);
for (i=0; i < no_loops; i++)
{
test_bit=get_rand_bit(bitsize);
@ -321,6 +330,24 @@ my_bool test_prefix(MY_BITMAP *map, uint bitsize)
goto error3;
bitmap_clear_all(map);
}
for (i=0; i < bitsize; i++)
{
if (bitmap_is_prefix(map, i + 1))
goto error4;
bitmap_set_bit(map, i);
if (!bitmap_is_prefix(map, i + 1))
goto error5;
test_bit=get_rand_bit(bitsize);
bitmap_set_bit(map, test_bit);
if (test_bit <= i && !bitmap_is_prefix(map, i + 1))
goto error5;
else if (test_bit > i)
{
if (bitmap_is_prefix(map, i + 1))
goto error4;
bitmap_clear_bit(map, test_bit);
}
}
return FALSE;
error1:
diag("prefix1 error bitsize = %u, prefix_size = %u", bitsize,test_bit);
@ -331,13 +358,127 @@ error2:
error3:
diag("prefix3 error bitsize = %u, prefix_size = %u", bitsize,test_bit);
return TRUE;
error4:
diag("prefix4 error bitsize = %u, i = %u", bitsize,i);
return TRUE;
error5:
diag("prefix5 error bitsize = %u, i = %u", bitsize,i);
return TRUE;
}
my_bool test_compare(MY_BITMAP *map, uint bitsize)
{
MY_BITMAP map2;
uint32 map2buf[MAX_TESTED_BITMAP_SIZE];
uint i, test_bit;
uint no_loops= bitsize > 128 ? 128 : bitsize;
if (bitmap_init(&map2, map2buf, bitsize, FALSE))
{
diag("init error for bitsize %d", bitsize);
return TRUE;
}
/* Test all 4 possible combinations of set/unset bits. */
for (i=0; i < no_loops; i++)
{
test_bit=get_rand_bit(bitsize);
bitmap_clear_bit(map, test_bit);
bitmap_clear_bit(&map2, test_bit);
if (!bitmap_is_subset(map, &map2))
goto error_is_subset;
bitmap_set_bit(map, test_bit);
if (bitmap_is_subset(map, &map2))
goto error_is_subset;
bitmap_set_bit(&map2, test_bit);
if (!bitmap_is_subset(map, &map2))
goto error_is_subset;
bitmap_clear_bit(map, test_bit);
if (!bitmap_is_subset(map, &map2))
goto error_is_subset;
/* Note that test_bit is not cleared i map2. */
}
bitmap_clear_all(map);
bitmap_clear_all(&map2);
/* Test all 4 possible combinations of set/unset bits. */
for (i=0; i < no_loops; i++)
{
test_bit=get_rand_bit(bitsize);
if (bitmap_is_overlapping(map, &map2))
goto error_is_overlapping;
bitmap_set_bit(map, test_bit);
if (bitmap_is_overlapping(map, &map2))
goto error_is_overlapping;
bitmap_set_bit(&map2, test_bit);
if (!bitmap_is_overlapping(map, &map2))
goto error_is_overlapping;
bitmap_clear_bit(map, test_bit);
if (bitmap_is_overlapping(map, &map2))
goto error_is_overlapping;
bitmap_clear_bit(&map2, test_bit);
/* Note that test_bit is not cleared i map2. */
}
return FALSE;
error_is_subset:
diag("is_subset error bitsize = %u", bitsize);
return TRUE;
error_is_overlapping:
diag("is_overlapping error bitsize = %u", bitsize);
return TRUE;
}
my_bool test_intersect(MY_BITMAP *map, uint bitsize)
{
uint bitsize2 = 1 + get_rand_bit(MAX_TESTED_BITMAP_SIZE - 1);
MY_BITMAP map2;
uint32 map2buf[bitsize2];
uint i, test_bit1, test_bit2, test_bit3;
if (bitmap_init(&map2, map2buf, bitsize2, FALSE))
{
diag("init error for bitsize %d", bitsize2);
return TRUE;
}
test_bit1= get_rand_bit(bitsize);
test_bit2= get_rand_bit(bitsize);
bitmap_set_bit(map, test_bit1);
bitmap_set_bit(map, test_bit2);
test_bit3= get_rand_bit(bitsize2);
bitmap_set_bit(&map2, test_bit3);
if (test_bit2 < bitsize2)
bitmap_set_bit(&map2, test_bit2);
bitmap_intersect(map, &map2);
if (test_bit2 < bitsize2)
{
if (!bitmap_is_set(map, test_bit2))
goto error;
bitmap_clear_bit(map, test_bit2);
}
if (test_bit1 == test_bit3)
{
if (!bitmap_is_set(map, test_bit1))
goto error;
bitmap_clear_bit(map, test_bit1);
}
if (!bitmap_is_clear_all(map))
goto error;
bitmap_set_all(map);
bitmap_set_all(&map2);
for (i=0; i < bitsize2; i++)
bitmap_clear_bit(&map2, i);
bitmap_intersect(map, &map2);
if (!bitmap_is_clear_all(map))
goto error;
return FALSE;
error:
diag("intersect error bitsize = %u, bit1 = %u, bit2 = %u, bit3 = %u",
bitsize, test_bit1, test_bit2, test_bit3);
return TRUE;
}
my_bool do_test(uint bitsize)
{
MY_BITMAP map;
uint32 buf[1024];
uint32 buf[MAX_TESTED_BITMAP_SIZE];
if (bitmap_init(&map, buf, bitsize, FALSE))
{
diag("init error for bitsize %d", bitsize);
@ -349,9 +490,6 @@ my_bool do_test(uint bitsize)
if (test_flip_bit(&map,bitsize))
goto error;
bitmap_clear_all(&map);
if (test_operators(&map,bitsize))
goto error;
bitmap_clear_all(&map);
if (test_get_all_bits(&map, bitsize))
goto error;
bitmap_clear_all(&map);
@ -366,8 +504,15 @@ my_bool do_test(uint bitsize)
bitmap_clear_all(&map);
if (test_get_next_bit(&map,bitsize))
goto error;
bitmap_clear_all(&map);
if (test_prefix(&map,bitsize))
goto error;
bitmap_clear_all(&map);
if (test_compare(&map,bitsize))
goto error;
bitmap_clear_all(&map);
if (test_intersect(&map,bitsize))
goto error;
return FALSE;
error:
return TRUE;
@ -377,7 +522,7 @@ int main()
{
int i;
int const min_size = 1;
int const max_size = 1024;
int const max_size = MAX_TESTED_BITMAP_SIZE;
MY_INIT("bitmap-t");
plan(max_size - min_size);