Commit 117d1833 authored by hf@deer.(none)'s avatar hf@deer.(none)

Merge abotchkov@bk-internal.mysql.com:/home/bk/mysql-4.1

into deer.(none):/home/hf/work/mysql-4.1.stmt
parents 87fb862e 7a763f3f
...@@ -250,7 +250,6 @@ typedef struct st_mysql ...@@ -250,7 +250,6 @@ typedef struct st_mysql
LIST *stmts; /* list of all statements */ LIST *stmts; /* list of all statements */
const struct st_mysql_methods *methods; const struct st_mysql_methods *methods;
struct st_mysql_res *result;
void *thd; void *thd;
} MYSQL; } MYSQL;
...@@ -359,6 +358,8 @@ int STDCALL mysql_send_query(MYSQL *mysql, const char *q, ...@@ -359,6 +358,8 @@ int STDCALL mysql_send_query(MYSQL *mysql, const char *q,
unsigned long length); unsigned long length);
int STDCALL mysql_real_query(MYSQL *mysql, const char *q, int STDCALL mysql_real_query(MYSQL *mysql, const char *q,
unsigned long length); unsigned long length);
MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql);
/* perform query on master */ /* perform query on master */
my_bool STDCALL mysql_master_query(MYSQL *mysql, const char *q, my_bool STDCALL mysql_master_query(MYSQL *mysql, const char *q,
unsigned long length); unsigned long length);
...@@ -427,6 +428,8 @@ MYSQL_FIELD_OFFSET STDCALL mysql_field_seek(MYSQL_RES *result, ...@@ -427,6 +428,8 @@ MYSQL_FIELD_OFFSET STDCALL mysql_field_seek(MYSQL_RES *result,
MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result); MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result);
unsigned long * STDCALL mysql_fetch_lengths(MYSQL_RES *result); unsigned long * STDCALL mysql_fetch_lengths(MYSQL_RES *result);
MYSQL_FIELD * STDCALL mysql_fetch_field(MYSQL_RES *result); MYSQL_FIELD * STDCALL mysql_fetch_field(MYSQL_RES *result);
MYSQL_RES * STDCALL mysql_list_fields(MYSQL *mysql, const char *table,
const char *wild);
unsigned long STDCALL mysql_escape_string(char *to,const char *from, unsigned long STDCALL mysql_escape_string(char *to,const char *from,
unsigned long from_length); unsigned long from_length);
unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql, unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql,
...@@ -538,9 +541,7 @@ typedef struct st_mysql_stmt ...@@ -538,9 +541,7 @@ typedef struct st_mysql_stmt
#define mysql_read_query_result(mysql) (*(mysql)->methods->read_query_result)(mysql) #define mysql_read_query_result(mysql) (*(mysql)->methods->read_query_result)(mysql)
#define mysql_store_result(mysql) (*(mysql)->methods->store_result)(mysql)
#define mysql_use_result(mysql) (*(mysql)->methods->use_result)(mysql) #define mysql_use_result(mysql) (*(mysql)->methods->use_result)(mysql)
#define mysql_list_fields(mysql, table, wild) (*(mysql)->methods->list_fields)(mysql, table, wild)
typedef struct st_mysql_methods typedef struct st_mysql_methods
{ {
...@@ -552,12 +553,14 @@ typedef struct st_mysql_methods ...@@ -552,12 +553,14 @@ typedef struct st_mysql_methods
const char *arg, const char *arg,
unsigned long arg_length, unsigned long arg_length,
my_bool skip_check); my_bool skip_check);
MYSQL_RES * (STDCALL *store_result)(MYSQL *mysql); MYSQL_DATA *(STDCALL *read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
uint fields);
MYSQL_RES * (STDCALL *use_result)(MYSQL *mysql); MYSQL_RES * (STDCALL *use_result)(MYSQL *mysql);
void (STDCALL *fetch_lengths)(unsigned long *to, void (STDCALL *fetch_lengths)(unsigned long *to,
MYSQL_ROW column, uint field_count); MYSQL_ROW column, uint field_count);
MYSQL_RES * (STDCALL *list_fields)(MYSQL *mysql, const char *table, MYSQL_FIELD * (STDCALL *list_fields)(MYSQL *mysql);
const char *wild); my_bool (STDCALL *read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
int (STDCALL *stmt_execute)(MYSQL_STMT *stmt);
} MYSQL_METHODS; } MYSQL_METHODS;
MYSQL_STMT * STDCALL mysql_prepare(MYSQL * mysql, const char *query, MYSQL_STMT * STDCALL mysql_prepare(MYSQL * mysql, const char *query,
......
...@@ -28,14 +28,19 @@ my_ulonglong net_field_length_ll(uchar **packet); ...@@ -28,14 +28,19 @@ my_ulonglong net_field_length_ll(uchar **packet);
MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
my_bool default_value, uint server_capabilities); my_bool default_value, uint server_capabilities);
void free_rows(MYSQL_DATA *cur); void free_rows(MYSQL_DATA *cur);
MYSQL_DATA *read_rows (MYSQL *mysql,MYSQL_FIELD *fields,
uint field_count);
my_bool mysql_autenticate(MYSQL *mysql, const char *passwd); my_bool mysql_autenticate(MYSQL *mysql, const char *passwd);
void free_old_query(MYSQL *mysql); void free_old_query(MYSQL *mysql);
void end_server(MYSQL *mysql); void end_server(MYSQL *mysql);
my_bool mysql_reconnect(MYSQL *mysql); my_bool mysql_reconnect(MYSQL *mysql);
void mysql_read_default_options(struct st_mysql_options *options, void mysql_read_default_options(struct st_mysql_options *options,
const char *filename,const char *group); const char *filename,const char *group);
my_bool STDCALL
cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
const char *header, ulong header_length,
const char *arg, ulong arg_length, my_bool skip_check);
void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode,
const char *sqlstate);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -41,5 +41,17 @@ my_bool send_file_to_server(MYSQL *mysql, const char *filename); ...@@ -41,5 +41,17 @@ my_bool send_file_to_server(MYSQL *mysql, const char *filename);
#define reset_sigpipe(mysql) #define reset_sigpipe(mysql)
#endif #endif
MYSQL_RES * STDCALL cli_list_fields(MYSQL *mysql, const char *table, const char *wild); void mysql_read_default_options(struct st_mysql_options *options,
const char *filename,const char *group);
MYSQL * STDCALL
cli_mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db,
uint port, const char *unix_socket,ulong client_flag);
void STDCALL cli_mysql_close(MYSQL *mysql);
MYSQL_FIELD * STDCALL cli_list_fields(MYSQL *mysql);
my_bool STDCALL cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt);
MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
uint fields);
int STDCALL cli_stmt_execute(MYSQL_STMT *stmt);
...@@ -973,6 +973,19 @@ mysql_list_tables(MYSQL *mysql, const char *wild) ...@@ -973,6 +973,19 @@ mysql_list_tables(MYSQL *mysql, const char *wild)
DBUG_RETURN (mysql_store_result(mysql)); DBUG_RETURN (mysql_store_result(mysql));
} }
MYSQL_FIELD * STDCALL cli_list_fields(MYSQL *mysql)
{
MYSQL_DATA *query;
if (!(query= cli_read_rows(mysql,(MYSQL_FIELD*) 0,
protocol_41(mysql) ? 8 : 6)))
return NULL;
mysql->field_count= query->rows;
return unpack_fields(query,&mysql->field_alloc,
query->rows, 1, mysql->server_capabilities);
}
/************************************************************************** /**************************************************************************
List all fields in a table List all fields in a table
If wild is given then only the fields matching wild is returned If wild is given then only the fields matching wild is returned
...@@ -981,36 +994,29 @@ mysql_list_tables(MYSQL *mysql, const char *wild) ...@@ -981,36 +994,29 @@ mysql_list_tables(MYSQL *mysql, const char *wild)
**************************************************************************/ **************************************************************************/
MYSQL_RES * STDCALL MYSQL_RES * STDCALL
cli_list_fields(MYSQL *mysql, const char *table, const char *wild) mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)
{ {
MYSQL_RES *result; MYSQL_RES *result;
MYSQL_DATA *query; MYSQL_FIELD *fields;
char buff[257],*end; char buff[257],*end;
DBUG_ENTER("mysql_list_fields"); DBUG_ENTER("mysql_list_fields");
DBUG_PRINT("enter",("table: '%s' wild: '%s'",table,wild ? wild : "")); DBUG_PRINT("enter",("table: '%s' wild: '%s'",table,wild ? wild : ""));
LINT_INIT(query);
end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128); end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128);
free_old_query(mysql);
if (simple_command(mysql,COM_FIELD_LIST,buff,(ulong) (end-buff),1) || if (simple_command(mysql,COM_FIELD_LIST,buff,(ulong) (end-buff),1) ||
!(query = read_rows(mysql,(MYSQL_FIELD*) 0, !(fields= (*mysql->methods->list_fields)(mysql)))
protocol_41(mysql) ? 8 : 6)))
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
free_old_query(mysql);
if (!(result = (MYSQL_RES *) my_malloc(sizeof(MYSQL_RES), if (!(result = (MYSQL_RES *) my_malloc(sizeof(MYSQL_RES),
MYF(MY_WME | MY_ZEROFILL)))) MYF(MY_WME | MY_ZEROFILL))))
{
free_rows(query);
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
}
result->methods= mysql->methods; result->methods= mysql->methods;
result->field_alloc=mysql->field_alloc; result->field_alloc=mysql->field_alloc;
mysql->fields=0; mysql->fields=0;
result->field_count = (uint) query->rows; result->field_count = mysql->field_count;
result->fields= unpack_fields(query,&result->field_alloc, result->fields= fields;
result->field_count, 1,
mysql->server_capabilities);
result->eof=1; result->eof=1;
DBUG_RETURN(result); DBUG_RETURN(result);
} }
...@@ -1031,8 +1037,8 @@ mysql_list_processes(MYSQL *mysql) ...@@ -1031,8 +1037,8 @@ mysql_list_processes(MYSQL *mysql)
free_old_query(mysql); free_old_query(mysql);
pos=(uchar*) mysql->net.read_pos; pos=(uchar*) mysql->net.read_pos;
field_count=(uint) net_field_length(&pos); field_count=(uint) net_field_length(&pos);
if (!(fields = read_rows(mysql,(MYSQL_FIELD*) 0, if (!(fields = (*mysql->methods->read_rows)(mysql,(MYSQL_FIELD*) 0,
protocol_41(mysql) ? 7 : 5))) protocol_41(mysql) ? 7 : 5)))
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,field_count,0, if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,field_count,0,
mysql->server_capabilities))) mysql->server_capabilities)))
...@@ -1488,8 +1494,8 @@ static void set_stmt_error(MYSQL_STMT * stmt, int errcode, ...@@ -1488,8 +1494,8 @@ static void set_stmt_error(MYSQL_STMT * stmt, int errcode,
Copy error message to statement handler Copy error message to statement handler
*/ */
static void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode, void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode,
const char *sqlstate) const char *sqlstate)
{ {
DBUG_ENTER("set_stmt_error_msg"); DBUG_ENTER("set_stmt_error_msg");
DBUG_PRINT("enter", ("error: %d/%s '%s'", errcode, sqlstate, err)); DBUG_PRINT("enter", ("error: %d/%s '%s'", errcode, sqlstate, err));
...@@ -1563,7 +1569,7 @@ static my_bool my_realloc_str(NET *net, ulong length) ...@@ -1563,7 +1569,7 @@ static my_bool my_realloc_str(NET *net, ulong length)
1 error 1 error
*/ */
static my_bool read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) my_bool STDCALL cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
{ {
uchar *pos; uchar *pos;
uint field_count; uint field_count;
...@@ -1586,25 +1592,25 @@ static my_bool read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) ...@@ -1586,25 +1592,25 @@ static my_bool read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
mysql->server_status|= SERVER_STATUS_IN_TRANS; mysql->server_status|= SERVER_STATUS_IN_TRANS;
mysql->extra_info= net_field_length_ll(&pos); mysql->extra_info= net_field_length_ll(&pos);
if (!(fields_data= read_rows(mysql, (MYSQL_FIELD*) 0, 7))) if (!(fields_data= (*mysql->methods->read_rows)(mysql,(MYSQL_FIELD*)0,7)))
DBUG_RETURN(1); DBUG_RETURN(1);
if (!(stmt->fields= unpack_fields(fields_data,&stmt->mem_root, if (!(stmt->fields= unpack_fields(fields_data,&stmt->mem_root,
field_count,0, field_count,0,
mysql->server_capabilities))) mysql->server_capabilities)))
DBUG_RETURN(1); DBUG_RETURN(1);
} }
stmt->field_count= (uint) field_count;
stmt->param_count= (ulong) param_count;
if (!(stmt->params= (MYSQL_BIND *) alloc_root(&stmt->mem_root, if (!(stmt->params= (MYSQL_BIND *) alloc_root(&stmt->mem_root,
sizeof(MYSQL_BIND)* sizeof(MYSQL_BIND)*
(param_count + (stmt->param_count +
field_count)))) stmt->field_count))))
{ {
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate); set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
DBUG_RETURN(0); DBUG_RETURN(1);
} }
stmt->bind= (stmt->params + param_count); stmt->bind= stmt->params + stmt->param_count;
stmt->field_count= (uint) field_count;
stmt->param_count= (ulong) param_count;
mysql->status= MYSQL_STATUS_READY;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -1648,14 +1654,16 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length) ...@@ -1648,14 +1654,16 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length)
} }
init_alloc_root(&stmt->mem_root,8192,0); init_alloc_root(&stmt->mem_root,8192,0);
if (read_prepare_result(mysql, stmt)) if ((*mysql->methods->read_prepare_result)(mysql, stmt))
{ {
stmt_close(stmt, 1); stmt_close(stmt, 1);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
stmt->state= MY_ST_PREPARE; stmt->state= MY_ST_PREPARE;
stmt->mysql= mysql; stmt->mysql= mysql;
mysql->stmts= list_add(mysql->stmts, &stmt->list); mysql->stmts= list_add(mysql->stmts, &stmt->list);
mysql->status= MYSQL_STATUS_READY;
stmt->list.data= stmt; stmt->list.data= stmt;
DBUG_PRINT("info", ("Parameter count: %ld", stmt->param_count)); DBUG_PRINT("info", ("Parameter count: %ld", stmt->param_count));
DBUG_RETURN(stmt); DBUG_RETURN(stmt);
...@@ -1971,36 +1979,21 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length) ...@@ -1971,36 +1979,21 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length)
mysql->last_used_con= mysql; mysql->last_used_con= mysql;
int4store(buff, stmt->stmt_id); /* Send stmt id to server */ int4store(buff, stmt->stmt_id); /* Send stmt id to server */
if ((*mysql->methods->advanced_command)(mysql, COM_EXECUTE, buff, if (cli_advanced_command(mysql, COM_EXECUTE, buff,
MYSQL_STMT_HEADER, packet, MYSQL_STMT_HEADER, packet,
length, 1) || length, 1) ||
mysql_read_query_result(mysql)) mysql_read_query_result(mysql))
{ {
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
stmt->state= MY_ST_EXECUTE;
mysql_free_result(stmt->result);
stmt->result= (MYSQL_RES *)0;
stmt->result_buffered= 0;
stmt->current_row= 0;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
int STDCALL cli_stmt_execute(MYSQL_STMT *stmt)
/*
Execute the prepare query
*/
int STDCALL mysql_execute(MYSQL_STMT *stmt)
{ {
DBUG_ENTER("mysql_execute"); DBUG_ENTER("cli_stmt_execute");
if (stmt->state == MY_ST_UNKNOWN)
{
set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate);
DBUG_RETURN(1);
}
if (stmt->param_count) if (stmt->param_count)
{ {
NET *net= &stmt->mysql->net; NET *net= &stmt->mysql->net;
...@@ -2061,6 +2054,30 @@ int STDCALL mysql_execute(MYSQL_STMT *stmt) ...@@ -2061,6 +2054,30 @@ int STDCALL mysql_execute(MYSQL_STMT *stmt)
DBUG_RETURN((int) execute(stmt,0,0)); DBUG_RETURN((int) execute(stmt,0,0));
} }
/*
Execute the prepare query
*/
int STDCALL mysql_execute(MYSQL_STMT *stmt)
{
DBUG_ENTER("mysql_execute");
if (stmt->state == MY_ST_UNKNOWN)
{
set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate);
DBUG_RETURN(1);
}
if ((*stmt->mysql->methods->stmt_execute)(stmt))
DBUG_RETURN(1);
stmt->state= MY_ST_EXECUTE;
mysql_free_result(stmt->result);
stmt->result= (MYSQL_RES *)0;
stmt->result_buffered= 0;
stmt->current_row= 0;
DBUG_RETURN(0);
}
/* /*
Return total parameters count in the statement Return total parameters count in the statement
......
...@@ -26,4 +26,7 @@ C_MODE_START ...@@ -26,4 +26,7 @@ C_MODE_START
extern void lib_connection_phase(NET *net, int phase); extern void lib_connection_phase(NET *net, int phase);
extern void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db); extern void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db);
extern void *create_embedded_thd(int client_flag, char *db); extern void *create_embedded_thd(int client_flag, char *db);
extern MYSQL_METHODS embedded_methods;
void free_old_query(MYSQL *mysql);
extern my_bool server_inited;
C_MODE_END C_MODE_END
...@@ -50,7 +50,7 @@ static bool check_user(THD *thd, enum_server_command command, ...@@ -50,7 +50,7 @@ static bool check_user(THD *thd, enum_server_command command,
char * get_mysql_home(){ return mysql_home;}; char * get_mysql_home(){ return mysql_home;};
char * get_mysql_real_data_home(){ return mysql_real_data_home;}; char * get_mysql_real_data_home(){ return mysql_real_data_home;};
my_bool STDCALL static my_bool STDCALL
emb_advanced_command(MYSQL *mysql, enum enum_server_command command, emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
const char *header, ulong header_length, const char *header, ulong header_length,
const char *arg, ulong arg_length, my_bool skip_check) const char *arg, ulong arg_length, my_bool skip_check)
...@@ -94,6 +94,116 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, ...@@ -94,6 +94,116 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
return result; return result;
} }
static MYSQL_DATA * STDCALL
emb_read_rows(MYSQL *mysql, MYSQL_FIELD *mysql_fields __attribute__((unused)),
uint fields __attribute__((unused)))
{
MYSQL_DATA *result= ((THD*)mysql->thd)->data;
if (!result)
{
if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
MYF(MY_WME | MY_ZEROFILL))))
{
NET *net = &mysql->net;
net->last_errno=CR_OUT_OF_MEMORY;
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error,ER(net->last_errno));
return NULL;
}
return result;
}
*result->prev_ptr= NULL;
((THD*)mysql->thd)->data= NULL;
return result;
}
static MYSQL_FIELD * STDCALL emb_list_fields(MYSQL *mysql)
{
return mysql->fields;
}
static my_bool STDCALL emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
{
THD *thd= (THD*)mysql->thd;
stmt->stmt_id= thd->client_stmt_id;
stmt->param_count= thd->client_param_count;
stmt->field_count= mysql->field_count;
if (stmt->field_count != 0)
{
if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
mysql->server_status|= SERVER_STATUS_IN_TRANS;
stmt->fields= mysql->fields;
stmt->mem_root= mysql->field_alloc;
}
if (!(stmt->bind=
(MYSQL_BIND *) alloc_root(&stmt->mem_root,
sizeof(MYSQL_BIND)*stmt->field_count)))
{
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
return 1;
}
stmt->params= NULL; // we don't need parameter's buffer in embedded library
return 0;
}
/**************************************************************************
Get column lengths of the current row
If one uses mysql_use_result, res->lengths contains the length information,
else the lengths are calculated from the offset between pointers.
**************************************************************************/
static void STDCALL emb_fetch_lengths(ulong *to, MYSQL_ROW column, uint field_count)
{
MYSQL_ROW end;
for (end=column + field_count; column != end ; column++,to++)
*to= *column ? *(uint *)((*column) - sizeof(uint)) : 0;
}
static my_bool STDCALL emb_mysql_read_query_result(MYSQL *mysql)
{
if (mysql->net.last_errno)
return -1;
if (mysql->field_count)
mysql->status=MYSQL_STATUS_GET_RESULT;
return 0;
}
static int STDCALL emb_stmt_execute(MYSQL_STMT *stmt)
{
DBUG_ENTER("emb_stmt_execute");
THD *thd= (THD*)stmt->mysql->thd;
thd->client_param_count= stmt->param_count;
thd->client_parameters= stmt->params;
if (emb_advanced_command(stmt->mysql, COM_EXECUTE,0,0,
(const char*)&stmt->stmt_id,sizeof(stmt->stmt_id),1)
|| emb_mysql_read_query_result(stmt->mysql))
{
NET *net= &stmt->mysql->net;
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
DBUG_RETURN(1);
}
DBUG_RETURN(0);
}
MYSQL_METHODS embedded_methods=
{
emb_mysql_read_query_result,
emb_advanced_command,
emb_read_rows,
mysql_store_result,
emb_fetch_lengths,
emb_list_fields,
emb_read_prepare_result,
emb_stmt_execute
};
C_MODE_END C_MODE_END
void THD::clear_error() void THD::clear_error()
...@@ -334,6 +444,8 @@ void *create_embedded_thd(int client_flag, char *db) ...@@ -334,6 +444,8 @@ void *create_embedded_thd(int client_flag, char *db)
thd->master_access= ~NO_ACCESS; thd->master_access= ~NO_ACCESS;
thd->net.query_cache_query= 0; thd->net.query_cache_query= 0;
thd->data= 0;
return thd; return thd;
} }
...@@ -343,35 +455,29 @@ bool Protocol::send_fields(List<Item> *list, uint flag) ...@@ -343,35 +455,29 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
{ {
List_iterator_fast<Item> it(*list); List_iterator_fast<Item> it(*list);
Item *item; Item *item;
MYSQL_FIELD *field, *client_field; MYSQL_FIELD *client_field;
MYSQL *mysql= thd->mysql; MYSQL *mysql= thd->mysql;
MEM_ROOT *field_alloc;
DBUG_ENTER("send_fields"); DBUG_ENTER("send_fields");
field_count= list->elements; field_count= list->elements;
if (!(mysql->result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES)+ field_alloc= &mysql->field_alloc;
sizeof(ulong) * (field_count + 1), if (!(client_field= thd->mysql->fields=
MYF(MY_WME | MY_ZEROFILL)))) (MYSQL_FIELD *)alloc_root(field_alloc,
goto err; sizeof(MYSQL_FIELD) * field_count)))
mysql->result->lengths= (ulong *)(mysql->result + 1);
mysql->field_count=field_count;
alloc= &mysql->field_alloc;
field= (MYSQL_FIELD *)alloc_root(alloc, sizeof(MYSQL_FIELD) * field_count);
if (!field)
goto err; goto err;
client_field= field;
while ((item= it++)) while ((item= it++))
{ {
Send_field server_field; Send_field server_field;
item->make_field(&server_field); item->make_field(&server_field);
client_field->db= strdup_root(alloc, server_field.db_name); client_field->db= strdup_root(field_alloc, server_field.db_name);
client_field->table= strdup_root(alloc, server_field.table_name); client_field->table= strdup_root(field_alloc, server_field.table_name);
client_field->name= strdup_root(alloc, server_field.col_name); client_field->name= strdup_root(field_alloc, server_field.col_name);
client_field->org_table= strdup_root(alloc, server_field.org_table_name); client_field->org_table= strdup_root(field_alloc, server_field.org_table_name);
client_field->org_name= strdup_root(alloc, server_field.org_col_name); client_field->org_name= strdup_root(field_alloc, server_field.org_col_name);
client_field->length= server_field.length; client_field->length= server_field.length;
client_field->type= server_field.type; client_field->type= server_field.type;
client_field->flags= server_field.flags; client_field->flags= server_field.flags;
...@@ -392,31 +498,16 @@ bool Protocol::send_fields(List<Item> *list, uint flag) ...@@ -392,31 +498,16 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
String tmp(buff, sizeof(buff), default_charset_info), *res; String tmp(buff, sizeof(buff), default_charset_info), *res;
if (!(res=item->val_str(&tmp))) if (!(res=item->val_str(&tmp)))
client_field->def= strdup_root(alloc, ""); client_field->def= strdup_root(field_alloc, "");
else else
client_field->def= strdup_root(alloc, tmp.ptr()); client_field->def= strdup_root(field_alloc, tmp.ptr());
} }
else else
client_field->def=0; client_field->def=0;
client_field->max_length= 0; client_field->max_length= 0;
++client_field; ++client_field;
} }
mysql->result->fields = field; thd->mysql->field_count= field_count;
if (!(mysql->result->data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
MYF(MY_WME | MY_ZEROFILL))))
goto err;
init_alloc_root(&mysql->result->data->alloc,8192,0); /* Assume rowlength < 8192 */
mysql->result->data->alloc.min_malloc=sizeof(MYSQL_ROWS);
mysql->result->data->rows=0;
mysql->result->data->fields=field_count;
mysql->result->field_count=field_count;
mysql->result->data->prev_ptr= &mysql->result->data->data;
mysql->result->field_alloc= mysql->field_alloc;
mysql->result->current_field=0;
mysql->result->current_row=0;
DBUG_RETURN(prepare_for_send(list)); DBUG_RETURN(prepare_for_send(list));
err: err:
...@@ -456,13 +547,27 @@ send_eof(THD *thd, bool no_flush) ...@@ -456,13 +547,27 @@ send_eof(THD *thd, bool no_flush)
void Protocol_simple::prepare_for_resend() void Protocol_simple::prepare_for_resend()
{ {
MYSQL_ROWS *cur; MYSQL_ROWS *cur;
MYSQL_DATA *result= thd->mysql->result->data; MYSQL_DATA *data= thd->data;
DBUG_ENTER("send_data"); DBUG_ENTER("send_data");
alloc= &result->alloc; if (!data)
result->rows++; {
if (!(data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
MYF(MY_WME | MY_ZEROFILL))))
goto err;
alloc= &data->alloc;
init_alloc_root(alloc,8192,0); /* Assume rowlength < 8192 */
alloc->min_malloc=sizeof(MYSQL_ROWS);
data->rows=0;
data->fields=field_count;
data->prev_ptr= &data->data;
thd->data= data;
}
data->rows++;
if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS)+(field_count + 1) * sizeof(char *)))) if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS)+(field_count + 1) * sizeof(char *))))
{ {
my_error(ER_OUT_OF_RESOURCES,MYF(0)); my_error(ER_OUT_OF_RESOURCES,MYF(0));
...@@ -470,11 +575,11 @@ void Protocol_simple::prepare_for_resend() ...@@ -470,11 +575,11 @@ void Protocol_simple::prepare_for_resend()
} }
cur->data= (MYSQL_ROW)(((char *)cur) + sizeof(MYSQL_ROWS)); cur->data= (MYSQL_ROW)(((char *)cur) + sizeof(MYSQL_ROWS));
*result->prev_ptr= cur; *data->prev_ptr= cur;
result->prev_ptr= &cur->next; data->prev_ptr= &cur->next;
next_field=cur->data; next_field=cur->data;
next_mysql_field= thd->mysql->result->fields; next_mysql_field= thd->mysql->fields;
err:
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <signal.h> #include <signal.h>
#include <time.h> #include <time.h>
#include "client_settings.h"
#ifdef HAVE_PWD_H #ifdef HAVE_PWD_H
#include <pwd.h> #include <pwd.h>
#endif #endif
...@@ -58,29 +59,11 @@ ...@@ -58,29 +59,11 @@
#define closesocket(A) close(A) #define closesocket(A) close(A)
#endif #endif
void free_old_query(MYSQL *mysql);
my_bool STDCALL
emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
const char *header, ulong header_length,
const char *arg, ulong arg_length, my_bool skip_check);
/* From client.c */
void mysql_read_default_options(struct st_mysql_options *options,
const char *filename,const char *group);
MYSQL * STDCALL
cli_mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db,
uint port, const char *unix_socket,ulong client_flag);
void STDCALL cli_mysql_close(MYSQL *mysql);
#ifdef HAVE_GETPWUID #ifdef HAVE_GETPWUID
struct passwd *getpwuid(uid_t); struct passwd *getpwuid(uid_t);
char* getlogin(void); char* getlogin(void);
#endif #endif
extern char server_inited;
#ifdef __WIN__ #ifdef __WIN__
static my_bool is_NT(void) static my_bool is_NT(void)
{ {
...@@ -165,73 +148,6 @@ static inline int mysql_init_charset(MYSQL *mysql) ...@@ -165,73 +148,6 @@ static inline int mysql_init_charset(MYSQL *mysql)
return 0; return 0;
} }
/**************************************************************************
Get column lengths of the current row
If one uses mysql_use_result, res->lengths contains the length information,
else the lengths are calculated from the offset between pointers.
**************************************************************************/
static void STDCALL emb_fetch_lengths(ulong *to, MYSQL_ROW column, uint field_count)
{
MYSQL_ROW end;
for (end=column + field_count; column != end ; column++,to++)
*to= *column ? *(uint *)((*column) - sizeof(uint)) : 0;
}
/**************************************************************************
List all fields in a table
If wild is given then only the fields matching wild is returned
Instead of this use query:
show fields in 'table' like "wild"
**************************************************************************/
static MYSQL_RES * STDCALL
emb_list_fields(MYSQL *mysql, const char *table, const char *wild)
{
MYSQL_RES *result;
MYSQL_DATA *query;
char buff[257],*end;
DBUG_ENTER("mysql_list_fields");
DBUG_PRINT("enter",("table: '%s' wild: '%s'",table,wild ? wild : ""));
LINT_INIT(query);
end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128);
if (simple_command(mysql,COM_FIELD_LIST,buff,(ulong) (end-buff),1))
DBUG_RETURN(NULL);
result= mysql->result;
if (!result)
return 0;
result->methods= mysql->methods;
result->eof=1;
DBUG_RETURN(result);
}
/*
** Note that the mysql argument must be initialized with mysql_init()
** before calling mysql_real_connect !
*/
static my_bool STDCALL emb_mysql_read_query_result(MYSQL *mysql);
static MYSQL_RES * STDCALL emb_mysql_store_result(MYSQL *mysql);
static MYSQL_RES * STDCALL emb_mysql_use_result(MYSQL *mysql);
static MYSQL_METHODS embedded_methods=
{
emb_mysql_read_query_result,
emb_advanced_command,
emb_mysql_store_result,
emb_mysql_use_result,
emb_fetch_lengths,
emb_list_fields
};
MYSQL * STDCALL MYSQL * STDCALL
mysql_real_connect(MYSQL *mysql,const char *host, const char *user, mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db, const char *passwd, const char *db,
...@@ -379,58 +295,3 @@ void STDCALL mysql_close(MYSQL *mysql) ...@@ -379,58 +295,3 @@ void STDCALL mysql_close(MYSQL *mysql)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
static my_bool STDCALL emb_mysql_read_query_result(MYSQL *mysql)
{
if (mysql->net.last_errno)
return -1;
if (mysql->field_count)
{
mysql->status=MYSQL_STATUS_GET_RESULT;
mysql->affected_rows= mysql->result->row_count= mysql->result->data->rows;
mysql->result->data_cursor= mysql->result->data->data;
}
return 0;
}
/**************************************************************************
** Alloc result struct for buffered results. All rows are read to buffer.
** mysql_data_seek may be used.
**************************************************************************/
static MYSQL_RES * STDCALL emb_mysql_store_result(MYSQL *mysql)
{
MYSQL_RES *result= mysql->result;
if (!result)
return 0;
result->methods= mysql->methods;
mysql->result= NULL;
*result->data->prev_ptr= 0;
result->eof= 1;
result->lengths= (ulong*)(result + 1);
mysql->affected_rows= result->row_count= result->data->rows;
result->data_cursor= result->data->data;
mysql->status=MYSQL_STATUS_READY; /* server is ready */
return result;
}
/**************************************************************************
** Alloc struct for use with unbuffered reads. Data is fetched by domand
** when calling to mysql_fetch_row.
** mysql_data_seek is a noop.
**
** No other queries may be specified with the same MYSQL handle.
** There shouldn't be much processing per row because mysql server shouldn't
** have to wait for the client (and will not wait more than 30 sec/packet).
**************************************************************************/
static MYSQL_RES * STDCALL emb_mysql_use_result(MYSQL *mysql)
{
DBUG_ENTER("mysql_use_result");
if (mysql->options.separate_thread)
DBUG_RETURN(0);
DBUG_RETURN(emb_mysql_store_result(mysql));
}
...@@ -636,10 +636,10 @@ void free_rows(MYSQL_DATA *cur) ...@@ -636,10 +636,10 @@ void free_rows(MYSQL_DATA *cur)
} }
} }
static my_bool STDCALL my_bool STDCALL
cli_advanced_command(MYSQL *mysql, enum enum_server_command command, cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
const char *header, ulong header_length, const char *header, ulong header_length,
const char *arg, ulong arg_length, my_bool skip_check) const char *arg, ulong arg_length, my_bool skip_check)
{ {
NET *net= &mysql->net; NET *net= &mysql->net;
my_bool result= 1; my_bool result= 1;
...@@ -1139,8 +1139,8 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, ...@@ -1139,8 +1139,8 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
/* Read all rows (fields or data) from server */ /* Read all rows (fields or data) from server */
MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
uint fields) uint fields)
{ {
uint field; uint field;
ulong pkt_len; ulong pkt_len;
...@@ -1150,7 +1150,7 @@ MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, ...@@ -1150,7 +1150,7 @@ MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
MYSQL_DATA *result; MYSQL_DATA *result;
MYSQL_ROWS **prev_ptr,*cur; MYSQL_ROWS **prev_ptr,*cur;
NET *net = &mysql->net; NET *net = &mysql->net;
DBUG_ENTER("read_rows"); DBUG_ENTER("cli_read_rows");
if ((pkt_len= net_safe_read(mysql)) == packet_error) if ((pkt_len= net_safe_read(mysql)) == packet_error)
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -1397,17 +1397,18 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused))) ...@@ -1397,17 +1397,18 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused)))
*/ */
static my_bool STDCALL cli_mysql_read_query_result(MYSQL *mysql); static my_bool STDCALL cli_mysql_read_query_result(MYSQL *mysql);
static MYSQL_RES * STDCALL cli_mysql_store_result(MYSQL *mysql);
static MYSQL_RES * STDCALL cli_mysql_use_result(MYSQL *mysql); static MYSQL_RES * STDCALL cli_mysql_use_result(MYSQL *mysql);
static MYSQL_METHODS client_methods= static MYSQL_METHODS client_methods=
{ {
cli_mysql_read_query_result, cli_mysql_read_query_result,
cli_advanced_command, cli_advanced_command,
cli_mysql_store_result, cli_read_rows,
cli_mysql_use_result, cli_mysql_use_result,
cli_fetch_lengths, cli_fetch_lengths,
cli_list_fields cli_list_fields,
cli_read_prepare_result,
cli_stmt_execute
}; };
MYSQL * STDCALL MYSQL * STDCALL
...@@ -2264,7 +2265,8 @@ get_info: ...@@ -2264,7 +2265,8 @@ get_info:
mysql->extra_info= net_field_length_ll(&pos); /* Maybe number of rec */ mysql->extra_info= net_field_length_ll(&pos); /* Maybe number of rec */
if (!(fields=read_rows(mysql,(MYSQL_FIELD*)0,protocol_41(mysql) ? 7 : 5))) if (!(fields=(*mysql->methods->read_rows)(mysql,(MYSQL_FIELD*)0,
protocol_41(mysql) ? 7 : 5)))
DBUG_RETURN(1); DBUG_RETURN(1);
if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc, if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,
(uint) field_count,0, (uint) field_count,0,
...@@ -2326,7 +2328,7 @@ mysql_real_query(MYSQL *mysql, const char *query, ulong length) ...@@ -2326,7 +2328,7 @@ mysql_real_query(MYSQL *mysql, const char *query, ulong length)
mysql_data_seek may be used. mysql_data_seek may be used.
**************************************************************************/ **************************************************************************/
static MYSQL_RES * STDCALL cli_mysql_store_result(MYSQL *mysql) MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql)
{ {
MYSQL_RES *result; MYSQL_RES *result;
DBUG_ENTER("mysql_store_result"); DBUG_ENTER("mysql_store_result");
...@@ -2355,7 +2357,8 @@ static MYSQL_RES * STDCALL cli_mysql_store_result(MYSQL *mysql) ...@@ -2355,7 +2357,8 @@ static MYSQL_RES * STDCALL cli_mysql_store_result(MYSQL *mysql)
result->methods= mysql->methods; result->methods= mysql->methods;
result->eof=1; /* Marker for buffered */ result->eof=1; /* Marker for buffered */
result->lengths=(ulong*) (result+1); result->lengths=(ulong*) (result+1);
if (!(result->data=read_rows(mysql,mysql->fields,mysql->field_count))) if (!(result->data=
(*mysql->methods->read_rows)(mysql,mysql->fields,mysql->field_count)))
{ {
my_free((gptr) result,MYF(0)); my_free((gptr) result,MYF(0));
DBUG_RETURN(0); DBUG_RETURN(0);
......
...@@ -33,4 +33,6 @@ ...@@ -33,4 +33,6 @@
#undef _CUSTOMCONFIG_ #undef _CUSTOMCONFIG_
#define cli_list_fields NULL #define cli_list_fields NULL
#define cli_read_prepare_result NULL
#define cli_stmt_execute NULL
...@@ -422,6 +422,9 @@ class THD :public ilink ...@@ -422,6 +422,9 @@ class THD :public ilink
public: public:
#ifdef EMBEDDED_LIBRARY #ifdef EMBEDDED_LIBRARY
struct st_mysql *mysql; struct st_mysql *mysql;
struct st_mysql_data *data;
unsigned long client_stmt_id;
unsigned long client_param_count;
#endif #endif
NET net; // client connection descriptor NET net; // client connection descriptor
LEX lex; // parse tree descriptor LEX lex; // parse tree descriptor
......
...@@ -142,6 +142,7 @@ void free_prep_stmt(PREP_STMT *stmt, TREE_FREE mode, void *not_used) ...@@ -142,6 +142,7 @@ void free_prep_stmt(PREP_STMT *stmt, TREE_FREE mode, void *not_used)
Send prepared stmt info to client after prepare Send prepared stmt info to client after prepare
*/ */
#ifndef EMBEDDED_LIBRARY
static bool send_prep_stmt(PREP_STMT *stmt, uint columns) static bool send_prep_stmt(PREP_STMT *stmt, uint columns)
{ {
NET *net=&stmt->thd->net; NET *net=&stmt->thd->net;
...@@ -150,14 +151,21 @@ static bool send_prep_stmt(PREP_STMT *stmt, uint columns) ...@@ -150,14 +151,21 @@ static bool send_prep_stmt(PREP_STMT *stmt, uint columns)
int4store(buff+1, stmt->stmt_id); int4store(buff+1, stmt->stmt_id);
int2store(buff+5, columns); int2store(buff+5, columns);
int2store(buff+7, stmt->param_count); int2store(buff+7, stmt->param_count);
#ifndef EMBEDDED_LIBRARY
/* This should be fixed to work with prepared statements /* This should be fixed to work with prepared statements
*/ */
return (my_net_write(net, buff, sizeof(buff)) || net_flush(net)); return (my_net_write(net, buff, sizeof(buff)) || net_flush(net));
}
#else #else
return true; static bool send_prep_stmt(PREP_STMT *stmt, uint columns __attribute__((unused)))
#endif {
THD *thd= stmt->thd;
thd->client_stmt_id= stmt->stmt_id;
thd->client_param_count= stmt->param_count;
return 0;
} }
#endif /*!EMBEDDED_LIBRAYR*/
/* /*
Send information about all item parameters Send information about all item parameters
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment