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
79e1fd8d
Commit
79e1fd8d
authored
Jan 28, 2003
by
venu@myvenu.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix leak when the client disconnects with open prep statements
parent
cb00984a
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
71 additions
and
50 deletions
+71
-50
libmysql/libmysql.c
libmysql/libmysql.c
+5
-8
sql/sql_prepare.cc
sql/sql_prepare.cc
+32
-27
tests/client_test.c
tests/client_test.c
+34
-15
No files found.
libmysql/libmysql.c
View file @
79e1fd8d
...
...
@@ -5299,14 +5299,11 @@ static my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list)
int4store
(
buff
,
stmt
->
stmt_id
);
error
=
simple_command
(
stmt
->
mysql
,
COM_CLOSE_STMT
,
buff
,
4
,
1
);
}
if
(
!
error
)
{
mysql_free_result
(
stmt
->
result
);
free_root
(
&
stmt
->
mem_root
,
MYF
(
0
));
if
(
!
skip_list
)
stmt
->
mysql
->
stmts
=
list_delete
(
stmt
->
mysql
->
stmts
,
&
stmt
->
list
);
my_free
((
gptr
)
stmt
,
MYF
(
MY_WME
));
}
mysql_free_result
(
stmt
->
result
);
free_root
(
&
stmt
->
mem_root
,
MYF
(
0
));
if
(
!
skip_list
)
stmt
->
mysql
->
stmts
=
list_delete
(
stmt
->
mysql
->
stmts
,
&
stmt
->
list
);
my_free
((
gptr
)
stmt
,
MYF
(
MY_WME
));
DBUG_RETURN
(
error
);
}
...
...
sql/sql_prepare.cc
View file @
79e1fd8d
...
...
@@ -128,7 +128,8 @@ int compare_prep_stmt(void *not_used, PREP_STMT *stmt, ulong *key)
*/
void
free_prep_stmt
(
PREP_STMT
*
stmt
,
TREE_FREE
mode
,
void
*
not_used
)
{
{
my_free
((
char
*
)
stmt
->
param
,
MYF
(
MY_ALLOW_ZERO_PTR
));
free_items
(
stmt
->
free_list
);
free_root
(
&
stmt
->
mem_root
,
MYF
(
0
));
}
...
...
@@ -319,7 +320,7 @@ static void setup_param_date(Item_param *param, uchar **pos)
uchar
*
to
=
*
pos
;
TIME
tm
;
tm
.
year
=
(
uint
)
sint2korr
(
to
);
tm
.
year
=
(
uint
)
sint2korr
(
to
);
tm
.
month
=
(
uint
)
to
[
2
];
tm
.
day
=
(
uint
)
to
[
3
];
...
...
@@ -344,44 +345,44 @@ static void setup_param_functions(Item_param *param, uchar param_type)
switch
(
param_type
)
{
case
FIELD_TYPE_TINY
:
param
->
setup_param_func
=
setup_param_tiny
;
param
->
item_result_type
=
INT_RESULT
;
param
->
item_result_type
=
INT_RESULT
;
break
;
case
FIELD_TYPE_SHORT
:
param
->
setup_param_func
=
setup_param_short
;
param
->
item_result_type
=
INT_RESULT
;
param
->
item_result_type
=
INT_RESULT
;
break
;
case
FIELD_TYPE_LONG
:
param
->
setup_param_func
=
setup_param_int32
;
param
->
item_result_type
=
INT_RESULT
;
param
->
item_result_type
=
INT_RESULT
;
break
;
case
FIELD_TYPE_LONGLONG
:
param
->
setup_param_func
=
setup_param_int64
;
param
->
item_result_type
=
INT_RESULT
;
param
->
item_result_type
=
INT_RESULT
;
break
;
case
FIELD_TYPE_FLOAT
:
param
->
setup_param_func
=
setup_param_float
;
param
->
item_result_type
=
REAL_RESULT
;
param
->
item_result_type
=
REAL_RESULT
;
break
;
case
FIELD_TYPE_DOUBLE
:
param
->
setup_param_func
=
setup_param_double
;
param
->
item_result_type
=
REAL_RESULT
;
param
->
item_result_type
=
REAL_RESULT
;
break
;
case
FIELD_TYPE_TIME
:
param
->
setup_param_func
=
setup_param_time
;
param
->
item_result_type
=
STRING_RESULT
;
param
->
item_result_type
=
STRING_RESULT
;
break
;
case
FIELD_TYPE_DATE
:
param
->
setup_param_func
=
setup_param_date
;
param
->
item_result_type
=
STRING_RESULT
;
param
->
item_result_type
=
STRING_RESULT
;
break
;
case
FIELD_TYPE_DATETIME
:
case
FIELD_TYPE_TIMESTAMP
:
param
->
setup_param_func
=
setup_param_datetime
;
param
->
item_result_type
=
STRING_RESULT
;
param
->
item_result_type
=
STRING_RESULT
;
break
;
default:
param
->
setup_param_func
=
setup_param_str
;
param
->
item_result_type
=
STRING_RESULT
;
param
->
item_result_type
=
STRING_RESULT
;
}
}
...
...
@@ -453,7 +454,7 @@ static bool mysql_test_insert_fields(PREP_STMT *stmt,
List_item
*
values
;
DBUG_ENTER
(
"mysql_test_insert_fields"
);
if
(
!
(
table
=
open_ltable
(
thd
,
table_list
,
table_list
->
lock_type
)))
if
(
!
(
table
=
open_ltable
(
thd
,
table_list
,
table_list
->
lock_type
)))
DBUG_RETURN
(
1
);
if
((
values
=
its
++
))
...
...
@@ -587,7 +588,7 @@ static bool send_prepare_results(PREP_STMT *stmt)
{
THD
*
thd
=
stmt
->
thd
;
LEX
*
lex
=
&
thd
->
lex
;
enum
enum_sql_command
sql_command
=
thd
->
lex
.
sql_command
;
enum
enum_sql_command
sql_command
=
thd
->
lex
.
sql_command
;
DBUG_ENTER
(
"send_prepare_results"
);
DBUG_PRINT
(
"enter"
,(
"command: %d, param_count: %ld"
,
sql_command
,
lex
->
param_count
));
...
...
@@ -597,7 +598,7 @@ static bool send_prepare_results(PREP_STMT *stmt)
stmt
->
free_list
=
thd
->
free_list
;
// Save items used in stmt
thd
->
free_list
=
0
;
SELECT_LEX
*
select_lex
=
&
lex
->
select_lex
;
SELECT_LEX
*
select_lex
=
&
lex
->
select_lex
;
TABLE_LIST
*
tables
=
(
TABLE_LIST
*
)
select_lex
->
table_list
.
first
;
switch
(
sql_command
)
{
...
...
@@ -682,13 +683,18 @@ static bool init_param_items(PREP_STMT *stmt)
{
List
<
Item
>
&
params
=
stmt
->
thd
->
lex
.
param_list
;
Item_param
**
to
;
if
(
!
(
stmt
->
param
=
to
=
(
Item_param
**
)
my_malloc
(
sizeof
(
Item_param
*
)
*
(
stmt
->
param_count
+
1
),
MYF
(
MY_WME
))))
return
1
;
List_iterator
<
Item
>
param_iterator
(
params
);
while
((
*
(
to
++
)
=
(
Item_param
*
)
param_iterator
++
));
if
(
!
stmt
->
param_count
)
stmt
->
param
=
(
Item_param
**
)
0
;
else
{
if
(
!
(
stmt
->
param
=
to
=
(
Item_param
**
)
my_malloc
(
sizeof
(
Item_param
*
)
*
(
stmt
->
param_count
+
1
),
MYF
(
MY_WME
))))
return
1
;
List_iterator
<
Item
>
param_iterator
(
params
);
while
((
*
(
to
++
)
=
(
Item_param
*
)
param_iterator
++
));
}
return
0
;
}
...
...
@@ -726,7 +732,7 @@ static void init_stmt_execute(PREP_STMT *stmt)
bool
mysql_stmt_prepare
(
THD
*
thd
,
char
*
packet
,
uint
packet_length
)
{
MEM_ROOT
thd_root
=
thd
->
mem_root
;
MEM_ROOT
thd_root
=
thd
->
mem_root
;
PREP_STMT
stmt
;
DBUG_ENTER
(
"mysql_stmt_prepare"
);
...
...
@@ -758,7 +764,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
err:
stmt
.
mem_root
=
stmt
.
thd
->
mem_root
;
free_prep_stmt
(
&
stmt
,
free_free
,
(
void
*
)
0
);
thd
->
mem_root
=
thd_root
;
// restore main mem_root
thd
->
mem_root
=
thd_root
;
// restore main mem_root
DBUG_RETURN
(
1
);
}
...
...
@@ -878,9 +884,8 @@ void mysql_stmt_free(THD *thd, char *packet)
send_error
(
thd
);
// Not seen by the client
DBUG_VOID_RETURN
;
}
my_free
((
char
*
)
stmt
->
param
,
MYF
(
MY_ALLOW_ZERO_PTR
));
tree_delete
(
&
thd
->
prepared_statements
,
(
void
*
)
&
stmt
,
(
void
*
)
0
);
thd
->
last_prepared_stmt
=
0
;
tree_delete
(
&
thd
->
prepared_statements
,
(
void
*
)
&
stmt_id
,
(
void
*
)
0
);
thd
->
last_prepared_stmt
=
(
PREP_STMT
*
)
0
;
DBUG_VOID_RETURN
;
}
...
...
tests/client_test.c
View file @
79e1fd8d
...
...
@@ -284,6 +284,7 @@ static void my_print_result_metadata(MYSQL_RES *result)
mysql_field_seek
(
result
,
0
);
fputc
(
'\n'
,
stdout
);
fputc
(
'\n'
,
stdout
);
field_count
=
mysql_num_fields
(
result
);
for
(
i
=
0
;
i
<
field_count
;
i
++
)
...
...
@@ -702,6 +703,7 @@ static void test_tran_bdb()
mytest
(
result
);
my_process_result_set
(
result
);
mysql_free_result
(
result
);
/* test the results now, only one row should exists */
rc
=
mysql_query
(
mysql
,
"SELECT * FROM my_demo_transaction"
);
...
...
@@ -779,6 +781,7 @@ static void test_tran_innodb()
mytest
(
result
);
my_process_result_set
(
result
);
mysql_free_result
(
result
);
/* test the results now, only one row should exists */
rc
=
mysql_query
(
mysql
,
"SELECT * FROM my_demo_transaction"
);
...
...
@@ -930,6 +933,7 @@ static void test_prepare_field_result()
param_count
=
mysql_num_fields
(
result
);
fprintf
(
stdout
,
"
\n\n
total fields: `%d` (expected: `5`)"
,
param_count
);
myassert
(
param_count
==
5
);
mysql_free_result
(
result
);
mysql_stmt_close
(
stmt
);
}
...
...
@@ -1478,7 +1482,7 @@ static void test_select_direct()
*********************************************************/
static
void
test_select_prepare
()
{
int
rc
,
count
;
int
rc
;
MYSQL_STMT
*
stmt
;
myheader
(
"test_select_prepare"
);
...
...
@@ -1511,7 +1515,8 @@ static void test_select_prepare()
rc
=
mysql_execute
(
stmt
);
mystmt
(
stmt
,
rc
);
count
=
my_process_stmt_result
(
stmt
);
myassert
(
1
==
my_process_stmt_result
(
stmt
));
mysql_stmt_close
(
stmt
);
rc
=
mysql_query
(
mysql
,
"DROP TABLE test_select"
);
myquery
(
rc
);
...
...
@@ -1540,8 +1545,7 @@ static void test_select_prepare()
rc
=
mysql_execute
(
stmt
);
mystmt
(
stmt
,
rc
);
my_process_stmt_result
(
stmt
);
myassert
(
1
==
my_process_stmt_result
(
stmt
));
mysql_stmt_close
(
stmt
);
}
...
...
@@ -1615,7 +1619,7 @@ static void test_select()
rc
=
mysql_execute
(
stmt
);
mystmt
(
stmt
,
rc
);
myassert
(
my_process_stmt_result
(
stmt
)
!=
0
);
myassert
(
my_process_stmt_result
(
stmt
)
==
1
);
mysql_stmt_close
(
stmt
);
}
...
...
@@ -1817,6 +1821,7 @@ static void test_long_data()
verify_col_data
(
"test_long_data"
,
"col1"
,
"999"
);
verify_col_data
(
"test_long_data"
,
"col2"
,
"Michael 'Monty' Widenius"
);
verify_col_data
(
"test_long_data"
,
"col3"
,
"Venu"
);
mysql_stmt_close
(
stmt
);
}
...
...
@@ -3608,8 +3613,9 @@ static void test_stmt_close()
fprintf
(
stdout
,
"
\n
mysql_close_stmt(1) returned: %d"
,
rc
);
myassert
(
rc
==
0
);
mysql_close
(
lmysql
);
/* it should free all open stmts(stmt3, stmt2) */
mysql_close
(
lmysql
);
/* it should free all open stmts(stmt3, 2 and 1) */
#if NOT_VALID
rc
=
mysql_stmt_close
(
stmt3
);
fprintf
(
stdout
,
"
\n
mysql_close_stmt(3) returned: %d"
,
rc
);
myassert
(
rc
==
1
);
...
...
@@ -3617,6 +3623,7 @@ static void test_stmt_close()
rc
=
mysql_stmt_close
(
stmt2
);
fprintf
(
stdout
,
"
\n
mysql_close_stmt(2) returned: %d"
,
rc
);
myassert
(
rc
==
1
);
#endif
count
=
100
;
bind
[
0
].
buffer
=
(
char
*
)
&
count
;
...
...
@@ -3625,6 +3632,7 @@ static void test_stmt_close()
rc
=
mysql_bind_param
(
stmt_x
,
bind
);
mystmt
(
stmt_x
,
rc
);
rc
=
mysql_execute
(
stmt_x
);
mystmt
(
stmt_x
,
rc
);
...
...
@@ -3673,7 +3681,6 @@ static void test_set_variable()
result
=
mysql_param_result
(
stmt
);
mytest_r
(
result
);
bind
[
0
].
buffer_type
=
MYSQL_TYPE_LONG
;
bind
[
0
].
buffer
=
(
char
*
)
&
select_limit
;
bind
[
0
].
is_null
=
0
;
...
...
@@ -3745,6 +3752,8 @@ static void test_insert_meta()
result
=
mysql_param_result
(
stmt
);
mytest_r
(
result
);
mysql_stmt_close
(
stmt
);
strmov
(
query
,
"INSERT INTO test_prep_insert VALUES(?,'venu',?)"
);
stmt
=
mysql_prepare
(
mysql
,
query
,
strlen
(
query
));
mystmt_init
(
stmt
);
...
...
@@ -3807,6 +3816,8 @@ static void test_update_meta()
result
=
mysql_param_result
(
stmt
);
mytest_r
(
result
);
mysql_stmt_close
(
stmt
);
strmov
(
query
,
"UPDATE test_prep_update SET col1=?, col2='venu' WHERE col3=?"
);
stmt
=
mysql_prepare
(
mysql
,
query
,
strlen
(
query
));
mystmt_init
(
stmt
);
...
...
@@ -3901,7 +3912,7 @@ static void test_select_meta()
field
=
mysql_fetch_field
(
result
);
mytest_r
(
field
);
n
mysql_free_result
(
result
);
mysql_stmt_close
(
stmt
);
}
...
...
@@ -4023,7 +4034,6 @@ static void test_multi_stmt()
bind
[
1
].
length
=
&
length
[
1
];
bind
[
1
].
is_null
=
&
is_null
[
0
];
rc
=
mysql_bind_param
(
stmt
,
bind
);
mystmt
(
stmt
,
rc
);
...
...
@@ -4592,7 +4602,7 @@ static void test_store_result2()
rc
=
mysql_bind_result
(
stmt
,
bind
);
mystmt
(
stmt
,
rc
);
nData
=
10
;
length
=
0
;
rc
=
mysql_execute
(
stmt
);
mystmt
(
stmt
,
rc
);
...
...
@@ -4626,7 +4636,6 @@ static void test_store_result2()
rc
=
mysql_fetch
(
stmt
);
myassert
(
rc
==
MYSQL_NO_DATA
);
mysql_stmt_close
(
stmt
);
}
...
...
@@ -5239,14 +5248,18 @@ int main(int argc, char **argv)
{
MY_INIT
(
argv
[
0
]);
get_options
(
argc
,
argv
);
time_t
start_time
,
end_time
;
double
total_time
=
0
;
client_connect
();
/* connect to server */
for
(
iter_count
=
1
;
iter_count
<=
opt_count
;
iter_count
++
)
{
/* Start of tests */
test_count
=
0
;
test_count
=
1
;
start_time
=
time
((
time_t
*
)
0
);
test_fetch_null
();
/* to fetch null data */
test_fetch_date
();
/* to fetch date,time and timestamp */
test_fetch_str
();
/* to fetch string to all types */
...
...
@@ -5319,14 +5332,20 @@ int main(int argc, char **argv)
test_manual_sample
();
/* sample in the manual */
test_pure_coverage
();
/* keep pure coverage happy */
test_buffers
();
/* misc buffer handling */
end_time
=
time
((
time_t
*
)
0
);
total_time
+=
difftime
(
end_time
,
start_time
);
/* End of tests */
}
client_disconnect
();
/* disconnect from server */
fprintf
(
stdout
,
"
\n\n
All '%d' tests were successful (in '%d' iterations)"
,
test_count
-
1
,
opt_count
);
fprintf
(
stdout
,
"
\n
Total execution time: %g SECS"
,
total_time
);
if
(
opt_count
>
1
)
fprintf
(
stdout
,
" (Avg: %g SECS)"
,
total_time
/
opt_count
);
fprintf
(
stdout
,
"
\n
SUCCESS !!!
\n
"
);
fprintf
(
stdout
,
"
\n
\n
SUCCESS !!!
\n
"
);
return
(
0
);
}
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