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
e9f2c7d4
Commit
e9f2c7d4
authored
Jun 16, 2004
by
konstantin@mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Comments and cleanups in client library.
parent
3ac650c8
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
237 additions
and
155 deletions
+237
-155
include/mysql.h
include/mysql.h
+1
-1
libmysql/libmysql.c
libmysql/libmysql.c
+236
-154
No files found.
include/mysql.h
View file @
e9f2c7d4
...
...
@@ -558,7 +558,7 @@ typedef struct st_mysql_bind
enum
enum_field_types
buffer_type
;
/* buffer type */
unsigned
long
buffer_length
;
/* buffer length, must be set for str/binary */
/* Following are for internal use. Set by mysql_bind_param */
/* Following are for internal use. Set by mysql_
stmt_
bind_param */
unsigned
char
*
inter_buffer
;
/* for the current data position */
unsigned
long
offset
;
/* offset position for char/binary fetch */
unsigned
long
internal_length
;
/* Used if length is 0 */
...
...
libmysql/libmysql.c
View file @
e9f2c7d4
...
...
@@ -1945,7 +1945,7 @@ mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, ulong length)
mysql_stmt_free_result
(
stmt
);
/*
These members must be reset for API to
These members must be reset for API to
function in case of error or misuse.
*/
stmt
->
bind_param_done
=
stmt
->
bind_result_done
=
FALSE
;
...
...
@@ -1984,14 +1984,14 @@ mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, ulong length)
}
/*
alloc_root will return valid address even in case param_count
alloc_root will return valid address even in case param_count
and field_count are zero. Thus we should never rely on stmt->bind
or stmt->params when checking for existence of placeholders or
result set.
*/
if
(
!
(
stmt
->
params
=
(
MYSQL_BIND
*
)
alloc_root
(
&
stmt
->
mem_root
,
sizeof
(
MYSQL_BIND
)
*
(
stmt
->
param_count
+
(
stmt
->
param_count
+
stmt
->
field_count
))))
{
set_stmt_error
(
stmt
,
CR_OUT_OF_MEMORY
,
unknown_sqlstate
);
...
...
@@ -2015,22 +2015,22 @@ static unsigned int alloc_stmt_fields(MYSQL_STMT *stmt)
MYSQL_FIELD
*
fields
,
*
field
,
*
end
;
MEM_ROOT
*
alloc
=
&
stmt
->
mem_root
;
MYSQL
*
mysql
=
stmt
->
mysql
->
last_used_con
;
stmt
->
field_count
=
mysql
->
field_count
;
/*
Get the field information for non-select statements
Get the field information for non-select statements
like SHOW and DESCRIBE commands
*/
if
(
!
(
stmt
->
fields
=
(
MYSQL_FIELD
*
)
alloc_root
(
alloc
,
if
(
!
(
stmt
->
fields
=
(
MYSQL_FIELD
*
)
alloc_root
(
alloc
,
sizeof
(
MYSQL_FIELD
)
*
stmt
->
field_count
))
||
!
(
stmt
->
bind
=
(
MYSQL_BIND
*
)
alloc_root
(
alloc
,
stmt
->
field_count
))
||
!
(
stmt
->
bind
=
(
MYSQL_BIND
*
)
alloc_root
(
alloc
,
sizeof
(
MYSQL_BIND
)
*
stmt
->
field_count
)))
return
0
;
for
(
fields
=
mysql
->
fields
,
end
=
fields
+
stmt
->
field_count
,
for
(
fields
=
mysql
->
fields
,
end
=
fields
+
stmt
->
field_count
,
field
=
stmt
->
fields
;
field
&&
fields
<
end
;
fields
++
,
field
++
)
{
...
...
@@ -2107,7 +2107,7 @@ mysql_stmt_result_metadata(MYSQL_STMT *stmt)
{
MYSQL_RES
*
result
;
DBUG_ENTER
(
"mysql_stmt_result_metadata"
);
/*
stmt->fields is only defined if stmt->field_count is not null;
stmt->field_count is initialized in prepare.
...
...
@@ -2130,41 +2130,65 @@ mysql_stmt_result_metadata(MYSQL_STMT *stmt)
DBUG_RETURN
(
result
);
}
/*
Returns parameter columns meta information in the form of
result set.
XXX: not implemented yet.
SYNOPSYS
mysql_stmt_param_metadata()
stmt statement handle
DESCRIPTION
This function can be called after you prepared the statement handle
with mysql_stmt_prepare().
XXX: not implemented yet.
RETURN
MYSQL_RES on success, 0 if there is no metadata.
Currently this function always returns 0.
*/
MYSQL_RES
*
STDCALL
mysql_stmt_param_metadata
(
MYSQL_STMT
*
stmt
)
{
DBUG_ENTER
(
"mysql_stmt_param_metadata"
);
if
(
!
stmt
->
param_count
)
DBUG_RETURN
(
0
);
/*
TODO: Fix this when server sends the information.
Till then keep a dummy prototype
TODO: Fix this when server sends the information.
Till then keep a dummy prototype
.
*/
DBUG_RETURN
(
0
);
}
/* Store type of parameter in network buffer. */
static
void
store_param_type
(
char
**
pos
,
MYSQL_BIND
*
param
)
{
uint
typecode
=
param
->
buffer_type
|
(
param
->
is_unsigned
?
32768
:
0
);
int2store
(
*
pos
,
typecode
);
*
pos
+=
2
;
}
/*
Functions to store parameter data in network packet.
All functions have the following characteristics:
SYNOPSIS
store_param_xxx()
net MySQL NET connection
param MySQL bind param
RETURN VALUES
0 ok
1 Error (Can't alloc net->buffer)
DESCRIPTION
These funtions are invoked from mysql_stmt_execute by
MYSQL_BIND::store_param_func pointer. This pointer is set once per many
executions in mysql_stmt_bind_param. The caller must ensure that network
buffer have enough capacity to store parameter (MYSQL_BIND::buffer_length
contains needed number of bytes).
*/
static
void
store_param_tinyint
(
NET
*
net
,
MYSQL_BIND
*
param
)
...
...
@@ -2253,7 +2277,7 @@ static void net_store_datetime(NET *net, MYSQL_TIME *tm)
length
=
4
;
else
length
=
0
;
buff
[
0
]
=
(
char
)
length
++
;
buff
[
0
]
=
(
char
)
length
++
;
memcpy
((
char
*
)
net
->
write_pos
,
buff
,
length
);
net
->
write_pos
+=
length
;
}
...
...
@@ -2271,7 +2295,7 @@ static void store_param_datetime(NET *net, MYSQL_BIND *param)
MYSQL_TIME
*
tm
=
(
MYSQL_TIME
*
)
param
->
buffer
;
net_store_datetime
(
net
,
tm
);
}
static
void
store_param_str
(
NET
*
net
,
MYSQL_BIND
*
param
)
{
/* param->length is always set in mysql_stmt_bind_param */
...
...
@@ -2292,7 +2316,8 @@ static void store_param_str(NET *net, MYSQL_BIND *param)
DESCRIPTION
A data package starts with a string of bits where we set a bit
if a parameter is NULL
if a parameter is NULL. Unlike bit string in result set row, here
we don't have reserved bits for OK/error packet.
*/
static
void
store_param_null
(
NET
*
net
,
MYSQL_BIND
*
param
)
...
...
@@ -2303,8 +2328,9 @@ static void store_param_null(NET *net, MYSQL_BIND *param)
/*
Set parameter data by reading from input buffers from the
client application
Store one parameter in network packet: data is read from
client buffer and saved in network packet by means of one
of store_param_xxxx functions.
*/
static
my_bool
store_param
(
MYSQL_STMT
*
stmt
,
MYSQL_BIND
*
param
)
...
...
@@ -2339,11 +2365,11 @@ static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param)
Send the prepared query to server for execution
*/
static
my_bool
execute
(
MYSQL_STMT
*
stmt
,
char
*
packet
,
ulong
length
)
static
my_bool
execute
(
MYSQL_STMT
*
stmt
,
char
*
packet
,
ulong
length
)
{
MYSQL
*
mysql
=
stmt
->
mysql
;
NET
*
net
=
&
mysql
->
net
;
char
buff
[
4
/* size of stmt id */
+
char
buff
[
4
/* size of stmt id */
+
5
/* execution flags */
];
DBUG_ENTER
(
"execute"
);
DBUG_PRINT
(
"enter"
,(
"packet: %s, length :%d"
,
packet
?
packet
:
" "
,
length
));
...
...
@@ -2363,14 +2389,6 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length)
stmt
->
insert_id
=
mysql
->
insert_id
;
DBUG_RETURN
(
0
);
}
static
void
store_param_type
(
char
**
pos
,
MYSQL_BIND
*
param
)
{
uint
typecode
=
param
->
buffer_type
|
(
param
->
is_unsigned
?
32768
:
0
);
int2store
(
*
pos
,
typecode
);
*
pos
+=
2
;
}
int
cli_stmt_execute
(
MYSQL_STMT
*
stmt
)
...
...
@@ -2413,7 +2431,7 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
for
(
param
=
stmt
->
params
;
param
<
param_end
;
param
++
)
{
/* check if mysql_long_data() was used */
/* check if mysql_
stmt_send_
long_data() was used */
if
(
param
->
long_data_used
)
param
->
long_data_used
=
0
;
/* Clear for next execute call */
else
if
(
store_param
(
stmt
,
param
))
...
...
@@ -2472,16 +2490,16 @@ static int stmt_read_row_buffered(MYSQL_STMT *stmt, unsigned char **row)
0 - success; *row contains valid address of a row;
row data is stored in network buffer
1 - error; error code is written to
stmt->last_{errno,error}; *row is not changed
stmt->last_{errno,error}; *row is not changed
MYSQL_NO_DATA - end of file was read from network;
*row is to NULL
*row is to NULL
*/
static
int
stmt_read_row_unbuffered
(
MYSQL_STMT
*
stmt
,
unsigned
char
**
row
)
{
int
rc
=
1
;
MYSQL
*
mysql
=
stmt
->
mysql
;
/*
/*
This function won't be called if stmt->field_count is zero
or execution wasn't done: this is ensured by mysql_stmt_execute.
*/
...
...
@@ -2555,7 +2573,7 @@ stmt_read_row_no_data(MYSQL_STMT *stmt __attribute__((unused)),
0 success
!0 wrong attribute type
*/
my_bool
STDCALL
mysql_stmt_attr_set
(
MYSQL_STMT
*
stmt
,
enum
enum_stmt_attr_type
attr_type
,
const
void
*
value
)
...
...
@@ -2564,14 +2582,14 @@ my_bool STDCALL mysql_stmt_attr_set(MYSQL_STMT *stmt,
case
STMT_ATTR_UPDATE_MAX_LENGTH
:
stmt
->
update_max_length
=
value
?
*
(
const
my_bool
*
)
value
:
0
;
break
;
default:
default:
return
TRUE
;
}
return
FALSE
;
}
my_bool
STDCALL
mysql_stmt_attr_get
(
MYSQL_STMT
*
stmt
,
my_bool
STDCALL
mysql_stmt_attr_get
(
MYSQL_STMT
*
stmt
,
enum
enum_stmt_attr_type
attr_type
,
void
*
value
)
{
...
...
@@ -2579,7 +2597,7 @@ my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt,
case
STMT_ATTR_UPDATE_MAX_LENGTH
:
*
(
unsigned
long
*
)
value
=
stmt
->
update_max_length
;
break
;
default:
default:
return
TRUE
;
}
return
FALSE
;
...
...
@@ -2587,7 +2605,47 @@ my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt,
/*
Execute the prepared query
Send placeholders data to server (if there are placeholders)
and execute prepared statement.
SYNOPSIS
mysql_stmt_execute()
stmt statement handle. The handle must be created
with mysql_stmt_init() and prepared with
mysql_stmt_prepare(). If there are placeholders
in the statement they must be bound to local
variables with mysql_stmt_bind_param().
DESCRIPTION
This function will automatically flush pending result
set (if there is one), send parameters data to the server
and read result of statement execution.
If previous result set was cached with mysql_stmt_store_result()
it will also be freed in the beginning of this call.
The server can return 3 types of responses to this command:
- error, can be retrieved with mysql_stmt_error()
- ok, no result set pending. In this case we just update
stmt->insert_id and stmt->affected_rows.
- the query returns a result set: there could be 0 .. N
rows in it. In this case the server can also send updated
result set metadata.
Next steps you may want to make:
- find out if there is result set with mysql_stmt_field_count().
If there is one:
- optionally, cache entire result set on client to unblock
connection with mysql_stmt_store_result()
- bind client variables to result set columns and start read rows
with mysql_stmt_fetch().
- reset statement with mysql_stmt_reset() or close it with
mysql_stmt_close()
Otherwise:
- find out last insert id and number of affected rows with
mysql_stmt_insert_id(), mysql_stmt_affected_rows()
RETURN
0 success
1 error, message can be retrieved with mysql_stmt_error().
*/
int
STDCALL
mysql_stmt_execute
(
MYSQL_STMT
*
stmt
)
...
...
@@ -2681,7 +2739,19 @@ unsigned int STDCALL mysql_stmt_field_count(MYSQL_STMT *stmt)
}
/*
Return last inserted id for auto_increment columns
Return last inserted id for auto_increment columns.
SYNOPSIS
mysql_stmt_insert_id()
stmt statement handle
DESCRIPTION
Current implementation of this call has a caveat: stmt->insert_id is
unconditionally updated from mysql->insert_id in the end of each
mysql_stmt_execute(). This works OK if mysql->insert_id contains new
value (sent in reply to mysql_stmt_execute()), otherwise stmt->insert_id
value gets undefined, as it's updated from some arbitrary value saved in
connection structure during some other call.
*/
my_ulonglong
STDCALL
mysql_stmt_insert_id
(
MYSQL_STMT
*
stmt
)
...
...
@@ -2693,11 +2763,24 @@ my_ulonglong STDCALL mysql_stmt_insert_id(MYSQL_STMT *stmt)
static
my_bool
int_is_null_true
=
1
;
/* Used for MYSQL_TYPE_NULL */
static
my_bool
int_is_null_false
=
0
;
/*
Setup the parameter data buffers from application
Setup the input parameter data buffers from application
SYNOPSIS
mysql_stmt_bind_param()
stmt statement handle
The statement must be prepared with mysql_stmt_prepare().
bind Array of mysql_stmt_param_count() bind parameters.
RETURN
0 success
1 error, can be retrieved with mysql_stmt_error.
Note, that this function doesn't check that size of MYSQL_BIND
array is >= mysql_stmt_field_count(),
*/
my_bool
STDCALL
mysql_stmt_bind_param
(
MYSQL_STMT
*
stmt
,
MYSQL_BIND
*
bind
)
my_bool
STDCALL
mysql_stmt_bind_param
(
MYSQL_STMT
*
stmt
,
MYSQL_BIND
*
bind
)
{
uint
count
=
0
;
MYSQL_BIND
*
param
,
*
end
;
...
...
@@ -2839,7 +2922,7 @@ mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number,
DBUG_ASSERT
(
stmt
!=
0
);
DBUG_PRINT
(
"enter"
,(
"param no : %d, data : %lx, length : %ld"
,
param_number
,
data
,
length
));
/*
We only need to check for stmt->param_count, if it's not null
prepare was done.
...
...
@@ -2864,7 +2947,7 @@ mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number,
DBUG_RETURN
(
1
);
}
/*
/*
Send long data packet if there is data or we're sending long data
for the first time.
*/
...
...
@@ -2872,8 +2955,8 @@ mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number,
{
MYSQL
*
mysql
=
stmt
->
mysql
;
/* Packet header: stmt id (4 bytes), param no (2 bytes) */
char
buff
[
MYSQL_LONG_DATA_HEADER
];
char
buff
[
MYSQL_LONG_DATA_HEADER
];
int4store
(
buff
,
stmt
->
stmt_id
);
int2store
(
buff
+
4
,
param_number
);
param
->
long_data_used
=
1
;
...
...
@@ -2926,7 +3009,7 @@ static uint read_binary_time(MYSQL_TIME *tm, uchar **pos)
{
uchar
*
to
;
uint
length
;
/* net_field_length will set pos to the first byte of data */
if
(
!
(
length
=
net_field_length
(
pos
)))
{
...
...
@@ -2983,14 +3066,14 @@ static uint read_binary_date(MYSQL_TIME *tm, uchar **pos)
{
uchar
*
to
;
uint
length
;
if
(
!
(
length
=
net_field_length
(
pos
)))
{
set_zero_time
(
tm
);
return
0
;
}
to
=
*
pos
;
to
=
*
pos
;
tm
->
year
=
(
uint
)
sint2korr
(
to
);
tm
->
month
=
(
uint
)
to
[
2
];
tm
->
day
=
(
uint
)
to
[
3
];
...
...
@@ -3004,7 +3087,7 @@ static uint read_binary_date(MYSQL_TIME *tm, uchar **pos)
/* Convert Numeric to buffer types */
static
void
send_data_long
(
MYSQL_BIND
*
param
,
MYSQL_FIELD
*
field
,
longlong
value
)
{
{
char
*
buffer
=
param
->
buffer
;
uint
field_is_unsigned
=
(
field
->
flags
&
UNSIGNED_FLAG
);
...
...
@@ -3041,26 +3124,26 @@ static void send_data_long(MYSQL_BIND *param, MYSQL_FIELD *field,
{
char
tmp
[
22
];
/* Enough for longlong */
uint
length
=
(
uint
)(
longlong10_to_str
(
value
,(
char
*
)
tmp
,
field_is_unsigned
?
10
:
-
10
)
-
tmp
);
field_is_unsigned
?
10
:
-
10
)
-
tmp
);
ulong
copy_length
=
min
((
ulong
)
length
-
param
->
offset
,
param
->
buffer_length
);
if
((
long
)
copy_length
<
0
)
copy_length
=
0
;
else
memcpy
(
buffer
,
(
char
*
)
tmp
+
param
->
offset
,
copy_length
);
*
param
->
length
=
length
;
*
param
->
length
=
length
;
if
(
copy_length
!=
param
->
buffer_length
)
*
(
buffer
+
copy_length
)
=
'\0'
;
}
}
}
}
/* Convert Double to buffer types */
static
void
send_data_double
(
MYSQL_BIND
*
param
,
double
value
)
{
{
char
*
buffer
=
param
->
buffer
;
switch
(
param
->
buffer_type
)
{
...
...
@@ -3099,19 +3182,19 @@ static void send_data_double(MYSQL_BIND *param, double value)
copy_length
=
0
;
else
memcpy
(
buffer
,
(
char
*
)
tmp
+
param
->
offset
,
copy_length
);
*
param
->
length
=
length
;
*
param
->
length
=
length
;
if
(
copy_length
!=
param
->
buffer_length
)
*
(
buffer
+
copy_length
)
=
'\0'
;
}
}
}
}
/* Convert string to buffer types */
static
void
send_data_str
(
MYSQL_BIND
*
param
,
char
*
value
,
uint
length
)
{
{
char
*
buffer
=
param
->
buffer
;
int
err
=
0
;
...
...
@@ -3136,7 +3219,7 @@ static void send_data_str(MYSQL_BIND *param, char *value, uint length)
{
int32
data
=
(
int32
)
my_strntol
(
&
my_charset_latin1
,
value
,
length
,
10
,
NULL
,
&
err
);
int4store
(
buffer
,
data
);
int4store
(
buffer
,
data
);
break
;
}
case
MYSQL_TYPE_LONGLONG
:
...
...
@@ -3179,7 +3262,7 @@ static void send_data_str(MYSQL_BIND *param, char *value, uint length)
}
static
void
send_data_time
(
MYSQL_BIND
*
param
,
MYSQL_TIME
ltime
,
static
void
send_data_time
(
MYSQL_BIND
*
param
,
MYSQL_TIME
ltime
,
uint
length
)
{
switch
(
param
->
buffer_type
)
{
...
...
@@ -3192,7 +3275,7 @@ static void send_data_time(MYSQL_BIND *param, MYSQL_TIME ltime,
case
MYSQL_TYPE_TIMESTAMP
:
{
MYSQL_TIME
*
tm
=
(
MYSQL_TIME
*
)
param
->
buffer
;
tm
->
year
=
ltime
.
year
;
tm
->
month
=
ltime
.
month
;
tm
->
day
=
ltime
.
day
;
...
...
@@ -3203,33 +3286,33 @@ static void send_data_time(MYSQL_BIND *param, MYSQL_TIME ltime,
tm
->
second_part
=
ltime
.
second_part
;
tm
->
neg
=
ltime
.
neg
;
break
;
break
;
}
default:
{
char
buff
[
25
];
if
(
!
length
)
ltime
.
time_type
=
MYSQL_TIMESTAMP_NONE
;
switch
(
ltime
.
time_type
)
{
case
MYSQL_TIMESTAMP_DATE
:
length
=
my_sprintf
(
buff
,(
buff
,
"%04d-%02d-%02d"
,
ltime
.
year
,
ltime
.
month
,
ltime
.
day
));
ltime
.
month
,
ltime
.
day
));
break
;
case
MYSQL_TIMESTAMP_FULL
:
length
=
my_sprintf
(
buff
,(
buff
,
"%04d-%02d-%02d %02d:%02d:%02d"
,
ltime
.
year
,
ltime
.
month
,
ltime
.
day
,
ltime
.
hour
,
ltime
.
minute
,
ltime
.
second
));
ltime
.
year
,
ltime
.
month
,
ltime
.
day
,
ltime
.
hour
,
ltime
.
minute
,
ltime
.
second
));
break
;
case
MYSQL_TIMESTAMP_TIME
:
length
=
my_sprintf
(
buff
,
(
buff
,
"%02d:%02d:%02d"
,
ltime
.
hour
,
ltime
.
minute
,
ltime
.
second
));
ltime
.
hour
,
ltime
.
minute
,
ltime
.
second
));
break
;
default:
length
=
0
;
buff
[
0
]
=
'\0'
;
}
send_data_str
(
param
,
(
char
*
)
buff
,
length
);
send_data_str
(
param
,
(
char
*
)
buff
,
length
);
}
}
}
...
...
@@ -3261,7 +3344,7 @@ static void fetch_results(MYSQL_BIND *param, MYSQL_FIELD *field, uchar **row)
longlong
data
=
((
field_is_unsigned
)
?
(
longlong
)
(
unsigned
short
)
value
:
(
longlong
)
value
);
send_data_long
(
param
,
field
,
data
);
length
=
2
;
length
=
2
;
break
;
}
case
MYSQL_TYPE_LONG
:
...
...
@@ -3300,7 +3383,7 @@ static void fetch_results(MYSQL_BIND *param, MYSQL_FIELD *field, uchar **row)
case
MYSQL_TYPE_DATE
:
{
MYSQL_TIME
tm
;
length
=
read_binary_date
(
&
tm
,
row
);
tm
.
time_type
=
MYSQL_TIMESTAMP_DATE
;
send_data_time
(
param
,
tm
,
length
);
...
...
@@ -3309,7 +3392,7 @@ static void fetch_results(MYSQL_BIND *param, MYSQL_FIELD *field, uchar **row)
case
MYSQL_TYPE_TIME
:
{
MYSQL_TIME
tm
;
length
=
read_binary_time
(
&
tm
,
row
);
tm
.
time_type
=
MYSQL_TIMESTAMP_TIME
;
send_data_time
(
param
,
tm
,
length
);
...
...
@@ -3319,14 +3402,14 @@ static void fetch_results(MYSQL_BIND *param, MYSQL_FIELD *field, uchar **row)
case
MYSQL_TYPE_TIMESTAMP
:
{
MYSQL_TIME
tm
;
length
=
read_binary_datetime
(
&
tm
,
row
);
tm
.
time_type
=
MYSQL_TIMESTAMP_FULL
;
send_data_time
(
param
,
tm
,
length
);
break
;
}
default:
length
=
net_field_length
(
row
);
default:
length
=
net_field_length
(
row
);
send_data_str
(
param
,(
char
*
)
*
row
,
length
);
break
;
}
...
...
@@ -3355,7 +3438,7 @@ static void fetch_result_int32(MYSQL_BIND *param, uchar **row)
}
static
void
fetch_result_int64
(
MYSQL_BIND
*
param
,
uchar
**
row
)
{
{
longlong
value
=
(
longlong
)
sint8korr
(
*
row
);
longlongstore
(
param
->
buffer
,
value
);
*
row
+=
8
;
...
...
@@ -3396,11 +3479,11 @@ static void fetch_result_datetime(MYSQL_BIND *param, uchar **row)
}
static
void
fetch_result_bin
(
MYSQL_BIND
*
param
,
uchar
**
row
)
{
{
ulong
length
=
net_field_length
(
row
);
ulong
copy_length
=
min
(
length
,
param
->
buffer_length
);
memcpy
(
param
->
buffer
,
(
char
*
)
*
row
,
copy_length
);
*
param
->
length
=
length
;
*
param
->
length
=
length
;
*
row
+=
length
;
}
...
...
@@ -3481,7 +3564,7 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
We only need to check that stmt->field_count - if it is not null
stmt->bind was initialized in mysql_stmt_prepare
*/
memcpy
((
char
*
)
stmt
->
bind
,
(
char
*
)
bind
,
sizeof
(
MYSQL_BIND
)
*
bind_count
);
for
(
param
=
stmt
->
bind
,
end
=
param
+
bind_count
,
field
=
stmt
->
fields
;
...
...
@@ -3643,16 +3726,16 @@ static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row)
/* If output parameters were not bound we should just return success */
return
0
;
}
null_ptr
=
row
;
null_ptr
=
row
;
row
+=
(
stmt
->
field_count
+
9
)
/
8
;
/* skip null bits */
bit
=
4
;
/* first 2 bits are reserved */
/* Copy complete row to application buffers */
for
(
bind
=
stmt
->
bind
,
end
=
bind
+
stmt
->
field_count
,
field
=
stmt
->
fields
;
bind
<
end
;
bind
++
,
field
++
)
{
{
if
(
*
null_ptr
&
bit
)
{
/*
...
...
@@ -3666,12 +3749,12 @@ static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row)
*
bind
->
is_null
=
1
;
}
else
{
{
*
bind
->
is_null
=
0
;
bind
->
inter_buffer
=
row
;
if
(
field
->
type
==
bind
->
buffer_type
)
(
*
bind
->
fetch_result
)(
bind
,
&
row
);
else
else
fetch_results
(
bind
,
field
,
&
row
);
}
if
(
!
((
bit
<<=
1
)
&
255
))
...
...
@@ -3731,15 +3814,15 @@ int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt)
column Column to fetch (first column is 0)
ulong offset Offset in result data (to fetch blob in pieces)
This is normally 0
RETURN
RETURN
0 ok
1 error
*/
int
STDCALL
mysql_stmt_fetch_column
(
MYSQL_STMT
*
stmt
,
MYSQL_BIND
*
bind
,
int
STDCALL
mysql_stmt_fetch_column
(
MYSQL_STMT
*
stmt
,
MYSQL_BIND
*
bind
,
uint
column
,
ulong
offset
)
{
MYSQL_BIND
*
param
=
stmt
->
bind
+
column
;
MYSQL_BIND
*
param
=
stmt
->
bind
+
column
;
DBUG_ENTER
(
"mysql_stmt_fetch_column"
);
if
((
int
)
stmt
->
state
<
(
int
)
MYSQL_STMT_FETCH_DONE
)
...
...
@@ -3755,7 +3838,7 @@ int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind,
if
(
param
->
inter_buffer
)
{
MYSQL_FIELD
*
field
=
stmt
->
fields
+
column
;
MYSQL_FIELD
*
field
=
stmt
->
fields
+
column
;
uchar
*
row
=
param
->
inter_buffer
;
bind
->
offset
=
offset
;
if
(
bind
->
is_null
)
...
...
@@ -3825,6 +3908,49 @@ int cli_read_binary_rows(MYSQL_STMT *stmt)
}
/*
Update meta data for statement
SYNOPSIS
stmt_update_metadata()
stmt Statement handler
row Binary data
NOTES
Only updates MYSQL_FIELD->max_length for strings
*/
static
void
stmt_update_metadata
(
MYSQL_STMT
*
stmt
,
MYSQL_ROWS
*
data
)
{
MYSQL_BIND
*
bind
,
*
end
;
MYSQL_FIELD
*
field
;
uchar
*
null_ptr
,
bit
;
uchar
*
row
=
(
uchar
*
)
data
->
data
;
#ifndef DBUG_OFF
uchar
*
row_end
=
row
+
data
->
length
;
#endif
null_ptr
=
row
;
row
+=
(
stmt
->
field_count
+
9
)
/
8
;
/* skip null bits */
bit
=
4
;
/* first 2 bits are reserved */
/* Go throw all fields and calculate metadata */
for
(
bind
=
stmt
->
bind
,
end
=
bind
+
stmt
->
field_count
,
field
=
stmt
->
fields
;
bind
<
end
;
bind
++
,
field
++
)
{
if
(
!
(
*
null_ptr
&
bit
))
(
*
bind
->
skip_result
)(
bind
,
field
,
&
row
);
DBUG_ASSERT
(
row
<=
row_end
);
if
(
!
((
bit
<<=
1
)
&
255
))
{
bit
=
1
;
/* To next byte */
null_ptr
++
;
}
}
}
/*
Store or buffer the binary results to stmt
*/
...
...
@@ -3909,7 +4035,7 @@ mysql_stmt_row_seek(MYSQL_STMT *stmt, MYSQL_ROW_OFFSET row)
{
MYSQL_ROW_OFFSET
offset
=
stmt
->
data_cursor
;
DBUG_ENTER
(
"mysql_stmt_row_seek"
);
stmt
->
data_cursor
=
row
;
DBUG_RETURN
(
offset
);
}
...
...
@@ -3919,11 +4045,11 @@ mysql_stmt_row_seek(MYSQL_STMT *stmt, MYSQL_ROW_OFFSET row)
Return the current statement row cursor position
*/
MYSQL_ROW_OFFSET
STDCALL
MYSQL_ROW_OFFSET
STDCALL
mysql_stmt_row_tell
(
MYSQL_STMT
*
stmt
)
{
DBUG_ENTER
(
"mysql_stmt_row_tell"
);
DBUG_RETURN
(
stmt
->
data_cursor
);
}
...
...
@@ -3938,7 +4064,7 @@ mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong row)
MYSQL_ROWS
*
tmp
=
stmt
->
result
.
data
;
DBUG_ENTER
(
"mysql_stmt_data_seek"
);
DBUG_PRINT
(
"enter"
,(
"row id to seek: %ld"
,(
long
)
row
));
for
(;
tmp
&&
row
;
--
row
,
tmp
=
tmp
->
next
)
;
stmt
->
data_cursor
=
tmp
;
...
...
@@ -3953,7 +4079,7 @@ mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong row)
my_ulonglong
STDCALL
mysql_stmt_num_rows
(
MYSQL_STMT
*
stmt
)
{
DBUG_ENTER
(
"mysql_stmt_num_rows"
);
DBUG_RETURN
(
stmt
->
result
.
rows
);
}
...
...
@@ -3963,7 +4089,7 @@ my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt)
DBUG_ENTER
(
"mysql_stmt_free_result"
);
DBUG_ASSERT
(
stmt
!=
0
);
if
((
int
)
stmt
->
state
>
(
int
)
MYSQL_STMT_INIT_DONE
)
{
MYSQL
*
mysql
=
stmt
->
mysql
;
...
...
@@ -4031,7 +4157,7 @@ my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt)
mysql
->
unbuffered_fetch_owner
=
0
;
if
(
mysql
->
status
!=
MYSQL_STATUS_READY
)
{
/*
/*
Flush result set of the connection. If it does not belong
to this statement, set a warning.
*/
...
...
@@ -4069,13 +4195,13 @@ my_bool STDCALL mysql_stmt_reset(MYSQL_STMT *stmt)
/* If statement hasnt been prepared there is nothing to reset */
if
((
int
)
stmt
->
state
<
(
int
)
MYSQL_STMT_PREPARE_DONE
)
DBUG_RETURN
(
0
);
mysql
=
stmt
->
mysql
->
last_used_con
;
int4store
(
buff
,
stmt
->
stmt_id
);
/* Send stmt id to server */
if
((
*
mysql
->
methods
->
advanced_command
)(
mysql
,
COM_RESET_STMT
,
buff
,
sizeof
(
buff
),
0
,
0
,
0
))
{
set_stmt_errmsg
(
stmt
,
mysql
->
net
.
last_error
,
mysql
->
net
.
last_errno
,
set_stmt_errmsg
(
stmt
,
mysql
->
net
.
last_error
,
mysql
->
net
.
last_errno
,
mysql
->
net
.
sqlstate
);
DBUG_RETURN
(
1
);
}
...
...
@@ -4116,50 +4242,6 @@ const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt)
}
/*
Update meta data for statement
SYNOPSIS
stmt_update_metadata()
stmt Statement handler
row Binary data
NOTES
Only updates MYSQL_FIELD->max_length for strings
*/
static
void
stmt_update_metadata
(
MYSQL_STMT
*
stmt
,
MYSQL_ROWS
*
data
)
{
MYSQL_BIND
*
bind
,
*
end
;
MYSQL_FIELD
*
field
;
uchar
*
null_ptr
,
bit
;
uchar
*
row
=
(
uchar
*
)
data
->
data
;
#ifndef DBUG_OFF
uchar
*
row_end
=
row
+
data
->
length
;
#endif
null_ptr
=
row
;
row
+=
(
stmt
->
field_count
+
9
)
/
8
;
/* skip null bits */
bit
=
4
;
/* first 2 bits are reserved */
/* Go throw all fields and calculate metadata */
for
(
bind
=
stmt
->
bind
,
end
=
bind
+
stmt
->
field_count
,
field
=
stmt
->
fields
;
bind
<
end
;
bind
++
,
field
++
)
{
if
(
!
(
*
null_ptr
&
bit
))
(
*
bind
->
skip_result
)(
bind
,
field
,
&
row
);
DBUG_ASSERT
(
row
<=
row_end
);
if
(
!
((
bit
<<=
1
)
&
255
))
{
bit
=
1
;
/* To next byte */
null_ptr
++
;
}
}
}
/********************************************************************
Transactional APIs
*********************************************************************/
...
...
@@ -4213,10 +4295,10 @@ my_bool STDCALL mysql_more_results(MYSQL *mysql)
{
my_bool
res
;
DBUG_ENTER
(
"mysql_more_results"
);
res
=
((
mysql
->
last_used_con
->
server_status
&
SERVER_MORE_RESULTS_EXISTS
)
?
res
=
((
mysql
->
last_used_con
->
server_status
&
SERVER_MORE_RESULTS_EXISTS
)
?
1
:
0
);
DBUG_PRINT
(
"exit"
,(
"More results exists ? %d"
,
res
));
DBUG_PRINT
(
"exit"
,(
"More results exists ? %d"
,
res
));
DBUG_RETURN
(
res
);
}
...
...
@@ -4227,7 +4309,7 @@ my_bool STDCALL mysql_more_results(MYSQL *mysql)
int
STDCALL
mysql_next_result
(
MYSQL
*
mysql
)
{
DBUG_ENTER
(
"mysql_next_result"
);
if
(
mysql
->
status
!=
MYSQL_STATUS_READY
)
{
strmov
(
mysql
->
net
.
sqlstate
,
unknown_sqlstate
);
...
...
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