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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
b74c43f4
Commit
b74c43f4
authored
Nov 22, 2002
by
venu@myvenu.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
protocol fixups
parent
5601da7a
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
397 additions
and
272 deletions
+397
-272
libmysql/errmsg.c
libmysql/errmsg.c
+3
-3
libmysql/libmysql.c
libmysql/libmysql.c
+188
-101
libmysql/libmysql.def
libmysql/libmysql.def
+18
-2
sql/item.cc
sql/item.cc
+6
-11
sql/item.h
sql/item.h
+7
-6
sql/mysql_priv.h
sql/mysql_priv.h
+1
-1
sql/sql_class.h
sql/sql_class.h
+1
-2
sql/sql_error.cc
sql/sql_error.cc
+1
-1
sql/sql_prepare.cc
sql/sql_prepare.cc
+172
-145
No files found.
libmysql/errmsg.c
View file @
b74c43f4
...
...
@@ -58,7 +58,7 @@ const char *client_errors[]=
"No parameters exists in the statement"
,
"Invalid parameter number"
,
"Can't send long data for non string or binary data types (parameter: %d)"
,
"Using
not
supported parameter type: %d (parameter: %d)"
"Using
un
supported parameter type: %d (parameter: %d)"
"Shared memory (%lu)"
,
"Can't open shared memory. Request event don't create (%lu)"
,
"Can't open shared memory. Answer event don't create (%lu)"
,
...
...
@@ -111,7 +111,7 @@ const char *client_errors[]=
"No parameters exists in the statement"
,
"Invalid parameter number"
,
"Can't send long data for non string or binary data types (parameter: %d)"
,
"Using
not
supported parameter type: %d (parameter: %d)"
"Using
un
supported parameter type: %d (parameter: %d)"
"Shared memory (%lu)"
,
"Can't open shared memory. Request event don't create (%lu)"
,
"Can't open shared memory. Answer event don't create (%lu)"
,
...
...
@@ -162,7 +162,7 @@ const char *client_errors[]=
"No parameters exists in the statement"
,
"Invalid parameter number"
,
"Can't send long data for non string or binary data types (parameter: %d)"
,
"Using
not
supported parameter type: %d (parameter: %d)"
"Using
un
supported parameter type: %d (parameter: %d)"
"Shared memory (%lu)"
,
"Can't open shared memory. Request event don't create (%lu)"
,
"Can't open shared memory. Answer event don't create (%lu)"
,
...
...
libmysql/libmysql.c
View file @
b74c43f4
...
...
@@ -927,7 +927,8 @@ static const char *default_options[]=
"character-sets-dir"
,
"default-character-set"
,
"interactive-timeout"
,
"connect-timeout"
,
"local-infile"
,
"disable-local-infile"
,
"replication-probe"
,
"enable-reads-from-master"
,
"repl-parse-query"
,
"ssl-cipher"
,
"protocol"
,
"shared_memory_base_name"
,
"ssl-cipher"
,
"protocol"
,
"shared_memory_base_name"
,
NullS
};
...
...
@@ -1736,11 +1737,10 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
Free strings in the SSL structure and clear 'use_ssl' flag.
NB! Errors are not reported until you do mysql_real_connect.
**************************************************************************/
static
void
mysql_ssl_free
(
MYSQL
*
mysql
__attribute__
((
unused
)))
{
#ifdef HAVE_OPENS
S
L
#ifdef HAVE_OPENS
L
L
my_free
(
mysql
->
options
.
ssl_key
,
MYF
(
MY_ALLOW_ZERO_PTR
));
my_free
(
mysql
->
options
.
ssl_cert
,
MYF
(
MY_ALLOW_ZERO_PTR
));
my_free
(
mysql
->
options
.
ssl_ca
,
MYF
(
MY_ALLOW_ZERO_PTR
));
...
...
@@ -1754,7 +1754,7 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused)))
mysql
->
options
.
ssl_cipher
=
0
;
mysql
->
options
.
use_ssl
=
FALSE
;
mysql
->
connector_fd
=
0
;
#endif
/* HAVE_OPENS
S
L */
#endif
/* HAVE_OPENS
L
L */
}
/**************************************************************************
...
...
@@ -2567,7 +2567,7 @@ my_bool STDCALL mysql_read_query_result(MYSQL *mysql)
{
mysql
->
affected_rows
=
net_field_length_ll
(
&
pos
);
mysql
->
insert_id
=
net_field_length_ll
(
&
pos
);
if
(
mysql
->
server_capabilities
&
CLIENT_PROTOCOL_41
)
if
(
protocol_41
(
mysql
)
)
{
mysql
->
server_status
=
uint2korr
(
pos
);
pos
+=
2
;
mysql
->
warning_count
=
uint2korr
(
pos
);
pos
+=
2
;
...
...
@@ -3650,10 +3650,10 @@ MYSQL_STMT *STDCALL
mysql_prepare
(
MYSQL
*
mysql
,
const
char
*
query
,
ulong
length
)
{
MYSQL_STMT
*
stmt
;
DBUG_ENTER
(
"mysql_
real_
prepare"
);
DBUG_ENTER
(
"mysql_prepare"
);
DBUG_ASSERT
(
mysql
!=
0
);
#ifdef
EXTRA_CHECK
_ARGUMENTS
#ifdef
CHECK_EXTRA
_ARGUMENTS
if
(
!
query
)
{
set_mysql_error
(
mysql
,
CR_NULL_POINTER
);
...
...
@@ -3674,7 +3674,6 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length)
mysql_stmt_close
(
stmt
);
DBUG_RETURN
(
0
);
}
stmt
->
state
=
MY_ST_PREPARE
;
init_alloc_root
(
&
stmt
->
mem_root
,
8192
,
0
);
if
(
read_prepare_result
(
mysql
,
stmt
))
...
...
@@ -3682,7 +3681,7 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length)
mysql_stmt_close
(
stmt
);
DBUG_RETURN
(
0
);
}
stmt
->
state
=
MY_ST_PREPARE
;
stmt
->
mysql
=
mysql
;
DBUG_PRINT
(
"info"
,
(
"Parameter count: %ld"
,
stmt
->
param_count
));
DBUG_RETURN
(
stmt
);
...
...
@@ -3819,7 +3818,7 @@ static void store_param_str(NET *net, MYSQL_BIND *param)
ulong
length
=
*
param
->
length
;
char
*
to
=
(
char
*
)
net_store_length
((
char
*
)
net
->
write_pos
,
length
);
memcpy
(
to
,
param
->
buffer
,
length
);
net
->
write_pos
+=
length
;
net
->
write_pos
=
to
+
length
;
}
...
...
@@ -3853,17 +3852,19 @@ static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param)
MYSQL
*
mysql
=
stmt
->
mysql
;
NET
*
net
=
&
mysql
->
net
;
DBUG_ENTER
(
"store_param"
);
DBUG_PRINT
(
"enter"
,(
"type
: %d, buffer :%lx
"
,
param
->
buffer_type
,
param
->
buffer
));
DBUG_PRINT
(
"enter"
,(
"type
: %d, buffer:%lx, length: %d
"
,
param
->
buffer_type
,
param
->
buffer
?
param
->
buffer
:
"0"
,
*
param
->
length
));
/* Allocate for worst case (long string) */
if
((
my_realloc_str
(
net
,
9
+
*
param
->
length
)))
return
1
;
if
(
!
param
->
buffer
)
if
(
param
->
is_null
||
param
->
buffer_type
==
MYSQL_TYPE_NULL
)
store_param_null
(
net
,
param
);
else
(
*
param
->
store_param_func
)(
net
,
param
);
{
/* Allocate for worst case (long string) */
if
((
my_realloc_str
(
net
,
9
+
*
param
->
length
)))
DBUG_RETURN
(
1
);
(
*
param
->
store_param_func
)(
net
,
param
);
}
DBUG_RETURN
(
0
);
}
...
...
@@ -3875,13 +3876,13 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length)
{
MYSQL
*
mysql
=
stmt
->
mysql
;
NET
*
net
=
&
mysql
->
net
;
char
buff
[
4
];
char
buff
[
MYSQL_STMT_HEADER
];
DBUG_ENTER
(
"execute"
);
DBUG_PRINT
(
"enter"
,(
"packet: %s, length :%d"
,
packet
?
packet
:
" "
,
length
));
mysql
->
last_used_con
=
mysql
;
int4store
(
buff
,
stmt
->
stmt_id
);
/* Send stmt id to server */
if
(
advanced_command
(
mysql
,
COM_EXECUTE
,
buff
,
sizeof
(
buff
)
,
packet
,
if
(
advanced_command
(
mysql
,
COM_EXECUTE
,
buff
,
MYSQL_STMT_HEADER
,
packet
,
length
,
1
)
||
mysql_read_query_result
(
mysql
))
{
...
...
@@ -3889,12 +3890,14 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length)
DBUG_RETURN
(
1
);
}
stmt
->
state
=
MY_ST_EXECUTE
;
if
(
stmt
->
bind
)
mysql_free_result
(
stmt
->
result
);
#if USED_IN_FETCH
if
(
stmt
->
res_buffers
)
/* Result buffers exists, cache results */
{
mysql_free_result
(
stmt
->
result
);
stmt
->
result
=
mysql_store_result
(
mysql
);
}
#endif
DBUG_RETURN
(
0
);
}
...
...
@@ -3905,8 +3908,6 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length)
int
STDCALL
mysql_execute
(
MYSQL_STMT
*
stmt
)
{
ulong
length
;
uint
null_count
;
DBUG_ENTER
(
"mysql_execute"
);
if
(
stmt
->
state
==
MY_ST_UNKNOWN
)
...
...
@@ -3920,14 +3921,18 @@ int STDCALL mysql_execute(MYSQL_STMT *stmt)
NET
*
net
=
&
stmt
->
mysql
->
net
;
MYSQL_BIND
*
param
,
*
param_end
;
char
*
param_data
;
ulong
length
;
uint
null_count
;
my_bool
result
;
if
(
!
stmt
->
params
)
#ifdef CHECK_EXTRA_ARGUMENTS
if
(
!
stmt
->
param_buffers
)
{
/* Parameters exists, but no bound buffers */
set_stmt_error
(
stmt
,
CR_NOT_ALL_PARAMS_BOUND
);
DBUG_RETURN
(
1
);
}
#endif
net_clear
(
net
);
/* Sets net->write_pos */
/* Reserve place for null-marker bytes */
null_count
=
(
stmt
->
param_count
+
7
)
/
8
;
...
...
@@ -3936,10 +3941,9 @@ int STDCALL mysql_execute(MYSQL_STMT *stmt)
param_end
=
stmt
->
params
+
stmt
->
param_count
;
/* In case if buffers (type) altered, indicate to server */
*
(
net
->
write_pos
)
++=
(
uchar
)
stmt
->
types_supplied
;
if
(
!
stmt
->
types_supplied
)
*
(
net
->
write_pos
)
++=
(
uchar
)
stmt
->
send_types_to_server
;
if
(
stmt
->
send_types_to_server
)
{
stmt
->
types_supplied
=
1
;
/*
Store types of parameters in first in first package
that is sent to the server.
...
...
@@ -3961,13 +3965,14 @@ int STDCALL mysql_execute(MYSQL_STMT *stmt)
}
length
=
(
ulong
)
(
net
->
write_pos
-
net
->
buff
);
/* TODO: Look into avoding the following memdup */
if
(
!
(
param_data
=
my_memdup
(
(
byte
*
)
net
->
buff
,
length
,
MYF
(
0
))))
if
(
!
(
param_data
=
my_memdup
(
net
->
buff
,
length
,
MYF
(
0
))))
{
set_stmt_error
(
stmt
,
CR_OUT_OF_MEMORY
);
DBUG_RETURN
(
1
);
}
net
->
write_pos
=
net
->
buff
;
/* Reset for net_write() */
result
=
execute
(
stmt
,
param_data
,
length
);
stmt
->
send_types_to_server
=
0
;
my_free
(
param_data
,
MYF
(
MY_WME
));
DBUG_RETURN
(
result
);
}
...
...
@@ -4030,6 +4035,7 @@ my_bool STDCALL mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind)
param
->
param_number
);
DBUG_RETURN
(
1
);
}
/*
If param->length is not given, change it to point to bind_length.
This way we can always use *param->length to get the length of data
...
...
@@ -4039,6 +4045,9 @@ my_bool STDCALL mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind)
/* Setup data copy functions for the different supported types */
switch
(
param
->
buffer_type
)
{
case
MYSQL_TYPE_NULL
:
param
->
is_null
=
1
;
break
;
case
MYSQL_TYPE_TINY
:
param
->
bind_length
=
1
;
param
->
store_param_func
=
store_param_tinyint
;
...
...
@@ -4060,12 +4069,13 @@ my_bool STDCALL mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind)
param
->
store_param_func
=
store_param_float
;
break
;
case
MYSQL_TYPE_DOUBLE
:
param
->
bind_length
=
4
;
param
->
bind_length
=
8
;
param
->
store_param_func
=
store_param_double
;
break
;
case
MYSQL_TYPE_TINY_BLOB
:
case
MYSQL_TYPE_MEDIUM_BLOB
:
case
MYSQL_TYPE_LONG_BLOB
:
case
MYSQL_TYPE_BLOB
:
case
MYSQL_TYPE_VAR_STRING
:
case
MYSQL_TYPE_STRING
:
param
->
bind_length
=
param
->
buffer_length
;
...
...
@@ -4078,7 +4088,8 @@ my_bool STDCALL mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind)
}
}
/* We have to send/resendtype information to MySQL */
stmt
->
types_supplied
=
0
;
stmt
->
send_types_to_server
=
1
;
stmt
->
param_buffers
=
1
;
DBUG_RETURN
(
0
);
}
...
...
@@ -4152,6 +4163,73 @@ mysql_send_long_data(MYSQL_STMT *stmt, uint param_number,
Fetch-bind related implementations
*********************************************************************/
/****************************************************************************
Functions to fetch data to application buffers
All functions has the following characteristics:
SYNOPSIS
fetch_result_xxx()
param MySQL bind param
row Row value
RETURN VALUES
0 ok
1 Error (Can't alloc net->buffer)
****************************************************************************/
static
void
fetch_result_tinyint
(
MYSQL_BIND
*
param
,
uchar
**
row
)
{
*
param
->
buffer
=
(
uchar
)
**
row
;
*
row
++
;
}
static
void
fetch_result_short
(
MYSQL_BIND
*
param
,
uchar
**
row
)
{
short
value
=
*
(
short
*
)
row
;
int2store
(
param
->
buffer
,
value
);
*
row
+=
2
;
}
static
void
fetch_result_int32
(
MYSQL_BIND
*
param
,
uchar
**
row
)
{
int32
value
=
*
(
int32
*
)
row
;
int4store
(
param
->
buffer
,
value
);
*
row
+=
4
;
}
static
void
fetch_result_int64
(
MYSQL_BIND
*
param
,
uchar
**
row
)
{
longlong
value
=
*
(
longlong
*
)
row
;
int8store
(
param
->
buffer
,
value
);
*
row
+=
8
;
}
static
void
fetch_result_float
(
MYSQL_BIND
*
param
,
uchar
**
row
)
{
float
value
;
float4get
(
value
,
*
row
);
float4store
(
param
->
buffer
,
*
row
);
*
row
+=
4
;
}
static
void
fetch_result_double
(
MYSQL_BIND
*
param
,
uchar
**
row
)
{
double
value
;
float8get
(
value
,
*
row
);
float8store
(
param
->
buffer
,
value
);
*
row
+=
8
;
}
static
void
fetch_result_str
(
MYSQL_BIND
*
param
,
uchar
**
row
)
{
ulong
length
=
net_field_length
(
row
);
memcpy
(
param
->
buffer
,
(
char
*
)
*
row
,
length
);
*
param
->
length
=
length
;
*
row
+=
length
;
}
/*
Setup the bind buffers for resultset processing
*/
...
...
@@ -4163,21 +4241,62 @@ my_bool STDCALL mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
DBUG_ENTER
(
"mysql_bind_result"
);
DBUG_ASSERT
(
stmt
!=
0
);
#ifdef
EXTRA_CHECK
_ARGUMENTS
#ifdef
CHECK_EXTRA
_ARGUMENTS
if
(
!
bind
)
{
set_stmt_error
(
stmt
,
CR_NULL_POINTER
);
DBUG_RETURN
(
1
);
}
#endif
bind_count
=
stmt
->
result
->
field_count
;
bind_count
=
stmt
->
field_count
;
memcpy
((
char
*
)
stmt
->
bind
,
(
char
*
)
bind
,
sizeof
(
MYSQL_BIND
)
*
bind_count
);
for
(
param
=
stmt
->
bind
,
end
=
param
+
bind_count
;
param
<
end
;
param
++
)
{
/* TODO: Set up convert functions like in mysql_bind_param */
/* Setup data copy functions for the different supported types */
switch
(
param
->
buffer_type
)
{
case
MYSQL_TYPE_TINY
:
param
->
bind_length
=
1
;
param
->
fetch_result
=
fetch_result_tinyint
;
break
;
case
MYSQL_TYPE_SHORT
:
param
->
bind_length
=
2
;
param
->
fetch_result
=
fetch_result_short
;
break
;
case
MYSQL_TYPE_LONG
:
param
->
bind_length
=
4
;
param
->
fetch_result
=
fetch_result_int32
;
break
;
case
MYSQL_TYPE_LONGLONG
:
param
->
bind_length
=
8
;
param
->
fetch_result
=
fetch_result_int64
;
break
;
case
MYSQL_TYPE_FLOAT
:
param
->
bind_length
=
4
;
param
->
fetch_result
=
fetch_result_float
;
break
;
case
MYSQL_TYPE_DOUBLE
:
param
->
bind_length
=
8
;
param
->
fetch_result
=
fetch_result_double
;
break
;
case
MYSQL_TYPE_TINY_BLOB
:
case
MYSQL_TYPE_MEDIUM_BLOB
:
case
MYSQL_TYPE_LONG_BLOB
:
case
MYSQL_TYPE_VAR_STRING
:
case
MYSQL_TYPE_STRING
:
param
->
length
=
&
param
->
buffer_length
;
param
->
fetch_result
=
fetch_result_str
;
break
;
default:
sprintf
(
stmt
->
last_error
,
ER
(
stmt
->
last_errno
=
CR_UNSUPPORTED_PARAM_TYPE
),
param
->
buffer_type
,
param
->
param_number
);
DBUG_RETURN
(
1
);
}
if
(
!
param
->
length
)
param
->
length
=
&
param
->
bind_length
;
}
stmt
->
res_buffers
=
1
;
DBUG_RETURN
(
0
);
}
...
...
@@ -4187,16 +4306,16 @@ my_bool STDCALL mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
*/
static
my_bool
my_fetch_row
(
MYSQL_STMT
*
stmt
,
MYSQL_RES
*
result
,
const
byte
*
row
)
stmt_fetch_row
(
MYSQL_STMT
*
stmt
,
uchar
*
*
row
)
{
MYSQL_BIND
*
bind
,
*
end
;
uchar
*
null_ptr
=
(
uchar
*
)
row
,
bit
;
uchar
*
null_ptr
=
(
uchar
*
)
*
row
,
bit
;
result
->
row_count
++
;
row
+=
(
result
->
field_count
+
7
)
/
8
;
/* Copy complete row to application buffers */
*
row
+=
(
stmt
->
field_count
+
7
)
/
8
;
bit
=
1
;
for
(
bind
=
stmt
->
bind
,
end
=
(
MYSQL_BIND
*
)
bind
+
result
->
field_count
;
/* Copy complete row to application buffers */
for
(
bind
=
stmt
->
bind
,
end
=
(
MYSQL_BIND
*
)
bind
+
stmt
->
field_count
;
bind
<
end
;
bind
++
)
{
...
...
@@ -4205,7 +4324,7 @@ my_fetch_row(MYSQL_STMT *stmt, MYSQL_RES *result, const byte *row)
else
{
bind
->
is_null
=
0
;
row
=
(
byte
*
)
(
*
bind
->
fetch_result
)(
bind
,
(
char
*
)
row
);
(
*
bind
->
fetch_result
)(
bind
,
row
);
}
if
(
!
(
bit
<<=
1
)
&
255
)
{
...
...
@@ -4216,12 +4335,9 @@ my_fetch_row(MYSQL_STMT *stmt, MYSQL_RES *result, const byte *row)
return
0
;
}
static
int
read_binary_data
(
MYSQL
*
mysql
)
static
int
read_binary_data
(
MYSQL
*
mysql
)
{
ulong
pkt_len
;
if
((
pkt_len
=
net_safe_read
(
mysql
))
==
packet_error
)
if
(
packet_error
==
net_safe_read
(
mysql
))
return
-
1
;
if
(
mysql
->
net
.
read_pos
[
0
])
return
1
;
/* End of data */
...
...
@@ -4235,57 +4351,30 @@ read_binary_data(MYSQL *mysql)
int
STDCALL
mysql_fetch
(
MYSQL_STMT
*
stmt
)
{
MYSQL
_RES
*
result
;
MYSQL
*
mysql
=
stmt
->
mysql
;
DBUG_ENTER
(
"mysql_fetch"
);
result
=
stmt
->
result
;
if
(
!
result
)
DBUG_RETURN
(
MYSQL_NO_DATA
);
if
(
!
result
->
data
)
{
MYSQL
*
mysql
=
stmt
->
mysql
;
if
(
!
result
->
eof
)
if
(
stmt
->
res_buffers
)
{
int
res
;
if
(
!
(
res
=
read_binary_data
(
result
->
handle
)))
DBUG_RETURN
((
int
)
my_fetch_row
(
stmt
,
result
,
(
byte
*
)
mysql
->
net
.
read_pos
+
1
));
if
(
!
(
res
=
read_binary_data
(
mysql
)))
{
if
(
stmt
->
res_buffers
)
DBUG_RETURN
((
int
)
stmt_fetch_row
(
stmt
,(
uchar
**
)
&
mysql
->
net
.
read_pos
+
1
));
DBUG_RETURN
(
0
);
}
DBUG_PRINT
(
"info"
,
(
"end of data"
));
result
->
eof
=
1
;
result
->
handle
->
status
=
MYSQL_STATUS_READY
;
mysql
->
status
=
MYSQL_STATUS_READY
;
/* Don't clear handle in mysql_free_results */
result
->
handle
=
0
;
if
(
res
<
0
)
/* Network error */
{
set_stmt_errmsg
(
stmt
,(
char
*
)
mysql
->
net
.
last_error
,
mysql
->
net
.
last_errno
);
DBUG_RETURN
(
MYSQL_STATUS_ERROR
);
}
}
DBUG_RETURN
(
MYSQL_NO_DATA
);
/* no more data */
}
{
/*
For prepared statements, the row data is a string of binary bytes,
not a set of string pointers as for normal statements
It's however convenient to use the data pointer also for prepared
statements.
*/
MYSQL_ROW
values
;
if
(
!
result
->
data_cursor
)
{
DBUG_PRINT
(
"info"
,
(
"end of data"
));
result
->
current_row
=
(
MYSQL_ROW
)
NULL
;
DBUG_RETURN
(
MYSQL_NO_DATA
);
}
values
=
result
->
data_cursor
->
data
;
result
->
data_cursor
=
result
->
data_cursor
->
next
;
DBUG_RETURN
((
int
)
my_fetch_row
(
stmt
,
result
,
(
byte
*
)
values
));
}
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
//?? do we need to set MYSQL_STATUS_READY ?
}
...
...
@@ -4302,17 +4391,15 @@ my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt)
my_bool
error
=
0
;
DBUG_ENTER
(
"mysql_stmt_close"
);
if
(
stmt
->
state
)
if
(
stmt
->
state
!=
MY_ST_UNKNOWN
)
{
char
buff
[
4
];
int4store
(
buff
,
stmt
->
stmt_id
);
error
=
simple_command
(
stmt
->
mysql
,
COM_CLOSE_STMT
,
buff
,
4
,
0
);
}
mysql_free_result
(
stmt
->
result
);
free_root
(
&
stmt
->
mem_root
,
MYF
(
0
));
my_free
((
gptr
)
stmt
->
query
,
MYF
(
MY_WME
|
MY_ALLOW_ZERO_PTR
));
my_free
((
gptr
)
stmt
->
bind
,
MY_ALLOW_ZERO_PTR
);
my_free
((
gptr
)
stmt
->
params
,
MY_ALLOW_ZERO_PTR
);
my_free
((
gptr
)
stmt
,
MYF
(
MY_WME
));
DBUG_RETURN
(
error
);
}
...
...
libmysql/libmysql.def
View file @
b74c43f4
...
...
@@ -102,6 +102,22 @@ EXPORTS
mysql_add_slave
mysql_warning_count
mysql_warnings
mysql_prepare
mysql_execute
mysql_param_count
mysql_bind_param
mysql_bind_result
mysql_prepare_result
mysql_stmt_close
mysql_stmt_error
mysql_stmt_errno
mysql_fetch
mysql_send_long_data
mysql_multi_query
mysql_next_result
mysql_commit
mysql_rollback
mysql_autocommit
...
...
sql/item.cc
View file @
b74c43f4
...
...
@@ -315,32 +315,27 @@ void Item_param::set_null()
void
Item_param
::
set_int
(
longlong
i
)
{
int_value
=
(
longlong
)
i
;
item_result_type
=
INT_RESULT
;
item_type
=
INT_ITEM
;
}
void
Item_param
::
set_double
(
double
value
)
{
real_value
=
value
;
item_result_type
=
REAL_RESULT
;
item_type
=
REAL_ITEM
;
}
void
Item_param
::
set_value
(
const
char
*
str
,
uint
length
,
CHARSET_INFO
*
cs
)
void
Item_param
::
set_value
(
const
char
*
str
,
uint
length
)
{
str_value
.
set
(
str
,
length
,
cs
);
item_result_type
=
STRING_RESULT
;
str_value
.
set
(
str
,
length
,
thd_charset
());
item_type
=
STRING_ITEM
;
}
void
Item_param
::
set_longdata
(
const
char
*
str
,
ulong
length
,
CHARSET_INFO
*
cs
)
void
Item_param
::
set_longdata
(
const
char
*
str
,
ulong
length
)
{
/* TODO: Fix this for binary handling by making use of
buffer_type..
*/
str_value
.
append
(
str
,
length
);
long_data_supplied
=
1
;
}
...
...
sql/item.h
View file @
b74c43f4
...
...
@@ -186,8 +186,8 @@ class Item_param :public Item
Item_param
(
char
*
name_par
=
0
)
{
name
=
name_par
?
name_par
:
(
char
*
)
"?"
;
long_data_supplied
=
false
;
item_type
=
STRING_ITEM
;
long_data_supplied
=
false
;
item_type
=
STRING_ITEM
;
item_result_type
=
STRING_RESULT
;
}
enum
Type
type
()
const
{
return
item_type
;
}
...
...
@@ -199,12 +199,13 @@ class Item_param :public Item
void
set_null
();
void
set_int
(
longlong
i
);
void
set_double
(
double
i
);
void
set_value
(
const
char
*
str
,
uint
length
,
CHARSET_INFO
*
cs
);
void
set_long_str
(
const
char
*
str
,
ulong
length
,
CHARSET_INFO
*
cs
);
void
set_long_binary
(
const
char
*
str
,
ulong
length
,
CHARSET_INFO
*
cs
);
void
set_longdata
(
const
char
*
str
,
ulong
length
,
CHARSET_INFO
*
cs
);
void
set_value
(
const
char
*
str
,
uint
length
);
void
set_long_str
(
const
char
*
str
,
ulong
length
);
void
set_long_binary
(
const
char
*
str
,
ulong
length
);
void
set_longdata
(
const
char
*
str
,
ulong
length
);
void
set_long_end
();
void
reset
()
{}
void
(
*
setup_param_func
)(
Item_param
*
param
,
uchar
**
pos
);
enum
Item_result
result_type
()
const
{
return
item_result_type
;
}
Item
*
new_item
()
{
return
new
Item_param
(
name
);
}
...
...
sql/mysql_priv.h
View file @
b74c43f4
...
...
@@ -509,7 +509,7 @@ int mysqld_show_column_types(THD *thd);
int
mysqld_help
(
THD
*
thd
,
const
char
*
text
);
/* sql_prepare.cc */
int
compare_prep_stmt
(
PREP_STMT
*
a
,
PREP_STMT
*
b
,
void
*
not_used
);
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
);
bool
mysql_stmt_prepare
(
THD
*
thd
,
char
*
packet
,
uint
packet_length
);
void
mysql_stmt_execute
(
THD
*
thd
,
char
*
packet
);
...
...
sql/sql_class.h
View file @
b74c43f4
...
...
@@ -325,7 +325,7 @@ typedef struct st_prep_stmt
uint
param_count
;
uint
last_errno
;
char
last_error
[
MYSQL_ERRMSG_SIZE
];
bool
error_in_prepare
,
long_data_used
;
bool
error_in_prepare
,
long_data_used
,
param_inited
;
}
PREP_STMT
;
...
...
@@ -510,7 +510,6 @@ class THD :public ilink {
bool
safe_to_cache_query
;
bool
volatile
killed
;
bool
prepare_command
;
Item_param
*
params
;
// Pointer to array of params
/*
If we do a purge of binary logs, log index info of the threads
...
...
sql/sql_error.cc
View file @
b74c43f4
...
...
@@ -115,7 +115,7 @@ static const char *warning_level_names[]= {"Note", "Warning", "Error", "?"};
my_bool
mysqld_show_warnings
(
THD
*
thd
,
ulong
levels_to_show
)
{
List
<
Item
>
field_list
;
DBUG_ENTER
(
"mysqld_show_
error
s"
);
DBUG_ENTER
(
"mysqld_show_
warning
s"
);
field_list
.
push_back
(
new
Item_empty_string
(
"Level"
,
7
));
field_list
.
push_back
(
new
Item_int
(
"Code"
,
0
,
4
));
...
...
sql/sql_prepare.cc
View file @
b74c43f4
...
...
@@ -30,10 +30,11 @@ This file contains the implementation of prepare and executes.
Prepare-execute:
- Server gets the command 'COM_EXECUTE' to execute the
previously prepared query.
- If there is are any parameters, then replace the markers with the
data supplied by client with the following format:
[types_specified(0/1)][type][length][data] .. [type][length]..
previously prepared query. If there is any param markers; then client
will send the data in the following format:
[null_bits][types_specified(0/1)][[length][data]][[length][data] .. [length][data].
- Replace the param items with this new data. If it is a first execute
or types altered by client; then setup the conversion routines.
- Execute the query without re-parsing and send back the results
to client
...
...
@@ -53,33 +54,9 @@ Long data handling:
#include <assert.h> // for DEBUG_ASSERT()
#include <m_ctype.h> // for isspace()
extern
int
yyparse
(
void
);
static
ulong
get_param_length
(
uchar
**
packet
);
static
uint
get_buffer_type
(
uchar
**
packet
);
static
bool
param_is_null
(
uchar
**
packet
);
static
bool
setup_param_fields
(
THD
*
thd
,
List
<
Item
>
&
params
);
static
uchar
*
setup_param_field
(
Item_param
*
item_param
,
uchar
*
pos
,
uint
buffer_type
);
static
void
setup_longdata_field
(
Item_param
*
item_param
,
uchar
*
pos
);
static
bool
setup_longdata
(
THD
*
thd
,
List
<
Item
>
&
params
);
static
bool
send_prepare_results
(
PREP_STMT
*
stmt
);
static
bool
parse_prepare_query
(
PREP_STMT
*
stmt
,
char
*
packet
,
uint
length
);
static
bool
mysql_send_insert_fields
(
PREP_STMT
*
stmt
,
TABLE_LIST
*
table_list
,
List
<
Item
>
&
fields
,
List
<
List_item
>
&
values_list
,
thr_lock_type
lock_type
);
static
bool
mysql_test_insert_fields
(
PREP_STMT
*
stmt
,
TABLE_LIST
*
table_list
,
List
<
Item
>
&
fields
,
List
<
List_item
>
&
values_list
,
thr_lock_type
lock_type
);
static
bool
mysql_test_upd_fields
(
PREP_STMT
*
stmt
,
TABLE_LIST
*
table_list
,
List
<
Item
>
&
fields
,
List
<
Item
>
&
values
,
COND
*
conds
,
thr_lock_type
lock_type
);
static
bool
mysql_test_select_fields
(
PREP_STMT
*
stmt
,
TABLE_LIST
*
tables
,
List
<
Item
>
&
fields
,
List
<
Item
>
&
values
,
COND
*
conds
,
ORDER
*
order
,
ORDER
*
group
,
Item
*
having
,
thr_lock_type
lock_type
);
#define IS_PARAM_NULL(pos, param_no) pos[param_no/8] & (1 << param_no & 7)
extern
int
yyparse
(
void
);
/*
Find prepared statement in thd
...
...
@@ -114,9 +91,9 @@ static PREP_STMT *find_prepared_statement(THD *thd, ulong stmt_id,
Compare two prepared statements; Used to find a prepared statement
*/
int
compare_prep_stmt
(
PREP_STMT
*
a
,
PREP_STMT
*
b
,
void
*
not_used
)
int
compare_prep_stmt
(
void
*
not_used
,
PREP_STMT
*
stmt
,
ulong
*
key
)
{
return
(
a
->
stmt_id
<
b
->
stmt_id
)
?
-
1
:
(
a
->
stmt_id
==
b
->
stmt_id
)
?
0
:
1
;
return
(
stmt
->
stmt_id
==
*
key
)
?
0
:
(
stmt
->
stmt_id
<
*
key
)
?
-
1
:
1
;
}
...
...
@@ -133,21 +110,22 @@ int compare_prep_stmt(PREP_STMT *a, PREP_STMT *b, void *not_used)
void
free_prep_stmt
(
PREP_STMT
*
stmt
,
TREE_FREE
mode
,
void
*
not_used
)
{
free_root
(
&
stmt
->
mem_root
,
MYF
(
0
));
free_items
(
stmt
->
free_list
);
free_root
(
&
stmt
->
mem_root
,
MYF
(
0
));
}
/*
Send prepared stmt info to client after prepare
*/
bool
send_prep_stmt
(
PREP_STMT
*
stmt
,
uint
columns
)
static
bool
send_prep_stmt
(
PREP_STMT
*
stmt
,
uint
columns
)
{
NET
*
net
=&
stmt
->
thd
->
net
;
char
buff
[
8
];
int4store
(
buff
,
stmt
->
stmt_id
);
int2store
(
buff
+
4
,
columns
);
int2store
(
buff
+
6
,
stmt
->
param_count
);
return
my_net_write
(
&
stmt
->
thd
->
net
,
buff
,
sizeof
(
buff
));
return
(
my_net_write
(
net
,
buff
,
sizeof
(
buff
))
||
net_flush
(
net
));
}
/*
...
...
@@ -156,43 +134,15 @@ bool send_prep_stmt(PREP_STMT *stmt, uint columns)
TODO: Not yet ready
*/
bool
send_item_params
(
PREP_STMT
*
stmt
)
static
bool
send_item_params
(
PREP_STMT
*
stmt
)
{
#if 0
char buff[1];
buff[0]=0;
return
my_net_write
(
&
stmt
->
thd
->
net
,
buff
,
sizeof
(
buff
));
}
/*
Read the buffer type, this happens only first time
*/
static
uint
get_buffer_type
(
uchar
**
packet
)
{
reg1
uchar
*
pos
=
*
packet
;
(
*
packet
)
+=
2
;
return
(
uint
)
uint2korr
(
pos
);
}
/*
Check for NULL param data
RETURN VALUES
0 Value was not NULL
1 Value was NULL
*/
static
bool
param_is_null
(
uchar
**
packet
)
{
reg1
uchar
*
pos
=
*
packet
;
if
(
*
pos
==
251
)
{
(
*
packet
)
++
;
if (my_net_write(&stmt->thd->net, buff, sizeof(buff)))
return 1;
}
send_eof(stmt->thd);
#endif
return
0
;
}
...
...
@@ -222,60 +172,103 @@ static ulong get_param_length(uchar **packet)
(
*
packet
)
+=
9
;
// Must be 254 when here
return
(
ulong
)
uint4korr
(
pos
+
1
);
}
/*
Setup param conversion routines
setup_param_xx()
param Parameter Item
pos Input data buffer
All these functions reads the data from pos and sets up that data
through 'param' and advances the buffer position to predifined
length position.
Make a note that the NULL handling is examined at first execution
(i.e. when input types altered) and for all subsequent executions
we don't read any values for this.
RETURN VALUES
/*
Read and return the data for parameters supplied by client
*/
static
uchar
*
setup_param_field
(
Item_param
*
item_param
,
uchar
*
pos
,
uint
buffer_type
)
static
void
setup_param_tiny
(
Item_param
*
param
,
uchar
**
pos
)
{
if
(
param_is_null
(
&
pos
))
{
item_param
->
set_null
();
return
(
pos
);
}
switch
(
buffer_type
)
{
param
->
set_int
((
longlong
)(
**
pos
));
*
pos
+=
1
;
}
static
void
setup_param_short
(
Item_param
*
param
,
uchar
**
pos
)
{
param
->
set_int
((
longlong
)
sint2korr
(
*
pos
));
*
pos
+=
2
;
}
static
void
setup_param_int32
(
Item_param
*
param
,
uchar
**
pos
)
{
param
->
set_int
((
longlong
)
sint4korr
(
*
pos
));
*
pos
+=
4
;
}
static
void
setup_param_int64
(
Item_param
*
param
,
uchar
**
pos
)
{
param
->
set_int
((
longlong
)
sint8korr
(
*
pos
));
*
pos
+=
8
;
}
static
void
setup_param_float
(
Item_param
*
param
,
uchar
**
pos
)
{
float
data
;
float4get
(
data
,
*
pos
);
param
->
set_double
((
double
)
data
);
*
pos
+=
4
;
}
static
void
setup_param_double
(
Item_param
*
param
,
uchar
**
pos
)
{
double
data
;
float8get
(
data
,
*
pos
);
param
->
set_double
((
double
)
data
);
*
pos
+=
8
;
}
static
void
setup_param_str
(
Item_param
*
param
,
uchar
**
pos
)
{
ulong
len
=
get_param_length
(
pos
);
param
->
set_value
((
const
char
*
)
*
pos
,
len
);
*
pos
+=
len
;
}
static
void
setup_param_functions
(
Item_param
*
param
,
uchar
read_pos
)
{
switch
(
read_pos
)
{
case
FIELD_TYPE_TINY
:
item_param
->
set_int
((
longlong
)(
*
pos
))
;
p
os
+=
1
;
param
->
setup_param_func
=
setup_param_tiny
;
p
aram
->
item_result_type
=
INT_RESULT
;
break
;
case
FIELD_TYPE_SHORT
:
item_param
->
set_int
((
longlong
)
sint2korr
(
pos
));
pos
+=
2
;
break
;
case
FIELD_TYPE_INT24
:
item_param
->
set_int
((
longlong
)
sint4korr
(
pos
));
pos
+=
3
;
param
->
setup_param_func
=
setup_param_short
;
param
->
item_result_type
=
INT_RESULT
;
break
;
case
FIELD_TYPE_LONG
:
item_param
->
set_int
((
longlong
)
sint4korr
(
pos
))
;
p
os
+=
4
;
param
->
setup_param_func
=
setup_param_int32
;
p
aram
->
item_result_type
=
INT_RESULT
;
break
;
case
FIELD_TYPE_LONGLONG
:
item_param
->
set_int
((
longlong
)
sint8korr
(
pos
))
;
p
os
+=
8
;
param
->
setup_param_func
=
setup_param_int64
;
p
aram
->
item_result_type
=
INT_RESULT
;
break
;
case
FIELD_TYPE_FLOAT
:
float
data
;
float4get
(
data
,
pos
);
item_param
->
set_double
((
double
)
data
);
pos
+=
4
;
param
->
setup_param_func
=
setup_param_float
;
param
->
item_result_type
=
REAL_RESULT
;
break
;
case
FIELD_TYPE_DOUBLE
:
double
j
;
float8get
(
j
,
pos
)
item_param
->
set_double
(
j
);
pos
+=
8
;
param
->
setup_param_func
=
setup_param_double
;
param
->
item_result_type
=
REAL_RESULT
;
break
;
default:
{
ulong
len
=
get_param_length
(
&
pos
);
item_param
->
set_value
((
const
char
*
)
pos
,
len
,
current_thd
->
thd_charset
);
pos
+=
len
;
param
->
setup_param_func
=
setup_param_str
;
param
->
item_result_type
=
STRING_RESULT
;
}
}
return
(
pos
);
}
/*
...
...
@@ -283,42 +276,45 @@ static uchar* setup_param_field(Item_param *item_param,
from client ..
*/
static
bool
setup_param
_fields
(
THD
*
thd
,
PREP_STMT
*
stmt
)
static
bool
setup_param
s_data
(
THD
*
thd
,
PREP_STMT
*
stmt
)
{
DBUG_ENTER
(
"setup_param_fields"
);
#ifdef READY_TO_BE_USED
Item_param
*
item_param
;
ulong
param_count
=
0
;
uchar
*
pos
=
(
uchar
*
)
thd
->
net
.
read_pos
+
1
;
// skip command type
List
<
Item
>
&
params
=
thd
->
lex
.
param_list
;
List_iterator
<
Item
>
param_iterator
(
params
);
Item_param
*
param
;
DBUG_ENTER
(
"setup_params_data"
);
uchar
*
pos
=
(
uchar
*
)
thd
->
net
.
read_pos
+
1
+
MYSQL_STMT_HEADER
;
//skip header
uchar
*
read_pos
=
pos
+
(
stmt
->
param_count
+
7
)
/
8
;
//skip null bits
ulong
param_no
;
if
(
*
pos
++
)
// No types supplied, read only param data
if
(
*
read_pos
++
)
//types supplied / first execute
{
/*
First execute or types altered by the client, setup the
conversion routines for all parameters (one time)
*/
while
((
param
=
(
Item_param
*
)
param_iterator
++
))
{
while
((
item_param
=
(
Item_param
*
)
it
++
)
&&
(
param_count
++
<
stmt
->
param_count
))
if
(
!
param
->
long_data_supplied
)
{
if
(
item_param
->
long_data_supplied
)
continue
;
if
(
!
(
pos
=
setup_param_field
(
item_param
,
pos
,
item_param
->
buffer_type
)))
DBUG_RETURN
(
1
);
setup_param_functions
(
param
,
*
read_pos
);
read_pos
+=
2
;
}
}
else
// Types supplied, read and store it along with param data
param_iterator
.
rewind
();
}
param_no
=
0
;
while
((
param
=
(
Item_param
*
)
param_iterator
++
))
{
while
((
item_param
=
(
Item_param
*
)
it
++
)
&&
(
param_count
++
<
thd
->
param_count
))
if
(
!
param
->
long_data_supplied
)
{
if
(
item_param
->
long_data_supplied
)
continue
;
if
(
!
(
pos
=
setup_param_field
(
item_param
,
pos
,
item_param
->
buffer_type
=
(
enum_field_types
)
get_buffer_type
(
&
pos
))))
DBUG_RETURN
(
1
);
if
(
IS_PARAM_NULL
(
pos
,
param_no
))
param
->
maybe_null
=
param
->
null_value
=
1
;
else
param
->
setup_param_func
(
param
,
&
read_pos
);
}
param_no
++
;
}
#endif
DBUG_RETURN
(
0
);
}
...
...
@@ -583,6 +579,8 @@ static bool send_prepare_results(PREP_STMT *stmt)
Rest fall through to default category, no parsing
for non-DML statements
*/
if
(
send_prep_stmt
(
stmt
,
0
))
goto
abort
;
}
}
DBUG_RETURN
(
0
);
...
...
@@ -607,6 +605,7 @@ static bool parse_prepare_query(PREP_STMT *stmt,
mysql_init_query
(
thd
);
thd
->
prepare_command
=
true
;
thd
->
safe_to_cache_query
=
0
;
thd
->
lex
.
param_count
=
0
;
LEX
*
lex
=
lex_start
(
thd
,
(
uchar
*
)
packet
,
length
);
if
(
!
yyparse
()
&&
!
thd
->
fatal_error
)
...
...
@@ -615,6 +614,25 @@ static bool parse_prepare_query(PREP_STMT *stmt,
DBUG_RETURN
(
error
);
}
/*
Initialize parameter items in statement
*/
static
bool
init_param_items
(
THD
*
thd
,
PREP_STMT
*
stmt
)
{
#if TO_BE_TESTED
Item_param
**
to
;
if
(
!
(
to
=
(
Item_param
*
)
my_malloc
(
sizeof
(
Item_param
*
)
*
stmt
->
param_count
,
MYF
(
MY_WME
))))
return
1
;
List
<
Item
>
&
params
=
thd
->
lex
.
param_list
;
List_iterator
<
Item
>
param_iterator
(
params
);
while
((
to
++
=
(
Item_param
*
)
param_iterator
++
))
{
DBUG_PRINT
(
"info"
,(
"param: %lx"
,
to
));
}
return
0
;
#endif
}
/*
Parse the query and send the total number of parameters
...
...
@@ -649,9 +667,14 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
if
(
!
(
specialflag
&
SPECIAL_NO_PRIOR
))
my_pthread_setprio
(
pthread_self
(),
WAIT_PRIOR
);
#if 0
if (init_param_items(thd, &stmt))
goto err;
#endif
stmt
.
mem_root
=
thd
->
mem_root
;
tree_insert
(
&
thd
->
prepared_statements
,
(
void
*
)
&
stmt
,
0
,
(
void
*
)
0
);
thd
->
mem_root
=
thd_root
;
// restore main mem_root
thd
->
last_prepared_stmt
=
&
stmt
;
DBUG_RETURN
(
0
);
err:
...
...
@@ -685,11 +708,11 @@ void mysql_stmt_execute(THD *thd, char *packet)
/* Check if we got an error when sending long data */
if
(
stmt
->
error_in_prepare
)
{
send_error
(
thd
);
send_error
(
thd
,
stmt
->
last_errno
,
stmt
->
last_error
);
DBUG_VOID_RETURN
;
}
if
(
stmt
->
param_count
&&
setup_param
_fields
(
thd
,
stmt
))
if
(
stmt
->
param_count
&&
setup_param
s_data
(
thd
,
stmt
))
DBUG_VOID_RETURN
;
MEM_ROOT
thd_root
=
thd
->
mem_root
;
...
...
@@ -705,6 +728,8 @@ void mysql_stmt_execute(THD *thd, char *packet)
*/
mysql_execute_command
(
thd
);
thd
->
last_prepared_stmt
=
stmt
;
if
(
!
(
specialflag
&
SPECIAL_NO_PRIOR
))
my_pthread_setprio
(
pthread_self
(),
WAIT_PRIOR
);
...
...
@@ -768,8 +793,10 @@ void mysql_stmt_close(THD *thd, char *packet)
send_error
(
thd
);
DBUG_VOID_RETURN
;
}
stmt
->
param
=
0
;
my_free
((
char
*
)
stmt
->
param
,
MYF
(
MY_ALLOW_ZERO_PTR
));
/* Will call free_prep_stmt() */
tree_delete
(
&
thd
->
prepared_statements
,
(
void
*
)
stmt
,
NULL
);
tree_delete
(
&
thd
->
prepared_statements
,
(
void
*
)
&
stmt
,
(
void
*
)
0
);
thd
->
last_prepared_stmt
=
0
;
DBUG_VOID_RETURN
;
}
...
...
@@ -800,17 +827,16 @@ void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length)
DBUG_ENTER
(
"mysql_stmt_get_longdata"
);
/* The following should never happen */
if
(
packet_length
<
9
)
if
(
packet_length
<
MYSQL_LONG_DATA_HEADER
+
1
)
{
my_error
(
ER_WRONG_ARGUMENTS
,
MYF
(
0
),
"get_longdata"
);
DBUG_VOID_RETURN
;
}
pos
++
;
// skip command type at first position
ulong
stmt_id
=
uint4korr
(
pos
);
uint
param_number
=
uint2korr
(
pos
+
4
);
uint
param_type
=
uint2korr
(
pos
+
6
);
pos
+=
8
;
// Point to data
pos
+=
MYSQL_LONG_DATA_HEADER
;
// Point to data
if
(
!
(
stmt
=
find_prepared_statement
(
thd
,
stmt_id
,
"get_longdata"
)))
{
...
...
@@ -829,7 +855,8 @@ void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length)
sprintf
(
stmt
->
last_error
,
ER
(
ER_WRONG_ARGUMENTS
),
"get_longdata"
);
DBUG_VOID_RETURN
;
}
stmt
->
param
[
param_number
].
set_longdata
(
pos
,
packet_length
-
9
,
current_thd
->
thd_charset
);
stmt
->
param
[
param_number
].
set_longdata
(
pos
,
packet_length
-
9
);
stmt
->
long_data_used
=
1
;
DBUG_VOID_RETURN
;
}
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