summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <tulin@build.mysql.com>2004-09-09 10:41:33 +0200
committerunknown <tulin@build.mysql.com>2004-09-09 10:41:33 +0200
commit9106686846cb87de91afe5068b29caa72e2e537b (patch)
tree08926077476c0cd8f62d6215c6a9dc9c61d8f1bf
parentc59228f85c881f31e3fa017d15a7c7fba8ab708a (diff)
parent1460e454d066c928de8f95870c72a2515d8bbc79 (diff)
downloadmariadb-git-9106686846cb87de91afe5068b29caa72e2e537b.tar.gz
Merge tulin@bk-internal.mysql.com:/home/bk/mysql-4.1
into build.mysql.com:/users/tulin/mysql-4.1-ndb-merge sql/ha_ndbcluster.cc: Auto merged sql/handler.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_table.cc: Auto merged
-rw-r--r--client/mysql.cc36
-rw-r--r--client/mysqlcheck.c8
-rw-r--r--include/m_ctype.h7
-rw-r--r--innobase/srv/srv0start.c40
-rw-r--r--innobase/trx/trx0undo.c2
-rw-r--r--libmysql/errmsg.c12
-rw-r--r--libmysql/libmysql.c31
-rw-r--r--mysql-test/r/cast.result23
-rw-r--r--mysql-test/r/ctype_uca.result39
-rw-r--r--mysql-test/r/ctype_utf8.result5
-rw-r--r--mysql-test/r/func_group.result9
-rw-r--r--mysql-test/r/group_by.result9
-rw-r--r--mysql-test/r/ndb_insert.result12
-rw-r--r--mysql-test/r/rpl_set_charset.result48
-rw-r--r--mysql-test/r/select.result16
-rw-r--r--mysql-test/r/subselect_innodb.result8
-rw-r--r--mysql-test/r/type_float.result2
-rw-r--r--mysql-test/t/cast.test13
-rw-r--r--mysql-test/t/ctype_uca.test37
-rw-r--r--mysql-test/t/ctype_utf8.test7
-rw-r--r--mysql-test/t/func_group.test16
-rw-r--r--mysql-test/t/group_by.test9
-rw-r--r--mysql-test/t/ndb_insert.test29
-rw-r--r--mysql-test/t/rpl_set_charset.test33
-rw-r--r--mysql-test/t/select.test21
-rw-r--r--mysql-test/t/subselect_innodb.test14
-rw-r--r--scripts/mysqld_safe.sh37
-rw-r--r--sql-common/client.c6
-rw-r--r--sql/field.cc2
-rw-r--r--sql/ha_myisam.cc20
-rw-r--r--sql/ha_ndbcluster.cc47
-rw-r--r--sql/handler.cc2
-rw-r--r--sql/item_func.h2
-rw-r--r--sql/item_sum.cc2
-rw-r--r--sql/item_timefunc.cc18
-rw-r--r--sql/item_timefunc.h5
-rw-r--r--sql/log.cc36
-rw-r--r--sql/log_event.cc14
-rw-r--r--sql/mysqld.cc111
-rw-r--r--sql/net_serv.cc2
-rw-r--r--sql/opt_range.cc6
-rw-r--r--sql/opt_sum.cc18
-rw-r--r--sql/slave.cc15
-rw-r--r--sql/sql_acl.cc56
-rw-r--r--sql/sql_analyse.cc7
-rw-r--r--sql/sql_base.cc8
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_class.h21
-rw-r--r--sql/sql_db.cc5
-rw-r--r--sql/sql_parse.cc12
-rw-r--r--sql/sql_prepare.cc10
-rw-r--r--sql/sql_select.cc1
-rw-r--r--sql/sql_table.cc47
-rw-r--r--sql/sql_udf.cc3
-rw-r--r--strings/ctype-mb.c88
-rw-r--r--strings/ctype-uca.c7
-rw-r--r--tests/client_test.c269
57 files changed, 1066 insertions, 299 deletions
diff --git a/client/mysql.cc b/client/mysql.cc
index 0b43f9b80ec..e940fdcc406 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -2602,32 +2602,31 @@ com_use(String *buffer __attribute__((unused)), char *line)
put_info("USE must be followed by a database name", INFO_ERROR);
return 0;
}
-
- /*
- We need to recheck the current database, because it may change
- under our feet, for example if DROP DATABASE or RENAME DATABASE
- (latter one not yet available by the time the comment was written)
+ /*
+ We need to recheck the current database, because it may change
+ under our feet, for example if DROP DATABASE or RENAME DATABASE
+ (latter one not yet available by the time the comment was written)
*/
- current_db= 0; // Let's reset current_db, assume it's gone
- /*
- We don't care about in case of an error below because current_db
- was just set to 0.
+ /* Let's reset current_db, assume it's gone */
+ my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
+ current_db= 0;
+ /*
+ We don't care about in case of an error below because current_db
+ was just set to 0.
*/
if (!mysql_query(&mysql, "SELECT DATABASE()") &&
(res= mysql_use_result(&mysql)))
{
row= mysql_fetch_row(res);
- if (row[0] &&
- (!current_db || cmp_database(charset_info, current_db, row[0])))
+ if (row[0])
{
- my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
current_db= my_strdup(row[0], MYF(MY_WME));
}
- (void) mysql_fetch_row(res); // Read eof
+ (void) mysql_fetch_row(res); // Read eof
mysql_free_result(res);
}
-
- if (!current_db || cmp_database(charset_info, current_db, tmp))
+
+ if (!current_db || cmp_database(charset_info, current_db,tmp))
{
if (one_database)
skip_updates= 1;
@@ -2948,7 +2947,12 @@ put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate)
(void) fflush(file);
fprintf(file,"ERROR");
if (error)
- (void) fprintf(file," %d",error);
+ {
+ if (sqlstate)
+ (void) fprintf(file," %d (%s)",error, sqlstate);
+ else
+ (void) fprintf(file," %d",error);
+ }
if (status.query_start_line && line_numbers)
{
(void) fprintf(file," at line %lu",status.query_start_line);
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index b072d1c86fe..bcfceb74f14 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -436,18 +436,18 @@ static int process_all_tables_in_db(char *database)
LINT_INIT(res);
if (use_db(database))
return 1;
- if (!(mysql_query(sock, "SHOW TABLES") ||
- (res = mysql_store_result(sock))))
+ if (mysql_query(sock, "SHOW TABLES") ||
+ !((res= mysql_store_result(sock))))
return 1;
if (opt_all_in_1)
{
- /*
+ /*
We need table list in form `a`, `b`, `c`
that's why we need 4 more chars added to to each table name
space is for more readable output in logs and in case of error
*/
-
+
char *tables, *end;
uint tot_length = 0;
diff --git a/include/m_ctype.h b/include/m_ctype.h
index 65b11f4c06a..16490af7fc3 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -312,6 +312,13 @@ my_bool my_like_range_simple(CHARSET_INFO *cs,
char *min_str, char *max_str,
uint *min_length, uint *max_length);
+my_bool my_like_range_mb(CHARSET_INFO *cs,
+ const char *ptr, uint ptr_length,
+ pbool escape, pbool w_one, pbool w_many,
+ uint res_length,
+ char *min_str, char *max_str,
+ uint *min_length, uint *max_length);
+
my_bool my_like_range_ucs2(CHARSET_INFO *cs,
const char *ptr, uint ptr_length,
pbool escape, pbool w_one, pbool w_many,
diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c
index 4a0335086f0..8e48034e09c 100644
--- a/innobase/srv/srv0start.c
+++ b/innobase/srv/srv0start.c
@@ -1055,34 +1055,15 @@ innobase_start_or_create_for_mysql(void)
srv_file_flush_method_str);
return(DB_ERROR);
}
-
- /* Set the maximum number of threads which can wait for a semaphore
- inside InnoDB */
-#if defined(__WIN__) || defined(__NETWARE__)
-/* Create less event semaphores because Win 98/ME had difficulty creating
-40000 event semaphores.
-Comment from Novell, Inc.: also, these just take a lot of memory on
-NetWare. */
- srv_max_n_threads = 1000;
-#else
- if (srv_pool_size >= 8 * 1024) {
- /* Here we still have srv_pool_size counted
- in kilobytes, srv_boot converts the value to
- pages; if buffer pool is less than 8 MB,
- assume fewer threads. */
- srv_max_n_threads = 10000;
- } else {
- srv_max_n_threads = 1000; /* saves several MB of memory,
- especially in 64-bit
- computers */
- }
-#endif
/* Note that the call srv_boot() also changes the values of
srv_pool_size etc. to the units used by InnoDB internally */
/* Set the maximum number of threads which can wait for a semaphore
- inside InnoDB */
+ inside InnoDB: this is the 'sync wait array' size, as well as the
+ maximum number of threads that can wait in the 'srv_conc array' for
+ their time to enter InnoDB. */
+
#if defined(__WIN__) || defined(__NETWARE__)
/* Create less event semaphores because Win 98/ME had difficulty creating
@@ -1091,11 +1072,16 @@ Comment from Novell, Inc.: also, these just take a lot of memory on
NetWare. */
srv_max_n_threads = 1000;
#else
- if (srv_pool_size >= 8 * 1024 * 1024) {
+ if (srv_pool_size >= 1000 * 1024) {
/* Here we still have srv_pool_size counted
- in bytes, srv_boot converts the value to
- pages; if buffer pool is less than 8 MB,
+ in kilobytes (in 4.0 this was in bytes)
+ srv_boot() converts the value to
+ pages; if buffer pool is less than 1000 MB,
assume fewer threads. */
+ srv_max_n_threads = 50000;
+
+ } else if (srv_pool_size >= 8 * 1024) {
+
srv_max_n_threads = 10000;
} else {
srv_max_n_threads = 1000; /* saves several MB of memory,
@@ -1103,7 +1089,7 @@ NetWare. */
computers */
}
#endif
- err = srv_boot();
+ err = srv_boot(); /* This changes srv_pool_size to units of a page */
if (err != DB_SUCCESS) {
diff --git a/innobase/trx/trx0undo.c b/innobase/trx/trx0undo.c
index 79566fe01c3..c1edc223cbc 100644
--- a/innobase/trx/trx0undo.c
+++ b/innobase/trx/trx0undo.c
@@ -404,7 +404,7 @@ trx_undo_seg_create(
ut_print_timestamp(stderr);
fprintf(stderr,
"InnoDB: Warning: cannot find a free slot for an undo log. Do you have too\n"
-"InnoDB: many active transactions running concurrently?");
+"InnoDB: many active transactions running concurrently?\n");
return(NULL);
}
diff --git a/libmysql/errmsg.c b/libmysql/errmsg.c
index 82040100ded..710bf4ccd8d 100644
--- a/libmysql/errmsg.c
+++ b/libmysql/errmsg.c
@@ -42,7 +42,7 @@ const char *client_errors[]=
"Error in server handshake",
"Lost connection to MySQL server during query",
"Commands out of sync; you can't run this command now",
- "Verbindung ueber Named Pipe; Host: %-.100s",
+ "Verbindung ueber Named Pipe: %-.32s",
"Kann nicht auf Named Pipe warten. Host: %-.64s pipe: %-.32s (%lu)",
"Kann Named Pipe nicht oeffnen. Host: %-.64s pipe: %-.32s (%lu)",
"Kann den Status der Named Pipe nicht setzen. Host: %-.64s pipe: %-.32s (%lu)",
@@ -64,7 +64,7 @@ const char *client_errors[]=
"Invalid parameter number",
"Can't send long data for non-string/non-binary data types (parameter: %d)",
"Using unsupported buffer type: %d (parameter: %d)",
- "Shared memory (%lu)",
+ "Shared memory: %-.100s",
"Can't open shared memory; client could not create request event (%lu)",
"Can't open shared memory; no answer event received from server (%lu)",
"Can't open shared memory; server could not allocate file mapping (%lu)",
@@ -101,7 +101,7 @@ const char *client_errors[]=
"Erro na negociação de acesso ao servidor",
"Conexão perdida com servidor MySQL durante 'query'",
"Comandos fora de sincronismo; você não pode executar este comando agora",
- "%-.100s via 'named pipe'",
+ "Named pipe: %-.32s",
"Não pode esperar pelo 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
"Não pode abrir 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
"Não pode estabelecer o estado do 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
@@ -123,7 +123,7 @@ const char *client_errors[]=
"Invalid parameter number",
"Can't send long data for non-string/non-binary data types (parameter: %d)",
"Using unsupported buffer type: %d (parameter: %d)",
- "Shared memory (%lu)",
+ "Shared memory: %-.100s",
"Can't open shared memory; client could not create request event (%lu)",
"Can't open shared memory; no answer event received from server (%lu)",
"Can't open shared memory; server could not allocate file mapping (%lu)",
@@ -158,7 +158,7 @@ const char *client_errors[]=
"Error in server handshake",
"Lost connection to MySQL server during query",
"Commands out of sync; you can't run this command now",
- "%-.100s via named pipe",
+ "Named pipe: %-.32s",
"Can't wait for named pipe to host: %-.64s pipe: %-.32s (%lu)",
"Can't open named pipe to host: %-.64s pipe: %-.32s (%lu)",
"Can't set state of named pipe to host: %-.64s pipe: %-.32s (%lu)",
@@ -180,7 +180,7 @@ const char *client_errors[]=
"Invalid parameter number",
"Can't send long data for non-string/non-binary data types (parameter: %d)",
"Using unsupported buffer type: %d (parameter: %d)",
- "Shared memory (%lu)",
+ "Shared memory: %-.100s",
"Can't open shared memory; client could not create request event (%lu)",
"Can't open shared memory; no answer event received from server (%lu)",
"Can't open shared memory; server could not allocate file mapping (%lu)",
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 7d71998f37d..f9a6202b761 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -1703,16 +1703,18 @@ static void stmt_update_metadata(MYSQL_STMT *stmt, MYSQL_ROWS *data);
/**************** Misc utility functions ****************************/
/*
- Reallocate the NET package to be at least of 'length' bytes
+ Reallocate the NET package to have at least length bytes available.
SYNPOSIS
- my_realloc_str()
- net The NET structure to modify
- length Ensure that net->buff is at least this big
+ my_realloc_str()
+ net The NET structure to modify.
+ length Ensure that net->buff has space for at least
+ this number of bytes.
RETURN VALUES
- 0 ok
- 1 Error
+ 0 Success.
+ 1 Error, i.e. out of memory or requested packet size is bigger
+ than max_allowed_packet. The error code is stored in net->last_errno.
*/
static my_bool my_realloc_str(NET *net, ulong length)
@@ -2365,7 +2367,7 @@ static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param)
*/
if ((my_realloc_str(net, *param->length)))
{
- set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
+ set_stmt_error(stmt, net->last_errno, unknown_sqlstate);
DBUG_RETURN(1);
}
(*param->store_param_func)(net, param);
@@ -2427,6 +2429,11 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
net_clear(net); /* Sets net->write_pos */
/* Reserve place for null-marker bytes */
null_count= (stmt->param_count+7) /8;
+ if (my_realloc_str(net, null_count + 1))
+ {
+ set_stmt_error(stmt, net->last_errno, unknown_sqlstate);
+ DBUG_RETURN(1);
+ }
bzero((char*) net->write_pos, null_count);
net->write_pos+= null_count;
param_end= stmt->params + stmt->param_count;
@@ -2435,6 +2442,11 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
*(net->write_pos)++= (uchar) stmt->send_types_to_server;
if (stmt->send_types_to_server)
{
+ if (my_realloc_str(net, 2 * stmt->param_count))
+ {
+ set_stmt_error(stmt, net->last_errno, unknown_sqlstate);
+ DBUG_RETURN(1);
+ }
/*
Store types of parameters in first in first package
that is sent to the server.
@@ -3487,10 +3499,11 @@ static void fetch_float_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
char *end;
/* TODO: move this to a header shared between client and server. */
#define NOT_FIXED_DEC 31
- if (field->decimals >= 31)
+ if (field->decimals >= NOT_FIXED_DEC)
#undef NOT_FIXED_DEC
{
- sprintf(buff, "%-*.*g", (int) param->buffer_length, width, value);
+ sprintf(buff, "%-*.*g", (int) min(sizeof(buff)-1, param->buffer_length),
+ width, value);
end= strcend(buff, ' ');
*end= 0;
}
diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result
index 6564a3e392b..ccf75f68e88 100644
--- a/mysql-test/r/cast.result
+++ b/mysql-test/r/cast.result
@@ -155,3 +155,26 @@ NULL
select cast(NULL as BINARY);
cast(NULL as BINARY)
NULL
+CREATE TABLE t1 (a enum ('aac','aab','aaa') not null);
+INSERT INTO t1 VALUES ('aaa'),('aab'),('aac');
+SELECT a, CAST(a AS CHAR) FROM t1 ORDER BY CAST(a AS UNSIGNED) ;
+a CAST(a AS CHAR)
+aac aac
+aab aab
+aaa aaa
+SELECT a, CAST(a AS CHAR(3)) FROM t1 ORDER BY CAST(a AS CHAR(2)), a;
+a CAST(a AS CHAR(3))
+aac aac
+aab aab
+aaa aaa
+SELECT a, CAST(a AS UNSIGNED) FROM t1 ORDER BY CAST(a AS CHAR) ;
+a CAST(a AS UNSIGNED)
+aaa 3
+aab 2
+aac 1
+SELECT a, CAST(a AS CHAR(2)) FROM t1 ORDER BY CAST(a AS CHAR(3)), a;
+a CAST(a AS CHAR(2))
+aaa aa
+aab aa
+aac aa
+DROP TABLE t1;
diff --git a/mysql-test/r/ctype_uca.result b/mysql-test/r/ctype_uca.result
index 94fe15fed26..da4b5bfb663 100644
--- a/mysql-test/r/ctype_uca.result
+++ b/mysql-test/r/ctype_uca.result
@@ -1872,3 +1872,42 @@ Z,z,Ź,ź,Ż,ż,Ž,ž
Ç
Ç‚
ǃ
+drop table t1;
+SET NAMES utf8;
+CREATE TABLE t1 (c varchar(255) NOT NULL COLLATE utf8_general_ci, INDEX (c));
+INSERT INTO t1 VALUES (CONVERT(_ucs2 0x039C03C903B403B11F770308 USING utf8));
+SELECT * FROM t1 WHERE c LIKE CONVERT(_ucs2 0x039C0025 USING utf8)
+COLLATE utf8_general_ci;
+c
+Μωδαί̈
+INSERT INTO t1 VALUES (CONVERT(_ucs2 0x039C03C903B4 USING utf8));
+SELECT * FROM t1 WHERE c LIKE CONVERT(_ucs2 0x039C0025 USING utf8)
+COLLATE utf8_general_ci ORDER BY c;
+c
+Μωδ
+Μωδαί̈
+DROP TABLE t1;
+CREATE TABLE t1 (c varchar(255) NOT NULL COLLATE ucs2_unicode_ci, INDEX (c));
+INSERT INTO t1 VALUES (_ucs2 0x039C03C903B403B11F770308);
+SELECT * FROM t1 WHERE c LIKE _ucs2 0x039C0025 COLLATE ucs2_unicode_ci;
+c
+Μωδαί̈
+INSERT INTO t1 VALUES (_ucs2 0x039C03C903B4);
+SELECT * FROM t1 WHERE c LIKE _ucs2 0x039C0025
+COLLATE ucs2_unicode_ci ORDER BY c;
+c
+Μωδ
+Μωδαί̈
+DROP TABLE t1;
+CREATE TABLE t1 (c varchar(255) NOT NULL COLLATE utf8_unicode_ci, INDEX (c));
+INSERT INTO t1 VALUES (CONVERT(_ucs2 0x039C03C903B403B11F770308 USING utf8));
+SELECT * FROM t1 WHERE c LIKE CONVERT(_ucs2 0x039C0025 USING utf8) COLLATE utf8_unicode_ci;
+c
+Μωδαί̈
+INSERT INTO t1 VALUES (CONVERT(_ucs2 0x039C03C903B4 USING utf8));
+SELECT * FROM t1 WHERE c LIKE CONVERT(_ucs2 0x039C0025 USING utf8)
+COLLATE utf8_unicode_ci ORDER BY c;
+c
+Μωδ
+Μωδαί̈
+DROP TABLE t1;
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index f3be539251a..c7d015da9dc 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -639,3 +639,8 @@ select * from t1 where str='str';
str
str
drop table t1;
+CREATE TABLE t1 (a varchar(32) BINARY) CHARACTER SET utf8;
+INSERT INTO t1 VALUES ('test');
+SELECT a FROM t1 WHERE a LIKE '%te';
+a
+DROP TABLE t1;
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result
index 06259ff4931..011a47874c2 100644
--- a/mysql-test/r/func_group.result
+++ b/mysql-test/r/func_group.result
@@ -684,3 +684,12 @@ max(a)
2
deallocate prepare stmt1;
drop table t1;
+CREATE TABLE t1 (a int primary key);
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+SELECT MAX(a) FROM t1 WHERE a > 5;
+MAX(a)
+NULL
+SELECT MIN(a) FROM t1 WHERE a < 0;
+MIN(a)
+NULL
+DROP TABLE t1;
diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result
index 9af7304c167..022b8eff7e8 100644
--- a/mysql-test/r/group_by.result
+++ b/mysql-test/r/group_by.result
@@ -629,3 +629,12 @@ explain SELECT i, COUNT(DISTINCT(i)) FROM t1 GROUP BY j ORDER BY NULL;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using filesort
DROP TABLE t1;
+create table t1 ( col1 int, col2 int );
+insert into t1 values (1,1),(1,2),(1,3),(2,1),(2,2);
+select group_concat( distinct col1 ) as alias from t1
+group by col2 having alias like '%';
+alias
+1,2
+1,2
+1
+drop table t1;
diff --git a/mysql-test/r/ndb_insert.result b/mysql-test/r/ndb_insert.result
index 93f46c85499..87f27518ea3 100644
--- a/mysql-test/r/ndb_insert.result
+++ b/mysql-test/r/ndb_insert.result
@@ -416,4 +416,16 @@ INSERT INTO t1 VALUES
SELECT COUNT(*) FROM t1;
COUNT(*)
2000
+INSERT INTO t1 VALUES
+(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
+(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
+ERROR 23000: Duplicate entry '10' for key 1
+begin;
+INSERT INTO t1 VALUES
+(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
+(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
+ERROR 23000: Duplicate entry '10' for key 1
+commit;
+insert into t1 select * from t1 where b < 10 order by pk1;
+ERROR 23000: Duplicate entry '9' for key 1
DROP TABLE t1;
diff --git a/mysql-test/r/rpl_set_charset.result b/mysql-test/r/rpl_set_charset.result
new file mode 100644
index 00000000000..480d926fbba
--- /dev/null
+++ b/mysql-test/r/rpl_set_charset.result
@@ -0,0 +1,48 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+drop database if exists mysqltest1;
+create database mysqltest1 /*!40100 character set latin2 */;
+use mysqltest1;
+drop table if exists t1;
+create table t1 (a varchar(255) character set latin2, b varchar(4));
+SET CHARACTER SET cp1250_latin2;
+INSERT INTO t1 VALUES ('ŠŒŽ','80');
+INSERT INTO t1 VALUES ('šœžŸ','90');
+INSERT INTO t1 VALUES ('£¥ª¯','A0');
+INSERT INTO t1 VALUES ('³¹º¼¾¿','B0');
+INSERT INTO t1 VALUES ('ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ','C0');
+INSERT INTO t1 VALUES ('ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß','D0');
+INSERT INTO t1 VALUES ('àáâãäåæçèéêëìíîï','E0');
+INSERT INTO t1 VALUES ('ðñòóôõö÷øùúûüýþÿ','F0');
+select "--- on master ---";
+--- on master ---
+--- on master ---
+select hex(a),b from t1 order by b;
+hex(a) b
+A9A6ABAEAC 80
+B9B6BBBEBC 90
+A3A1AAAF A0
+B3B1BAA5B5BF B0
+C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF C0
+D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF D0
+E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF E0
+F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF F0
+use mysqltest1;
+select "--- on slave ---";
+--- on slave ---
+--- on slave ---
+select hex(a),b from t1 order by b;
+hex(a) b
+A9A6ABAEAC 80
+B9B6BBBEBC 90
+A3A1AAAF A0
+B3B1BAA5B5BF B0
+C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF C0
+D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF D0
+E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF E0
+F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF F0
+drop database mysqltest1;
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 8da1660a109..f0618c0f153 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -2348,3 +2348,19 @@ select * from t2,t3 where t2.s = t3.s;
s s
two two
drop table t1, t2, t3;
+CREATE TABLE t1 (
+i int(11) NOT NULL default '0',
+c char(10) NOT NULL default '',
+PRIMARY KEY (i),
+UNIQUE KEY c (c)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,'a');
+INSERT INTO t1 VALUES (2,'b');
+INSERT INTO t1 VALUES (3,'c');
+EXPLAIN SELECT i FROM t1 WHERE i=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
+EXPLAIN SELECT i FROM t1 WHERE i=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
+DROP TABLE t1;
diff --git a/mysql-test/r/subselect_innodb.result b/mysql-test/r/subselect_innodb.result
index bbbc607b6f8..e8f6426f51b 100644
--- a/mysql-test/r/subselect_innodb.result
+++ b/mysql-test/r/subselect_innodb.result
@@ -106,3 +106,11 @@ a b
2 12
4 105
drop table t1, t2;
+CREATE TABLE `t1` ( `unit` varchar(50) NOT NULL default '', `ingredient` varchar(50) NOT NULL default '') ENGINE=InnoDB DEFAULT CHARSET=latin1;
+CREATE TABLE `t2` ( `ingredient` varchar(50) NOT NULL default '', `unit` varchar(50) NOT NULL default '', PRIMARY KEY (ingredient, unit)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES ('xx','yy');
+INSERT INTO `t2` VALUES ('yy','xx');
+SELECT R.unit, R.ingredient FROM t1 R WHERE R.ingredient IN (SELECT N.ingredient FROM t2 N WHERE N.unit = R.unit);
+unit ingredient
+xx yy
+drop table t1, t2;
diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result
index 843bdc2bdc5..75f0298797a 100644
--- a/mysql-test/r/type_float.result
+++ b/mysql-test/r/type_float.result
@@ -137,6 +137,8 @@ t1 CREATE TABLE `t1` (
drop table t1;
create table t1 (c20 char);
insert into t1 values (5000.0);
+Warnings:
+Warning 1265 Data truncated for column 'c20' at row 1
drop table t1;
create table t1 (f float(54));
ERROR 42000: Incorrect column specifier for column 'f'
diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test
index e2deb792d47..e5681dedbac 100644
--- a/mysql-test/t/cast.test
+++ b/mysql-test/t/cast.test
@@ -95,3 +95,16 @@ select cast("2001-1-1" as datetime) = "2001-01-01 00:00:00";
select cast("1:2:3" as TIME) = "1:02:03";
select cast(NULL as DATE);
select cast(NULL as BINARY);
+
+#
+# Bug #5228 ORDER BY CAST(enumcol) sorts incorrectly under certain conditions
+#
+CREATE TABLE t1 (a enum ('aac','aab','aaa') not null);
+INSERT INTO t1 VALUES ('aaa'),('aab'),('aac');
+# these two should be in enum order
+SELECT a, CAST(a AS CHAR) FROM t1 ORDER BY CAST(a AS UNSIGNED) ;
+SELECT a, CAST(a AS CHAR(3)) FROM t1 ORDER BY CAST(a AS CHAR(2)), a;
+# these two should be in alphabetic order
+SELECT a, CAST(a AS UNSIGNED) FROM t1 ORDER BY CAST(a AS CHAR) ;
+SELECT a, CAST(a AS CHAR(2)) FROM t1 ORDER BY CAST(a AS CHAR(3)), a;
+DROP TABLE t1;
diff --git a/mysql-test/t/ctype_uca.test b/mysql-test/t/ctype_uca.test
index 187d21f9ab7..d9181b19992 100644
--- a/mysql-test/t/ctype_uca.test
+++ b/mysql-test/t/ctype_uca.test
@@ -180,3 +180,40 @@ select group_concat(c1 order by c1) from t1 group by c1 collate utf8_slovak_ci;
select group_concat(c1 order by c1) from t1 group by c1 collate utf8_spanish2_ci;
select group_concat(c1 order by c1) from t1 group by c1 collate utf8_roman_ci;
+drop table t1;
+
+#
+# Bug#5324
+#
+SET NAMES utf8;
+#test1
+CREATE TABLE t1 (c varchar(255) NOT NULL COLLATE utf8_general_ci, INDEX (c));
+INSERT INTO t1 VALUES (CONVERT(_ucs2 0x039C03C903B403B11F770308 USING utf8));
+#Check one row
+SELECT * FROM t1 WHERE c LIKE CONVERT(_ucs2 0x039C0025 USING utf8)
+COLLATE utf8_general_ci;
+INSERT INTO t1 VALUES (CONVERT(_ucs2 0x039C03C903B4 USING utf8));
+#Check two rows
+SELECT * FROM t1 WHERE c LIKE CONVERT(_ucs2 0x039C0025 USING utf8)
+COLLATE utf8_general_ci ORDER BY c;
+DROP TABLE t1;
+#test2
+CREATE TABLE t1 (c varchar(255) NOT NULL COLLATE ucs2_unicode_ci, INDEX (c));
+INSERT INTO t1 VALUES (_ucs2 0x039C03C903B403B11F770308);
+#Check one row
+SELECT * FROM t1 WHERE c LIKE _ucs2 0x039C0025 COLLATE ucs2_unicode_ci;
+INSERT INTO t1 VALUES (_ucs2 0x039C03C903B4);
+#Check two rows
+SELECT * FROM t1 WHERE c LIKE _ucs2 0x039C0025
+COLLATE ucs2_unicode_ci ORDER BY c;
+DROP TABLE t1;
+#test 3
+CREATE TABLE t1 (c varchar(255) NOT NULL COLLATE utf8_unicode_ci, INDEX (c));
+INSERT INTO t1 VALUES (CONVERT(_ucs2 0x039C03C903B403B11F770308 USING utf8));
+#Check one row row
+SELECT * FROM t1 WHERE c LIKE CONVERT(_ucs2 0x039C0025 USING utf8) COLLATE utf8_unicode_ci;
+INSERT INTO t1 VALUES (CONVERT(_ucs2 0x039C03C903B4 USING utf8));
+#Check two rows
+SELECT * FROM t1 WHERE c LIKE CONVERT(_ucs2 0x039C0025 USING utf8)
+COLLATE utf8_unicode_ci ORDER BY c;
+DROP TABLE t1;
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 2c531d4e5d2..f5bd9ede673 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -492,3 +492,10 @@ INSERT INTO t1 VALUES ('str2');
select * from t1 where str='str';
drop table t1;
+#
+# Bug #5397: Crash with varchar binary and LIKE
+#
+CREATE TABLE t1 (a varchar(32) BINARY) CHARACTER SET utf8;
+INSERT INTO t1 VALUES ('test');
+SELECT a FROM t1 WHERE a LIKE '%te';
+DROP TABLE t1;
diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test
index 74f4c1bad44..7f48f2b92bd 100644
--- a/mysql-test/t/func_group.test
+++ b/mysql-test/t/func_group.test
@@ -418,3 +418,19 @@ execute stmt1;
execute stmt1;
deallocate prepare stmt1;
drop table t1;
+
+#
+# Bug #5406 min/max optimization for empty set
+#
+
+CREATE TABLE t1 (a int primary key);
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+
+SELECT MAX(a) FROM t1 WHERE a > 5;
+SELECT MIN(a) FROM t1 WHERE a < 0;
+
+DROP TABLE t1;
+
+
+
+
diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test
index d6d1922c10f..59983594c32 100644
--- a/mysql-test/t/group_by.test
+++ b/mysql-test/t/group_by.test
@@ -456,3 +456,12 @@ INSERT INTO t1 VALUES (1,2),(2,3),(4,5),(3,5),(1,5),(23,5);
SELECT i, COUNT(DISTINCT(i)) FROM t1 GROUP BY j ORDER BY NULL;
explain SELECT i, COUNT(DISTINCT(i)) FROM t1 GROUP BY j ORDER BY NULL;
DROP TABLE t1;
+
+# Test for BUG#5400: GROUP_CONCAT returns everything twice.
+create table t1 ( col1 int, col2 int );
+insert into t1 values (1,1),(1,2),(1,3),(2,1),(2,2);
+select group_concat( distinct col1 ) as alias from t1
+ group by col2 having alias like '%';
+
+drop table t1;
+
diff --git a/mysql-test/t/ndb_insert.test b/mysql-test/t/ndb_insert.test
index c55a925dca2..a448e413f1d 100644
--- a/mysql-test/t/ndb_insert.test
+++ b/mysql-test/t/ndb_insert.test
@@ -429,5 +429,34 @@ INSERT INTO t1 VALUES
SELECT COUNT(*) FROM t1;
+#
+# Insert duplicate rows
+#
+--error 1062
+INSERT INTO t1 VALUES
+(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
+(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
+
+
+
+begin;
+
+#
+# Insert duplicate rows, inside transaction
+#
+--error 1062
+INSERT INTO t1 VALUES
+(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
+(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
+
+commit;
+
+#
+# Insert duplicate rows using "insert .. select"
+
+#
+--error 1062
+insert into t1 select * from t1 where b < 10 order by pk1;
+
DROP TABLE t1;
diff --git a/mysql-test/t/rpl_set_charset.test b/mysql-test/t/rpl_set_charset.test
new file mode 100644
index 00000000000..269074b1c42
--- /dev/null
+++ b/mysql-test/t/rpl_set_charset.test
@@ -0,0 +1,33 @@
+source include/master-slave.inc;
+--disable_warnings
+drop database if exists mysqltest1;
+# 4.1 bases its conversion on the db's charset,
+# while 4.0 uses the part of "SET CHARACTER SET" after "_".
+# So for 4.1 we add a clause to CREATE DATABASE.
+create database mysqltest1 /*!40100 character set latin2 */;
+use mysqltest1;
+drop table if exists t1;
+--enable_warnings
+create table t1 (a varchar(255) character set latin2, b varchar(4));
+SET CHARACTER SET cp1250_latin2;
+INSERT INTO t1 VALUES ('ŠŒŽ','80');
+INSERT INTO t1 VALUES ('šœžŸ','90');
+INSERT INTO t1 VALUES ('£¥ª¯','A0');
+INSERT INTO t1 VALUES ('³¹º¼¾¿','B0');
+INSERT INTO t1 VALUES ('ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ','C0');
+INSERT INTO t1 VALUES ('ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß','D0');
+INSERT INTO t1 VALUES ('àáâãäåæçèéêëìíîï','E0');
+INSERT INTO t1 VALUES ('ðñòóôõö÷øùúûüýþÿ','F0');
+select "--- on master ---";
+select hex(a),b from t1 order by b;
+save_master_pos;
+connection slave;
+sync_with_master;
+use mysqltest1;
+select "--- on slave ---";
+select hex(a),b from t1 order by b;
+connection master;
+drop database mysqltest1;
+save_master_pos;
+connection slave;
+sync_with_master;
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index 57827f3cc7f..4490f97765b 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -1880,3 +1880,24 @@ select * from t3 where s = 'one';
select * from t1,t2 where t1.s = t2.s;
select * from t2,t3 where t2.s = t3.s;
drop table t1, t2, t3;
+
+#
+# Covering index is mentioned in EXPLAIN output for const tables (bug #5333)
+#
+
+CREATE TABLE t1 (
+ i int(11) NOT NULL default '0',
+ c char(10) NOT NULL default '',
+ PRIMARY KEY (i),
+ UNIQUE KEY c (c)
+) ENGINE=MyISAM;
+
+INSERT INTO t1 VALUES (1,'a');
+INSERT INTO t1 VALUES (2,'b');
+INSERT INTO t1 VALUES (3,'c');
+
+EXPLAIN SELECT i FROM t1 WHERE i=1;
+
+EXPLAIN SELECT i FROM t1 WHERE i=1;
+
+DROP TABLE t1;
diff --git a/mysql-test/t/subselect_innodb.test b/mysql-test/t/subselect_innodb.test
index 8c13171d221..5f4badb3624 100644
--- a/mysql-test/t/subselect_innodb.test
+++ b/mysql-test/t/subselect_innodb.test
@@ -111,3 +111,17 @@ create table t2 (a int) engine=innodb;
insert into t2 values (1),(2),(3),(4);
select a, sum(b) as b from t1 group by a having b > (select max(a) from t2);
drop table t1, t2;
+
+#
+# bug #5220 test suite
+#
+CREATE TABLE `t1` ( `unit` varchar(50) NOT NULL default '', `ingredient` varchar(50) NOT NULL default '') ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE `t2` ( `ingredient` varchar(50) NOT NULL default '', `unit` varchar(50) NOT NULL default '', PRIMARY KEY (ingredient, unit)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+INSERT INTO `t1` VALUES ('xx','yy');
+INSERT INTO `t2` VALUES ('yy','xx');
+
+SELECT R.unit, R.ingredient FROM t1 R WHERE R.ingredient IN (SELECT N.ingredient FROM t2 N WHERE N.unit = R.unit);
+
+drop table t1, t2;
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
index 8ad2ee1df4d..b9e7ce21f79 100644
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -322,36 +322,26 @@ do
# but should work for the rest of the servers.
# The only thing is ps x => redhat 5 gives warnings when using ps -x.
# kill -9 is used or the process won't react on the kill.
- if test -n "$mysql_tcp_port"
- then
- numofproces=`ps xa | grep -v "grep" | grep $ledir/$MYSQLD| grep -c "port=$mysql_tcp_port"`
- else
- numofproces=`ps xa | grep -v "grep" | grep -c $ledir/$MYSQLD`
- fi
+ numofproces=`ps xa | grep -v "grep" | grep "$ledir/$MYSQLD\>" | grep -c "pid-file=$pid_file"`
echo -e "\nNumber of processes running now: $numofproces" | tee -a $err_log
I=1
while test "$I" -le "$numofproces"
do
- if test -n "$mysql_tcp_port"
+ PROC=`ps xa | grep "$ledir/$MYSQLD\>" | grep -v "grep" | grep "pid-file=$pid_file" | sed -n '$p'`
+
+ for T in $PROC
+ do
+ break
+ done
+ # echo "TEST $I - $T **"
+ if kill -9 $T
then
- PROC=`ps xa | grep "$ledir/$MYSQLD\>" | grep -v "grep" | grep "port=$mysql_tcp_port" | sed -n '$p'`
- else
- PROC=`ps xa | grep "$ledir/$MYSQLD\>" | grep -v "grep" | sed -n '$p'`
+ echo "$MYSQLD process hanging, pid $T - killed" | tee -a $err_log
+ else
+ break
fi
-
- for T in $PROC
- do
- break
- done
- # echo "TEST $I - $T **"
- if kill -9 $T
- then
- echo "$MYSQLD process hanging, pid $T - killed" | tee -a $err_log
- else
- break
- fi
- I=`expr $I + 1`
+ I=`expr $I + 1`
done
fi
echo "`date +'%y%m%d %H:%M:%S'` mysqld restarted" | tee -a $err_log
@@ -359,3 +349,4 @@ done
echo "`date +'%y%m%d %H:%M:%S'` mysqld ended" | tee -a $err_log
echo "" | tee -a $err_log
+
diff --git a/sql-common/client.c b/sql-common/client.c
index 04d4bc06102..930388d2459 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1401,6 +1401,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;
+ strmov(mysql->net.sqlstate, not_error_sqlstate);
/*
By default, we are a replication pivot. The caller must reset it
after we return if this is not the case.
@@ -1614,7 +1615,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
sock=0;
unix_socket = 0;
host=mysql->options.shared_memory_base_name;
- host_info=(char*) ER(CR_SHARED_MEMORY_CONNECTION);
+ sprintf(host_info=buff, ER(CR_SHARED_MEMORY_CONNECTION), host);
}
}
#endif /* HAVE_SMEM */
@@ -1678,8 +1679,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
else
{
net->vio=vio_new_win32pipe(hPipe);
- sprintf(host_info=buff, ER(CR_NAMEDPIPE_CONNECTION), host,
- unix_socket);
+ sprintf(host_info=buff, ER(CR_NAMEDPIPE_CONNECTION), unix_socket);
}
}
#endif
diff --git a/sql/field.cc b/sql/field.cc
index 5356fbc773a..8a1c5ec5271 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4297,7 +4297,7 @@ if (field_length < 32 && fabs(nr) < log_10[field_length]-1)
like inserting 500.0 in char(1)
*/
DBUG_ASSERT(field_length < 5 || length <= field_length+1);
- return store((const char *)buff, min(length, field_length), charset());
+ return store((const char *) buff, length, charset());
}
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 3d2d25b3e7d..95a294764d3 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -509,16 +509,16 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
(uint) (T_RETRY_WITHOUT_QUICK | T_QUICK)))
{
param.testflag&= ~T_RETRY_WITHOUT_QUICK;
- sql_print_error("Note: Retrying repair of: '%s' without quick",
- table->path);
+ sql_print_information("Retrying repair of: '%s' without quick",
+ table->path);
continue;
}
param.testflag&= ~T_QUICK;
if ((param.testflag & T_REP_BY_SORT))
{
param.testflag= (param.testflag & ~T_REP_BY_SORT) | T_REP;
- sql_print_error("Note: Retrying repair of: '%s' with keycache",
- table->path);
+ sql_print_information("Retrying repair of: '%s' with keycache",
+ table->path);
continue;
}
break;
@@ -527,10 +527,10 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
!(check_opt->flags & T_VERY_SILENT))
{
char llbuff[22],llbuff2[22];
- sql_print_error("Note: Found %s of %s rows when repairing '%s'",
- llstr(file->state->records, llbuff),
- llstr(start_records, llbuff2),
- table->path);
+ sql_print_information("Found %s of %s rows when repairing '%s'",
+ llstr(file->state->records, llbuff),
+ llstr(start_records, llbuff2),
+ table->path);
}
return error;
}
@@ -1034,7 +1034,7 @@ bool ha_myisam::check_and_repair(THD *thd)
// Don't use quick if deleted rows
if (!file->state->del && (myisam_recover_options & HA_RECOVER_QUICK))
check_opt.flags|=T_QUICK;
- sql_print_error("Warning: Checking table: '%s'",table->path);
+ sql_print_warning("Checking table: '%s'",table->path);
old_query= thd->query;
old_query_length= thd->query_length;
@@ -1045,7 +1045,7 @@ bool ha_myisam::check_and_repair(THD *thd)
if ((marked_crashed= mi_is_crashed(file)) || check(thd, &check_opt))
{
- sql_print_error("Warning: Recovering table: '%s'",table->path);
+ sql_print_warning("Recovering table: '%s'",table->path);
check_opt.flags=
((myisam_recover_options & HA_RECOVER_BACKUP ? T_BACKUP_DATA : 0) |
(marked_crashed ? 0 : T_QUICK) |
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 08c82e12b29..d35f84a8fc8 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -1132,12 +1132,12 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op,
const char* bounds[]= {"LE", "LT", "GE", "GT", "EQ"};
DBUG_ASSERT(bound >= 0 && bound <= 4);
- DBUG_PRINT("info", ("Set Bound%s on %s %s %s %s",
+ DBUG_PRINT("info", ("Set Bound%s on %s %s %s",
bounds[bound],
field->field_name,
key_nullable ? "NULLABLE" : "",
key_null ? "NULL":""));
- DBUG_PRINT("info", ("Total length %ds", tot_len));
+ DBUG_PRINT("info", ("Total length %d", tot_len));
DBUG_DUMP("key", (char*) key_ptr, key_store_len);
@@ -1164,6 +1164,44 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op,
DBUG_RETURN(0);
}
+#ifndef DBUG_OFF
+
+const char* key_flag_strs[] =
+{ "HA_READ_KEY_EXACT",
+ "HA_READ_KEY_OR_NEXT",
+ "HA_READ_KEY_OR_PREV",
+ "HA_READ_AFTER_KEY",
+ "HA_READ_BEFORE_KEY",
+ "HA_READ_PREFIX",
+ "HA_READ_PREFIX_LAST",
+ "HA_READ_PREFIX_LAST_OR_PREV",
+ "HA_READ_MBR_CONTAIN",
+ "HA_READ_MBR_INTERSECT",
+ "HA_READ_MBR_WITHIN",
+ "HA_READ_MBR_DISJOINT",
+ "HA_READ_MBR_EQUAL"
+};
+
+const int no_of_key_flags = sizeof(key_flag_strs)/sizeof(char*);
+
+void print_key(const key_range* key, const char* info)
+{
+ if (key)
+ {
+ const char* str= key->flag < no_of_key_flags ?
+ key_flag_strs[key->flag] : "Unknown flag";
+
+ DBUG_LOCK_FILE;
+ fprintf(DBUG_FILE,"%s: %s, length=%d, key=", info, str, key->length);
+ uint i;
+ for (i=0; i<key->length-1; i++)
+ fprintf(DBUG_FILE,"%0d ", key->key[i]);
+ fprintf(DBUG_FILE, "\n");
+ DBUG_UNLOCK_FILE;
+ }
+ return;
+}
+#endif
/*
Start ordered index scan in NDB
@@ -1181,6 +1219,9 @@ int ha_ndbcluster::ordered_index_scan(const key_range *start_key,
DBUG_ENTER("ordered_index_scan");
DBUG_PRINT("enter", ("index: %u, sorted: %d", active_index, sorted));
DBUG_PRINT("enter", ("Starting new ordered scan on %s", m_tabname));
+
+ DBUG_EXECUTE("enter", print_key(start_key, "start_key"););
+ DBUG_EXECUTE("enter", print_key(end_key, "end_key"););
index_name= get_index_name(active_index);
if (!(op= trans->getNdbIndexScanOperation((NDBINDEX *)
@@ -2406,7 +2447,7 @@ int ha_ndbcluster::end_bulk_insert()
rows_inserted, bulk_insert_rows));
bulk_insert_not_flushed= false;
if (trans->execute(NoCommit) != 0)
- error= ndb_err(trans);
+ my_errno= error= ndb_err(trans);
}
rows_inserted= 0;
diff --git a/sql/handler.cc b/sql/handler.cc
index 4d3bf06d5f4..c7c480a80fa 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -558,7 +558,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
query_cache.invalidate(thd->transaction.changed_tables);
#endif /*HAVE_QUERY_CACHE*/
if (error && trans == &thd->transaction.all && mysql_bin_log.is_open())
- sql_print_error("Error: Got error during commit; Binlog is not up to date!");
+ sql_print_error("Got error during commit; Binlog is not up to date!");
thd->variables.tx_isolation=thd->session_tx_isolation;
if (operation_done)
{
diff --git a/sql/item_func.h b/sql/item_func.h
index d45f7244e55..836ed27ee46 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -214,6 +214,7 @@ class Item_func_signed :public Item_int_func
{
public:
Item_func_signed(Item *a) :Item_int_func(a) {}
+ const char *func_name() const { return "cast_as_signed"; }
double val()
{
double tmp= args[0]->val();
@@ -236,6 +237,7 @@ class Item_func_unsigned :public Item_func_signed
{
public:
Item_func_unsigned(Item *a) :Item_func_signed(a) {}
+ const char *func_name() const { return "cast_as_unsigned"; }
void fix_length_and_dec()
{ max_length=args[0]->max_length; unsigned_flag=1; }
void print(String *str);
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 79c1be57625..290e10bd59a 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -2121,6 +2121,8 @@ String* Item_func_group_concat::val_str(String* str)
DBUG_ASSERT(fixed == 1);
if (null_value)
return 0;
+ if (result.length())
+ return &result;
if (tree_mode)
{
tree_walk(tree, (tree_walk_action)&dump_leaf_key, (void*)this,
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 5d9a6dd9490..8f09fe82c1b 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -2059,6 +2059,24 @@ bool Item_extract::eq(const Item *item, bool binary_cmp) const
}
+bool Item_char_typecast::eq(const Item *item, bool binary_cmp) const
+{
+ if (this == item)
+ return 1;
+ if (item->type() != FUNC_ITEM ||
+ func_name() != ((Item_func*)item)->func_name())
+ return 0;
+
+ Item_char_typecast *cast= (Item_char_typecast*)item;
+ if (cast_length != cast->cast_length ||
+ cast_cs != cast->cast_cs)
+ return 0;
+
+ if (!args[0]->eq(cast->args[0], binary_cmp))
+ return 0;
+ return 1;
+}
+
void Item_typecast::print(String *str)
{
str->append("cast(", 5);
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 2254fc830c9..df0b05d6d42 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -683,6 +683,8 @@ class Item_char_typecast :public Item_typecast
public:
Item_char_typecast(Item *a, int length_arg, CHARSET_INFO *cs_arg)
:Item_typecast(a), cast_length(length_arg), cast_cs(cs_arg) {}
+ bool eq(const Item *item, bool binary_cmp) const;
+ const char *func_name() const { return "cast_as_char"; }
const char* cast_type() const { return "char"; };
String *val_str(String *a);
void fix_length_and_dec();
@@ -694,6 +696,7 @@ class Item_date_typecast :public Item_typecast_maybe_null
{
public:
Item_date_typecast(Item *a) :Item_typecast_maybe_null(a) {}
+ const char *func_name() const { return "cast_as_date"; }
String *val_str(String *str);
bool get_date(TIME *ltime, uint fuzzy_date);
const char *cast_type() const { return "date"; }
@@ -709,6 +712,7 @@ class Item_time_typecast :public Item_typecast_maybe_null
{
public:
Item_time_typecast(Item *a) :Item_typecast_maybe_null(a) {}
+ const char *func_name() const { return "cast_as_time"; }
String *val_str(String *str);
bool get_time(TIME *ltime);
const char *cast_type() const { return "time"; }
@@ -724,6 +728,7 @@ class Item_datetime_typecast :public Item_typecast_maybe_null
{
public:
Item_datetime_typecast(Item *a) :Item_typecast_maybe_null(a) {}
+ const char *func_name() const { return "cast_as_datetime"; }
String *val_str(String *str);
const char *cast_type() const { return "datetime"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
diff --git a/sql/log.cc b/sql/log.cc
index 08c1b31ed0d..79934451b09 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1426,15 +1426,6 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u",
if (e.write(file))
goto err;
}
-#if MYSQL_VERSION_ID < 40100
- if (thd->variables.convert_set)
- {
- Query_log_event e(thd, "SET CHARACTER SET DEFAULT", 25, 0);
- e.set_log_pos(this);
- if (e.write(file))
- goto err;
- }
-#endif
}
/*
@@ -1932,19 +1923,6 @@ void MYSQL_LOG::set_max_size(ulong max_size_arg)
}
-Disable_binlog::Disable_binlog(THD *thd_arg) :
- thd(thd_arg), save_options(thd_arg->options)
-{
- thd_arg->options&= ~OPTION_BIN_LOG;
-}
-
-
-Disable_binlog::~Disable_binlog()
-{
- thd->options= save_options;
-}
-
-
/*
Check if a string is a valid number
@@ -2009,14 +1987,14 @@ void print_buffer_to_file(enum loglevel level, const char *buffer)
localtime_r(&skr, &tm_tmp);
start=&tm_tmp;
fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %s\n",
- start->tm_year % 100,
- start->tm_mon+1,
- start->tm_mday,
- start->tm_hour,
- start->tm_min,
- start->tm_sec,
+ start->tm_year % 100,
+ start->tm_mon+1,
+ start->tm_mday,
+ start->tm_hour,
+ start->tm_min,
+ start->tm_sec,
(level == ERROR_LEVEL ? "ERROR" : level == WARNING_LEVEL ?
- "WARNING" : "INFORMATION"),
+ "WARNING" : "NOTE"),
buffer);
fflush(stderr);
diff --git a/sql/log_event.cc b/sql/log_event.cc
index ef77aa6603b..1f30e932c01 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -977,7 +977,7 @@ void Query_log_event::print(FILE* file, bool short_form, char* last_db)
int Query_log_event::exec_event(struct st_relay_log_info* rli)
{
int expected_error,actual_error= 0;
- thd->db= (char*) rewrite_db(db);
+ thd->db= (char*) rewrite_db(db); // thd->db_length is set later if needed
/*
InnoDB internally stores the master log position it has processed so far;
@@ -995,6 +995,11 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
if (db_ok(thd->db, replicate_do_db, replicate_ignore_db))
{
thd->set_time((time_t)when);
+ /*
+ We cannot use db_len from event to fill thd->db_length, because
+ rewrite_db() may have changed db.
+ */
+ thd->db_length= thd->db ? strlen(thd->db) : 0;
thd->query_length= q_len;
thd->query = (char*)query;
VOID(pthread_mutex_lock(&LOCK_thread_count));
@@ -1082,7 +1087,7 @@ end:
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->db= 0; // prevent db from being freed
thd->query= 0; // just to be sure
- thd->query_length= 0;
+ thd->query_length= thd->db_length =0;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
close_thread_tables(thd);
free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
@@ -1693,7 +1698,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
bool use_rli_only_for_errors)
{
char *load_data_query= 0;
- thd->db= (char*) rewrite_db(db);
+ thd->db= (char*) rewrite_db(db); // thd->db_length is set later if needed
DBUG_ASSERT(thd->query == 0);
thd->query_length= 0; // Should not be needed
thd->query_error= 0;
@@ -1728,6 +1733,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
if (db_ok(thd->db, replicate_do_db, replicate_ignore_db))
{
thd->set_time((time_t)when);
+ thd->db_length= thd->db ? strlen(thd->db) : 0;
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id = query_id++;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
@@ -1854,7 +1860,7 @@ Slave: load data infile on table '%s' at log position %s in log \
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->db= 0;
thd->query= 0;
- thd->query_length= 0;
+ thd->query_length= thd->db_length= 0;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
close_thread_tables(thd);
if (load_data_query)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 90b6d6319bf..c59f1ddcad6 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -327,6 +327,7 @@ const char *opt_date_time_formats[3];
char *language_ptr, *default_collation_name, *default_character_set_name;
char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
+struct passwd *user_info;
char server_version[SERVER_VERSION_LENGTH];
char *mysqld_unix_port, *opt_mysql_tmpdir;
char *my_bind_addr_str;
@@ -1047,65 +1048,72 @@ static void set_ports()
#ifndef EMBEDDED_LIBRARY
/* Change to run as another user if started with --user */
-static void set_user(const char *user)
+static struct passwd *check_user(const char *user)
{
#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
- struct passwd *ent;
+ struct passwd *user_info;
uid_t user_id= geteuid();
- // don't bother if we aren't superuser
+ // Don't bother if we aren't superuser
if (user_id)
{
if (user)
{
- /* Don't give a warning, if real user is same as given with --user */
- struct passwd *user_info= getpwnam(user);
+ // Don't give a warning, if real user is same as given with --user
+ user_info= getpwnam(user);
if ((!user_info || user_id != user_info->pw_uid) &&
global_system_variables.log_warnings)
sql_print_warning(
"One can only use the --user switch if running as root\n");
}
- return;
+ return NULL;
}
if (!user)
{
if (!opt_bootstrap)
{
- fprintf(stderr,"Fatal error: Please read \"Security\" section of the manual to find out how to run mysqld as root!\n");
+ sql_print_error("Fatal error: Please read \"Security\" section of the manual to find out how to run mysqld as root!\n");
unireg_abort(1);
}
- return;
+ return NULL;
}
if (!strcmp(user,"root"))
- return; // Avoid problem with dynamic libraries
+ return NULL; // Avoid problem with dynamic libraries
- uid_t uid;
- if (!(ent = getpwnam(user)))
+ if (!(user_info= getpwnam(user)))
{
- // allow a numeric uid to be used
+ // Allow a numeric uid to be used
const char *pos;
- for (pos=user; my_isdigit(mysqld_charset,*pos); pos++) ;
- if (*pos) // Not numeric id
- {
- fprintf(stderr,"Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user);
- unireg_abort(1);
- }
- uid=atoi(user); // Use numberic uid
+ for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ;
+ if (*pos) // Not numeric id
+ goto err;
+ if (!(user_info= getpwuid(atoi(user))))
+ goto err;
+ else
+ return user_info;
}
else
- {
+ return user_info;
+
+err:
+ sql_print_error("Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user);
+#endif
+ return NULL;
+}
+
+static void set_user(const char *user, struct passwd *user_info)
+{
+#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
+ DBUG_ASSERT(user_info);
#ifdef HAVE_INITGROUPS
- initgroups((char*) user,ent->pw_gid);
+ initgroups((char*) user,user_info->pw_gid);
#endif
- if (setgid(ent->pw_gid) == -1)
- {
- sql_perror("setgid");
- unireg_abort(1);
- }
- uid=ent->pw_uid;
+ if (setgid(user_info->pw_gid) == -1)
+ {
+ sql_perror("setgid");
+ unireg_abort(1);
}
-
- if (setuid(uid) == -1)
+ if (setuid(user_info->pw_uid) == -1)
{
sql_perror("setuid");
unireg_abort(1);
@@ -1113,6 +1121,25 @@ static void set_user(const char *user)
#endif
}
+
+static void set_effective_user(struct passwd *user_info)
+{
+#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
+ DBUG_ASSERT(user_info);
+ if (setegid(user_info->pw_gid) == -1)
+ {
+ sql_perror("setegid");
+ unireg_abort(1);
+ }
+ if (seteuid(user_info->pw_uid) == -1)
+ {
+ sql_perror("seteuid");
+ unireg_abort(1);
+ }
+#endif
+}
+
+
/* Change root user if started with --chroot */
static void set_root(const char *path)
@@ -1188,7 +1215,16 @@ static void server_init(void)
unireg_abort(1);
}
}
- set_user(mysqld_user); // Works also with mysqld_user==NULL
+
+ if ((user_info= check_user(mysqld_user)))
+ {
+#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
+ if (locked_in_memory) // getuid() == 0 here
+ set_effective_user(user_info);
+ else
+#endif
+ set_user(mysqld_user, user_info);
+ }
#ifdef __NT__
/* create named pipe */
@@ -2618,19 +2654,26 @@ server.");
/* We must set dflt_key_cache in case we are using ISAM tables */
dflt_key_cache= sql_key_cache;
-#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
- if (locked_in_memory && !geteuid())
+#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && !defined(EMBEDDED_LIBRARY)
+ if (locked_in_memory && !getuid())
{
+ if (seteuid(0) == -1)
+ { // this should never happen
+ sql_perror("seteuid");
+ unireg_abort(1);
+ }
if (mlockall(MCL_CURRENT))
{
if (global_system_variables.log_warnings)
sql_print_warning("Failed to lock memory. Errno: %d\n",errno);
locked_in_memory= 0;
}
+ if (user_info)
+ set_user(mysqld_user, user_info);
}
-#else
- locked_in_memory=0;
+ else
#endif
+ locked_in_memory=0;
ft_init_stopwords();
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index c2da47b480e..457b2052a45 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -193,9 +193,7 @@ my_bool net_realloc(NET *net, ulong length)
{
net->error= 1;
net->report_error= 1;
-#ifdef MYSQL_SERVER
net->last_errno= ER_OUT_OF_RESOURCES;
-#endif
DBUG_RETURN(1);
}
net->buff=net->write_pos=buff;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index f11ed31950a..27e8e9c11e7 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -2193,7 +2193,7 @@ void SEL_ARG::test_use_count(SEL_ARG *root)
uint e_count=0;
if (this == root && use_count != 1)
{
- sql_print_error("Note: Use_count: Wrong count %lu for root",use_count);
+ sql_print_information("Use_count: Wrong count %lu for root",use_count);
return;
}
if (this->type != SEL_ARG::KEY_RANGE)
@@ -2206,7 +2206,7 @@ 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_error("Note: Use_count: Wrong count for key at %lx, %lu should be %lu",
+ sql_print_information("Use_count: Wrong count for key at %lx, %lu should be %lu",
pos,pos->next_key_part->use_count,count);
return;
}
@@ -2214,7 +2214,7 @@ void SEL_ARG::test_use_count(SEL_ARG *root)
}
}
if (e_count != elements)
- sql_print_error("Warning: Wrong use count: %u (should be %u) for tree at %lx",
+ sql_print_warning("Wrong use count: %u (should be %u) for tree at %lx",
e_count, elements, (gptr) this);
}
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index f4c39462d0c..538f5c6097d 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -186,16 +186,15 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
if (!ref.key_length)
error= table->file->index_first(table->record[0]);
else
- {
error= table->file->index_read(table->record[0],key_buff,
ref.key_length,
range_fl & NEAR_MIN ?
HA_READ_AFTER_KEY :
HA_READ_KEY_OR_NEXT);
- if (!error && reckey_in_range(0, &ref, item_field->field,
- conds, range_fl, prefix_len))
- error= HA_ERR_KEY_NOT_FOUND;
- }
+ if ((!error || error == HA_ERR_KEY_NOT_FOUND) &&
+ reckey_in_range(0, &ref, item_field->field,
+ conds, range_fl, prefix_len))
+ error= HA_ERR_KEY_NOT_FOUND;
if (table->key_read)
{
table->key_read= 0;
@@ -260,16 +259,15 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
if (!ref.key_length)
error= table->file->index_last(table->record[0]);
else
- {
error= table->file->index_read(table->record[0], key_buff,
ref.key_length,
range_fl & NEAR_MAX ?
HA_READ_BEFORE_KEY :
HA_READ_PREFIX_LAST_OR_PREV);
- if (!error && reckey_in_range(1, &ref, item_field->field,
- conds, range_fl, prefix_len))
- error= HA_ERR_KEY_NOT_FOUND;
- }
+ if ((!error || error == HA_ERR_KEY_NOT_FOUND) &&
+ reckey_in_range(1, &ref, item_field->field,
+ conds, range_fl, prefix_len))
+ error= HA_ERR_KEY_NOT_FOUND;
if (table->key_read)
{
table->key_read=0;
diff --git a/sql/slave.cc b/sql/slave.cc
index cb37a798037..a45c5c62322 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1202,7 +1202,7 @@ slaves can't replicate a 5.0 or newer master.";
else
{
mi->clock_diff_with_master= 0; /* The "most sensible" value */
- sql_print_error("Warning: \"SELECT UNIX_TIMESTAMP()\" failed on master, \
+ sql_print_warning("\"SELECT UNIX_TIMESTAMP()\" failed on master, \
do not trust column Seconds_Behind_Master of SHOW SLAVE STATUS");
}
if (master_res)
@@ -1290,6 +1290,7 @@ be equal for replication to work";
Used by fetch_master_table (used by LOAD TABLE tblname FROM MASTER and LOAD
DATA FROM MASTER). Drops the table (if 'overwrite' is true) and recreates it
from the dump. Honours replication inclusion/exclusion rules.
+ db must be non-zero (guarded by assertion).
RETURN VALUES
0 success
@@ -1300,8 +1301,8 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
const char* table_name, bool overwrite)
{
ulong packet_len;
- char *query;
- char* save_db;
+ char *query, *save_db;
+ uint32 save_db_length;
Vio* save_vio;
HA_CHECK_OPT check_opt;
TABLE_LIST tables;
@@ -1357,9 +1358,13 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
thd->proc_info = "Creating table from master dump";
// save old db in case we are creating in a different database
save_db = thd->db;
+ save_db_length= thd->db_length;
thd->db = (char*)db;
+ DBUG_ASSERT(thd->db);
+ thd->db_length= strlen(thd->db);
mysql_parse(thd, thd->query, packet_len); // run create table
thd->db = save_db; // leave things the way the were before
+ thd->db_length= save_db_length;
thd->options = save_options;
if (thd->query_error)
@@ -3225,7 +3230,7 @@ err:
IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff));
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query = thd->db = 0; // extra safety
- thd->query_length = 0;
+ thd->query_length= thd->db_length= 0;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
if (mysql)
{
@@ -3391,7 +3396,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
err:
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query = thd->db = 0; // extra safety
- thd->query_length = 0;
+ thd->query_length= thd->db_length= 0;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
thd->proc_info = "Waiting for slave mutex on exit";
pthread_mutex_lock(&rli->run_lock);
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 9c6853187f6..fc68e26c21d 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -203,7 +203,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
host.sort= get_sort(2,host.host.hostname,host.db);
if (check_no_resolve && hostname_requires_resolving(host.host.hostname))
{
- sql_print_error("Warning: 'host' entry '%s|%s' "
+ sql_print_warning("'host' entry '%s|%s' "
"ignored in --skip-name-resolve mode.",
host.host.hostname, host.db, host.host.hostname);
continue;
@@ -271,8 +271,8 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
user.user= get_field(&mem, table->field[1]);
if (check_no_resolve && hostname_requires_resolving(user.host.hostname))
{
- sql_print_error("Warning: 'user' entry '%s@%s' "
- "ignored in --skip-name-resolve mode.",
+ sql_print_warning("'user' entry '%s@%s' "
+ "ignored in --skip-name-resolve mode.",
user.user, user.host.hostname, user.host.hostname);
continue;
}
@@ -284,16 +284,16 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
{
switch (password_len) {
case 45: /* 4.1: to be removed */
- sql_print_error("Found 4.1 style password for user '%s@%s'. "
- "Ignoring user. "
- "You should change password for this user.",
- user.user ? user.user : "",
- user.host.hostname ? user.host.hostname : "");
+ sql_print_warning("Found 4.1 style password for user '%s@%s'. "
+ "Ignoring user. "
+ "You should change password for this user.",
+ user.user ? user.user : "",
+ user.host.hostname ? user.host.hostname : "");
break;
default:
- sql_print_error("Found invalid password for user: '%s@%s'; "
- "Ignoring user", user.user ? user.user : "",
- user.host.hostname ? user.host.hostname : "");
+ sql_print_warning("Found invalid password for user: '%s@%s'; "
+ "Ignoring user", user.user ? user.user : "",
+ user.host.hostname ? user.host.hostname : "");
break;
}
}
@@ -368,15 +368,15 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
db.db=get_field(&mem, table->field[1]);
if (!db.db)
{
- sql_print_error("Found an entry in the 'db' table with empty database name; Skipped");
+ sql_print_warning("Found an entry in the 'db' table with empty database name; Skipped");
continue;
}
db.user=get_field(&mem, table->field[2]);
if (check_no_resolve && hostname_requires_resolving(db.host.hostname))
{
- sql_print_error("Warning: 'db' entry '%s %s@%s' "
- "ignored in --skip-name-resolve mode.",
- db.db, db.user, db.host.hostname, db.host.hostname);
+ sql_print_warning("'db' entry '%s %s@%s' "
+ "ignored in --skip-name-resolve mode.",
+ db.db, db.user, db.host.hostname, db.host.hostname);
continue;
}
db.access=get_access(table,3);
@@ -733,9 +733,9 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh,
else
{
if (global_system_variables.log_warnings)
- sql_print_error("X509 ciphers mismatch: should be '%s' but is '%s'",
- acl_user->ssl_cipher,
- SSL_get_cipher(ssl));
+ sql_print_information("X509 ciphers mismatch: should be '%s' but is '%s'",
+ acl_user->ssl_cipher,
+ SSL_get_cipher(ssl));
break;
}
}
@@ -757,8 +757,8 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh,
if (strcmp(acl_user->x509_issuer, ptr))
{
if (global_system_variables.log_warnings)
- sql_print_error("X509 issuer mismatch: should be '%s' "
- "but is '%s'", acl_user->x509_issuer, ptr);
+ sql_print_information("X509 issuer mismatch: should be '%s' "
+ "but is '%s'", acl_user->x509_issuer, ptr);
free(ptr);
break;
}
@@ -775,7 +775,7 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh,
if (strcmp(acl_user->x509_subject,ptr))
{
if (global_system_variables.log_warnings)
- sql_print_error("X509 subject mismatch: '%s' vs '%s'",
+ sql_print_information("X509 subject mismatch: '%s' vs '%s'",
acl_user->x509_subject, ptr);
}
else
@@ -2610,10 +2610,10 @@ my_bool grant_init(THD *org_thd)
{
if (hostname_requires_resolving(mem_check->host))
{
- sql_print_error("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);
+ 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);
continue;
}
}
@@ -3680,12 +3680,6 @@ int mysql_revoke_all(THD *thd, List <LEX_USER> &list)
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
- /* XXX this should not be necessary. The error message is already printed
- by replace_xxx_table. my_error() should be use above instead of
- sql_print_error(), and print ER_NONEXISTING_GRANT - as other grant
- commands do */
- /* when this code is deleted, the error slot (error 1268) can be reused,
- as this error code was not present in any MySQL release */
if (result)
my_error(ER_REVOKE_GRANTS, MYF(0));
diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc
index 3f75dadb6f0..1e0aebbc1ec 100644
--- a/sql/sql_analyse.cc
+++ b/sql/sql_analyse.cc
@@ -799,6 +799,13 @@ void field_real::get_opt_type(String *answer,
if (min_arg >= 0)
answer->append(" UNSIGNED");
}
+ else if (item->decimals == NOT_FIXED_DEC)
+ {
+ if (min_arg >= -FLT_MAX && max_arg <= FLT_MAX)
+ answer->append("FLOAT", 5);
+ else
+ answer->append("DOUBLE", 6);
+ }
else
{
if (min_arg >= -FLT_MAX && max_arg <= FLT_MAX)
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index ac5008717e6..30f97cf20a9 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1384,7 +1384,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
/* Give right error message */
thd->clear_error();
my_error(ER_NOT_KEYFILE, MYF(0), name, my_errno);
- sql_print_error("Error: Couldn't repair table: %s.%s",db,name);
+ sql_print_error("Couldn't repair table: %s.%s",db,name);
if (entry->file)
closefrm(entry);
error=1;
@@ -1424,7 +1424,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
DBA on top of warning the client (which will automatically be done
because of MYF(MY_WME) in my_malloc() above).
*/
- sql_print_error("Error: when opening HEAP table, could not allocate \
+ sql_print_error("When opening HEAP table, could not allocate \
memory to write 'DELETE FROM `%s`.`%s`' to the binary log",db,name);
if (entry->file)
closefrm(entry);
@@ -1820,8 +1820,8 @@ bool rm_temporary_table(enum db_type base, char *path)
if (file && file->delete_table(path))
{
error=1;
- sql_print_error("Warning: Could not remove tmp table: '%s', error: %d",
- path, my_errno);
+ sql_print_warning("Could not remove tmp table: '%s', error: %d",
+ path, my_errno);
}
delete file;
DBUG_RETURN(error);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 9dcc3b24883..b564775703c 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1503,7 +1503,7 @@ Statement_map::Statement_map() :
START_STMT_HASH_SIZE = 16,
START_NAME_HASH_SIZE = 16
};
- hash_init(&st_hash, default_charset_info, START_STMT_HASH_SIZE, 0, 0,
+ hash_init(&st_hash, &my_charset_bin, START_STMT_HASH_SIZE, 0, 0,
get_statement_id_as_hash_key,
delete_statement_as_hash_key, MYF(0));
hash_init(&names_hash, system_charset_info, START_NAME_HASH_SIZE, 0, 0,
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 5e221b394df..5a5b0fa81ce 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1021,27 +1021,6 @@ public:
#define SYSTEM_THREAD_SLAVE_SQL 4
/*
- Disables binary logging for one thread, and resets it back to what it was
- before being disabled.
- Some functions (like the internal mysql_create_table() when it's called by
- mysql_alter_table()) must NOT write to the binlog (binlogging is done at the
- at a later stage of the command already, and must be, for locking reasons);
- so we internally disable it temporarily by creating the Disable_binlog
- object and reset the state by destroying the object (don't forget that! or
- write code so that the object gets automatically destroyed when leaving a
- block, see example in sql_table.cc).
-*/
-class Disable_binlog {
-private:
- THD *thd;
- ulong save_options;
-public:
- Disable_binlog(THD *thd_arg);
- ~Disable_binlog();
-};
-
-
-/*
Used to hold information about file and file structure in exchainge
via non-DB file (...INTO OUTFILE..., ...LOAD DATA...)
XXX: We never call destructor for objects of this class.
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index cfc75e3be95..426f7d36633 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -852,6 +852,11 @@ err:
communication packet (in case of 'connect' or 'COM_INIT_DB')
we have to do end space removal in this function.
+ NOTES
+ Do as little as possible in this function, as it is not called for the
+ replication slave SQL thread (for that thread, setting of thd->db is done
+ in ::exec_event() methods of log_event.cc).
+
RETURN VALUES
0 ok
1 error
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 8cf057a8532..39b94362269 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1022,12 +1022,12 @@ pthread_handler_decl(handle_one_connection,arg)
if (net->error && net->vio != 0 && net->report_error)
{
if (!thd->killed && thd->variables.log_warnings > 1)
- sql_print_error(ER(ER_NEW_ABORTING_CONNECTION),
- thd->thread_id,(thd->db ? thd->db : "unconnected"),
- thd->user ? thd->user : "unauthenticated",
- thd->host_or_ip,
- (net->last_errno ? ER(net->last_errno) :
- ER(ER_UNKNOWN_ERROR)));
+ sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
+ thd->thread_id,(thd->db ? thd->db : "unconnected"),
+ thd->user ? thd->user : "unauthenticated",
+ thd->host_or_ip,
+ (net->last_errno ? ER(net->last_errno) :
+ ER(ER_UNKNOWN_ERROR)));
send_error(thd,net->last_errno,NullS);
statistic_increment(aborted_threads,&LOCK_status);
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 1b6c7dbc9bc..aa3301d540f 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1475,8 +1475,16 @@ error:
static bool init_param_array(Prepared_statement *stmt)
{
LEX *lex= stmt->lex;
+ THD *thd= stmt->thd;
if ((stmt->param_count= lex->param_list.elements))
{
+ if (stmt->param_count > (uint) UINT_MAX16)
+ {
+ /* Error code to be defined in 5.0 */
+ send_error(thd, ER_UNKNOWN_ERROR,
+ "Prepared statement contains too many placeholders.");
+ return 1;
+ }
Item_param **to;
List_iterator<Item_param> param_iterator(lex->param_list);
/* Use thd->mem_root as it points at statement mem_root */
@@ -1485,7 +1493,7 @@ static bool init_param_array(Prepared_statement *stmt)
sizeof(Item_param*) * stmt->param_count);
if (!stmt->param_array)
{
- send_error(stmt->thd, ER_OUT_OF_RESOURCES);
+ send_error(thd, ER_OUT_OF_RESOURCES);
return 1;
}
for (to= stmt->param_array;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index f3eed672231..dbfecb9610f 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -5930,6 +5930,7 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
+ tab->index= tab->ref.key;
}
if ((error=join_read_const(tab)))
{
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index d490a5f03f4..5929e8c4289 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -29,7 +29,13 @@
#include <io.h>
#endif
-const char *primary_key_name= "PRIMARY";
+#define tmp_disable_binlog(A) \
+ ulong save_options= (A)->options; \
+ (A)->options&= ~OPTION_BIN_LOG;
+
+#define reenable_binlog(A) (A)->options= save_options;
+
+const char *primary_key_name="PRIMARY";
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
@@ -1348,10 +1354,9 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
MYSQL_LOCK **lock)
{
TABLE tmp_table; // Used during 'create_field()'
- TABLE *table;
+ TABLE *table= 0;
tmp_table.table_name=0;
uint select_field_count= items->elements;
- Disable_binlog disable_binlog(thd);
DBUG_ENTER("create_table_from_items");
/* Add selected items to field list */
@@ -1381,23 +1386,26 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
extra_fields->push_back(cr_field);
}
/* create and lock table */
- /* QQ: This should be done atomic ! */
- /* We don't log the statement, it will be logged later */
- if (mysql_create_table(thd,db,name,create_info,*extra_fields,
- *keys,0,select_field_count))
- DBUG_RETURN(0);
+ /* QQ: create and open should be done atomic ! */
/*
+ We don't log the statement, it will be logged later.
If this is a HEAP table, the automatic DELETE FROM which is written to the
binlog when a HEAP table is opened for the first time since startup, must
not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we
don't want to delete from it) 2) it would be written before the CREATE
- TABLE, which is a wrong order. So we keep binary logging disabled.
+ TABLE, which is a wrong order. So we keep binary logging disabled when we
+ open_table().
*/
- if (!(table=open_table(thd,db,name,name,(bool*) 0)))
+ tmp_disable_binlog(thd);
+ if (!mysql_create_table(thd,db,name,create_info,*extra_fields,
+ *keys,0,select_field_count))
{
- quick_rm_table(create_info->db_type,db,table_case_name(create_info,name));
- DBUG_RETURN(0);
+ if (!(table=open_table(thd,db,name,name,(bool*) 0)))
+ quick_rm_table(create_info->db_type,db,table_case_name(create_info,name));
}
+ reenable_binlog(thd);
+ if (!table)
+ DBUG_RETURN(0);
table->reginfo.lock_type=TL_WRITE;
if (!((*lock)=mysql_lock_tables(thd,&table,1)))
{
@@ -3018,11 +3026,12 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
else
create_info->data_file_name=create_info->index_file_name=0;
{
- /* We don't log the statement, it will be logged later */
- Disable_binlog disable_binlog(thd);
- if ((error=mysql_create_table(thd, new_db, tmp_name,
- create_info,
- create_list,key_list,1,0)))
+ /* We don't log the statement, it will be logged later. */
+ tmp_disable_binlog(thd);
+ error= mysql_create_table(thd, new_db, tmp_name,
+ create_info,create_list,key_list,1,0);
+ reenable_binlog(thd);
+ if (error)
DBUG_RETURN(error);
}
if (table->tmp_table)
@@ -3250,8 +3259,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
my_free((char*) table, MYF(0));
}
else
- sql_print_error("Warning: Could not open BDB table %s.%s after rename\n",
- new_db,table_name);
+ sql_print_warning("Could not open BDB table %s.%s after rename\n",
+ new_db,table_name);
(void) berkeley_flush_logs();
}
#endif
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index 561f79f9de1..0bb8ac8a28b 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -184,8 +184,7 @@ void udf_init()
if (!(dl = dlopen(tmp->dl, RTLD_NOW)))
{
/* Print warning to log */
- sql_print_error(ER(ER_CANT_OPEN_LIBRARY),
- tmp->dl,errno,dlerror());
+ sql_print_error(ER(ER_CANT_OPEN_LIBRARY), tmp->dl,errno,dlerror());
/* Keep the udf in the hash so that we can remove it later */
continue;
}
diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c
index 2548a68ab19..3bfc66029ce 100644
--- a/strings/ctype-mb.c
+++ b/strings/ctype-mb.c
@@ -458,6 +458,92 @@ static void my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
}
}
+/*
+** Calculate min_str and max_str that ranges a LIKE string.
+** Arguments:
+** ptr Pointer to LIKE string.
+** ptr_length Length of LIKE string.
+** escape Escape character in LIKE. (Normally '\').
+** All escape characters should be removed from min_str and max_str
+** res_length Length of min_str and max_str.
+** min_str Smallest case sensitive string that ranges LIKE.
+** Should be space padded to res_length.
+** max_str Largest case sensitive string that ranges LIKE.
+** Normally padded with the biggest character sort value.
+**
+** The function should return 0 if ok and 1 if the LIKE string can't be
+** optimized !
+*/
+
+my_bool my_like_range_mb(CHARSET_INFO *cs,
+ const char *ptr,uint ptr_length,
+ pbool escape, pbool w_one, pbool w_many,
+ uint res_length,
+ char *min_str,char *max_str,
+ uint *min_length,uint *max_length)
+{
+ 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;
+
+ for (; ptr != end && min_str != min_end ; ptr++)
+ {
+ 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 */
+ {
+ char buf[10];
+ uint buflen;
+
+ /* Write min key */
+ *min_length= (uint) (min_str - min_org);
+ *max_length=res_length;
+ do
+ {
+ *min_str++= (char) cs->min_sort_char;
+ } while (min_str != min_end);
+
+ /*
+ Write max key: create a buffer with multibyte
+ representation of the max_sort_char character,
+ and copy it into max_str in a loop.
+ */
+ buflen= cs->cset->wc_mb(cs, cs->max_sort_char, buf, buf + sizeof(buf));
+ DBUG_ASSERT(buflen > 0);
+ do
+ {
+ if ((max_str + buflen) <= max_end)
+ {
+ /* Enough space for max characer */
+ memcpy(max_str, buf, buflen);
+ max_str+= buflen;
+ }
+ else
+ {
+ /*
+ There is no space for whole multibyte
+ character, then add trailing spaces.
+ */
+
+ *max_str++= ' ';
+ }
+ } while (max_str != max_end);
+ return 0;
+ }
+ *min_str++= *max_str++ = *ptr;
+ }
+ *min_length= *max_length = (uint) (min_str - min_org);
+
+ while (min_str != min_end)
+ *min_str++ = *max_str++ = ' '; /* Because if key compression */
+ return 0;
+}
+
static int my_wildcmp_mb_bin(CHARSET_INFO *cs,
const char *str,const char *str_end,
const char *wildstr,const char *wildend,
@@ -565,7 +651,7 @@ static int my_wildcmp_mb_bin(CHARSET_INFO *cs,
if (str++ == str_end) return (-1);
}
{
- int tmp=my_wildcmp_mb(cs,str,str_end,wildstr,wildend,escape,w_one,w_many);
+ int tmp=my_wildcmp_mb_bin(cs,str,str_end,wildstr,wildend,escape,w_one,w_many);
if (tmp <= 0)
return (tmp);
}
diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c
index cecc3be5045..edb84dbf225 100644
--- a/strings/ctype-uca.c
+++ b/strings/ctype-uca.c
@@ -6876,7 +6876,8 @@ static int my_uca_scanner_next_any(my_uca_scanner *scanner)
int mblen;
if (((mblen= scanner->cs->cset->mb_wc(scanner->cs, &wc,
- scanner->sbeg, scanner->send)) < 0))
+ scanner->sbeg,
+ scanner->send)) <= 0))
return -1;
scanner->page= wc >> 8;
@@ -7918,7 +7919,7 @@ MY_COLLATION_HANDLER my_collation_ucs2_uca_handler =
my_strnncoll_ucs2_uca,
my_strnncollsp_ucs2_uca,
my_strnxfrm_ucs2_uca,
- my_like_range_simple,
+ my_like_range_ucs2,
my_wildcmp_uca,
NULL,
my_instr_mb,
@@ -8369,7 +8370,7 @@ MY_COLLATION_HANDLER my_collation_any_uca_handler =
my_strnncoll_any_uca,
my_strnncollsp_any_uca,
my_strnxfrm_any_uca,
- my_like_range_simple,
+ my_like_range_mb,
my_wildcmp_uca,
NULL,
my_instr_mb,
diff --git a/tests/client_test.c b/tests/client_test.c
index b124fba3f59..8a98c5b6584 100644
--- a/tests/client_test.c
+++ b/tests/client_test.c
@@ -223,7 +223,7 @@ static void client_disconnect()
if (mysql)
{
- fprintf(stdout, "\n droping the test database '%s' ...", current_db);
+ fprintf(stdout, "\n dropping the test database '%s' ...", current_db);
strxmov(query, "DROP DATABASE IF EXISTS ", current_db, NullS);
mysql_query(mysql, query);
@@ -797,21 +797,21 @@ static void test_tran_bdb()
rc= mysql_commit(mysql);
myquery(rc);
- /* now insert the second row, and rollback the transaction */
+ /* now insert the second row, and roll back the transaction */
rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(20, 'mysql')");
myquery(rc);
rc= mysql_rollback(mysql);
myquery(rc);
- /* delete first row, and rollback it */
+ /* delete first row, and roll it back */
rc= mysql_query(mysql, "DELETE FROM my_demo_transaction WHERE col1= 10");
myquery(rc);
rc= mysql_rollback(mysql);
myquery(rc);
- /* test the results now, only one row should exists */
+ /* test the results now, only one row should exist */
rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
myquery(rc);
@@ -822,7 +822,7 @@ static void test_tran_bdb()
my_process_result_set(result);
mysql_free_result(result);
- /* test the results now, only one row should exists */
+ /* test the results now, only one row should exist */
rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
myquery(rc);
@@ -870,21 +870,21 @@ static void test_tran_innodb()
rc= mysql_commit(mysql);
myquery(rc);
- /* now insert the second row, and rollback the transaction */
+ /* now insert the second row, and roll back the transaction */
rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(20, 'mysql')");
myquery(rc);
rc= mysql_rollback(mysql);
myquery(rc);
- /* delete first row, and rollback it */
+ /* delete first row, and roll it back */
rc= mysql_query(mysql, "DELETE FROM my_demo_transaction WHERE col1= 10");
myquery(rc);
rc= mysql_rollback(mysql);
myquery(rc);
- /* test the results now, only one row should exists */
+ /* test the results now, only one row should exist */
rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
myquery(rc);
@@ -895,7 +895,7 @@ static void test_tran_innodb()
my_process_result_set(result);
mysql_free_result(result);
- /* test the results now, only one row should exists */
+ /* test the results now, only one row should exist */
rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
myquery(rc);
@@ -1158,7 +1158,7 @@ static void test_prepare()
rc= mysql_commit(mysql);
myquery(rc);
- /* test the results now, only one row should exists */
+ /* test the results now, only one row should exist */
assert(tiny_data == (char) my_stmt_result("SELECT * FROM my_prepare"));
stmt= mysql_simple_prepare(mysql, "SELECT * FROM my_prepare");
@@ -1304,7 +1304,7 @@ static void test_double_compare()
rc= mysql_commit(mysql);
myquery(rc);
- /* test the results now, only one row should exists */
+ /* test the results now, only one row should exist */
rc= mysql_query(mysql, "SELECT * FROM test_double_compare");
myquery(rc);
@@ -1740,7 +1740,7 @@ static void test_select()
rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 'venu')");
myquery(rc);
- /* now insert the second row, and rollback the transaction */
+ /* now insert the second row, and roll back the transaction */
rc= mysql_query(mysql, "INSERT INTO test_select VALUES(20, 'mysql')");
myquery(rc);
@@ -2259,7 +2259,7 @@ static void test_simple_update()
rc= mysql_commit(mysql);
myquery(rc);
- /* test the results now, only one row should exists */
+ /* test the results now, only one row should exist */
rc= mysql_query(mysql, "SELECT * FROM test_update");
myquery(rc);
@@ -2738,7 +2738,7 @@ static void test_simple_delete()
rc= mysql_commit(mysql);
myquery(rc);
- /* test the results now, only one row should exists */
+ /* test the results now, only one row should exist */
rc= mysql_query(mysql, "SELECT * FROM test_simple_delete");
myquery(rc);
@@ -2837,7 +2837,7 @@ static void test_update()
rc= mysql_commit(mysql);
myquery(rc);
- /* test the results now, only one row should exists */
+ /* test the results now, only one row should exist */
rc= mysql_query(mysql, "SELECT * FROM test_update");
myquery(rc);
@@ -2883,7 +2883,7 @@ static void test_prepare_noparam()
rc= mysql_commit(mysql);
myquery(rc);
- /* test the results now, only one row should exists */
+ /* test the results now, only one row should exist */
rc= mysql_query(mysql, "SELECT * FROM my_prepare");
myquery(rc);
@@ -3953,7 +3953,7 @@ static void test_insert()
rc= mysql_commit(mysql);
myquery(rc);
- /* test the results now, only one row should exists */
+ /* test the results now, only one row should exist */
rc= mysql_query(mysql, "SELECT * FROM test_prep_insert");
myquery(rc);
@@ -4906,7 +4906,7 @@ DROP TABLE IF EXISTS test_multi_tab";
/*
First test that we get an error for multi statements
- (Becasue default connection is not opened with CLIENT_MULTI_STATEMENTS)
+ (Because default connection is not opened with CLIENT_MULTI_STATEMENTS)
*/
rc= mysql_query(mysql, query); /* syntax error */
myquery_r(rc);
@@ -4920,7 +4920,7 @@ DROP TABLE IF EXISTS test_multi_tab";
exit(1);
}
- /* Create connection that supprot multi statements */
+ /* Create connection that supports multi statements */
if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
opt_password, current_db, opt_port,
opt_unix_socket, CLIENT_MULTI_STATEMENTS)))
@@ -10163,6 +10163,234 @@ static void test_bug4231()
myquery(rc);
}
+
+static void test_bug5399()
+{
+ /*
+ Ascii 97 is 'a', which gets mapped to Ascii 65 'A' unless internal
+ statement id hash in the server uses binary collation.
+ */
+#define NUM_OF_USED_STMT 97
+ MYSQL_STMT *stmt[NUM_OF_USED_STMT];
+ MYSQL_BIND bind[1];
+ char buff[500];
+ int rc, i;
+ int32 no;
+
+ myheader("test_bug5399");
+
+ bzero(bind, sizeof(bind));
+ bind[0].buffer_type= MYSQL_TYPE_LONG;
+ bind[0].buffer= &no;
+
+ for (i= 0; i < NUM_OF_USED_STMT; ++i)
+ {
+ stmt[i]= mysql_stmt_init(mysql);
+ sprintf(buff, "select %d", i);
+ rc= mysql_stmt_prepare(stmt[i], buff, strlen(buff));
+ check_execute(stmt[i], rc);
+ mysql_stmt_bind_result(stmt[i], bind);
+ }
+ printf("%d statements prepared.\n", NUM_OF_USED_STMT);
+
+ for (i= 0; i < NUM_OF_USED_STMT; ++i)
+ {
+ rc= mysql_stmt_execute(stmt[i]);
+ check_execute(stmt[i], rc);
+ rc= mysql_stmt_store_result(stmt[i]);
+ check_execute(stmt[i], rc);
+ rc= mysql_stmt_fetch(stmt[i]);
+ assert(rc == 0);
+ assert((int32) i == no);
+ }
+
+ for (i= 0; i < NUM_OF_USED_STMT; ++i)
+ mysql_stmt_close(stmt[i]);
+#undef NUM_OF_USED_STMT
+}
+
+
+static void test_bug5194()
+{
+ MYSQL_STMT *stmt;
+ MYSQL_BIND *bind;
+ char *query;
+ char *param_str;
+ int param_str_length;
+ const char *stmt_text;
+ int rc;
+ float float_array[250] =
+ {
+ 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
+ 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
+ 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
+ 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
+ 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
+ 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
+ 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
+ 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
+ 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
+ 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
+ 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
+ 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
+ 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
+ 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
+ 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
+ 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
+ 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
+ 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
+ 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
+ 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
+ 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
+ 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
+ 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
+ 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
+ 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25
+ };
+ float *fa_ptr= float_array;
+ /* Number of columns per row */
+ const int COLUMN_COUNT= sizeof(float_array)/sizeof(*float_array);
+ /* Number of rows per bulk insert to start with */
+ const int MIN_ROWS_PER_INSERT= 260;
+ /* Max number of rows per bulk insert to end with */
+ const int MAX_ROWS_PER_INSERT= 300;
+ const int MAX_PARAM_COUNT= COLUMN_COUNT*MAX_ROWS_PER_INSERT;
+ const char *query_template= "insert into t1 values %s";
+ const int CHARS_PER_PARAM= 5; /* space needed to place ", ?" in the query */
+ const int uint16_max= 65535;
+ int nrows, i;
+
+ myheader("test_bug5194");
+
+ stmt_text= "drop table if exists t1";
+ rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
+
+ stmt_text= "create table if not exists t1"
+ "(c1 float, c2 float, c3 float, c4 float, c5 float, c6 float, "
+ "c7 float, c8 float, c9 float, c10 float, c11 float, c12 float, "
+ "c13 float, c14 float, c15 float, c16 float, c17 float, c18 float, "
+ "c19 float, c20 float, c21 float, c22 float, c23 float, c24 float, "
+ "c25 float, c26 float, c27 float, c28 float, c29 float, c30 float, "
+ "c31 float, c32 float, c33 float, c34 float, c35 float, c36 float, "
+ "c37 float, c38 float, c39 float, c40 float, c41 float, c42 float, "
+ "c43 float, c44 float, c45 float, c46 float, c47 float, c48 float, "
+ "c49 float, c50 float, c51 float, c52 float, c53 float, c54 float, "
+ "c55 float, c56 float, c57 float, c58 float, c59 float, c60 float, "
+ "c61 float, c62 float, c63 float, c64 float, c65 float, c66 float, "
+ "c67 float, c68 float, c69 float, c70 float, c71 float, c72 float, "
+ "c73 float, c74 float, c75 float, c76 float, c77 float, c78 float, "
+ "c79 float, c80 float, c81 float, c82 float, c83 float, c84 float, "
+ "c85 float, c86 float, c87 float, c88 float, c89 float, c90 float, "
+ "c91 float, c92 float, c93 float, c94 float, c95 float, c96 float, "
+ "c97 float, c98 float, c99 float, c100 float, c101 float, c102 float, "
+ "c103 float, c104 float, c105 float, c106 float, c107 float, c108 float, "
+ "c109 float, c110 float, c111 float, c112 float, c113 float, c114 float, "
+ "c115 float, c116 float, c117 float, c118 float, c119 float, c120 float, "
+ "c121 float, c122 float, c123 float, c124 float, c125 float, c126 float, "
+ "c127 float, c128 float, c129 float, c130 float, c131 float, c132 float, "
+ "c133 float, c134 float, c135 float, c136 float, c137 float, c138 float, "
+ "c139 float, c140 float, c141 float, c142 float, c143 float, c144 float, "
+ "c145 float, c146 float, c147 float, c148 float, c149 float, c150 float, "
+ "c151 float, c152 float, c153 float, c154 float, c155 float, c156 float, "
+ "c157 float, c158 float, c159 float, c160 float, c161 float, c162 float, "
+ "c163 float, c164 float, c165 float, c166 float, c167 float, c168 float, "
+ "c169 float, c170 float, c171 float, c172 float, c173 float, c174 float, "
+ "c175 float, c176 float, c177 float, c178 float, c179 float, c180 float, "
+ "c181 float, c182 float, c183 float, c184 float, c185 float, c186 float, "
+ "c187 float, c188 float, c189 float, c190 float, c191 float, c192 float, "
+ "c193 float, c194 float, c195 float, c196 float, c197 float, c198 float, "
+ "c199 float, c200 float, c201 float, c202 float, c203 float, c204 float, "
+ "c205 float, c206 float, c207 float, c208 float, c209 float, c210 float, "
+ "c211 float, c212 float, c213 float, c214 float, c215 float, c216 float, "
+ "c217 float, c218 float, c219 float, c220 float, c221 float, c222 float, "
+ "c223 float, c224 float, c225 float, c226 float, c227 float, c228 float, "
+ "c229 float, c230 float, c231 float, c232 float, c233 float, c234 float, "
+ "c235 float, c236 float, c237 float, c238 float, c239 float, c240 float, "
+ "c241 float, c242 float, c243 float, c244 float, c245 float, c246 float, "
+ "c247 float, c248 float, c249 float, c250 float)";
+ rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
+ myquery(rc);
+
+ bind= (MYSQL_BIND*) malloc(MAX_PARAM_COUNT * sizeof(MYSQL_BIND));
+ query= (char*) malloc(strlen(query_template) +
+ MAX_PARAM_COUNT * CHARS_PER_PARAM + 1);
+ param_str= (char*) malloc(COLUMN_COUNT * CHARS_PER_PARAM);
+
+ if (bind == 0 || query == 0 || param_str == 0)
+ {
+ fprintf(stderr, "Can't allocate enough memory for query structs\n");
+ return;
+ }
+
+ stmt= mysql_stmt_init(mysql);
+
+ /* setup a template for one row of parameters */
+ sprintf(param_str, "(");
+ for (i= 1; i < COLUMN_COUNT; ++i)
+ strcat(param_str, "?, ");
+ strcat(param_str, "?)");
+ param_str_length= strlen(param_str);
+
+ /* setup bind array */
+ bzero(bind, MAX_PARAM_COUNT * sizeof(MYSQL_BIND));
+ for (i= 0; i < MAX_PARAM_COUNT; ++i)
+ {
+ bind[i].buffer_type= MYSQL_TYPE_FLOAT;
+ bind[i].buffer= fa_ptr;
+ if (++fa_ptr == float_array + COLUMN_COUNT)
+ fa_ptr= float_array;
+ }
+
+ /*
+ Test each number of rows per bulk insert, so that we can see where
+ MySQL fails.
+ */
+ for (nrows= MIN_ROWS_PER_INSERT; nrows <= MAX_ROWS_PER_INSERT; ++nrows)
+ {
+ char *query_ptr;
+ /* Create statement text for current number of rows */
+ sprintf(query, query_template, param_str);
+ query_ptr= query + strlen(query);
+ for (i= 1; i < nrows; ++i)
+ {
+ memcpy(query_ptr, ", ", 2);
+ query_ptr+= 2;
+ memcpy(query_ptr, param_str, param_str_length);
+ query_ptr+= param_str_length;
+ }
+ *query_ptr= '\0';
+
+ rc= mysql_stmt_prepare(stmt, query, query_ptr - query);
+ if (rc && nrows * COLUMN_COUNT > uint16_max)
+ {
+ printf("Failed to prepare a statement with %d placeholders "
+ "(as expected).\n", nrows * COLUMN_COUNT);
+ break;
+ }
+ else
+ check_execute(stmt, rc);
+
+ printf("Insert: query length= %d, row count= %d, param count= %lu\n",
+ strlen(query), nrows, mysql_stmt_param_count(stmt));
+
+ /* bind the parameter array and execute the query */
+ rc= mysql_stmt_bind_param(stmt, bind);
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ }
+
+ mysql_stmt_close(stmt);
+ free(bind);
+ free(query);
+ free(param_str);
+ stmt_text= "drop table t1";
+ rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
+ myquery(rc);
+}
+
+
/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -10463,6 +10691,9 @@ int main(int argc, char **argv)
test_bug5126(); /* support for mediumint type in libmysql */
test_bug4231(); /* proper handling of all-zero times and
dates in the server */
+ test_bug5399(); /* check that statement id uniquely identifies
+ statement */
+ test_bug5194(); /* bulk inserts in prepared mode */
/*
XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST
DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH.