Merge sanja.is.com.ua:/home/bell/mysql/mysql-4.1

into sanja.is.com.ua:/home/bell/mysql/work-select-4.1
This commit is contained in:
bell@sanja.is.com.ua 2003-02-02 17:39:27 +02:00
commit 291f8a225a
42 changed files with 1196 additions and 338 deletions

View File

@ -18,6 +18,7 @@
#undef MYSQL_SERVER
#include "client_priv.h"
#include <time.h>
#include <assert.h>
#include "log_event.h"
#define BIN_LOG_HEADER_SIZE 4

View File

@ -16,6 +16,12 @@
/* Defines for Win32 to make it compatible for MySQL */
#ifdef __WIN2000__
/* We have to do this define before including windows.h to get the AWE API
functions */
#define _WIN32_WINNT 0x0500
#endif
#include <sys/locking.h>
#include <windows.h>
#include <math.h> /* Because of rint() */

View File

@ -92,6 +92,8 @@ typedef struct charset_info_st
uint strxfrm_multiply;
int (*strnncoll)(struct charset_info_st *,
const uchar *, uint, const uchar *, uint);
int (*strnncollsp)(struct charset_info_st *,
const uchar *, uint, const uchar *, uint);
int (*strnxfrm)(struct charset_info_st *,
uchar *, uint, const uchar *, uint);
my_bool (*like_range)(struct charset_info_st *,
@ -110,6 +112,8 @@ typedef struct charset_info_st
int (*ismbchar)(struct charset_info_st *, const char *, const char *);
my_bool (*ismbhead)(struct charset_info_st *, uint);
int (*mbcharlen)(struct charset_info_st *, uint);
uint (*numchars)(struct charset_info_st *, const char *b, const char *e);
uint (*charpos)(struct charset_info_st *, const char *b, const char *e, uint pos);
/* Unicode convertion */
int (*mb_wc)(struct charset_info_st *cs,my_wc_t *wc,
@ -189,6 +193,9 @@ extern int my_strnxfrm_simple(CHARSET_INFO *, uchar *, uint, const uchar *,
extern int my_strnncoll_simple(CHARSET_INFO *, const uchar *, uint,
const uchar *, uint);
extern int my_strnncollsp_simple(CHARSET_INFO *, const uchar *, uint,
const uchar *, uint);
extern uint my_hash_caseup_simple(CHARSET_INFO *cs,
const byte *key, uint len);
@ -247,6 +254,9 @@ int my_wildcmp_8bit(CHARSET_INFO *,
const char *wildstr,const char *wildend,
int escape, int w_one, int w_many);
uint my_numchars_8bit(CHARSET_INFO *, const char *b, const char *e);
uint my_charpos_8bit(CHARSET_INFO *, const char *b, const char *e, uint pos);
#ifdef USE_MB
/* Functions for multibyte charsets */
@ -261,6 +271,9 @@ int my_wildcmp_mb(CHARSET_INFO *,
const char *str,const char *str_end,
const char *wildstr,const char *wildend,
int escape, int w_one, int w_many);
uint my_numchars_mb(CHARSET_INFO *, const char *b, const char *e);
uint my_charpos_mb(CHARSET_INFO *, const char *b, const char *e, uint pos);
#endif
#define _U 01 /* Upper case */

View File

@ -706,6 +706,7 @@ extern void freeze_size(DYNAMIC_ARRAY *array);
#define dynamic_array_ptr(array,array_index) ((array)->buffer+(array_index)*(array)->size_of_element)
#define dynamic_element(array,array_index,type) ((type)((array)->buffer) +(array_index))
#define push_dynamic(A,B) insert_dynamic(A,B)
#define reset_dynamic(array) ((array)->elements= 0)
extern my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,
uint init_alloc,uint alloc_increment);

View File

@ -16,7 +16,7 @@ typedef void* os_process_t;
typedef unsigned long int os_process_id_t;
/* The cell type in os_awe_allocate_mem page info */
#if defined(__NT__) && defined(ULONG_PTR)
#if defined(__WIN2000__) && defined(ULONG_PTR)
typedef ULONG_PTR os_awe_t;
#else
typedef ulint os_awe_t;

View File

@ -20,14 +20,14 @@ Created 9/30/1995 Heikki Tuuri
How to get AWE to compile on Windows?
-------------------------------------
the Visual C++ has to be relatively recent and _WIN32_WINNT has to be
defined to a value >= 0x0500 when windows.h is included. An easy way
to accomplish that is to put
In the project settings of the innobase project the Visual C++ source,
__WIN2000__ has to be defined.
The Visual C++ has to be relatively recent and _WIN32_WINNT has to be
defined to a value >= 0x0500 when windows.h is included.
#define _WIN32_WINNT 0x0500
to the start of file \mysql\include\config-win.h
Where does AWE work?
-------------------
@ -62,7 +62,7 @@ to a mapped 'physical page' for each 4 kB page in the AWE window */
byte** os_awe_simulate_map;
#endif
#ifdef __NT__
#ifdef __WIN2000__
os_awe_t* os_awe_page_info;
ulint os_awe_n_pages;
byte* os_awe_window;
@ -84,7 +84,7 @@ os_awe_enable_lock_pages_in_mem(void)
return(TRUE);
#elif defined(__NT__)
#elif defined(__WIN2000__)
struct {
DWORD Count;
LUID_AND_ATTRIBUTES Privilege[1];
@ -187,7 +187,7 @@ os_awe_allocate_physical_mem(
return(TRUE);
#elif defined(__NT__)
#elif defined(__WIN2000__)
BOOL bResult;
os_awe_t NumberOfPages; /* Question: why does Windows
use the name ULONG_PTR for
@ -318,7 +318,7 @@ os_awe_allocate_virtual_mem_window(
return(os_awe_simulate_window);
#elif defined(__NT__)
#elif defined(__WIN2000__)
byte* ptr;
if (size > 0x7FFFFFFFFF) {
@ -424,7 +424,7 @@ os_awe_map_physical_mem_to_window(
return(TRUE);
#elif defined(__NT__)
#elif defined(__WIN2000__)
BOOL bResult;
os_awe_t n_pages;

View File

@ -1008,7 +1008,7 @@ innobase_start_or_create_for_mysql(void)
srv_startup_is_before_trx_rollback_phase = TRUE;
os_aio_use_native_aio = FALSE;
#if !defined(__NT__) && !defined(UNIV_SIMULATE_AWE)
#if !defined(__WIN2000__) && !defined(UNIV_SIMULATE_AWE)
if (srv_use_awe) {
fprintf(stderr,

View File

@ -59,7 +59,7 @@ const char *client_errors[]=
"No parameters exists in the statement",
"Invalid parameter number",
"Can't send long data for non string or binary data types (parameter: %d)",
"Using un supported buffer type: %d (parameter: %d)",
"Using unsupported buffer type: %d (parameter: %d)",
"Shared memory (%lu)",
"Can't open shared memory. Request event don't create (%lu)",
"Can't open shared memory. Answer event don't create (%lu)",
@ -114,7 +114,7 @@ const char *client_errors[]=
"No parameters exists in the statement",
"Invalid parameter number",
"Can't send long data for non string or binary data types (parameter: %d)",
"Using un supported buffer type: %d (parameter: %d)",
"Using unsupported buffer type: %d (parameter: %d)",
"Shared memory (%lu)",
"Can't open shared memory. Request event don't create (%lu)",
"Can't open shared memory. Answer event don't create (%lu)",
@ -167,7 +167,7 @@ const char *client_errors[]=
"No parameters exists in the statement",
"Invalid parameter number",
"Can't send long data for non string or binary data types (parameter: %d)",
"Using un supported buffer type: %d (parameter: %d)",
"Using unsupported buffer type: %d (parameter: %d)",
"Shared memory (%lu)",
"Can't open shared memory. Request event don't create (%lu)",
"Can't open shared memory. Answer event don't create (%lu)",

View File

@ -3932,19 +3932,40 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length)
unsigned int alloc_stmt_fields(MYSQL_STMT *stmt)
{
MYSQL_FIELD *fields;
MYSQL_FIELD *fields, *field, *end;
MEM_ROOT *alloc= &stmt->mem_root;
if (!stmt->mysql->field_count)
return 0;
stmt->field_count= stmt->mysql->field_count;
fields= stmt->mysql->fields;
if (!(stmt->fields= (MYSQL_FIELD *) alloc_root(&stmt->mem_root,
sizeof(fields))) ||
!(stmt->bind= (MYSQL_BIND *) alloc_root(&stmt->mem_root,
stmt->field_count= stmt->mysql->field_count;
/*
Get the field information for non-select statements
like SHOW and DESCRIBE commands
*/
if (!(stmt->fields= (MYSQL_FIELD *) alloc_root(alloc,
sizeof(MYSQL_FIELD) * stmt->field_count)) ||
!(stmt->bind= (MYSQL_BIND *) alloc_root(alloc,
sizeof(MYSQL_BIND ) * stmt->field_count)))
return 0;
memcpy((char *)stmt->fields, (char *)fields, sizeof(fields));
for (fields= stmt->mysql->fields, end= fields+stmt->field_count,
field= stmt->fields;
field && fields < end; fields++, field++)
{
field->db = strdup_root(alloc,fields->db);
field->table = strdup_root(alloc,fields->table);
field->org_table= strdup_root(alloc,fields->org_table);
field->name = strdup_root(alloc,fields->name);
field->org_name = strdup_root(alloc,fields->org_name);
field->length = fields->length;
field->type = fields->type;
field->flags = fields->flags;
field->decimals = fields->decimals;
field->def = fields->def ? strdup_root(alloc,fields->def): 0;
field->max_length= 0;
}
return stmt->field_count;
}
@ -4356,6 +4377,7 @@ my_ulonglong STDCALL mysql_stmt_affected_rows(MYSQL_STMT *stmt)
static my_bool int_is_null_true= 1; /* Used for MYSQL_TYPE_NULL */
static my_bool int_is_null_false= 0;
static my_bool int_is_null_dummy;
static unsigned long param_length_is_dummy;
/*
Setup the parameter data buffers from application
@ -5041,7 +5063,7 @@ my_bool STDCALL mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
param->is_null= &int_is_null_dummy;
if (!param->length)
param->length= &param->buffer_length;
param->length= &param_length_is_dummy;
param->param_number= param_count++;
/* Setup data copy functions for the different supported types */
@ -5318,22 +5340,42 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
*/
static my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list)
{
MYSQL *mysql;
my_bool error= 0;
DBUG_ENTER("mysql_stmt_close");
DBUG_ASSERT(stmt != 0);
mysql= stmt->mysql;
if (mysql->status != MYSQL_STATUS_READY)
{
/* Clear the current execution status */
DBUG_PRINT("warning",("Not all packets read, clearing them"));
for (;;)
{
ulong pkt_len;
if ((pkt_len= net_safe_read(mysql)) == packet_error)
break;
if (pkt_len <= 8 && mysql->net.read_pos[0] == 254)
break;
}
mysql->status= MYSQL_STATUS_READY;
}
if (stmt->state == MY_ST_PREPARE || stmt->state == MY_ST_EXECUTE)
{
char buff[4];
int4store(buff, stmt->stmt_id);
error= simple_command(stmt->mysql, COM_CLOSE_STMT, buff, 4, 1);
error= simple_command(mysql, COM_CLOSE_STMT, buff, 4, 1);
}
if (!error)
{
mysql_free_result(stmt->result);
free_root(&stmt->mem_root, MYF(0));
if (!skip_list)
mysql->stmts= list_delete(mysql->stmts, &stmt->list);
mysql->status= MYSQL_STATUS_READY;
my_free((gptr) stmt, MYF(MY_WME));
}
mysql_free_result(stmt->result);
free_root(&stmt->mem_root, MYF(0));
if (!skip_list)
stmt->mysql->stmts= list_delete(stmt->mysql->stmts, &stmt->list);
stmt->mysql->status= MYSQL_STATUS_READY;
my_free((gptr) stmt, MYF(MY_WME));
DBUG_RETURN(error);
}

View File

@ -0,0 +1,78 @@
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
stop slave;
reset master;
drop table if exists t1;
create table t1(n char(30));
set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1;
set @s1:='This is a test', @r1:=12.5, @r2:=-12.5;
set @n1:=null;
set @s2:='', @s3:='abc\'def', @s4:= 'abc\\def', @s5:= 'abc''def';
insert into t1 values (@i1), (@i2), (@i3), (@i4);
insert into t1 values (@r1), (@r2);
insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5);
insert into t1 values (@n1);
insert into t1 values (@n2);
insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1);
insert into t1 values (@a+(@b:=@a+1));
set @q:='abc';
insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'));
set @a:=5;
insert into t1 values (@a),(@a);
start slave;
select * from t1;
n
12345678901234
-12345678901234
0
-1
12.5
-12.5
This is a test
abc'def
abc\def
abc'def
NULL
NULL
0
1
2
5
abc
abcn1
abcn1n2
5
5
show binlog events from 141;
Log_name Pos Event_type Server_id Orig_log_pos Info
slave-bin.000001 141 User var 2 141 @i1=12345678901234
slave-bin.000001 184 User var 2 184 @i2=-12345678901234
slave-bin.000001 227 User var 2 227 @i3=0
slave-bin.000001 270 User var 2 270 @i4=-1
slave-bin.000001 313 Query 1 313 use `test`; insert into t1 values (@i1), (@i2), (@i3), (@i4)
slave-bin.000001 396 User var 2 396 @r1=12.5
slave-bin.000001 439 User var 2 439 @r2=-12.5
slave-bin.000001 482 Query 1 482 use `test`; insert into t1 values (@r1), (@r2)
slave-bin.000001 551 User var 2 551 @s1='This is a test'
slave-bin.000001 601 User var 2 601 @s2=''
slave-bin.000001 637 User var 2 637 @s3='abc'def'
slave-bin.000001 680 User var 2 680 @s4='abc\def'
slave-bin.000001 723 User var 2 723 @s5='abc'def'
slave-bin.000001 766 Query 1 766 use `test`; insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5)
slave-bin.000001 856 User var 2 856 @n1=NULL
slave-bin.000001 882 Query 1 882 use `test`; insert into t1 values (@n1)
slave-bin.000001 944 Query 1 944 use `test`; insert into t1 values (@n2)
slave-bin.000001 1006 Query 1 1006 use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1)
slave-bin.000001 1094 User var 2 1094 @a='2'
slave-bin.000001 1130 Query 1 1130 use `test`; insert into t1 values (@a+(@b:=@a+1))
slave-bin.000001 1202 User var 2 1202 @q='abc'
slave-bin.000001 1240 Query 1 1240 use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'))
slave-bin.000001 1344 User var 2 1344 @a=5
slave-bin.000001 1386 Query 1 1386 use `test`; insert into t1 values (@a),(@a)
drop table t1;
stop slave;

