merge from 5.1 main
This commit is contained in:
commit
e58e15ff13
21
README
21
README
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) \
|
||||
|
@ -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'
|
||||
|
@ -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
2
mysql-test/r/ctype_eucjpms.result
Executable file → Normal 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'
|
||||
|
@ -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 */ ;
|
||||
|
||||
|
@ -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 */ ;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
#
|
||||
|
8
mysql-test/suite/innodb/r/innodb_bug60049.result
Normal file
8
mysql-test/suite/innodb/r/innodb_bug60049.result
Normal 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
|
1
mysql-test/suite/innodb/t/innodb_bug60049-master.opt
Normal file
1
mysql-test/suite/innodb/t/innodb_bug60049-master.opt
Normal file
@ -0,0 +1 @@
|
||||
--innodb_fast_shutdown=0
|
39
mysql-test/suite/innodb/t/innodb_bug60049.test
Normal file
39
mysql-test/suite/innodb/t/innodb_bug60049.test
Normal 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
|
28
mysql-test/suite/innodb_plugin/r/innodb_bug59307.result
Normal file
28
mysql-test/suite/innodb_plugin/r/innodb_bug59307.result
Normal 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;
|
8
mysql-test/suite/innodb_plugin/r/innodb_bug60049.result
Normal file
8
mysql-test/suite/innodb_plugin/r/innodb_bug60049.result
Normal 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
|
32
mysql-test/suite/innodb_plugin/t/innodb_bug59307.test
Normal file
32
mysql-test/suite/innodb_plugin/t/innodb_bug59307.test
Normal 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;
|
@ -0,0 +1 @@
|
||||
--innodb_fast_shutdown=0
|
39
mysql-test/suite/innodb_plugin/t/innodb_bug60049.test
Normal file
39
mysql-test/suite/innodb_plugin/t/innodb_bug60049.test
Normal 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
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 #
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 #
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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. */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
/**********************************************************************//**
|
||||
|
@ -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 */
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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.
|
||||
|
@ -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 }
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user