Commit 355c15b8 authored by Matthias Leich's avatar Matthias Leich

Merge of latest modfications into GCA tree, no conflicts

parents fc77e47d 9e530c0f
......@@ -587,9 +587,4 @@ SELECT CASE c1 WHEN c1 + 1 THEN 1 END, ABS(AVG(c0)) FROM t1;
CASE c1 WHEN c1 + 1 THEN 1 END ABS(AVG(c0))
NULL 1.0000
DROP TABLE t1;
CREATE TABLE t1(a TEXT);
INSERT INTO t1 VALUES('iynfj');
SELECT SUM( DISTINCT a ) FROM t1 GROUP BY a HAVING a IN ( AVG( 1 ), 1 + a );
SUM( DISTINCT a )
DROP TABLE t1;
End of 5.1 tests
......@@ -11,7 +11,7 @@ prepare s from "insert into t1 select 100 limit ?";
set @a=100;
execute s using @a;
Warnings:
Note 1592 Statement is not safe to log in statement format.
Note 1592 Statement may not be safe to log in statement format.
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; create table t1 (a int)
......
......@@ -289,7 +289,7 @@ CREATE TABLE t1(i INT PRIMARY KEY);
CREATE TABLE t2(i INT PRIMARY KEY);
CREATE TABLE t3(i INT, ch CHAR(50));
--echo "Should issue message Statement is not safe to log in statement format."
--echo "Should issue message Statement may not be safe to log in statement format."
INSERT INTO t1 SELECT * FROM t2 LIMIT 1;
DELIMITER |;
......@@ -302,7 +302,7 @@ BEGIN
RETURN 0;
END|
DELIMITER ;|
--echo "Should issue message Statement is not safe to log in statement format only once"
--echo "Should issue message Statement may not be safe to log in statement format only once"
INSERT INTO t3 VALUES(func6(), UUID());
--echo "Check whether SET @@SQL_LOG_BIN = 0/1 doesn't work in substatements"
......
......@@ -10,7 +10,7 @@ CREATE TABLE test.t1 (a INT, blob_column LONGBLOB, PRIMARY KEY(a));
INSERT INTO test.t1 VALUES(1,'test');
UPDATE test.t1 SET blob_column=LOAD_FILE('../../std_data/words2.dat') WHERE a=1;
Warnings:
Note 1592 Statement is not safe to log in statement format.
Note 1592 Statement may not be safe to log in statement format.
create procedure test.p1()
begin
INSERT INTO test.t1 VALUES(2,'test');
......@@ -18,7 +18,7 @@ UPDATE test.t1 SET blob_column=LOAD_FILE('../../std_data/words2.dat') WHERE a=2;
end|
CALL test.p1();
Warnings:
Note 1592 Statement is not safe to log in statement format.
Note 1592 Statement may not be safe to log in statement format.
SELECT * FROM test.t1 ORDER BY blob_column;
a blob_column
1 abase
......
......@@ -182,19 +182,19 @@ CREATE TABLE t1(sum INT, price FLOAT(24)) ENGINE=MyISAM;
affected rows: 0
INSERT INTO t1 VALUES(myfunc_int(100), myfunc_double(50.00));
Warnings:
Note 1592 Statement is not safe to log in statement format.
Note 1592 Statement may not be safe to log in statement format.
affected rows: 1
INSERT INTO t1 VALUES(myfunc_int(10), myfunc_double(5.00));
Warnings:
Note 1592 Statement is not safe to log in statement format.
Note 1592 Statement may not be safe to log in statement format.
affected rows: 1
INSERT INTO t1 VALUES(myfunc_int(200), myfunc_double(25.00));
Warnings:
Note 1592 Statement is not safe to log in statement format.
Note 1592 Statement may not be safe to log in statement format.
affected rows: 1
INSERT INTO t1 VALUES(myfunc_int(1), myfunc_double(500.00));
Warnings:
Note 1592 Statement is not safe to log in statement format.
Note 1592 Statement may not be safe to log in statement format.
affected rows: 1
SELECT * FROM t1 ORDER BY sum;
sum price
......
......@@ -439,14 +439,4 @@ SELECT CASE c1 WHEN c1 + 1 THEN 1 END, ABS(AVG(c0)) FROM t1;
DROP TABLE t1;
#
# Bug #44399: crash with statement using TEXT columns, aggregates, GROUP BY,
# and HAVING
#
CREATE TABLE t1(a TEXT);
INSERT INTO t1 VALUES('iynfj');
SELECT SUM( DISTINCT a ) FROM t1 GROUP BY a HAVING a IN ( AVG( 1 ), 1 + a );
DROP TABLE t1;
--echo End of 5.1 tests
......@@ -120,6 +120,7 @@ const char *def_shared_memory_base_name= default_shared_memory_base_name;
static void mysql_close_free_options(MYSQL *mysql);
static void mysql_close_free(MYSQL *mysql);
static void mysql_prune_stmt_list(MYSQL *mysql);
#if !(defined(__WIN__) || defined(__NETWARE__))
static int wait_for_data(my_socket fd, uint timeout);
......@@ -924,6 +925,7 @@ void end_server(MYSQL *mysql)
vio_delete(mysql->net.vio);
reset_sigpipe(mysql);
mysql->net.vio= 0; /* Marker */
mysql_prune_stmt_list(mysql);
}
net_end(&mysql->net);
free_old_query(mysql);
......@@ -2526,30 +2528,9 @@ my_bool mysql_reconnect(MYSQL *mysql)
tmp_mysql.reconnect= 1;
tmp_mysql.free_me= mysql->free_me;
/*
For each stmt in mysql->stmts, move it to tmp_mysql if it is
in state MYSQL_STMT_INIT_DONE, otherwise close it.
*/
{
LIST *element= mysql->stmts;
for (; element; element= element->next)
{
MYSQL_STMT *stmt= (MYSQL_STMT *) element->data;
if (stmt->state != MYSQL_STMT_INIT_DONE)
{
stmt->mysql= 0;
stmt->last_errno= CR_SERVER_LOST;
strmov(stmt->last_error, ER(CR_SERVER_LOST));
strmov(stmt->sqlstate, unknown_sqlstate);
}
else
{
tmp_mysql.stmts= list_add(tmp_mysql.stmts, &stmt->list);
}
/* No need to call list_delete for statement here */
}
mysql->stmts= NULL;
}
/* Move prepared statements (if any) over to the new mysql object */
tmp_mysql.stmts= mysql->stmts;
mysql->stmts= 0;
/* Don't free options as these are now used in tmp_mysql */
bzero((char*) &mysql->options,sizeof(mysql->options));
......@@ -2639,6 +2620,46 @@ static void mysql_close_free(MYSQL *mysql)
}
/**
For use when the connection to the server has been lost (in which case
the server has discarded all information about prepared statements
associated with the connection).
Mark all statements in mysql->stmts by setting stmt->mysql= 0 if the
statement has transitioned beyond the MYSQL_STMT_INIT_DONE state, and
unlink the statement from the mysql->stmts list.
The remaining pruned list of statements (if any) is kept in mysql->stmts.
@param mysql pointer to the MYSQL object
@return none
*/
static void mysql_prune_stmt_list(MYSQL *mysql)
{
LIST *element= mysql->stmts;
LIST *pruned_list= 0;
for (; element; element= element->next)
{
MYSQL_STMT *stmt= (MYSQL_STMT *) element->data;
if (stmt->state != MYSQL_STMT_INIT_DONE)
{
stmt->mysql= 0;
stmt->last_errno= CR_SERVER_LOST;
strmov(stmt->last_error, ER(CR_SERVER_LOST));
strmov(stmt->sqlstate, unknown_sqlstate);
}
else
{
pruned_list= list_add(pruned_list, element);
}
}
mysql->stmts= pruned_list;
}
/*
Clear connection pointer of every statement: this is necessary
to give error on attempt to use a prepared statement of closed
......
......@@ -189,7 +189,6 @@ enum_field_types agg_field_type(Item **items, uint nitems)
collect_cmp_types()
items Array of items to collect types from
nitems Number of items in the array
with_sum_func a sum function is referenced
DESCRIPTION
This function collects different result types for comparison of the first
......@@ -200,7 +199,7 @@ enum_field_types agg_field_type(Item **items, uint nitems)
Bitmap of collected types - otherwise
*/
static uint collect_cmp_types(Item **items, uint nitems, my_bool with_sum_func)
static uint collect_cmp_types(Item **items, uint nitems)
{
uint i;
uint found_types;
......@@ -216,16 +215,6 @@ static uint collect_cmp_types(Item **items, uint nitems, my_bool with_sum_func)
found_types|= 1<< (uint)item_cmp_type(left_result,
items[i]->result_type());
}
if (with_sum_func || current_thd->lex->current_select->group_list.elements)
{
/*
See TODO commentary in the setup_copy_fields function:
item in a group may be wrapped with an Item_copy_string item.
That item has a STRING_RESULT result type, so we need
to take this type into account.
*/
found_types |= (1 << item_cmp_type(left_result, STRING_RESULT));
}
return found_types;
}
......@@ -2733,8 +2722,19 @@ void Item_func_case::fix_length_and_dec()
for (nagg= 0; nagg < ncases/2 ; nagg++)
agg[nagg+1]= args[nagg*2];
nagg++;
if (!(found_types= collect_cmp_types(agg, nagg, with_sum_func)))
if (!(found_types= collect_cmp_types(agg, nagg)))
return;
if (with_sum_func || current_thd->lex->current_select->group_list.elements)
{
/*
See TODO commentary in the setup_copy_fields function:
item in a group may be wrapped with an Item_copy_string item.
That item has a STRING_RESULT result type, so we need
to take this type into account.
*/
found_types |= (1 << item_cmp_type(left_result_type, STRING_RESULT));
}
for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
{
if (found_types & (1 << i) && !cmp_items[i])
......@@ -3525,7 +3525,7 @@ void Item_func_in::fix_length_and_dec()
uint type_cnt= 0, i;
Item_result cmp_type= STRING_RESULT;
left_result_type= args[0]->result_type();
if (!(found_types= collect_cmp_types(args, arg_count, with_sum_func)))
if (!(found_types= collect_cmp_types(args, arg_count)))
return;
for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
......
......@@ -2461,6 +2461,9 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
stmt->execute_loop(&expanded_query, open_cursor, packet, packet_end);
/* Close connection socket; for use with client testing (Bug#43560). */
DBUG_EXECUTE_IF("close_conn_after_stmt_execute", vio_close(thd->net.vio););
DBUG_VOID_RETURN;
}
......
......@@ -103,7 +103,7 @@ if (!opt_silent) \
static void print_error(const char *msg);
static void print_st_error(MYSQL_STMT *stmt, const char *msg);
static void client_disconnect(void);
static void client_disconnect(MYSQL* mysql, my_bool drop_db);
/*
......@@ -271,10 +271,20 @@ mysql_simple_prepare(MYSQL *mysql_arg, const char *query)
}
/* Connect to the server */
static void client_connect(ulong flag)
/**
Connect to the server with options given by arguments to this application,
stored in global variables opt_host, opt_user, opt_password, opt_db,
opt_port and opt_unix_socket.
@param flag[in] client_flag passed on to mysql_real_connect
@param protocol[in] MYSQL_PROTOCOL_* to use for this connection
@param auto_reconnect[in] set to 1 for auto reconnect
@return pointer to initialized and connected MYSQL object
*/
static MYSQL* client_connect(ulong flag, uint protocol, my_bool auto_reconnect)
{
MYSQL* mysql;
int rc;
static char query[MAX_TEST_QUERY_LENGTH];
myheader_r("client_connect");
......@@ -291,6 +301,7 @@ static void client_connect(ulong flag)
}
/* enable local infile, in non-binary builds often disabled by default */
mysql_options(mysql, MYSQL_OPT_LOCAL_INFILE, 0);
mysql_options(mysql, MYSQL_OPT_PROTOCOL, &protocol);
if (!(mysql_real_connect(mysql, opt_host, opt_user,
opt_password, opt_db ? opt_db:"test", opt_port,
......@@ -302,7 +313,7 @@ static void client_connect(ulong flag)
fprintf(stdout, "\n Check the connection options using --help or -?\n");
exit(1);
}
mysql->reconnect= 1;
mysql->reconnect= auto_reconnect;
if (!opt_silent)
fprintf(stdout, "OK");
......@@ -329,12 +340,14 @@ static void client_connect(ulong flag)
if (!opt_silent)
fprintf(stdout, "OK");
return mysql;
}
/* Close the connection */
static void client_disconnect()
static void client_disconnect(MYSQL* mysql, my_bool drop_db)
{
static char query[MAX_TEST_QUERY_LENGTH];
......@@ -342,13 +355,16 @@ static void client_disconnect()
if (mysql)
{
if (!opt_silent)
fprintf(stdout, "\n dropping the test database '%s' ...", current_db);
strxmov(query, "DROP DATABASE IF EXISTS ", current_db, NullS);
if (drop_db)
{
if (!opt_silent)
fprintf(stdout, "\n dropping the test database '%s' ...", current_db);
strxmov(query, "DROP DATABASE IF EXISTS ", current_db, NullS);
mysql_query(mysql, query);
if (!opt_silent)
fprintf(stdout, "OK");
mysql_query(mysql, query);
if (!opt_silent)
fprintf(stdout, "OK");
}
if (!opt_silent)
fprintf(stdout, "\n closing the connection ...");
......@@ -17712,6 +17728,100 @@ static void test_bug40365(void)
}
/**
Subtest for Bug#43560. Verifies that a loss of connection on the server side
is handled well by the mysql_stmt_execute() call, i.e., no SIGSEGV due to
a vio socket that is cleared upon closed connection.
Assumes the presence of the close_conn_after_stmt_execute debug feature in
the server. Verifies that it is connected to a debug server before proceeding
with the test.
*/
static void test_bug43560(void)
{
MYSQL* conn;
uint rc;
MYSQL_STMT *stmt= 0;
MYSQL_BIND bind;
my_bool is_null= 0;
const uint BUFSIZE= 256;
char buffer[BUFSIZE];
const char* values[] = {"eins", "zwei", "drei", "viele", NULL};
const char insert_str[] = "INSERT INTO t1 (c2) VALUES (?)";
unsigned long length;
DBUG_ENTER("test_bug43560");
myheader("test_bug43560");
/* Make sure we only run against a debug server. */
if (!strstr(mysql->server_version, "debug"))
{
fprintf(stdout, "Skipping test_bug43560: server not DEBUG version\n");
DBUG_VOID_RETURN;
}
/*
Set up a separate connection for this test to avoid messing up the
general MYSQL object used in other subtests. Use TCP protocol to avoid
problems with the buffer semantics of AF_UNIX, and turn off auto reconnect.
*/
conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
rc= mysql_query(conn, "DROP TABLE IF EXISTS t1");
myquery(rc);
rc= mysql_query(conn,
"CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 CHAR(10))");
myquery(rc);
stmt= mysql_stmt_init(conn);
check_stmt(stmt);
rc= mysql_stmt_prepare(stmt, insert_str, strlen(insert_str));
check_execute(stmt, rc);
bind.buffer_type= MYSQL_TYPE_STRING;
bind.buffer_length= BUFSIZE;
bind.buffer= buffer;
bind.is_null= &is_null;
bind.length= &length;
rc= mysql_stmt_bind_param(stmt, &bind);
check_execute(stmt, rc);
/* First execute; should succeed. */
strncpy(buffer, values[0], BUFSIZE);
length= strlen(buffer);
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
/*
Set up the server to close this session's server-side socket after
next execution of prep statement.
*/
rc= mysql_query(conn,"SET SESSION debug='+d,close_conn_after_stmt_execute'");
myquery(rc);
/* Second execute; should fail due to socket closed during execution. */
strncpy(buffer, values[1], BUFSIZE);
length= strlen(buffer);
rc= mysql_stmt_execute(stmt);
DIE_UNLESS(rc && mysql_stmt_errno(stmt) == CR_SERVER_LOST);
/*
Third execute; should fail (connection already closed), or SIGSEGV in
case of a Bug#43560 type regression in which case the whole test fails.
*/
strncpy(buffer, values[2], BUFSIZE);
length= strlen(buffer);
rc= mysql_stmt_execute(stmt);
DIE_UNLESS(rc && mysql_stmt_errno(stmt) == CR_SERVER_LOST);
client_disconnect(conn, 0);
rc= mysql_query(mysql, "DROP TABLE t1");
myquery(rc);
DBUG_VOID_RETURN;
}
/**
Bug#36326: nested transaction and select
*/
......@@ -18140,6 +18250,7 @@ static struct my_tests_st my_tests[]= {
{ "test_wl4166_2", test_wl4166_2 },
{ "test_bug38486", test_bug38486 },
{ "test_bug40365", test_bug40365 },
{ "test_bug43560", test_bug43560 },
#ifdef HAVE_QUERY_CACHE
{ "test_bug36326", test_bug36326 },
#endif
......@@ -18268,7 +18379,8 @@ int main(int argc, char **argv)
(char**) embedded_server_groups))
DIE("Can't initialize MySQL server");
client_connect(0); /* connect to server */
/* connect to server with no flags, default protocol, auto reconnect true */
mysql= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 1);
total_time= 0;
for (iter_count= 1; iter_count <= opt_count; iter_count++)
......@@ -18298,7 +18410,7 @@ int main(int argc, char **argv)
fprintf(stderr, "\n\nGiven test not found: '%s'\n", *argv);
fprintf(stderr, "See legal test names with %s -T\n\nAborting!\n",
my_progname);
client_disconnect();
client_disconnect(mysql, 1);
free_defaults(defaults_argv);
exit(1);
}
......@@ -18311,7 +18423,7 @@ int main(int argc, char **argv)
/* End of tests */
}
client_disconnect(); /* disconnect from server */
client_disconnect(mysql, 1); /* disconnect from server */
free_defaults(defaults_argv);
print_test_output();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment