mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
Merge abotchkov@bk-internal.mysql.com:/home/bk/mysql-4.1
into deer.(none):/home/hf/work/mysql-4.1.stmt
This commit is contained in:
commit
117d18335a
11 changed files with 283 additions and 261 deletions
|
@ -250,7 +250,6 @@ typedef struct st_mysql
|
|||
|
||||
LIST *stmts; /* list of all statements */
|
||||
const struct st_mysql_methods *methods;
|
||||
struct st_mysql_res *result;
|
||||
void *thd;
|
||||
} MYSQL;
|
||||
|
||||
|
@ -359,6 +358,8 @@ int STDCALL mysql_send_query(MYSQL *mysql, const char *q,
|
|||
unsigned long length);
|
||||
int STDCALL mysql_real_query(MYSQL *mysql, const char *q,
|
||||
unsigned long length);
|
||||
MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql);
|
||||
|
||||
/* perform query on master */
|
||||
my_bool STDCALL mysql_master_query(MYSQL *mysql, const char *q,
|
||||
unsigned long length);
|
||||
|
@ -427,6 +428,8 @@ MYSQL_FIELD_OFFSET STDCALL mysql_field_seek(MYSQL_RES *result,
|
|||
MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result);
|
||||
unsigned long * STDCALL mysql_fetch_lengths(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 from_length);
|
||||
unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql,
|
||||
|
@ -538,9 +541,7 @@ typedef struct st_mysql_stmt
|
|||
|
||||
|
||||
#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_list_fields(mysql, table, wild) (*(mysql)->methods->list_fields)(mysql, table, wild)
|
||||
|
||||
typedef struct st_mysql_methods
|
||||
{
|
||||
|
@ -552,12 +553,14 @@ typedef struct st_mysql_methods
|
|||
const char *arg,
|
||||
unsigned long arg_length,
|
||||
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);
|
||||
void (STDCALL *fetch_lengths)(unsigned long *to,
|
||||
MYSQL_ROW column, uint field_count);
|
||||
MYSQL_RES * (STDCALL *list_fields)(MYSQL *mysql, const char *table,
|
||||
const char *wild);
|
||||
MYSQL_FIELD * (STDCALL *list_fields)(MYSQL *mysql);
|
||||
my_bool (STDCALL *read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
|
||||
int (STDCALL *stmt_execute)(MYSQL_STMT *stmt);
|
||||
} MYSQL_METHODS;
|
||||
|
||||
MYSQL_STMT * STDCALL mysql_prepare(MYSQL * mysql, const char *query,
|
||||
|
|
|
@ -28,14 +28,19 @@ my_ulonglong net_field_length_ll(uchar **packet);
|
|||
MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
|
||||
my_bool default_value, uint server_capabilities);
|
||||
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);
|
||||
void free_old_query(MYSQL *mysql);
|
||||
void end_server(MYSQL *mysql);
|
||||
my_bool mysql_reconnect(MYSQL *mysql);
|
||||
void mysql_read_default_options(struct st_mysql_options *options,
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -41,5 +41,17 @@ my_bool send_file_to_server(MYSQL *mysql, const char *filename);
|
|||
#define reset_sigpipe(mysql)
|
||||
#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)
|
|||
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
|
||||
If wild is given then only the fields matching wild is returned
|
||||
|
@ -981,36 +994,29 @@ mysql_list_tables(MYSQL *mysql, const char *wild)
|
|||
**************************************************************************/
|
||||
|
||||
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_DATA *query;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_FIELD *fields;
|
||||
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);
|
||||
free_old_query(mysql);
|
||||
if (simple_command(mysql,COM_FIELD_LIST,buff,(ulong) (end-buff),1) ||
|
||||
!(query = read_rows(mysql,(MYSQL_FIELD*) 0,
|
||||
protocol_41(mysql) ? 8 : 6)))
|
||||
!(fields= (*mysql->methods->list_fields)(mysql)))
|
||||
DBUG_RETURN(NULL);
|
||||
|
||||
free_old_query(mysql);
|
||||
if (!(result = (MYSQL_RES *) my_malloc(sizeof(MYSQL_RES),
|
||||
MYF(MY_WME | MY_ZEROFILL))))
|
||||
{
|
||||
free_rows(query);
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
|
||||
result->methods= mysql->methods;
|
||||
result->field_alloc=mysql->field_alloc;
|
||||
mysql->fields=0;
|
||||
result->field_count = (uint) query->rows;
|
||||
result->fields= unpack_fields(query,&result->field_alloc,
|
||||
result->field_count, 1,
|
||||
mysql->server_capabilities);
|
||||
result->field_count = mysql->field_count;
|
||||
result->fields= fields;
|
||||
result->eof=1;
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
@ -1031,8 +1037,8 @@ mysql_list_processes(MYSQL *mysql)
|
|||
free_old_query(mysql);
|
||||
pos=(uchar*) mysql->net.read_pos;
|
||||
field_count=(uint) net_field_length(&pos);
|
||||
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(NULL);
|
||||
if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,field_count,0,
|
||||
mysql->server_capabilities)))
|
||||
|
@ -1488,8 +1494,8 @@ static void set_stmt_error(MYSQL_STMT * stmt, int errcode,
|
|||
Copy error message to statement handler
|
||||
*/
|
||||
|
||||
static void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode,
|
||||
const char *sqlstate)
|
||||
void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode,
|
||||
const char *sqlstate)
|
||||
{
|
||||
DBUG_ENTER("set_stmt_error_msg");
|
||||
DBUG_PRINT("enter", ("error: %d/%s '%s'", errcode, sqlstate, err));
|
||||
|
@ -1563,7 +1569,7 @@ static my_bool my_realloc_str(NET *net, ulong length)
|
|||
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;
|
||||
uint field_count;
|
||||
|
@ -1586,25 +1592,25 @@ static my_bool read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
|
|||
mysql->server_status|= SERVER_STATUS_IN_TRANS;
|
||||
|
||||
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);
|
||||
if (!(stmt->fields= unpack_fields(fields_data,&stmt->mem_root,
|
||||
field_count,0,
|
||||
mysql->server_capabilities)))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (!(stmt->params= (MYSQL_BIND *) alloc_root(&stmt->mem_root,
|
||||
sizeof(MYSQL_BIND)*
|
||||
(param_count +
|
||||
field_count))))
|
||||
{
|
||||
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
stmt->bind= (stmt->params + param_count);
|
||||
stmt->field_count= (uint) field_count;
|
||||
stmt->param_count= (ulong) param_count;
|
||||
mysql->status= MYSQL_STATUS_READY;
|
||||
if (!(stmt->params= (MYSQL_BIND *) alloc_root(&stmt->mem_root,
|
||||
sizeof(MYSQL_BIND)*
|
||||
(stmt->param_count +
|
||||
stmt->field_count))))
|
||||
{
|
||||
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
stmt->bind= stmt->params + stmt->param_count;
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -1648,14 +1654,16 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length)
|
|||
}
|
||||
|
||||
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);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
stmt->state= MY_ST_PREPARE;
|
||||
stmt->mysql= mysql;
|
||||
mysql->stmts= list_add(mysql->stmts, &stmt->list);
|
||||
mysql->status= MYSQL_STATUS_READY;
|
||||
stmt->list.data= stmt;
|
||||
DBUG_PRINT("info", ("Parameter count: %ld", stmt->param_count));
|
||||
DBUG_RETURN(stmt);
|
||||
|
@ -1971,36 +1979,21 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length)
|
|||
|
||||
mysql->last_used_con= mysql;
|
||||
int4store(buff, stmt->stmt_id); /* Send stmt id to server */
|
||||
if ((*mysql->methods->advanced_command)(mysql, COM_EXECUTE, buff,
|
||||
MYSQL_STMT_HEADER, packet,
|
||||
length, 1) ||
|
||||
if (cli_advanced_command(mysql, COM_EXECUTE, buff,
|
||||
MYSQL_STMT_HEADER, packet,
|
||||
length, 1) ||
|
||||
mysql_read_query_result(mysql))
|
||||
{
|
||||
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Execute the prepare query
|
||||
*/
|
||||
|
||||
int STDCALL mysql_execute(MYSQL_STMT *stmt)
|
||||
int STDCALL cli_stmt_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)
|
||||
{
|
||||
NET *net= &stmt->mysql->net;
|
||||
|
@ -2061,6 +2054,30 @@ int STDCALL mysql_execute(MYSQL_STMT *stmt)
|
|||
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
|
||||
|
|
|
@ -26,4 +26,7 @@ C_MODE_START
|
|||
extern void lib_connection_phase(NET *net, int phase);
|
||||
extern void init_embedded_mysql(MYSQL *mysql, 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
|
||||
|
|
|
@ -50,7 +50,7 @@ static bool check_user(THD *thd, enum_server_command command,
|
|||
char * get_mysql_home(){ return mysql_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,
|
||||
const char *header, ulong header_length,
|
||||
const char *arg, ulong arg_length, my_bool skip_check)
|
||||
|
@ -94,6 +94,116 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
|
|||
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
|
||||
|
||||
void THD::clear_error()
|
||||
|
@ -334,6 +444,8 @@ void *create_embedded_thd(int client_flag, char *db)
|
|||
thd->master_access= ~NO_ACCESS;
|
||||
thd->net.query_cache_query= 0;
|
||||
|
||||
thd->data= 0;
|
||||
|
||||
return thd;
|
||||
}
|
||||
|
||||
|
@ -343,35 +455,29 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
|
|||
{
|
||||
List_iterator_fast<Item> it(*list);
|
||||
Item *item;
|
||||
MYSQL_FIELD *field, *client_field;
|
||||
MYSQL_FIELD *client_field;
|
||||
MYSQL *mysql= thd->mysql;
|
||||
MEM_ROOT *field_alloc;
|
||||
|
||||
DBUG_ENTER("send_fields");
|
||||
|
||||
field_count= list->elements;
|
||||
if (!(mysql->result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES)+
|
||||
sizeof(ulong) * (field_count + 1),
|
||||
MYF(MY_WME | MY_ZEROFILL))))
|
||||
goto err;
|
||||
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)
|
||||
field_alloc= &mysql->field_alloc;
|
||||
if (!(client_field= thd->mysql->fields=
|
||||
(MYSQL_FIELD *)alloc_root(field_alloc,
|
||||
sizeof(MYSQL_FIELD) * field_count)))
|
||||
goto err;
|
||||
|
||||
client_field= field;
|
||||
while ((item= it++))
|
||||
{
|
||||
Send_field server_field;
|
||||
item->make_field(&server_field);
|
||||
|
||||
client_field->db= strdup_root(alloc, server_field.db_name);
|
||||
client_field->table= strdup_root(alloc, server_field.table_name);
|
||||
client_field->name= strdup_root(alloc, server_field.col_name);
|
||||
client_field->org_table= strdup_root(alloc, server_field.org_table_name);
|
||||
client_field->org_name= strdup_root(alloc, server_field.org_col_name);
|
||||
client_field->db= strdup_root(field_alloc, server_field.db_name);
|
||||
client_field->table= strdup_root(field_alloc, server_field.table_name);
|
||||
client_field->name= strdup_root(field_alloc, server_field.col_name);
|
||||
client_field->org_table= strdup_root(field_alloc, server_field.org_table_name);
|
||||
client_field->org_name= strdup_root(field_alloc, server_field.org_col_name);
|
||||
client_field->length= server_field.length;
|
||||
client_field->type= server_field.type;
|
||||
client_field->flags= server_field.flags;
|
||||
|
@ -392,31 +498,16 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
|
|||
String tmp(buff, sizeof(buff), default_charset_info), *res;
|
||||
|
||||
if (!(res=item->val_str(&tmp)))
|
||||
client_field->def= strdup_root(alloc, "");
|
||||
client_field->def= strdup_root(field_alloc, "");
|
||||
else
|
||||
client_field->def= strdup_root(alloc, tmp.ptr());
|
||||
client_field->def= strdup_root(field_alloc, tmp.ptr());
|
||||
}
|
||||
else
|
||||
client_field->def=0;
|
||||
client_field->max_length= 0;
|
||||
++client_field;
|
||||
}
|
||||
mysql->result->fields = field;
|
||||
|
||||
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;
|
||||
thd->mysql->field_count= field_count;
|
||||
|
||||
DBUG_RETURN(prepare_for_send(list));
|
||||
err:
|
||||
|
@ -456,13 +547,27 @@ send_eof(THD *thd, bool no_flush)
|
|||
|
||||
void Protocol_simple::prepare_for_resend()
|
||||
{
|
||||
MYSQL_ROWS *cur;
|
||||
MYSQL_DATA *result= thd->mysql->result->data;
|
||||
MYSQL_ROWS *cur;
|
||||
MYSQL_DATA *data= thd->data;
|
||||
|
||||
DBUG_ENTER("send_data");
|
||||
|
||||
alloc= &result->alloc;
|
||||
result->rows++;
|
||||
if (!data)
|
||||
{
|
||||
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 *))))
|
||||
{
|
||||
my_error(ER_OUT_OF_RESOURCES,MYF(0));
|
||||
|
@ -470,11 +575,11 @@ void Protocol_simple::prepare_for_resend()
|
|||
}
|
||||
cur->data= (MYSQL_ROW)(((char *)cur) + sizeof(MYSQL_ROWS));
|
||||
|
||||
*result->prev_ptr= cur;
|
||||
result->prev_ptr= &cur->next;
|
||||
*data->prev_ptr= cur;
|
||||
data->prev_ptr= &cur->next;
|
||||
next_field=cur->data;
|
||||
next_mysql_field= thd->mysql->result->fields;
|
||||
|
||||
next_mysql_field= thd->mysql->fields;
|
||||
err:
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include "client_settings.h"
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
|
@ -58,29 +59,11 @@
|
|||
#define closesocket(A) close(A)
|
||||
#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
|
||||
struct passwd *getpwuid(uid_t);
|
||||
char* getlogin(void);
|
||||
#endif
|
||||
|
||||
extern char server_inited;
|
||||
|
||||
#ifdef __WIN__
|
||||
static my_bool is_NT(void)
|
||||
{
|
||||
|
@ -165,73 +148,6 @@ static inline int mysql_init_charset(MYSQL *mysql)
|
|||
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_real_connect(MYSQL *mysql,const char *host, const char *user,
|
||||
const char *passwd, const char *db,
|
||||
|
@ -379,58 +295,3 @@ void STDCALL mysql_close(MYSQL *mysql)
|
|||
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)
|
|||
}
|
||||
}
|
||||
|
||||
static my_bool STDCALL
|
||||
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)
|
||||
const char *header, ulong header_length,
|
||||
const char *arg, ulong arg_length, my_bool skip_check)
|
||||
{
|
||||
NET *net= &mysql->net;
|
||||
my_bool result= 1;
|
||||
|
@ -1139,8 +1139,8 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
|
|||
|
||||
/* Read all rows (fields or data) from server */
|
||||
|
||||
MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
|
||||
uint fields)
|
||||
MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
|
||||
uint fields)
|
||||
{
|
||||
uint field;
|
||||
ulong pkt_len;
|
||||
|
@ -1150,7 +1150,7 @@ MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
|
|||
MYSQL_DATA *result;
|
||||
MYSQL_ROWS **prev_ptr,*cur;
|
||||
NET *net = &mysql->net;
|
||||
DBUG_ENTER("read_rows");
|
||||
DBUG_ENTER("cli_read_rows");
|
||||
|
||||
if ((pkt_len= net_safe_read(mysql)) == packet_error)
|
||||
DBUG_RETURN(0);
|
||||
|
@ -1397,17 +1397,18 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused)))
|
|||
*/
|
||||
|
||||
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_METHODS client_methods=
|
||||
{
|
||||
cli_mysql_read_query_result,
|
||||
cli_advanced_command,
|
||||
cli_mysql_store_result,
|
||||
cli_read_rows,
|
||||
cli_mysql_use_result,
|
||||
cli_fetch_lengths,
|
||||
cli_list_fields
|
||||
cli_list_fields,
|
||||
cli_read_prepare_result,
|
||||
cli_stmt_execute
|
||||
};
|
||||
|
||||
MYSQL * STDCALL
|
||||
|
@ -2264,7 +2265,8 @@ get_info:
|
|||
|
||||
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);
|
||||
if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,
|
||||
(uint) field_count,0,
|
||||
|
@ -2326,7 +2328,7 @@ mysql_real_query(MYSQL *mysql, const char *query, ulong length)
|
|||
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;
|
||||
DBUG_ENTER("mysql_store_result");
|
||||
|
@ -2355,7 +2357,8 @@ static MYSQL_RES * STDCALL cli_mysql_store_result(MYSQL *mysql)
|
|||
result->methods= mysql->methods;
|
||||
result->eof=1; /* Marker for buffered */
|
||||
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));
|
||||
DBUG_RETURN(0);
|
||||
|
|
|
@ -33,4 +33,6 @@
|
|||
#undef _CUSTOMCONFIG_
|
||||
|
||||
#define cli_list_fields NULL
|
||||
#define cli_read_prepare_result NULL
|
||||
#define cli_stmt_execute NULL
|
||||
|
||||
|
|
|
@ -422,6 +422,9 @@ class THD :public ilink
|
|||
public:
|
||||
#ifdef EMBEDDED_LIBRARY
|
||||
struct st_mysql *mysql;
|
||||
struct st_mysql_data *data;
|
||||
unsigned long client_stmt_id;
|
||||
unsigned long client_param_count;
|
||||
#endif
|
||||
NET net; // client connection descriptor
|
||||
LEX lex; // parse tree descriptor
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
static bool send_prep_stmt(PREP_STMT *stmt, uint columns)
|
||||
{
|
||||
NET *net=&stmt->thd->net;
|
||||
|
@ -150,14 +151,21 @@ static bool send_prep_stmt(PREP_STMT *stmt, uint columns)
|
|||
int4store(buff+1, stmt->stmt_id);
|
||||
int2store(buff+5, columns);
|
||||
int2store(buff+7, stmt->param_count);
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
/* This should be fixed to work with prepared statements
|
||||
*/
|
||||
return (my_net_write(net, buff, sizeof(buff)) || net_flush(net));
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static bool send_prep_stmt(PREP_STMT *stmt, uint columns __attribute__((unused)))
|
||||
{
|
||||
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
|
||||
|
|
Loading…
Add table
Reference in a new issue