Commit 42dd6922 authored by holyfoot@mysql.com's avatar holyfoot@mysql.com

Merge bk@192.168.21.1:mysql-5.1-new into mysql.com:/home/hf/work/5.1.emb

parents a410de98 e8697cf4
...@@ -130,14 +130,14 @@ typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */ ...@@ -130,14 +130,14 @@ typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */
#include "my_alloc.h" #include "my_alloc.h"
typedef struct embedded_query_result EMBEDDED_QUERY_RESULT;
typedef struct st_mysql_data { typedef struct st_mysql_data {
my_ulonglong rows; my_ulonglong rows;
unsigned int fields; unsigned int fields;
MYSQL_ROWS *data; MYSQL_ROWS *data;
MEM_ROOT alloc; MEM_ROOT alloc;
#if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY) /* extra info for embedded library */
MYSQL_ROWS **prev_ptr; struct embedded_query_result *embedded_info;
#endif
} MYSQL_DATA; } MYSQL_DATA;
enum mysql_option enum mysql_option
...@@ -287,6 +287,8 @@ typedef struct st_mysql ...@@ -287,6 +287,8 @@ typedef struct st_mysql
from mysql_stmt_close if close had to cancel result set of this object. from mysql_stmt_close if close had to cancel result set of this object.
*/ */
my_bool *unbuffered_fetch_owner; my_bool *unbuffered_fetch_owner;
/* needed for embedded server - no net buffer to store the 'info' */
char *info_buffer;
} MYSQL; } MYSQL;
typedef struct st_mysql_res { typedef struct st_mysql_res {
...@@ -755,6 +757,7 @@ typedef struct st_mysql_methods ...@@ -755,6 +757,7 @@ typedef struct st_mysql_methods
const char *(*read_statistics)(MYSQL *mysql); const char *(*read_statistics)(MYSQL *mysql);
my_bool (*next_result)(MYSQL *mysql); my_bool (*next_result)(MYSQL *mysql);
int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd); int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd);
int (*read_rows_from_cursor)(MYSQL_STMT *stmt);
#endif #endif
} MYSQL_METHODS; } MYSQL_METHODS;
......
...@@ -2722,13 +2722,13 @@ stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row) ...@@ -2722,13 +2722,13 @@ stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row)
/* Send row request to the server */ /* Send row request to the server */
int4store(buff, stmt->stmt_id); int4store(buff, stmt->stmt_id);
int4store(buff + 4, stmt->prefetch_rows); /* number of rows to fetch */ int4store(buff + 4, stmt->prefetch_rows); /* number of rows to fetch */
if (cli_advanced_command(mysql, COM_STMT_FETCH, buff, sizeof(buff), if ((*mysql->methods->advanced_command)(mysql, COM_STMT_FETCH,
NullS, 0, 1)) buff, sizeof(buff), NullS, 0, 1))
{ {
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
return 1; return 1;
} }
if (cli_read_binary_rows(stmt)) if ((*mysql->methods->read_rows_from_cursor)(stmt))
return 1; return 1;
stmt->server_status= mysql->server_status; stmt->server_status= mysql->server_status;
...@@ -5101,9 +5101,9 @@ my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode) ...@@ -5101,9 +5101,9 @@ my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode)
DBUG_ENTER("mysql_autocommit"); DBUG_ENTER("mysql_autocommit");
DBUG_PRINT("enter", ("mode : %d", auto_mode)); DBUG_PRINT("enter", ("mode : %d", auto_mode));
if (auto_mode) /* set to true */ DBUG_RETURN((my_bool) mysql_real_query(mysql, auto_mode ?
DBUG_RETURN((my_bool) mysql_real_query(mysql, "set autocommit=1", 16)); "set autocommit=1":"set autocommit=0",
DBUG_RETURN((my_bool) mysql_real_query(mysql, "set autocommit=0", 16)); 16));
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#ifdef HAVE_QUERY_CACHE #ifdef HAVE_QUERY_CACHE
#include <mysql.h> #include <mysql.h>
#include "emb_qcache.h" #include "emb_qcache.h"
#include "embedded_priv.h"
void Querycache_stream::store_char(char c) void Querycache_stream::store_char(char c)
{ {
...@@ -284,22 +285,25 @@ int Querycache_stream::load_column(MEM_ROOT *alloc, char** column) ...@@ -284,22 +285,25 @@ int Querycache_stream::load_column(MEM_ROOT *alloc, char** column)
uint emb_count_querycache_size(THD *thd) uint emb_count_querycache_size(THD *thd)
{ {
uint result; uint result= 0;
MYSQL *mysql= thd->mysql; MYSQL_FIELD *field;
MYSQL_FIELD *field= mysql->fields; MYSQL_FIELD *field_end;
MYSQL_FIELD *field_end= field + mysql->field_count; MYSQL_ROWS *cur_row;
MYSQL_ROWS *cur_row=NULL; my_ulonglong n_rows;
my_ulonglong n_rows=0; MYSQL_DATA *data= thd->first_data;
while (data->embedded_info->next)
data= data->embedded_info->next;
field= data->embedded_info->fields_list;
field_end= field + data->fields;
if (!field) if (!field)
return 0; return result;
if (thd->data) *data->embedded_info->prev_ptr= NULL; // this marks the last record
{ cur_row= data->data;
*thd->data->prev_ptr= NULL; // this marks the last record n_rows= data->rows;
cur_row= thd->data->data; /* n_fields + n_rows + (field_info + strlen * n_rows) * n_fields */
n_rows= thd->data->rows; result+= (uint) (4+8 + (42 + 4*n_rows)*data->fields);
}
result= (uint) (4+8 + (42 + 4*n_rows)*mysql->field_count);
for(; field < field_end; field++) for(; field < field_end; field++)
{ {
...@@ -313,34 +317,38 @@ uint emb_count_querycache_size(THD *thd) ...@@ -313,34 +317,38 @@ uint emb_count_querycache_size(THD *thd)
for (; cur_row; cur_row=cur_row->next) for (; cur_row; cur_row=cur_row->next)
{ {
MYSQL_ROW col= cur_row->data; MYSQL_ROW col= cur_row->data;
MYSQL_ROW col_end= col + mysql->field_count; MYSQL_ROW col_end= col + data->fields;
for (; col < col_end; col++) for (; col < col_end; col++)
if (*col) if (*col)
result+= *(uint *)((*col) - sizeof(uint)); result+= *(uint *)((*col) - sizeof(uint));
} }
return result; return result;
} }
void emb_store_querycache_result(Querycache_stream *dst, THD *thd) void emb_store_querycache_result(Querycache_stream *dst, THD *thd)
{ {
MYSQL *mysql= thd->mysql; MYSQL_FIELD *field;
MYSQL_FIELD *field= mysql->fields; MYSQL_FIELD *field_end;
MYSQL_FIELD *field_end= field + mysql->field_count; MYSQL_ROWS *cur_row;
MYSQL_ROWS *cur_row= NULL; my_ulonglong n_rows;
my_ulonglong n_rows= 0; MYSQL_DATA *data= thd->first_data;
DBUG_ENTER("emb_store_querycache_result");
while (data->embedded_info->next)
data= data->embedded_info->next;
field= data->embedded_info->fields_list;
field_end= field + data->fields;
if (!field) if (!field)
return; DBUG_VOID_RETURN;
if (thd->data) *data->embedded_info->prev_ptr= NULL; // this marks the last record
{ cur_row= data->data;
*thd->data->prev_ptr= NULL; // this marks the last record n_rows= data->rows;
cur_row= thd->data->data;
n_rows= thd->data->rows;
}
dst->store_int((uint)mysql->field_count); dst->store_int((uint)data->fields);
dst->store_ll((uint)n_rows); dst->store_ll((ulonglong)n_rows);
for(; field < field_end; field++) for(; field < field_end; field++)
{ {
...@@ -356,14 +364,13 @@ void emb_store_querycache_result(Querycache_stream *dst, THD *thd) ...@@ -356,14 +364,13 @@ void emb_store_querycache_result(Querycache_stream *dst, THD *thd)
dst->store_str(field->org_table, field->org_table_length); dst->store_str(field->org_table, field->org_table_length);
dst->store_str(field->db, field->db_length); dst->store_str(field->db, field->db_length);
dst->store_str(field->catalog, field->catalog_length); dst->store_str(field->catalog, field->catalog_length);
dst->store_safe_str(field->def, field->def_length); dst->store_safe_str(field->def, field->def_length);
} }
for (; cur_row; cur_row=cur_row->next) for (; cur_row; cur_row=cur_row->next)
{ {
MYSQL_ROW col= cur_row->data; MYSQL_ROW col= cur_row->data;
MYSQL_ROW col_end= col + mysql->field_count; MYSQL_ROW col_end= col + data->fields;
for (; col < col_end; col++) for (; col < col_end; col++)
{ {
uint len= *col ? *(uint *)((*col) - sizeof(uint)) : 0; uint len= *col ? *(uint *)((*col) - sizeof(uint)) : 0;
...@@ -371,28 +378,34 @@ void emb_store_querycache_result(Querycache_stream *dst, THD *thd) ...@@ -371,28 +378,34 @@ void emb_store_querycache_result(Querycache_stream *dst, THD *thd)
} }
} }
DBUG_ASSERT(emb_count_querycache_size(thd) == dst->stored_size); DBUG_ASSERT(emb_count_querycache_size(thd) == dst->stored_size);
DBUG_VOID_RETURN;
} }
int emb_load_querycache_result(THD *thd, Querycache_stream *src) int emb_load_querycache_result(THD *thd, Querycache_stream *src)
{ {
MYSQL *mysql= thd->mysql; MYSQL_DATA *data= thd->alloc_new_dataset();
MYSQL_DATA *data;
MYSQL_FIELD *field; MYSQL_FIELD *field;
MYSQL_FIELD *field_end; MYSQL_FIELD *field_end;
MEM_ROOT *f_alloc= &mysql->field_alloc; MEM_ROOT *f_alloc;
MYSQL_ROWS *row, *end_row; MYSQL_ROWS *row, *end_row;
MYSQL_ROWS **prev_row; MYSQL_ROWS **prev_row;
ulonglong rows; ulonglong rows;
MYSQL_ROW columns; MYSQL_ROW columns;
DBUG_ENTER("emb_load_querycache_result");
if (!data)
goto err;
init_alloc_root(&data->alloc, 8192,0);
f_alloc= &data->alloc;
mysql->field_count= src->load_int(); data->fields= src->load_int();
rows= src->load_ll(); rows= src->load_ll();
if (!(field= (MYSQL_FIELD *) if (!(field= (MYSQL_FIELD *)
alloc_root(&mysql->field_alloc,mysql->field_count*sizeof(MYSQL_FIELD)))) alloc_root(f_alloc,data->fields*sizeof(MYSQL_FIELD))))
goto err; goto err;
mysql->fields= field; data->embedded_info->fields_list= field;
for(field_end= field+mysql->field_count; field < field_end; field++) for(field_end= field+data->fields; field < field_end; field++)
{ {
field->length= src->load_int(); field->length= src->load_int();
field->max_length= (unsigned int)src->load_int(); field->max_length= (unsigned int)src->load_int();
...@@ -402,47 +415,43 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src) ...@@ -402,47 +415,43 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src)
field->decimals= (unsigned int)src->load_char(); field->decimals= (unsigned int)src->load_char();
if (!(field->name= src->load_str(f_alloc, &field->name_length)) || if (!(field->name= src->load_str(f_alloc, &field->name_length)) ||
!(field->table= src->load_str(f_alloc,&field->table_length)) || !(field->table= src->load_str(f_alloc,&field->table_length)) ||
!(field->org_name= src->load_str(f_alloc, &field->org_name_length)) || !(field->org_name= src->load_str(f_alloc, &field->org_name_length)) ||
!(field->org_table= src->load_str(f_alloc, &field->org_table_length))|| !(field->org_table= src->load_str(f_alloc, &field->org_table_length))||
!(field->db= src->load_str(f_alloc, &field->db_length)) || !(field->db= src->load_str(f_alloc, &field->db_length)) ||
!(field->catalog= src->load_str(f_alloc, &field->catalog_length)) || !(field->catalog= src->load_str(f_alloc, &field->catalog_length)) ||
src->load_safe_str(f_alloc, &field->def, &field->def_length)) src->load_safe_str(f_alloc, &field->def, &field->def_length))
goto err; goto err;
} }
if (!rows) row= (MYSQL_ROWS *)alloc_root(&data->alloc,
return 0; (uint) (rows * sizeof(MYSQL_ROWS) +
if (!(data= (MYSQL_DATA*)my_malloc(sizeof(MYSQL_DATA), rows*(data->fields+1)*sizeof(char*)));
MYF(MY_WME | MY_ZEROFILL))))
goto err;
thd->data= data;
init_alloc_root(&data->alloc, 8192,0);
row= (MYSQL_ROWS *)alloc_root(&data->alloc, (uint) (rows * sizeof(MYSQL_ROWS) +
rows * (mysql->field_count+1)*sizeof(char*)));
end_row= row + rows; end_row= row + rows;
columns= (MYSQL_ROW)end_row; columns= (MYSQL_ROW)end_row;
data->rows= rows; data->rows= rows;
data->fields= mysql->field_count;
data->data= row; data->data= row;
if (!rows)
goto return_ok;
for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++) for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++)
{ {
*prev_row= row; *prev_row= row;
row->data= columns; row->data= columns;
MYSQL_ROW col_end= columns + mysql->field_count; MYSQL_ROW col_end= columns + data->fields;
for (; columns < col_end; columns++) for (; columns < col_end; columns++)
src->load_column(&data->alloc, columns); src->load_column(&data->alloc, columns);
*(columns++)= NULL; *(columns++)= NULL;
} }
*prev_row= NULL; *prev_row= NULL;
data->prev_ptr= prev_row; data->embedded_info->prev_ptr= prev_row;
return_ok:
return 0; send_eof(thd);
DBUG_RETURN(0);
err: err:
return 1; DBUG_RETURN(1);
} }
#endif /*HAVE_QUERY_CACHE*/ #endif /*HAVE_QUERY_CACHE*/
......
...@@ -16,18 +16,25 @@ ...@@ -16,18 +16,25 @@
/* Prototypes for the embedded version of MySQL */ /* Prototypes for the embedded version of MySQL */
#include <my_global.h>
#include <mysql.h>
#include <mysql_embed.h>
#include <mysqld_error.h>
#include <my_pthread.h>
C_MODE_START C_MODE_START
void lib_connection_phase(NET *net, int phase); void lib_connection_phase(NET *net, int phase);
void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db); void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db);
void *create_embedded_thd(int client_flag, char *db); void *create_embedded_thd(int client_flag, char *db);
int check_embedded_connection(MYSQL *mysql); int check_embedded_connection(MYSQL *mysql);
void free_old_query(MYSQL *mysql); void free_old_query(MYSQL *mysql);
void embedded_get_error(MYSQL *mysql);
extern MYSQL_METHODS embedded_methods; extern MYSQL_METHODS embedded_methods;
/* This one is used by embedded library to gather returning data */
typedef struct embedded_query_result
{
MYSQL_ROWS **prev_ptr;
unsigned int warning_count, server_status;
struct st_mysql_data *next;
my_ulonglong affected_rows, insert_id;
char info[MYSQL_ERRMSG_SIZE];
MYSQL_FIELD *fields_list;
unsigned int last_errno;
char sqlstate[SQLSTATE_LENGTH+1];
} EQR;
C_MODE_END C_MODE_END
This diff is collapsed.
...@@ -14,6 +14,11 @@ ...@@ -14,6 +14,11 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#include <mysql.h>
#include <mysql_embed.h>
#include <mysqld_error.h>
#include <my_pthread.h>
#include "embedded_priv.h" #include "embedded_priv.h"
#include <my_sys.h> #include <my_sys.h>
#include <mysys_err.h> #include <mysys_err.h>
...@@ -193,7 +198,12 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, ...@@ -193,7 +198,12 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
if (!user) if (!user)
user= ""; user= "";
mysql->user=my_strdup(user,MYF(0)); /*
We need to alloc some space for mysql->info but don't want to
put extra 'my_free's in mysql_close.
So we alloc it with the 'user' string to be freed at once
*/
mysql->user= my_strdup(user, MYF(0));
port=0; port=0;
unix_socket=0; unix_socket=0;
...@@ -207,6 +217,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, ...@@ -207,6 +217,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
if (db) if (db)
client_flag|=CLIENT_CONNECT_WITH_DB; client_flag|=CLIENT_CONNECT_WITH_DB;
mysql->info_buffer= my_malloc(MYSQL_ERRMSG_SIZE, MYF(0));
mysql->thd= create_embedded_thd(client_flag, db_name); mysql->thd= create_embedded_thd(client_flag, db_name);
init_embedded_mysql(mysql, client_flag, db_name); init_embedded_mysql(mysql, client_flag, db_name);
...@@ -243,7 +254,6 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, ...@@ -243,7 +254,6 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
DBUG_RETURN(mysql); DBUG_RETURN(mysql);
error: error:
embedded_get_error(mysql);
DBUG_PRINT("error",("message: %u (%s)", mysql->net.last_errno, DBUG_PRINT("error",("message: %u (%s)", mysql->net.last_errno,
mysql->net.last_error)); mysql->net.last_error));
{ {
......
# This test should work in embedded server after we fix mysqltest
-- source include/not_embedded.inc
# #
# This test is a bit tricky as we can't use backup table to overwrite an old # This test is a bit tricky as we can't use backup table to overwrite an old
# table # table
......
# This is a wrapper for binlog.test so that the same test case can be used # This is a wrapper for binlog.test so that the same test case can be used
# For both statement and row based bin logs 9/19/2005 [jbm] # For both statement and row based bin logs 9/19/2005 [jbm]
-- source include/not_embedded.inc
-- source include/have_binlog_format_statement.inc -- source include/have_binlog_format_statement.inc
-- source extra/binlog_tests/binlog.test -- source extra/binlog_tests/binlog.test
# This is a wrapper for binlog.test so that the same test case can be used # This is a wrapper for binlog.test so that the same test case can be used
# For both statement and row based bin logs 9/19/2005 [jbm] # For both statement and row based bin logs 9/19/2005 [jbm]
-- source include/not_embedded.inc
-- source include/have_binlog_format_statement.inc -- source include/have_binlog_format_statement.inc
-- source extra/binlog_tests/blackhole.test -- source extra/binlog_tests/blackhole.test
# This is a wrapper for binlog.test so that the same test case can be used # This is a wrapper for binlog.test so that the same test case can be used
# For both statement and row based bin logs 9/19/2005 [jbm] # For both statement and row based bin logs 9/19/2005 [jbm]
-- source include/not_embedded.inc
-- source include/have_binlog_format_statement.inc -- source include/have_binlog_format_statement.inc
-- source extra/binlog_tests/ctype_cp932.test -- source extra/binlog_tests/ctype_cp932.test
# Turn on compression between the client and server # Turn on compression between the client and server
# and run a number of tests # and run a number of tests
# Can't test with embedded server
-- source include/not_embedded.inc
-- source include/have_compress.inc -- source include/have_compress.inc
connect (comp_con,localhost,root,,,,,COMPRESS); connect (comp_con,localhost,root,,,,,COMPRESS);
......
-- source include/not_embedded.inc
-- source include/have_cp932.inc
--character_set cp932
--disable_warnings
drop table if exists t1;
--enable_warnings
set names cp932;
set character_set_database = cp932;
# Test prepared statement with 0x8300 sequence in parameter while
# running with cp932 client character set.
RESET MASTER;
CREATE TABLE t1(f1 blob);
PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
SET @var1= x'8300';
# TODO: Note that this doesn't actually test the code which was added for
# bug#11338 because this syntax for prepared statements causes the PS to
# be replicated differently than if we executed the PS from C or Java.
# Using this syntax, variable names are inserted into the binlog instead
# of values. The real goal of this test is to check the code that was
# added to Item_param::query_val_str() in order to do hex encoding of
# PS parameters when the client character set is cp932;
# Bug#11338 has an example java program which can be used to verify this
# code (and I have used it to test the fix) until there is some way to
# exercise this code from mysql-test-run.
EXECUTE stmt1 USING @var1;
SHOW BINLOG EVENTS FROM 98;
SELECT HEX(f1) FROM t1;
DROP table t1;
# end test for bug#11338
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
# (Can't be tested with purify :( ) # (Can't be tested with purify :( )
# #
# This tests not performed with embedded server
-- source include/not_embedded.inc
--disable_warnings --disable_warnings
drop table if exists t1; drop table if exists t1;
--enable_warnings --enable_warnings
......
# should work with embedded server after mysqltest is fixed
-- source include/not_embedded.inc
source include/federated.inc; source include/federated.inc;
connection slave; connection slave;
......
# should work with embedded server after mysqltest is fixed
-- source include/not_embedded.inc
source include/have_archive.inc; source include/have_archive.inc;
source include/federated.inc; source include/federated.inc;
......
# should work with embedded server after mysqltest is fixed
-- source include/not_embedded.inc
source include/federated.inc; source include/federated.inc;
......
# should work with embedded server after mysqltest is fixed
-- source include/not_embedded.inc
source include/have_bdb.inc; source include/have_bdb.inc;
source include/federated.inc; source include/federated.inc;
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
# Test of flush table # Test of flush table
# #
# Should work in embedded server after mysqltest is fixed
-- source include/not_embedded.inc
--disable_warnings --disable_warnings
drop table if exists t1,t2; drop table if exists t1,t2;
--enable_warnings --enable_warnings
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
# test of HANDLER ... # test of HANDLER ...
# #
# should work in embedded server after mysqltest is fixed
-- source include/not_embedded.inc
--disable_warnings --disable_warnings
drop table if exists t1; drop table if exists t1;
--enable_warnings --enable_warnings
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
# Test of init_connect variable # Test of init_connect variable
# #
# should work with embedded server after mysqltest is fixed
-- source include/not_embedded.inc
connect (con0,localhost,root,,); connect (con0,localhost,root,,);
connection con0; connection con0;
select hex(@a); select hex(@a);
......
...@@ -1576,33 +1576,7 @@ connection a; ...@@ -1576,33 +1576,7 @@ connection a;
checksum table t1; checksum table t1;
drop table t1; drop table t1;
#
# BUG#11238 - in prelocking mode SELECT .. FOR UPDATE is changed to
# non-blocking SELECT
#
create table t1 (col1 integer primary key, col2 integer) engine=innodb;
insert t1 values (1,100);
delimiter |;
create function f1 () returns integer begin
declare var1 int;
select col2 into var1 from t1 where col1=1 for update;
return var1;
end|
delimiter ;|
start transaction;
select f1();
connection b;
send update t1 set col2=0 where col1=1;
connection default;
select * from t1;
connection a;
rollback;
connection b;
reap;
rollback;
connection default; connection default;
drop table t1;
drop function f1;
disconnect a; disconnect a;
disconnect b; disconnect b;
......
-- source include/not_embedded.inc
-- source include/have_innodb.inc
connect (a,localhost,root,,);
connect (b,localhost,root,,);
#
# BUG#11238 - in prelocking mode SELECT .. FOR UPDATE is changed to
# non-blocking SELECT
#
create table t1 (col1 integer primary key, col2 integer) engine=innodb;
insert t1 values (1,100);
delimiter |;
create function f1 () returns integer begin
declare var1 int;
select col2 into var1 from t1 where col1=1 for update;
return var1;
end|
delimiter ;|
start transaction;
select f1();
connection b;
send update t1 set col2=0 where col1=1;
connection default;
select * from t1;
connection a;
rollback;
connection b;
reap;
rollback;
connection default;
drop table t1;
drop function f1;
disconnect a;
disconnect b;
# This test should work in embedded server after we fix mysqltest
-- source include/not_embedded.inc
# #
# Testing the MySQL command line client(mysql) # Testing the MySQL command line client(mysql)
# #
......
# This test should work in embedded server after we fix mysqltest
-- source include/not_embedded.inc
# We run with different binaries for normal and --embedded-server # We run with different binaries for normal and --embedded-server
# #
# If this test fails with "command "$MYSQL_CLIENT_TEST" failed", # If this test fails with "command "$MYSQL_CLIENT_TEST" failed",
......
# This test should work in embedded server after mysqltest is fixed
-- source include/not_embedded.inc
# ============================================================================ # ============================================================================
# #
......
...@@ -822,29 +822,14 @@ select sql_cache * from t1 where s1=1; ...@@ -822,29 +822,14 @@ select sql_cache * from t1 where s1=1;
end;// end;//
delimiter ;// delimiter ;//
call f1(); call f1();
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
call f1(); call f1();
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
call f1(); call f1();
select sql_cache * from t1; select sql_cache * from t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
insert into t1 values (1); insert into t1 values (1);
select sql_cache * from t1; select sql_cache * from t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
call f1(); call f1();
call f1(); call f1();
select sql_cache * from t1; select sql_cache * from t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
flush query cache; flush query cache;
reset query cache; reset query cache;
flush status; flush status;
......
...@@ -97,4 +97,88 @@ connection root; ...@@ -97,4 +97,88 @@ connection root;
SELECT * FROM t1; SELECT * FROM t1;
drop table t1; drop table t1;
#
# query in QC from normal execution and SP (BUG#6897)
# improved to also test BUG#3583 and BUG#12990
#
flush query cache;
reset query cache;
flush status;
delimiter //;
create table t1 (s1 int)//
create procedure f1 () begin
select sql_cache * from t1;
select sql_cache * from t1;
select sql_cache * from t1;
end;//
create procedure f2 () begin
select sql_cache * from t1 where s1=1;
select sql_cache * from t1;
end;//
create procedure f3 () begin
select sql_cache * from t1;
select sql_cache * from t1 where s1=1;
end;//
create procedure f4 () begin
select sql_cache * from t1;
select sql_cache * from t1 where s1=1;
select sql_cache * from t1;
select sql_cache * from t1 where s1=1;
select sql_cache * from t1 where s1=1;
end;//
delimiter ;//
call f1();
--replace_result 1 3
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
call f1();
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
call f1();
select sql_cache * from t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
insert into t1 values (1);
select sql_cache * from t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
call f1();
call f1();
select sql_cache * from t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
flush query cache;
reset query cache;
flush status;
select sql_cache * from t1;
select sql_cache * from t1 where s1=1;
call f1();
call f2();
call f3();
call f4();
call f4();
call f3();
call f2();
select sql_cache * from t1 where s1=1;
insert into t1 values (2);
call f1();
select sql_cache * from t1 where s1=1;
select sql_cache * from t1;
call f1();
call f3();
call f3();
call f1();
drop procedure f1;
drop procedure f2;
drop procedure f3;
drop procedure f4;
drop table t1;
set GLOBAL query_cache_size=0; set GLOBAL query_cache_size=0;
# Test of the READ_ONLY global variable: # Test of the READ_ONLY global variable:
# check that it blocks updates unless they are only on temporary tables. # check that it blocks updates unless they are only on temporary tables.
# should work with embedded server after mysqltest is fixed
-- source include/not_embedded.inc
--disable_warnings --disable_warnings
DROP TABLE IF EXISTS t1,t2,t3; DROP TABLE IF EXISTS t1,t2,t3;
--enable_warnings --enable_warnings
......
# This tests not performed with embedded server
-- source include/not_embedded.inc
--disable_warnings --disable_warnings
drop table if exists t1,v1; drop table if exists t1,v1;
drop view if exists t1,v1; drop view if exists t1,v1;
......
...@@ -35,10 +35,13 @@ create trigger t1_ai after insert on t1 for each row call bug14233(); ...@@ -35,10 +35,13 @@ create trigger t1_ai after insert on t1 for each row call bug14233();
# Unsupported tampering with the mysql.proc definition # Unsupported tampering with the mysql.proc definition
alter table mysql.proc drop type; alter table mysql.proc drop type;
--replace_result $MYSQL_TEST_DIR .
--error ER_SP_PROC_TABLE_CORRUPT --error ER_SP_PROC_TABLE_CORRUPT
call bug14233(); call bug14233();
--replace_result $MYSQL_TEST_DIR .
--error ER_SP_PROC_TABLE_CORRUPT --error ER_SP_PROC_TABLE_CORRUPT
create view v1 as select bug14233_f(); create view v1 as select bug14233_f();
--replace_result $MYSQL_TEST_DIR .
--error ER_SP_PROC_TABLE_CORRUPT --error ER_SP_PROC_TABLE_CORRUPT
insert into t1 values (0); insert into t1 values (0);
......
...@@ -647,28 +647,6 @@ create table t5 (x int)| ...@@ -647,28 +647,6 @@ create table t5 (x int)|
call bug3294()| call bug3294()|
drop procedure bug3294| drop procedure bug3294|
#
# BUG#6807: Stored procedure crash if CREATE PROCEDURE ... KILL QUERY
#
--disable_warnings
drop procedure if exists bug6807|
--enable_warnings
create procedure bug6807()
begin
declare id int;
set id = connection_id();
kill query id;
select 'Not reached';
end|
--error 1317
call bug6807()|
--error 1317
call bug6807()|
drop procedure bug6807|
# #
# BUG#876: Stored Procedures: Invalid SQLSTATE is allowed in # BUG#876: Stored Procedures: Invalid SQLSTATE is allowed in
# a DECLARE ? HANDLER FOR stmt. # a DECLARE ? HANDLER FOR stmt.
......
# This test should work in embedded server after mysqltest is fixed
-- source include/not_embedded.inc
# #
# Testing stored procedures with multiple connections, # Testing stored procedures with multiple connections,
# except security/privilege tests, they go to sp-security.test # except security/privilege tests, they go to sp-security.test
......
...@@ -1368,11 +1368,11 @@ end| ...@@ -1368,11 +1368,11 @@ end|
call ifac(20)| call ifac(20)|
select * from fac| select * from fac|
drop table fac| drop table fac|
--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00' --replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
show function status like '%f%'| show function status like '%f%'|
drop procedure ifac| drop procedure ifac|
drop function fac| drop function fac|
--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00' --replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
show function status like '%f%'| show function status like '%f%'|
...@@ -1455,7 +1455,7 @@ begin ...@@ -1455,7 +1455,7 @@ begin
end while; end while;
end| end|
show create procedure opp| show create procedure opp|
--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00' --replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
show procedure status like '%p%'| show procedure status like '%p%'|
# This isn't the fastest way in the world to compute prime numbers, so # This isn't the fastest way in the world to compute prime numbers, so
...@@ -1473,7 +1473,7 @@ select * from primes where i=45 or i=100 or i=199| ...@@ -1473,7 +1473,7 @@ select * from primes where i=45 or i=100 or i=199|
drop table primes| drop table primes|
drop procedure opp| drop procedure opp|
drop procedure ip| drop procedure ip|
--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00' --replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
show procedure status like '%p%'| show procedure status like '%p%'|
...@@ -1541,13 +1541,13 @@ drop procedure if exists bar| ...@@ -1541,13 +1541,13 @@ drop procedure if exists bar|
create procedure bar(x char(16), y int) create procedure bar(x char(16), y int)
comment "111111111111" sql security invoker comment "111111111111" sql security invoker
insert into test.t1 values (x, y)| insert into test.t1 values (x, y)|
--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00' --replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
show procedure status like 'bar'| show procedure status like 'bar'|
alter procedure bar comment "2222222222" sql security definer| alter procedure bar comment "2222222222" sql security definer|
alter procedure bar comment "3333333333"| alter procedure bar comment "3333333333"|
alter procedure bar| alter procedure bar|
show create procedure bar| show create procedure bar|
--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00' --replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
show procedure status like 'bar'| show procedure status like 'bar'|
drop procedure bar| drop procedure bar|
...@@ -2497,7 +2497,6 @@ begin ...@@ -2497,7 +2497,6 @@ begin
show databases like 'foo'; show databases like 'foo';
show errors; show errors;
show columns from t1; show columns from t1;
show grants for 'root'@'localhost';
show keys from t1; show keys from t1;
show open tables like 'foo'; show open tables like 'foo';
show privileges; show privileges;
...@@ -2519,20 +2518,6 @@ call bug4902()| ...@@ -2519,20 +2518,6 @@ call bug4902()|
drop procedure bug4902| drop procedure bug4902|
# We need separate SP for SHOW PROCESSLIST since we want use replace_column
--disable_warnings
drop procedure if exists bug4902_2|
--enable_warnings
create procedure bug4902_2()
begin
show processlist;
end|
--replace_column 1 # 6 # 3 localhost
call bug4902_2()|
--replace_column 1 # 6 # 3 localhost
call bug4902_2()|
drop procedure bug4902_2|
# #
# BUG#4904 # BUG#4904
# #
...@@ -2747,44 +2732,6 @@ select @x| ...@@ -2747,44 +2732,6 @@ select @x|
delete from t1| delete from t1|
drop procedure bug4941| drop procedure bug4941|
#
# BUG#3583: query cache doesn't work for stored procedures
#
--disable_warnings
drop procedure if exists bug3583|
--enable_warnings
--disable_warnings
drop procedure if exists bug3583|
--enable_warnings
create procedure bug3583()
begin
declare c int;
select * from t1;
select count(*) into c from t1;
select c;
end|
insert into t1 values ("x", 3), ("y", 5)|
set @x = @@query_cache_size|
set global query_cache_size = 10*1024*1024|
flush status|
flush query cache|
show status like 'Qcache_hits'|
call bug3583()|
show status like 'Qcache_hits'|
call bug3583()|
call bug3583()|
show status like 'Qcache_hits'|
set global query_cache_size = @x|
flush status|
flush query cache|
delete from t1|
drop procedure bug3583|
# #
# BUG#4905: Stored procedure doesn't clear for "Rows affected" # BUG#4905: Stored procedure doesn't clear for "Rows affected"
# #
...@@ -3093,24 +3040,6 @@ insert into t1 values ("answer", 42)| ...@@ -3093,24 +3040,6 @@ insert into t1 values ("answer", 42)|
select id, bug5240() from t1| select id, bug5240() from t1|
drop function bug5240| drop function bug5240|
#
# BUG#5278: Stored procedure packets out of order if SET PASSWORD.
#
--disable_warnings
drop function if exists bug5278|
--enable_warnings
create function bug5278 () returns char
begin
SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');
return 'okay';
end|
--error 1133
select bug5278()|
--error 1133
select bug5278()|
drop function bug5278|
# #
# BUG#7992: rolling back temporary Item tree changes in SP # BUG#7992: rolling back temporary Item tree changes in SP
# #
...@@ -4733,24 +4662,6 @@ select bug10100f(5)| ...@@ -4733,24 +4662,6 @@ select bug10100f(5)|
call bug10100t(5)| call bug10100t(5)|
#end of the stack checking #end of the stack checking
set @@max_sp_recursion_depth=255|
set @var=1|
#disable log because error about stack overrun contains numbers which
#depend on a system
-- disable_result_log
-- error ER_STACK_OVERRUN_NEED_MORE
call bug10100p(255, @var)|
-- error ER_STACK_OVERRUN_NEED_MORE
call bug10100pt(1,255)|
-- error ER_STACK_OVERRUN_NEED_MORE
call bug10100pv(1,255)|
-- error ER_STACK_OVERRUN_NEED_MORE
call bug10100pd(1,255)|
-- error ER_STACK_OVERRUN_NEED_MORE
call bug10100pc(1,255)|
-- enable_result_log
set @@max_sp_recursion_depth=0|
deallocate prepare stmt2| deallocate prepare stmt2|
drop function bug10100f| drop function bug10100f|
......
# Can't test with embedded server
-- source include/not_embedded.inc
delimiter |;
#
# BUG#4902: Stored procedure with SHOW WARNINGS leads to packet error
#
# Added tests for show grants command
--disable_warnings
drop procedure if exists bug4902|
--enable_warnings
create procedure bug4902()
begin
show grants for 'root'@'localhost';
end|
--disable_parsing
show binlog events;
show storage engines;
show master status;
show slave hosts;
show slave status;
--enable_parsing
call bug4902()|
call bug4902()|
drop procedure bug4902|
# We need separate SP for SHOW PROCESSLIST since we want use replace_column
--disable_warnings
drop procedure if exists bug4902_2|
--enable_warnings
create procedure bug4902_2()
begin
show processlist;
end|
--replace_column 1 # 6 # 3 localhost
call bug4902_2()|
--replace_column 1 # 6 # 3 localhost
call bug4902_2()|
drop procedure bug4902_2|
#
# BUG#5278: Stored procedure packets out of order if SET PASSWORD.
#
--disable_warnings
drop function if exists bug5278|
--enable_warnings
create function bug5278 () returns char
begin
SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');
return 'okay';
end|
--error 1133
select bug5278()|
--error 1133
select bug5278()|
drop function bug5278|
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (
id char(16) not null default '',
data int not null
);
#
# BUG#3583: query cache doesn't work for stored procedures
#
--disable_warnings
drop procedure if exists bug3583|
--enable_warnings
--disable_warnings
drop procedure if exists bug3583|
--enable_warnings
create procedure bug3583()
begin
declare c int;
select * from t1;
select count(*) into c from t1;
select c;
end|
insert into t1 values ("x", 3), ("y", 5)|
set @x = @@query_cache_size|
set global query_cache_size = 10*1024*1024|
flush status|
flush query cache|
show status like 'Qcache_hits'|
call bug3583()|
show status like 'Qcache_hits'|
call bug3583()|
call bug3583()|
show status like 'Qcache_hits'|
set global query_cache_size = @x|
flush status|
flush query cache|
delete from t1|
drop procedure bug3583|
drop table t1;
#
# BUG#6807: Stored procedure crash if CREATE PROCEDURE ... KILL QUERY
#
--disable_warnings
drop procedure if exists bug6807|
--enable_warnings
create procedure bug6807()
begin
declare id int;
set id = connection_id();
kill query id;
select 'Not reached';
end|
--error 1317
call bug6807()|
--error 1317
call bug6807()|
drop procedure bug6807|
#
# BUG#10100: function (and stored procedure?) recursivity problem
#
--disable_warnings
drop function if exists bug10100f|
drop procedure if exists bug10100p|
drop procedure if exists bug10100t|
drop procedure if exists bug10100pt|
drop procedure if exists bug10100pv|
drop procedure if exists bug10100pd|
drop procedure if exists bug10100pc|
--enable_warnings
# routines with simple recursion
create function bug10100f(prm int) returns int
begin
if prm > 1 then
return prm * bug10100f(prm - 1);
end if;
return 1;
end|
create procedure bug10100p(prm int, inout res int)
begin
set res = res * prm;
if prm > 1 then
call bug10100p(prm - 1, res);
end if;
end|
create procedure bug10100t(prm int)
begin
declare res int;
set res = 1;
call bug10100p(prm, res);
select res;
end|
# a procedure which use tables and recursion
create table t3 (a int)|
insert into t3 values (0)|
create view v1 as select a from t3;
create procedure bug10100pt(level int, lim int)
begin
if level < lim then
update t3 set a=level;
FLUSH TABLES;
call bug10100pt(level+1, lim);
else
select * from t3;
end if;
end|
# view & recursion
create procedure bug10100pv(level int, lim int)
begin
if level < lim then
update v1 set a=level;
FLUSH TABLES;
call bug10100pv(level+1, lim);
else
select * from v1;
end if;
end|
# dynamic sql & recursion
prepare stmt2 from "select * from t3;";
create procedure bug10100pd(level int, lim int)
begin
if level < lim then
select level;
prepare stmt1 from "update t3 set a=a+2";
execute stmt1;
FLUSH TABLES;
execute stmt1;
FLUSH TABLES;
execute stmt1;
FLUSH TABLES;
deallocate prepare stmt1;
execute stmt2;
select * from t3;
call bug10100pd(level+1, lim);
else
execute stmt2;
end if;
end|
# cursor & recursion
create procedure bug10100pc(level int, lim int)
begin
declare lv int;
declare c cursor for select a from t3;
open c;
if level < lim then
select level;
fetch c into lv;
select lv;
update t3 set a=level+lv;
FLUSH TABLES;
call bug10100pc(level+1, lim);
else
select * from t3;
end if;
close c;
end|
#end of the stack checking
set @@max_sp_recursion_depth=255|
set @var=1|
#disable log because error about stack overrun contains numbers which
#depend on a system
-- disable_result_log
-- error ER_STACK_OVERRUN_NEED_MORE
call bug10100p(255, @var)|
-- error ER_STACK_OVERRUN_NEED_MORE
call bug10100pt(1,255)|
-- error ER_STACK_OVERRUN_NEED_MORE
call bug10100pv(1,255)|
-- error ER_STACK_OVERRUN_NEED_MORE
call bug10100pd(1,255)|
-- error ER_STACK_OVERRUN_NEED_MORE
call bug10100pc(1,255)|
-- enable_result_log
set @@max_sp_recursion_depth=0|
deallocate prepare stmt2|
drop function bug10100f|
drop procedure bug10100p|
drop procedure bug10100t|
drop procedure bug10100pt|
drop procedure bug10100pv|
drop procedure bug10100pd|
drop procedure bug10100pc|
drop view v1|
delimiter ;|
-- source include/not_embedded.inc
#
# BUG #10308: purge log with subselect
#
purge master logs before (select adddate(current_timestamp(), interval -4 day));
...@@ -2084,7 +2084,9 @@ drop table t1, t2; ...@@ -2084,7 +2084,9 @@ drop table t1, t2;
# #
-- error ER_MALFORMED_DEFINER -- error ER_MALFORMED_DEFINER
create definer=some_user@`` sql security invoker view v1 as select 1; create definer=some_user@`` sql security invoker view v1 as select 1;
--disable_warnings
create definer=some_user@localhost sql security invoker view v1 as select 1; create definer=some_user@localhost sql security invoker view v1 as select 1;
--enable_warnings
show create view v1; show create view v1;
drop view v1; drop view v1;
......
# This tests not performed with embedded server
-- source include/not_embedded.inc
# #
# Bug #8731: wait_timeout does not work on Mac OS X # Bug #8731: wait_timeout does not work on Mac OS X
# #
......
...@@ -1545,7 +1545,8 @@ static MYSQL_METHODS client_methods= ...@@ -1545,7 +1545,8 @@ static MYSQL_METHODS client_methods=
NULL, NULL,
cli_read_statistics, cli_read_statistics,
cli_read_query_result, cli_read_query_result,
cli_read_change_user_result cli_read_change_user_result,
cli_read_binary_rows
#endif #endif
}; };
...@@ -2339,8 +2340,9 @@ static void mysql_close_free(MYSQL *mysql) ...@@ -2339,8 +2340,9 @@ static void mysql_close_free(MYSQL *mysql)
my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->info_buffer,MYF(MY_ALLOW_ZERO_PTR));
/* Clear pointers for better safety */ /* Clear pointers for better safety */
mysql->host_info=mysql->user=mysql->passwd=mysql->db=0; mysql->info_buffer=mysql->host_info=mysql->user=mysql->passwd=mysql->db=0;
} }
...@@ -2476,8 +2478,7 @@ get_info: ...@@ -2476,8 +2478,7 @@ get_info:
if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT)) if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
mysql->server_status|= SERVER_STATUS_IN_TRANS; mysql->server_status|= SERVER_STATUS_IN_TRANS;
if (!(fields=(*mysql->methods->read_rows)(mysql,(MYSQL_FIELD*)0, if (!(fields=cli_read_rows(mysql,(MYSQL_FIELD*)0, protocol_41(mysql) ? 7:5)))
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,
......
...@@ -2473,9 +2473,7 @@ static int my_message_sql(uint error, const char *str, myf MyFlags) ...@@ -2473,9 +2473,7 @@ static int my_message_sql(uint error, const char *str, myf MyFlags)
{ {
NET *net= &thd->net; NET *net= &thd->net;
net->report_error= 1; net->report_error= 1;
#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/
query_cache_abort(net); query_cache_abort(net);
#endif
if (!net->last_error[0]) // Return only first message if (!net->last_error[0]) // Return only first message
{ {
strmake(net->last_error, str, sizeof(net->last_error)-1); strmake(net->last_error, str, sizeof(net->last_error)-1);
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024; static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
static void write_eof_packet(THD *thd, NET *net); static void write_eof_packet(THD *thd, NET *net);
void net_send_error_packet(THD *thd, uint sql_errno, const char *err);
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
bool Protocol::net_store_data(const char *from, uint length) bool Protocol::net_store_data(const char *from, uint length)
...@@ -56,10 +57,6 @@ bool Protocol_prep::net_store_data(const char *from, uint length) ...@@ -56,10 +57,6 @@ bool Protocol_prep::net_store_data(const char *from, uint length)
void net_send_error(THD *thd, uint sql_errno, const char *err) void net_send_error(THD *thd, uint sql_errno, const char *err)
{ {
#ifndef EMBEDDED_LIBRARY
uint length;
char buff[MYSQL_ERRMSG_SIZE+2], *pos;
#endif
NET *net= &thd->net; NET *net= &thd->net;
bool generate_warning= thd->killed != THD::KILL_CONNECTION; bool generate_warning= thd->killed != THD::KILL_CONNECTION;
DBUG_ENTER("net_send_error"); DBUG_ENTER("net_send_error");
...@@ -106,42 +103,8 @@ void net_send_error(THD *thd, uint sql_errno, const char *err) ...@@ -106,42 +103,8 @@ void net_send_error(THD *thd, uint sql_errno, const char *err)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, sql_errno, err); push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, sql_errno, err);
} }
#ifdef EMBEDDED_LIBRARY net_send_error_packet(thd, sql_errno, err);
net->last_errno= sql_errno;
strmake(net->last_error, err, sizeof(net->last_error)-1);
strmov(net->sqlstate, mysql_errno_to_sqlstate(sql_errno));
#else
if (net->vio == 0)
{
if (thd->bootstrap)
{
/* In bootstrap it's ok to print on stderr */
fprintf(stderr,"ERROR: %d %s\n",sql_errno,err);
}
DBUG_VOID_RETURN;
}
if (net->return_errno)
{ // new client code; Add errno before message
int2store(buff,sql_errno);
pos= buff+2;
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{
/* The first # is to make the protocol backward compatible */
buff[2]= '#';
pos= strmov(buff+3, mysql_errno_to_sqlstate(sql_errno));
}
length= (uint) (strmake(pos, err, MYSQL_ERRMSG_SIZE-1) - buff);
err=buff;
}
else
{
length=(uint) strlen(err);
set_if_smaller(length,MYSQL_ERRMSG_SIZE-1);
}
VOID(net_write_command(net,(uchar) 255, "", 0, (char*) err,length));
#endif /* EMBEDDED_LIBRARY*/
thd->is_fatal_error=0; // Error message is given thd->is_fatal_error=0; // Error message is given
thd->net.report_error= 0; thd->net.report_error= 0;
...@@ -430,6 +393,47 @@ bool send_old_password_request(THD *thd) ...@@ -430,6 +393,47 @@ bool send_old_password_request(THD *thd)
return my_net_write(net, eof_buff, 1) || net_flush(net); return my_net_write(net, eof_buff, 1) || net_flush(net);
} }
void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
{
NET *net= &thd->net;
uint length;
char buff[MYSQL_ERRMSG_SIZE+2], *pos;
DBUG_ENTER("send_error_packet");
if (net->vio == 0)
{
if (thd->bootstrap)
{
/* In bootstrap it's ok to print on stderr */
fprintf(stderr,"ERROR: %d %s\n",sql_errno,err);
}
DBUG_VOID_RETURN;
}
if (net->return_errno)
{ // new client code; Add errno before message
int2store(buff,sql_errno);
pos= buff+2;
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{
/* The first # is to make the protocol backward compatible */
buff[2]= '#';
pos= strmov(buff+3, mysql_errno_to_sqlstate(sql_errno));
}
length= (uint) (strmake(pos, err, MYSQL_ERRMSG_SIZE-1) - buff);
err=buff;
}
else
{
length=(uint) strlen(err);
set_if_smaller(length,MYSQL_ERRMSG_SIZE-1);
}
VOID(net_write_command(net,(uchar) 255, "", 0, (char*) err,length));
DBUG_VOID_RETURN;
}
#endif /* EMBEDDED_LIBRARY */ #endif /* EMBEDDED_LIBRARY */
/* /*
......
...@@ -91,6 +91,12 @@ public: ...@@ -91,6 +91,12 @@ public:
virtual bool store_date(TIME *time)=0; virtual bool store_date(TIME *time)=0;
virtual bool store_time(TIME *time)=0; virtual bool store_time(TIME *time)=0;
virtual bool store(Field *field)=0; virtual bool store(Field *field)=0;
#ifdef EMBEDDED_LIBRARY
int begin_dataset();
virtual void remove_last_row() {}
#else
void remove_last_row() {}
#endif
}; };
...@@ -117,6 +123,9 @@ public: ...@@ -117,6 +123,9 @@ public:
virtual bool store(float nr, uint32 decimals, String *buffer); virtual bool store(float nr, uint32 decimals, String *buffer);
virtual bool store(double from, uint32 decimals, String *buffer); virtual bool store(double from, uint32 decimals, String *buffer);
virtual bool store(Field *field); virtual bool store(Field *field);
#ifdef EMBEDDED_LIBRARY
void remove_last_row();
#endif
}; };
......
...@@ -958,7 +958,9 @@ bool select_send::send_data(List<Item> &items) ...@@ -958,7 +958,9 @@ bool select_send::send_data(List<Item> &items)
thd->sent_row_count++; thd->sent_row_count++;
if (!thd->vio_ok()) if (!thd->vio_ok())
DBUG_RETURN(0); DBUG_RETURN(0);
if (!thd->net.report_error) if (thd->net.report_error)
protocol->remove_last_row();
else
DBUG_RETURN(protocol->write()); DBUG_RETURN(protocol->write());
DBUG_RETURN(1); DBUG_RETURN(1);
} }
...@@ -1990,10 +1992,8 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup, ...@@ -1990,10 +1992,8 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
cuted_fields= 0; cuted_fields= 0;
transaction.savepoints= 0; transaction.savepoints= 0;
#ifndef EMBEDDED_LIBRARY
/* Surpress OK packets in case if we will execute statements */ /* Surpress OK packets in case if we will execute statements */
net.no_send_ok= TRUE; net.no_send_ok= TRUE;
#endif
} }
......
...@@ -801,13 +801,16 @@ public: ...@@ -801,13 +801,16 @@ 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_stmt_id;
unsigned long client_param_count; unsigned long client_param_count;
struct st_mysql_bind *client_params; struct st_mysql_bind *client_params;
char *extra_data; char *extra_data;
ulong extra_length; ulong extra_length;
String query_rest; struct st_mysql_data *cur_data;
struct st_mysql_data *first_data;
struct st_mysql_data **data_tail;
void clear_data_list();
struct st_mysql_data *alloc_new_dataset();
#endif #endif
NET net; // client connection descriptor NET net; // client connection descriptor
MEM_ROOT warn_root; // For warnings and errors MEM_ROOT warn_root; // For warnings and errors
...@@ -1441,6 +1444,11 @@ public: ...@@ -1441,6 +1444,11 @@ public:
*/ */
virtual void cleanup(); virtual void cleanup();
void set_thd(THD *thd_arg) { thd= thd_arg; } void set_thd(THD *thd_arg) { thd= thd_arg; }
#ifdef EMBEDDED_LIBRARY
virtual void begin_dataset() {}
#else
void begin_dataset() {}
#endif
}; };
......
...@@ -603,6 +603,7 @@ void Materialized_cursor::fetch(ulong num_rows) ...@@ -603,6 +603,7 @@ void Materialized_cursor::fetch(ulong num_rows)
THD *thd= table->in_use; THD *thd= table->in_use;
int res= 0; int res= 0;
result->begin_dataset();
for (fetch_limit+= num_rows; fetch_count < fetch_limit; fetch_count++) for (fetch_limit+= num_rows; fetch_count < fetch_limit; fetch_count++)
{ {
if ((res= table->file->rnd_next(table->record[0]))) if ((res= table->file->rnd_next(table->record[0])))
......
...@@ -1713,13 +1713,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1713,13 +1713,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
net->no_send_error= 0; net->no_send_error= 0;
/* /*
Multiple queries exits, execute them individually Multiple queries exits, execute them individually
in embedded server - just store them to be executed later
*/ */
#ifndef EMBEDDED_LIBRARY
if (thd->lock || thd->open_tables || thd->derived_tables || if (thd->lock || thd->open_tables || thd->derived_tables ||
thd->prelocked_mode) thd->prelocked_mode)
close_thread_tables(thd); close_thread_tables(thd);
#endif
ulong length= (ulong)(packet_end-packet); ulong length= (ulong)(packet_end-packet);
log_slow_statement(thd); log_slow_statement(thd);
...@@ -1737,25 +1734,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1737,25 +1734,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->set_time(); /* Reset the query start time. */ thd->set_time(); /* Reset the query start time. */
/* TODO: set thd->lex->sql_command to SQLCOM_END here */ /* TODO: set thd->lex->sql_command to SQLCOM_END here */
VOID(pthread_mutex_unlock(&LOCK_thread_count)); VOID(pthread_mutex_unlock(&LOCK_thread_count));
#ifndef EMBEDDED_LIBRARY
mysql_parse(thd, packet, length); mysql_parse(thd, packet, length);
#else
/*
'packet' can point inside the query_rest's buffer
so we have to do memmove here
*/
if (thd->query_rest.length() > length)
{
memmove(thd->query_rest.c_ptr(), packet, length);
thd->query_rest.length(length);
}
else
thd->query_rest.copy(packet, length, thd->query_rest.charset());
thd->server_status&= ~ (SERVER_QUERY_NO_INDEX_USED |
SERVER_QUERY_NO_GOOD_INDEX_USED);
break;
#endif /*EMBEDDED_LIBRARY*/
} }
if (!(specialflag & SPECIAL_NO_PRIOR)) if (!(specialflag & SPECIAL_NO_PRIOR))
...@@ -4242,10 +4221,8 @@ end_with_restore_list: ...@@ -4242,10 +4221,8 @@ end_with_restore_list:
goto error; goto error;
} }
#ifndef EMBEDDED_LIBRARY
my_bool nsok= thd->net.no_send_ok; my_bool nsok= thd->net.no_send_ok;
thd->net.no_send_ok= TRUE; thd->net.no_send_ok= TRUE;
#endif
if (sp->m_flags & sp_head::MULTI_RESULTS) if (sp->m_flags & sp_head::MULTI_RESULTS)
{ {
if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS)) if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS))
...@@ -4255,9 +4232,7 @@ end_with_restore_list: ...@@ -4255,9 +4232,7 @@ end_with_restore_list:
back back
*/ */
my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str); my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
#ifndef EMBEDDED_LIBRARY
thd->net.no_send_ok= nsok; thd->net.no_send_ok= nsok;
#endif
goto error; goto error;
} }
/* /*
...@@ -4274,18 +4249,14 @@ end_with_restore_list: ...@@ -4274,18 +4249,14 @@ end_with_restore_list:
sp->m_db.str, sp->m_name.str, TRUE, 0) || sp->m_db.str, sp->m_name.str, TRUE, 0) ||
sp_change_security_context(thd, sp, &save_ctx)) sp_change_security_context(thd, sp, &save_ctx))
{ {
#ifndef EMBEDDED_LIBRARY
thd->net.no_send_ok= nsok; thd->net.no_send_ok= nsok;
#endif
goto error; goto error;
} }
if (save_ctx && if (save_ctx &&
check_routine_access(thd, EXECUTE_ACL, check_routine_access(thd, EXECUTE_ACL,
sp->m_db.str, sp->m_name.str, TRUE, 0)) sp->m_db.str, sp->m_name.str, TRUE, 0))
{ {
#ifndef EMBEDDED_LIBRARY
thd->net.no_send_ok= nsok; thd->net.no_send_ok= nsok;
#endif
sp_restore_security_context(thd, save_ctx); sp_restore_security_context(thd, save_ctx);
goto error; goto error;
} }
...@@ -4317,9 +4288,7 @@ end_with_restore_list: ...@@ -4317,9 +4288,7 @@ end_with_restore_list:
sp_restore_security_context(thd, save_ctx); sp_restore_security_context(thd, save_ctx);
#endif #endif
#ifndef EMBEDDED_LIBRARY
thd->net.no_send_ok= nsok; thd->net.no_send_ok= nsok;
#endif
thd->server_status&= ~bits_to_be_cleared; thd->server_status&= ~bits_to_be_cleared;
if (!res) if (!res)
......
...@@ -92,6 +92,12 @@ public: ...@@ -92,6 +92,12 @@ public:
virtual bool send_fields(List<Item> &list, uint flags); virtual bool send_fields(List<Item> &list, uint flags);
virtual bool send_data(List<Item> &items); virtual bool send_data(List<Item> &items);
virtual bool send_eof(); virtual bool send_eof();
#ifdef EMBEDDED_LIBRARY
void begin_dataset()
{
protocol.begin_dataset();
}
#endif
}; };
/****************************************************************************** /******************************************************************************
...@@ -524,9 +530,10 @@ void set_param_time(Item_param *param, uchar **pos, ulong len) ...@@ -524,9 +530,10 @@ void set_param_time(Item_param *param, uchar **pos, ulong len)
void set_param_datetime(Item_param *param, uchar **pos, ulong len) void set_param_datetime(Item_param *param, uchar **pos, ulong len)
{ {
MYSQL_TIME *to= (MYSQL_TIME*)*pos; MYSQL_TIME tm= *((MYSQL_TIME*)*pos);
tm.neg= 0;
param->set_time(to, MYSQL_TIMESTAMP_DATETIME, param->set_time(&tm, MYSQL_TIMESTAMP_DATETIME,
MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
} }
......
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