From cb6a084076d4688c11936bfa91b03a83570f69e0 Mon Sep 17 00:00:00 2001
From: "jimw@rama.(none)" <>
Date: Thu, 17 Aug 2006 12:25:40 -0700
Subject: [PATCH 01/19] Bug #2717: include/my_global.h mis-defines
__attribute__
Fix when __attribute__() is stubbed out, add ATTRIBUTE_FORMAT() for specifying
__attribute__((format(...))) safely, make more use of the format attribute,
and fix some of the warnings that this turns up (plus a bonus unrelated one).
---
include/m_ctype.h | 5 +++--
include/m_string.h | 3 ++-
include/my_global.h | 22 +++++++++++++++++++++-
include/my_sys.h | 4 ++--
sql/item_subselect.cc | 2 +-
sql/item_timefunc.cc | 4 ++--
sql/mysql_priv.h | 11 ++++++-----
sql/mysqld.cc | 21 +++++++++++----------
sql/opt_range.cc | 7 ++++---
sql/set_var.cc | 12 ++++++------
sql/slave.cc | 2 +-
sql/slave.h | 3 ++-
sql/sql_acl.cc | 4 ++--
sql/sql_class.h | 2 +-
14 files changed, 64 insertions(+), 38 deletions(-)
diff --git a/include/m_ctype.h b/include/m_ctype.h
index cd1dac9dde8..b2bf8d3e30f 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -175,7 +175,7 @@ typedef struct my_charset_handler_st
/* Charset dependant snprintf() */
int (*snprintf)(struct charset_info_st *, char *to, uint n, const char *fmt,
- ...);
+ ...) ATTRIBUTE_FORMAT(printf, 4, 5);
int (*long10_to_str)(struct charset_info_st *, char *to, uint n, int radix,
long int val);
int (*longlong10_to_str)(struct charset_info_st *, char *to, uint n,
@@ -300,7 +300,8 @@ int my_wc_mb_8bit(CHARSET_INFO *cs,my_wc_t wc, uchar *s, uchar *e);
ulong my_scan_8bit(CHARSET_INFO *cs, const char *b, const char *e, int sq);
int my_snprintf_8bit(struct charset_info_st *, char *to, uint n,
- const char *fmt, ...);
+ const char *fmt, ...)
+ ATTRIBUTE_FORMAT(printf, 4, 5);
long my_strntol_8bit(CHARSET_INFO *, const char *s, uint l, int base,
char **e, int *err);
diff --git a/include/m_string.h b/include/m_string.h
index d7edff4f626..08408c372b5 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -247,7 +247,8 @@ extern ulonglong strtoull(const char *str, char **ptr, int base);
extern int my_vsnprintf( char *str, size_t n,
const char *format, va_list ap );
-extern int my_snprintf(char* to, size_t n, const char* fmt, ...);
+extern int my_snprintf(char *to, size_t n, const char *fmt, ...)
+ ATTRIBUTE_FORMAT(printf, 3, 4);
#if defined(__cplusplus) && !defined(OS2)
}
diff --git a/include/my_global.h b/include/my_global.h
index 6baa4558d50..2fbb1db4b77 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -414,14 +414,34 @@ typedef unsigned short ushort;
#define function_volatile volatile
#define my_reinterpret_cast(A) reinterpret_cast
#define my_const_cast(A) const_cast
+# ifndef GCC_VERSION
+# define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
+# endif
#elif !defined(my_reinterpret_cast)
#define my_reinterpret_cast(A) (A)
#define my_const_cast(A) (A)
#endif
-#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
+
+/*
+ Disable __attribute__() on GCC < 2.7 and non-GCC compilers
+*/
+#if !defined(__attribute__) && (!defined(__GNUC__) || GCC_VERSION < 2007)
#define __attribute__(A)
#endif
+/*
+ __attribute__((format(...))) is only supported in gcc >= 2.8 and g++ >= 3.4
+*/
+#ifndef ATTRIBUTE_FORMAT
+# if defined(__GNUC__) && \
+ ((!defined(__cplusplus__) && GCC_VERSION >= 2008) || \
+ GCC_VERSION >= 3004)
+# define ATTRIBUTE_FORMAT(style, m, n) __attribute__((format(style, m, n)))
+# else
+# define ATTRIBUTE_FORMAT(style, m, n)
+# endif
+#endif
+
/* From old s-system.h */
/*
diff --git a/include/my_sys.h b/include/my_sys.h
index 02ea188a18e..46e09e8ddf4 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -588,8 +588,8 @@ extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags);
extern int my_sync(File fd, myf my_flags);
extern int my_error _VARARGS((int nr,myf MyFlags, ...));
extern int my_printf_error _VARARGS((uint my_err, const char *format,
- myf MyFlags, ...)
- __attribute__ ((format (printf, 2, 4))));
+ myf MyFlags, ...))
+ ATTRIBUTE_FORMAT(printf, 2, 4);
extern int my_message(uint my_err, const char *str,myf MyFlags);
extern int my_message_no_curses(uint my_err, const char *str,myf MyFlags);
extern int my_message_curses(uint my_err, const char *str,myf MyFlags);
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index c95a91de13e..006153cc51f 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -545,7 +545,7 @@ Item_allany_subselect::Item_allany_subselect(Item * left_exp,
chooser_compare_func_creator fc,
st_select_lex *select_lex,
bool all_arg)
- :Item_in_subselect(), all(all_arg), func_creator(fc)
+ :Item_in_subselect(), func_creator(fc), all(all_arg)
{
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
left_expr= left_exp;
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 44d9b422263..21e27d6c7b4 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -65,7 +65,7 @@ static bool make_datetime(date_time_format_types format, TIME *ltime,
ltime->hour, ltime->minute, ltime->second);
break;
case TIME_MICROSECOND:
- length= cs->cset->snprintf(cs, buff, length, "%s%02d:%02d:%02d.%06d",
+ length= cs->cset->snprintf(cs, buff, length, "%s%02d:%02d:%02d.%06ld",
ltime->neg ? "-" : "",
ltime->hour, ltime->minute, ltime->second,
ltime->second_part);
@@ -82,7 +82,7 @@ static bool make_datetime(date_time_format_types format, TIME *ltime,
break;
case DATE_TIME_MICROSECOND:
length= cs->cset->snprintf(cs, buff, length,
- "%04d-%02d-%02d %02d:%02d:%02d.%06d",
+ "%04d-%02d-%02d %02d:%02d:%02d.%06ld",
ltime->year, ltime->month, ltime->day,
ltime->hour, ltime->minute, ltime->second,
ltime->second_part);
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 9c5bcc2d53f..76627eaf3ec 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -712,7 +712,8 @@ void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length);
MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code,
const char *msg);
void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
- uint code, const char *format, ...);
+ uint code, const char *format, ...)
+ ATTRIBUTE_FORMAT(printf,4,5);
void mysql_reset_errors(THD *thd);
my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show);
@@ -847,10 +848,10 @@ bool init_errmessage(void);
void sql_perror(const char *message);
void vprint_msg_to_log(enum loglevel level, const char *format, va_list args);
-void sql_print_error(const char *format, ...);
-void sql_print_warning(const char *format, ...);
-void sql_print_information(const char *format, ...);
-
+void sql_print_error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
+void sql_print_warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
+void sql_print_information(const char *format, ...)
+ ATTRIBUTE_FORMAT(printf, 1, 2);
bool fn_format_relative_to_data_home(my_string to, const char *name,
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 74c7b1a4e4c..ba0a7d134fa 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -952,8 +952,8 @@ extern "C" sig_handler print_signal_warning(int sig)
if (!DBUG_IN_USE)
{
if (global_system_variables.log_warnings)
- sql_print_warning("Got signal %d from thread %d",
- sig,my_thread_id());
+ sql_print_warning("Got signal %d from thread %ld",
+ sig, my_thread_id());
}
#ifdef DONT_REMEMBER_SIGNAL
my_sigset(sig,print_signal_warning); /* int. thread system calls */
@@ -1443,8 +1443,8 @@ static void server_init(void)
if (strlen(mysqld_unix_port) > (sizeof(UNIXaddr.sun_path) - 1))
{
- sql_print_error("The socket file path is too long (> %d): %s",
- sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
+ sql_print_error("The socket file path is too long (> %lu): %s",
+ sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
unireg_abort(1);
}
if ((unix_sock= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
@@ -2786,9 +2786,9 @@ static void openssl_lock(int mode, openssl_lock_t *lock, const char *file,
sql_print_error("Fatal: OpenSSL interface problem (mode=0x%x)", mode);
abort();
}
- if (err)
+ if (err)
{
- sql_print_error("Fatal: can't %s OpenSSL %s lock", what);
+ sql_print_error("Fatal: can't %s OpenSSL lock", what);
abort();
}
}
@@ -6549,14 +6549,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
exit(1);
}
switch (method-1) {
- case 0:
- method_conv= MI_STATS_METHOD_NULLS_EQUAL;
+ case 2:
+ method_conv= MI_STATS_METHOD_IGNORE_NULLS;
break;
case 1:
method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
break;
- case 2:
- method_conv= MI_STATS_METHOD_IGNORE_NULLS;
+ case 0:
+ default:
+ method_conv= MI_STATS_METHOD_NULLS_EQUAL;
break;
}
global_system_variables.myisam_stats_method= method_conv;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 57903ffe7b9..f5e8a799c4c 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -2513,8 +2513,9 @@ void SEL_ARG::test_use_count(SEL_ARG *root)
ulong count=count_key_part_usage(root,pos->next_key_part);
if (count > pos->next_key_part->use_count)
{
- sql_print_information("Use_count: Wrong count for key at %lx, %lu should be %lu",
- pos,pos->next_key_part->use_count,count);
+ sql_print_information("Use_count: Wrong count for key at %lx, %lu "
+ "should be %lu", (long unsigned int)pos,
+ pos->next_key_part->use_count, count);
return;
}
pos->next_key_part->test_use_count(root);
@@ -2522,7 +2523,7 @@ void SEL_ARG::test_use_count(SEL_ARG *root)
}
if (e_count != elements)
sql_print_warning("Wrong use count: %u (should be %u) for tree at %lx",
- e_count, elements, (gptr) this);
+ e_count, elements, (long unsigned int) this);
}
#endif
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 1d994f1c98f..8d6db6bf688 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -1150,14 +1150,14 @@ static void fix_net_retry_count(THD *thd, enum_var_type type)
thd->net.retry_count=thd->variables.net_retry_count;
}
#else /* HAVE_REPLICATION */
-static void fix_net_read_timeout(THD *thd __attribute__(unused),
- enum_var_type type __attribute__(unused))
+static void fix_net_read_timeout(THD *thd __attribute__((unused)),
+ enum_var_type type __attribute__((unused)))
{}
-static void fix_net_write_timeout(THD *thd __attribute__(unused),
- enum_var_type type __attribute__(unused))
+static void fix_net_write_timeout(THD *thd __attribute__((unused)),
+ enum_var_type type __attribute__((unused)))
{}
-static void fix_net_retry_count(THD *thd __attribute__(unused),
- enum_var_type type __attribute__(unused))
+static void fix_net_retry_count(THD *thd __attribute__((unused)),
+ enum_var_type type __attribute__((unused)))
{}
#endif /* HAVE_REPLICATION */
diff --git a/sql/slave.cc b/sql/slave.cc
index b2862a437bb..ff1da2541d4 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -4073,7 +4073,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
suppress_warnings= 0;
sql_print_error("Slave I/O thread: error %s to master \
'%s@%s:%d': \
-Error: '%s' errno: %d retry-time: %d retries: %d",
+Error: '%s' errno: %d retry-time: %d retries: %lu",
(reconnect ? "reconnecting" : "connecting"),
mi->user,mi->host,mi->port,
mysql_error(mysql), last_errno,
diff --git a/sql/slave.h b/sql/slave.h
index f780b7c8473..dccfcf01a8f 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -551,7 +551,8 @@ const char *rewrite_db(const char* db, uint32 *new_db_len);
const char *print_slave_db_safe(const char *db);
int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int error_code);
void skip_load_data_infile(NET* net);
-void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...);
+void slave_print_error(RELAY_LOG_INFO *rli, int err_code, const char *msg, ...)
+ ATTRIBUTE_FORMAT(printf, 3, 4);
void end_slave(); /* clean up */
void init_master_info_with_options(MASTER_INFO* mi);
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 734bccb6b46..affab490656 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -426,7 +426,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
"case that has been forced to lowercase because "
"lower_case_table_names is set. It will not be "
"possible to remove this privilege using REVOKE.",
- db.db, db.user, db.host.hostname, db.host.hostname);
+ db.db, db.user, db.host.hostname);
}
}
db.sort=get_sort(3,db.host.hostname,db.db,db.user);
@@ -2778,7 +2778,7 @@ static my_bool grant_load(TABLE_LIST *tables)
sql_print_warning("'tables_priv' entry '%s %s@%s' "
"ignored in --skip-name-resolve mode.",
mem_check->tname, mem_check->user,
- mem_check->host);
+ mem_check->host.hostname);
continue;
}
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index e8fe175cd7c..fe5ceb4c754 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -145,7 +145,7 @@ public:
bool no_auto_events_arg, ulong max_size);
void new_file(bool need_lock= 1);
bool write(THD *thd, enum enum_server_command command,
- const char *format,...);
+ const char *format, ...) ATTRIBUTE_FORMAT(printf, 4, 5);
bool write(THD *thd, const char *query, uint query_length,
time_t query_start=0);
bool write(Log_event* event_info); // binary log write
From f25b8f20d21e15be7ca7eb71f3bbbed539924fc1 Mon Sep 17 00:00:00 2001
From: "ramil/ram@mysql.com/myoffice.izhnet.ru" <>
Date: Tue, 29 Aug 2006 14:38:02 +0500
Subject: [PATCH 02/19] Fix for bug #21142: Malformed insert causes a
segmentation fault. - possible stack overflow fixed.
---
client/mysql.cc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/client/mysql.cc b/client/mysql.cc
index 09818ae27b3..1a967ed8364 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -2615,7 +2615,7 @@ com_connect(String *buffer, char *line)
bzero(buff, sizeof(buff));
if (buffer)
{
- strmov(buff, line);
+ strmake(buff, line, sizeof(buff) - 1);
tmp= get_arg(buff, 0);
if (tmp && *tmp)
{
@@ -2729,7 +2729,7 @@ com_use(String *buffer __attribute__((unused)), char *line)
char *tmp, buff[FN_REFLEN + 1];
bzero(buff, sizeof(buff));
- strmov(buff, line);
+ strmake(buff, line, sizeof(buff) - 1);
tmp= get_arg(buff, 0);
if (!tmp || !*tmp)
{
From 13200c3f9616cc10d1d077799f4d9945693350bc Mon Sep 17 00:00:00 2001
From: "tnurnberg@salvation.intern.azundris.com" <>
Date: Mon, 4 Sep 2006 09:13:40 +0200
Subject: [PATCH 03/19] Bug#21913: DATE_FORMAT() Crashes mysql server if I use
it through mysql-connector-j driver.
Variable character_set_results can legally be NULL (for "no conversion.")
This could result in a NULL deref that crashed the server. Fixed.
(Although ran some additional precursory tests to see whether I could break
anything else, but no breakage so far.)
---
mysql-test/r/func_time.result | 12 ++++++++++++
mysql-test/t/func_time.test | 18 ++++++++++++++++++
sql/sql_string.cc | 7 ++++++-
3 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index fab0bf01f58..07a46f92469 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -688,3 +688,15 @@ t1 CREATE TABLE `t1` (
`from_unixtime(1) + 0` double(23,6) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
+SET NAMES latin1;
+SET character_set_results = NULL;
+SHOW VARIABLES LIKE 'character_set_results';
+Variable_name Value
+character_set_results
+CREATE TABLE testBug8868 (field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY);
+INSERT INTO testBug8868 VALUES ('2006-09-04', 'abcd');
+SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868;
+fmtddate field2
+Sep-4 12:00AM abcd
+DROP TABLE testBug8868;
+SET NAMES DEFAULT;
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index b232fb14e1e..8a7f8792081 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -358,4 +358,22 @@ create table t1 select now() - now(), curtime() - curtime(),
show create table t1;
drop table t1;
+#
+# 21913: DATE_FORMAT() Crashes mysql server if I use it through
+# mysql-connector-j driver.
+#
+
+SET NAMES latin1;
+SET character_set_results = NULL;
+SHOW VARIABLES LIKE 'character_set_results';
+
+CREATE TABLE testBug8868 (field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY);
+INSERT INTO testBug8868 VALUES ('2006-09-04', 'abcd');
+
+SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868;
+
+DROP TABLE testBug8868;
+
+SET NAMES DEFAULT;
+
# End of 4.1 tests
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 939ffe8d9d2..aaa85b0d96c 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -248,6 +248,10 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs)
0 No conversion needed
1 Either character set conversion or adding leading zeros
(e.g. for UCS-2) must be done
+
+ NOTE
+ to_cs may be NULL for "no conversion" if the system variable
+ character_set_results is NULL.
*/
bool String::needs_conversion(uint32 arg_length,
@@ -256,7 +260,8 @@ bool String::needs_conversion(uint32 arg_length,
uint32 *offset)
{
*offset= 0;
- if ((to_cs == &my_charset_bin) ||
+ if (!to_cs ||
+ (to_cs == &my_charset_bin) ||
(to_cs == from_cs) ||
my_charset_same(from_cs, to_cs) ||
((from_cs == &my_charset_bin) &&
From f4265f7a5741517799b17b493cebffb6bbb86571 Mon Sep 17 00:00:00 2001
From: "tsmith@maint1.mysql.com" <>
Date: Thu, 7 Sep 2006 00:01:00 +0200
Subject: [PATCH 04/19] Bug #21250: esolve stack traces on AMD64 (backport to
mysql-4.1)
---
sql/stacktrace.c | 55 +++++++++++++++++++++++++++++++++++-------------
sql/stacktrace.h | 8 +++++--
2 files changed, 46 insertions(+), 17 deletions(-)
diff --git a/sql/stacktrace.c b/sql/stacktrace.c
index 838f547dc02..43f35c452f7 100644
--- a/sql/stacktrace.c
+++ b/sql/stacktrace.c
@@ -21,6 +21,7 @@
#ifdef HAVE_STACKTRACE
#include
+#include
#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
@@ -44,7 +45,29 @@ void safe_print_str(const char* name, const char* val, int max_len)
}
#ifdef TARGET_OS_LINUX
-#define SIGRETURN_FRAME_COUNT 2
+
+#ifdef __i386__
+#define SIGRETURN_FRAME_OFFSET 17
+#endif
+
+#ifdef __x86_64__
+#define SIGRETURN_FRAME_OFFSET 23
+#endif
+
+static my_bool is_nptl;
+
+/* Check if we are using NPTL or LinuxThreads on Linux */
+void check_thread_lib(void)
+{
+ char buf[5];
+
+#ifdef _CS_GNU_LIBPTHREAD_VERSION
+ confstr(_CS_GNU_LIBPTHREAD_VERSION, buf, sizeof(buf));
+ is_nptl = !strncasecmp(buf, "NPTL", sizeof(buf));
+#else
+ is_nptl = 0;
+#endif
+}
#if defined(__alpha__) && defined(__GNUC__)
/*
@@ -90,7 +113,7 @@ inline uint32* find_prev_pc(uint32* pc, uchar** fp)
void print_stacktrace(gptr stack_bottom, ulong thread_stack)
{
uchar** fp;
- uint frame_count = 0;
+ uint frame_count = 0, sigreturn_frame_count;
#if defined(__alpha__) && defined(__GNUC__)
uint32* pc;
#endif
@@ -100,28 +123,27 @@ void print_stacktrace(gptr stack_bottom, ulong thread_stack)
Attempting backtrace. You can use the following information to find out\n\
where mysqld died. If you see no messages after this, something went\n\
terribly wrong...\n");
-#ifdef __i386__
+#ifdef __i386__
__asm __volatile__ ("movl %%ebp,%0"
:"=r"(fp)
:"r"(fp));
- if (!fp)
- {
- fprintf(stderr, "frame pointer (ebp) is NULL, did you compile with\n\
--fomit-frame-pointer? Aborting backtrace!\n");
- return;
- }
+#endif
+#ifdef __x86_64__
+ __asm __volatile__ ("movq %%rbp,%0"
+ :"=r"(fp)
+ :"r"(fp));
#endif
#if defined(__alpha__) && defined(__GNUC__)
__asm __volatile__ ("mov $30,%0"
:"=r"(fp)
:"r"(fp));
+#endif
if (!fp)
{
- fprintf(stderr, "frame pointer (fp) is NULL, did you compile with\n\
+ fprintf(stderr, "frame pointer is NULL, did you compile with\n\
-fomit-frame-pointer? Aborting backtrace!\n");
return;
}
-#endif /* __alpha__ */
if (!stack_bottom || (gptr) stack_bottom > (gptr) &fp)
{
@@ -151,13 +173,16 @@ terribly wrong...\n");
:"r"(pc));
#endif /* __alpha__ */
+ /* We are 1 frame above signal frame with NPTL and 2 frames above with LT */
+ sigreturn_frame_count = is_nptl ? 1 : 2;
+
while (fp < (uchar**) stack_bottom)
{
-#ifdef __i386__
+#if defined(__i386__) || defined(__x86_64__)
uchar** new_fp = (uchar**)*fp;
- fprintf(stderr, "%p\n", frame_count == SIGRETURN_FRAME_COUNT ?
- *(fp+17) : *(fp+1));
-#endif /* __386__ */
+ fprintf(stderr, "%p\n", frame_count == sigreturn_frame_count ?
+ *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1));
+#endif /* defined(__386__) || defined(__x86_64__) */
#if defined(__alpha__) && defined(__GNUC__)
uchar** new_fp = find_prev_fp(pc, fp);
diff --git a/sql/stacktrace.h b/sql/stacktrace.h
index d5d1e05ef0e..527d10d70a2 100644
--- a/sql/stacktrace.h
+++ b/sql/stacktrace.h
@@ -19,16 +19,20 @@ extern "C" {
#endif
#ifdef TARGET_OS_LINUX
-#if defined(HAVE_STACKTRACE) || (defined (__i386__) || (defined(__alpha__) && defined(__GNUC__)))
+#if defined(HAVE_STACKTRACE) || (defined (__x86_64__) || defined (__i386__) || (defined(__alpha__) && defined(__GNUC__)))
#undef HAVE_STACKTRACE
#define HAVE_STACKTRACE
extern char* __bss_start;
extern char* heap_start;
-#define init_stacktrace() { heap_start = (char*) &__bss_start; }
+#define init_stacktrace() do { \
+ heap_start = (char*) &__bss_start; \
+ check_thread_lib(); \
+ } while(0);
void print_stacktrace(gptr stack_bottom, ulong thread_stack);
void safe_print_str(const char* name, const char* val, int max_len);
+void check_thread_lib(void);
#endif /* (defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) */
#endif /* TARGET_OS_LINUX */
From b6cd727ed1f722ae37f9302196f6f20121bbbb4d Mon Sep 17 00:00:00 2001
From: "tsmith@maint1.mysql.com" <>
Date: Thu, 7 Sep 2006 00:11:43 +0200
Subject: [PATCH 05/19] Bug #21054: myisam_stats_method ignored in my.cnf and
cmdline Fix OPT_MYISAM_STATS_METHOD case, where the NULLS_EQUAL and
NULLS_NOT_EQUAL methods were mixed up
---
sql/mysqld.cc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index fc3ca5085cf..71a0e35925e 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -6537,10 +6537,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
}
switch (method-1) {
case 0:
- method_conv= MI_STATS_METHOD_NULLS_EQUAL;
+ method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
break;
case 1:
- method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
+ method_conv= MI_STATS_METHOD_NULLS_EQUAL;
break;
case 2:
method_conv= MI_STATS_METHOD_IGNORE_NULLS;
From 268c7a352280cf2e2bc334296866b46867777c64 Mon Sep 17 00:00:00 2001
From: "kaa@polly.local" <>
Date: Fri, 8 Sep 2006 14:08:29 +0400
Subject: [PATCH 06/19] Bug #20924: CAST(expr as UNSIGNED) returns SIGNED value
when used in various functions - Honor unsigned_flag in the corresponding
functions - Use compare_int_signed_unsigned()/compare_int_unsigned_signed()
instead of explicit comparison in GREATEST() and LEAST()
---
mysql-test/r/case.result | 6 ++++++
mysql-test/r/func_if.result | 6 ++++++
mysql-test/r/func_test.result | 6 ++++++
mysql-test/r/user_var.result | 4 ++++
mysql-test/t/case.test | 6 ++++++
mysql-test/t/func_if.test | 10 ++++++++++
mysql-test/t/func_test.test | 6 ++++++
mysql-test/t/user_var.test | 6 ++++++
sql/item_cmpfunc.cc | 21 +++++++++-----------
sql/item_cmpfunc.h | 14 +++++++++++++
sql/item_func.cc | 37 ++++++++++++++++++++++++++++-------
sql/item_func.h | 2 +-
sql/sql_class.h | 1 +
13 files changed, 105 insertions(+), 20 deletions(-)
diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result
index a5495d0fc3e..ccac701bfc1 100644
--- a/mysql-test/r/case.result
+++ b/mysql-test/r/case.result
@@ -177,3 +177,9 @@ from t1 where b=3 group by b;
min(a) min(case when 1=1 then a else NULL end) min(case when 1!=1 then NULL else a end)
2 2 2
drop table t1;
+SELECT CASE 1 WHEN 1 THEN 18446744073709551615 ELSE 1 END;
+CASE 1 WHEN 1 THEN 18446744073709551615 ELSE 1 END
+18446744073709551615
+SELECT COALESCE(18446744073709551615);
+COALESCE(18446744073709551615)
+18446744073709551615
diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result
index 2c8f19f1754..e9aa195d175 100644
--- a/mysql-test/r/func_if.result
+++ b/mysql-test/r/func_if.result
@@ -99,3 +99,9 @@ a NULLIF(a,'')
NULL NULL
NULL
DROP TABLE t1;
+SELECT IF(1 != 0, 18446744073709551615, 1);
+IF(1 != 0, 18446744073709551615, 1)
+18446744073709551615
+SELECT IFNULL(NULL, 18446744073709551615);
+IFNULL(NULL, 18446744073709551615)
+18446744073709551615
diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result
index 8a28312b348..cc27865cc4c 100644
--- a/mysql-test/r/func_test.result
+++ b/mysql-test/r/func_test.result
@@ -183,3 +183,9 @@ select 5.1 mod 3, 5.1 mod -3, -5.1 mod 3, -5.1 mod -3;
select 5 mod 3, 5 mod -3, -5 mod 3, -5 mod -3;
5 mod 3 5 mod -3 -5 mod 3 -5 mod -3
2 2 -2 -2
+SELECT GREATEST(1, 18446744073709551615);
+GREATEST(1, 18446744073709551615)
+18446744073709551615
+SELECT LEAST(1, 18446744073709551615);
+LEAST(1, 18446744073709551615)
+1
diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result
index 58b785d1432..dce852e84ae 100644
--- a/mysql-test/r/user_var.result
+++ b/mysql-test/r/user_var.result
@@ -203,3 +203,7 @@ select @@global.version;
select @@session.VERSION;
@@session.VERSION
#
+set @a=18446744073709551615;
+select @a;
+@a
+18446744073709551615
diff --git a/mysql-test/t/case.test b/mysql-test/t/case.test
index fd1b6e5247f..b868ae12b69 100644
--- a/mysql-test/t/case.test
+++ b/mysql-test/t/case.test
@@ -130,4 +130,10 @@ select min(a), min(case when 1=1 then a else NULL end),
from t1 where b=3 group by b;
drop table t1;
+#
+# Bug #20924: UNSIGNED values in CASE and COALESCE are treated as SIGNED
+#
+SELECT CASE 1 WHEN 1 THEN 18446744073709551615 ELSE 1 END;
+SELECT COALESCE(18446744073709551615);
+
# End of 4.1 tests
diff --git a/mysql-test/t/func_if.test b/mysql-test/t/func_if.test
index 5756793c673..17117b07437 100644
--- a/mysql-test/t/func_if.test
+++ b/mysql-test/t/func_if.test
@@ -73,4 +73,14 @@ SELECT a, NULLIF(a,'') FROM t1 WHERE NULLIF(a,'') IS NULL;
DROP TABLE t1;
+#
+# Bug #20924: UNSIGNED values in IF() are treated as SIGNED
+#
+SELECT IF(1 != 0, 18446744073709551615, 1);
+
+#
+# Bug #20924: UNSIGNED values in IFNULL() are treated as SIGNED
+#
+SELECT IFNULL(NULL, 18446744073709551615);
+
# End of 4.1 tests
diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test
index 2ad64b6c5a6..631639c7a74 100644
--- a/mysql-test/t/func_test.test
+++ b/mysql-test/t/func_test.test
@@ -108,4 +108,10 @@ select 5.1 mod 3, 5.1 mod -3, -5.1 mod 3, -5.1 mod -3;
select 5 mod 3, 5 mod -3, -5 mod 3, -5 mod -3;
+#
+# Bug #20924: UNSIGNED values in GREATEST() and LEAST() are treated as SIGNED
+#
+SELECT GREATEST(1, 18446744073709551615);
+SELECT LEAST(1, 18446744073709551615);
+
# End of 4.1 tests
diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test
index 7691a574a2a..810d5e96da5 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -141,4 +141,10 @@ select @@global.version;
--replace_column 1 #
select @@session.VERSION;
+#
+# Bug #20924 SET on a user variable saves UNSIGNED as SIGNED
+#
+set @a=18446744073709551615;
+select @a;
+
# End of 4.1 tests
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index f14efc7187b..cf8d0c39d58 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -619,11 +619,7 @@ int Arg_comparator::compare_int_signed_unsigned()
if (!(*b)->null_value)
{
owner->null_value= 0;
- if (sval1 < 0 || (ulonglong)sval1 < uval2)
- return -1;
- if ((ulonglong)sval1 == uval2)
- return 0;
- return 1;
+ return ::compare_int_signed_unsigned(sval1, uval2);
}
}
owner->null_value= 1;
@@ -644,13 +640,7 @@ int Arg_comparator::compare_int_unsigned_signed()
if (!(*b)->null_value)
{
owner->null_value= 0;
- if (sval2 < 0)
- return 1;
- if (uval1 < (ulonglong)sval2)
- return -1;
- if (uval1 == (ulonglong)sval2)
- return 0;
- return 1;
+ return ::compare_int_unsigned_signed(uval1, sval2);
}
}
owner->null_value= 1;
@@ -1162,11 +1152,13 @@ Item_func_ifnull::val_int()
if (!args[0]->null_value)
{
null_value=0;
+ unsigned_flag= args[0]->unsigned_flag;
return value;
}
value=args[1]->val_int();
if ((null_value=args[1]->null_value))
return 0;
+ unsigned_flag= args[1]->unsigned_flag;
return value;
}
@@ -1286,6 +1278,7 @@ Item_func_if::val_int()
Item *arg= args[0]->val_int() ? args[1] : args[2];
longlong value=arg->val_int();
null_value=arg->null_value;
+ unsigned_flag= arg->unsigned_flag;
return value;
}
@@ -1492,6 +1485,7 @@ longlong Item_func_case::val_int()
}
res=item->val_int();
null_value=item->null_value;
+ unsigned_flag= item->unsigned_flag;
return res;
}
@@ -1623,7 +1617,10 @@ longlong Item_func_coalesce::val_int()
{
longlong res=args[i]->val_int();
if (!args[i]->null_value)
+ {
+ unsigned_flag= args[i]->unsigned_flag;
return res;
+ }
}
null_value=1;
return 0;
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 73abe208d9e..513260205c2 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1077,3 +1077,17 @@ inline Item *and_conds(Item *a, Item *b)
}
Item *and_expressions(Item *a, Item *b, Item **org_item);
+
+inline int compare_int_signed_unsigned(longlong sval, ulonglong uval)
+{
+ if (sval < 0 || (ulonglong)sval < uval)
+ return -1;
+ if ((ulonglong)sval == uval)
+ return 0;
+ return 1;
+}
+
+inline int compare_int_unsigned_signed(ulonglong uval, longlong sval)
+{
+ return -compare_int_signed_unsigned(sval, uval);
+}
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 91ccef6511f..85865ad6fb6 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1235,19 +1235,35 @@ longlong Item_func_min_max::val_int()
{
DBUG_ASSERT(fixed == 1);
longlong value=0;
+ my_bool arg_unsigned_flag;
+ my_bool cmp;
null_value=1;
for (uint i=0; i < arg_count ; i++)
{
+ longlong tmp= args[i]->val_int();
+ arg_unsigned_flag= args[i]->unsigned_flag;
if (null_value)
{
- value=args[i]->val_int();
+ value= tmp;
null_value=args[i]->null_value;
+ unsigned_flag= arg_unsigned_flag;
}
else
{
- longlong tmp=args[i]->val_int();
- if (!args[i]->null_value && (tmp < value ? cmp_sign : -cmp_sign) > 0)
- value=tmp;
+ if (args[i]->null_value)
+ continue;
+ if (unsigned_flag && arg_unsigned_flag ||
+ (!unsigned_flag && !arg_unsigned_flag))
+ cmp= tmp < value;
+ else if (unsigned_flag)
+ cmp= compare_int_signed_unsigned(tmp, value) < 0;
+ else
+ cmp= compare_int_unsigned_signed(tmp, value) < 0;
+ if ((cmp ? cmp_sign : -cmp_sign) > 0)
+ {
+ value= tmp;
+ unsigned_flag= arg_unsigned_flag;
+ }
}
}
return value;
@@ -2313,6 +2329,7 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
entry->length=0;
entry->update_query_id=0;
entry->collation.set(NULL, DERIVATION_IMPLICIT);
+ entry->unsigned_flag= 0;
/*
If we are here, we were called from a SET or a query which sets a
variable. Imagine it is this:
@@ -2390,7 +2407,7 @@ Item_func_set_user_var::fix_length_and_dec()
bool Item_func_set_user_var::update_hash(void *ptr, uint length,
Item_result type,
CHARSET_INFO *cs,
- Derivation dv)
+ Derivation dv, bool unsigned_arg)
{
if ((null_value=args[0]->null_value))
{
@@ -2437,6 +2454,7 @@ bool Item_func_set_user_var::update_hash(void *ptr, uint length,
entry->length= length;
entry->type=type;
entry->collation.set(cs, dv);
+ entry->unsigned_flag= unsigned_arg;
}
return 0;
@@ -2507,7 +2525,10 @@ String *user_var_entry::val_str(my_bool *null_value, String *str,
str->set(*(double*) value, decimals, &my_charset_bin);
break;
case INT_RESULT:
- str->set(*(longlong*) value, &my_charset_bin);
+ if (!unsigned_flag)
+ str->set(*(longlong*) value, &my_charset_bin);
+ else
+ str->set(*(ulonglong*) value, &my_charset_bin);
break;
case STRING_RESULT:
if (str->copy(value, length, collation.collation))
@@ -2548,6 +2569,7 @@ Item_func_set_user_var::check()
case INT_RESULT:
{
save_result.vint= args[0]->val_int();
+ unsigned_flag= args[0]->unsigned_flag;
break;
}
case STRING_RESULT:
@@ -2598,7 +2620,8 @@ Item_func_set_user_var::update()
case INT_RESULT:
{
res= update_hash((void*) &save_result.vint, sizeof(save_result.vint),
- INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT);
+ INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT,
+ unsigned_flag);
break;
}
case STRING_RESULT:
diff --git a/sql/item_func.h b/sql/item_func.h
index f4a1258a02c..d9e1396fde6 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -962,7 +962,7 @@ public:
longlong val_int();
String *val_str(String *str);
bool update_hash(void *ptr, uint length, enum Item_result type,
- CHARSET_INFO *cs, Derivation dv);
+ CHARSET_INFO *cs, Derivation dv, bool unsigned_arg= 0);
bool check();
bool update();
enum Item_result result_type () const { return cached_result_type; }
diff --git a/sql/sql_class.h b/sql/sql_class.h
index f1cf9c7b3e2..2db0077c0b4 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1460,6 +1460,7 @@ class user_var_entry
char *value;
ulong length, update_query_id, used_query_id;
Item_result type;
+ bool unsigned_flag;
double val(my_bool *null_value);
longlong val_int(my_bool *null_value);
From c5d70b1a931d06ed143e6067e749885fe9a46618 Mon Sep 17 00:00:00 2001
From: "knielsen@ymer.(none)" <>
Date: Mon, 11 Sep 2006 16:49:44 +0200
Subject: [PATCH 07/19] BUG#16282
Build gcc.o as a small library, instead of passing .cpp sources to the
linker command (causes problems with parallel make on Solaris).
This fix is for 4.1. In 5.0 and up a different fix is used.
---
ndb/config/common.mk.am | 2 +-
ndb/config/type_ndbapitools.mk.am | 2 +-
ndb/src/common/portlib/Makefile.am | 3 ++-
ndb/src/kernel/Makefile.am | 3 ++-
4 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/ndb/config/common.mk.am b/ndb/config/common.mk.am
index 869e2fae91d..4df1b0e289a 100644
--- a/ndb/config/common.mk.am
+++ b/ndb/config/common.mk.am
@@ -7,6 +7,6 @@ ndbapiincludedir = "$(pkgincludedir)/ndb/ndbapi"
mgmapiincludedir = "$(pkgincludedir)/ndb/mgmapi"
INCLUDES = $(INCLUDES_LOC)
-LDADD = $(top_srcdir)/ndb/src/common/portlib/gcc.cpp $(LDADD_LOC)
+LDADD = $(LDADD_LOC) -L$(top_srcdir)/ndb/src/common/portlib -lmygcc
DEFS = @DEFS@ @NDB_DEFS@ $(DEFS_LOC) $(NDB_EXTRA_FLAGS)
NDB_CXXFLAGS=@ndb_cxxflags_fix@ $(NDB_CXXFLAGS_LOC)
diff --git a/ndb/config/type_ndbapitools.mk.am b/ndb/config/type_ndbapitools.mk.am
index d4eb090112d..679dac09f47 100644
--- a/ndb/config/type_ndbapitools.mk.am
+++ b/ndb/config/type_ndbapitools.mk.am
@@ -3,7 +3,7 @@ LDADD += \
$(top_builddir)/ndb/src/libndbclient.la \
$(top_builddir)/dbug/libdbug.a \
$(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
+ $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ -lmygcc
INCLUDES += -I$(srcdir) -I$(top_srcdir)/include \
-I$(top_srcdir)/ndb/include \
diff --git a/ndb/src/common/portlib/Makefile.am b/ndb/src/common/portlib/Makefile.am
index 99138a7414e..67b5dbc3001 100644
--- a/ndb/src/common/portlib/Makefile.am
+++ b/ndb/src/common/portlib/Makefile.am
@@ -1,4 +1,5 @@
-noinst_HEADERS = gcc.cpp
+noinst_LIBRARIES = libmygcc.a
+libmygcc_a_SOURCES = gcc.cpp
noinst_LTLIBRARIES = libportlib.la
diff --git a/ndb/src/kernel/Makefile.am b/ndb/src/kernel/Makefile.am
index 389cb85c1d8..5b55238c262 100644
--- a/ndb/src/kernel/Makefile.am
+++ b/ndb/src/kernel/Makefile.am
@@ -53,7 +53,8 @@ LDADD += \
$(top_builddir)/ndb/src/common/util/libgeneral.la \
$(top_builddir)/dbug/libdbug.a \
$(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
+ $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ -lmygcc
+
# Don't update the files from bitkeeper
%::SCCS/s.%
From 5df7611caa310a88666f7fd2a7f14bd23ca8e24a Mon Sep 17 00:00:00 2001
From: "kaa@polly.local" <>
Date: Tue, 12 Sep 2006 16:25:40 +0400
Subject: [PATCH 08/19] Post-review fixes for bug #20924
---
mysql-test/r/case.result | 1 +
mysql-test/r/func_if.result | 1 +
mysql-test/r/func_test.result | 1 +
mysql-test/r/user_var.result | 1 +
mysql-test/t/case.test | 6 ++++--
mysql-test/t/func_if.test | 10 +++++++---
mysql-test/t/func_test.test | 6 ++++--
mysql-test/t/user_var.test | 6 ++++--
sql/item_func.cc | 13 ++++++-------
sql/item_func.h | 2 +-
sql/log_event.cc | 2 +-
11 files changed, 31 insertions(+), 18 deletions(-)
diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result
index ccac701bfc1..db56fd82f72 100644
--- a/mysql-test/r/case.result
+++ b/mysql-test/r/case.result
@@ -183,3 +183,4 @@ CASE 1 WHEN 1 THEN 18446744073709551615 ELSE 1 END
SELECT COALESCE(18446744073709551615);
COALESCE(18446744073709551615)
18446744073709551615
+End of 4.1 tests
diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result
index e9aa195d175..72275039ba7 100644
--- a/mysql-test/r/func_if.result
+++ b/mysql-test/r/func_if.result
@@ -105,3 +105,4 @@ IF(1 != 0, 18446744073709551615, 1)
SELECT IFNULL(NULL, 18446744073709551615);
IFNULL(NULL, 18446744073709551615)
18446744073709551615
+End of 4.1 tests
diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result
index cc27865cc4c..7c9827a5005 100644
--- a/mysql-test/r/func_test.result
+++ b/mysql-test/r/func_test.result
@@ -189,3 +189,4 @@ GREATEST(1, 18446744073709551615)
SELECT LEAST(1, 18446744073709551615);
LEAST(1, 18446744073709551615)
1
+End of 4.1 tests
diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result
index dce852e84ae..6797fb0799d 100644
--- a/mysql-test/r/user_var.result
+++ b/mysql-test/r/user_var.result
@@ -207,3 +207,4 @@ set @a=18446744073709551615;
select @a;
@a
18446744073709551615
+End of 4.1 tests
diff --git a/mysql-test/t/case.test b/mysql-test/t/case.test
index b868ae12b69..d0d503a8821 100644
--- a/mysql-test/t/case.test
+++ b/mysql-test/t/case.test
@@ -131,9 +131,11 @@ from t1 where b=3 group by b;
drop table t1;
#
-# Bug #20924: UNSIGNED values in CASE and COALESCE are treated as SIGNED
+# Bug #20924: CAST(expr as UNSIGNED) returns SIGNED value when used in various
+# functions
+# - UNSIGNED values in CASE and COALESCE are treated as SIGNED
#
SELECT CASE 1 WHEN 1 THEN 18446744073709551615 ELSE 1 END;
SELECT COALESCE(18446744073709551615);
-# End of 4.1 tests
+--echo End of 4.1 tests
diff --git a/mysql-test/t/func_if.test b/mysql-test/t/func_if.test
index 17117b07437..69cfcf7860b 100644
--- a/mysql-test/t/func_if.test
+++ b/mysql-test/t/func_if.test
@@ -74,13 +74,17 @@ SELECT a, NULLIF(a,'') FROM t1 WHERE NULLIF(a,'') IS NULL;
DROP TABLE t1;
#
-# Bug #20924: UNSIGNED values in IF() are treated as SIGNED
+# Bug #20924: CAST(expr as UNSIGNED) returns SIGNED value when used in various
+# functions
+# - UNSIGNED values in IF() are treated as SIGNED
#
SELECT IF(1 != 0, 18446744073709551615, 1);
#
-# Bug #20924: UNSIGNED values in IFNULL() are treated as SIGNED
+# Bug #20924: CAST(expr as UNSIGNED) returns SIGNED value when used in various
+# functions
+# - UNSIGNED values in IFNULL() are treated as SIGNED
#
SELECT IFNULL(NULL, 18446744073709551615);
-# End of 4.1 tests
+--echo End of 4.1 tests
diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test
index 631639c7a74..549b0e60246 100644
--- a/mysql-test/t/func_test.test
+++ b/mysql-test/t/func_test.test
@@ -109,9 +109,11 @@ select 5.1 mod 3, 5.1 mod -3, -5.1 mod 3, -5.1 mod -3;
select 5 mod 3, 5 mod -3, -5 mod 3, -5 mod -3;
#
-# Bug #20924: UNSIGNED values in GREATEST() and LEAST() are treated as SIGNED
+# Bug #20924: CAST(expr as UNSIGNED) returns SIGNED value when used in various
+# functions
+# - UNSIGNED values in GREATEST() and LEAST() are treated as SIGNED
#
SELECT GREATEST(1, 18446744073709551615);
SELECT LEAST(1, 18446744073709551615);
-# End of 4.1 tests
+--echo End of 4.1 tests
diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test
index 810d5e96da5..b7c8f962637 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -142,9 +142,11 @@ select @@global.version;
select @@session.VERSION;
#
-# Bug #20924 SET on a user variable saves UNSIGNED as SIGNED
+# Bug #20924: CAST(expr as UNSIGNED) returns SIGNED value when used in various
+# functions
+# - SET on a user variable saves UNSIGNED as SIGNED
#
set @a=18446744073709551615;
select @a;
-# End of 4.1 tests
+--echo End of 4.1 tests
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 85865ad6fb6..d43dadfa4a4 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1252,8 +1252,7 @@ longlong Item_func_min_max::val_int()
{
if (args[i]->null_value)
continue;
- if (unsigned_flag && arg_unsigned_flag ||
- (!unsigned_flag && !arg_unsigned_flag))
+ if (unsigned_flag == arg_unsigned_flag)
cmp= tmp < value;
else if (unsigned_flag)
cmp= compare_int_signed_unsigned(tmp, value) < 0;
@@ -2614,26 +2613,26 @@ Item_func_set_user_var::update()
case REAL_RESULT:
{
res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal),
- REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT);
+ REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
break;
}
case INT_RESULT:
{
res= update_hash((void*) &save_result.vint, sizeof(save_result.vint),
- INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT,
- unsigned_flag);
+ INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT,
+ unsigned_flag);
break;
}
case STRING_RESULT:
{
if (!save_result.vstr) // Null value
res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin,
- DERIVATION_IMPLICIT);
+ DERIVATION_IMPLICIT, 0);
else
res= update_hash((void*) save_result.vstr->ptr(),
save_result.vstr->length(), STRING_RESULT,
save_result.vstr->charset(),
- DERIVATION_IMPLICIT);
+ DERIVATION_IMPLICIT, 0);
break;
}
case ROW_RESULT:
diff --git a/sql/item_func.h b/sql/item_func.h
index d9e1396fde6..3a29b9d6f15 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -962,7 +962,7 @@ public:
longlong val_int();
String *val_str(String *str);
bool update_hash(void *ptr, uint length, enum Item_result type,
- CHARSET_INFO *cs, Derivation dv, bool unsigned_arg= 0);
+ CHARSET_INFO *cs, Derivation dv, bool unsigned_arg);
bool check();
bool update();
enum Item_result result_type () const { return cached_result_type; }
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 19c32b2d28e..ef375a30441 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -2607,7 +2607,7 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli)
a single record and with a single column. Thus, like
a column value, it could always have IMPLICIT derivation.
*/
- e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT);
+ e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, 0);
free_root(thd->mem_root,0);
rli->inc_event_relay_log_pos(get_event_len());
From 397f0df9ad2df62698d4c1824c965c4b884b990c Mon Sep 17 00:00:00 2001
From: "kaa@polly.local" <>
Date: Wed, 13 Sep 2006 14:41:28 +0400
Subject: [PATCH 09/19] Cset exclude:
kaa@polly.local|ChangeSet|20060912122540|09861 Cset exclude:
kaa@polly.local|ChangeSet|20060908100829|09983
---
mysql-test/r/case.result | 7 ------
mysql-test/r/func_if.result | 7 ------
mysql-test/r/func_test.result | 7 ------
mysql-test/r/user_var.result | 5 -----
mysql-test/t/case.test | 10 +--------
mysql-test/t/func_if.test | 16 +------------
mysql-test/t/func_test.test | 10 +--------
mysql-test/t/user_var.test | 10 +--------
sql/item_cmpfunc.cc | 21 ++++++++++--------
sql/item_cmpfunc.h | 14 ------------
sql/item_func.cc | 42 +++++++++--------------------------
sql/item_func.h | 2 +-
sql/log_event.cc | 2 +-
sql/sql_class.h | 1 -
14 files changed, 28 insertions(+), 126 deletions(-)
diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result
index db56fd82f72..a5495d0fc3e 100644
--- a/mysql-test/r/case.result
+++ b/mysql-test/r/case.result
@@ -177,10 +177,3 @@ from t1 where b=3 group by b;
min(a) min(case when 1=1 then a else NULL end) min(case when 1!=1 then NULL else a end)
2 2 2
drop table t1;
-SELECT CASE 1 WHEN 1 THEN 18446744073709551615 ELSE 1 END;
-CASE 1 WHEN 1 THEN 18446744073709551615 ELSE 1 END
-18446744073709551615
-SELECT COALESCE(18446744073709551615);
-COALESCE(18446744073709551615)
-18446744073709551615
-End of 4.1 tests
diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result
index 72275039ba7..2c8f19f1754 100644
--- a/mysql-test/r/func_if.result
+++ b/mysql-test/r/func_if.result
@@ -99,10 +99,3 @@ a NULLIF(a,'')
NULL NULL
NULL
DROP TABLE t1;
-SELECT IF(1 != 0, 18446744073709551615, 1);
-IF(1 != 0, 18446744073709551615, 1)
-18446744073709551615
-SELECT IFNULL(NULL, 18446744073709551615);
-IFNULL(NULL, 18446744073709551615)
-18446744073709551615
-End of 4.1 tests
diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result
index 7c9827a5005..8a28312b348 100644
--- a/mysql-test/r/func_test.result
+++ b/mysql-test/r/func_test.result
@@ -183,10 +183,3 @@ select 5.1 mod 3, 5.1 mod -3, -5.1 mod 3, -5.1 mod -3;
select 5 mod 3, 5 mod -3, -5 mod 3, -5 mod -3;
5 mod 3 5 mod -3 -5 mod 3 -5 mod -3
2 2 -2 -2
-SELECT GREATEST(1, 18446744073709551615);
-GREATEST(1, 18446744073709551615)
-18446744073709551615
-SELECT LEAST(1, 18446744073709551615);
-LEAST(1, 18446744073709551615)
-1
-End of 4.1 tests
diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result
index 6797fb0799d..58b785d1432 100644
--- a/mysql-test/r/user_var.result
+++ b/mysql-test/r/user_var.result
@@ -203,8 +203,3 @@ select @@global.version;
select @@session.VERSION;
@@session.VERSION
#
-set @a=18446744073709551615;
-select @a;
-@a
-18446744073709551615
-End of 4.1 tests
diff --git a/mysql-test/t/case.test b/mysql-test/t/case.test
index d0d503a8821..fd1b6e5247f 100644
--- a/mysql-test/t/case.test
+++ b/mysql-test/t/case.test
@@ -130,12 +130,4 @@ select min(a), min(case when 1=1 then a else NULL end),
from t1 where b=3 group by b;
drop table t1;
-#
-# Bug #20924: CAST(expr as UNSIGNED) returns SIGNED value when used in various
-# functions
-# - UNSIGNED values in CASE and COALESCE are treated as SIGNED
-#
-SELECT CASE 1 WHEN 1 THEN 18446744073709551615 ELSE 1 END;
-SELECT COALESCE(18446744073709551615);
-
---echo End of 4.1 tests
+# End of 4.1 tests
diff --git a/mysql-test/t/func_if.test b/mysql-test/t/func_if.test
index 69cfcf7860b..5756793c673 100644
--- a/mysql-test/t/func_if.test
+++ b/mysql-test/t/func_if.test
@@ -73,18 +73,4 @@ SELECT a, NULLIF(a,'') FROM t1 WHERE NULLIF(a,'') IS NULL;
DROP TABLE t1;
-#
-# Bug #20924: CAST(expr as UNSIGNED) returns SIGNED value when used in various
-# functions
-# - UNSIGNED values in IF() are treated as SIGNED
-#
-SELECT IF(1 != 0, 18446744073709551615, 1);
-
-#
-# Bug #20924: CAST(expr as UNSIGNED) returns SIGNED value when used in various
-# functions
-# - UNSIGNED values in IFNULL() are treated as SIGNED
-#
-SELECT IFNULL(NULL, 18446744073709551615);
-
---echo End of 4.1 tests
+# End of 4.1 tests
diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test
index 549b0e60246..2ad64b6c5a6 100644
--- a/mysql-test/t/func_test.test
+++ b/mysql-test/t/func_test.test
@@ -108,12 +108,4 @@ select 5.1 mod 3, 5.1 mod -3, -5.1 mod 3, -5.1 mod -3;
select 5 mod 3, 5 mod -3, -5 mod 3, -5 mod -3;
-#
-# Bug #20924: CAST(expr as UNSIGNED) returns SIGNED value when used in various
-# functions
-# - UNSIGNED values in GREATEST() and LEAST() are treated as SIGNED
-#
-SELECT GREATEST(1, 18446744073709551615);
-SELECT LEAST(1, 18446744073709551615);
-
---echo End of 4.1 tests
+# End of 4.1 tests
diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test
index b7c8f962637..7691a574a2a 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -141,12 +141,4 @@ select @@global.version;
--replace_column 1 #
select @@session.VERSION;
-#
-# Bug #20924: CAST(expr as UNSIGNED) returns SIGNED value when used in various
-# functions
-# - SET on a user variable saves UNSIGNED as SIGNED
-#
-set @a=18446744073709551615;
-select @a;
-
---echo End of 4.1 tests
+# End of 4.1 tests
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index cf8d0c39d58..f14efc7187b 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -619,7 +619,11 @@ int Arg_comparator::compare_int_signed_unsigned()
if (!(*b)->null_value)
{
owner->null_value= 0;
- return ::compare_int_signed_unsigned(sval1, uval2);
+ if (sval1 < 0 || (ulonglong)sval1 < uval2)
+ return -1;
+ if ((ulonglong)sval1 == uval2)
+ return 0;
+ return 1;
}
}
owner->null_value= 1;
@@ -640,7 +644,13 @@ int Arg_comparator::compare_int_unsigned_signed()
if (!(*b)->null_value)
{
owner->null_value= 0;
- return ::compare_int_unsigned_signed(uval1, sval2);
+ if (sval2 < 0)
+ return 1;
+ if (uval1 < (ulonglong)sval2)
+ return -1;
+ if (uval1 == (ulonglong)sval2)
+ return 0;
+ return 1;
}
}
owner->null_value= 1;
@@ -1152,13 +1162,11 @@ Item_func_ifnull::val_int()
if (!args[0]->null_value)
{
null_value=0;
- unsigned_flag= args[0]->unsigned_flag;
return value;
}
value=args[1]->val_int();
if ((null_value=args[1]->null_value))
return 0;
- unsigned_flag= args[1]->unsigned_flag;
return value;
}
@@ -1278,7 +1286,6 @@ Item_func_if::val_int()
Item *arg= args[0]->val_int() ? args[1] : args[2];
longlong value=arg->val_int();
null_value=arg->null_value;
- unsigned_flag= arg->unsigned_flag;
return value;
}
@@ -1485,7 +1492,6 @@ longlong Item_func_case::val_int()
}
res=item->val_int();
null_value=item->null_value;
- unsigned_flag= item->unsigned_flag;
return res;
}
@@ -1617,10 +1623,7 @@ longlong Item_func_coalesce::val_int()
{
longlong res=args[i]->val_int();
if (!args[i]->null_value)
- {
- unsigned_flag= args[i]->unsigned_flag;
return res;
- }
}
null_value=1;
return 0;
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 513260205c2..73abe208d9e 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1077,17 +1077,3 @@ inline Item *and_conds(Item *a, Item *b)
}
Item *and_expressions(Item *a, Item *b, Item **org_item);
-
-inline int compare_int_signed_unsigned(longlong sval, ulonglong uval)
-{
- if (sval < 0 || (ulonglong)sval < uval)
- return -1;
- if ((ulonglong)sval == uval)
- return 0;
- return 1;
-}
-
-inline int compare_int_unsigned_signed(ulonglong uval, longlong sval)
-{
- return -compare_int_signed_unsigned(sval, uval);
-}
diff --git a/sql/item_func.cc b/sql/item_func.cc
index d43dadfa4a4..91ccef6511f 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1235,34 +1235,19 @@ longlong Item_func_min_max::val_int()
{
DBUG_ASSERT(fixed == 1);
longlong value=0;
- my_bool arg_unsigned_flag;
- my_bool cmp;
null_value=1;
for (uint i=0; i < arg_count ; i++)
{
- longlong tmp= args[i]->val_int();
- arg_unsigned_flag= args[i]->unsigned_flag;
if (null_value)
{
- value= tmp;
+ value=args[i]->val_int();
null_value=args[i]->null_value;
- unsigned_flag= arg_unsigned_flag;
}
else
{
- if (args[i]->null_value)
- continue;
- if (unsigned_flag == arg_unsigned_flag)
- cmp= tmp < value;
- else if (unsigned_flag)
- cmp= compare_int_signed_unsigned(tmp, value) < 0;
- else
- cmp= compare_int_unsigned_signed(tmp, value) < 0;
- if ((cmp ? cmp_sign : -cmp_sign) > 0)
- {
- value= tmp;
- unsigned_flag= arg_unsigned_flag;
- }
+ longlong tmp=args[i]->val_int();
+ if (!args[i]->null_value && (tmp < value ? cmp_sign : -cmp_sign) > 0)
+ value=tmp;
}
}
return value;
@@ -2328,7 +2313,6 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
entry->length=0;
entry->update_query_id=0;
entry->collation.set(NULL, DERIVATION_IMPLICIT);
- entry->unsigned_flag= 0;
/*
If we are here, we were called from a SET or a query which sets a
variable. Imagine it is this:
@@ -2406,7 +2390,7 @@ Item_func_set_user_var::fix_length_and_dec()
bool Item_func_set_user_var::update_hash(void *ptr, uint length,
Item_result type,
CHARSET_INFO *cs,
- Derivation dv, bool unsigned_arg)
+ Derivation dv)
{
if ((null_value=args[0]->null_value))
{
@@ -2453,7 +2437,6 @@ bool Item_func_set_user_var::update_hash(void *ptr, uint length,
entry->length= length;
entry->type=type;
entry->collation.set(cs, dv);
- entry->unsigned_flag= unsigned_arg;
}
return 0;
@@ -2524,10 +2507,7 @@ String *user_var_entry::val_str(my_bool *null_value, String *str,
str->set(*(double*) value, decimals, &my_charset_bin);
break;
case INT_RESULT:
- if (!unsigned_flag)
- str->set(*(longlong*) value, &my_charset_bin);
- else
- str->set(*(ulonglong*) value, &my_charset_bin);
+ str->set(*(longlong*) value, &my_charset_bin);
break;
case STRING_RESULT:
if (str->copy(value, length, collation.collation))
@@ -2568,7 +2548,6 @@ Item_func_set_user_var::check()
case INT_RESULT:
{
save_result.vint= args[0]->val_int();
- unsigned_flag= args[0]->unsigned_flag;
break;
}
case STRING_RESULT:
@@ -2613,26 +2592,25 @@ Item_func_set_user_var::update()
case REAL_RESULT:
{
res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal),
- REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
+ REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT);
break;
}
case INT_RESULT:
{
res= update_hash((void*) &save_result.vint, sizeof(save_result.vint),
- INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT,
- unsigned_flag);
+ INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT);
break;
}
case STRING_RESULT:
{
if (!save_result.vstr) // Null value
res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin,
- DERIVATION_IMPLICIT, 0);
+ DERIVATION_IMPLICIT);
else
res= update_hash((void*) save_result.vstr->ptr(),
save_result.vstr->length(), STRING_RESULT,
save_result.vstr->charset(),
- DERIVATION_IMPLICIT, 0);
+ DERIVATION_IMPLICIT);
break;
}
case ROW_RESULT:
diff --git a/sql/item_func.h b/sql/item_func.h
index 3a29b9d6f15..f4a1258a02c 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -962,7 +962,7 @@ public:
longlong val_int();
String *val_str(String *str);
bool update_hash(void *ptr, uint length, enum Item_result type,
- CHARSET_INFO *cs, Derivation dv, bool unsigned_arg);
+ CHARSET_INFO *cs, Derivation dv);
bool check();
bool update();
enum Item_result result_type () const { return cached_result_type; }
diff --git a/sql/log_event.cc b/sql/log_event.cc
index ef375a30441..19c32b2d28e 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -2607,7 +2607,7 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli)
a single record and with a single column. Thus, like
a column value, it could always have IMPLICIT derivation.
*/
- e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, 0);
+ e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT);
free_root(thd->mem_root,0);
rli->inc_event_relay_log_pos(get_event_len());
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 2db0077c0b4..f1cf9c7b3e2 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1460,7 +1460,6 @@ class user_var_entry
char *value;
ulong length, update_query_id, used_query_id;
Item_result type;
- bool unsigned_flag;
double val(my_bool *null_value);
longlong val_int(my_bool *null_value);
From 66fa757e1f6a3d9373119ac5437e490ead191411 Mon Sep 17 00:00:00 2001
From: "thek@kpdesk.mysql.com" <>
Date: Tue, 19 Sep 2006 12:40:31 +0200
Subject: [PATCH 10/19] Bug#21139 Handling of database differs in "embedded" ,
test lowercase_fs_off fails - Access checks are omitted when compliled
without --with-embedded-privilege-control - Patch: skip this test
---
mysql-test/t/lowercase_fs_off.test | 1 +
1 file changed, 1 insertion(+)
diff --git a/mysql-test/t/lowercase_fs_off.test b/mysql-test/t/lowercase_fs_off.test
index 7f7b573e7ee..883315994fe 100644
--- a/mysql-test/t/lowercase_fs_off.test
+++ b/mysql-test/t/lowercase_fs_off.test
@@ -3,6 +3,7 @@
# i.e. lower_case_filesystem=OFF
#
-- source include/have_case_sensitive_file_system.inc
+-- source include/not_embedded.inc
connect (master,localhost,root,,);
connection master;
From d3f503a0bd4160dc62998777c6d9013cad5e7efe Mon Sep 17 00:00:00 2001
From: "ramil/ram@mysql.com/myoffice.izhnet.ru" <>
Date: Thu, 21 Sep 2006 16:05:01 +0500
Subject: [PATCH 11/19] Fix for bug #20204: "order by" changes the results
returned
Item_substr's results are improperly stored in a temporary table due to
wrongly calculated max_length value for multi-byte charsets if two
arguments specified.
---
mysql-test/r/ctype_utf8.result | 13 +++++++++++++
mysql-test/t/ctype_utf8.test | 12 ++++++++++++
sql/item_strfunc.cc | 3 ++-
3 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 941b834a733..22b6de80a35 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -1352,3 +1352,16 @@ select database();
database()
имя_базы_в_кодировке_утф8_длиной_больше_чем_45
drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45;
+use test;
+create table t1(a char(10)) default charset utf8;
+insert into t1 values ('123'), ('456');
+explain
+select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE Y ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+1 SIMPLE Z ALL NULL NULL NULL NULL 2 Using where
+select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1;
+substr(Z.a,-1) a
+3 123
+6 456
+drop table t1;
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 7272cb79089..90d7ec1b3a0 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -1087,5 +1087,17 @@ create database имя_базы_в_кодировке_утф8_длиной_бо
use имя_базы_в_кодировке_утф8_длиной_больше_чем_45;
select database();
drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45;
+use test;
+
+#
+# Bug #20204: "order by" changes the results returned
+#
+
+create table t1(a char(10)) default charset utf8;
+insert into t1 values ('123'), ('456');
+explain
+ select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1;
+select substr(Z.a,-1), Z.a from t1 as Y join t1 as Z on Y.a=Z.a order by 1;
+drop table t1;
# End of 4.1 tests
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 1ef11945bd5..98888226e58 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1109,12 +1109,13 @@ void Item_func_substr::fix_length_and_dec()
}
if (arg_count == 3 && args[2]->const_item())
{
- int32 length= (int32) args[2]->val_int() * collation.collation->mbmaxlen;
+ int32 length= (int32) args[2]->val_int();
if (length <= 0)
max_length=0; /* purecov: inspected */
else
set_if_smaller(max_length,(uint) length);
}
+ max_length*= collation.collation->mbmaxlen;
}
From 1530b51d8f3b976b18c94e6d04195350c32b39f7 Mon Sep 17 00:00:00 2001
From: "kaa@polly.local" <>
Date: Fri, 22 Sep 2006 19:23:58 +0400
Subject: [PATCH 12/19] Fixed bug #22129: A small double precision number
becomes zero Better checks for underflow/overflow
---
mysql-test/r/type_float.result | 7 ++++
mysql-test/t/type_float.test | 11 +++++-
strings/strtod.c | 69 ++++++++++++++++++++++------------
3 files changed, 61 insertions(+), 26 deletions(-)
diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result
index e8daeb08526..95050163787 100644
--- a/mysql-test/r/type_float.result
+++ b/mysql-test/r/type_float.result
@@ -272,3 +272,10 @@ desc t3;
Field Type Null Key Default Extra
a double 0
drop table t1,t2,t3;
+select 1e-308, 1.00000001e-300, 100000000e-300;
+1e-308 1.00000001e-300 100000000e-300
+0 1.00000001e-300 1e-292
+select 10e307;
+10e307
+1e+308
+End of 4.1 tests
diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test
index 75723d2a0ff..8a484f7bcd0 100644
--- a/mysql-test/t/type_float.test
+++ b/mysql-test/t/type_float.test
@@ -179,4 +179,13 @@ show warnings;
desc t3;
drop table t1,t2,t3;
-# End of 4.1 tests
+#
+# Bug #22129: A small double precision number becomes zero
+#
+# check if underflows are detected correctly
+select 1e-308, 1.00000001e-300, 100000000e-300;
+
+# check if overflows are detected correctly
+select 10e307;
+
+--echo End of 4.1 tests
diff --git a/strings/strtod.c b/strings/strtod.c
index da1b4f4baa6..3f9a1ac8c52 100644
--- a/strings/strtod.c
+++ b/strings/strtod.c
@@ -30,7 +30,8 @@
#include
#define MAX_DBL_EXP 308
-#define MAX_RESULT_FOR_MAX_EXP 1.79769313486232
+#define MAX_RESULT_FOR_MAX_EXP 1.7976931348623157
+#define MIN_RESULT_FOR_MIN_EXP 2.225073858507202
static double scaler10[] = {
1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90
};
@@ -57,10 +58,11 @@ double my_strtod(const char *str, char **end_ptr, int *error)
{
double result= 0.0;
uint negative= 0, ndigits, dec_digits= 0, neg_exp= 0;
- int exp= 0, digits_after_dec_point= 0;
+ int exp= 0, digits_after_dec_point= 0, tmp_exp;
const char *old_str, *end= *end_ptr, *start_of_number;
char next_char;
my_bool overflow=0;
+ double scaler= 1.0;
*error= 0;
if (str >= end)
@@ -91,6 +93,7 @@ double my_strtod(const char *str, char **end_ptr, int *error)
while ((next_char= *str) >= '0' && next_char <= '9')
{
result= result*10.0 + (next_char - '0');
+ scaler= scaler*10.0;
if (++str == end)
{
next_char= 0; /* Found end of string */
@@ -114,6 +117,7 @@ double my_strtod(const char *str, char **end_ptr, int *error)
{
result= result*10.0 + (next_char - '0');
digits_after_dec_point++;
+ scaler= scaler*10.0;
if (++str == end)
{
next_char= 0;
@@ -144,39 +148,54 @@ double my_strtod(const char *str, char **end_ptr, int *error)
} while (str < end && my_isdigit(&my_charset_latin1, *str));
}
}
- if ((exp= (neg_exp ? exp + digits_after_dec_point :
- exp - digits_after_dec_point)))
+ tmp_exp= neg_exp ? exp + digits_after_dec_point : exp - digits_after_dec_point;
+ if (tmp_exp)
{
- double scaler;
+ int order;
+ /*
+ Check for underflow/overflow.
+ order is such an integer number that f = C * 10 ^ order,
+ where f is the resulting floating point number and 1 <= C < 10.
+ Here we compute the modulus
+ */
+ order= exp + (neg_exp ? -1 : 1) * (ndigits - 1);
+ if (order < 0)
+ order= -order;
+ if (order >= MAX_DBL_EXP && result)
+ {
+ double c;
+ /* Compute modulus of C (see comment above) */
+ c= result / scaler * 10.0;
+ if (neg_exp)
+ {
+ if (order > MAX_DBL_EXP || c < MIN_RESULT_FOR_MIN_EXP)
+ {
+ result= 0.0;
+ goto done;
+ }
+ }
+ else
+ {
+ if (order > MAX_DBL_EXP || c > MAX_RESULT_FOR_MAX_EXP)
+ {
+ overflow= 1;
+ goto done;
+ }
+ }
+ }
+
+ exp= tmp_exp;
if (exp < 0)
{
exp= -exp;
neg_exp= 1; /* neg_exp was 0 before */
}
- if (exp + ndigits >= MAX_DBL_EXP + 1 && result)
- {
- /*
- This is not 100 % as we actually will give an owerflow for
- 17E307 but not for 1.7E308 but lets cut some corners to make life
- simpler
- */
- if (exp + ndigits > MAX_DBL_EXP + 1 ||
- result >= MAX_RESULT_FOR_MAX_EXP)
- {
- if (neg_exp)
- result= 0.0;
- else
- overflow= 1;
- goto done;
- }
- }
- scaler= 1.0;
while (exp >= 100)
{
- scaler*= 1.0e100;
+ result= neg_exp ? result/1.0e100 : result*1.0e100;
exp-= 100;
}
- scaler*= scaler10[exp/10]*scaler1[exp%10];
+ scaler= scaler10[exp/10]*scaler1[exp%10];
if (neg_exp)
result/= scaler;
else
From 5edd58b14c9c7217bfd397f6479202c147c6682c Mon Sep 17 00:00:00 2001
From: "msvensson@neptunus.(none)" <>
Date: Mon, 25 Sep 2006 20:01:39 +0200
Subject: [PATCH 13/19] Bug#18888 Trying to overwrite sql/lex_hash.h during
build -Backport fix for bug19738 to 4.1
---
sql/Makefile.am | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 9e512c362a9..43a7617df52 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -26,7 +26,7 @@ INCLUDES = @MT_INCLUDES@ @ZLIB_INCLUDES@ \
WRAPLIBS= @WRAPLIBS@
SUBDIRS = share
libexec_PROGRAMS = mysqld
-noinst_PROGRAMS = gen_lex_hash
+EXTRA_PROGRAMS = gen_lex_hash
bin_PROGRAMS = mysql_tzinfo_to_sql
gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@
LDADD = @isam_libs@ \
@@ -137,7 +137,11 @@ sql_yacc.o: sql_yacc.cc sql_yacc.h $(HEADERS)
@echo "If it fails, re-run configure with --with-low-memory"
$(CXXCOMPILE) $(LM_CFLAGS) -c $<
-lex_hash.h: gen_lex_hash$(EXEEXT)
+# This generates lex_hash.h
+# NOTE Built sources should depend on their sources not the tool
+# this avoid the rebuild of the built files in a source dist
+lex_hash.h: gen_lex_hash.cc lex.h
+ $(MAKE) $(AM_MAKEFLAGS) gen_lex_hash$(EXEEXT)
./gen_lex_hash$(EXEEXT) > $@
# For testing of udf_example.so; Works on platforms with gcc
From f063bee3b264cd6e1f61f190196f1a01780fe410 Mon Sep 17 00:00:00 2001
From: "iggy@rolltop.ignatz42.dyndns.org" <>
Date: Thu, 28 Sep 2006 14:30:20 -0400
Subject: [PATCH 14/19] Bug#20305: PROCEDURE ANALYSE() returns wrong M for
FLOAT(M, D) and DOUBLE(M, D)
---
mysql-test/r/analyse.result | 13 +++++++++++++
mysql-test/t/analyse.test | 14 +++++++++++++-
sql/sql_analyse.cc | 8 ++++----
3 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/mysql-test/r/analyse.result b/mysql-test/r/analyse.result
index f8737d8082b..fd1b0a1bb86 100644
--- a/mysql-test/r/analyse.result
+++ b/mysql-test/r/analyse.result
@@ -134,3 +134,16 @@ test.t1.product Computer TV 2 8 0 0 4.2500 NULL ENUM('Computer','Phone','TV') NO
sum(profit) 10 6900 2 4 0 0 1946 2868 ENUM('10','275','600','6900') NOT NULL
avg(profit) 10.0000 1380.0000 7 9 0 0 394.6875 570.2003 ENUM('10.0000','68.7500','120.0000','1380.0000') NOT NULL
drop table t1,t2;
+create table t1 (f1 double(10,5), f2 char(10), f3 double(10,5));
+insert into t1 values (5.999, "5.9999", 5.99999), (9.555, "9.5555", 9.55555);
+select f1 from t1 procedure analyse(1, 1);
+Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
+test.t1.f1 5.99900 9.55500 7 7 0 0 7.77700 1.77800 FLOAT(4,3) NOT NULL
+select f2 from t1 procedure analyse(1, 1);
+Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
+test.t1.f2 5.9999 9.5555 6 6 0 0 6.0000 NULL FLOAT(5,4) UNSIGNED NOT NULL
+select f3 from t1 procedure analyse(1, 1);
+Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
+test.t1.f3 5.99999 9.55555 7 7 0 0 7.77777 1.77778 FLOAT(6,5) NOT NULL
+drop table t1;
+End of 4.1 tests
diff --git a/mysql-test/t/analyse.test b/mysql-test/t/analyse.test
index dfca8f575a4..88fe8dc55e7 100644
--- a/mysql-test/t/analyse.test
+++ b/mysql-test/t/analyse.test
@@ -82,4 +82,16 @@ create table t2 (country_id int primary key, country char(20) not null);
insert into t2 values (1, 'USA'),(2,'India'), (3,'Finland');
select product, sum(profit),avg(profit) from t1 group by product with rollup procedure analyse();
drop table t1,t2;
-# End of 4.1 tests
+
+#
+# Bug #20305 PROCEDURE ANALYSE() returns wrong M for FLOAT(M, D) and DOUBLE(M, D)
+#
+
+create table t1 (f1 double(10,5), f2 char(10), f3 double(10,5));
+insert into t1 values (5.999, "5.9999", 5.99999), (9.555, "9.5555", 9.55555);
+select f1 from t1 procedure analyse(1, 1);
+select f2 from t1 procedure analyse(1, 1);
+select f3 from t1 procedure analyse(1, 1);
+drop table t1;
+
+--echo End of 4.1 tests
diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc
index d2237c24139..3420368a026 100644
--- a/sql/sql_analyse.cc
+++ b/sql/sql_analyse.cc
@@ -709,9 +709,9 @@ void field_str::get_opt_type(String *answer, ha_rows total_rows)
else if (num_info.decimals) // DOUBLE(%d,%d) sometime
{
if (num_info.dval > -FLT_MAX && num_info.dval < FLT_MAX)
- sprintf(buff, "FLOAT(%d,%d)", num_info.integers, num_info.decimals);
+ sprintf(buff, "FLOAT(%d,%d)", (num_info.integers + num_info.decimals), num_info.decimals);
else
- sprintf(buff, "DOUBLE(%d,%d)", num_info.integers, num_info.decimals);
+ sprintf(buff, "DOUBLE(%d,%d)", (num_info.integers + num_info.decimals), num_info.decimals);
}
else if (ev_num_info.llval >= -128 &&
ev_num_info.ullval <=
@@ -818,10 +818,10 @@ void field_real::get_opt_type(String *answer,
else
{
if (min_arg >= -FLT_MAX && max_arg <= FLT_MAX)
- sprintf(buff, "FLOAT(%d,%d)", (int) max_length - (item->decimals + 1),
+ sprintf(buff, "FLOAT(%d,%d)", (int) max_length - (item->decimals + 1) + max_notzero_dec_len,
max_notzero_dec_len);
else
- sprintf(buff, "DOUBLE(%d,%d)", (int) max_length - (item->decimals + 1),
+ sprintf(buff, "DOUBLE(%d,%d)", (int) max_length - (item->decimals + 1) + max_notzero_dec_len,
max_notzero_dec_len);
answer->append(buff, (uint) strlen(buff));
}
From 52d22ad827e298a6dc6c581cc266022eefd475d8 Mon Sep 17 00:00:00 2001
From: "jimw@rama.(none)" <>
Date: Fri, 29 Sep 2006 19:28:16 -0700
Subject: [PATCH 15/19] Disable __attribute__ entirely on g++ < 3.4. (Bug
#2717)
---
include/my_global.h | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/include/my_global.h b/include/my_global.h
index 2fbb1db4b77..173f054b306 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -423,23 +423,28 @@ typedef unsigned short ushort;
#endif
/*
- Disable __attribute__() on GCC < 2.7 and non-GCC compilers
+ Disable __attribute__() on gcc < 2.7, g++ < 3.4, and non-gcc compilers.
+ Some forms of __attribute__ are actually supported in earlier versions of
+ g++, but we just disable them all because we only use them to generate
+ compilation warnings.
*/
-#if !defined(__attribute__) && (!defined(__GNUC__) || GCC_VERSION < 2007)
-#define __attribute__(A)
+#ifndef __attribute__
+# if !defined(__GNUC__)
+# define __attribute__(A)
+# elif GCC_VERSION < 2008
+# define __attribute__(A)
+# elif defined(__cplusplus__) && GCC_VERSION < 3004
+# define __attribute__(A)
+# endif
#endif
/*
__attribute__((format(...))) is only supported in gcc >= 2.8 and g++ >= 3.4
+ But that's already covered by the __attribute__ tests above, so this is
+ just a convenience macro.
*/
#ifndef ATTRIBUTE_FORMAT
-# if defined(__GNUC__) && \
- ((!defined(__cplusplus__) && GCC_VERSION >= 2008) || \
- GCC_VERSION >= 3004)
-# define ATTRIBUTE_FORMAT(style, m, n) __attribute__((format(style, m, n)))
-# else
-# define ATTRIBUTE_FORMAT(style, m, n)
-# endif
+# define ATTRIBUTE_FORMAT(style, m, n) __attribute__((format(style, m, n)))
#endif
/* From old s-system.h */
From 1517d370486b84ba3d3f536c201c2cbb7f5a5b89 Mon Sep 17 00:00:00 2001
From: "msvensson@neptunus.(none)" <>
Date: Mon, 2 Oct 2006 13:46:40 +0200
Subject: [PATCH 16/19] Fix __attribute__(A) macro (it formerly used bogus
__cplusplus__ symbol)
---
include/my_global.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/my_global.h b/include/my_global.h
index 173f054b306..a150bb42928 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -433,7 +433,7 @@ typedef unsigned short ushort;
# define __attribute__(A)
# elif GCC_VERSION < 2008
# define __attribute__(A)
-# elif defined(__cplusplus__) && GCC_VERSION < 3004
+# elif defined(__cplusplus) && GCC_VERSION < 3004
# define __attribute__(A)
# endif
#endif
From c3a1980e1683c83ae26e77727a6ba525d71dd2e4 Mon Sep 17 00:00:00 2001
From: "msvensson@neptunus.(none)" <>
Date: Mon, 2 Oct 2006 13:47:18 +0200
Subject: [PATCH 17/19] Remove faulty merge causing ctype_utf8 failure
---
mysql-test/r/ctype_utf8.result | 12 ------------
mysql-test/t/ctype_utf8.test | 17 -----------------
2 files changed, 29 deletions(-)
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 22b6de80a35..a6eeabb83ef 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -1340,18 +1340,6 @@ select a from t1 group by a;
a
e
drop table t1;
-set names utf8;
-grant select on test.* to юзер_юзер@localhost;
-user()
-юзер_юзер@localhost
-revoke all on test.* from юзер_юзер@localhost;
-drop user юзер_юзер@localhost;
-create database имя_базы_в_кодировке_утф8_длиной_больше_чем_45;
-use имя_базы_в_кодировке_утф8_длиной_больше_чем_45;
-select database();
-database()
-имя_базы_в_кодировке_утф8_длиной_больше_чем_45
-drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45;
use test;
create table t1(a char(10)) default charset utf8;
insert into t1 values ('123'), ('456');
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index cb34d51e3cb..4e2bb6a7d66 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -1073,23 +1073,6 @@ select a from t1 group by a;
drop table t1;
-#
-# Bug#20393: User name truncation in mysql client
-# Bug#21432: Database/Table name limited to 64 bytes, not chars, problems with multi-byte
-#
-set names utf8;
-#create user юзер_юзер@localhost;
-grant select on test.* to юзер_юзер@localhost;
---exec $MYSQL --default-character-set=utf8 --user=юзер_юзер -e "select user()"
-revoke all on test.* from юзер_юзер@localhost;
-drop user юзер_юзер@localhost;
-
-create database имя_базы_в_кодировке_утф8_длиной_больше_чем_45;
-use имя_базы_в_кодировке_утф8_длиной_больше_чем_45;
-select database();
-drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45;
-use test;
-
#
# Bug #20204: "order by" changes the results returned
#
From cb0a874c11a2959e3f88f5a1cbcd1c0fe6807c9b Mon Sep 17 00:00:00 2001
From: "msvensson@neptunus.(none)" <>
Date: Mon, 2 Oct 2006 13:53:10 +0200
Subject: [PATCH 18/19] When compiling with qcc on QNC the define __GNUC__will
be set although it doesn't support full GNU syntax - disable __attribute__
when using qcc
---
include/my_global.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/my_global.h b/include/my_global.h
index a150bb42928..d92df6fa743 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -431,6 +431,9 @@ typedef unsigned short ushort;
#ifndef __attribute__
# if !defined(__GNUC__)
# define __attribute__(A)
+# elif defined (__QNXNTO__)
+ /* qcc defines GNUC */
+# define __attribute__(A)
# elif GCC_VERSION < 2008
# define __attribute__(A)
# elif defined(__cplusplus) && GCC_VERSION < 3004
From d5ad8ff4a2e523ad8f9e45bd98a329f33f542266 Mon Sep 17 00:00:00 2001
From: "msvensson@neptunus.(none)" <>
Date: Mon, 2 Oct 2006 14:05:36 +0200
Subject: [PATCH 19/19] Remove faulty merge
---
mysql-test/r/ctype_utf8.result | 1 -
1 file changed, 1 deletion(-)
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index a6eeabb83ef..2862d6ad650 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -1340,7 +1340,6 @@ select a from t1 group by a;
a
e
drop table t1;
-use test;
create table t1(a char(10)) default charset utf8;
insert into t1 values ('123'), ('456');
explain