mirror of
https://github.com/MariaDB/server.git
synced 2025-01-26 00:34:18 +01:00
Fixes to embedded server to be able to run tests with it
(Needed for "list of pushes" web page and autopush) include/mysql.h: Fix to embedded server to be able to run tests on it libmysql/libmysql.c: Fix to embedded server to be able to run tests on it libmysqld/emb_qcache.cc: Fix to embedded server to be able to run tests on it libmysqld/embedded_priv.h: Fix to embedded server to be able to run tests on it libmysqld/lib_sql.cc: Fix to embedded server to be able to run tests on it libmysqld/libmysqld.c: Fix to embedded server to be able to run tests on it mysql-test/mysql-test-run.sh: Fix to embedded server to be able to run tests on it mysql-test/r/binlog.result: Updated test for embedded server mysql-test/r/ctype_cp932.result: Updated test for embedded server mysql-test/r/innodb.result: Updated test for embedded server mysql-test/r/mysqltest.result: Updated test for embedded server mysql-test/r/query_cache.result: Updated test for embedded server mysql-test/r/query_cache_notembedded.result: Updated test for embedded server mysql-test/r/sp-error.result: Updated test for embedded server mysql-test/r/sp.result: Updated test for embedded server mysql-test/r/subselect.result: Updated test for embedded server mysql-test/r/view.result: Updated test for embedded server mysql-test/r/view_grant.result: Updated test for embedded server mysql-test/t/backup.test: Updated test for embedded server mysql-test/t/binlog.test: Updated test for embedded server mysql-test/t/blackhole.test: Updated test for embedded server mysql-test/t/compress.test: Updated test for embedded server mysql-test/t/ctype_cp932.test: Updated test for embedded server mysql-test/t/delayed.test: Updated test for embedded server mysql-test/t/handler.test: Updated test for embedded server mysql-test/t/innodb.test: Updated test for embedded server mysql-test/t/mysql.test: Updated test for embedded server mysql-test/t/mysql_client_test.test: Updated test for embedded server mysql-test/t/mysqltest.test: Updated test for embedded server mysql-test/t/query_cache.test: Updated test for embedded server mysql-test/t/query_cache_notembedded.test: Updated test for embedded server mysql-test/t/read_only.test: Updated test for embedded server mysql-test/t/skip_grants.test: Updated test for embedded server mysql-test/t/sp-destruct.test: Updated test for embedded server mysql-test/t/sp-error.test: Updated test for embedded server mysql-test/t/sp-threads.test: Updated test for embedded server mysql-test/t/sp.test: Updated test for embedded server mysql-test/t/subselect.test: Updated test for embedded server mysql-test/t/temp_table.test: Updated test for embedded server mysql-test/t/view.test: Updated test for embedded server mysql-test/t/view_grant.test: Updated test for embedded server mysql-test/t/wait_timeout.test: Updated test for embedded server mysys/mf_dirname.c: Review fix: Don't access data outside of array mysys/my_bitmap.c: Remove compiler warnings scripts/mysql_fix_privilege_tables.sql: Add flush privileges to .sql script so that one doesn't have to reboot mysqld when one runs the mysql_fix_privilege_script sql-common/client.c: Updated test for embedded server sql/item.cc: Remove DBUG_PRINT statement that can cause crashes when running with --debug sql/mysqld.cc: Fix to embedded server to be able to run tests on it sql/protocol.cc: Fix to embedded server to be able to run tests on it (Trivial reconstruction of code) sql/protocol.h: Fix to embedded server to be able to run tests on it sql/sql_base.cc: Better comment sql/sql_class.cc: Fix to embedded server to be able to run tests on it sql/sql_class.h: Fix to embedded server to be able to run tests on it sql/sql_cursor.cc: Fix to embedded server to be able to run tests on it sql/sql_parse.cc: Fix to embedded server to be able to run tests on it Don't crash for disabled commands when using embedded server sql/sql_prepare.cc: Fix to embedded server to be able to run tests on it mysql-test/r/ctype_cp932_notembedded.result: New BitKeeper file ``mysql-test/r/ctype_cp932_notembedded.result'' mysql-test/r/innodb_notembedded.result: New BitKeeper file ``mysql-test/r/innodb_notembedded.result'' mysql-test/r/sp.result.orig: New BitKeeper file ``mysql-test/r/sp.result.orig'' mysql-test/r/sp_notembedded.result: New BitKeeper file ``mysql-test/r/sp_notembedded.result'' mysql-test/r/subselect_notembedded.result: New BitKeeper file ``mysql-test/r/subselect_notembedded.result'' mysql-test/t/ctype_cp932_notembedded.test: New BitKeeper file ``mysql-test/t/ctype_cp932_notembedded.test'' mysql-test/t/innodb_notembedded.test: New BitKeeper file ``mysql-test/t/innodb_notembedded.test'' mysql-test/t/sp.test.orig: New BitKeeper file ``mysql-test/t/sp.test.orig'' mysql-test/t/sp_notembedded.test: New BitKeeper file ``mysql-test/t/sp_notembedded.test'' mysql-test/t/subselect_notembedded.test: New BitKeeper file ``mysql-test/t/subselect_notembedded.test''
This commit is contained in:
parent
ef1316fadd
commit
0afb6ff660
66 changed files with 12108 additions and 698 deletions
include
libmysql
libmysqld
mysql-test
mysql-test-run.sh
r
binlog.resultctype_cp932.resultctype_cp932_notembedded.resultinnodb.resultinnodb_notembedded.resultmysqltest.resultquery_cache.resultquery_cache_notembedded.resultsp-error.resultsp.resultsp.result.origsp_notembedded.resultsubselect.resultsubselect_notembedded.resultview.resultview_grant.result
t
backup.testbinlog.testblackhole.testcompress.testctype_cp932.testctype_cp932_notembedded.testdelayed.testhandler.testinnodb.testinnodb_notembedded.testmysql.testmysql_client_test.testmysqltest.testquery_cache.testquery_cache_notembedded.testread_only.testskip_grants.testsp-destruct.testsp-error.testsp-threads.testsp.testsp.test.origsp_notembedded.testsubselect.testsubselect_notembedded.testtemp_table.testview.testview_grant.testwait_timeout.test
mysys
scripts
sql-common
sql
|
@ -130,14 +130,14 @@ typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */
|
|||
|
||||
#include "my_alloc.h"
|
||||
|
||||
typedef struct embedded_query_result EMBEDDED_QUERY_RESULT;
|
||||
typedef struct st_mysql_data {
|
||||
my_ulonglong rows;
|
||||
unsigned int fields;
|
||||
MYSQL_ROWS *data;
|
||||
MEM_ROOT alloc;
|
||||
#if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY)
|
||||
MYSQL_ROWS **prev_ptr;
|
||||
#endif
|
||||
/* extra info for embedded library */
|
||||
struct embedded_query_result *embedded_info;
|
||||
} MYSQL_DATA;
|
||||
|
||||
enum mysql_option
|
||||
|
@ -287,6 +287,8 @@ typedef struct st_mysql
|
|||
from mysql_stmt_close if close had to cancel result set of this object.
|
||||
*/
|
||||
my_bool *unbuffered_fetch_owner;
|
||||
/* needed for embedded server - no net buffer to store the 'info' */
|
||||
char *info_buffer;
|
||||
} MYSQL;
|
||||
|
||||
typedef struct st_mysql_res {
|
||||
|
@ -755,6 +757,7 @@ typedef struct st_mysql_methods
|
|||
const char *(*read_statistics)(MYSQL *mysql);
|
||||
my_bool (*next_result)(MYSQL *mysql);
|
||||
int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd);
|
||||
int (*read_rows_from_cursor)(MYSQL_STMT *stmt);
|
||||
#endif
|
||||
} MYSQL_METHODS;
|
||||
|
||||
|
|
|
@ -2727,13 +2727,13 @@ stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row)
|
|||
/* Send row request to the server */
|
||||
int4store(buff, stmt->stmt_id);
|
||||
int4store(buff + 4, stmt->prefetch_rows); /* number of rows to fetch */
|
||||
if (cli_advanced_command(mysql, COM_STMT_FETCH, buff, sizeof(buff),
|
||||
NullS, 0, 1))
|
||||
if ((*mysql->methods->advanced_command)(mysql, COM_STMT_FETCH,
|
||||
buff, sizeof(buff), NullS, 0, 1))
|
||||
{
|
||||
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
|
||||
return 1;
|
||||
}
|
||||
if (cli_read_binary_rows(stmt))
|
||||
if ((*mysql->methods->read_rows_from_cursor)(stmt))
|
||||
return 1;
|
||||
stmt->server_status= mysql->server_status;
|
||||
|
||||
|
@ -5143,9 +5143,9 @@ my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode)
|
|||
DBUG_ENTER("mysql_autocommit");
|
||||
DBUG_PRINT("enter", ("mode : %d", auto_mode));
|
||||
|
||||
if (auto_mode) /* set to true */
|
||||
DBUG_RETURN((my_bool) mysql_real_query(mysql, "set autocommit=1", 16));
|
||||
DBUG_RETURN((my_bool) mysql_real_query(mysql, "set autocommit=0", 16));
|
||||
DBUG_RETURN((my_bool) mysql_real_query(mysql, auto_mode ?
|
||||
"set autocommit=1":"set autocommit=0",
|
||||
16));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#ifdef HAVE_QUERY_CACHE
|
||||
#include <mysql.h>
|
||||
#include "emb_qcache.h"
|
||||
#include "embedded_priv.h"
|
||||
|
||||
void Querycache_stream::store_char(char c)
|
||||
{
|
||||
|
@ -284,22 +285,25 @@ int Querycache_stream::load_column(MEM_ROOT *alloc, char** column)
|
|||
|
||||
uint emb_count_querycache_size(THD *thd)
|
||||
{
|
||||
uint result;
|
||||
MYSQL *mysql= thd->mysql;
|
||||
MYSQL_FIELD *field= mysql->fields;
|
||||
MYSQL_FIELD *field_end= field + mysql->field_count;
|
||||
MYSQL_ROWS *cur_row=NULL;
|
||||
my_ulonglong n_rows=0;
|
||||
uint result= 0;
|
||||
MYSQL_FIELD *field;
|
||||
MYSQL_FIELD *field_end;
|
||||
MYSQL_ROWS *cur_row;
|
||||
my_ulonglong n_rows;
|
||||
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)
|
||||
return 0;
|
||||
if (thd->data)
|
||||
{
|
||||
*thd->data->prev_ptr= NULL; // this marks the last record
|
||||
cur_row= thd->data->data;
|
||||
n_rows= thd->data->rows;
|
||||
}
|
||||
result= (uint) (4+8 + (42 + 4*n_rows)*mysql->field_count);
|
||||
return result;
|
||||
*data->embedded_info->prev_ptr= NULL; // this marks the last record
|
||||
cur_row= data->data;
|
||||
n_rows= data->rows;
|
||||
/* n_fields + n_rows + (field_info + strlen * n_rows) * n_fields */
|
||||
result+= (uint) (4+8 + (42 + 4*n_rows)*data->fields);
|
||||
|
||||
for(; field < field_end; field++)
|
||||
{
|
||||
|
@ -313,34 +317,38 @@ uint emb_count_querycache_size(THD *thd)
|
|||
for (; cur_row; cur_row=cur_row->next)
|
||||
{
|
||||
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++)
|
||||
if (*col)
|
||||
result+= *(uint *)((*col) - sizeof(uint));
|
||||
result+= *(uint *)((*col) - sizeof(uint));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void emb_store_querycache_result(Querycache_stream *dst, THD *thd)
|
||||
{
|
||||
MYSQL *mysql= thd->mysql;
|
||||
MYSQL_FIELD *field= mysql->fields;
|
||||
MYSQL_FIELD *field_end= field + mysql->field_count;
|
||||
MYSQL_ROWS *cur_row= NULL;
|
||||
my_ulonglong n_rows= 0;
|
||||
MYSQL_FIELD *field;
|
||||
MYSQL_FIELD *field_end;
|
||||
MYSQL_ROWS *cur_row;
|
||||
my_ulonglong n_rows;
|
||||
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)
|
||||
return;
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
if (thd->data)
|
||||
{
|
||||
*thd->data->prev_ptr= NULL; // this marks the last record
|
||||
cur_row= thd->data->data;
|
||||
n_rows= thd->data->rows;
|
||||
}
|
||||
*data->embedded_info->prev_ptr= NULL; // this marks the last record
|
||||
cur_row= data->data;
|
||||
n_rows= data->rows;
|
||||
|
||||
dst->store_int((uint)mysql->field_count);
|
||||
dst->store_ll((uint)n_rows);
|
||||
dst->store_int((uint)data->fields);
|
||||
dst->store_ll((ulonglong)n_rows);
|
||||
|
||||
for(; field < field_end; field++)
|
||||
{
|
||||
|
@ -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->db, field->db_length);
|
||||
dst->store_str(field->catalog, field->catalog_length);
|
||||
|
||||
dst->store_safe_str(field->def, field->def_length);
|
||||
}
|
||||
|
||||
for (; cur_row; cur_row=cur_row->next)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
uint len= *col ? *(uint *)((*col) - sizeof(uint)) : 0;
|
||||
|
@ -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_VOID_RETURN;
|
||||
}
|
||||
|
||||
int emb_load_querycache_result(THD *thd, Querycache_stream *src)
|
||||
{
|
||||
MYSQL *mysql= thd->mysql;
|
||||
MYSQL_DATA *data;
|
||||
MYSQL_DATA *data= thd->alloc_new_dataset();
|
||||
MYSQL_FIELD *field;
|
||||
MYSQL_FIELD *field_end;
|
||||
MEM_ROOT *f_alloc= &mysql->field_alloc;
|
||||
MEM_ROOT *f_alloc;
|
||||
MYSQL_ROWS *row, *end_row;
|
||||
MYSQL_ROWS **prev_row;
|
||||
ulonglong rows;
|
||||
MYSQL_ROW columns;
|
||||
DBUG_ENTER("emb_load_querycache_result");
|
||||
|
||||
mysql->field_count= src->load_int();
|
||||
if (!data)
|
||||
goto err;
|
||||
init_alloc_root(&data->alloc, 8192,0);
|
||||
f_alloc= &data->alloc;
|
||||
|
||||
data->fields= src->load_int();
|
||||
rows= src->load_ll();
|
||||
|
||||
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;
|
||||
mysql->fields= field;
|
||||
for(field_end= field+mysql->field_count; field < field_end; field++)
|
||||
data->embedded_info->fields_list= field;
|
||||
for(field_end= field+data->fields; field < field_end; field++)
|
||||
{
|
||||
field->length= 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)
|
|||
field->decimals= (unsigned int)src->load_char();
|
||||
|
||||
if (!(field->name= src->load_str(f_alloc, &field->name_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_table= src->load_str(f_alloc, &field->org_table_length))||
|
||||
!(field->db= src->load_str(f_alloc, &field->db_length)) ||
|
||||
!(field->catalog= src->load_str(f_alloc, &field->catalog_length)) ||
|
||||
src->load_safe_str(f_alloc, &field->def, &field->def_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_table= src->load_str(f_alloc, &field->org_table_length))||
|
||||
!(field->db= src->load_str(f_alloc, &field->db_length)) ||
|
||||
!(field->catalog= src->load_str(f_alloc, &field->catalog_length)) ||
|
||||
src->load_safe_str(f_alloc, &field->def, &field->def_length))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!rows)
|
||||
return 0;
|
||||
if (!(data= (MYSQL_DATA*)my_malloc(sizeof(MYSQL_DATA),
|
||||
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*)));
|
||||
row= (MYSQL_ROWS *)alloc_root(&data->alloc,
|
||||
(uint) (rows * sizeof(MYSQL_ROWS) +
|
||||
rows*(data->fields+1)*sizeof(char*)));
|
||||
end_row= row + rows;
|
||||
columns= (MYSQL_ROW)end_row;
|
||||
|
||||
data->rows= rows;
|
||||
data->fields= mysql->field_count;
|
||||
data->data= row;
|
||||
if (!rows)
|
||||
goto return_ok;
|
||||
|
||||
for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++)
|
||||
{
|
||||
*prev_row= row;
|
||||
row->data= columns;
|
||||
MYSQL_ROW col_end= columns + mysql->field_count;
|
||||
MYSQL_ROW col_end= columns + data->fields;
|
||||
for (; columns < col_end; columns++)
|
||||
src->load_column(&data->alloc, columns);
|
||||
|
||||
*(columns++)= NULL;
|
||||
}
|
||||
*prev_row= NULL;
|
||||
data->prev_ptr= prev_row;
|
||||
|
||||
return 0;
|
||||
data->embedded_info->prev_ptr= prev_row;
|
||||
return_ok:
|
||||
send_eof(thd);
|
||||
DBUG_RETURN(0);
|
||||
err:
|
||||
return 1;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
#endif /*HAVE_QUERY_CACHE*/
|
||||
|
|
|
@ -16,18 +16,25 @@
|
|||
|
||||
/* 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
|
||||
void lib_connection_phase(NET *net, int phase);
|
||||
void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db);
|
||||
void *create_embedded_thd(int client_flag, char *db);
|
||||
int check_embedded_connection(MYSQL *mysql);
|
||||
void free_old_query(MYSQL *mysql);
|
||||
void embedded_get_error(MYSQL *mysql);
|
||||
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
|
||||
|
|
|
@ -42,21 +42,48 @@ C_MODE_START
|
|||
#undef ER
|
||||
#include "errmsg.h"
|
||||
#include <sql_common.h>
|
||||
#include "embedded_priv.h"
|
||||
|
||||
void embedded_get_error(MYSQL *mysql)
|
||||
static my_bool emb_read_query_result(MYSQL *mysql);
|
||||
|
||||
void THD::clear_data_list()
|
||||
{
|
||||
while (first_data)
|
||||
{
|
||||
MYSQL_DATA *data= first_data;
|
||||
first_data= data->embedded_info->next;
|
||||
free_rows(data);
|
||||
}
|
||||
data_tail= &first_data;
|
||||
free_rows(cur_data);
|
||||
cur_data= 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Reads error information from the MYSQL_DATA and puts
|
||||
it into proper MYSQL members
|
||||
|
||||
SYNOPSIS
|
||||
embedded_get_error()
|
||||
mysql connection handler
|
||||
data query result
|
||||
|
||||
NOTES
|
||||
after that function error information will be accessible
|
||||
with usual functions like mysql_error()
|
||||
data is my_free-d in this function
|
||||
most of the data is stored in data->embedded_info structure
|
||||
*/
|
||||
|
||||
void embedded_get_error(MYSQL *mysql, MYSQL_DATA *data)
|
||||
{
|
||||
THD *thd=(THD *) mysql->thd;
|
||||
NET *net= &mysql->net;
|
||||
if ((net->last_errno= thd->net.last_errno))
|
||||
{
|
||||
memcpy(net->last_error, thd->net.last_error, sizeof(net->last_error));
|
||||
memcpy(net->sqlstate, thd->net.sqlstate, sizeof(net->sqlstate));
|
||||
}
|
||||
else
|
||||
{
|
||||
net->last_error[0]= 0;
|
||||
strmov(net->sqlstate, not_error_sqlstate);
|
||||
}
|
||||
struct embedded_query_result *ei= data->embedded_info;
|
||||
net->last_errno= ei->last_errno;
|
||||
strmake(net->last_error, ei->info, sizeof(net->last_error));
|
||||
memcpy(net->sqlstate, ei->sqlstate, sizeof(net->sqlstate));
|
||||
my_free((gptr) data, MYF(0));
|
||||
}
|
||||
|
||||
static my_bool
|
||||
|
@ -68,11 +95,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
|
|||
THD *thd=(THD *) mysql->thd;
|
||||
NET *net= &mysql->net;
|
||||
|
||||
if (thd->data)
|
||||
{
|
||||
free_rows(thd->data);
|
||||
thd->data= 0;
|
||||
}
|
||||
thd->clear_data_list();
|
||||
/* Check that we are calling the client functions in right order */
|
||||
if (mysql->status != MYSQL_STATUS_READY)
|
||||
{
|
||||
|
@ -104,83 +127,101 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
|
|||
arg_length= header_length;
|
||||
}
|
||||
|
||||
thd->net.no_send_error= 0;
|
||||
result= dispatch_command(command, thd, (char *) arg, arg_length + 1);
|
||||
thd->cur_data= 0;
|
||||
|
||||
if (!skip_check)
|
||||
result= thd->net.last_errno ? -1 : 0;
|
||||
|
||||
/*
|
||||
If mysql->field_count is set it means the parsing of the query was OK
|
||||
and metadata was returned (see Protocol::send_fields).
|
||||
In this case we postpone the error to be returned in mysql_stmt_store_result
|
||||
(see emb_read_rows) to behave just as standalone server.
|
||||
*/
|
||||
if (!mysql->field_count)
|
||||
embedded_get_error(mysql);
|
||||
mysql->server_status= thd->server_status;
|
||||
mysql->warning_count= ((THD*)mysql->thd)->total_warn_count;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void emb_flush_use_result(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_DATA *data= ((THD*)(mysql->thd))->data;
|
||||
|
||||
if (data)
|
||||
THD *thd= (THD*) mysql->thd;
|
||||
if (thd->cur_data)
|
||||
{
|
||||
free_rows(thd->cur_data);
|
||||
thd->cur_data= 0;
|
||||
}
|
||||
else if (thd->first_data)
|
||||
{
|
||||
MYSQL_DATA *data= thd->first_data;
|
||||
thd->first_data= data->embedded_info->next;
|
||||
free_rows(data);
|
||||
((THD*)(mysql->thd))->data= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
reads dataset from the next query result
|
||||
|
||||
SYNOPSIS
|
||||
emb_read_rows()
|
||||
mysql connection handle
|
||||
other parameters are not used
|
||||
|
||||
NOTES
|
||||
It just gets next MYSQL_DATA from the result's queue
|
||||
|
||||
RETURN
|
||||
pointer to MYSQL_DATA with the coming recordset
|
||||
*/
|
||||
|
||||
static MYSQL_DATA *
|
||||
emb_read_rows(MYSQL *mysql, MYSQL_FIELD *mysql_fields __attribute__((unused)),
|
||||
unsigned int fields __attribute__((unused)))
|
||||
{
|
||||
MYSQL_DATA *result= ((THD*)mysql->thd)->data;
|
||||
embedded_get_error(mysql);
|
||||
if (mysql->net.last_errno)
|
||||
return NULL;
|
||||
if (!result)
|
||||
MYSQL_DATA *result= ((THD*)mysql->thd)->cur_data;
|
||||
((THD*)mysql->thd)->cur_data= 0;
|
||||
if (result->embedded_info->last_errno)
|
||||
{
|
||||
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;
|
||||
embedded_get_error(mysql, result);
|
||||
return NULL;
|
||||
}
|
||||
*result->prev_ptr= NULL;
|
||||
((THD*)mysql->thd)->data= NULL;
|
||||
*result->embedded_info->prev_ptr= NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static MYSQL_FIELD *emb_list_fields(MYSQL *mysql)
|
||||
{
|
||||
MYSQL_DATA *res;
|
||||
if (emb_read_query_result(mysql))
|
||||
return 0;
|
||||
res= ((THD*) mysql->thd)->cur_data;
|
||||
((THD*) mysql->thd)->cur_data= 0;
|
||||
mysql->field_alloc= res->alloc;
|
||||
my_free((gptr) res,MYF(0));
|
||||
mysql->status= MYSQL_STATUS_READY;
|
||||
return mysql->fields;
|
||||
}
|
||||
|
||||
static my_bool emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
|
||||
{
|
||||
THD *thd= (THD*)mysql->thd;
|
||||
if (mysql->net.last_errno)
|
||||
return 1;
|
||||
THD *thd= (THD*) mysql->thd;
|
||||
MYSQL_DATA *res;
|
||||
|
||||
stmt->stmt_id= thd->client_stmt_id;
|
||||
stmt->param_count= thd->client_param_count;
|
||||
stmt->field_count= mysql->field_count;
|
||||
stmt->field_count= 0;
|
||||
|
||||
if (stmt->field_count != 0)
|
||||
if (thd->first_data)
|
||||
{
|
||||
if (emb_read_query_result(mysql))
|
||||
return 1;
|
||||
stmt->field_count= mysql->field_count;
|
||||
mysql->status= MYSQL_STATUS_READY;
|
||||
res= thd->cur_data;
|
||||
thd->cur_data= NULL;
|
||||
if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
|
||||
mysql->server_status|= SERVER_STATUS_IN_TRANS;
|
||||
|
||||
stmt->fields= mysql->fields;
|
||||
stmt->mem_root= mysql->field_alloc;
|
||||
stmt->mem_root= res->alloc;
|
||||
mysql->fields= NULL;
|
||||
my_free((gptr) res,MYF(0));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -201,13 +242,42 @@ static void emb_fetch_lengths(ulong *to, MYSQL_ROW column,
|
|||
*to= *column ? *(uint *)((*column) - sizeof(uint)) : 0;
|
||||
}
|
||||
|
||||
static my_bool emb_mysql_read_query_result(MYSQL *mysql)
|
||||
static my_bool emb_read_query_result(MYSQL *mysql)
|
||||
{
|
||||
if (mysql->net.last_errno)
|
||||
return -1;
|
||||
THD *thd= (THD*) mysql->thd;
|
||||
MYSQL_DATA *res= thd->first_data;
|
||||
DBUG_ASSERT(!thd->cur_data);
|
||||
thd->first_data= res->embedded_info->next;
|
||||
if (res->embedded_info->last_errno &&
|
||||
!res->embedded_info->fields_list)
|
||||
{
|
||||
embedded_get_error(mysql, res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mysql->field_count)
|
||||
mysql->warning_count= res->embedded_info->warning_count;
|
||||
mysql->server_status= res->embedded_info->server_status;
|
||||
mysql->field_count= res->fields;
|
||||
mysql->fields= res->embedded_info->fields_list;
|
||||
mysql->affected_rows= res->embedded_info->affected_rows;
|
||||
mysql->insert_id= res->embedded_info->insert_id;
|
||||
mysql->net.last_errno= 0;
|
||||
mysql->net.last_error[0]= 0;
|
||||
mysql->info= 0;
|
||||
|
||||
if (res->embedded_info->info[0])
|
||||
{
|
||||
strmake(mysql->info_buffer, res->embedded_info->info, MYSQL_ERRMSG_SIZE-1);
|
||||
mysql->info= mysql->info_buffer;
|
||||
}
|
||||
|
||||
if (res->embedded_info->fields_list)
|
||||
{
|
||||
mysql->status=MYSQL_STATUS_GET_RESULT;
|
||||
thd->cur_data= res;
|
||||
}
|
||||
else
|
||||
my_free((gptr) res, MYF(0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -215,14 +285,18 @@ static my_bool emb_mysql_read_query_result(MYSQL *mysql)
|
|||
static int emb_stmt_execute(MYSQL_STMT *stmt)
|
||||
{
|
||||
DBUG_ENTER("emb_stmt_execute");
|
||||
char header[4];
|
||||
char header[5];
|
||||
MYSQL_DATA *res;
|
||||
THD *thd;
|
||||
|
||||
int4store(header, stmt->stmt_id);
|
||||
THD *thd= (THD*)stmt->mysql->thd;
|
||||
header[4]= stmt->flags;
|
||||
thd= (THD*)stmt->mysql->thd;
|
||||
thd->client_param_count= stmt->param_count;
|
||||
thd->client_params= stmt->params;
|
||||
if (emb_advanced_command(stmt->mysql, COM_STMT_EXECUTE,0,0,
|
||||
header, sizeof(header), 1) ||
|
||||
emb_mysql_read_query_result(stmt->mysql))
|
||||
emb_read_query_result(stmt->mysql))
|
||||
{
|
||||
NET *net= &stmt->mysql->net;
|
||||
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
|
||||
|
@ -230,6 +304,8 @@ static int emb_stmt_execute(MYSQL_STMT *stmt)
|
|||
}
|
||||
stmt->affected_rows= stmt->mysql->affected_rows;
|
||||
stmt->insert_id= stmt->mysql->insert_id;
|
||||
stmt->server_status= stmt->mysql->server_status;
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -240,22 +316,53 @@ int emb_read_binary_rows(MYSQL_STMT *stmt)
|
|||
return 1;
|
||||
stmt->result= *data;
|
||||
my_free((char *) data, MYF(0));
|
||||
set_stmt_errmsg(stmt, stmt->mysql->net.last_error,
|
||||
stmt->mysql->net.last_errno, stmt->mysql->net.sqlstate);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int emb_read_rows_from_cursor(MYSQL_STMT *stmt)
|
||||
{
|
||||
MYSQL *mysql= stmt->mysql;
|
||||
THD *thd= (THD*) mysql->thd;
|
||||
MYSQL_DATA *res= thd->first_data;
|
||||
DBUG_ASSERT(!thd->first_data->embedded_info->next);
|
||||
thd->first_data= 0;
|
||||
if (res->embedded_info->last_errno)
|
||||
{
|
||||
embedded_get_error(mysql, res);
|
||||
set_stmt_errmsg(stmt, mysql->net.last_error,
|
||||
mysql->net.last_errno, mysql->net.sqlstate);
|
||||
return 1;
|
||||
}
|
||||
|
||||
thd->cur_data= res;
|
||||
mysql->warning_count= res->embedded_info->warning_count;
|
||||
mysql->server_status= res->embedded_info->server_status;
|
||||
mysql->net.last_errno= 0;
|
||||
mysql->net.last_error[0]= 0;
|
||||
|
||||
return emb_read_binary_rows(stmt);
|
||||
}
|
||||
|
||||
int emb_unbuffered_fetch(MYSQL *mysql, char **row)
|
||||
{
|
||||
MYSQL_DATA *data= ((THD*)mysql->thd)->data;
|
||||
embedded_get_error(mysql);
|
||||
if (mysql->net.last_errno)
|
||||
return mysql->net.last_errno;
|
||||
THD *thd= (THD*) mysql->thd;
|
||||
MYSQL_DATA *data= thd->cur_data;
|
||||
if (data && data->embedded_info->last_errno)
|
||||
{
|
||||
embedded_get_error(mysql, data);
|
||||
thd->cur_data= 0;
|
||||
return 1;
|
||||
}
|
||||
if (!data || !data->data)
|
||||
{
|
||||
*row= NULL;
|
||||
if (data)
|
||||
{
|
||||
thd->cur_data= thd->first_data;
|
||||
thd->first_data= data->embedded_info->next;
|
||||
free_rows(data);
|
||||
((THD*)mysql->thd)->data= NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -269,9 +376,9 @@ int emb_unbuffered_fetch(MYSQL *mysql, char **row)
|
|||
static void emb_free_embedded_thd(MYSQL *mysql)
|
||||
{
|
||||
THD *thd= (THD*)mysql->thd;
|
||||
if (thd->data)
|
||||
free_rows(thd->data);
|
||||
thd->clear_data_list();
|
||||
thread_count--;
|
||||
thd->store_globals();
|
||||
delete thd;
|
||||
mysql->thd=0;
|
||||
}
|
||||
|
@ -283,23 +390,11 @@ static const char * emb_read_statistics(MYSQL *mysql)
|
|||
}
|
||||
|
||||
|
||||
static MYSQL_RES * emb_mysql_store_result(MYSQL *mysql)
|
||||
static MYSQL_RES * emb_store_result(MYSQL *mysql)
|
||||
{
|
||||
return mysql_store_result(mysql);
|
||||
}
|
||||
|
||||
my_bool emb_next_result(MYSQL *mysql)
|
||||
{
|
||||
THD *thd= (THD*)mysql->thd;
|
||||
DBUG_ENTER("emb_next_result");
|
||||
|
||||
if (emb_advanced_command(mysql, COM_QUERY,0,0,
|
||||
thd->query_rest.ptr(),thd->query_rest.length(),1) ||
|
||||
emb_mysql_read_query_result(mysql))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
DBUG_RETURN(0); /* No more results */
|
||||
}
|
||||
|
||||
int emb_read_change_user_result(MYSQL *mysql,
|
||||
char *buff __attribute__((unused)),
|
||||
|
@ -310,10 +405,10 @@ int emb_read_change_user_result(MYSQL *mysql,
|
|||
|
||||
MYSQL_METHODS embedded_methods=
|
||||
{
|
||||
emb_mysql_read_query_result,
|
||||
emb_read_query_result,
|
||||
emb_advanced_command,
|
||||
emb_read_rows,
|
||||
emb_mysql_store_result,
|
||||
emb_store_result,
|
||||
emb_fetch_lengths,
|
||||
emb_flush_use_result,
|
||||
emb_list_fields,
|
||||
|
@ -323,8 +418,9 @@ MYSQL_METHODS embedded_methods=
|
|||
emb_unbuffered_fetch,
|
||||
emb_free_embedded_thd,
|
||||
emb_read_statistics,
|
||||
emb_next_result,
|
||||
emb_read_change_user_result
|
||||
emb_read_query_result,
|
||||
emb_read_change_user_result,
|
||||
emb_read_rows_from_cursor
|
||||
};
|
||||
|
||||
C_MODE_END
|
||||
|
@ -483,6 +579,7 @@ void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db)
|
|||
THD *thd = (THD *)mysql->thd;
|
||||
thd->mysql= mysql;
|
||||
mysql->server_version= server_version;
|
||||
init_alloc_root(&mysql->field_alloc, 8192, 0);
|
||||
}
|
||||
|
||||
void *create_embedded_thd(int client_flag, char *db)
|
||||
|
@ -490,6 +587,7 @@ void *create_embedded_thd(int client_flag, char *db)
|
|||
THD * thd= new THD;
|
||||
thd->thread_id= thread_id++;
|
||||
|
||||
thd->thread_stack= (char*) &thd;
|
||||
if (thd->store_globals())
|
||||
{
|
||||
fprintf(stderr,"store_globals failed.\n");
|
||||
|
@ -517,9 +615,10 @@ void *create_embedded_thd(int client_flag, char *db)
|
|||
thd->security_ctx->db_access= DB_ACLS;
|
||||
thd->security_ctx->master_access= ~NO_ACCESS;
|
||||
#endif
|
||||
thd->net.query_cache_query= 0;
|
||||
|
||||
thd->data= 0;
|
||||
thd->cur_data= 0;
|
||||
thd->first_data= 0;
|
||||
thd->data_tail= &thd->first_data;
|
||||
bzero((char*) &thd->net, sizeof(thd->net));
|
||||
|
||||
thread_count++;
|
||||
return thd;
|
||||
|
@ -531,11 +630,15 @@ err:
|
|||
#ifdef NO_EMBEDDED_ACCESS_CHECKS
|
||||
int check_embedded_connection(MYSQL *mysql)
|
||||
{
|
||||
int result;
|
||||
THD *thd= (THD*)mysql->thd;
|
||||
Security_context *sctx= thd->security_ctx;
|
||||
sctx->host_or_ip= sctx->host= (char*)my_localhost;
|
||||
sctx->host_or_ip= sctx->host= (char*) my_localhost;
|
||||
strmake(sctx->priv_host, (char*) my_localhost, MAX_HOSTNAME-1);
|
||||
sctx->priv_user= sctx->user= my_strdup(mysql->user, MYF(0));
|
||||
return check_user(thd, COM_CONNECT, NULL, 0, thd->db, true);
|
||||
result= check_user(thd, COM_CONNECT, NULL, 0, thd->db, true);
|
||||
emb_read_query_result(mysql);
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -616,26 +719,147 @@ static char *dup_str_aux(MEM_ROOT *root, const char *from, uint length,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
creates new result and hooks it to the list
|
||||
|
||||
SYNOPSIS
|
||||
alloc_new_dataset()
|
||||
|
||||
NOTES
|
||||
allocs the MYSQL_DATA + embedded_query_result couple
|
||||
to store the next query result,
|
||||
links these two and attach it to the THD::data_tail
|
||||
|
||||
RETURN
|
||||
pointer to the newly created query result
|
||||
*/
|
||||
|
||||
MYSQL_DATA *THD::alloc_new_dataset()
|
||||
{
|
||||
MYSQL_DATA *data;
|
||||
struct embedded_query_result *emb_data;
|
||||
if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
|
||||
&data, sizeof(*data),
|
||||
&emb_data, sizeof(*emb_data),
|
||||
NULL))
|
||||
return NULL;
|
||||
|
||||
emb_data->prev_ptr= &data->data;
|
||||
cur_data= data;
|
||||
*data_tail= data;
|
||||
data_tail= &emb_data->next;
|
||||
data->embedded_info= emb_data;
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
stores server_status and warning_count in the current
|
||||
query result structures
|
||||
|
||||
SYNOPSIS
|
||||
write_eof_packet()
|
||||
thd current thread
|
||||
|
||||
NOTES
|
||||
should be called to after we get the recordset-result
|
||||
|
||||
*/
|
||||
|
||||
static void write_eof_packet(THD *thd)
|
||||
{
|
||||
/*
|
||||
The following test should never be true, but it's better to do it
|
||||
because if 'is_fatal_error' is set the server is not going to execute
|
||||
other queries (see the if test in dispatch_command / COM_QUERY)
|
||||
*/
|
||||
if (thd->is_fatal_error)
|
||||
thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
|
||||
thd->cur_data->embedded_info->server_status= thd->server_status;
|
||||
/*
|
||||
Don't send warn count during SP execution, as the warn_list
|
||||
is cleared between substatements, and mysqltest gets confused
|
||||
*/
|
||||
thd->cur_data->embedded_info->warning_count=
|
||||
(thd->spcont ? 0 : min(thd->total_warn_count, 65535));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
allocs new query result and initialises Protocol::alloc
|
||||
|
||||
SYNOPSIS
|
||||
Protocol::begin_dataset()
|
||||
|
||||
RETURN
|
||||
0 if success
|
||||
1 if memory allocation failed
|
||||
*/
|
||||
|
||||
int Protocol::begin_dataset()
|
||||
{
|
||||
MYSQL_DATA *data= thd->alloc_new_dataset();
|
||||
if (!data)
|
||||
return 1;
|
||||
alloc= &data->alloc;
|
||||
init_alloc_root(alloc,8192,0); /* Assume rowlength < 8192 */
|
||||
alloc->min_malloc=sizeof(MYSQL_ROWS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
remove last row of current recordset
|
||||
|
||||
SYNOPSIS
|
||||
Protocol_simple::remove_last_row()
|
||||
|
||||
NOTES
|
||||
does the loop from the beginning of the current recordset to
|
||||
the last record and cuts it off.
|
||||
Not supposed to be frequently called.
|
||||
*/
|
||||
|
||||
void Protocol_simple::remove_last_row()
|
||||
{
|
||||
MYSQL_DATA *data= thd->cur_data;
|
||||
MYSQL_ROWS **last_row_hook= &data->data;
|
||||
uint count= data->rows;
|
||||
DBUG_ENTER("Protocol_simple::remove_last_row");
|
||||
while (--count)
|
||||
last_row_hook= &(*last_row_hook)->next;
|
||||
|
||||
*last_row_hook= 0;
|
||||
data->embedded_info->prev_ptr= last_row_hook;
|
||||
data->rows--;
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
bool Protocol::send_fields(List<Item> *list, uint flags)
|
||||
{
|
||||
List_iterator_fast<Item> it(*list);
|
||||
Item *item;
|
||||
MYSQL_FIELD *client_field;
|
||||
MYSQL *mysql= thd->mysql;
|
||||
MEM_ROOT *field_alloc;
|
||||
CHARSET_INFO *thd_cs= thd->variables.character_set_results;
|
||||
CHARSET_INFO *cs= system_charset_info;
|
||||
|
||||
MYSQL_DATA *data;
|
||||
DBUG_ENTER("send_fields");
|
||||
|
||||
if (!mysql) // bootstrap file handling
|
||||
if (!thd->mysql) // bootstrap file handling
|
||||
DBUG_RETURN(0);
|
||||
|
||||
field_count= list->elements;
|
||||
field_alloc= &mysql->field_alloc;
|
||||
if (!(client_field= thd->mysql->fields=
|
||||
(MYSQL_FIELD *)alloc_root(field_alloc,
|
||||
sizeof(MYSQL_FIELD) * field_count)))
|
||||
if (begin_dataset())
|
||||
goto err;
|
||||
|
||||
data= thd->cur_data;
|
||||
data->fields= field_count= list->elements;
|
||||
field_alloc= &data->alloc;
|
||||
|
||||
if (!(client_field= data->embedded_info->fields_list=
|
||||
(MYSQL_FIELD*)alloc_root(field_alloc, sizeof(MYSQL_FIELD)*field_count)))
|
||||
goto err;
|
||||
|
||||
while ((item= it++))
|
||||
|
@ -643,6 +867,10 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
|
|||
Send_field server_field;
|
||||
item->make_field(&server_field);
|
||||
|
||||
/* Keep things compatible for old clients */
|
||||
if (server_field.type == MYSQL_TYPE_VARCHAR)
|
||||
server_field.type= MYSQL_TYPE_VAR_STRING;
|
||||
|
||||
client_field->db= dup_str_aux(field_alloc, server_field.db_name,
|
||||
strlen(server_field.db_name), cs, thd_cs);
|
||||
client_field->table= dup_str_aux(field_alloc, server_field.table_name,
|
||||
|
@ -703,7 +931,9 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
|
|||
client_field->max_length= 0;
|
||||
++client_field;
|
||||
}
|
||||
thd->mysql->field_count= field_count;
|
||||
|
||||
if (flags & SEND_EOF)
|
||||
write_eof_packet(thd);
|
||||
|
||||
DBUG_RETURN(prepare_for_send(list));
|
||||
err:
|
||||
|
@ -723,25 +953,11 @@ bool Protocol::write()
|
|||
bool Protocol_prep::write()
|
||||
{
|
||||
MYSQL_ROWS *cur;
|
||||
MYSQL_DATA *data= thd->data;
|
||||
|
||||
if (!data)
|
||||
{
|
||||
if (!(data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
|
||||
MYF(MY_WME | MY_ZEROFILL))))
|
||||
return true;
|
||||
|
||||
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;
|
||||
}
|
||||
MYSQL_DATA *data= thd->cur_data;
|
||||
|
||||
data->rows++;
|
||||
if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS)+packet->length())))
|
||||
if (!(cur= (MYSQL_ROWS *)alloc_root(alloc,
|
||||
sizeof(MYSQL_ROWS)+packet->length())))
|
||||
{
|
||||
my_error(ER_OUT_OF_RESOURCES,MYF(0));
|
||||
return true;
|
||||
|
@ -750,8 +966,8 @@ bool Protocol_prep::write()
|
|||
memcpy(cur->data, packet->ptr()+1, packet->length()-1);
|
||||
cur->length= packet->length(); /* To allow us to do sanity checks */
|
||||
|
||||
*data->prev_ptr= cur;
|
||||
data->prev_ptr= &cur->next;
|
||||
*data->embedded_info->prev_ptr= cur;
|
||||
data->embedded_info->prev_ptr= &cur->next;
|
||||
cur->next= 0;
|
||||
|
||||
return false;
|
||||
|
@ -761,46 +977,52 @@ void
|
|||
send_ok(THD *thd,ha_rows affected_rows,ulonglong id,const char *message)
|
||||
{
|
||||
DBUG_ENTER("send_ok");
|
||||
MYSQL *mysql= current_thd->mysql;
|
||||
MYSQL_DATA *data;
|
||||
MYSQL *mysql= thd->mysql;
|
||||
|
||||
if (!mysql) // bootstrap file handling
|
||||
DBUG_VOID_RETURN;
|
||||
mysql->affected_rows= affected_rows;
|
||||
mysql->insert_id= id;
|
||||
if (thd->net.no_send_ok) // hack for re-parsing queries
|
||||
DBUG_VOID_RETURN;
|
||||
if (!(data= thd->alloc_new_dataset()))
|
||||
return;
|
||||
data->embedded_info->affected_rows= affected_rows;
|
||||
data->embedded_info->insert_id= id;
|
||||
if (message)
|
||||
{
|
||||
strmake(thd->net.last_error, message, sizeof(thd->net.last_error)-1);
|
||||
mysql->info= thd->net.last_error;
|
||||
}
|
||||
strmake(data->embedded_info->info, message,
|
||||
sizeof(data->embedded_info->info)-1);
|
||||
|
||||
write_eof_packet(thd);
|
||||
thd->cur_data= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void
|
||||
send_eof(THD *thd)
|
||||
{
|
||||
write_eof_packet(thd);
|
||||
thd->cur_data= 0;
|
||||
}
|
||||
|
||||
|
||||
void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
|
||||
{
|
||||
MYSQL_DATA *data= thd->cur_data ? thd->cur_data : thd->alloc_new_dataset();
|
||||
struct embedded_query_result *ei= data->embedded_info;
|
||||
|
||||
ei->last_errno= sql_errno;
|
||||
strmake(ei->info, err, sizeof(ei->info)-1);
|
||||
strmov(ei->sqlstate, mysql_errno_to_sqlstate(sql_errno));
|
||||
thd->cur_data= 0;
|
||||
}
|
||||
|
||||
|
||||
void Protocol_simple::prepare_for_resend()
|
||||
{
|
||||
MYSQL_ROWS *cur;
|
||||
MYSQL_DATA *data= thd->data;
|
||||
|
||||
MYSQL_DATA *data= thd->cur_data;
|
||||
DBUG_ENTER("send_data");
|
||||
|
||||
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 *))))
|
||||
{
|
||||
|
@ -809,10 +1031,10 @@ void Protocol_simple::prepare_for_resend()
|
|||
}
|
||||
cur->data= (MYSQL_ROW)(((char *)cur) + sizeof(MYSQL_ROWS));
|
||||
|
||||
*data->prev_ptr= cur;
|
||||
data->prev_ptr= &cur->next;
|
||||
*data->embedded_info->prev_ptr= cur;
|
||||
data->embedded_info->prev_ptr= &cur->next;
|
||||
next_field=cur->data;
|
||||
next_mysql_field= thd->mysql->fields;
|
||||
next_mysql_field= data->embedded_info->fields_list;
|
||||
err:
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,11 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
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 <my_sys.h>
|
||||
#include <mysys_err.h>
|
||||
|
@ -193,7 +198,12 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
|||
|
||||
if (!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;
|
||||
unix_socket=0;
|
||||
|
@ -207,6 +217,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
|||
if (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);
|
||||
|
||||
init_embedded_mysql(mysql, client_flag, db_name);
|
||||
|
@ -243,7 +254,6 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
|||
DBUG_RETURN(mysql);
|
||||
|
||||
error:
|
||||
embedded_get_error(mysql);
|
||||
DBUG_PRINT("error",("message: %u (%s)", mysql->net.last_errno,
|
||||
mysql->net.last_error));
|
||||
{
|
||||
|
|
|
@ -318,6 +318,7 @@ while test $# -gt 0; do
|
|||
USE_EMBEDDED_SERVER=1
|
||||
USE_MANAGER=0 NO_SLAVE=1
|
||||
USE_RUNNING_SERVER=0
|
||||
USE_NDBCLUSTER=""
|
||||
TEST_MODE="$TEST_MODE embedded" ;;
|
||||
--purify)
|
||||
USE_PURIFY=1
|
||||
|
|
|
@ -17,7 +17,7 @@ master-bin.000001 # Query 1 # use `test`; insert t1 values (5)
|
|||
master-bin.000001 # Query 1 # use `test`; COMMIT
|
||||
master-bin.000001 # Query 1 # use `test`; BEGIN
|
||||
master-bin.000001 # Query 1 # use `test`; insert t2 values (5)
|
||||
master-bin.000001 # Xid 1 # COMMIT /* xid=11 */
|
||||
master-bin.000001 # Xid 1 # COMMIT /* xid=12 */
|
||||
drop table t1,t2;
|
||||
reset master;
|
||||
create table t1 (n int) engine=innodb;
|
||||
|
@ -128,7 +128,7 @@ master-bin.000001 # Query 1 # use `test`; insert into t1 values(4 + 4)
|
|||
master-bin.000001 # Query 1 # use `test`; insert into t1 values(3 + 4)
|
||||
master-bin.000001 # Query 1 # use `test`; insert into t1 values(2 + 4)
|
||||
master-bin.000001 # Query 1 # use `test`; insert into t1 values(1 + 4)
|
||||
master-bin.000001 # Xid 1 # COMMIT /* xid=18 */
|
||||
master-bin.000001 # Xid 1 # COMMIT /* xid=19 */
|
||||
master-bin.000001 # Rotate 1 # master-bin.000002;pos=4
|
||||
show binlog events in 'master-bin.000002' from 98;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
|
|
|
@ -11315,20 +11315,6 @@ DROP TABLE t1;
|
|||
DROP TABLE t2;
|
||||
DROP TABLE t3;
|
||||
DROP TABLE t4;
|
||||
RESET MASTER;
|
||||
CREATE TABLE t1(f1 blob);
|
||||
PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
|
||||
SET @var1= x'8300';
|
||||
EXECUTE stmt1 USING @var1;
|
||||
SHOW BINLOG EVENTS FROM 98;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 98 Query 1 185 use `test`; CREATE TABLE t1(f1 blob)
|
||||
master-bin.000001 185 User var 1 224 @`var1`=_binary 0x8300 COLLATE binary
|
||||
master-bin.000001 224 Query 1 317 use `test`; INSERT INTO t1 VALUES(@'var1')
|
||||
SELECT HEX(f1) FROM t1;
|
||||
HEX(f1)
|
||||
8300
|
||||
DROP table t1;
|
||||
SET collation_connection='cp932_japanese_ci';
|
||||
create table t1 select repeat('a',4000) a;
|
||||
delete from t1;
|
||||
|
|
17
mysql-test/r/ctype_cp932_notembedded.result
Normal file
17
mysql-test/r/ctype_cp932_notembedded.result
Normal file
|
@ -0,0 +1,17 @@
|
|||
drop table if exists t1;
|
||||
set names cp932;
|
||||
set character_set_database = cp932;
|
||||
RESET MASTER;
|
||||
CREATE TABLE t1(f1 blob);
|
||||
PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
|
||||
SET @var1= x'8300';
|
||||
EXECUTE stmt1 USING @var1;
|
||||
SHOW BINLOG EVENTS FROM 98;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 98 Query 1 185 use `test`; CREATE TABLE t1(f1 blob)
|
||||
master-bin.000001 185 User var 1 224 @`var1`=_binary 0x8300 COLLATE binary
|
||||
master-bin.000001 224 Query 1 317 use `test`; INSERT INTO t1 VALUES(@'var1')
|
||||
SELECT HEX(f1) FROM t1;
|
||||
HEX(f1)
|
||||
8300
|
||||
DROP table t1;
|
|
@ -2673,25 +2673,6 @@ checksum table t1;
|
|||
Table Checksum
|
||||
test.t1 2050879373
|
||||
drop table t1;
|
||||
create table t1 (col1 integer primary key, col2 integer) engine=innodb;
|
||||
insert t1 values (1,100);
|
||||
create function f1 () returns integer begin
|
||||
declare var1 int;
|
||||
select col2 into var1 from t1 where col1=1 for update;
|
||||
return var1;
|
||||
end|
|
||||
start transaction;
|
||||
select f1();
|
||||
f1()
|
||||
100
|
||||
update t1 set col2=0 where col1=1;
|
||||
select * from t1;
|
||||
col1 col2
|
||||
1 100
|
||||
rollback;
|
||||
rollback;
|
||||
drop table t1;
|
||||
drop function f1;
|
||||
create table t1 (
|
||||
a int, b char(10), c char(10), filler char(10), primary key(a, b(2)), unique key (a, c(2))
|
||||
) character set utf8 engine = innodb;
|
||||
|
|
20
mysql-test/r/innodb_notembedded.result
Normal file
20
mysql-test/r/innodb_notembedded.result
Normal file
|
@ -0,0 +1,20 @@
|
|||
drop table if exists t1;
|
||||
create table t1 (col1 integer primary key, col2 integer) engine=innodb;
|
||||
insert t1 values (1,100);
|
||||
create function f1 () returns integer begin
|
||||
declare var1 int;
|
||||
select col2 into var1 from t1 where col1=1 for update;
|
||||
return var1;
|
||||
end|
|
||||
start transaction;
|
||||
select f1();
|
||||
f1()
|
||||
100
|
||||
update t1 set col2=0 where col1=1;
|
||||
select * from t1;
|
||||
col1 col2
|
||||
1 100
|
||||
rollback;
|
||||
rollback;
|
||||
drop table t1;
|
||||
drop function f1;
|
|
@ -1,6 +1,6 @@
|
|||
select -1 as "before_use_test" ;
|
||||
select 0 as "before_use_test" ;
|
||||
before_use_test
|
||||
-1
|
||||
0
|
||||
select otto from (select 1 as otto) as t1;
|
||||
otto
|
||||
1
|
||||
|
|
|
@ -1104,56 +1104,20 @@ call f1();
|
|||
s1
|
||||
s1
|
||||
s1
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 3
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 3
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 0
|
||||
call f1();
|
||||
s1
|
||||
s1
|
||||
s1
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 3
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 3
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 3
|
||||
call f1();
|
||||
s1
|
||||
s1
|
||||
s1
|
||||
select sql_cache * from t1;
|
||||
s1
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 4
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 4
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 6
|
||||
insert into t1 values (1);
|
||||
select sql_cache * from t1;
|
||||
s1
|
||||
1
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 5
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 6
|
||||
call f1();
|
||||
s1
|
||||
1
|
||||
|
@ -1171,15 +1135,6 @@ s1
|
|||
select sql_cache * from t1;
|
||||
s1
|
||||
1
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 4
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 8
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 10
|
||||
flush query cache;
|
||||
reset query cache;
|
||||
flush status;
|
||||
|
|
|
@ -94,4 +94,224 @@ a
|
|||
SELECT * FROM t1;
|
||||
a
|
||||
drop table t1;
|
||||
flush query cache;
|
||||
reset query cache;
|
||||
flush status;
|
||||
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;//
|
||||
call f1();
|
||||
s1
|
||||
s1
|
||||
s1
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 3
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 3
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 0
|
||||
call f1();
|
||||
s1
|
||||
s1
|
||||
s1
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 3
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 3
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 3
|
||||
call f1();
|
||||
s1
|
||||
s1
|
||||
s1
|
||||
select sql_cache * from t1;
|
||||
s1
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 4
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 4
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 6
|
||||
insert into t1 values (1);
|
||||
select sql_cache * from t1;
|
||||
s1
|
||||
1
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 5
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 6
|
||||
call f1();
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
call f1();
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
select sql_cache * from t1;
|
||||
s1
|
||||
1
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 4
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 8
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 10
|
||||
flush query cache;
|
||||
reset query cache;
|
||||
flush status;
|
||||
select sql_cache * from t1;
|
||||
s1
|
||||
1
|
||||
select sql_cache * from t1 where s1=1;
|
||||
s1
|
||||
1
|
||||
call f1();
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
call f2();
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
call f3();
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
call f4();
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
call f4();
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
call f3();
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
call f2();
|
||||
s1
|
||||
1
|
||||
s1
|
||||
1
|
||||
select sql_cache * from t1 where s1=1;
|
||||
s1
|
||||
1
|
||||
insert into t1 values (2);
|
||||
call f1();
|
||||
s1
|
||||
1
|
||||
2
|
||||
s1
|
||||
1
|
||||
2
|
||||
s1
|
||||
1
|
||||
2
|
||||
select sql_cache * from t1 where s1=1;
|
||||
s1
|
||||
1
|
||||
select sql_cache * from t1;
|
||||
s1
|
||||
1
|
||||
2
|
||||
call f1();
|
||||
s1
|
||||
1
|
||||
2
|
||||
s1
|
||||
1
|
||||
2
|
||||
s1
|
||||
1
|
||||
2
|
||||
call f3();
|
||||
s1
|
||||
1
|
||||
2
|
||||
s1
|
||||
1
|
||||
call f3();
|
||||
s1
|
||||
1
|
||||
2
|
||||
s1
|
||||
1
|
||||
call f1();
|
||||
s1
|
||||
1
|
||||
2
|
||||
s1
|
||||
1
|
||||
2
|
||||
s1
|
||||
1
|
||||
2
|
||||
drop procedure f1;
|
||||
drop procedure f2;
|
||||
drop procedure f3;
|
||||
drop procedure f4;
|
||||
drop table t1;
|
||||
set GLOBAL query_cache_size=0;
|
||||
|
|
|
@ -464,19 +464,6 @@ create table t5 (x int)|
|
|||
call bug3294()|
|
||||
ERROR 42S02: Unknown table 't5'
|
||||
drop procedure bug3294|
|
||||
drop procedure if exists bug6807|
|
||||
create procedure bug6807()
|
||||
begin
|
||||
declare id int;
|
||||
set id = connection_id();
|
||||
kill query id;
|
||||
select 'Not reached';
|
||||
end|
|
||||
call bug6807()|
|
||||
ERROR 70100: Query execution was interrupted
|
||||
call bug6807()|
|
||||
ERROR 70100: Query execution was interrupted
|
||||
drop procedure bug6807|
|
||||
drop procedure if exists bug8776_1|
|
||||
drop procedure if exists bug8776_2|
|
||||
drop procedure if exists bug8776_3|
|
||||
|
|
|
@ -2463,7 +2463,6 @@ show create database test;
|
|||
show databases like 'foo';
|
||||
show errors;
|
||||
show columns from t1;
|
||||
show grants for 'root'@'localhost';
|
||||
show keys from t1;
|
||||
show open tables like 'foo';
|
||||
show privileges;
|
||||
|
@ -2490,8 +2489,6 @@ Level Code Message
|
|||
Field Type Null Key Default Extra
|
||||
id char(16) NO
|
||||
data int(11) NO
|
||||
Grants for root@localhost
|
||||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
Database Table In_use Name_locked
|
||||
Privilege Context Comment
|
||||
|
@ -2544,8 +2541,6 @@ Level Code Message
|
|||
Field Type Null Key Default Extra
|
||||
id char(16) NO
|
||||
data int(11) NO
|
||||
Grants for root@localhost
|
||||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
Database Table In_use Name_locked
|
||||
Privilege Context Comment
|
||||
|
@ -2581,18 +2576,6 @@ Tables_in_test (foo)
|
|||
Variable_name Value
|
||||
Level Code Message
|
||||
drop procedure bug4902|
|
||||
drop procedure if exists bug4902_2|
|
||||
create procedure bug4902_2()
|
||||
begin
|
||||
show processlist;
|
||||
end|
|
||||
call bug4902_2()|
|
||||
Id User Host db Command Time State Info
|
||||
# root localhost test Query # NULL show processlist
|
||||
call bug4902_2()|
|
||||
Id User Host db Command Time State Info
|
||||
# root localhost test Query # NULL show processlist
|
||||
drop procedure bug4902_2|
|
||||
drop procedure if exists bug4904|
|
||||
create procedure bug4904()
|
||||
begin
|
||||
|
@ -2735,52 +2718,6 @@ select @x|
|
|||
NULL
|
||||
delete from t1|
|
||||
drop procedure bug4941|
|
||||
drop procedure if exists bug3583|
|
||||
drop procedure if exists bug3583|
|
||||
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'|
|
||||
Variable_name Value
|
||||
Qcache_hits 0
|
||||
call bug3583()|
|
||||
id data
|
||||
x 3
|
||||
y 5
|
||||
c
|
||||
2
|
||||
show status like 'Qcache_hits'|
|
||||
Variable_name Value
|
||||
Qcache_hits 0
|
||||
call bug3583()|
|
||||
id data
|
||||
x 3
|
||||
y 5
|
||||
c
|
||||
2
|
||||
call bug3583()|
|
||||
id data
|
||||
x 3
|
||||
y 5
|
||||
c
|
||||
2
|
||||
show status like 'Qcache_hits'|
|
||||
Variable_name Value
|
||||
Qcache_hits 2
|
||||
set global query_cache_size = @x|
|
||||
flush status|
|
||||
flush query cache|
|
||||
delete from t1|
|
||||
drop procedure bug3583|
|
||||
drop procedure if exists bug4905|
|
||||
create table t3 (s1 int,primary key (s1))|
|
||||
drop procedure if exists bug4905|
|
||||
|
@ -2996,17 +2933,6 @@ select id, bug5240() from t1|
|
|||
id bug5240()
|
||||
answer 42
|
||||
drop function bug5240|
|
||||
drop function if exists bug5278|
|
||||
create function bug5278 () returns char
|
||||
begin
|
||||
SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');
|
||||
return 'okay';
|
||||
end|
|
||||
select bug5278()|
|
||||
ERROR 42000: Can't find any matching row in the user table
|
||||
select bug5278()|
|
||||
ERROR 42000: Can't find any matching row in the user table
|
||||
drop function bug5278|
|
||||
drop procedure if exists p1|
|
||||
create table t3(id int)|
|
||||
insert into t3 values(1)|
|
||||
|
@ -4352,14 +4278,6 @@ select bug10100f(5)|
|
|||
ERROR HY000: Recursive stored functions and triggers are not allowed.
|
||||
call bug10100t(5)|
|
||||
ERROR HY000: Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine bug10100p
|
||||
set @@max_sp_recursion_depth=255|
|
||||
set @var=1|
|
||||
call bug10100p(255, @var)|
|
||||
call bug10100pt(1,255)|
|
||||
call bug10100pv(1,255)|
|
||||
call bug10100pd(1,255)|
|
||||
call bug10100pc(1,255)|
|
||||
set @@max_sp_recursion_depth=0|
|
||||
deallocate prepare stmt2|
|
||||
drop function bug10100f|
|
||||
drop procedure bug10100p|
|
||||
|
|
4853
mysql-test/r/sp.result.orig
Normal file
4853
mysql-test/r/sp.result.orig
Normal file
File diff suppressed because it is too large
Load diff
206
mysql-test/r/sp_notembedded.result
Normal file
206
mysql-test/r/sp_notembedded.result
Normal file
|
@ -0,0 +1,206 @@
|
|||
drop procedure if exists bug4902|
|
||||
create procedure bug4902()
|
||||
begin
|
||||
show grants for 'root'@'localhost';
|
||||
end|
|
||||
call bug4902()|
|
||||
Grants for root@localhost
|
||||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
|
||||
call bug4902()|
|
||||
Grants for root@localhost
|
||||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
|
||||
drop procedure bug4902|
|
||||
drop procedure if exists bug4902_2|
|
||||
create procedure bug4902_2()
|
||||
begin
|
||||
show processlist;
|
||||
end|
|
||||
call bug4902_2()|
|
||||
Id User Host db Command Time State Info
|
||||
# root localhost test Query # NULL show processlist
|
||||
call bug4902_2()|
|
||||
Id User Host db Command Time State Info
|
||||
# root localhost test Query # NULL show processlist
|
||||
drop procedure bug4902_2|
|
||||
drop function if exists bug5278|
|
||||
create function bug5278 () returns char
|
||||
begin
|
||||
SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');
|
||||
return 'okay';
|
||||
end|
|
||||
select bug5278()|
|
||||
ERROR 42000: Can't find any matching row in the user table
|
||||
select bug5278()|
|
||||
ERROR 42000: Can't find any matching row in the user table
|
||||
drop function bug5278|
|
||||
drop table if exists t1|
|
||||
create table t1 (
|
||||
id char(16) not null default '',
|
||||
data int not null
|
||||
)|
|
||||
drop procedure if exists bug3583|
|
||||
drop procedure if exists bug3583|
|
||||
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'|
|
||||
Variable_name Value
|
||||
Qcache_hits 0
|
||||
call bug3583()|
|
||||
id data
|
||||
x 3
|
||||
y 5
|
||||
c
|
||||
2
|
||||
show status like 'Qcache_hits'|
|
||||
Variable_name Value
|
||||
Qcache_hits 0
|
||||
call bug3583()|
|
||||
id data
|
||||
x 3
|
||||
y 5
|
||||
c
|
||||
2
|
||||
call bug3583()|
|
||||
id data
|
||||
x 3
|
||||
y 5
|
||||
c
|
||||
2
|
||||
show status like 'Qcache_hits'|
|
||||
Variable_name Value
|
||||
Qcache_hits 2
|
||||
set global query_cache_size = @x|
|
||||
flush status|
|
||||
flush query cache|
|
||||
delete from t1|
|
||||
drop procedure bug3583|
|
||||
drop table t1;
|
||||
#|
|
||||
drop procedure if exists bug6807|
|
||||
create procedure bug6807()
|
||||
begin
|
||||
declare id int;
|
||||
set id = connection_id();
|
||||
kill query id;
|
||||
select 'Not reached';
|
||||
end|
|
||||
call bug6807()|
|
||||
ERROR 70100: Query execution was interrupted
|
||||
call bug6807()|
|
||||
ERROR 70100: Query execution was interrupted
|
||||
drop procedure bug6807|
|
||||
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|
|
||||
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|
|
||||
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|
|
||||
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|
|
||||
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|
|
||||
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|
|
||||
set @@max_sp_recursion_depth=255|
|
||||
set @var=1|
|
||||
call bug10100p(255, @var)|
|
||||
call bug10100pt(1,255)|
|
||||
call bug10100pv(1,255)|
|
||||
call bug10100pd(1,255)|
|
||||
call bug10100pc(1,255)|
|
||||
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|
|
|
@ -2987,7 +2987,6 @@ select * from (select max(fld) from t1) as foo;
|
|||
max(fld)
|
||||
1
|
||||
drop table t1;
|
||||
purge master logs before (select adddate(current_timestamp(), interval -4 day));
|
||||
CREATE TABLE t1 (a int, b int);
|
||||
CREATE TABLE t2 (c int, d int);
|
||||
CREATE TABLE t3 (e int);
|
||||
|
|
1
mysql-test/r/subselect_notembedded.result
Normal file
1
mysql-test/r/subselect_notembedded.result
Normal file
|
@ -0,0 +1 @@
|
|||
purge master logs before (select adddate(current_timestamp(), interval -4 day));
|
|
@ -2213,15 +2213,6 @@ r_object_id users_names
|
|||
120001a080000542 guser02
|
||||
drop view v1, v2;
|
||||
drop table t1, t2;
|
||||
create definer=some_user@`` sql security invoker view v1 as select 1;
|
||||
ERROR HY000: Definer is not fully qualified
|
||||
create definer=some_user@localhost sql security invoker view v1 as select 1;
|
||||
Warnings:
|
||||
Note 1449 There is no 'some_user'@'localhost' registered
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`some_user`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select 1 AS `1`
|
||||
drop view v1;
|
||||
create table t1 (s1 int);
|
||||
create view abc as select * from t1 as abc;
|
||||
drop table t1;
|
||||
|
|
|
@ -519,3 +519,12 @@ use test;
|
|||
use test;
|
||||
drop user mysqltest_1@localhost;
|
||||
drop database mysqltest;
|
||||
create definer=some_user@`` sql security invoker view v1 as select 1;
|
||||
ERROR HY000: Definer is not fully qualified
|
||||
create definer=some_user@localhost sql security invoker view v1 as select 1;
|
||||
Warnings:
|
||||
Note 1449 There is no 'some_user'@'localhost' registered
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`some_user`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select 1 AS `1`
|
||||
drop view v1;
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# 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
|
||||
# table
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#
|
||||
# misc binlogging tests that do not require a slave running
|
||||
#
|
||||
-- source include/not_embedded.inc
|
||||
-- source include/have_bdb.inc
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
|
@ -18,7 +19,7 @@ begin;
|
|||
insert t2 values (5);
|
||||
commit;
|
||||
# first COMMIT must be Query_log_event, second - Xid_log_event
|
||||
--replace_result "xid=18" "xid=11"
|
||||
--replace_result "xid=19" "xid=12"
|
||||
--replace_column 2 # 5 #
|
||||
show binlog events from 98;
|
||||
drop table t1,t2;
|
||||
|
@ -40,7 +41,7 @@ while ($1)
|
|||
--enable_query_log
|
||||
commit;
|
||||
drop table t1;
|
||||
--replace_result "xid=29" "xid=18"
|
||||
--replace_result "xid=30" "xid=19"
|
||||
--replace_column 2 # 5 #
|
||||
show binlog events in 'master-bin.000001' from 98;
|
||||
--replace_column 2 # 5 #
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# Simple test for blackhole example
|
||||
# Taken from the select test
|
||||
#
|
||||
-- source include/not_embedded.inc
|
||||
-- source include/have_blackhole.inc
|
||||
|
||||
--disable_warnings
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
# Turn on compression between the client and server
|
||||
# and run a number of tests
|
||||
|
||||
# Can't test with embedded server
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
-- source include/have_compress.inc
|
||||
|
||||
connect (comp_con,localhost,root,,,,,COMPRESS);
|
||||
|
|
|
@ -398,28 +398,6 @@ DROP TABLE t2;
|
|||
DROP TABLE t3;
|
||||
DROP TABLE t4;
|
||||
|
||||
# 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
|
||||
|
||||
SET collation_connection='cp932_japanese_ci';
|
||||
-- source include/ctype_filesort.inc
|
||||
SET collation_connection='cp932_bin';
|
||||
|
|
32
mysql-test/t/ctype_cp932_notembedded.test
Normal file
32
mysql-test/t/ctype_cp932_notembedded.test
Normal file
|
@ -0,0 +1,32 @@
|
|||
-- 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 @@
|
|||
# (Can't be tested with purify :( )
|
||||
#
|
||||
|
||||
# This tests not performed with embedded server
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
# test of HANDLER ...
|
||||
#
|
||||
|
||||
# should work in embedded server after mysqltest is fixed
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1,t3,t4,t5;
|
||||
--enable_warnings
|
||||
|
|
|
@ -1619,33 +1619,7 @@ connection a;
|
|||
checksum 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;
|
||||
drop table t1;
|
||||
drop function f1;
|
||||
disconnect a;
|
||||
disconnect b;
|
||||
|
||||
|
@ -1788,6 +1762,7 @@ commit;
|
|||
|
||||
set foreign_key_checks=0;
|
||||
create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb;
|
||||
--replace_result $MYSQLTEST_VARDIR . master-data/ ''
|
||||
-- error 1005
|
||||
create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
|
||||
set foreign_key_checks=1;
|
||||
|
@ -1798,6 +1773,7 @@ drop table t2;
|
|||
|
||||
set foreign_key_checks=0;
|
||||
create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
|
||||
--replace_result $MYSQLTEST_VARDIR . master-data/ ''
|
||||
-- error 1005
|
||||
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8;
|
||||
set foreign_key_checks=1;
|
||||
|
@ -1827,6 +1803,7 @@ drop table t2,t1;
|
|||
set foreign_key_checks=0;
|
||||
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
|
||||
create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
|
||||
--replace_result $MYSQLTEST_VARDIR . master-data/ ''
|
||||
-- error 1025
|
||||
rename table t3 to t1;
|
||||
set foreign_key_checks=1;
|
||||
|
|
40
mysql-test/t/innodb_notembedded.test
Normal file
40
mysql-test/t/innodb_notembedded.test
Normal file
|
@ -0,0 +1,40 @@
|
|||
-- source include/not_embedded.inc
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
|
||||
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;
|
|
@ -1,3 +1,5 @@
|
|||
# This test should work in embedded server after we fix mysqltest
|
||||
-- source include/not_embedded.inc
|
||||
#
|
||||
# Testing the MySQL command line client(mysql)
|
||||
#
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# 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
|
||||
#
|
||||
# If this test fails with "command "$MYSQL_CLIENT_TEST" failed",
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# This test should work in embedded server after mysqltest is fixed
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
# ============================================================================
|
||||
#
|
||||
|
|
|
@ -819,29 +819,14 @@ select sql_cache * from t1 where s1=1;
|
|||
end;//
|
||||
delimiter ;//
|
||||
call f1();
|
||||
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;
|
||||
|
|
|
@ -97,4 +97,88 @@ connection root;
|
|||
SELECT * FROM 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;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
# Test of the READ_ONLY global variable:
|
||||
# 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
|
||||
DROP TABLE IF EXISTS t1,t2,t3;
|
||||
--enable_warnings
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# This tests not performed with embedded server
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1,v1;
|
||||
drop view if exists t1,v1;
|
||||
|
|
|
@ -46,10 +46,13 @@ flush table mysql.proc;
|
|||
|
||||
# Thrashing the .frm file
|
||||
--system echo 'saljdlfa' > $MYSQLTEST_VARDIR/master-data/mysql/proc.frm
|
||||
--replace_result $MYSQLTEST_VARDIR . master-data// ''
|
||||
--error ER_NOT_FORM_FILE
|
||||
call bug14233();
|
||||
--replace_result $MYSQLTEST_VARDIR . master-data// ''
|
||||
--error ER_NOT_FORM_FILE
|
||||
create view v1 as select bug14233_f();
|
||||
--replace_result $MYSQLTEST_VARDIR . master-data// ''
|
||||
--error ER_NOT_FORM_FILE
|
||||
insert into t1 values (0);
|
||||
|
||||
|
|
|
@ -647,28 +647,6 @@ create table t5 (x int)|
|
|||
call 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
|
||||
# a DECLARE ? HANDLER FOR stmt.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# This test should work in embedded server after mysqltest is fixed
|
||||
-- source include/not_embedded.inc
|
||||
#
|
||||
# Testing stored procedures with multiple connections,
|
||||
# except security/privilege tests, they go to sp-security.test
|
||||
|
|
|
@ -699,10 +699,11 @@ drop procedure into_test4|
|
|||
--disable_warnings
|
||||
drop procedure if exists into_outfile|
|
||||
--enable_warnings
|
||||
create procedure into_outfile(x char(16), y int)
|
||||
--replace_result $MYSQLTEST_VARDIR ..
|
||||
eval create procedure into_outfile(x char(16), y int)
|
||||
begin
|
||||
insert into test.t1 values (x, y);
|
||||
select * into outfile "../tmp/spout" from test.t1;
|
||||
select * into outfile "$MYSQLTEST_VARDIR/tmp/spout" from test.t1;
|
||||
insert into test.t1 values (concat(x, "2"), y+2);
|
||||
end|
|
||||
|
||||
|
@ -715,10 +716,11 @@ drop procedure into_outfile|
|
|||
--disable_warnings
|
||||
drop procedure if exists into_dumpfile|
|
||||
--enable_warnings
|
||||
create procedure into_dumpfile(x char(16), y int)
|
||||
--replace_result $MYSQLTEST_VARDIR ..
|
||||
eval create procedure into_dumpfile(x char(16), y int)
|
||||
begin
|
||||
insert into test.t1 values (x, y);
|
||||
select * into dumpfile "../tmp/spdump" from test.t1 limit 1;
|
||||
select * into dumpfile "$MYSQLTEST_VARDIR/tmp/spdump" from test.t1 limit 1;
|
||||
insert into test.t1 values (concat(x, "2"), y+2);
|
||||
end|
|
||||
|
||||
|
@ -1531,7 +1533,7 @@ begin
|
|||
end while;
|
||||
end|
|
||||
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%'|
|
||||
|
||||
# This isn't the fastest way in the world to compute prime numbers, so
|
||||
|
@ -1549,7 +1551,7 @@ select * from t3 where i=45 or i=100 or i=199|
|
|||
drop table t3|
|
||||
drop procedure opp|
|
||||
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%'|
|
||||
|
||||
|
||||
|
@ -1618,13 +1620,13 @@ drop procedure if exists bar|
|
|||
create procedure bar(x char(16), y int)
|
||||
comment "111111111111" sql security invoker
|
||||
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'|
|
||||
alter procedure bar comment "2222222222" sql security definer|
|
||||
alter procedure bar comment "3333333333"|
|
||||
alter 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'|
|
||||
drop procedure bar|
|
||||
|
||||
|
@ -2965,7 +2967,6 @@ begin
|
|||
show databases like 'foo';
|
||||
show errors;
|
||||
show columns from t1;
|
||||
show grants for 'root'@'localhost';
|
||||
show keys from t1;
|
||||
show open tables like 'foo';
|
||||
show privileges;
|
||||
|
@ -2987,20 +2988,6 @@ 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#4904
|
||||
#
|
||||
|
@ -3215,44 +3202,6 @@ select @x|
|
|||
delete from t1|
|
||||
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"
|
||||
#
|
||||
|
@ -3561,24 +3510,6 @@ insert into t1 values ("answer", 42)|
|
|||
select id, bug5240() from t1|
|
||||
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
|
||||
#
|
||||
|
@ -5176,24 +5107,6 @@ select bug10100f(5)|
|
|||
call bug10100t(5)|
|
||||
|
||||
#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|
|
||||
|
|
5716
mysql-test/t/sp.test.orig
Normal file
5716
mysql-test/t/sp.test.orig
Normal file
File diff suppressed because it is too large
Load diff
262
mysql-test/t/sp_notembedded.test
Normal file
262
mysql-test/t/sp_notembedded.test
Normal file
|
@ -0,0 +1,262 @@
|
|||
# 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 ;|
|
|
@ -1962,12 +1962,6 @@ insert into t1 values ('1');
|
|||
select * from (select max(fld) from t1) as foo;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# BUG #10308: purge log with subselect
|
||||
#
|
||||
|
||||
purge master logs before (select adddate(current_timestamp(), interval -4 day));
|
||||
|
||||
#
|
||||
# Test for bug #11762: subquery with an aggregate function in HAVING
|
||||
#
|
||||
|
|
8
mysql-test/t/subselect_notembedded.test
Normal file
8
mysql-test/t/subselect_notembedded.test
Normal file
|
@ -0,0 +1,8 @@
|
|||
-- source include/not_embedded.inc
|
||||
|
||||
#
|
||||
# BUG #10308: purge log with subselect
|
||||
#
|
||||
|
||||
purge master logs before (select adddate(current_timestamp(), interval -4 day));
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
# mysqltest should be fixed
|
||||
-- source include/not_embedded.inc
|
||||
#
|
||||
# Test of temporary tables
|
||||
#
|
||||
|
|
|
@ -2075,16 +2075,6 @@ order by users_names;
|
|||
drop view v1, v2;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# DEFINER information check
|
||||
#
|
||||
-- error ER_MALFORMED_DEFINER
|
||||
create definer=some_user@`` sql security invoker view v1 as select 1;
|
||||
create definer=some_user@localhost sql security invoker view v1 as select 1;
|
||||
show create view v1;
|
||||
drop view v1;
|
||||
|
||||
#
|
||||
# Bug #6808 - Views: CREATE VIEW v ... FROM t AS v fails
|
||||
#
|
||||
|
||||
|
|
|
@ -702,3 +702,14 @@ drop database mysqltest;
|
|||
disconnect user1;
|
||||
disconnect root;
|
||||
connection default;
|
||||
|
||||
#
|
||||
# DEFINER information check
|
||||
#
|
||||
-- error ER_MALFORMED_DEFINER
|
||||
create definer=some_user@`` sql security invoker view v1 as select 1;
|
||||
create definer=some_user@localhost sql security invoker view v1 as select 1;
|
||||
show create view v1;
|
||||
drop view v1;
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# This tests not performed with embedded server
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
#
|
||||
# Bug #8731: wait_timeout does not work on Mac OS X
|
||||
#
|
||||
|
|
|
@ -108,7 +108,7 @@ char *convert_dirname(char *to, const char *from, const char *from_end)
|
|||
|
||||
#if FN_LIBCHAR != '/' || defined(FN_C_BEFORE_DIR_2)
|
||||
{
|
||||
for (; *from && from != from_end; from++)
|
||||
for (; from != from_end && *from ; from++)
|
||||
{
|
||||
if (*from == '/')
|
||||
*to++= FN_LIBCHAR;
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#include <my_bitmap.h>
|
||||
#include <m_string.h>
|
||||
|
||||
static inline void bitmap_lock(MY_BITMAP *map)
|
||||
static inline void bitmap_lock(MY_BITMAP *map __attribute__((unused)))
|
||||
{
|
||||
#ifdef THREAD
|
||||
if (map->mutex)
|
||||
|
@ -48,7 +48,7 @@ static inline void bitmap_lock(MY_BITMAP *map)
|
|||
#endif
|
||||
}
|
||||
|
||||
static inline void bitmap_unlock(MY_BITMAP *map)
|
||||
static inline void bitmap_unlock(MY_BITMAP *map __attribute__((unused)))
|
||||
{
|
||||
#ifdef THREAD
|
||||
if (map->mutex)
|
||||
|
|
|
@ -521,3 +521,9 @@ ALTER TABLE proc MODIFY db
|
|||
char(77) collate utf8_bin DEFAULT '' NOT NULL,
|
||||
MODIFY comment
|
||||
char(64) collate utf8_bin DEFAULT '' NOT NULL;
|
||||
|
||||
# Activate the new, possible modified privilege tables
|
||||
# This should not be needed, but gives us some extra testing that the above
|
||||
# changes was correct
|
||||
|
||||
flush privileges;
|
||||
|
|
|
@ -1563,7 +1563,8 @@ static MYSQL_METHODS client_methods=
|
|||
NULL,
|
||||
cli_read_statistics,
|
||||
cli_read_query_result,
|
||||
cli_read_change_user_result
|
||||
cli_read_change_user_result,
|
||||
cli_read_binary_rows
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -2340,8 +2341,9 @@ static void mysql_close_free(MYSQL *mysql)
|
|||
my_free(mysql->user,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->info_buffer,MYF(MY_ALLOW_ZERO_PTR));
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2477,8 +2479,7 @@ get_info:
|
|||
if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
|
||||
mysql->server_status|= SERVER_STATUS_IN_TRANS;
|
||||
|
||||
if (!(fields=(*mysql->methods->read_rows)(mysql,(MYSQL_FIELD*)0,
|
||||
protocol_41(mysql) ? 7 : 5)))
|
||||
if (!(fields=cli_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,
|
||||
|
|
|
@ -375,9 +375,6 @@ void Item::print_item_w_name(String *str)
|
|||
void Item::cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item::cleanup");
|
||||
DBUG_PRINT("info", ("Item: 0x%lx, Type: %d, name %s, original name %s",
|
||||
this, (int)type(), name ? name : "(null)",
|
||||
orig_name ? orig_name : "null"));
|
||||
fixed=0;
|
||||
marker= 0;
|
||||
if (orig_name)
|
||||
|
|
|
@ -2387,9 +2387,7 @@ static int my_message_sql(uint error, const char *str, myf MyFlags)
|
|||
{
|
||||
NET *net= &thd->net;
|
||||
net->report_error= 1;
|
||||
#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/
|
||||
query_cache_abort(net);
|
||||
#endif
|
||||
if (!net->last_error[0]) // Return only first message
|
||||
{
|
||||
strmake(net->last_error, str, sizeof(net->last_error)-1);
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
|
||||
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
|
||||
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)
|
|||
|
||||
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;
|
||||
bool generate_warning= thd->killed != THD::KILL_CONNECTION;
|
||||
DBUG_ENTER("net_send_error");
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
#ifdef EMBEDDED_LIBRARY
|
||||
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
|
||||
net_send_error_packet(thd, sql_errno, err);
|
||||
|
||||
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->net.report_error= 0;
|
||||
|
||||
|
@ -430,6 +393,47 @@ bool send_old_password_request(THD *thd)
|
|||
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 */
|
||||
|
||||
/*
|
||||
|
|
|
@ -91,6 +91,12 @@ public:
|
|||
virtual bool store_date(TIME *time)=0;
|
||||
virtual bool store_time(TIME *time)=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:
|
|||
virtual bool store(float nr, uint32 decimals, String *buffer);
|
||||
virtual bool store(double from, uint32 decimals, String *buffer);
|
||||
virtual bool store(Field *field);
|
||||
#ifdef EMBEDDED_LIBRARY
|
||||
void remove_last_row();
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -368,6 +368,15 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
|
|||
DESCRIPTION
|
||||
Marks all tables in the list which were used by current substatement
|
||||
(they are marked by its query_id) as free for reuse.
|
||||
|
||||
NOTE
|
||||
The reason we reset query_id is that it's not enough to just test
|
||||
if table->query_id != thd->query_id to know if a table is in use.
|
||||
|
||||
For example
|
||||
SELECT f1_that_uses_t1() FROM t1;
|
||||
In f1_that_uses_t1() we will see one instance of t1 where query_id is
|
||||
set to query_id of original query.
|
||||
*/
|
||||
|
||||
static void mark_used_tables_as_free_for_reuse(THD *thd, TABLE *table)
|
||||
|
|
|
@ -950,6 +950,7 @@ bool select_send::send_data(List<Item> &items)
|
|||
DBUG_RETURN(0);
|
||||
if (!thd->net.report_error)
|
||||
DBUG_RETURN(protocol->write());
|
||||
protocol->remove_last_row();
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
|
@ -1981,10 +1982,8 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
|
|||
cuted_fields= 0;
|
||||
transaction.savepoints= 0;
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
/* Surpress OK packets in case if we will execute statements */
|
||||
net.no_send_ok= TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1102,13 +1102,16 @@ public:
|
|||
|
||||
#ifdef EMBEDDED_LIBRARY
|
||||
struct st_mysql *mysql;
|
||||
struct st_mysql_data *data;
|
||||
unsigned long client_stmt_id;
|
||||
unsigned long client_param_count;
|
||||
struct st_mysql_bind *client_params;
|
||||
char *extra_data;
|
||||
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
|
||||
NET net; // client connection descriptor
|
||||
MEM_ROOT warn_root; // For warnings and errors
|
||||
|
@ -1659,6 +1662,11 @@ public:
|
|||
*/
|
||||
virtual void cleanup();
|
||||
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)
|
|||
THD *thd= table->in_use;
|
||||
|
||||
int res= 0;
|
||||
result->begin_dataset();
|
||||
for (fetch_limit+= num_rows; fetch_count < fetch_limit; fetch_count++)
|
||||
{
|
||||
if ((res= table->file->rnd_next(table->record[0])))
|
||||
|
|
|
@ -1724,13 +1724,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||
net->no_send_error= 0;
|
||||
/*
|
||||
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 ||
|
||||
thd->prelocked_mode)
|
||||
close_thread_tables(thd);
|
||||
#endif
|
||||
ulong length= (ulong)(packet_end-packet);
|
||||
|
||||
log_slow_statement(thd);
|
||||
|
@ -1748,25 +1745,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||
thd->set_time(); /* Reset the query start time. */
|
||||
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
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))
|
||||
|
@ -4273,10 +4252,8 @@ end_with_restore_list:
|
|||
goto error;
|
||||
}
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
my_bool nsok= thd->net.no_send_ok;
|
||||
thd->net.no_send_ok= TRUE;
|
||||
#endif
|
||||
if (sp->m_flags & sp_head::MULTI_RESULTS)
|
||||
{
|
||||
if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS))
|
||||
|
@ -4286,9 +4263,7 @@ end_with_restore_list:
|
|||
back
|
||||
*/
|
||||
my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
thd->net.no_send_ok= nsok;
|
||||
#endif
|
||||
goto error;
|
||||
}
|
||||
/*
|
||||
|
@ -4305,18 +4280,14 @@ end_with_restore_list:
|
|||
sp->m_db.str, sp->m_name.str, TRUE, 0) ||
|
||||
sp_change_security_context(thd, sp, &save_ctx))
|
||||
{
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
thd->net.no_send_ok= nsok;
|
||||
#endif
|
||||
goto error;
|
||||
}
|
||||
if (save_ctx &&
|
||||
check_routine_access(thd, EXECUTE_ACL,
|
||||
sp->m_db.str, sp->m_name.str, TRUE, 0))
|
||||
{
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
thd->net.no_send_ok= nsok;
|
||||
#endif
|
||||
sp_restore_security_context(thd, save_ctx);
|
||||
goto error;
|
||||
}
|
||||
|
@ -4348,9 +4319,7 @@ end_with_restore_list:
|
|||
sp_restore_security_context(thd, save_ctx);
|
||||
#endif
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
thd->net.no_send_ok= nsok;
|
||||
#endif
|
||||
thd->server_status&= ~bits_to_be_cleared;
|
||||
|
||||
if (!res)
|
||||
|
@ -4846,7 +4815,9 @@ end_with_restore_list:
|
|||
res= mysql_xa_recover(thd);
|
||||
break;
|
||||
default:
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
DBUG_ASSERT(0); /* Impossible */
|
||||
#endif
|
||||
send_ok(thd);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -92,6 +92,12 @@ public:
|
|||
virtual bool send_fields(List<Item> &list, uint flags);
|
||||
virtual bool send_data(List<Item> &items);
|
||||
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)
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue