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
0830a3be
Commit
0830a3be
authored
Jul 15, 2009
by
Davi Arnaut
Browse files
Options
Browse Files
Download
Plain Diff
Bug#44495: Prepared Statement: CALL p(<x>) - `thd->protocol == &thd->protocol_text' failed
Merge Konstantin's patch and add a test case.
parents
bb4f24bf
e601194c
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
77 additions
and
18 deletions
+77
-18
sql/sql_prepare.cc
sql/sql_prepare.cc
+25
-18
tests/mysql_client_test.c
tests/mysql_client_test.c
+52
-0
No files found.
sql/sql_prepare.cc
View file @
0830a3be
...
@@ -127,12 +127,12 @@ class Prepared_statement: public Statement
...
@@ -127,12 +127,12 @@ class Prepared_statement: public Statement
public:
public:
enum
flag_values
enum
flag_values
{
{
IS_IN_USE
=
1
IS_IN_USE
=
1
,
IS_SQL_PREPARE
=
2
};
};
THD
*
thd
;
THD
*
thd
;
Select_fetch_protocol_binary
result
;
Select_fetch_protocol_binary
result
;
Protocol
*
protocol
;
Item_param
**
param_array
;
Item_param
**
param_array
;
uint
param_count
;
uint
param_count
;
uint
last_errno
;
uint
last_errno
;
...
@@ -148,7 +148,7 @@ public:
...
@@ -148,7 +148,7 @@ public:
List
<
LEX_STRING
>&
varnames
,
List
<
LEX_STRING
>&
varnames
,
String
*
expanded_query
);
String
*
expanded_query
);
public:
public:
Prepared_statement
(
THD
*
thd_arg
,
Protocol
*
protocol_arg
);
Prepared_statement
(
THD
*
thd_arg
);
virtual
~
Prepared_statement
();
virtual
~
Prepared_statement
();
void
setup_set_params
();
void
setup_set_params
();
virtual
Query_arena
::
Type
type
()
const
;
virtual
Query_arena
::
Type
type
()
const
;
...
@@ -156,7 +156,8 @@ public:
...
@@ -156,7 +156,8 @@ public:
bool
set_name
(
LEX_STRING
*
name
);
bool
set_name
(
LEX_STRING
*
name
);
inline
void
close_cursor
()
{
delete
cursor
;
cursor
=
0
;
}
inline
void
close_cursor
()
{
delete
cursor
;
cursor
=
0
;
}
inline
bool
is_in_use
()
{
return
flags
&
(
uint
)
IS_IN_USE
;
}
inline
bool
is_in_use
()
{
return
flags
&
(
uint
)
IS_IN_USE
;
}
inline
bool
is_protocol_text
()
const
{
return
protocol
==
&
thd
->
protocol_text
;
}
inline
bool
is_sql_prepare
()
const
{
return
flags
&
(
uint
)
IS_SQL_PREPARE
;
}
void
set_sql_prepare
()
{
flags
|=
(
uint
)
IS_SQL_PREPARE
;
}
bool
prepare
(
const
char
*
packet
,
uint
packet_length
);
bool
prepare
(
const
char
*
packet
,
uint
packet_length
);
bool
execute_loop
(
String
*
expanded_query
,
bool
execute_loop
(
String
*
expanded_query
,
bool
open_cursor
,
bool
open_cursor
,
...
@@ -1358,7 +1359,7 @@ static int mysql_test_select(Prepared_statement *stmt,
...
@@ -1358,7 +1359,7 @@ static int mysql_test_select(Prepared_statement *stmt,
*/
*/
if
(
unit
->
prepare
(
thd
,
0
,
0
))
if
(
unit
->
prepare
(
thd
,
0
,
0
))
goto
error
;
goto
error
;
if
(
!
lex
->
describe
&&
!
stmt
->
is_
protocol_text
())
if
(
!
lex
->
describe
&&
!
stmt
->
is_
sql_prepare
())
{
{
/* Make copy of item list, as change_columns may change it */
/* Make copy of item list, as change_columns may change it */
List
<
Item
>
fields
(
lex
->
select_lex
.
item_list
);
List
<
Item
>
fields
(
lex
->
select_lex
.
item_list
);
...
@@ -1988,7 +1989,7 @@ static bool check_prepared_statement(Prepared_statement *stmt)
...
@@ -1988,7 +1989,7 @@ static bool check_prepared_statement(Prepared_statement *stmt)
break
;
break
;
}
}
if
(
res
==
0
)
if
(
res
==
0
)
DBUG_RETURN
(
stmt
->
is_
protocol_text
()
?
DBUG_RETURN
(
stmt
->
is_
sql_prepare
()
?
FALSE
:
(
send_prep_stmt
(
stmt
,
0
)
||
thd
->
protocol
->
flush
()));
FALSE
:
(
send_prep_stmt
(
stmt
,
0
)
||
thd
->
protocol
->
flush
()));
error:
error:
DBUG_RETURN
(
TRUE
);
DBUG_RETURN
(
TRUE
);
...
@@ -2058,6 +2059,7 @@ static bool init_param_array(Prepared_statement *stmt)
...
@@ -2058,6 +2059,7 @@ static bool init_param_array(Prepared_statement *stmt)
void
mysqld_stmt_prepare
(
THD
*
thd
,
const
char
*
packet
,
uint
packet_length
)
void
mysqld_stmt_prepare
(
THD
*
thd
,
const
char
*
packet
,
uint
packet_length
)
{
{
Protocol
*
save_protocol
=
thd
->
protocol
;
Prepared_statement
*
stmt
;
Prepared_statement
*
stmt
;
bool
error
;
bool
error
;
DBUG_ENTER
(
"mysqld_stmt_prepare"
);
DBUG_ENTER
(
"mysqld_stmt_prepare"
);
...
@@ -2067,7 +2069,7 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length)
...
@@ -2067,7 +2069,7 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length)
/* First of all clear possible warnings from the previous command */
/* First of all clear possible warnings from the previous command */
mysql_reset_thd_for_next_command
(
thd
);
mysql_reset_thd_for_next_command
(
thd
);
if
(
!
(
stmt
=
new
Prepared_statement
(
thd
,
&
thd
->
protocol_binary
)))
if
(
!
(
stmt
=
new
Prepared_statement
(
thd
)))
DBUG_VOID_RETURN
;
/* out of memory: error is set in Sql_alloc */
DBUG_VOID_RETURN
;
/* out of memory: error is set in Sql_alloc */
if
(
thd
->
stmt_map
.
insert
(
thd
,
stmt
))
if
(
thd
->
stmt_map
.
insert
(
thd
,
stmt
))
...
@@ -2084,6 +2086,8 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length)
...
@@ -2084,6 +2086,8 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length)
sp_cache_flush_obsolete
(
&
thd
->
sp_proc_cache
);
sp_cache_flush_obsolete
(
&
thd
->
sp_proc_cache
);
sp_cache_flush_obsolete
(
&
thd
->
sp_func_cache
);
sp_cache_flush_obsolete
(
&
thd
->
sp_func_cache
);
thd
->
protocol
=
&
thd
->
protocol_binary
;
if
(
!
(
specialflag
&
SPECIAL_NO_PRIOR
))
if
(
!
(
specialflag
&
SPECIAL_NO_PRIOR
))
my_pthread_setprio
(
pthread_self
(),
QUERY_PRIOR
);
my_pthread_setprio
(
pthread_self
(),
QUERY_PRIOR
);
...
@@ -2097,6 +2101,9 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length)
...
@@ -2097,6 +2101,9 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length)
/* Statement map deletes statement on erase */
/* Statement map deletes statement on erase */
thd
->
stmt_map
.
erase
(
stmt
);
thd
->
stmt_map
.
erase
(
stmt
);
}
}
thd
->
protocol
=
save_protocol
;
/* check_prepared_statemnt sends the metadata packet in case of success */
/* check_prepared_statemnt sends the metadata packet in case of success */
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -2229,7 +2236,6 @@ void mysql_sql_stmt_prepare(THD *thd)
...
@@ -2229,7 +2236,6 @@ void mysql_sql_stmt_prepare(THD *thd)
const
char
*
query
;
const
char
*
query
;
uint
query_len
=
0
;
uint
query_len
=
0
;
DBUG_ENTER
(
"mysql_sql_stmt_prepare"
);
DBUG_ENTER
(
"mysql_sql_stmt_prepare"
);
DBUG_ASSERT
(
thd
->
protocol
==
&
thd
->
protocol_text
);
if
((
stmt
=
(
Prepared_statement
*
)
thd
->
stmt_map
.
find_by_name
(
name
)))
if
((
stmt
=
(
Prepared_statement
*
)
thd
->
stmt_map
.
find_by_name
(
name
)))
{
{
...
@@ -2247,11 +2253,13 @@ void mysql_sql_stmt_prepare(THD *thd)
...
@@ -2247,11 +2253,13 @@ void mysql_sql_stmt_prepare(THD *thd)
}
}
if
(
!
(
query
=
get_dynamic_sql_string
(
lex
,
&
query_len
))
||
if
(
!
(
query
=
get_dynamic_sql_string
(
lex
,
&
query_len
))
||
!
(
stmt
=
new
Prepared_statement
(
thd
,
&
thd
->
protocol_text
)))
!
(
stmt
=
new
Prepared_statement
(
thd
)))
{
{
DBUG_VOID_RETURN
;
/* out of memory */
DBUG_VOID_RETURN
;
/* out of memory */
}
}
stmt
->
set_sql_prepare
();
/* Set the name first, insert should know that this statement has a name */
/* Set the name first, insert should know that this statement has a name */
if
(
stmt
->
set_name
(
name
))
if
(
stmt
->
set_name
(
name
))
{
{
...
@@ -2431,6 +2439,7 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
...
@@ -2431,6 +2439,7 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
String
expanded_query
;
String
expanded_query
;
uchar
*
packet_end
=
packet
+
packet_length
;
uchar
*
packet_end
=
packet
+
packet_length
;
Prepared_statement
*
stmt
;
Prepared_statement
*
stmt
;
Protocol
*
save_protocol
=
thd
->
protocol
;
bool
open_cursor
;
bool
open_cursor
;
DBUG_ENTER
(
"mysqld_stmt_execute"
);
DBUG_ENTER
(
"mysqld_stmt_execute"
);
...
@@ -2458,7 +2467,9 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
...
@@ -2458,7 +2467,9 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
open_cursor
=
test
(
flags
&
(
ulong
)
CURSOR_TYPE_READ_ONLY
);
open_cursor
=
test
(
flags
&
(
ulong
)
CURSOR_TYPE_READ_ONLY
);
thd
->
protocol
=
&
thd
->
protocol_binary
;
stmt
->
execute_loop
(
&
expanded_query
,
open_cursor
,
packet
,
packet_end
);
stmt
->
execute_loop
(
&
expanded_query
,
open_cursor
,
packet
,
packet_end
);
thd
->
protocol
=
save_protocol
;
/* Close connection socket; for use with client testing (Bug#43560). */
/* Close connection socket; for use with client testing (Bug#43560). */
DBUG_EXECUTE_IF
(
"close_conn_after_stmt_execute"
,
vio_close
(
thd
->
net
.
vio
););
DBUG_EXECUTE_IF
(
"close_conn_after_stmt_execute"
,
vio_close
(
thd
->
net
.
vio
););
...
@@ -2814,12 +2825,11 @@ Select_fetch_protocol_binary::send_data(List<Item> &fields)
...
@@ -2814,12 +2825,11 @@ Select_fetch_protocol_binary::send_data(List<Item> &fields)
Prepared_statement
Prepared_statement
****************************************************************************/
****************************************************************************/
Prepared_statement
::
Prepared_statement
(
THD
*
thd_arg
,
Protocol
*
protocol_arg
)
Prepared_statement
::
Prepared_statement
(
THD
*
thd_arg
)
:
Statement
(
NULL
,
&
main_mem_root
,
:
Statement
(
NULL
,
&
main_mem_root
,
INITIALIZED
,
++
thd_arg
->
statement_id_counter
),
INITIALIZED
,
++
thd_arg
->
statement_id_counter
),
thd
(
thd_arg
),
thd
(
thd_arg
),
result
(
thd_arg
),
result
(
thd_arg
),
protocol
(
protocol_arg
),
param_array
(
0
),
param_array
(
0
),
param_count
(
0
),
param_count
(
0
),
last_errno
(
0
),
last_errno
(
0
),
...
@@ -3288,7 +3298,9 @@ Prepared_statement::reprepare()
...
@@ -3288,7 +3298,9 @@ Prepared_statement::reprepare()
bool
cur_db_changed
;
bool
cur_db_changed
;
bool
error
;
bool
error
;
Prepared_statement
copy
(
thd
,
&
thd
->
protocol_text
);
Prepared_statement
copy
(
thd
);
copy
.
set_sql_prepare
();
/* To suppress sending metadata to the client. */
status_var_increment
(
thd
->
status_var
.
com_stmt_reprepare
);
status_var_increment
(
thd
->
status_var
.
com_stmt_reprepare
);
...
@@ -3346,7 +3358,7 @@ bool Prepared_statement::validate_metadata(Prepared_statement *copy)
...
@@ -3346,7 +3358,7 @@ bool Prepared_statement::validate_metadata(Prepared_statement *copy)
return FALSE -- the metadata of the original SELECT,
return FALSE -- the metadata of the original SELECT,
if any, has not been sent to the client.
if any, has not been sent to the client.
*/
*/
if
(
is_
protocol_text
()
||
lex
->
describe
)
if
(
is_
sql_prepare
()
||
lex
->
describe
)
return
FALSE
;
return
FALSE
;
if
(
lex
->
select_lex
.
item_list
.
elements
!=
if
(
lex
->
select_lex
.
item_list
.
elements
!=
...
@@ -3409,7 +3421,6 @@ Prepared_statement::swap_prepared_statement(Prepared_statement *copy)
...
@@ -3409,7 +3421,6 @@ Prepared_statement::swap_prepared_statement(Prepared_statement *copy)
DBUG_ASSERT
(
thd
==
copy
->
thd
);
DBUG_ASSERT
(
thd
==
copy
->
thd
);
last_error
[
0
]
=
'\0'
;
last_error
[
0
]
=
'\0'
;
last_errno
=
0
;
last_errno
=
0
;
/* Do not swap protocols, the copy always has protocol_text */
}
}
...
@@ -3550,8 +3561,6 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
...
@@ -3550,8 +3561,6 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
thd
->
stmt_arena
=
this
;
thd
->
stmt_arena
=
this
;
reinit_stmt_before_use
(
thd
,
lex
);
reinit_stmt_before_use
(
thd
,
lex
);
thd
->
protocol
=
protocol
;
/* activate stmt protocol */
/* Go! */
/* Go! */
if
(
open_cursor
)
if
(
open_cursor
)
...
@@ -3582,8 +3591,6 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
...
@@ -3582,8 +3591,6 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
if
(
cur_db_changed
)
if
(
cur_db_changed
)
mysql_change_db
(
thd
,
&
saved_cur_db_name
,
TRUE
);
mysql_change_db
(
thd
,
&
saved_cur_db_name
,
TRUE
);
thd
->
protocol
=
&
thd
->
protocol_text
;
/* use normal protocol */
/* Assert that if an error, no cursor is open */
/* Assert that if an error, no cursor is open */
DBUG_ASSERT
(
!
(
error
&&
cursor
));
DBUG_ASSERT
(
!
(
error
&&
cursor
));
...
...
tests/mysql_client_test.c
View file @
0830a3be
...
@@ -17940,6 +17940,57 @@ static void test_bug41078(void)
...
@@ -17940,6 +17940,57 @@ static void test_bug41078(void)
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
/**
Bug#44495: Prepared Statement:
CALL p(<x>) - `thd->protocol == &thd->protocol_text' failed
*/
static
void
test_bug44495
()
{
int
rc
;
MYSQL
con
;
MYSQL_STMT
*
stmt
;
DBUG_ENTER
(
"test_bug44495"
);
myheader
(
"test_44495"
);
rc
=
mysql_query
(
mysql
,
"DROP PROCEDURE IF EXISTS p1"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"CREATE PROCEDURE p1(IN arg VARCHAR(25))"
" BEGIN SET @stmt = CONCAT('SELECT
\"
', arg, '
\"
');"
" PREPARE ps1 FROM @stmt;"
" EXECUTE ps1;"
" DROP PREPARE ps1;"
"END;"
);
myquery
(
rc
);
DIE_UNLESS
(
mysql_init
(
&
con
));
DIE_UNLESS
(
mysql_real_connect
(
&
con
,
opt_host
,
opt_user
,
opt_password
,
current_db
,
opt_port
,
opt_unix_socket
,
CLIENT_MULTI_RESULTS
));
stmt
=
mysql_simple_prepare
(
&
con
,
"CALL p1('abc')"
);
check_stmt
(
stmt
);
rc
=
mysql_stmt_execute
(
stmt
);
check_execute
(
stmt
,
rc
);
rc
=
my_process_stmt_result
(
stmt
);
DIE_UNLESS
(
rc
==
1
);
mysql_stmt_close
(
stmt
);
mysql_close
(
&
con
);
rc
=
mysql_query
(
mysql
,
"DROP PROCEDURE p1"
);
myquery
(
rc
);
DBUG_VOID_RETURN
;
}
/*
/*
Read and parse arguments and MySQL options from my.cnf
Read and parse arguments and MySQL options from my.cnf
*/
*/
...
@@ -18255,6 +18306,7 @@ static struct my_tests_st my_tests[]= {
...
@@ -18255,6 +18306,7 @@ static struct my_tests_st my_tests[]= {
{
"test_bug36326"
,
test_bug36326
},
{
"test_bug36326"
,
test_bug36326
},
#endif
#endif
{
"test_bug41078"
,
test_bug41078
},
{
"test_bug41078"
,
test_bug41078
},
{
"test_bug44495"
,
test_bug44495
},
{
0
,
0
}
{
0
,
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