View File

@ -0,0 +1,39 @@
source include/master-slave.inc;
connection master;
save_master_pos;
connection slave;
sync_with_master;
stop slave;
reset master;
connection master;
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1(n char(30));
set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1;
set @s1:='This is a test', @r1:=12.5, @r2:=-12.5;
set @n1:=null;
set @s2:='', @s3:='abc\'def', @s4:= 'abc\\def', @s5:= 'abc''def';
insert into t1 values (@i1), (@i2), (@i3), (@i4);
insert into t1 values (@r1), (@r2);
insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5);
insert into t1 values (@n1);
insert into t1 values (@n2);
insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1);
insert into t1 values (@a+(@b:=@a+1));
set @q:='abc';
insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'));
set @a:=5;
insert into t1 values (@a),(@a);
save_master_pos;
connection slave;
start slave;
sync_with_master;
select * from t1;
show binlog events from 141;
connection master;
drop table t1;
save_master_pos;
connection slave;
sync_with_master;
stop slave;

View File

@ -59,6 +59,7 @@ static void simple_cs_init_functions(CHARSET_INFO *cs)
cs->strnxfrm = my_strnxfrm_simple;
cs->strnncoll = my_strnncoll_simple;
cs->strnncollsp = my_strnncollsp_simple;
cs->like_range = my_like_range_simple;
cs->wildcmp = my_wildcmp_8bit;
cs->mb_wc = my_mb_wc_8bit;
@ -83,6 +84,8 @@ static void simple_cs_init_functions(CHARSET_INFO *cs)
cs->strntod = my_strntod_8bit;
cs->scan = my_scan_8bit;
cs->mbmaxlen = 1;
cs->numchars = my_numchars_8bit;
cs->charpos = my_charpos_8bit;
}

View File

@ -1280,11 +1280,11 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func,
}
else
thd=current_thd; // In WHERE / const clause
udf_func *tmp_udf=find_udf(u_d->name,(uint) strlen(u_d->name),1);
udf_func *tmp_udf=find_udf(u_d->name.str,(uint) u_d->name.length,1);
if (!tmp_udf)
{
my_printf_error(ER_CANT_FIND_UDF,ER(ER_CANT_FIND_UDF),MYF(0),u_d->name,
my_printf_error(ER_CANT_FIND_UDF,ER(ER_CANT_FIND_UDF),MYF(0),u_d->name.str,
errno);
DBUG_RETURN(1);
}
@ -1930,6 +1930,7 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
entry->value=0;
entry->length=0;
entry->update_query_id=0;
entry->used_query_id=current_thd->query_id;
entry->type=STRING_RESULT;
memcpy(entry->name.str, name.str, name.length+1);
if (hash_insert(hash,(byte*) entry))
@ -2063,7 +2064,7 @@ Item_func_set_user_var::val_str(String *str)
{
String *res=args[0]->val_str(str);
if (!res) // Null value
update_hash((void*) 0,0,STRING_RESULT, default_charset_info);
update_hash((void*) 0, 0, STRING_RESULT, default_charset_info);
else
update_hash(res->c_ptr(),res->length()+1,STRING_RESULT,res->charset());
return res;
@ -2162,14 +2163,58 @@ longlong Item_func_get_user_var::val_int()
return LL(0); // Impossible
}
/* From sql_parse.cc */
extern bool is_update_query(enum enum_sql_command command);
void Item_func_get_user_var::fix_length_and_dec()
{
BINLOG_USER_VAR_EVENT *user_var_event;
THD *thd=current_thd;
maybe_null=1;
decimals=NOT_FIXED_DEC;
max_length=MAX_BLOB_WIDTH;
var_entry= get_variable(&thd->user_vars, name, 0);
if ((var_entry= get_variable(&thd->user_vars, name, 0)))
{
if (opt_bin_log && is_update_query(thd->lex.sql_command) &&
var_entry->used_query_id != thd->query_id)
{
/*
First we need to store value of var_entry, when the next situation appers:
> set @a:=1;
> insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1);
We have to write to binlog value @a= 1;
*/
uint size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length;
if (!(user_var_event= (BINLOG_USER_VAR_EVENT *) thd->alloc(size)))
goto err;
user_var_event->value= (char*) user_var_event +
ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT));
user_var_event->user_var_event= var_entry;
user_var_event->type= var_entry->type;
user_var_event->charset_number= var_entry->var_charset->number;
if (!var_entry->value)
{
/* NULL value*/
user_var_event->length= 0;
user_var_event->value= 0;
}
else
{
user_var_event->length= var_entry->length;
memcpy(user_var_event->value, var_entry->value,
var_entry->length);
}
var_entry->used_query_id= thd->query_id;
if (insert_dynamic(&thd->user_var_events, (gptr) &user_var_event))
goto err;
}
}
return;
err:
thd->fatal_error= 1;
return;
}

View File

@ -805,13 +805,8 @@ String *Item_func_insert::val_str(String *str)
if (args[0]->null_value || args[1]->null_value || args[2]->null_value ||
args[3]->null_value)
goto null; /* purecov: inspected */
#ifdef USE_MB
if (use_mb(res->charset()) && !args[0]->binary())
{
start=res->charpos(start);
length=res->charpos(length,start);
}
#endif
start=res->charpos(start);
length=res->charpos(length,start);
if (start > res->length()+1)
return res; // Wrong param; skip insert
if (length > res->length()-start)
@ -878,10 +873,7 @@ String *Item_func_left::val_str(String *str)
return 0;
if (length <= 0)
return &empty_string;
#ifdef USE_MB
if (use_mb(res->charset()) && !binary())
length = res->charpos(length);
#endif
length= res->charpos(length);
if (res->length() > (ulong) length)
{ // Safe even if const arg
if (!res->alloced_length())
@ -927,19 +919,11 @@ String *Item_func_right::val_str(String *str)
return &empty_string; /* purecov: inspected */
if (res->length() <= (uint) length)
return res; /* purecov: inspected */
#ifdef USE_MB
if (use_mb(res->charset()) && !binary())
{
uint start=res->numchars()-(uint) length;
if (start<=0) return res;
start=res->charpos(start);
tmp_value.set(*res,start,res->length()-start);
}
else
#endif
{
tmp_value.set(*res,(res->length()- (uint) length),(uint) length);
}
uint start=res->numchars()-(uint) length;
if (start<=0) return res;
start=res->charpos(start);
tmp_value.set(*res,start,res->length()-start);
return &tmp_value;
}
@ -960,13 +944,8 @@ String *Item_func_substr::val_str(String *str)
if ((null_value=(args[0]->null_value || args[1]->null_value ||
(arg_count == 3 && args[2]->null_value))))
return 0; /* purecov: inspected */
#ifdef USE_MB
if (use_mb(res->charset()) && !binary())
{
start=res->charpos(start);
length=res->charpos(length,start);
}
#endif
start=res->charpos(start);
length=res->charpos(length,start);
if (start < 0 || (uint) start+1 > res->length() || length <= 0)
return &empty_string;

View File

@ -1104,6 +1104,23 @@ bool MYSQL_LOG::write(Log_event* event_info)
if (e.write(file))
goto err;
}
if (thd->user_var_events.elements)
{
for (uint i= 0; i < thd->user_var_events.elements; i++)
{
BINLOG_USER_VAR_EVENT *user_var_event;
get_dynamic(&thd->user_var_events,(gptr) &user_var_event, i);
User_var_log_event e(thd, user_var_event->user_var_event->name.str,
user_var_event->user_var_event->name.length,
user_var_event->value,
user_var_event->length,
user_var_event->type,
user_var_event->charset_number);
e.set_log_pos(this);
if (e.write(file))
goto err;
}
}
if (thd->variables.convert_set)
{
char buf[256], *p;

View File

@ -227,6 +227,7 @@ const char* Log_event::get_type_str()
case DELETE_FILE_EVENT: return "Delete_file";
case EXEC_LOAD_EVENT: return "Exec_load";
case RAND_EVENT: return "RAND";
case USER_VAR_EVENT: return "User var";
default: /* impossible */ return "Unknown";
}
}
@ -614,6 +615,9 @@ Log_event* Log_event::read_log_event(const char* buf, int event_len,
case RAND_EVENT:
ev = new Rand_log_event(buf, old_format);
break;
case USER_VAR_EVENT:
ev = new User_var_log_event(buf, old_format);
break;
default:
break;
}
@ -1979,8 +1983,246 @@ int Rand_log_event::exec_event(struct st_relay_log_info* rli)
rli->inc_pending(get_event_len());
return 0;
}
#endif // !MYSQL_CLIENT
/*****************************************************************************
*****************************************************************************
User_var_log_event methods
*****************************************************************************
****************************************************************************/
/*****************************************************************************
User_var_log_event::pack_info()
****************************************************************************/
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
void User_var_log_event::pack_info(Protocol* protocol)
{
char *buf= 0;
uint val_offset= 2 + name_len;
uint event_len= val_offset;
if (is_null)
{
buf= my_malloc(val_offset + 5, MYF(MY_WME));
strmov(buf + val_offset, "NULL");
event_len= val_offset + 4;
}
else
{
switch (type) {
case REAL_RESULT:
double real_val;
float8get(real_val, val);
buf= my_malloc(val_offset + FLOATING_POINT_BUFFER, MYF(MY_WME));
event_len += my_sprintf(buf + val_offset,
(buf + val_offset, "%.14g", real_val));
break;
case INT_RESULT:
buf= my_malloc(val_offset + 22, MYF(MY_WME));
event_len= longlong10_to_str(uint8korr(val), buf + val_offset,-10)-buf;
break;
case STRING_RESULT:
/*
This is correct as pack_info is used for SHOW BINLOG command
only. But be carefull this is may be incorrect in other cases as
string may contain \ and '.
*/
buf= my_malloc(val_offset + 2 + val_len, MYF(MY_WME));
buf[val_offset]= '\'';
memcpy(buf + val_offset + 1, val, val_len);
buf[val_offset + val_len]= '\'';
event_len= val_offset + 1 + val_len;
break;
case ROW_RESULT:
DBUG_ASSERT(1);
return;
}
}
buf[0]= '@';
buf[1+name_len]= '=';
memcpy(buf+1, name, name_len);
protocol->store(buf, event_len);
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
}
#endif // !MYSQL_CLIENT
/*****************************************************************************
User_var_log_event::User_var_log_event()
****************************************************************************/
User_var_log_event::User_var_log_event(const char* buf, bool old_format)
:Log_event(buf, old_format)
{
buf+= (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
name_len= uint4korr(buf);
name= (char *) buf + UV_NAME_LEN_SIZE;
is_null= buf[UV_NAME_LEN_SIZE + name_len];
if (is_null)
{
type= STRING_RESULT;
val_len= 0;
val= 0;
}
else
{
type= (Item_result) buf[UV_VAL_IS_NULL + UV_NAME_LEN_SIZE + name_len];
charset_number= uint4korr(buf + UV_NAME_LEN_SIZE + name_len +
UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE);
val_len= uint4korr(buf + UV_NAME_LEN_SIZE + name_len +
UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
UV_CHARSET_NUMBER_SIZE);
val= (char *) buf + UV_NAME_LEN_SIZE + name_len + UV_VAL_IS_NULL +
UV_VAL_TYPE_SIZE + UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE;
}
}
/*****************************************************************************
User_var_log_event::write_data()
****************************************************************************/
int User_var_log_event::write_data(IO_CACHE* file)
{
char buf[UV_NAME_LEN_SIZE];
char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
char buf2[8];
char *pos= buf2;
int4store(buf, name_len);
buf1[0]= is_null;
if (!is_null)
{
buf1[1]= type;
int4store(buf1 + 2, charset_number);
int4store(buf1 + 2 + UV_CHARSET_NUMBER_SIZE, val_len);
switch (type) {
case REAL_RESULT:
float8store(buf2, *(double*) val);
break;
case INT_RESULT:
int8store(buf2, *(longlong*) val);
break;
case STRING_RESULT:
pos= val;
break;
case ROW_RESULT:
DBUG_ASSERT(1);
return 0;
}
return (my_b_safe_write(file, (byte*) buf, sizeof(buf)) ||
my_b_safe_write(file, (byte*) name, name_len) ||
my_b_safe_write(file, (byte*) buf1, sizeof(buf1)) ||
my_b_safe_write(file, (byte*) pos, val_len));
}
return (my_b_safe_write(file, (byte*) buf, sizeof(buf)) ||
my_b_safe_write(file, (byte*) name, name_len) ||
my_b_safe_write(file, (byte*) buf1, 1));
}
/*****************************************************************************
User_var_log_event::print()
****************************************************************************/
#ifdef MYSQL_CLIENT
void User_var_log_event::print(FILE* file, bool short_form, char* last_db)
{
if (!short_form)
{
print_header(file);
fprintf(file, "\tUser_var\n");
}
fprintf(file, "SET @");
my_fwrite(file, (byte*) name, (uint) (name_len), MYF(MY_NABP | MY_WME));
if (is_null)
{
fprintf(file, ":=NULL;\n");
}
else
{
switch (type) {
case REAL_RESULT:
double real_val;
float8get(real_val, val);
fprintf(file, ":=%.14g;\n", real_val);
break;
case INT_RESULT:
char int_buf[22];
longlong10_to_str(uint8korr(val), int_buf, -10);
fprintf(file, ":=%s;\n", int_buf);
break;
case STRING_RESULT:
fprintf(file, ":='%s';\n", val);
break;
case ROW_RESULT:
DBUG_ASSERT(1);
return;
}
}
fflush(file);
}
#endif
/*****************************************************************************
User_var_log_event::exec_event()
****************************************************************************/
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
int User_var_log_event::exec_event(struct st_relay_log_info* rli)
{
Item *it= 0;
CHARSET_INFO *charset= log_cs;
LEX_STRING user_var_name;
user_var_name.str= name;
user_var_name.length= name_len;
if (type != ROW_RESULT)
init_sql_alloc(&thd->mem_root, 8192,0);
if (is_null)
{
it= new Item_null();
}
else
{
switch (type) {
case REAL_RESULT:
double real_val;
float8get(real_val, val);
it= new Item_real(real_val);
break;
case INT_RESULT:
it= new Item_int((longlong) uint8korr(val));
break;
case STRING_RESULT:
it= new Item_string(val, val_len, charset);
break;
case ROW_RESULT:
DBUG_ASSERT(1);
return 0;
}
charset= get_charset(charset_number, MYF(0));
}
Item_func_set_user_var e(user_var_name, it);
e.fix_fields(thd, 0, 0);
e.update_hash(val, val_len, type, charset);
free_root(&thd->mem_root,0);
rli->inc_pending(get_event_len());
return 0;
}
#endif // !MYSQL_CLIENT
/*****************************************************************************
*****************************************************************************

View File

@ -173,6 +173,14 @@ struct sql_ex_info
#define RAND_SEED1_OFFSET 0
#define RAND_SEED2_OFFSET 8
/* User_var event post-header */
#define UV_VAL_LEN_SIZE 4
#define UV_VAL_IS_NULL 1
#define UV_VAL_TYPE_SIZE 1
#define UV_NAME_LEN_SIZE 4
#define UV_CHARSET_NUMBER_SIZE 4
/* Load event post-header */
#define L_THREAD_ID_OFFSET 0
@ -222,7 +230,7 @@ enum Log_event_type
START_EVENT = 1, QUERY_EVENT =2, STOP_EVENT=3, ROTATE_EVENT = 4,
INTVAR_EVENT=5, LOAD_EVENT=6, SLAVE_EVENT=7, CREATE_FILE_EVENT=8,
APPEND_BLOCK_EVENT=9, EXEC_LOAD_EVENT=10, DELETE_FILE_EVENT=11,
NEW_LOAD_EVENT=12, RAND_EVENT=13
NEW_LOAD_EVENT=12, RAND_EVENT=13, USER_VAR_EVENT=14
};
enum Int_event_type
@ -613,6 +621,46 @@ class Rand_log_event: public Log_event
bool is_valid() { return 1; }
};
/*****************************************************************************
User var Log Event class
****************************************************************************/
class User_var_log_event: public Log_event
{
public:
char *name;
uint name_len;
char *val;
ulong val_len;
Item_result type;
uint charset_number;
byte is_null;
#ifndef MYSQL_CLIENT
User_var_log_event(THD* thd_arg, char *name_arg, uint name_len_arg,
char *val_arg, ulong val_len_arg, Item_result type_arg,
uint charset_number_arg)
:Log_event(), name(name_arg), name_len(name_len_arg), val(val_arg),
val_len(val_len_arg), type(type_arg), charset_number(charset_number_arg)
{ is_null= !val; }
void pack_info(Protocol* protocol);
int exec_event(struct st_relay_log_info* rli);
#else
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
User_var_log_event(const char* buf, bool old_format);
~User_var_log_event() {}
Log_event_type get_type_code() { return USER_VAR_EVENT;}
int get_data_size()
{
return (is_null ? UV_NAME_LEN_SIZE + name_len + UV_VAL_IS_NULL :
UV_NAME_LEN_SIZE + name_len + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE + val_len);
}
int write_data(IO_CACHE* file);
bool is_valid() { return 1; }
};
/*****************************************************************************

View File

@ -146,6 +146,17 @@ THD::THD():user_time(0), is_fatal_error(0),
(hash_get_key) get_var_key,
(hash_free_key) free_user_var,0);
/* For user vars replication*/
if (opt_bin_log)
my_init_dynamic_array(&user_var_events,
sizeof(BINLOG_USER_VAR_EVENT *),
16,
16);
else
bzero((char*) &user_var_events, sizeof(user_var_events));
/* Prepared statements */
last_prepared_stmt= 0;
init_tree(&prepared_statements, 0, 0, sizeof(PREP_STMT),
@ -244,6 +255,7 @@ void THD::cleanup(void)
close_thread_tables(this);
}
close_temporary_tables(this);
delete_dynamic(&user_var_events);
hash_free(&user_vars);
if (global_read_lock)
unlock_global_read_lock(this);

View File

@ -57,6 +57,15 @@ typedef struct st_log_info
~st_log_info() { pthread_mutex_destroy(&lock);}
} LOG_INFO;
typedef struct st_user_var_events
{
user_var_entry *user_var_event;
char *value;
ulong length;
Item_result type;
uint charset_number;
} BINLOG_USER_VAR_EVENT;
class Log_event;
class MYSQL_LOG {
@ -523,6 +532,8 @@ public:
uint select_number; //number of select (used for EXPLAIN)
/* variables.transaction_isolation is reset to this after each commit */
enum_tx_isolation session_tx_isolation;
/* for user variables replication*/
DYNAMIC_ARRAY user_var_events;
// extend scramble to handle new auth
char scramble[SCRAMBLE41_LENGTH+1];
// old scramble is needed to handle old clients
@ -917,7 +928,7 @@ class user_var_entry
public:
LEX_STRING name;
char *value;
ulong length, update_query_id;
ulong length, update_query_id, used_query_id;
Item_result type;
CHARSET_INFO *var_charset;
};

View File

@ -396,6 +396,10 @@ void init_update_queries(void)
uc_update_queries[SQLCOM_UPDATE_MULTI]=1;
}
bool is_update_query(enum enum_sql_command command)
{
return uc_update_queries[command];
}
/*
Check if maximum queries per hour limit has been reached
@ -1225,6 +1229,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
thd->query_length= length;
thd->query= packet;
thd->net.last_error[0]= '\0';
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id= query_id++;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
@ -2709,7 +2714,7 @@ mysql_execute_command(THD *thd)
if (check_access(thd,DELETE_ACL,"mysql",0,1))
break;
#ifdef HAVE_DLOPEN
if (!(res = mysql_drop_function(thd,lex->udf.name)))
if (!(res = mysql_drop_function(thd,&lex->udf.name)))
send_ok(thd);
#else
res= -1;
@ -3157,6 +3162,9 @@ mysql_init_query(THD *thd)
thd->sent_row_count= thd->examined_row_count= 0;
thd->is_fatal_error= thd->rand_used= 0;
thd->server_status &= ~SERVER_MORE_RESULTS_EXISTS;
if (opt_bin_log)
reset_dynamic(&thd->user_var_events);
DBUG_VOID_RETURN;
}

View File

@ -363,46 +363,13 @@ bool String::append(IO_CACHE* file, uint32 arg_length)
uint32 String::numchars()
{
#ifdef USE_MB
register uint32 n=0,mblen;
register const char *mbstr=Ptr;
register const char *end=mbstr+str_length;
if (use_mb(str_charset))
{
while (mbstr < end) {
if ((mblen=my_ismbchar(str_charset, mbstr,end))) mbstr+=mblen;
else ++mbstr;
++n;
}
return n;
}
else
#endif
return str_length;
return str_charset->numchars(str_charset, Ptr, Ptr+str_length);
}
int String::charpos(int i,uint32 offset)
{
#ifdef USE_MB
register uint32 mblen;
register const char *mbstr=Ptr+offset;
register const char *end=Ptr+str_length;
if (use_mb(str_charset))
{
if (i<=0) return i;
while (i && mbstr < end) {
if ((mblen=my_ismbchar(str_charset, mbstr,end))) mbstr+=mblen;
else ++mbstr;
--i;
}
if ( INT_MAX32-i <= (int) (mbstr-Ptr-offset))
return INT_MAX32;
else
return (int) ((mbstr-Ptr-offset)+i);
}
else
#endif
return i;
if (i<0) return i;
return str_charset->charpos(str_charset,Ptr+offset,Ptr+str_length,i);
}
int String::strstr(const String &s,uint32 offset)
@ -573,66 +540,10 @@ void String::qs_append(const char &c)
int sortcmp(const String *x,const String *y)
{
const char *s= x->ptr();
const char *t= y->ptr();
uint32 x_len=x->length(),y_len=y->length(),len=min(x_len,y_len);
if (use_strnxfrm(x->str_charset))
{
#ifndef CMP_ENDSPACE
while (x_len && my_isspace(x->str_charset,s[x_len-1]))
x_len--;
while (y_len && my_isspace(x->str_charset,t[y_len-1]))
y_len--;
#endif
return my_strnncoll(x->str_charset,
(unsigned char *)s,x_len,(unsigned char *)t,y_len);
}
else
{
x_len-=len; // For easy end space test
y_len-=len;
if (x->str_charset->sort_order)
{
while (len--)
{
if (x->str_charset->sort_order[(uchar) *s++] !=
x->str_charset->sort_order[(uchar) *t++])
return ((int) x->str_charset->sort_order[(uchar) s[-1]] -
(int) x->str_charset->sort_order[(uchar) t[-1]]);
}
}
else
{
while (len--)
{
if (*s++ != *t++)
return ((int) s[-1] - (int) t[-1]);
}
}
#ifndef CMP_ENDSPACE
/* Don't compare end space in strings */
{
if (y_len)
{
const char *end=t+y_len;
for (; t != end ; t++)
if (!my_isspace(x->str_charset,*t))
return -1;
}
else
{
const char *end=s+x_len;
for (; s != end ; s++)
if (!my_isspace(x->str_charset,*s))
return 1;
}
return 0;
}
#else
return (int) (x_len-y_len);
#endif /* CMP_ENDSPACE */
}
CHARSET_INFO *cs= x->str_charset;
return cs->strnncollsp(cs,
(unsigned char *) x->ptr(),x->length(),
(unsigned char *) y->ptr(),y->length());
}

View File

