mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 11:01:52 +01:00
Merge bk-internal.mysql.com:/home/bk/mysql-4.1
into mysql.com:/home/kostja/mysql/mysql-4.1-4030
This commit is contained in:
commit
834e9f870e
2 changed files with 237 additions and 155 deletions
|
@ -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 */
|
||||
|
|
|
@ -2130,10 +2130,23 @@ mysql_stmt_result_metadata(MYSQL_STMT *stmt)
|
|||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Returns parameter columns meta information in the form of
|
||||
result set.
|
||||
|
||||
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
|
||||
|
@ -2146,25 +2159,36 @@ mysql_stmt_param_metadata(MYSQL_STMT *stmt)
|
|||
|
||||
/*
|
||||
TODO: Fix this when server sends the information.
|
||||
Till then keep a dummy prototype
|
||||
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)
|
||||
|
@ -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,7 +2365,7 @@ 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;
|
||||
|
@ -2365,14 +2391,6 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length)
|
|||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
DBUG_ENTER("cli_stmt_execute");
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -3825,6 +3908,49 @@ err:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
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
|
||||
*/
|
||||
|
@ -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
|
||||
*********************************************************************/
|
||||
|
|
Loading…
Add table
Reference in a new issue