summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <igreenhoe/greenman@anubis.greendragongames.com>2006-07-13 00:33:49 -0700
committerunknown <igreenhoe/greenman@anubis.greendragongames.com>2006-07-13 00:33:49 -0700
commit4bdc42514c355eab7a77173515afc5ff6d78c095 (patch)
tree4f6e78078c0bda5c1d91a020f0524bf77dc2373a
parent3efeb8924652b77d5299891a6048e161603f00f6 (diff)
parent76215977850defe766718d483a2ecf9204b1413f (diff)
downloadmariadb-git-4bdc42514c355eab7a77173515afc5ff6d78c095.tar.gz
Merge igreenhoe@bk-internal.mysql.com:/home/bk/mysql-4.1-maint
into anubis.greendragongames.com:/home/greenman/workspace-mysql/mysql/pending/bug-4.1-15977
-rw-r--r--client/mysql.cc2
-rw-r--r--configure.in8
-rw-r--r--heap/hp_test1.c3
-rw-r--r--heap/hp_test2.c1
-rw-r--r--include/my_global.h4
-rw-r--r--include/sql_common.h1
-rw-r--r--libmysql/libmysql.c7
-rw-r--r--libmysqld/lib_sql.cc7
-rw-r--r--libmysqld/libmysqld.c48
-rw-r--r--mysql-test/mysql-test-run.sh23
-rw-r--r--mysql-test/r/ctype_ucs.result7
-rw-r--r--mysql-test/r/ctype_utf8.result169
-rw-r--r--mysql-test/r/date_formats.result6
-rw-r--r--mysql-test/r/distinct.result51
-rw-r--r--mysql-test/r/func_sapdb.result6
-rw-r--r--mysql-test/r/func_time.result6
-rw-r--r--mysql-test/r/gis.result10
-rw-r--r--mysql-test/r/key.result18
-rw-r--r--mysql-test/r/myisam.result13
-rw-r--r--mysql-test/r/mysql_client.result4
-rw-r--r--mysql-test/r/symlink.result6
-rw-r--r--mysql-test/t/ctype_ucs.test12
-rw-r--r--mysql-test/t/ctype_utf8.test114
-rw-r--r--mysql-test/t/date_formats.test8
-rw-r--r--mysql-test/t/distinct.test28
-rw-r--r--mysql-test/t/func_sapdb.test2
-rw-r--r--mysql-test/t/func_time.test6
-rw-r--r--mysql-test/t/gis.test7
-rw-r--r--mysql-test/t/key.test12
-rw-r--r--mysql-test/t/myisam.test12
-rw-r--r--mysql-test/t/mysql_client.test29
-rw-r--r--mysql-test/t/mysqldump.test2
-rw-r--r--mysys/my_handler.c1
-rw-r--r--ndb/src/mgmsrv/ConfigInfo.cpp2
-rw-r--r--scripts/make_binary_distribution.sh18
-rw-r--r--scripts/mysqld_safe-watch.sh4
-rw-r--r--sql-common/client.c84
-rw-r--r--sql/field.cc20
-rw-r--r--sql/ha_ndbcluster.cc95
-rw-r--r--sql/item_cmpfunc.h14
-rw-r--r--sql/item_geofunc.h2
-rw-r--r--sql/item_sum.cc1
-rw-r--r--sql/item_timefunc.cc11
-rw-r--r--sql/opt_range.cc4
-rw-r--r--sql/opt_sum.cc6
-rw-r--r--sql/spatial.h4
-rw-r--r--sql/sql_parse.cc65
-rw-r--r--sql/sql_select.cc168
-rw-r--r--sql/sql_select.h2
-rw-r--r--sql/sql_update.cc2
-rw-r--r--sql/time.cc2
-rw-r--r--strings/ctype-mb.c25
-rw-r--r--strings/strtod.c4
-rw-r--r--support-files/mysql.spec.sh1
-rw-r--r--tests/mysql_client_test.c53
55 files changed, 1016 insertions, 204 deletions
diff --git a/client/mysql.cc b/client/mysql.cc
index 2f9031b84b8..09818ae27b3 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1052,7 +1052,7 @@ static int read_lines(bool execute_commands)
(We want to allow help, print and clear anywhere at line start
*/
if (execute_commands && (named_cmds || glob_buffer.is_empty())
- && !in_string && (com=find_command(line,0)))
+ && !ml_comment && !in_string && (com=find_command(line,0)))
{
if ((*com->func)(&glob_buffer,line) > 0)
break;
diff --git a/configure.in b/configure.in
index 7eadc5bd241..773ab7630bd 100644
--- a/configure.in
+++ b/configure.in
@@ -441,18 +441,18 @@ fi
AC_SUBST(LD_VERSION_SCRIPT)
# Avoid bug in fcntl on some versions of linux
-AC_MSG_CHECKING("if we should use 'skip-locking' as default for $target_os")
+AC_MSG_CHECKING([if we should use 'skip-external-locking' as default for $target_os])
# Any wariation of Linux
if expr "$target_os" : "[[Ll]]inux.*" > /dev/null
then
- MYSQLD_DEFAULT_SWITCHES="--skip-locking"
+ MYSQLD_DEFAULT_SWITCHES="--skip-external-locking"
TARGET_LINUX="true"
- AC_MSG_RESULT("yes")
+ AC_MSG_RESULT([yes])
AC_DEFINE([TARGET_OS_LINUX], [1], [Whether we build for Linux])
else
MYSQLD_DEFAULT_SWITCHES=""
TARGET_LINUX="false"
- AC_MSG_RESULT("no")
+ AC_MSG_RESULT([no])
fi
AC_SUBST(MYSQLD_DEFAULT_SWITCHES)
AC_SUBST(TARGET_LINUX)
diff --git a/heap/hp_test1.c b/heap/hp_test1.c
index dd696528eb8..703b39b1e2d 100644
--- a/heap/hp_test1.c
+++ b/heap/hp_test1.c
@@ -44,6 +44,7 @@ int main(int argc, char **argv)
get_options(argc,argv);
bzero(&hp_create_info, sizeof(hp_create_info));
+ hp_create_info.max_table_size= 1024L*1024L;
keyinfo[0].keysegs=1;
keyinfo[0].seg=keyseg;
@@ -58,7 +59,7 @@ int main(int argc, char **argv)
bzero((gptr) flags,sizeof(flags));
printf("- Creating heap-file\n");
- if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000l,10l,
+ if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000L,10L,
&hp_create_info) ||
!(file= heap_open(filename, 2)))
goto err;
diff --git a/heap/hp_test2.c b/heap/hp_test2.c
index 2de49bcb66b..ff07b402f4d 100644
--- a/heap/hp_test2.c
+++ b/heap/hp_test2.c
@@ -74,6 +74,7 @@ int main(int argc, char *argv[])
get_options(argc,argv);
bzero(&hp_create_info, sizeof(hp_create_info));
+ hp_create_info.max_table_size= 1024L*1024L;
write_count=update=opt_delete=0;
key_check=0;
diff --git a/include/my_global.h b/include/my_global.h
index 0f99aacd079..6baa4558d50 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -976,8 +976,8 @@ do { doubleget_union _tmp; \
#define doublestore(T,V) do { *((long *) T) = ((doubleget_union *)&V)->m[0]; \
*(((long *) T)+1) = ((doubleget_union *)&V)->m[1]; \
} while (0)
-#define float4get(V,M) do { *((long *) &(V)) = *((long*) (M)); } while(0)
-#define float8get(V,M) doubleget((V),(M))
+#define float4get(V,M) do { *((float *) &(V)) = *((float*) (M)); } while(0)
+#define float8get(V,M) doubleget((V),(M))
#define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float))
#define floatstore(T,V) memcpy((byte*)(T), (byte*)(&V),sizeof(float))
#define floatget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(float))
diff --git a/include/sql_common.h b/include/sql_common.h
index c07a4a831bb..9fc8d4f457b 100644
--- a/include/sql_common.h
+++ b/include/sql_common.h
@@ -22,6 +22,7 @@ extern const char *not_error_sqlstate;
extern "C" {
#endif
+extern CHARSET_INFO *default_client_charset_info;
MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
my_bool default_value, uint server_capabilities);
void free_rows(MYSQL_DATA *cur);
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 4b8f1c9da1f..80a7112eab2 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -2409,10 +2409,9 @@ static void net_store_datetime(NET *net, MYSQL_TIME *tm)
static void store_param_date(NET *net, MYSQL_BIND *param)
{
- MYSQL_TIME *tm= (MYSQL_TIME *) param->buffer;
- tm->hour= tm->minute= tm->second= 0;
- tm->second_part= 0;
- net_store_datetime(net, tm);
+ MYSQL_TIME tm= *((MYSQL_TIME *) param->buffer);
+ tm.hour= tm.minute= tm.second= tm.second_part= 0;
+ net_store_datetime(net, &tm);
}
static void store_param_datetime(NET *net, MYSQL_BIND *param)
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index bf8c17a71af..56f4200e695 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -41,6 +41,8 @@ static const char *fake_groups[] = { "server", "embedded", 0 };
int check_user(THD *thd, enum enum_server_command command,
const char *passwd, uint passwd_len, const char *db,
bool check_count);
+void thd_init_client_charset(THD *thd, uint cs_number);
+
C_MODE_START
#include <mysql.h>
#undef ER
@@ -532,10 +534,13 @@ err:
return NULL;
}
+
#ifdef NO_EMBEDDED_ACCESS_CHECKS
int check_embedded_connection(MYSQL *mysql)
{
THD *thd= (THD*)mysql->thd;
+ thd_init_client_charset(thd, mysql->charset->number);
+ thd->update_charset();
thd->host= (char*)my_localhost;
thd->host_or_ip= thd->host;
thd->user= my_strdup(mysql->user, MYF(0));
@@ -551,6 +556,8 @@ int check_embedded_connection(MYSQL *mysql)
char scramble_buff[SCRAMBLE_LENGTH];
int passwd_len;
+ thd_init_client_charset(thd, mysql->charset->number);
+ thd->update_charset();
if (mysql->options.client_ip)
{
thd->host= my_strdup(mysql->options.client_ip, MYF(0));
diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c
index 6fa41fb3fd0..a2bd4242c3d 100644
--- a/libmysqld/libmysqld.c
+++ b/libmysqld/libmysqld.c
@@ -85,49 +85,7 @@ static void end_server(MYSQL *mysql)
}
-static int mysql_init_charset(MYSQL *mysql)
-{
- char charset_name_buff[16], *charset_name;
-
- if ((charset_name=mysql->options.charset_name))
- {
- const char *save=charsets_dir;
- if (mysql->options.charset_dir)
- charsets_dir=mysql->options.charset_dir;
- mysql->charset=get_charset_by_name(mysql->options.charset_name,
- MYF(MY_WME));
- charsets_dir=save;
- }
- else if (mysql->server_language)
- {
- charset_name=charset_name_buff;
- sprintf(charset_name,"%d",mysql->server_language); /* In case of errors */
- mysql->charset=get_charset((uint8) mysql->server_language, MYF(MY_WME));
- }
- else
- mysql->charset=default_charset_info;
-
- if (!mysql->charset)
- {
- mysql->net.last_errno=CR_CANT_READ_CHARSET;
- strmov(mysql->net.sqlstate, "HY0000");
- if (mysql->options.charset_dir)
- sprintf(mysql->net.last_error,ER(mysql->net.last_errno),
- charset_name ? charset_name : "unknown",
- mysql->options.charset_dir);
- else
- {
- char cs_dir_name[FN_REFLEN];
- get_charsets_dir(cs_dir_name);
- sprintf(mysql->net.last_error,ER(mysql->net.last_errno),
- charset_name ? charset_name : "unknown",
- cs_dir_name);
- }
- return mysql->net.last_errno;
- }
- return 0;
-}
-
+int mysql_init_character_set(MYSQL *mysql);
MYSQL * STDCALL
mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
@@ -203,10 +161,10 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
init_embedded_mysql(mysql, client_flag, db_name);
- if (check_embedded_connection(mysql))
+ if (mysql_init_character_set(mysql))
goto error;
- if (mysql_init_charset(mysql))
+ if (check_embedded_connection(mysql))
goto error;
/* Send client information for access check */
diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh
index fb3484c212e..15c7470a74c 100644
--- a/mysql-test/mysql-test-run.sh
+++ b/mysql-test/mysql-test-run.sh
@@ -171,7 +171,8 @@ BASEDIR=`pwd`
cd $CWD
MYSQL_TEST_DIR=$BASEDIR/mysql-test
MYSQL_TEST_WINDIR=$MYSQL_TEST_DIR
-export MYSQL_TEST_DIR MYSQL_TEST_WINDIR
+MYSQLTEST_VARDIR=$MYSQL_TEST_DIR/var
+export MYSQL_TEST_DIR MYSQL_TEST_WINDIR MYSQLTEST_VARDIR
STD_DATA=$MYSQL_TEST_DIR/std_data
hostname=`hostname` # Installed in the mysql privilege table
@@ -1251,16 +1252,16 @@ start_master()
if [ x$DO_DDD = x1 ]
then
- $ECHO "set args $master_args" > $GDB_MASTER_INIT
+ $ECHO "set args $master_args" > $GDB_MASTER_INIT$1
manager_launch master ddd -display $DISPLAY --debugger \
- "gdb -x $GDB_MASTER_INIT" $MASTER_MYSQLD
+ "gdb -x $GDB_MASTER_INIT$1" $MASTER_MYSQLD
elif [ x$DO_GDB = x1 ]
then
if [ x$MANUAL_GDB = x1 ]
then
- $ECHO "set args $master_args" > $GDB_MASTER_INIT
+ $ECHO "set args $master_args" > $GDB_MASTER_INIT$1
$ECHO "To start gdb for the master , type in another window:"
- $ECHO "cd $CWD ; gdb -x $GDB_MASTER_INIT $MASTER_MYSQLD"
+ $ECHO "cd $CWD ; gdb -x $GDB_MASTER_INIT$1 $MASTER_MYSQLD"
wait_for_master=1500
else
( $ECHO set args $master_args;
@@ -1272,9 +1273,9 @@ disa 1
end
r
EOF
- fi ) > $GDB_MASTER_INIT
+ fi ) > $GDB_MASTER_INIT$1
manager_launch master $XTERM -display $DISPLAY \
- -title "Master" -e gdb -x $GDB_MASTER_INIT $MASTER_MYSQLD
+ -title "Master" -e gdb -x $GDB_MASTER_INIT$1 $MASTER_MYSQLD
fi
else
manager_launch master $MASTER_MYSQLD $master_args
@@ -1809,13 +1810,7 @@ then
mysql_install_db
start_manager
-
-# Do not automagically start daemons if we are in gdb or running only one test
-# case
- if [ -z "$DO_GDB" ] && [ -z "$DO_DDD" ]
- then
- mysql_start
- fi
+ mysql_start
$ECHO "Loading Standard Test Databases"
mysql_loadstd
fi
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index 8869604b128..bcf9cc77519 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -715,3 +715,10 @@ lily
river
drop table t1;
deallocate prepare stmt;
+CREATE TABLE t1 (id int, s char(5) CHARACTER SET ucs2 COLLATE ucs2_unicode_ci);
+INSERT INTO t1 VALUES (1, 'ZZZZZ'), (1, 'ZZZ'), (2, 'ZZZ'), (2, 'ZZZZZ');
+SELECT id, MIN(s) FROM t1 GROUP BY id;
+id MIN(s)
+1 ZZZ
+2 ZZZ
+DROP TABLE t1;
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 69d7577ee77..4ceacaffcbb 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -1124,3 +1124,172 @@ check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
drop table t1;
+SET NAMES utf8;
+CREATE TABLE t1 (id int PRIMARY KEY,
+a varchar(16) collate utf8_unicode_ci NOT NULL default '',
+b int,
+f varchar(128) default 'XXX',
+INDEX (a(4))
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+INSERT INTO t1(id, a, b) VALUES
+(1, 'cccc', 50), (2, 'cccc', 70), (3, 'cccc', 30),
+(4, 'cccc', 30), (5, 'cccc', 20), (6, 'bbbbbb', 40),
+(7, 'dddd', 30), (8, 'aaaa', 10), (9, 'aaaa', 50),
+(10, 'eeeee', 40), (11, 'bbbbbb', 60);
+SELECT id, a, b FROM t1;
+id a b
+1 cccc 50
+2 cccc 70
+3 cccc 30
+4 cccc 30
+5 cccc 20
+6 bbbbbb 40
+7 dddd 30
+8 aaaa 10
+9 aaaa 50
+10 eeeee 40
+11 bbbbbb 60
+SELECT id, a, b FROM t1 WHERE a BETWEEN 'aaaa' AND 'bbbbbb';
+id a b
+8 aaaa 10
+9 aaaa 50
+6 bbbbbb 40
+11 bbbbbb 60
+SELECT id, a FROM t1 WHERE a='bbbbbb';
+id a
+6 bbbbbb
+11 bbbbbb
+SELECT id, a FROM t1 WHERE a='bbbbbb' ORDER BY b;
+id a
+6 bbbbbb
+11 bbbbbb
+DROP TABLE t1;
+SET NAMES utf8;
+CREATE TABLE t1 (
+a CHAR(13) DEFAULT '',
+INDEX(a)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+INSERT INTO t1 VALUES
+('Käli Käli 2-4'), ('Käli Käli 2-4'),
+('Käli Käli 2+4'), ('Käli Käli 2+4'),
+('Käli Käli 2-6'), ('Käli Käli 2-6');
+INSERT INTO t1 SELECT * FROM t1;
+CREATE TABLE t2 (
+a CHAR(13) DEFAULT '',
+INDEX(a)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO t2 VALUES
+('Kali Kali 2-4'), ('Kali Kali 2-4'),
+('Kali Kali 2+4'), ('Kali Kali 2+4'),
+('Kali Kali 2-6'), ('Kali Kali 2-6');
+INSERT INTO t2 SELECT * FROM t2;
+SELECT a FROM t1 WHERE a LIKE 'Käli Käli 2+4';
+a
+Käli Käli 2+4
+Käli Käli 2+4
+Käli Käli 2+4
+Käli Käli 2+4
+SELECT a FROM t2 WHERE a LIKE 'Kali Kali 2+4';
+a
+Kali Kali 2+4
+Kali Kali 2+4
+Kali Kali 2+4
+Kali Kali 2+4
+EXPLAIN SELECT a FROM t1 WHERE a LIKE 'Käli Käli 2+4';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 40 NULL 4 Using where; Using index
+EXPLAIN SELECT a FROM t1 WHERE a = 'Käli Käli 2+4';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref a a 40 const 4 Using where; Using index
+EXPLAIN SELECT a FROM t2 WHERE a LIKE 'Kali Kali 2+4';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range a a 14 NULL 4 Using where; Using index
+EXPLAIN SELECT a FROM t2 WHERE a = 'Kali Kali 2+4';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref a a 14 const 4 Using where; Using index
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+a char(255) DEFAULT '',
+KEY(a(10))
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+INSERT INTO t1 VALUES ('Käli Käli 2-4');
+SELECT * FROM t1 WHERE a LIKE 'Käli Käli 2%';
+a
+Käli Käli 2-4
+INSERT INTO t1 VALUES ('Käli Käli 2-4');
+SELECT * FROM t1 WHERE a LIKE 'Käli Käli 2%';
+a
+Käli Käli 2-4
+Käli Käli 2-4
+DROP TABLE t1;
+CREATE TABLE t1 (
+a char(255) DEFAULT ''
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+INSERT INTO t1 VALUES ('Käli Käli 2-4');
+INSERT INTO t1 VALUES ('Käli Käli 2-4');
+SELECT * FROM t1 WHERE a LIKE 'Käli Käli 2%';
+a
+Käli Käli 2-4
+Käli Käli 2-4
+ALTER TABLE t1 ADD KEY (a(10));
+SELECT * FROM t1 WHERE a LIKE 'Käli Käli 2%';
+a
+Käli Käli 2-4
+Käli Käli 2-4
+DROP TABLE t1;
+SET NAMES latin2;
+CREATE TABLE t1 (
+id int(11) NOT NULL default '0',
+tid int(11) NOT NULL default '0',
+val text NOT NULL,
+INDEX idx(tid, val(10))
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+INSERT INTO t1 VALUES
+(40988,72,'VOLNÝ ADSL'),(41009,72,'VOLNÝ ADSL'),
+(41032,72,'VOLNÝ ADSL'),(41038,72,'VOLNÝ ADSL'),
+(41063,72,'VOLNÝ ADSL'),(41537,72,'VOLNÝ ADSL Office'),
+(42141,72,'VOLNÝ ADSL'),(42565,72,'VOLNÝ ADSL Combi'),
+(42749,72,'VOLNÝ ADSL'),(44205,72,'VOLNÝ ADSL');
+SELECT * FROM t1 WHERE tid=72 and val LIKE 'VOLNY ADSL';
+id tid val
+40988 72 VOLNÝ ADSL
+41009 72 VOLNÝ ADSL
+41032 72 VOLNÝ ADSL
+41038 72 VOLNÝ ADSL
+41063 72 VOLNÝ ADSL
+42141 72 VOLNÝ ADSL
+42749 72 VOLNÝ ADSL
+44205 72 VOLNÝ ADSL
+SELECT * FROM t1 WHERE tid=72 and val LIKE 'VOLNÝ ADSL';
+id tid val
+40988 72 VOLNÝ ADSL
+41009 72 VOLNÝ ADSL
+41032 72 VOLNÝ ADSL
+41038 72 VOLNÝ ADSL
+41063 72 VOLNÝ ADSL
+42141 72 VOLNÝ ADSL
+42749 72 VOLNÝ ADSL
+44205 72 VOLNÝ ADSL
+SELECT * FROM t1 WHERE tid=72 and val LIKE '%VOLNÝ ADSL';
+id tid val
+40988 72 VOLNÝ ADSL
+41009 72 VOLNÝ ADSL
+41032 72 VOLNÝ ADSL
+41038 72 VOLNÝ ADSL
+41063 72 VOLNÝ ADSL
+42141 72 VOLNÝ ADSL
+42749 72 VOLNÝ ADSL
+44205 72 VOLNÝ ADSL
+ALTER TABLE t1 DROP KEY idx;
+ALTER TABLE t1 ADD KEY idx (tid,val(11));
+SELECT * FROM t1 WHERE tid=72 and val LIKE 'VOLNÝ ADSL';
+id tid val
+40988 72 VOLNÝ ADSL
+41009 72 VOLNÝ ADSL
+41032 72 VOLNÝ ADSL
+41038 72 VOLNÝ ADSL
+41063 72 VOLNÝ ADSL
+42141 72 VOLNÝ ADSL
+42749 72 VOLNÝ ADSL
+44205 72 VOLNÝ ADSL
+DROP TABLE t1;
diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result
index 24abdfcf148..04ada125847 100644
--- a/mysql-test/r/date_formats.result
+++ b/mysql-test/r/date_formats.result
@@ -509,3 +509,9 @@ TIME_FORMAT("24:00:00", '%l %p')
SELECT TIME_FORMAT("25:00:00", '%l %p');
TIME_FORMAT("25:00:00", '%l %p')
1 AM
+SELECT DATE_FORMAT('%Y-%m-%d %H:%i:%s', 1151414896);
+DATE_FORMAT('%Y-%m-%d %H:%i:%s', 1151414896)
+NULL
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '%Y-%m-%d %H:%i:%s'
+"End of 4.1 tests"
diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result
index 8932285b5d0..c6c614a5646 100644
--- a/mysql-test/r/distinct.result
+++ b/mysql-test/r/distinct.result
@@ -504,3 +504,54 @@ a 2 b
2 2 4
3 2 5
DROP TABLE t1,t2;
+CREATE TABLE t1(a INT PRIMARY KEY, b INT);
+INSERT INTO t1 VALUES (1,1), (2,1), (3,1);
+EXPLAIN SELECT DISTINCT a FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL PRIMARY 4 NULL 3 Using index
+EXPLAIN SELECT DISTINCT a,b FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+EXPLAIN SELECT DISTINCT t1_1.a, t1_1.b FROM t1 t1_1, t1 t1_2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1_1 ALL NULL NULL NULL NULL 3 Using temporary
+1 SIMPLE t1_2 index NULL PRIMARY 4 NULL 3 Using index; Distinct
+EXPLAIN SELECT DISTINCT t1_1.a, t1_1.b FROM t1 t1_1, t1 t1_2
+WHERE t1_1.a = t1_2.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1_1 ALL PRIMARY NULL NULL NULL 3 Using temporary
+1 SIMPLE t1_2 eq_ref PRIMARY PRIMARY 4 test.t1_1.a 1 Using index; Distinct
+EXPLAIN SELECT a FROM t1 GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL PRIMARY 4 NULL 3 Using index
+EXPLAIN SELECT a,b FROM t1 GROUP BY a,b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+EXPLAIN SELECT DISTINCT a,b FROM t1 GROUP BY a,b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+CREATE TABLE t2(a INT, b INT, c INT, d INT, PRIMARY KEY (a,b));
+INSERT INTO t2 VALUES (1,1,1,50), (1,2,3,40), (2,1,3,4);
+EXPLAIN SELECT DISTINCT a FROM t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index NULL PRIMARY 8 NULL 3 Using index
+EXPLAIN SELECT DISTINCT a,a FROM t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index NULL PRIMARY 8 NULL 3 Using index; Using temporary
+EXPLAIN SELECT DISTINCT b,a FROM t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index NULL PRIMARY 8 NULL 3 Using index
+EXPLAIN SELECT DISTINCT a,c FROM t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using temporary
+EXPLAIN SELECT DISTINCT c,a,b FROM t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3
+EXPLAIN SELECT DISTINCT a,b,d FROM t2 GROUP BY c,b,d;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using temporary; Using filesort
+CREATE UNIQUE INDEX c_b_unq ON t2 (c,b);
+EXPLAIN SELECT DISTINCT a,b,d FROM t2 GROUP BY c,b,d;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3
+DROP TABLE t1,t2;
diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result
index ea40e1559fd..b18885e218a 100644
--- a/mysql-test/r/func_sapdb.result
+++ b/mysql-test/r/func_sapdb.result
@@ -71,6 +71,12 @@ makedate(1997,1)
select makedate(1997,0);
makedate(1997,0)
NULL
+select makedate(9999,365);
+makedate(9999,365)
+9999-12-31
+select makedate(9999,366);
+makedate(9999,366)
+NULL
select addtime("1997-12-31 23:59:59.999999", "1 1:1:1.000002");
addtime("1997-12-31 23:59:59.999999", "1 1:1:1.000002")
1998-01-02 01:01:01.000001
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index c90a4258036..fab0bf01f58 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -352,6 +352,12 @@ extract(SECOND FROM "1999-01-02 10:11:12")
select extract(MONTH FROM "2001-02-00");
extract(MONTH FROM "2001-02-00")
2
+SELECT DATE_SUB(str_to_date('9999-12-31 00:01:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE);
+DATE_SUB(str_to_date('9999-12-31 00:01:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE)
+9999-12-31 00:00:00
+SELECT DATE_ADD(str_to_date('9999-12-30 23:59:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE);
+DATE_ADD(str_to_date('9999-12-30 23:59:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE)
+9999-12-31 00:00:00
SELECT "1900-01-01 00:00:00" + INTERVAL 2147483648 SECOND;
"1900-01-01 00:00:00" + INTERVAL 2147483648 SECOND
1968-01-20 03:14:08
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index bf2f3e2bf03..f7066e7edca 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -661,3 +661,13 @@ POINT(10 10)
select (asWKT(geomfromwkb((0x010100000000000000000024400000000000002440))));
(asWKT(geomfromwkb((0x010100000000000000000024400000000000002440))))
POINT(10 10)
+create table t1 (g GEOMETRY);
+select * from t1;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def test t1 t1 g g 255 4294967295 0 Y 144 0 63
+g
+select asbinary(g) from t1;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def asbinary(g) 252 8192 0 Y 128 0 63
+asbinary(g)
+drop table t1;
diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result
index f0a7afa239f..75fc469460e 100644
--- a/mysql-test/r/key.result
+++ b/mysql-test/r/key.result
@@ -326,6 +326,24 @@ alter table t1 add key (c1,c1,c2);
ERROR 42S21: Duplicate column name 'c1'
drop table t1;
create table t1 (
+i1 INT NOT NULL,
+i2 INT NOT NULL,
+UNIQUE i1idx (i1),
+UNIQUE i2idx (i2));
+desc t1;
+Field Type Null Key Default Extra
+i1 int(11) PRI 0
+i2 int(11) UNI 0
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i1` int(11) NOT NULL default '0',
+ `i2` int(11) NOT NULL default '0',
+ UNIQUE KEY `i1idx` (`i1`),
+ UNIQUE KEY `i2idx` (`i2`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (
c1 int,
c2 varchar(20) not null,
primary key (c1),
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index 7aaf3c8f85a..cd1bc5c34e8 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -748,6 +748,19 @@ select count(id1) from t1 where id2 = 10;
count(id1)
5
drop table t1;
+CREATE TABLE t1(a TINYINT, KEY(a)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES(1);
+SELECT MAX(a) FROM t1 IGNORE INDEX(a);
+MAX(a)
+1
+ALTER TABLE t1 DISABLE KEYS;
+SELECT MAX(a) FROM t1;
+MAX(a)
+1
+SELECT MAX(a) FROM t1 IGNORE INDEX(a);
+MAX(a)
+1
+DROP TABLE t1;
CREATE TABLE t1(a CHAR(9), b VARCHAR(7)) ENGINE=MyISAM;
INSERT INTO t1(a) VALUES('xxxxxxxxx'),('xxxxxxxxx');
UPDATE t1 AS ta1,t1 AS ta2 SET ta1.b='aaaaaa',ta2.b='bbbbbb';
diff --git a/mysql-test/r/mysql_client.result b/mysql-test/r/mysql_client.result
new file mode 100644
index 00000000000..87d09428ff6
--- /dev/null
+++ b/mysql-test/r/mysql_client.result
@@ -0,0 +1,4 @@
+1
+1
+ERROR 1064 (42000) at line 3: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
+ERROR at line 1: USE must be followed by a database name
diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result
index caff53f8fd7..f6779689133 100644
--- a/mysql-test/r/symlink.result
+++ b/mysql-test/r/symlink.result
@@ -65,18 +65,24 @@ t9 CREATE TABLE `t9` (
) ENGINE=MyISAM AUTO_INCREMENT=16725 DEFAULT CHARSET=latin1 DATA DIRECTORY='TEST_DIR/var/tmp/' INDEX DIRECTORY='TEST_DIR/var/run/'
drop database mysqltest;
create table t1 (a int not null) engine=myisam;
+Warnings:
+Warning 0 DATA DIRECTORY option ignored
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
alter table t1 add b int;
+Warnings:
+Warning 0 DATA DIRECTORY option ignored
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL default '0',
`b` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
+Warnings:
+Warning 0 INDEX DIRECTORY option ignored
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
index 2cbabf88ee0..a4d4d1846a7 100644
--- a/mysql-test/t/ctype_ucs.test
+++ b/mysql-test/t/ctype_ucs.test
@@ -451,4 +451,16 @@ execute stmt using @param1;
select utext from t1 where utext like '%%';
drop table t1;
deallocate prepare stmt;
+
+#
+# Bug #20076: server crashes for a query with GROUP BY if MIN/MAX aggregation
+# over a 'ucs2' field uses a temporary table
+#
+
+CREATE TABLE t1 (id int, s char(5) CHARACTER SET ucs2 COLLATE ucs2_unicode_ci);
+INSERT INTO t1 VALUES (1, 'ZZZZZ'), (1, 'ZZZ'), (2, 'ZZZ'), (2, 'ZZZZZ');
+
+SELECT id, MIN(s) FROM t1 GROUP BY id;
+
+DROP TABLE t1;
# End of 4.1 tests
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 5044f7979f1..b1d485ad1ce 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -926,4 +926,118 @@ INSERT INTO t1 VALUES('uUABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbb
check table t1;
drop table t1;
+#
+# Bug#14896: Comparison with a key in a partial index over mb chararacter field
+#
+
+SET NAMES utf8;
+CREATE TABLE t1 (id int PRIMARY KEY,
+ a varchar(16) collate utf8_unicode_ci NOT NULL default '',
+ b int,
+ f varchar(128) default 'XXX',
+ INDEX (a(4))
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+INSERT INTO t1(id, a, b) VALUES
+ (1, 'cccc', 50), (2, 'cccc', 70), (3, 'cccc', 30),
+ (4, 'cccc', 30), (5, 'cccc', 20), (6, 'bbbbbb', 40),
+ (7, 'dddd', 30), (8, 'aaaa', 10), (9, 'aaaa', 50),
+ (10, 'eeeee', 40), (11, 'bbbbbb', 60);
+
+SELECT id, a, b FROM t1;
+
+SELECT id, a, b FROM t1 WHERE a BETWEEN 'aaaa' AND 'bbbbbb';
+
+SELECT id, a FROM t1 WHERE a='bbbbbb';
+SELECT id, a FROM t1 WHERE a='bbbbbb' ORDER BY b;
+
+DROP TABLE t1;
+
+#
+# Bug#16674: LIKE predicate for a utf8 character set column
+#
+
+SET NAMES utf8;
+
+CREATE TABLE t1 (
+ a CHAR(13) DEFAULT '',
+ INDEX(a)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+INSERT INTO t1 VALUES
+ ('Käli Käli 2-4'), ('Käli Käli 2-4'),
+ ('Käli Käli 2+4'), ('Käli Käli 2+4'),
+ ('Käli Käli 2-6'), ('Käli Käli 2-6');
+INSERT INTO t1 SELECT * FROM t1;
+
+CREATE TABLE t2 (
+ a CHAR(13) DEFAULT '',
+ INDEX(a)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+
+INSERT INTO t2 VALUES
+ ('Kali Kali 2-4'), ('Kali Kali 2-4'),
+ ('Kali Kali 2+4'), ('Kali Kali 2+4'),
+ ('Kali Kali 2-6'), ('Kali Kali 2-6');
+INSERT INTO t2 SELECT * FROM t2;
+
+SELECT a FROM t1 WHERE a LIKE 'Käli Käli 2+4';
+SELECT a FROM t2 WHERE a LIKE 'Kali Kali 2+4';
+
+EXPLAIN SELECT a FROM t1 WHERE a LIKE 'Käli Käli 2+4';
+EXPLAIN SELECT a FROM t1 WHERE a = 'Käli Käli 2+4';
+EXPLAIN SELECT a FROM t2 WHERE a LIKE 'Kali Kali 2+4';
+EXPLAIN SELECT a FROM t2 WHERE a = 'Kali Kali 2+4';
+
+DROP TABLE t1,t2;
+
+CREATE TABLE t1 (
+ a char(255) DEFAULT '',
+ KEY(a(10))
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+INSERT INTO t1 VALUES ('Käli Käli 2-4');
+SELECT * FROM t1 WHERE a LIKE 'Käli Käli 2%';
+INSERT INTO t1 VALUES ('Käli Käli 2-4');
+SELECT * FROM t1 WHERE a LIKE 'Käli Käli 2%';
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ a char(255) DEFAULT ''
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+INSERT INTO t1 VALUES ('Käli Käli 2-4');
+INSERT INTO t1 VALUES ('Käli Käli 2-4');
+SELECT * FROM t1 WHERE a LIKE 'Käli Käli 2%';
+ALTER TABLE t1 ADD KEY (a(10));
+SELECT * FROM t1 WHERE a LIKE 'Käli Käli 2%';
+DROP TABLE t1;
+
+#
+# Bug#18359: LIKE predicate for a 'utf8' text column with a partial index
+# (see bug #16674 as well)
+#
+
+SET NAMES latin2;
+
+CREATE TABLE t1 (
+ id int(11) NOT NULL default '0',
+ tid int(11) NOT NULL default '0',
+ val text NOT NULL,
+ INDEX idx(tid, val(10))
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+INSERT INTO t1 VALUES
+ (40988,72,'VOLNÝ ADSL'),(41009,72,'VOLNÝ ADSL'),
+ (41032,72,'VOLNÝ ADSL'),(41038,72,'VOLNÝ ADSL'),
+ (41063,72,'VOLNÝ ADSL'),(41537,72,'VOLNÝ ADSL Office'),
+ (42141,72,'VOLNÝ ADSL'),(42565,72,'VOLNÝ ADSL Combi'),
+ (42749,72,'VOLNÝ ADSL'),(44205,72,'VOLNÝ ADSL');
+
+SELECT * FROM t1 WHERE tid=72 and val LIKE 'VOLNY ADSL';
+SELECT * FROM t1 WHERE tid=72 and val LIKE 'VOLNÝ ADSL';
+SELECT * FROM t1 WHERE tid=72 and val LIKE '%VOLNÝ ADSL';
+
+ALTER TABLE t1 DROP KEY idx;
+ALTER TABLE t1 ADD KEY idx (tid,val(11));
+
+SELECT * FROM t1 WHERE tid=72 and val LIKE 'VOLNÝ ADSL';
+
+DROP TABLE t1;
# End of 4.1 tests
diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test
index f3d507e69e6..0c227258383 100644
--- a/mysql-test/t/date_formats.test
+++ b/mysql-test/t/date_formats.test
@@ -275,7 +275,6 @@ drop table t1;
select str_to_date( 1, NULL );
select str_to_date( NULL, 1 );
select str_to_date( 1, IF(1=1,NULL,NULL) );
-# End of 4.1 tests
#
# Bug#11326
@@ -298,3 +297,10 @@ SELECT TIME_FORMAT("12:00:00", '%l %p');
SELECT TIME_FORMAT("23:00:00", '%l %p');
SELECT TIME_FORMAT("24:00:00", '%l %p');
SELECT TIME_FORMAT("25:00:00", '%l %p');
+
+#
+# Bug#20729: Bad date_format() call makes mysql server crash
+#
+SELECT DATE_FORMAT('%Y-%m-%d %H:%i:%s', 1151414896);
+
+--echo "End of 4.1 tests"
diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test
index f2fe1ec6372..8ca6f350b8d 100644
--- a/mysql-test/t/distinct.test
+++ b/mysql-test/t/distinct.test
@@ -349,5 +349,33 @@ SELECT DISTINCT 2, a, b FROM t2;
SELECT DISTINCT a, 2, b FROM t2;
DROP TABLE t1,t2;
+#
+# Bug#16458: Simple SELECT FOR UPDATE causes "Result Set not updatable"
+# error.
+#
+CREATE TABLE t1(a INT PRIMARY KEY, b INT);
+INSERT INTO t1 VALUES (1,1), (2,1), (3,1);
+EXPLAIN SELECT DISTINCT a FROM t1;
+EXPLAIN SELECT DISTINCT a,b FROM t1;
+EXPLAIN SELECT DISTINCT t1_1.a, t1_1.b FROM t1 t1_1, t1 t1_2;
+EXPLAIN SELECT DISTINCT t1_1.a, t1_1.b FROM t1 t1_1, t1 t1_2
+ WHERE t1_1.a = t1_2.a;
+EXPLAIN SELECT a FROM t1 GROUP BY a;
+EXPLAIN SELECT a,b FROM t1 GROUP BY a,b;
+EXPLAIN SELECT DISTINCT a,b FROM t1 GROUP BY a,b;
+
+CREATE TABLE t2(a INT, b INT, c INT, d INT, PRIMARY KEY (a,b));
+INSERT INTO t2 VALUES (1,1,1,50), (1,2,3,40), (2,1,3,4);
+EXPLAIN SELECT DISTINCT a FROM t2;
+EXPLAIN SELECT DISTINCT a,a FROM t2;
+EXPLAIN SELECT DISTINCT b,a FROM t2;
+EXPLAIN SELECT DISTINCT a,c FROM t2;
+EXPLAIN SELECT DISTINCT c,a,b FROM t2;
+
+EXPLAIN SELECT DISTINCT a,b,d FROM t2 GROUP BY c,b,d;
+CREATE UNIQUE INDEX c_b_unq ON t2 (c,b);
+EXPLAIN SELECT DISTINCT a,b,d FROM t2 GROUP BY c,b,d;
+
+DROP TABLE t1,t2;
# End of 4.1 tests
diff --git a/mysql-test/t/func_sapdb.test b/mysql-test/t/func_sapdb.test
index 8fd793f067b..930ad37c60c 100644
--- a/mysql-test/t/func_sapdb.test
+++ b/mysql-test/t/func_sapdb.test
@@ -37,6 +37,8 @@ select weekofyear("1997-11-31 23:59:59.000001");
select makedate(1997,1);
select makedate(1997,0);
+select makedate(9999,365);
+select makedate(9999,366);
#Time functions
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index d69545712c8..b232fb14e1e 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -140,6 +140,12 @@ select extract(SECOND FROM "1999-01-02 10:11:12");
select extract(MONTH FROM "2001-02-00");
#
+# MySQL Bugs: #12356: DATE_SUB or DATE_ADD incorrectly returns null
+#
+SELECT DATE_SUB(str_to_date('9999-12-31 00:01:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE);
+SELECT DATE_ADD(str_to_date('9999-12-30 23:59:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE);
+
+#
# Test big intervals (Bug #3498)
#
SELECT "1900-01-01 00:00:00" + INTERVAL 2147483648 SECOND;
diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test
index 3eb17f3a484..b66b97c2c41 100644
--- a/mysql-test/t/gis.test
+++ b/mysql-test/t/gis.test
@@ -364,3 +364,10 @@ select (asWKT(geomfromwkb((0x000000000140240000000000004024000000000000))));
select (asWKT(geomfromwkb((0x010100000000000000000024400000000000002440))));
# End of 4.1 tests
+
+--enable_metadata
+create table t1 (g GEOMETRY);
+select * from t1;
+select asbinary(g) from t1;
+--disable_metadata
+drop table t1;
diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test
index 85728582c75..9aab8a13b06 100644
--- a/mysql-test/t/key.test
+++ b/mysql-test/t/key.test
@@ -322,6 +322,18 @@ alter table t1 add key (c1,c1,c2);
drop table t1;
#
+# Bug#11228: DESC shows arbitrary column as "PRI"
+#
+create table t1 (
+ i1 INT NOT NULL,
+ i2 INT NOT NULL,
+ UNIQUE i1idx (i1),
+ UNIQUE i2idx (i2));
+desc t1;
+show create table t1;
+drop table t1;
+
+#
# Bug#12565 - ERROR 1034 when running simple UPDATE or DELETE
# on large MyISAM table
#
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index 5f948973141..ca49db40ae4 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -706,6 +706,18 @@ select count(id1) from t1 where id2 = 10;
drop table t1;
#
+# BUG##20357 - Got error 124 from storage engine using MIN and MAX functions
+# in queries
+#
+CREATE TABLE t1(a TINYINT, KEY(a)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES(1);
+SELECT MAX(a) FROM t1 IGNORE INDEX(a);
+ALTER TABLE t1 DISABLE KEYS;
+SELECT MAX(a) FROM t1;
+SELECT MAX(a) FROM t1 IGNORE INDEX(a);
+DROP TABLE t1;
+
+#
# BUG#18036 - update of table joined to self reports table as crashed
#
CREATE TABLE t1(a CHAR(9), b VARCHAR(7)) ENGINE=MyISAM;
diff --git a/mysql-test/t/mysql_client.test b/mysql-test/t/mysql_client.test
new file mode 100644
index 00000000000..e4b6658b631
--- /dev/null
+++ b/mysql-test/t/mysql_client.test
@@ -0,0 +1,29 @@
+# This test should work in embedded server after we fix mysqltest
+-- source include/not_embedded.inc
+
+#
+# Bug #20432: mysql client interprets commands in comments
+#
+
+# if the client sees the 'use' within the comment, we haven't fixed
+--exec echo "/*" > $MYSQLTEST_VARDIR/tmp/bug20432.sql
+--exec echo "use" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql
+--exec echo "*/" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql
+--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1
+
+# SQL can have embedded comments => workie
+--exec echo "select /*" > $MYSQLTEST_VARDIR/tmp/bug20432.sql
+--exec echo "use" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql
+--exec echo "*/ 1" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql
+--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1
+
+# client commands on the other hand must be at BOL => error
+--exec echo "/*" > $MYSQLTEST_VARDIR/tmp/bug20432.sql
+--exec echo "xxx" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql
+--exec echo "*/ use" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql
+--error 1
+--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1
+
+# client comment recognized, but parameter missing => error
+--exec echo "use" > $MYSQLTEST_VARDIR/tmp/bug20432.sql
+--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index eda89ff2dd3..e86635e24d0 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -652,7 +652,7 @@ drop table t1;
# BUG#15328 Segmentation fault occured if my.cnf is invalid for escape sequence
#
---exec $MYSQL_MY_PRINT_DEFAULTS --defaults-extra-file=$MYSQL_TEST_DIR/std_data/bug15328.cnf mysqldump
+--exec $MYSQL_MY_PRINT_DEFAULTS --defaults-file=$MYSQL_TEST_DIR/std_data/bug15328.cnf mysqldump
# BUG #19025 mysqldump doesn't correctly dump "auto_increment = [int]"
diff --git a/mysys/my_handler.c b/mysys/my_handler.c
index 3eed0ee6c08..156e7892580 100644
--- a/mysys/my_handler.c
+++ b/mysys/my_handler.c
@@ -15,6 +15,7 @@
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
+#include <my_global.h>
#include "my_handler.h"
int mi_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length,
diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp
index 66a400a3e22..3b257e2da48 100644
--- a/ndb/src/mgmsrv/ConfigInfo.cpp
+++ b/ndb/src/mgmsrv/ConfigInfo.cpp
@@ -857,7 +857,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
false,
ConfigInfo::CI_INT,
"8",
- "1",
+ "3",
STR_VALUE(MAX_INT_RNIL) },
{
diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh
index 0104d730e50..9b1cddbb7e4 100644
--- a/scripts/make_binary_distribution.sh
+++ b/scripts/make_binary_distribution.sh
@@ -162,11 +162,21 @@ if [ $BASE_SYSTEM = "netware" ] ; then
fi
copyfileto $BASE/lib \
- libmysql/.libs/libmysqlclient.a libmysql/.libs/libmysqlclient.so* \
- libmysql/libmysqlclient.* libmysql_r/.libs/libmysqlclient_r.a \
- libmysql_r/.libs/libmysqlclient_r.so* libmysql_r/libmysqlclient_r.* \
+ libmysql/.libs/libmysqlclient.a \
+ libmysql/.libs/libmysqlclient.so* \
+ libmysql/.libs/libmysqlclient.sl* \
+ libmysql/.libs/libmysqlclient*.dylib \
+ libmysql/libmysqlclient.* \
+ libmysql_r/.libs/libmysqlclient_r.a \
+ libmysql_r/.libs/libmysqlclient_r.so* \
+ libmysql_r/.libs/libmysqlclient_r.sl* \
+ libmysql_r/.libs/libmysqlclient_r*.dylib \
+ libmysql_r/libmysqlclient_r.* \
+ libmysqld/.libs/libmysqld.a \
+ libmysqld/.libs/libmysqld.so* \
+ libmysqld/.libs/libmysqld.sl* \
+ libmysqld/.libs/libmysqld*.dylib \
mysys/libmysys.a strings/libmystrings.a dbug/libdbug.a \
- libmysqld/.libs/libmysqld.a libmysqld/.libs/libmysqld.so* \
libmysqld/libmysqld.a netware/libmysql.imp \
zlib/.libs/libz.a
diff --git a/scripts/mysqld_safe-watch.sh b/scripts/mysqld_safe-watch.sh
index c59b3b2614d..c837ba9a118 100644
--- a/scripts/mysqld_safe-watch.sh
+++ b/scripts/mysqld_safe-watch.sh
@@ -93,10 +93,10 @@ do
if test "$#" -eq 0
then
nohup $ledir/mysqld --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR \
- --skip-locking >> $err 2>&1 &
+ --skip-external-locking >> $err 2>&1 &
else
nohup $ledir/mysqld --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR \
- --skip-locking "$@" >> $err 2>&1 &
+ --skip-external-locking "$@" >> $err 2>&1 &
fi
pid=$!
rm -f $lockfile
diff --git a/sql-common/client.c b/sql-common/client.c
index 3a598832253..ea8baeeffc7 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -133,6 +133,8 @@ static void mysql_close_free(MYSQL *mysql);
static int wait_for_data(my_socket fd, uint timeout);
#endif
+CHARSET_INFO *default_client_charset_info = &my_charset_latin1;
+
/****************************************************************************
A modified version of connect(). my_connect() allows you to specify
@@ -1424,7 +1426,7 @@ mysql_init(MYSQL *mysql)
bzero((char*) (mysql),sizeof(*(mysql)));
mysql->options.connect_timeout= CONNECT_TIMEOUT;
mysql->last_used_con= mysql->next_slave= mysql->master = mysql;
- mysql->charset=default_charset_info;
+ mysql->charset=default_client_charset_info;
strmov(mysql->net.sqlstate, not_error_sqlstate);
/*
By default, we are a replication pivot. The caller must reset it
@@ -1537,6 +1539,50 @@ static MYSQL_METHODS client_methods=
#endif
};
+C_MODE_START
+int mysql_init_character_set(MYSQL *mysql)
+{
+ NET *net= &mysql->net;
+ /* Set character set */
+ if (!mysql->options.charset_name &&
+ !(mysql->options.charset_name=
+ my_strdup(MYSQL_DEFAULT_CHARSET_NAME,MYF(MY_WME))))
+ return 1;
+
+ {
+ const char *save= charsets_dir;
+ if (mysql->options.charset_dir)
+ charsets_dir=mysql->options.charset_dir;
+ mysql->charset=get_charset_by_csname(mysql->options.charset_name,
+ MY_CS_PRIMARY, MYF(MY_WME));
+ charsets_dir= save;
+ }
+
+ if (!mysql->charset)
+ {
+ net->last_errno=CR_CANT_READ_CHARSET;
+ strmov(net->sqlstate, unknown_sqlstate);
+ if (mysql->options.charset_dir)
+ my_snprintf(net->last_error, sizeof(net->last_error)-1,
+ ER(net->last_errno),
+ mysql->options.charset_name,
+ mysql->options.charset_dir);
+ else
+ {
+ char cs_dir_name[FN_REFLEN];
+ get_charsets_dir(cs_dir_name);
+ my_snprintf(net->last_error, sizeof(net->last_error)-1,
+ ER(net->last_errno),
+ mysql->options.charset_name,
+ cs_dir_name);
+ }
+ return 1;
+ }
+ return 0;
+}
+C_MODE_END
+
+
MYSQL * STDCALL
CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db,
@@ -1875,42 +1921,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
goto error;
}
- /* Set character set */
- if (!mysql->options.charset_name &&
- !(mysql->options.charset_name=
- my_strdup(MYSQL_DEFAULT_CHARSET_NAME,MYF(MY_WME))))
- goto error;
-
- {
- const char *save= charsets_dir;
- if (mysql->options.charset_dir)
- charsets_dir=mysql->options.charset_dir;
- mysql->charset=get_charset_by_csname(mysql->options.charset_name,
- MY_CS_PRIMARY, MYF(MY_WME));
- charsets_dir= save;
- }
-
- if (!mysql->charset)
- {
- net->last_errno=CR_CANT_READ_CHARSET;
- strmov(net->sqlstate, unknown_sqlstate);
- if (mysql->options.charset_dir)
- my_snprintf(net->last_error, sizeof(net->last_error)-1,
- ER(net->last_errno),
- mysql->options.charset_name,
- mysql->options.charset_dir);
- else
- {
- char cs_dir_name[FN_REFLEN];
- get_charsets_dir(cs_dir_name);
- my_snprintf(net->last_error, sizeof(net->last_error)-1,
- ER(net->last_errno),
- mysql->options.charset_name,
- cs_dir_name);
- }
+ if (mysql_init_character_set(mysql))
goto error;
- }
-
/* Save connection information */
if (!my_multi_malloc(MYF(0),
diff --git a/sql/field.cc b/sql/field.cc
index ec4d4b4e4f5..3cb0c0d3a7c 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5072,17 +5072,6 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr)
{
uint a_len, b_len;
- if (field_charset->strxfrm_multiply > 1)
- {
- /*
- We have to remove end space to be able to compare multi-byte-characters
- like in latin_de 'ae' and 0xe4
- */
- return field_charset->coll->strnncollsp(field_charset,
- (const uchar*) a_ptr, field_length,
- (const uchar*) b_ptr,
- field_length);
- }
if (field_charset->mbmaxlen != 1)
{
uint char_len= field_length/field_charset->mbmaxlen;
@@ -5091,8 +5080,13 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr)
}
else
a_len= b_len= field_length;
- return my_strnncoll(field_charset,(const uchar*) a_ptr, a_len,
- (const uchar*) b_ptr, b_len);
+ /*
+ We have to remove end space to be able to compare multi-byte-characters
+ like in latin_de 'ae' and 0xe4
+ */
+ return field_charset->coll->strnncollsp(field_charset,
+ (const uchar*) a_ptr, a_len,
+ (const uchar*) b_ptr, b_len);
}
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index ffd5932a5c1..10240e597bf 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -270,6 +270,7 @@ void ha_ndbcluster::records_update()
{
Ndb *ndb= get_ndb();
Uint64 rows;
+ ndb->setDatabaseName(m_dbname);
if(ndb_get_table_statistics(ndb, m_tabname, &rows, 0) == 0){
info->records= rows;
}
@@ -1363,6 +1364,12 @@ int ha_ndbcluster::unique_index_read(const byte *key,
m_value[i].ptr= NULL;
}
}
+ if (table->primary_key == MAX_KEY)
+ {
+ DBUG_PRINT("info", ("Getting hidden key"));
+ if (get_ndb_value(op, NULL, i, NULL))
+ ERR_RETURN(op->getNdbError());
+ }
if (execute_no_commit_ie(this,trans) != 0)
{
@@ -2299,12 +2306,14 @@ void ha_ndbcluster::unpack_record(byte* buf)
{
// Table with hidden primary key
int hidden_no= table->fields;
+ char buff[22];
const NDBTAB *tab= (const NDBTAB *) m_table;
const NDBCOL *hidden_col= tab->getColumn(hidden_no);
NdbRecAttr* rec= m_value[hidden_no].rec;
DBUG_ASSERT(rec);
- DBUG_PRINT("hidden", ("%d: %s \"%llu\"", hidden_no,
- hidden_col->getName(), rec->u_64_value()));
+ DBUG_PRINT("hidden", ("%d: %s \"%s\"", hidden_no,
+ hidden_col->getName(),
+ llstr(rec->u_64_value(), buff)));
}
print_results();
#endif
@@ -2876,6 +2885,7 @@ void ha_ndbcluster::info(uint flag)
DBUG_VOID_RETURN;
Ndb *ndb= get_ndb();
Uint64 rows= 100;
+ ndb->setDatabaseName(m_dbname);
if (current_thd->variables.ndb_use_exact_count)
ndb_get_table_statistics(ndb, m_tabname, &rows, 0);
records= rows;
@@ -5228,34 +5238,53 @@ ndb_get_table_statistics(Ndb* ndb, const char * table,
{
DBUG_ENTER("ndb_get_table_statistics");
DBUG_PRINT("enter", ("table: %s", table));
- NdbConnection* pTrans= ndb->startTransaction();
- do
+ NdbConnection* pTrans;
+ NdbError error;
+ int retries= 10;
+ int retry_sleep= 30 * 1000; /* 30 milliseconds */
+
+ do
{
- if (pTrans == NULL)
- break;
+ Uint64 rows, commits;
+ Uint64 sum_rows= 0;
+ Uint64 sum_commits= 0;
+ NdbScanOperation*pOp;
+ NdbResultSet *rs;
+ int check;
+
+ if ((pTrans= ndb->startTransaction()) == NULL)
+ {
+ error= ndb->getNdbError();
+ goto retry;
+ }
- NdbScanOperation* pOp= pTrans->getNdbScanOperation(table);
- if (pOp == NULL)
- break;
+ if ((pOp= pTrans->getNdbScanOperation(table)) == NULL)
+ {
+ error= pTrans->getNdbError();
+ goto retry;
+ }
- NdbResultSet* rs= pOp->readTuples(NdbOperation::LM_CommittedRead);
- if (rs == 0)
- break;
+ if ((rs= pOp->readTuples(NdbOperation::LM_CommittedRead)) == 0)
+ {
+ error= pOp->getNdbError();
+ goto retry;
+ }
- int check= pOp->interpret_exit_last_row();
- if (check == -1)
- break;
+ if (pOp->interpret_exit_last_row() == -1)
+ {
+ error= pOp->getNdbError();
+ goto retry;
+ }
- Uint64 rows, commits;
pOp->getValue(NdbDictionary::Column::ROW_COUNT, (char*)&rows);
pOp->getValue(NdbDictionary::Column::COMMIT_COUNT, (char*)&commits);
- check= pTrans->execute(NoCommit, AbortOnError, TRUE);
- if (check == -1)
- break;
+ if (pTrans->execute(NoCommit, AbortOnError, TRUE) == -1)
+ {
+ error= pTrans->getNdbError();
+ goto retry;
+ }
- Uint64 sum_rows= 0;
- Uint64 sum_commits= 0;
while((check= rs->nextResult(TRUE, TRUE)) == 0)
{
sum_rows+= rows;
@@ -5263,7 +5292,10 @@ ndb_get_table_statistics(Ndb* ndb, const char * table,
}
if (check == -1)
- break;
+ {
+ error= pOp->getNdbError();
+ goto retry;
+ }
rs->close(TRUE);
@@ -5274,11 +5306,22 @@ ndb_get_table_statistics(Ndb* ndb, const char * table,
* commit_count= sum_commits;
DBUG_PRINT("exit", ("records: %u commits: %u", sum_rows, sum_commits));
DBUG_RETURN(0);
- } while(0);
- ndb->closeTransaction(pTrans);
- DBUG_PRINT("exit", ("failed"));
- DBUG_RETURN(-1);
+retry:
+ if (pTrans)
+ {
+ ndb->closeTransaction(pTrans);
+ pTrans= NULL;
+ }
+ if (error.status == NdbError::TemporaryError && retries--)
+ {
+ my_sleep(retry_sleep);
+ continue;
+ }
+ break;
+ } while(1);
+ DBUG_PRINT("exit", ("failed, error %u(%s)", error.code, error.message));
+ ERR_RETURN(error);
}
/*
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 68852b5a5f6..73abe208d9e 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -124,6 +124,8 @@ public:
class Comp_creator
{
public:
+ Comp_creator() {} /* Remove gcc warning */
+ virtual ~Comp_creator() {} /* Remove gcc warning */
virtual Item_bool_func2* create(Item *a, Item *b) const = 0;
virtual const char* symbol(bool invert) const = 0;
virtual bool eqne_op() const = 0;
@@ -133,6 +135,8 @@ public:
class Eq_creator :public Comp_creator
{
public:
+ Eq_creator() {} /* Remove gcc warning */
+ virtual ~Eq_creator() {} /* Remove gcc warning */
virtual Item_bool_func2* create(Item *a, Item *b) const;
virtual const char* symbol(bool invert) const { return invert? "<>" : "="; }
virtual bool eqne_op() const { return 1; }
@@ -142,6 +146,8 @@ public:
class Ne_creator :public Comp_creator
{
public:
+ Ne_creator() {} /* Remove gcc warning */
+ virtual ~Ne_creator() {} /* Remove gcc warning */
virtual Item_bool_func2* create(Item *a, Item *b) const;
virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; }
virtual bool eqne_op() const { return 1; }
@@ -151,6 +157,8 @@ public:
class Gt_creator :public Comp_creator
{
public:
+ Gt_creator() {} /* Remove gcc warning */
+ virtual ~Gt_creator() {} /* Remove gcc warning */
virtual Item_bool_func2* create(Item *a, Item *b) const;
virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
virtual bool eqne_op() const { return 0; }
@@ -160,6 +168,8 @@ public:
class Lt_creator :public Comp_creator
{
public:
+ Lt_creator() {} /* Remove gcc warning */
+ virtual ~Lt_creator() {} /* Remove gcc warning */
virtual Item_bool_func2* create(Item *a, Item *b) const;
virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
virtual bool eqne_op() const { return 0; }
@@ -169,6 +179,8 @@ public:
class Ge_creator :public Comp_creator
{
public:
+ Ge_creator() {} /* Remove gcc warning */
+ virtual ~Ge_creator() {} /* Remove gcc warning */
virtual Item_bool_func2* create(Item *a, Item *b) const;
virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
virtual bool eqne_op() const { return 0; }
@@ -178,6 +190,8 @@ public:
class Le_creator :public Comp_creator
{
public:
+ Le_creator() {} /* Remove gcc warning */
+ virtual ~Le_creator() {} /* Remove gcc warning */
virtual Item_bool_func2* create(Item *a, Item *b) const;
virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
virtual bool eqne_op() const { return 0; }
diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h
index 5f060416ff3..a466b606dc1 100644
--- a/sql/item_geofunc.h
+++ b/sql/item_geofunc.h
@@ -32,6 +32,7 @@ public:
Item_geometry_func(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
Item_geometry_func(List<Item> &list) :Item_str_func(list) {}
void fix_length_and_dec();
+ enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; }
};
class Item_func_geometry_from_text: public Item_geometry_func
@@ -67,6 +68,7 @@ public:
Item_func_as_wkb(Item *a): Item_geometry_func(a) {}
const char *func_name() const { return "aswkb"; }
String *val_str(String *);
+ enum_field_types field_type() const { return MYSQL_TYPE_BLOB; }
};
class Item_func_geometry_type: public Item_str_func
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 4b522cf06fa..0b9b10d05d4 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -930,7 +930,6 @@ Item_sum_hybrid::min_max_update_str_field()
if (!args[0]->null_value)
{
- res_str->strip_sp();
result_field->val_str(&tmp_value);
if (result_field->is_null() ||
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 8d3e768b74e..27876096bc5 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -27,6 +27,7 @@
/* TODO: Move month and days to language files */
+/* Day number for Dec 31st, 9999 */
#define MAX_DAY_NUMBER 3652424L
static const char *month_names[]=
@@ -401,7 +402,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
if (yearday > 0)
{
uint days= calc_daynr(l_time->year,1,1) + yearday - 1;
- if (days <= 0 || days >= MAX_DAY_NUMBER)
+ if (days <= 0 || days > MAX_DAY_NUMBER)
goto err;
get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day);
}
@@ -447,7 +448,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
(weekday - 1);
}
- if (days <= 0 || days >= MAX_DAY_NUMBER)
+ if (days <= 0 || days > MAX_DAY_NUMBER)
goto err;
get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day);
}
@@ -1931,7 +1932,7 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date)
ltime->hour= (uint) (sec/3600);
daynr= calc_daynr(ltime->year,ltime->month,1) + days;
/* Day number from year 0 to 9999-12-31 */
- if ((ulonglong) daynr >= MAX_DAY_NUMBER)
+ if ((ulonglong) daynr > MAX_DAY_NUMBER)
goto null_date;
get_date_from_daynr((long) daynr, &ltime->year, &ltime->month,
&ltime->day);
@@ -1941,7 +1942,7 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date)
period= (calc_daynr(ltime->year,ltime->month,ltime->day) +
sign * (long) interval.day);
/* Daynumber from year 0 to 9999-12-31 */
- if ((ulong) period >= MAX_DAY_NUMBER)
+ if ((ulong) period > MAX_DAY_NUMBER)
goto null_date;
get_date_from_daynr((long) period,&ltime->year,&ltime->month,&ltime->day);
break;
@@ -2412,7 +2413,7 @@ String *Item_func_makedate::val_str(String *str)
days= calc_daynr(yearnr,1,1) + daynr - 1;
/* Day number from year 0 to 9999-12-31 */
- if (days >= 0 && days < MAX_DAY_NUMBER)
+ if (days >= 0 && days <= MAX_DAY_NUMBER)
{
null_value=0;
get_date_from_daynr(days,&l_time.year,&l_time.month,&l_time.day);
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 67141aab6ce..34f11e4968a 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -63,8 +63,8 @@ public:
SEL_ARG(Field *field, uint8 part, char *min_value, char *max_value,
uint8 min_flag, uint8 max_flag, uint8 maybe_flag);
SEL_ARG(enum Type type_arg)
- :elements(1),use_count(1),left(0),next_key_part(0),color(BLACK),
- type(type_arg),min_flag(0)
+ :min_flag(0),elements(1),use_count(1),left(0),next_key_part(0),
+ color(BLACK), type(type_arg)
{}
inline bool is_same(SEL_ARG *arg)
{
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 97e271121d3..b53fbfd3f80 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -676,6 +676,12 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
{
KEY_PART_INFO *part,*part_end;
key_part_map key_part_to_use= 0;
+ /*
+ Perform a check if index is not disabled by ALTER TABLE
+ or IGNORE INDEX.
+ */
+ if (!table->keys_in_use_for_query.is_set(idx))
+ continue;
uint jdx= 0;
*prefix_len= 0;
for (part= keyinfo->key_part, part_end= part+keyinfo->key_parts ;
diff --git a/sql/spatial.h b/sql/spatial.h
index 206958b3eaf..378233a2156 100644
--- a/sql/spatial.h
+++ b/sql/spatial.h
@@ -165,6 +165,8 @@ struct Geometry_buffer;
class Geometry
{
public:
+ Geometry() {} /* remove gcc warning */
+ virtual ~Geometry() {} /* remove gcc warning */
static void *operator new(size_t size, void *buffer)
{
return buffer;
@@ -173,6 +175,8 @@ public:
static void operator delete(void *ptr, void *buffer)
{}
+ static void operator delete(void *buffer) {} /* remove gcc warning */
+
enum wkbType
{
wkb_point= 1,
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 06005f31198..fbe36bfdc4a 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -667,6 +667,37 @@ static void reset_mqh(THD *thd, LEX_USER *lu, bool get_them= 0)
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
}
+void thd_init_client_charset(THD *thd, uint cs_number)
+{
+ /*
+ Use server character set and collation if
+ - opt_character_set_client_handshake is not set
+ - client has not specified a character set
+ - client character set is the same as the servers
+ - 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))) ||
+ !my_strcasecmp(&my_charset_latin1,
+ global_system_variables.character_set_client->name,
+ thd->variables.character_set_client->name))
+ {
+ thd->variables.character_set_client=
+ global_system_variables.character_set_client;
+ thd->variables.collation_connection=
+ global_system_variables.collation_connection;
+ thd->variables.character_set_results=
+ global_system_variables.character_set_results;
+ }
+ else
+ {
+ thd->variables.character_set_results=
+ thd->variables.collation_connection=
+ thd->variables.character_set_client;
+ }
+}
+
+
/*
Perform handshake, authorize client and update thd ACL variables.
SYNOPSIS
@@ -809,33 +840,7 @@ 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]));
- /*
- Use server character set and collation if
- - opt_character_set_client_handshake is not set
- - client has not specified a character set
- - client character set is the same as the servers
- - client character set doesn't exists in server
- */
- if (!opt_character_set_client_handshake ||
- !(thd->variables.character_set_client=
- get_charset((uint) net->read_pos[8], MYF(0))) ||
- !my_strcasecmp(&my_charset_latin1,
- global_system_variables.character_set_client->name,
- thd->variables.character_set_client->name))
- {
- thd->variables.character_set_client=
- global_system_variables.character_set_client;
- thd->variables.collation_connection=
- global_system_variables.collation_connection;
- thd->variables.character_set_results=
- global_system_variables.character_set_results;
- }
- else
- {
- thd->variables.character_set_results=
- thd->variables.collation_connection=
- thd->variables.character_set_client;
- }
+ thd_init_client_charset(thd, (uint) net->read_pos[8]);
thd->update_charset();
end= (char*) net->read_pos+32;
}
@@ -2673,6 +2678,12 @@ unsent_create_error:
}
}
/* Don't yet allow changing of symlinks with ALTER TABLE */
+ if (lex->create_info.data_file_name)
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
+ "DATA DIRECTORY option ignored");
+ if (lex->create_info.index_file_name)
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
+ "INDEX DIRECTORY option ignored");
lex->create_info.data_file_name=lex->create_info.index_file_name=0;
/* ALTER TABLE ends previous transaction */
if (end_active_trans(thd))
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 709ff9726bb..cb23662f42c 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -114,6 +114,10 @@ static Item* part_of_refkey(TABLE *form,Field *field);
static uint find_shortest_key(TABLE *table, const key_map *usable_keys);
static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,
ha_rows select_limit, bool no_changes);
+static bool list_contains_unique_index(TABLE *table,
+ bool (*find_func) (Field *, void *), void *data);
+static bool find_field_in_item_list (Field *field, void *data);
+static bool find_field_in_order_list (Field *field, void *data);
static int create_sort_index(THD *thd, JOIN *join, ORDER *order,
ha_rows filesort_limit, ha_rows select_limit);
static int remove_duplicates(JOIN *join,TABLE *entry,List<Item> &fields,
@@ -695,6 +699,36 @@ JOIN::optimize()
if (old_group_list && !group_list)
select_distinct= 0;
}
+ /*
+ Check if we can optimize away GROUP BY/DISTINCT.
+ We can do that if there are no aggregate functions and the
+ fields in DISTINCT clause (if present) and/or columns in GROUP BY
+ (if present) contain direct references to all key parts of
+ an unique index (in whatever order).
+ Note that the unique keys for DISTINCT and GROUP BY should not
+ be the same (as long as they are unique).
+
+ The FROM clause must contain a single non-constant table.
+ */
+ if (tables - const_tables == 1 && (group_list || select_distinct) &&
+ !tmp_table_param.sum_func_count)
+ {
+ if (group_list &&
+ list_contains_unique_index(join_tab[const_tables].table,
+ find_field_in_order_list,
+ (void *) group_list))
+ {
+ group_list= 0;
+ group= 0;
+ }
+ if (select_distinct &&
+ list_contains_unique_index(join_tab[const_tables].table,
+ find_field_in_item_list,
+ (void *) &fields_list))
+ {
+ select_distinct= 0;
+ }
+ }
if (!group_list && group)
{
order=0; // The output has only one row
@@ -7376,6 +7410,140 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
return best;
}
+
+/*
+ Check if GROUP BY/DISTINCT can be optimized away because the set is
+ already known to be distinct.
+
+ SYNOPSIS
+ list_contains_unique_index ()
+ table The table to operate on.
+ find_func function to iterate over the list and search
+ for a field
+
+ DESCRIPTION
+ Used in removing the GROUP BY/DISTINCT of the following types of
+ statements:
+ SELECT [DISTINCT] <unique_key_cols>... FROM <single_table_ref>
+ [GROUP BY <unique_key_cols>,...]
+
+ If (a,b,c is distinct)
+ then <any combination of a,b,c>,{whatever} is also distinct
+
+ This function checks if all the key parts of any of the unique keys
+ of the table are referenced by a list : either the select list
+ through find_field_in_item_list or GROUP BY list through
+ find_field_in_order_list.
+ If the above holds then we can safely remove the GROUP BY/DISTINCT,
+ as no result set can be more distinct than an unique key.
+
+ RETURN VALUE
+ 1 found
+ 0 not found.
+*/
+
+static bool
+list_contains_unique_index(TABLE *table,
+ bool (*find_func) (Field *, void *), void *data)
+{
+ for (uint keynr= 0; keynr < table->keys; keynr++)
+ {
+ if (keynr == table->primary_key ||
+ (table->key_info[keynr].flags & HA_NOSAME))
+ {
+ KEY *keyinfo= table->key_info + keynr;
+ KEY_PART_INFO *key_part, *key_part_end;
+
+ for (key_part=keyinfo->key_part,
+ key_part_end=key_part+ keyinfo->key_parts;
+ key_part < key_part_end;
+ key_part++)
+ {
+ if (!find_func(key_part->field, data))
+ break;
+ }
+ if (key_part == key_part_end)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/*
+ Helper function for list_contains_unique_index.
+ Find a field reference in a list of ORDER structures.
+
+ SYNOPSIS
+ find_field_in_order_list ()
+ field The field to search for.
+ data ORDER *.The list to search in
+
+ DESCRIPTION
+ Finds a direct reference of the Field in the list.
+
+ RETURN VALUE
+ 1 found
+ 0 not found.
+*/
+
+static bool
+find_field_in_order_list (Field *field, void *data)
+{
+ ORDER *group= (ORDER *) data;
+ bool part_found= 0;
+ for (ORDER *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
+ {
+ Item *item= (*tmp_group->item)->real_item();
+ if (item->type() == Item::FIELD_ITEM &&
+ ((Item_field*) item)->field->eq(field))
+ {
+ part_found= 1;
+ break;
+ }
+ }
+ return part_found;
+}
+
+
+/*
+ Helper function for list_contains_unique_index.
+ Find a field reference in a dynamic list of Items.
+
+ SYNOPSIS
+ find_field_in_item_list ()
+ field in The field to search for.
+ data in List<Item> *.The list to search in
+
+ DESCRIPTION
+ Finds a direct reference of the Field in the list.
+
+ RETURN VALUE
+ 1 found
+ 0 not found.
+*/
+
+static bool
+find_field_in_item_list (Field *field, void *data)
+{
+ List<Item> *fields= (List<Item> *) data;
+ bool part_found= 0;
+ List_iterator<Item> li(*fields);
+ Item *item;
+
+ while ((item= li++))
+ {
+ if (item->type() == Item::FIELD_ITEM &&
+ ((Item_field*) item)->field->eq(field))
+ {
+ part_found= 1;
+ break;
+ }
+ }
+ return part_found;
+}
+
+
/*
Test if we can skip the ORDER BY by using an index.
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 75cd0b4d797..c61ef4fb92b 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -229,7 +229,7 @@ class JOIN :public Sql_alloc
}
JOIN(JOIN &join)
- :fields_list(join.fields_list)
+ :Sql_alloc(), fields_list(join.fields_list)
{
init(join.thd, join.fields_list, join.select_options,
join.result);
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 16423b39786..089d0bf0660 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1094,7 +1094,7 @@ bool multi_update::send_data(List<Item> &not_used_values)
memcpy((char*) tmp_table->field[0]->ptr,
(char*) table->file->ref, table->file->ref_length);
/* Write row, ignoring duplicated updates to a row */
- if (error= tmp_table->file->write_row(tmp_table->record[0]))
+ if ((error= tmp_table->file->write_row(tmp_table->record[0])))
{
if (error != HA_ERR_FOUND_DUPP_KEY &&
error != HA_ERR_FOUND_DUPP_UNIQUE &&
diff --git a/sql/time.cc b/sql/time.cc
index e76b169b336..ef832ac5a70 100644
--- a/sql/time.cc
+++ b/sql/time.cc
@@ -797,7 +797,7 @@ void make_truncated_value_warning(THD *thd, const char *str_val,
}
sprintf(warn_buff, ER(ER_TRUNCATED_WRONG_VALUE),
type_str, str.ptr());
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE, warn_buff);
}
diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c
index eb032759d25..4f57f7c78e4 100644
--- a/strings/ctype-mb.c
+++ b/strings/ctype-mb.c
@@ -502,21 +502,19 @@ my_bool my_like_range_mb(CHARSET_INFO *cs,
char *min_str,char *max_str,
uint *min_length,uint *max_length)
{
+ uint mblen;
const char *end= ptr + ptr_length;
char *min_org= min_str;
char *min_end= min_str + res_length;
char *max_end= max_str + res_length;
- uint charlen= res_length / cs->mbmaxlen;
+ uint maxcharlen= res_length / cs->mbmaxlen;
- for (; ptr != end && min_str != min_end && charlen > 0 ; ptr++, charlen--)
+ for (; ptr != end && min_str != min_end && maxcharlen ; maxcharlen--)
{
+ /* We assume here that escape, w_any, w_namy are one-byte characters */
if (*ptr == escape && ptr+1 != end)
- {
- ptr++; /* Skip escape */
- *min_str++= *max_str++ = *ptr;
- continue;
- }
- if (*ptr == w_one || *ptr == w_many) /* '_' and '%' in SQL */
+ ptr++; /* Skip escape */
+ else if (*ptr == w_one || *ptr == w_many) /* '_' and '%' in SQL */
{
/* Write min key */
*min_length= (uint) (min_str - min_org);
@@ -534,7 +532,16 @@ my_bool my_like_range_mb(CHARSET_INFO *cs,
pad_max_char(cs, max_str, max_end);
return 0;
}
- *min_str++= *max_str++ = *ptr;
+ if ((mblen= my_ismbchar(cs, ptr, end)) > 1)
+ {
+ if (ptr+mblen > end || min_str+mblen > min_end)
+ break;
+ while (mblen--)
+ *min_str++= *max_str++= *ptr++;
+ }
+ else
+ *min_str++= *max_str++= *ptr++;
+
}
*min_length= *max_length = (uint) (min_str - min_org);
diff --git a/strings/strtod.c b/strings/strtod.c
index 61f2c107abe..da1b4f4baa6 100644
--- a/strings/strtod.c
+++ b/strings/strtod.c
@@ -26,8 +26,8 @@
*/
-#include "my_base.h" /* Includes errno.h */
-#include "m_ctype.h"
+#include <my_global.h> /* Includes errno.h */
+#include <m_ctype.h>
#define MAX_DBL_EXP 308
#define MAX_RESULT_FOR_MAX_EXP 1.79769313486232
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index 9656851dc9c..854ad2e7ce7 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -148,6 +148,7 @@ Summary: MySQL - Benchmarks and test system
Group: Applications/Databases
Provides: mysql-bench
Obsoletes: mysql-bench
+AutoReqProv: no
%description bench
This package contains MySQL benchmark scripts and data.
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 3c54bf50c15..94034141d81 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -11855,6 +11855,58 @@ static void test_bug15613()
mysql_stmt_close(stmt);
}
+
+/*
+ Bug#20152: mysql_stmt_execute() writes to MYSQL_TYPE_DATE buffer
+ */
+static void test_bug20152()
+{
+ MYSQL_BIND bind[1];
+ MYSQL_STMT *stmt;
+ MYSQL_TIME tm;
+ int rc;
+ const char *query= "INSERT INTO t1 (f1) VALUES (?)";
+
+ myheader("test_bug20152");
+
+ memset(bind, 0, sizeof(bind));
+ bind[0].buffer_type= MYSQL_TYPE_DATE;
+ bind[0].buffer= (void*)&tm;
+
+ tm.year = 2006;
+ tm.month = 6;
+ tm.day = 18;
+ tm.hour = 14;
+ tm.minute = 9;
+ tm.second = 42;
+
+ rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
+ myquery(rc);
+ rc= mysql_query(mysql, "CREATE TABLE t1 (f1 DATE)");
+ myquery(rc);
+
+ stmt= mysql_stmt_init(mysql);
+ rc= mysql_stmt_prepare(stmt, query, strlen(query));
+ check_execute(stmt, rc);
+ rc= mysql_stmt_bind_param(stmt, bind);
+ check_execute(stmt, rc);
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ rc= mysql_stmt_close(stmt);
+ check_execute(stmt, rc);
+ rc= mysql_query(mysql, "DROP TABLE t1");
+ myquery(rc);
+
+ if (tm.hour == 14 && tm.minute == 9 && tm.second == 42) {
+ if (!opt_silent)
+ printf("OK!");
+ } else {
+ printf("[14:09:42] != [%02d:%02d:%02d]\n", tm.hour, tm.minute, tm.second);
+ DIE_UNLESS(0==1);
+ }
+}
+
+
/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -12078,6 +12130,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug11718", test_bug11718 },
{ "test_bug12925", test_bug12925 },
{ "test_bug15613", test_bug15613 },
+ { "test_bug20152", test_bug20152 },
{ 0, 0 }
};