Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
57ba4322
Commit
57ba4322
authored
May 20, 2009
by
Staale Smedseng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Recommit of bug 43560 after merge with mysql-5.1-bugteam
parent
182df740
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
174 additions
and
39 deletions
+174
-39
sql-common/client.c
sql-common/client.c
+44
-24
sql/sql_prepare.cc
sql/sql_prepare.cc
+3
-0
tests/mysql_client_test.c
tests/mysql_client_test.c
+127
-15
No files found.
sql-common/client.c
View file @
57ba4322
...
@@ -924,6 +924,7 @@ void end_server(MYSQL *mysql)
...
@@ -924,6 +924,7 @@ void end_server(MYSQL *mysql)
vio_delete
(
mysql
->
net
.
vio
);
vio_delete
(
mysql
->
net
.
vio
);
reset_sigpipe
(
mysql
);
reset_sigpipe
(
mysql
);
mysql
->
net
.
vio
=
0
;
/* Marker */
mysql
->
net
.
vio
=
0
;
/* Marker */
mysql_prune_stmt_list
(
mysql
);
}
}
net_end
(
&
mysql
->
net
);
net_end
(
&
mysql
->
net
);
free_old_query
(
mysql
);
free_old_query
(
mysql
);
...
@@ -2526,30 +2527,9 @@ my_bool mysql_reconnect(MYSQL *mysql)
...
@@ -2526,30 +2527,9 @@ my_bool mysql_reconnect(MYSQL *mysql)
tmp_mysql
.
reconnect
=
1
;
tmp_mysql
.
reconnect
=
1
;
tmp_mysql
.
free_me
=
mysql
->
free_me
;
tmp_mysql
.
free_me
=
mysql
->
free_me
;
/*
/* Move prepared statements (if any) over to the new mysql object */
For each stmt in mysql->stmts, move it to tmp_mysql if it is
tmp_mysql
.
stmts
=
mysql
->
stmts
;
in state MYSQL_STMT_INIT_DONE, otherwise close it.
mysql
->
stmts
=
0
;
*/
{
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
;
}
/* Don't free options as these are now used in tmp_mysql */
/* Don't free options as these are now used in tmp_mysql */
bzero
((
char
*
)
&
mysql
->
options
,
sizeof
(
mysql
->
options
));
bzero
((
char
*
)
&
mysql
->
options
,
sizeof
(
mysql
->
options
));
...
@@ -2639,6 +2619,46 @@ static void mysql_close_free(MYSQL *mysql)
...
@@ -2639,6 +2619,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
*/
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
Clear connection pointer of every statement: this is necessary
to give error on attempt to use a prepared statement of closed
to give error on attempt to use a prepared statement of closed
...
...
sql/sql_prepare.cc
View file @
57ba4322
...
@@ -2461,6 +2461,9 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
...
@@ -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
);
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
;
DBUG_VOID_RETURN
;
}
}
...
...
tests/mysql_client_test.c
View file @
57ba4322
...
@@ -103,7 +103,7 @@ if (!opt_silent) \
...
@@ -103,7 +103,7 @@ if (!opt_silent) \
static
void
print_error
(
const
char
*
msg
);
static
void
print_error
(
const
char
*
msg
);
static
void
print_st_error
(
MYSQL_STMT
*
stmt
,
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)
...
@@ -271,10 +271,20 @@ mysql_simple_prepare(MYSQL *mysql_arg, const char *query)
}
}
/* Connect to the server */
/**
Connect to the server with options given by arguments to this application,
static
void
client_connect
(
ulong
flag
)
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
;
int
rc
;
static
char
query
[
MAX_TEST_QUERY_LENGTH
];
static
char
query
[
MAX_TEST_QUERY_LENGTH
];
myheader_r
(
"client_connect"
);
myheader_r
(
"client_connect"
);
...
@@ -291,6 +301,7 @@ static void client_connect(ulong flag)
...
@@ -291,6 +301,7 @@ static void client_connect(ulong flag)
}
}
/* enable local infile, in non-binary builds often disabled by default */
/* enable local infile, in non-binary builds often disabled by default */
mysql_options
(
mysql
,
MYSQL_OPT_LOCAL_INFILE
,
0
);
mysql_options
(
mysql
,
MYSQL_OPT_LOCAL_INFILE
,
0
);
mysql_options
(
mysql
,
MYSQL_OPT_PROTOCOL
,
&
protocol
);
if
(
!
(
mysql_real_connect
(
mysql
,
opt_host
,
opt_user
,
if
(
!
(
mysql_real_connect
(
mysql
,
opt_host
,
opt_user
,
opt_password
,
opt_db
?
opt_db
:
"test"
,
opt_port
,
opt_password
,
opt_db
?
opt_db
:
"test"
,
opt_port
,
...
@@ -302,7 +313,7 @@ static void client_connect(ulong flag)
...
@@ -302,7 +313,7 @@ static void client_connect(ulong flag)
fprintf
(
stdout
,
"
\n
Check the connection options using --help or -?
\n
"
);
fprintf
(
stdout
,
"
\n
Check the connection options using --help or -?
\n
"
);
exit
(
1
);
exit
(
1
);
}
}
mysql
->
reconnect
=
1
;
mysql
->
reconnect
=
auto_reconnect
;
if
(
!
opt_silent
)
if
(
!
opt_silent
)
fprintf
(
stdout
,
"OK"
);
fprintf
(
stdout
,
"OK"
);
...
@@ -329,12 +340,14 @@ static void client_connect(ulong flag)
...
@@ -329,12 +340,14 @@ static void client_connect(ulong flag)
if
(
!
opt_silent
)
if
(
!
opt_silent
)
fprintf
(
stdout
,
"OK"
);
fprintf
(
stdout
,
"OK"
);
return
mysql
;
}
}
/* Close the connection */
/* Close the connection */
static
void
client_disconnect
()
static
void
client_disconnect
(
MYSQL
*
mysql
,
my_bool
drop_db
)
{
{
static
char
query
[
MAX_TEST_QUERY_LENGTH
];
static
char
query
[
MAX_TEST_QUERY_LENGTH
];
...
@@ -342,13 +355,16 @@ static void client_disconnect()
...
@@ -342,13 +355,16 @@ static void client_disconnect()
if
(
mysql
)
if
(
mysql
)
{
{
if
(
!
opt_silent
)
if
(
drop_db
)
fprintf
(
stdout
,
"
\n
dropping the test database '%s' ..."
,
current_db
);
{
strxmov
(
query
,
"DROP DATABASE IF EXISTS "
,
current_db
,
NullS
);
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
);
mysql_query
(
mysql
,
query
);
if
(
!
opt_silent
)
if
(
!
opt_silent
)
fprintf
(
stdout
,
"OK"
);
fprintf
(
stdout
,
"OK"
);
}
if
(
!
opt_silent
)
if
(
!
opt_silent
)
fprintf
(
stdout
,
"
\n
closing the connection ..."
);
fprintf
(
stdout
,
"
\n
closing the connection ..."
);
...
@@ -17712,6 +17728,100 @@ static void test_bug40365(void)
...
@@ -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
Bug#36326: nested transaction and select
*/
*/
...
@@ -18140,6 +18250,7 @@ static struct my_tests_st my_tests[]= {
...
@@ -18140,6 +18250,7 @@ static struct my_tests_st my_tests[]= {
{
"test_wl4166_2"
,
test_wl4166_2
},
{
"test_wl4166_2"
,
test_wl4166_2
},
{
"test_bug38486"
,
test_bug38486
},
{
"test_bug38486"
,
test_bug38486
},
{
"test_bug40365"
,
test_bug40365
},
{
"test_bug40365"
,
test_bug40365
},
{
"test_bug43560"
,
test_bug43560
},
#ifdef HAVE_QUERY_CACHE
#ifdef HAVE_QUERY_CACHE
{
"test_bug36326"
,
test_bug36326
},
{
"test_bug36326"
,
test_bug36326
},
#endif
#endif
...
@@ -18268,7 +18379,8 @@ int main(int argc, char **argv)
...
@@ -18268,7 +18379,8 @@ int main(int argc, char **argv)
(
char
**
)
embedded_server_groups
))
(
char
**
)
embedded_server_groups
))
DIE
(
"Can't initialize MySQL server"
);
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
;
total_time
=
0
;
for
(
iter_count
=
1
;
iter_count
<=
opt_count
;
iter_count
++
)
for
(
iter_count
=
1
;
iter_count
<=
opt_count
;
iter_count
++
)
...
@@ -18298,7 +18410,7 @@ int main(int argc, char **argv)
...
@@ -18298,7 +18410,7 @@ int main(int argc, char **argv)
fprintf
(
stderr
,
"
\n\n
Given test not found: '%s'
\n
"
,
*
argv
);
fprintf
(
stderr
,
"
\n\n
Given test not found: '%s'
\n
"
,
*
argv
);
fprintf
(
stderr
,
"See legal test names with %s -T
\n\n
Aborting!
\n
"
,
fprintf
(
stderr
,
"See legal test names with %s -T
\n\n
Aborting!
\n
"
,
my_progname
);
my_progname
);
client_disconnect
();
client_disconnect
(
mysql
,
1
);
free_defaults
(
defaults_argv
);
free_defaults
(
defaults_argv
);
exit
(
1
);
exit
(
1
);
}
}
...
@@ -18311,7 +18423,7 @@ int main(int argc, char **argv)
...
@@ -18311,7 +18423,7 @@ int main(int argc, char **argv)
/* End of tests */
/* End of tests */
}
}
client_disconnect
();
/* disconnect from server */
client_disconnect
(
mysql
,
1
);
/* disconnect from server */
free_defaults
(
defaults_argv
);
free_defaults
(
defaults_argv
);
print_test_output
();
print_test_output
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment