mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
Intermediate commit of client library (cleanups + fixes of 3 items from
flaws list) TODO: * verify that no sequence of API calls produces SIGSEGV. That is, verify that mysql_stmt_init -> mysql_stmt_fetch is OK, or mysql_stmt_prepare -> mysql_stmt_fetch_column is OK and sets meaningful error. * remove alloc_stmt_fields call * revise stmt->state codes and statement states. * there are other items in prepared statements 'to fix' document. Done: - cleanups and comments - revision of prepared statement error codes. - mysql_stmt_prepare is now can always be called (that is, you can reprepare a statement) - new implementation of mysql_stmt_close and fetch cancellation include/errmsg.h: - CR_NOT_ALL_PARAMS_BOUND - this error code wasn't used until now. Apparently it was added in advance, but then interface of mysql_stmt_bind_param changed. Now it's not possible to bind only some parameters - either all or none of parameters are bound. This error code is renamed to CR_PARAMS_NOT_BOUND - CR_FETCH_CANCELLED - error code set on server side when fetch from MYSQL_RES or MYSQL_STMT (in blocking mode) was cancelled because of intercepting call to mysql_stmt_close - CR_NO_DATA - this is proposed error code to return from mysql_stmt_fetch_column if no row was fetched (by any type of fetch). We always can fall back to CR_COMMANDS_OUT_OF_SYNC though. Need reviewer's opinion on this one. include/mysql.h: - added unbuffered_fetch_owner member to MYSQL to point to MYSQL_RES or MYSQL_STMT which is used to fetch result at the moment. This is to be able to set CR_FETCH_CANCELLED error without fantoms. - added unbuffered_fetch_cancelled boolean variable to MYSQL_STMT and MYSQL_RES structures - rename PREP_STMT_STATE -> enum enum_mysql_stmt_state - members of MYSQL_STMT ordered by size. - removed members of MYSQL_STMT: current_row, result_buffered, last_fetched_column, last_fetched_buffer, query - renamed members of MYSQL_STMT: param_buffers -> bind_param_done, res_buffers -> bind_result_done - now mysql_stmt_fetch calls stmt->read_row_func to read row either from buffer or from network. include/sql_common.h: declaration for flush_use_result libmysql/client_settings.h: stmt_close declaration removed libmysql/errmsg.c: Error messages for changed and added error codes. libmysql/libmysql.c: Many changes: - some unused variables removed - cleanups - better error reporting - some function calls commented - alloc_stmt_fields is now called right after execute, to not read mysql->fields of some other statement - new implementation of mysql_stmt_fetch - this is also with cursor fetch in mind (to implement cursor fetch I'll just need to write special read_row function for it, so this change will be local) - implementation of fetch cancellation, including complete rewrite of mysql_stmt_close - now mysql_stmt_free_result doesn't free results of other statements. sql-common/client.c: - implementation of flush_use_result - implementation of fetch cancellation - changed behaviour of mysql_close in regard to mysql_stmt_close - now mysql_close just set stmt->mysql to 0
This commit is contained in:
@@ -256,6 +256,11 @@ typedef struct st_mysql
|
||||
LIST *stmts; /* list of all statements */
|
||||
const struct st_mysql_methods *methods;
|
||||
void *thd;
|
||||
/*
|
||||
Points to boolean flag in MYSQL_RES or MYSQL_STMT. We set this flag
|
||||
from mysql_stmt_close if close had to cancel result set of this object.
|
||||
*/
|
||||
my_bool *unbuffered_fetch_owner;
|
||||
} MYSQL;
|
||||
|
||||
typedef struct st_mysql_res {
|
||||
@@ -270,6 +275,8 @@ typedef struct st_mysql_res {
|
||||
MYSQL_ROW row; /* If unbuffered read */
|
||||
MYSQL_ROW current_row; /* buffer to current row */
|
||||
my_bool eof; /* Used by mysql_fetch_row */
|
||||
/* mysql_stmt_close() had to cancel this result */
|
||||
my_bool unbuffered_fetch_cancelled;
|
||||
const struct st_mysql_methods *methods;
|
||||
} MYSQL_RES;
|
||||
|
||||
@@ -479,7 +486,11 @@ my_bool STDCALL mysql_read_query_result(MYSQL *mysql);
|
||||
*/
|
||||
|
||||
/* statement state */
|
||||
enum PREP_STMT_STATE { MY_ST_UNKNOWN, MY_ST_PREPARE, MY_ST_EXECUTE };
|
||||
enum enum_mysql_stmt_state
|
||||
{
|
||||
MYSQL_STMT_INIT_DONE= 1, MYSQL_STMT_PREPARE_DONE, MYSQL_STMT_EXECUTE_DONE,
|
||||
MYSQL_STMT_FETCH_DONE
|
||||
};
|
||||
|
||||
/*
|
||||
client TIME structure to handle TIME, DATE and TIMESTAMP directly in
|
||||
@@ -525,31 +536,34 @@ typedef struct st_mysql_bind
|
||||
/* statement handler */
|
||||
typedef struct st_mysql_stmt
|
||||
{
|
||||
MYSQL *mysql; /* connection handle */
|
||||
MYSQL_BIND *params; /* input parameters */
|
||||
MYSQL_RES *result; /* resultset */
|
||||
MYSQL_BIND *bind; /* row binding */
|
||||
MYSQL_FIELD *fields; /* prepare meta info */
|
||||
MEM_ROOT mem_root; /* root allocations */
|
||||
LIST list; /* list to keep track of all stmts */
|
||||
unsigned char *current_row; /* unbuffered row */
|
||||
unsigned char *last_fetched_buffer; /* last fetched column buffer */
|
||||
char *query; /* query buffer */
|
||||
MEM_ROOT mem_root; /* root allocations */
|
||||
my_ulonglong last_fetched_column; /* last fetched column */
|
||||
MYSQL *mysql; /* connection handle */
|
||||
MYSQL_BIND *params; /* input parameters */
|
||||
MYSQL_BIND *bind; /* output parameters */
|
||||
MYSQL_FIELD *fields; /* result set metadata */
|
||||
MYSQL_RES *result; /* cached result set */
|
||||
/* copy of mysql->affected_rows after statement execution */
|
||||
my_ulonglong affected_rows;
|
||||
/*
|
||||
mysql_stmt_fetch() calls this function to fetch one row (it's different
|
||||
for buffered, unbuffered and cursor fetch).
|
||||
*/
|
||||
int (*read_row_func)(struct st_mysql_stmt *stmt,
|
||||
unsigned char **row);
|
||||
unsigned long stmt_id; /* Id for prepared statement */
|
||||
unsigned int last_errno; /* error code */
|
||||
unsigned int param_count; /* parameters count */
|
||||
unsigned int field_count; /* fields count */
|
||||
enum PREP_STMT_STATE state; /* statement state */
|
||||
unsigned int param_count; /* inpute parameters count */
|
||||
unsigned int field_count; /* number of columns in result set */
|
||||
enum enum_mysql_stmt_state state; /* statement state */
|
||||
char last_error[MYSQL_ERRMSG_SIZE]; /* error message */
|
||||
char sqlstate[SQLSTATE_LENGTH+1];
|
||||
my_bool long_alloced; /* flag to indicate long alloced */
|
||||
my_bool send_types_to_server; /* Types sent to server */
|
||||
my_bool param_buffers; /* param bound buffers */
|
||||
my_bool res_buffers; /* output bound buffers */
|
||||
my_bool result_buffered; /* Results buffered */
|
||||
/* Types of input parameters should be sent to server */
|
||||
my_bool send_types_to_server;
|
||||
my_bool bind_param_done; /* input buffers were supplied */
|
||||
my_bool bind_result_done; /* output buffers were supplied */
|
||||
/* mysql_stmt_close() had to cancel this result */
|
||||
my_bool unbuffered_fetch_cancelled;
|
||||
} MYSQL_STMT;
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user