@ -74,7 +74,7 @@ static HASH udf_hash;
static rw_lock_t THR_LOCK_udf;
static udf_func *add_udf(char *name, Item_result ret, char *dl,
static udf_func *add_udf(LEX_STRING *name, Item_result ret, char *dl,
Item_udftype typ);
static void del_udf(udf_func *udf);
static void *find_udf_dl(const char *dl);
@ -84,8 +84,8 @@ static void init_syms(udf_func *tmp)
{
char nm[MAX_FIELD_NAME+16],*end;
tmp->func = dlsym(tmp->dlhandle, tmp->name);
end=strmov(nm,tmp->name);
tmp->func = dlsym(tmp->dlhandle, tmp->name.str);
end=strmov(nm,tmp->name.str);
(void) strmov(end,"_init");
tmp->func_init = dlsym(tmp->dlhandle, nm);
(void) strmov(end,"_deinit");
@ -103,8 +103,8 @@ extern "C" byte* get_hash_key(const byte *buff,uint *length,
my_bool not_used __attribute__((unused)))
{
udf_func *udf=(udf_func*) buff;
*length=(uint) udf->name_length;
return (byte*) udf->name;
*length=(uint) udf->name.length;
return (byte*) udf->name.str;
}
/*
@ -161,14 +161,16 @@ void udf_init()
while (!(error = read_record_info.read_record(&read_record_info)))
{
DBUG_PRINT("info",("init udf record"));
char *name=get_field(&mem, table, 0);
LEX_STRING name;
name.str=get_field(&mem, table, 0);
name.length = strlen(name.str);
char *dl_name= get_field(&mem, table, 2);
bool new_dl=0;
Item_udftype udftype=UDFTYPE_FUNCTION;
if (table->fields >= 4) // New func table
udftype=(Item_udftype) table->field[3]->val_int();
if (!(tmp = add_udf(name,(Item_result) table->field[1]->val_int(),
if (!(tmp = add_udf(&name,(Item_result) table->field[1]->val_int(),
dl_name, udftype)))
{
sql_print_error("Can't alloc memory for udf function: name");
@ -250,10 +252,10 @@ static void del_udf(udf_func *udf)
The functions will be automaticly removed when the least threads
doesn't use it anymore
*/
char *name= udf->name;
uint name_length=udf->name_length;
udf->name=(char*) "*";
udf->name_length=1;
char *name= udf->name.str;
uint name_length=udf->name.length;
udf->name.str=(char*) "*";
udf->name.length=1;
hash_update(&udf_hash,(byte*) udf,(byte*) name,name_length);
}
DBUG_VOID_RETURN;
@ -322,7 +324,7 @@ static void *find_udf_dl(const char *dl)
/* Assume that name && dl is already allocated */
static udf_func *add_udf(char *name, Item_result ret, char *dl,
static udf_func *add_udf(LEX_STRING *name, Item_result ret, char *dl,
Item_udftype type)
{
if (!name || !dl || !(uint) type || (uint) type > (uint) UDFTYPE_AGGREGATE)
@ -331,8 +333,7 @@ static udf_func *add_udf(char *name, Item_result ret, char *dl,
if (!tmp)
return 0;
bzero((char*) tmp,sizeof(*tmp));
tmp->name = name;
tmp->name_length=(uint) strlen(tmp->name);
tmp->name = *name; //dup !!
tmp->dl = dl;
tmp->returns = ret;
tmp->type = type;
@ -370,14 +371,14 @@ int mysql_create_function(THD *thd,udf_func *udf)
send_error(thd, ER_UDF_NO_PATHS,ER(ER_UDF_NO_PATHS));
DBUG_RETURN(1);
}
if (udf->name_length > NAME_LEN)
if (udf->name.length > NAME_LEN)
{
net_printf(thd, ER_TOO_LONG_IDENT,udf->name);
DBUG_RETURN(1);
}
rw_wrlock(&THR_LOCK_udf);
if ((hash_search(&udf_hash,(byte*) udf->name, udf->name_length)))
if ((hash_search(&udf_hash,(byte*) udf->name.str, udf->name.length)))
{
net_printf(thd, ER_UDF_EXISTS, udf->name);
goto err;
@ -401,9 +402,9 @@ int mysql_create_function(THD *thd,udf_func *udf)
net_printf(thd, ER_CANT_FIND_DL_ENTRY, udf->name);
goto err;
}
udf->name=strdup_root(&mem,udf->name);
udf->name.str=strdup_root(&mem,udf->name.str);
udf->dl=strdup_root(&mem,udf->dl);
if (!(u_d=add_udf(udf->name,udf->returns,udf->dl,udf->type)))
if (!(u_d=add_udf(&udf->name,udf->returns,udf->dl,udf->type)))
{
send_error(thd,0); // End of memory
goto err;
@ -425,7 +426,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
goto err;
restore_record(table,2); // Get default values for fields
table->field[0]->store(u_d->name, u_d->name_length, default_charset_info);
table->field[0]->store(u_d->name.str, u_d->name.length, default_charset_info);
table->field[1]->store((longlong) u_d->returns);
table->field[2]->store(u_d->dl,(uint) strlen(u_d->dl), default_charset_info);
if (table->fields >= 4) // If not old func format
@ -450,7 +451,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
}
int mysql_drop_function(THD *thd,const char *udf_name)
int mysql_drop_function(THD *thd,const LEX_STRING *udf_name)
{
TABLE *table;
TABLE_LIST tables;
@ -462,8 +463,8 @@ int mysql_drop_function(THD *thd,const char *udf_name)
DBUG_RETURN(1);
}
rw_wrlock(&THR_LOCK_udf);
if (!(udf=(udf_func*) hash_search(&udf_hash,(byte*) udf_name,
(uint) strlen(udf_name))))
if (!(udf=(udf_func*) hash_search(&udf_hash,(byte*) udf_name->str,
(uint) udf_name->length)))
{
net_printf(thd, ER_FUNCTION_NOT_DEFINED, udf_name);
goto err;
@ -481,8 +482,8 @@ int mysql_drop_function(THD *thd,const char *udf_name)
tables.real_name= tables.alias= (char*) "func";
if (!(table = open_ltable(thd,&tables,TL_WRITE)))
goto err;
if (!table->file->index_read_idx(table->record[0],0,(byte*) udf_name,
(uint) strlen(udf_name),
if (!table->file->index_read_idx(table->record[0],0,(byte*) udf_name->str,
(uint) udf_name->length,
HA_READ_KEY_EXACT))
{
int error;

View File

@ -25,8 +25,7 @@ enum Item_udftype {UDFTYPE_FUNCTION=1,UDFTYPE_AGGREGATE};
typedef struct st_udf_func
{
char *name;
int name_length;
LEX_STRING name;
Item_result returns;
Item_udftype type;
char *dl;
@ -61,7 +60,7 @@ class udf_handler :public Sql_alloc
initialized(0)
{}
~udf_handler();
const char *name() const { return u_d ? u_d->name : "?"; }
const char *name() const { return u_d ? u_d->name.str : "?"; }
Item_result result_type () const
{ return u_d ? u_d->returns : STRING_RESULT;}
bool get_arguments();
@ -140,5 +139,5 @@ void udf_init(void),udf_free(void);
udf_func *find_udf(const char *name, uint len=0,bool mark_used=0);
void free_udf(udf_func *udf);
int mysql_create_function(THD *thd,udf_func *udf);
int mysql_drop_function(THD *thd,const char *name);
int mysql_drop_function(THD *thd,const LEX_STRING *name);
#endif

View File

@ -870,12 +870,11 @@ create:
lex->name=$4.str;
lex->create_info.options=$3;
}
| CREATE udf_func_type UDF_SYM ident
| CREATE udf_func_type UDF_SYM IDENT
{
LEX *lex=Lex;
lex->sql_command = SQLCOM_CREATE_FUNCTION;
lex->udf.name=$4.str;
lex->udf.name_length=$4.length;
lex->udf.name = $4;
lex->udf.type= $2;
}
UDF_RETURNS_SYM udf_type UDF_SONAME_SYM TEXT_STRING
@ -3016,11 +3015,11 @@ drop:
lex->drop_if_exists=$3;
lex->name=$4.str;
}
| DROP UDF_SYM ident
| DROP UDF_SYM IDENT
{
LEX *lex=Lex;
lex->sql_command = SQLCOM_DROP_FUNCTION;
lex->udf.name=$3.str;
lex->udf.name = $3;
};

View File

@ -136,6 +136,8 @@ bfill((A)->null_flags,(A)->null_bytes,255);\
#define BIN_LOG_HEADER_SIZE 4
#define FLOATING_POINT_BUFFER 331
/* Include prototypes for unireg */
#include "mysqld_error.h"

View File

@ -242,6 +242,16 @@ static int my_strnncoll_big5(CHARSET_INFO *cs __attribute__((unused)),
return (int) (len1-len2);
}
static
int my_strnncollsp_big5(CHARSET_INFO * cs,
const uchar *s, uint slen,
const uchar *t, uint tlen)
{
for ( ; slen && my_isspace(cs, s[slen-1]) ; slen--);
for ( ; tlen && my_isspace(cs, t[tlen-1]) ; tlen--);
return my_strnncoll_big5(cs,s,slen,t,tlen);
}
static int my_strnxfrm_big5(CHARSET_INFO *cs __attribute__((unused)),
uchar * dest, uint len,
const uchar * src, uint srclen)
@ -6236,6 +6246,7 @@ CHARSET_INFO my_charset_big5 =
NULL, /* tab_from_uni */
1, /* strxfrm_multiply */
my_strnncoll_big5,
my_strnncollsp_big5,
my_strnxfrm_big5,
my_like_range_big5,
my_wildcmp_mb,
@ -6243,6 +6254,8 @@ CHARSET_INFO my_charset_big5 =
ismbchar_big5,
ismbhead_big5,
mbcharlen_big5,
my_numchars_mb,
my_charpos_mb,
my_mb_wc_big5, /* mb_wc */
my_wc_mb_big5, /* wc_mb */
my_caseup_str_mb,

View File

@ -284,6 +284,7 @@ CHARSET_INFO my_charset_bin =
NULL, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_binary, /* strnncoll */
my_strnncoll_binary,
my_strnxfrm_bin, /* strxnfrm */
my_like_range_simple, /* like_range */
my_wildcmp_bin, /* wildcmp */
@ -291,6 +292,8 @@ CHARSET_INFO my_charset_bin =
NULL, /* ismbchar */
NULL, /* ismbhead */
NULL, /* mbcharlen */
my_numchars_8bit,
my_charpos_8bit,
my_mb_wc_bin, /* mb_wc */
my_wc_mb_bin, /* wc_mb */
my_caseup_str_bin, /* caseup_str */

View File

@ -593,6 +593,18 @@ static MY_UNI_IDX idx_uni_8859_2[]={
{0,0,NULL}
};
static
int my_strnncollsp_czech(CHARSET_INFO * cs,
const uchar *s, uint slen,
const uchar *t, uint tlen)
{
for ( ; slen && my_isspace(cs, s[slen-1]) ; slen--);
for ( ; tlen && my_isspace(cs, t[tlen-1]) ; tlen--);
return my_strnncoll_czech(cs,s,slen,t,tlen);
}
CHARSET_INFO my_charset_czech =
{
2, /* number */
@ -608,6 +620,7 @@ CHARSET_INFO my_charset_czech =
idx_uni_8859_2, /* tab_from_uni */
4, /* strxfrm_multiply */
my_strnncoll_czech,
my_strnncollsp_czech,
my_strnxfrm_czech,
my_like_range_czech,
my_wildcmp_8bit,
@ -615,6 +628,8 @@ CHARSET_INFO my_charset_czech =
NULL, /* ismbchar */
NULL, /* ismbhead */
NULL, /* mbcharlen */
my_numchars_8bit,
my_charpos_8bit,
my_mb_wc_8bit, /* mb_wc */
my_wc_mb_8bit, /* wc_mb */
my_caseup_str_8bit,

View File

@ -8654,6 +8654,7 @@ CHARSET_INFO my_charset_euc_kr =
NULL, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_mb, /* wildcmp */
@ -8661,6 +8662,8 @@ CHARSET_INFO my_charset_euc_kr =
ismbchar_euc_kr,
ismbhead_euc_kr,
mbcharlen_euc_kr,
my_numchars_mb,
my_charpos_mb,
my_mb_wc_euc_kr, /* mb_wc */
my_wc_mb_euc_kr, /* wc_mb */
my_caseup_str_mb,

View File

@ -2820,6 +2820,7 @@ CHARSET_INFO compiled_charsets[] = {
idx_uni_8859_1, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -2827,6 +2828,8 @@ CHARSET_INFO compiled_charsets[] = {
NULL, /* ismbchar */
NULL, /* ismbhead */
NULL, /* mbcharlen */
my_numchars_8bit,
my_charpos_8bit,
my_mb_wc_8bit, /* mb_wc */
my_wc_mb_8bit, /* wc_mb */
my_caseup_str_8bit,
@ -2868,6 +2871,7 @@ CHARSET_INFO compiled_charsets[] = {
idx_uni_cp1251, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -2875,6 +2879,8 @@ CHARSET_INFO compiled_charsets[] = {
NULL, /* ismbchar */
NULL, /* ismbhead */
NULL, /* mbcharlen */
my_numchars_8bit,
my_charpos_8bit,
my_mb_wc_8bit, /* mb_wc */
my_wc_mb_8bit, /* wc_mb */
my_caseup_str_8bit,
@ -2915,6 +2921,7 @@ CHARSET_INFO compiled_charsets[] = {
idx_uni_cp1257, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -2922,6 +2929,8 @@ CHARSET_INFO compiled_charsets[] = {
NULL, /* ismbchar */
NULL, /* ismbhead */
NULL, /* mbcharlen */
my_numchars_8bit,
my_charpos_8bit,
my_mb_wc_8bit, /* mb_wc */
my_wc_mb_8bit, /* wc_mb */
my_caseup_str_8bit,
@ -2962,6 +2971,7 @@ CHARSET_INFO compiled_charsets[] = {
idx_uni_8859_2, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3010,6 +3020,7 @@ CHARSET_INFO compiled_charsets[] = {
idx_uni_8859_1, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3057,6 +3068,7 @@ CHARSET_INFO compiled_charsets[] = {
NULL, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3104,6 +3116,7 @@ CHARSET_INFO compiled_charsets[] = {
NULL, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3151,6 +3164,7 @@ CHARSET_INFO compiled_charsets[] = {
NULL, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3199,6 +3213,7 @@ CHARSET_INFO compiled_charsets[] = {
idx_uni_8859_1, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3246,6 +3261,7 @@ CHARSET_INFO compiled_charsets[] = {
NULL, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3293,6 +3309,7 @@ CHARSET_INFO compiled_charsets[] = {
NULL, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3340,6 +3357,7 @@ CHARSET_INFO compiled_charsets[] = {
NULL, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3387,6 +3405,7 @@ CHARSET_INFO compiled_charsets[] = {
idx_uni_8859_2, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3434,6 +3453,7 @@ CHARSET_INFO compiled_charsets[] = {
idx_uni_koi8_r, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3481,6 +3501,7 @@ CHARSET_INFO compiled_charsets[] = {
idx_uni_koi8_u, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3529,6 +3550,7 @@ CHARSET_INFO compiled_charsets[] = {
idx_uni_8859_2, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3576,6 +3598,7 @@ CHARSET_INFO compiled_charsets[] = {
idx_uni_8859_9, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3624,6 +3647,7 @@ CHARSET_INFO compiled_charsets[] = {
NULL, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3672,6 +3696,7 @@ CHARSET_INFO compiled_charsets[] = {
idx_uni_us_ascii, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3719,6 +3744,7 @@ CHARSET_INFO compiled_charsets[] = {
idx_uni_cp1250, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3766,6 +3792,7 @@ CHARSET_INFO compiled_charsets[] = {
idx_uni_cp1251, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3813,6 +3840,7 @@ CHARSET_INFO compiled_charsets[] = {
idx_uni_armscii_8, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3860,6 +3888,7 @@ CHARSET_INFO compiled_charsets[] = {
idx_uni_cp1251, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,/* strnncollsp */
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_8bit, /* wildcmp */
@ -3906,6 +3935,7 @@ CHARSET_INFO compiled_charsets[] = {
NULL, /* tab_from_uni */
0,
NULL, /* strnncoll */
NULL, /* strnncollsp */
NULL, /* strnxfrm */
NULL, /* like_range */
NULL, /* wildcmp */
@ -3913,7 +3943,8 @@ CHARSET_INFO compiled_charsets[] = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL, /* mb_wc */
NULL, /* wc_mb */

View File

@ -5704,6 +5704,7 @@ CHARSET_INFO my_charset_gb2312 =
NULL, /* tab_from_uni */
0, /* strxfrm_multiply */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_mb, /* wildcmp */
@ -5711,6 +5712,8 @@ CHARSET_INFO my_charset_gb2312 =
ismbchar_gb2312,
ismbhead_gb2312,
mbcharlen_gb2312,
my_numchars_mb,
my_charpos_mb,
my_mb_wc_gb2312, /* mb_wc */
my_wc_mb_gb2312, /* wc_mb */
my_caseup_str_mb,

View File

@ -2608,6 +2608,16 @@ int my_strnncoll_gbk(CHARSET_INFO *cs __attribute__((unused)),
return (int) (len1-len2);
}
static
int my_strnncollsp_gbk(CHARSET_INFO * cs,
const uchar *s, uint slen,
const uchar *t, uint tlen)
{
for ( ; slen && my_isspace(cs, s[slen-1]) ; slen--);
for ( ; tlen && my_isspace(cs, t[tlen-1]) ; tlen--);
return my_strnncoll_gbk(cs,s,slen,t,tlen);
}
int my_strnxfrm_gbk(CHARSET_INFO *cs __attribute__((unused)),
uchar * dest, uint len,
@ -9891,6 +9901,7 @@ CHARSET_INFO my_charset_gbk =
NULL, /* tab_from_uni */
1, /* strxfrm_multiply */
my_strnncoll_gbk,
my_strnncollsp_gbk,
my_strnxfrm_gbk,
my_like_range_gbk,
my_wildcmp_mb, /* wildcmp */
@ -9898,6 +9909,8 @@ CHARSET_INFO my_charset_gbk =
ismbchar_gbk,
ismbhead_gbk,
mbcharlen_gbk,
my_numchars_mb,
my_charpos_mb,
my_mb_wc_gbk, /* mb_wc */
my_wc_mb_gbk, /* wc_mb */
my_caseup_str_mb,

View File

@ -190,6 +190,7 @@ CHARSET_INFO my_charset_latin1 =
NULL, /* tab_from_uni */
2, /* strxfrm_multiply */
my_strnncoll_simple,
my_strnncollsp_simple,
my_strnxfrm_simple,
my_like_range_simple,
my_wildcmp_8bit, /* wildcmp */
@ -197,6 +198,8 @@ CHARSET_INFO my_charset_latin1 =
NULL, /* ismbchar */
NULL, /* ismbhead */
NULL, /* mbcharlen */
my_numchars_8bit,
my_charpos_8bit,
my_mb_wc_latin1, /* mb_wc */
my_wc_mb_latin1, /* wc_mb */
my_caseup_str_8bit,

View File

@ -295,6 +295,16 @@ static int my_strnncoll_latin1_de(CHARSET_INFO *cs __attribute__((unused)),
return s1 < e1 ? 1 : s2 < e2 ? -1 : 0;
}
static
int my_strnncollsp_latin1_de(CHARSET_INFO * cs,
const uchar *s, uint slen,
const uchar *t, uint tlen)
{
for ( ; slen && my_isspace(cs, s[slen-1]) ; slen--);
for ( ; tlen && my_isspace(cs, t[tlen-1]) ; tlen--);
return my_strnncoll_latin1_de(cs,s,slen,t,tlen);
}
static int my_strnxfrm_latin1_de(CHARSET_INFO *cs __attribute__((unused)),
uchar * dest, uint len,
@ -336,81 +346,6 @@ static int my_strnxfrm_latin1_de(CHARSET_INFO *cs __attribute__((unused)),
return dest - dest_orig;
}
/*
* Calculate min_str and max_str that ranges a LIKE string.
* Arguments:
* ptr IN: Pointer to LIKE string.
* ptr_length IN: Length of LIKE string.
* escape IN: Escape character in LIKE. (Normally '\').
* No escape characters should appear in min_str or max_str
* res_length IN: Length of min_str and max_str.
* min_str IN/OUT: Smallest case sensitive string that ranges LIKE.
* Should be space padded to res_length.
* max_str IN/OUT: Largest case sensitive string that ranges LIKE.
* Normally padded with the biggest character sort value.
* min_length OUT: Length of min_str without space padding.
* max_length OUT: Length of max_str without space padding.
*
* The function should return 0 if ok and 1 if the LIKE string can't be
* optimized !
*/
#define min_sort_char ((char) 0)
#define max_sort_char ((char) 255)
static my_bool my_like_range_latin1_de(CHARSET_INFO *cs __attribute__((unused)),
const char *ptr, uint ptr_length,
int escape, int w_one, int w_many,
uint res_length,
char *min_str, char *max_str,
uint *min_length, uint *max_length)
{
const char *end = ptr + ptr_length;
char *min_org = min_str;
char *min_end = min_str + res_length;
for (; ptr != end && min_str != min_end; ptr++)
{
if (*ptr == escape && ptr + 1 != end)
{
ptr++; /* Skip escape */
*min_str++ = *max_str++ = *ptr;
continue;
}
if (*ptr == w_one) /* '_' in SQL */
{
*min_str++ = min_sort_char;
*max_str++ = max_sort_char;
continue;
}
if (*ptr == w_many) /* '%' in SQL */
{
*min_length = (uint)(min_str - min_org);
*max_length = res_length;
do {
*min_str++ = ' '; /* Because if key compression */
*max_str++ = max_sort_char;
} while (min_str != min_end);
return 0;
}
*min_str++ = *max_str++ = *ptr;
}
*min_length = *max_length = (uint) (min_str - min_org);
/* Temporary fix for handling w_one at end of string (key compression) */
{
char *tmp;
for (tmp= min_str ; tmp > min_org && tmp[-1] == '\0';)
*--tmp=' ';
}
while (min_str != min_end)
*min_str++ = *max_str++ = ' '; /* Because if key compression */
return 0;
}
CHARSET_INFO my_charset_latin1_de =
{
31, /* number */
@ -426,13 +361,16 @@ CHARSET_INFO my_charset_latin1_de =
idx_uni_8859_1, /* tab_from_uni */
2, /* strxfrm_multiply */
my_strnncoll_latin1_de,
my_strnncollsp_latin1_de,
my_strnxfrm_latin1_de,
my_like_range_latin1_de,
my_like_range_simple,
my_wildcmp_8bit, /* wildcmp */
1, /* mbmaxlen */
NULL, /* ismbchar */
NULL, /* ismbhead */
NULL, /* mbcharlen */
my_numchars_8bit,
my_charpos_8bit,
my_mb_wc_8bit, /* mb_wc */
my_wc_mb_8bit, /* wc_mb */
my_caseup_str_8bit,

View File

@ -276,5 +276,31 @@ int my_wildcmp_mb(CHARSET_INFO *cs,
return (str != str_end ? 1 : 0);
}
uint my_numchars_mb(CHARSET_INFO *cs __attribute__((unused)),
const char *b, const char *e)
{
register uint32 n=0,mblen;
while (b < e)
{
b+= (mblen= my_ismbchar(cs,b,e)) ? mblen : 1;
++n;
}
return n;
}
uint my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)),
const char *b, const char *e, uint pos)
{
uint mblen;
const char *b0=b;
while (pos && b<e)
{
b+= (mblen= my_ismbchar(cs,b,e)) ? mblen : 1;
pos--;
}
return b-b0;
}
#endif

View File

@ -50,6 +50,26 @@ int my_strnncoll_simple(CHARSET_INFO * cs, const uchar *s, uint slen,
return (int) (slen-tlen);
}
int my_strnncollsp_simple(CHARSET_INFO * cs, const uchar *s, uint slen,
const uchar *t, uint tlen)
{
uchar *map= cs->sort_order;
int len;
for ( ; slen && my_isspace(cs, s[slen-1]) ; slen--);
for ( ; tlen && my_isspace(cs, t[tlen-1]) ; tlen--);
len = ( slen > tlen ) ? tlen : slen;
while (len--)
{
if (map[*s++] != map[*t++])
return ((int) map[s[-1]] - (int) map[t[-1]]);
}
return (int) (slen-tlen);
}
void my_caseup_str_8bit(CHARSET_INFO * cs,char *str)
{
register uchar *map=cs->to_upper;
@ -844,7 +864,7 @@ int my_wildcmp_8bit(CHARSET_INFO *cs,
const char *wildstr,const char *wildend,
int escape, int w_one, int w_many)
{
int result= -1; // Not found, using wildcards
int result= -1; /* Not found, using wildcards */
while (wildstr != wildend)
{
@ -854,16 +874,16 @@ int my_wildcmp_8bit(CHARSET_INFO *cs,
wildstr++;
if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++))
return(1); // No match
return(1); /* No match */
if (wildstr == wildend)
return (str != str_end); // Match if both are at end
result=1; // Found an anchor char
return (str != str_end); /* Match if both are at end */
result=1; /* Found an anchor char */
}
if (*wildstr == w_one)
{
do
{
if (str == str_end) // Skip one char if possible
if (str == str_end) /* Skip one char if possible */
return (result);
INC_PTR(cs,str,str_end);
} while (++wildstr < wildend && *wildstr == w_one);
@ -871,7 +891,7 @@ int my_wildcmp_8bit(CHARSET_INFO *cs,
break;
}
if (*wildstr == w_many)
{ // Found w_many
{ /* Found w_many */
uchar cmp;
wildstr++;
@ -887,17 +907,17 @@ int my_wildcmp_8bit(CHARSET_INFO *cs,
INC_PTR(cs,str,str_end);
continue;
}
break; // Not a wild character
break; /* Not a wild character */
}
if (wildstr == wildend)
return(0); // Ok if w_many is last
return(0); /* Ok if w_many is last */
if (str == str_end)
return -1;
if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
cmp= *++wildstr;
INC_PTR(cs,wildstr,wildend); // This is compared trough cmp
INC_PTR(cs,wildstr,wildend); /* This is compared trough cmp */
cmp=likeconv(cs,cmp);
do
{
@ -949,22 +969,22 @@ my_bool my_like_range_simple(CHARSET_INFO *cs,
{
if (*ptr == escape && ptr+1 != end)
{
ptr++; // Skip escape
ptr++; /* Skip escape */
*min_str++= *max_str++ = *ptr;
continue;
}
if (*ptr == w_one) // '_' in SQL
if (*ptr == w_one) /* '_' in SQL */
{
*min_str++='\0'; // This should be min char
*min_str++='\0'; /* This should be min char */
*max_str++=cs->max_sort_char;
continue;
}
if (*ptr == w_many) // '%' in SQL
if (*ptr == w_many) /* '%' in SQL */
{
*min_length= (uint) (min_str - min_org);
*max_length=res_length;
do {
*min_str++ = ' '; // Because if key compression
*min_str++ = ' '; /* Because if key compression */
*max_str++ = cs->max_sort_char;
} while (min_str != min_end);
return 0;
@ -981,7 +1001,7 @@ my_bool my_like_range_simple(CHARSET_INFO *cs,
}
while (min_str != min_end)
*min_str++ = *max_str++ = ' '; // Because if key compression
*min_str++ = *max_str++ = ' '; /* Because if key compression */
return 0;
}
@ -1015,4 +1035,18 @@ void my_fill_8bit(CHARSET_INFO *cs __attribute__((unused)),
char *s, uint l, int fill)
{
bfill(s,l,fill);
}
}
uint my_numchars_8bit(CHARSET_INFO *cs __attribute__((unused)),
const char *b, const char *e)
{
return e-b;
}
uint my_charpos_8bit(CHARSET_INFO *cs __attribute__((unused)),
const char *b __attribute__((unused)),
const char *e __attribute__((unused)),
uint pos)
{
return pos;
}

View File

@ -227,6 +227,16 @@ static int my_strnncoll_sjis(CHARSET_INFO *cs __attribute__((unused)),
return len1 - len2;
}
static
int my_strnncollsp_sjis(CHARSET_INFO * cs,
const uchar *s, uint slen,
const uchar *t, uint tlen)
{
for ( ; slen && my_isspace(cs, s[slen-1]) ; slen--);
for ( ; tlen && my_isspace(cs, t[tlen-1]) ; tlen--);
return my_strnncoll_sjis(cs,s,slen,t,tlen);
}
static int my_strnxfrm_sjis(CHARSET_INFO *cs __attribute__((unused)),
uchar *dest, uint len,
const uchar *src, uint srclen)
@ -4478,6 +4488,7 @@ CHARSET_INFO my_charset_sjis =
NULL, /* tab_from_uni */
1, /* strxfrm_multiply */
my_strnncoll_sjis,
my_strnncollsp_sjis,
my_strnxfrm_sjis,
my_like_range_sjis,
my_wildcmp_mb, /* wildcmp */
@ -4485,6 +4496,8 @@ CHARSET_INFO my_charset_sjis =
ismbchar_sjis,
ismbhead_sjis,
mbcharlen_sjis,
my_numchars_mb,
my_charpos_mb,
my_mb_wc_sjis, /* mb_wc */
my_wc_mb_sjis, /* wc_mb */
my_caseup_str_8bit,

View File

@ -551,6 +551,17 @@ int my_strnncoll_tis620(CHARSET_INFO *cs __attribute__((unused)),
return(i);
}
static
int my_strnncollsp_tis620(CHARSET_INFO * cs,
const uchar *s, uint slen,
const uchar *t, uint tlen)
{
for ( ; slen && my_isspace(cs, s[slen-1]) ; slen--);
for ( ; tlen && my_isspace(cs, t[tlen-1]) ; tlen--);
return my_strnncoll_tis620(cs,s,slen,t,tlen);
}
/* strnxfrm replacment, convert Thai string to sortable string
Arg: Destination buffer, source string, dest length and source length
Ret: Conveted string size
@ -700,6 +711,7 @@ CHARSET_INFO my_charset_tis620 =
NULL, /* tab_from_uni */
4, /* strxfrm_multiply */
my_strnncoll_tis620,
my_strnncollsp_tis620,
my_strnxfrm_tis620,
my_like_range_tis620,
my_wildcmp_8bit, /* wildcmp */
@ -707,6 +719,8 @@ CHARSET_INFO my_charset_tis620 =
NULL, /* ismbchar */
NULL, /* ismbhead */
NULL, /* mbcharlen */
my_numchars_8bit,
my_charpos_8bit,
my_mb_wc_8bit, /* mb_wc */
my_wc_mb_8bit, /* wc_mb */
my_caseup_str_8bit,

View File

@ -8444,7 +8444,8 @@ CHARSET_INFO my_charset_ujis =
NULL, /* tab_to_uni */
NULL, /* tab_from_uni */
0, /* strxfrm_multiply */
NULL, /* strnncoll */
my_strnncoll_simple,/* strnncoll */
my_strnncollsp_simple,
my_strnxfrm_simple, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_mb, /* wildcmp */
@ -8452,6 +8453,8 @@ CHARSET_INFO my_charset_ujis =
ismbchar_ujis,
ismbhead_ujis,
mbcharlen_ujis,
my_numchars_mb,
my_charpos_mb,
my_mb_wc_euc_jp, /* mb_wc */
my_wc_mb_euc_jp, /* wc_mb */
my_caseup_str_mb,

View File

@ -1855,6 +1855,17 @@ static int my_strnncoll_utf8(CHARSET_INFO *cs,
return ( (se-s) - (te-t) );
}
static
int my_strnncollsp_utf8(CHARSET_INFO * cs,
const uchar *s, uint slen,
const uchar *t, uint tlen)
{
for ( ; slen && my_isspace(cs, s[slen-1]) ; slen--);
for ( ; tlen && my_isspace(cs, t[tlen-1]) ; tlen--);
return my_strnncoll_utf8(cs,s,slen,t,tlen);
}
static int my_strncasecmp_utf8(CHARSET_INFO *cs,
const char *s, const char *t, uint len)
{
@ -1979,6 +1990,7 @@ CHARSET_INFO my_charset_utf8 =
NULL, /* tab_from_uni */
1, /* strxfrm_multiply */
my_strnncoll_utf8, /* strnncoll */
my_strnncollsp_utf8,
my_strnxfrm_utf8, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_mb, /* wildcmp */
@ -1986,6 +1998,8 @@ CHARSET_INFO my_charset_utf8 =
my_ismbchar_utf8, /* ismbchar */
my_ismbhead_utf8, /* ismbhead */
my_mbcharlen_utf8, /* mbcharlen */
my_numchars_mb,
my_charpos_mb,
my_utf8_uni, /* mb_wc */
my_uni_utf8, /* wc_mb */
my_caseup_str_utf8,
@ -3052,6 +3066,21 @@ cnv:
return (int) (dst-db);
}
static
uint my_numchars_ucs2(CHARSET_INFO *cs __attribute__((unused)),
const char *b, const char *e)
{
return (e-b)/2;
}
static
uint my_charpos_ucs2(CHARSET_INFO *cs __attribute__((unused)),
const char *b __attribute__((unused)),
const char *e __attribute__((unused)),
uint pos)
{
return pos*2;
}
CHARSET_INFO my_charset_ucs2 =
{
@ -3068,6 +3097,7 @@ CHARSET_INFO my_charset_ucs2 =
NULL, /* tab_from_uni */
1, /* strxfrm_multiply */
my_strnncoll_ucs2, /* strnncoll */
my_strnncoll_ucs2,
my_strnxfrm_ucs2, /* strnxfrm */
my_like_range_simple,/* like_range */
my_wildcmp_mb, /* wildcmp */
@ -3075,6 +3105,8 @@ CHARSET_INFO my_charset_ucs2 =
my_ismbchar_ucs2, /* ismbchar */
my_ismbhead_ucs2, /* ismbhead */
my_mbcharlen_ucs2, /* mbcharlen */
my_numchars_ucs2,
my_charpos_ucs2,
my_ucs2_uni, /* mb_wc */
my_uni_ucs2, /* wc_mb */
my_caseup_str_ucs2,

View File

@ -503,6 +503,17 @@ static int my_strnncoll_win1250ch(CHARSET_INFO *cs __attribute__((unused)),
return 0;
}
static
int my_strnncollsp_win1250ch(CHARSET_INFO * cs,
const uchar *s, uint slen,
const uchar *t, uint tlen)
{
for ( ; slen && my_isspace(cs, s[slen-1]) ; slen--);
for ( ; tlen && my_isspace(cs, t[tlen-1]) ; tlen--);
return my_strnncoll_win1250ch(cs,s,slen,t,tlen);
}
static int my_strnxfrm_win1250ch(CHARSET_INFO * cs __attribute__((unused)),
uchar * dest, uint len,
const uchar * src, uint srclen) {
@ -644,6 +655,7 @@ CHARSET_INFO my_charset_win1250ch =
idx_uni_cp1250, /* tab_from_uni */
2, /* strxfrm_multiply */
my_strnncoll_win1250ch,
my_strnncollsp_win1250ch,
my_strnxfrm_win1250ch,
my_like_range_win1250ch,
my_wildcmp_8bit, /* wildcmp */
@ -651,6 +663,8 @@ CHARSET_INFO my_charset_win1250ch =
NULL, /* ismbchar */
NULL, /* ismbhead */
NULL, /* mbcharlen */
my_numchars_8bit,
my_charpos_8bit,
my_mb_wc_8bit, /* mb_wc */
my_wc_mb_8bit, /* wc_mb */
my_caseup_str_8bit,

View File

@ -50,6 +50,9 @@ static unsigned int test_count= 0;
static unsigned int opt_count= 0;
static unsigned int iter_count= 0;
static time_t start_time, end_time;
static double total_time;
#define myheader(str) \
{ \
fprintf(stdout,"\n\n#####################################\n"); \
@ -77,10 +80,10 @@ static void print_error(const char *msg)
if (mysql)
{
if (mysql->server_version)
fprintf(stderr,"\n [MySQL-%s]",mysql->server_version);
fprintf(stdout,"\n [MySQL-%s]",mysql->server_version);
else
fprintf(stderr,"\n [MySQL]");
fprintf(stderr,"[%d] %s\n",mysql_errno(mysql),mysql_error(mysql));
fprintf(stdout,"\n [MySQL]");
fprintf(stdout,"[%d] %s\n",mysql_errno(mysql),mysql_error(mysql));
}
else if (msg) fprintf(stderr, " [MySQL] %s\n", msg);
}
@ -90,11 +93,11 @@ static void print_st_error(MYSQL_STMT *stmt, const char *msg)
if (stmt)
{
if (stmt->mysql && stmt->mysql->server_version)
fprintf(stderr,"\n [MySQL-%s]",stmt->mysql->server_version);
fprintf(stdout,"\n [MySQL-%s]",stmt->mysql->server_version);
else
fprintf(stderr,"\n [MySQL]");
fprintf(stdout,"\n [MySQL]");
fprintf(stderr,"[%d] %s\n",mysql_stmt_errno(stmt),
fprintf(stdout,"[%d] %s\n",mysql_stmt_errno(stmt),
mysql_stmt_error(stmt));
}
else if (msg) fprintf(stderr, " [MySQL] %s\n", msg);
@ -173,6 +176,7 @@ static void client_connect()
{
myerror("connection failed");
mysql_close(mysql);
fprintf(stdout,"\n Check the connection options using --help or -?\n");
exit(0);
}
fprintf(stdout," OK");
@ -438,7 +442,7 @@ uint my_stmt_result(const char *query, unsigned long length)
uint row_count;
int rc;
fprintf(stdout,"\n\n %s \n", query);
fprintf(stdout,"\n\n %s", query);
stmt= mysql_prepare(mysql,query,length);
mystmt_init(stmt);
@ -1072,7 +1076,7 @@ static void test_prepare()
myquery(rc);
/* test the results now, only one row should exists */
myassert(tiny_data == (int) my_stmt_result("SELECT * FROM my_prepare",50));
myassert(tiny_data == (char) my_stmt_result("SELECT * FROM my_prepare",50));
stmt = mysql_prepare(mysql,"SELECT * FROM my_prepare",50);
mystmt_init(stmt);
@ -1238,8 +1242,7 @@ static void test_null()
{
MYSQL_STMT *stmt;
int rc;
int nData=1;
MYSQL_RES *result;
uint nData;
MYSQL_BIND bind[2];
my_bool is_null[2];
@ -1268,33 +1271,69 @@ static void test_null()
bind[0].buffer_type=MYSQL_TYPE_LONG;
bind[0].is_null= &is_null[0];
is_null[0]= 1;
bind[1]=bind[0]; /* string data */
bind[1]=bind[0];
rc = mysql_bind_param(stmt,bind);
mystmt(stmt, rc);
/* now, execute the prepared statement to insert 10 records.. */
for (nData=0; nData<9; nData++)
for (nData=0; nData<10; nData++)
{
rc = mysql_execute(stmt);
mystmt(stmt, rc);
}
/* Re-bind with MYSQL_TYPE_NULL */
bind[0].buffer_type= MYSQL_TYPE_NULL;
is_null[0]= 0; /* reset */
bind[1]= bind[0];
rc = mysql_bind_param(stmt,bind);
mystmt(stmt,rc);
for (nData=0; nData<10; nData++)
{
rc = mysql_execute(stmt);
mystmt(stmt, rc);
}
mysql_stmt_close(stmt);
/* now fetch the results ..*/
rc = mysql_commit(mysql);
myquery(rc);
/* test the results now, only one row should exists */
rc = mysql_query(mysql,"SELECT * FROM test_null");
myquery(rc);
nData*= 2;
myassert(nData == my_stmt_result("SELECT * FROM test_null", 30));
/* get the result */
result = mysql_store_result(mysql);
mytest(result);
/* Fetch results */
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= (char *)&nData; /* this buffer won't be altered */
bind[0].length= 0;
bind[1]= bind[0];
bind[0].is_null= &is_null[0];
bind[1].is_null= &is_null[1];
myassert(nData == my_process_result_set(result));
mysql_free_result(result);
stmt = mysql_prepare(mysql,"SELECT * FROM test_null",30);
mystmt_init(stmt);
rc = mysql_execute(stmt);
mystmt(stmt,rc);
rc = mysql_bind_result(stmt,bind);
mystmt(stmt,rc);
rc= 0;
is_null[0]= is_null[1]= 0;
while (mysql_fetch(stmt) != MYSQL_NO_DATA)
{
myassert(is_null[0]);
myassert(is_null[1]);
rc++;
is_null[0]= is_null[1]= 0;
}
myassert(rc == (int)nData);
mysql_stmt_close(stmt);
}
@ -1636,8 +1675,13 @@ static void test_select_show()
mysql_autocommit(mysql,TRUE);
strmov(query,"SELECT * FROM mysql.host");
stmt = mysql_prepare(mysql, query, strlen(query));
rc = mysql_query(mysql, "DROP TABLE IF EXISTS test_show");
myquery(rc);
rc = mysql_query(mysql, "CREATE TABLE test_show(id int(4) NOT NULL, name char(2))");
myquery(rc);
stmt = mysql_prepare(mysql, "show columns from test_show", 30);
mystmt_init(stmt);
verify_param_count(stmt,0);
@ -1646,7 +1690,28 @@ static void test_select_show()
mystmt(stmt, rc);
my_process_stmt_result(stmt);
mysql_stmt_close(stmt);
stmt = mysql_prepare(mysql, "show tables from mysql like ?", 50);
mystmt_init_r(stmt);
strxmov(query,"show tables from ", current_db, " like \'test_show\'", NullS);
stmt = mysql_prepare(mysql, query, strlen(query));
mystmt_init(stmt);
rc = mysql_execute(stmt);
mystmt(stmt, rc);
my_process_stmt_result(stmt);
mysql_stmt_close(stmt);
stmt = mysql_prepare(mysql, "describe test_show", 30);
mystmt_init(stmt);
rc = mysql_execute(stmt);
mystmt(stmt, rc);
my_process_stmt_result(stmt);
mysql_stmt_close(stmt);
}
@ -4361,6 +4426,9 @@ static void test_multi_query()
int rc;
const char *query= "DROP TABLE IF EXISTS test_multi_tab;\
CREATE TABLE test_multi_tab(id int,name char(20));\
INSERT INTO test_multi_tab(xxxx) VALUES(10);\
UPDATE test_multi_tab SET id=10 WHERE unkown_col=10;\
CREATE TABLE test_multi_tab(id int,name char(20));\
INSERT INTO test_multi_tab(id) VALUES(10),(20);\
INSERT INTO test_multi_tab VALUES(20,'insert;comma');\
@ -4370,14 +4438,20 @@ static void test_multi_query()
DELETE FROM test_multi_tab WHERE name='new;name';\
SELECT * FROM test_multi_tab;\
DELETE FROM test_multi_tab WHERE id=10;\
SELECT * FROM test_multi_tab";
uint count, rows[10]={0,2,1,3,0,2,2,1,1,0};
SELECT * FROM test_multi_tab;\
DROP TABLE test_multi_tab;\
DROP TABLE test_multi_tab;\
DROP TABLE IF EXISTS test_multi_tab";
uint count, rows[16]={0,1054,1054,1050,2,1,3,1054,2,2,1,1,0,0,1051,0}, exp_value;
myheader("test_multi_query");
rc = mysql_query(mysql, query); /* syntax error */
myquery_r(rc);
myassert(0 == mysql_next_result(mysql));
myassert(0 == mysql_more_results(mysql));
if (!(l_mysql = mysql_init(NULL)))
{
fprintf(stdout,"\n mysql_init() failed");
@ -4396,19 +4470,25 @@ static void test_multi_query()
rc = mysql_query(mysql, query);
myquery(rc);
count= 0;
while (mysql_more_results(mysql) && count < sizeof(rows)/sizeof(uint))
count= exp_value= 0;
while (mysql_more_results(mysql) && count < array_elements(rows))
{
fprintf(stdout,"\n query %d", count);
fprintf(stdout,"\n Query %d: ", count);
if ((rc= mysql_next_result(mysql)))
fprintf(stdout, "\n\t failed(%s)", mysql_error(mysql));
{
exp_value= mysql_errno(mysql);
fprintf(stdout, "ERROR %d: %s", exp_value, mysql_error(mysql));
}
else
fprintf(stdout,"\n\t affected rows: %lld", mysql_affected_rows(mysql));
if ((result= mysql_store_result(mysql)))
my_process_result_set(result);
if (!rc)
myassert(rows[count] == (uint)mysql_affected_rows(mysql));
count++;
{
if ((result= mysql_store_result(mysql)))
my_process_result_set(result);
else
fprintf(stdout,"OK, %d row(s) affected, %d warning(s)", exp_value,
mysql_warning_count(mysql));
exp_value= (uint) mysql_affected_rows(mysql);
}
myassert(rows[count++] == exp_value);
}
mysql= org_mysql;
}
@ -4865,7 +4945,7 @@ static void test_bind_date_conv(uint row_count)
for (i= 0; i < array_elements(bind); i++)
{
fprintf(stdout, "\n");
fprintf(stdout,"time[%d]: %02d-%02d-%02d %02d:%02d:%02d.%02lu",
fprintf(stdout," time[%d]: %02d-%02d-%02d %02d:%02d:%02d.%02lu",
i, tm[i].year, tm[i].month, tm[i].day,
tm[i].hour, tm[i].minute, tm[i].second,
tm[i].second_part);
@ -5196,6 +5276,157 @@ static void test_buffers()
mysql_stmt_close(stmt);
}
/*
Test the direct query execution in the middle of open stmts
*/
static void test_open_direct()
{
MYSQL_STMT *stmt;
MYSQL_RES *result;
int rc;
myheader("test_open_direct");
rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_open_direct");
myquery(rc);
rc = mysql_query(mysql,"CREATE TABLE test_open_direct(id int, name char(6))");
myquery(rc);
stmt = mysql_prepare(mysql,"INSERT INTO test_open_direct values(10,'mysql')", 100);
mystmt_init(stmt);
rc = mysql_query(mysql, "SELECT * FROM test_open_direct");
myquery(rc);
result = mysql_store_result(mysql);
mytest(result);
myassert(0 == my_process_result_set(result));
rc = mysql_execute(stmt);
mystmt(stmt, rc);
fprintf(stdout, "\n total affected rows: %lld", mysql_stmt_affected_rows(stmt));
myassert(1 == mysql_stmt_affected_rows(stmt));
rc = mysql_query(mysql, "SELECT * FROM test_open_direct");
myquery(rc);
result = mysql_store_result(mysql);
mytest(result);
myassert(1 == my_process_result_set(result));
rc = mysql_execute(stmt);
mystmt(stmt, rc);
fprintf(stdout, "\n total affected rows: %lld", mysql_stmt_affected_rows(stmt));
myassert(1 == mysql_stmt_affected_rows(stmt));
rc = mysql_query(mysql, "SELECT * FROM test_open_direct");
myquery(rc);
result = mysql_store_result(mysql);
mytest(result);
myassert(2 == my_process_result_set(result));
mysql_stmt_close(stmt);
/* run a direct query in the middle of a fetch */
stmt= mysql_prepare(mysql,"SELECT * FROM test_open_direct",100);
mystmt_init(stmt);
rc = mysql_execute(stmt);
mystmt(stmt, rc);
rc = mysql_fetch(stmt);
mystmt(stmt, rc);
rc = mysql_query(mysql,"INSERT INTO test_open_direct(id) VALUES(20)");
myquery_r(rc);
rc = mysql_stmt_close(stmt);
mystmt(stmt, rc);
rc = mysql_query(mysql,"INSERT INTO test_open_direct(id) VALUES(20)");
myquery(rc);
/* run a direct query with store result */
stmt= mysql_prepare(mysql,"SELECT * FROM test_open_direct",100);
mystmt_init(stmt);
rc = mysql_execute(stmt);
mystmt(stmt, rc);
rc = mysql_stmt_store_result(stmt);
mystmt(stmt, rc);
rc = mysql_fetch(stmt);
mystmt(stmt, rc);
rc = mysql_query(mysql,"drop table test_open_direct");
myquery(rc);
rc = mysql_stmt_close(stmt);
mystmt(stmt, rc);
}
/*
To test fetch without prior bound buffers
*/
static void test_fetch_nobuffs()
{
MYSQL_STMT *stmt;
MYSQL_BIND bind[4];
char str[4][50];
int rc;
myheader("test_fetch_nobuffs");
stmt = mysql_prepare(mysql,"SELECT DATABASE(), CURRENT_USER(), CURRENT_DATE(), CURRENT_TIME()",100);
mystmt_init(stmt);
rc = mysql_execute(stmt);
mystmt(stmt, rc);
rc = 0;
while (mysql_fetch(stmt) != MYSQL_NO_DATA)
rc++;
fprintf(stdout, "\n total rows: %d", rc);
myassert(rc == 1);
bind[0].buffer_type= MYSQL_TYPE_STRING;
bind[0].buffer= (char *)str[0];
bind[0].is_null= 0;
bind[0].length= 0;
bind[0].buffer_length= sizeof(str[0]);
bind[1]= bind[2]= bind[3]= bind[0];
bind[1].buffer= (char *)str[1];
bind[2].buffer= (char *)str[2];
bind[3].buffer= (char *)str[3];
rc = mysql_bind_result(stmt, bind);
mystmt(stmt, rc);
rc = mysql_execute(stmt);
mystmt(stmt, rc);
rc = 0;
while (mysql_fetch(stmt) != MYSQL_NO_DATA)
{
rc++;
fprintf(stdout, "\n CURRENT_DATABASE(): %s", str[0]);
fprintf(stdout, "\n CURRENT_USER() : %s", str[1]);
fprintf(stdout, "\n CURRENT_DATE() : %s", str[2]);
fprintf(stdout, "\n CURRENT_TIME() : %s", str[3]);
}
fprintf(stdout, "\n total rows: %d", rc);
myassert(rc == 1);
mysql_stmt_close(stmt);
}
static struct my_option myctest_long_options[] =
{
{"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
@ -5225,6 +5456,7 @@ static void usage(void)
/*
* show the usage string when the user asks for this
*/
putc('\n',stdout);
puts("***********************************************************************\n");
puts(" Test for client-server protocol 4.1");
puts(" By Monty & Venu \n");
@ -5251,7 +5483,7 @@ static void usage(void)
#endif
fprintf(stdout,"\
-t, --count=... Execute the test count times.\n");
fprintf(stdout,"*********************************************************************\n");
puts("***********************************************************************\n");
}
static my_bool
@ -5300,26 +5532,42 @@ static void get_options(int argc, char **argv)
return;
}
/*
Print the test output on successful execution before exiting
*/
static void print_test_output()
{
fprintf(stdout,"\n\n");
fprintf(stdout,"All '%d' tests were successful (in '%d' iterations)",
test_count-1, opt_count);
fprintf(stdout,"\n Total execution time: %g SECS", total_time);
if (opt_count > 1)
fprintf(stdout," (Avg: %g SECS)", total_time/opt_count);
fprintf(stdout,"\n\n!!! SUCCESS !!!\n");
}
/********************************************************
* main routine *
*********************************************************/
int main(int argc, char **argv)
{
time_t start_time, end_time;
double total_time= 0;
MY_INIT(argv[0]);
get_options(argc,argv);
client_connect(); /* connect to server */
total_time= 0;
for (iter_count=1; iter_count <= opt_count; iter_count++)
{
/* Start of tests */
test_count= 1;
start_time= time((time_t *)0);
test_fetch_nobuffs(); /* to fecth without prior bound buffers */
test_open_direct(); /* direct execution in the middle of open stmts */
test_fetch_null(); /* to fetch null data */
test_fetch_date(); /* to fetch date,time and timestamp */
test_fetch_str(); /* to fetch string to all types */
@ -5399,13 +5647,8 @@ int main(int argc, char **argv)
}
client_disconnect(); /* disconnect from server */
fprintf(stdout,"\n\nAll '%d' tests were successful (in '%d' iterations)",
test_count-1, opt_count);
fprintf(stdout,"\n Total execution time: %g SECS", total_time);
if (opt_count > 1)
fprintf(stdout," (Avg: %g SECS)", total_time/opt_count);
print_test_output();
fprintf(stdout,"\n\nSUCCESS !!!\n");
return(0);
}