Commit d4abbb0d authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

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

into sanja.is.com.ua:/home/bell/mysql/work-ctype-4.1
parents 73193488 23ed6656
...@@ -56,6 +56,9 @@ static short binlog_flags = 0; ...@@ -56,6 +56,9 @@ static short binlog_flags = 0;
static MYSQL* mysql = NULL; static MYSQL* mysql = NULL;
static const char* table = 0; static const char* table = 0;
static bool use_local_load= 0;
static const char* dirname_for_local_load= 0;
static void dump_local_log_entries(const char* logname); static void dump_local_log_entries(const char* logname);
static void dump_remote_log_entries(const char* logname); static void dump_remote_log_entries(const char* logname);
static void dump_log_entries(const char* logname); static void dump_log_entries(const char* logname);
...@@ -64,6 +67,129 @@ static void dump_remote_table(NET* net, const char* db, const char* table); ...@@ -64,6 +67,129 @@ static void dump_remote_table(NET* net, const char* db, const char* table);
static void die(const char* fmt, ...); static void die(const char* fmt, ...);
static MYSQL* safe_connect(); static MYSQL* safe_connect();
class Load_log_processor {
char target_dir_name[MY_NFILE];
int target_dir_name_len;
DYNAMIC_ARRAY file_names;
const char* create_file(Create_file_log_event *ce)
{
const char *bname= ce->fname + ce->fname_len -1;
while (bname>ce->fname && bname[-1]!=FN_LIBCHAR)
bname--;
uint blen= ce->fname_len - (bname-ce->fname);
uint full_len= target_dir_name_len + blen;
char *tmp;
if (!(tmp= my_malloc(full_len + 9 + 1,MYF(MY_WME))) ||
set_dynamic(&file_names,(gptr)&ce,ce->file_id))
{
die("Could not construct local filename %s%s",target_dir_name,bname);
return 0;
}
char *ptr= tmp;
memcpy(ptr,target_dir_name,target_dir_name_len);
ptr+= target_dir_name_len;
memcpy(ptr,bname,blen);
ptr+= blen;
sprintf(ptr,"-%08x",ce->file_id);
ce->set_fname_outside_temp_buf(tmp,full_len);
return tmp;
}
void append_to_file(const char* fname, int flags,
gptr data, uint size)
{
FILE *file;
if(!(file= my_fopen(fname,flags,MYF(MY_WME))))
exit(1);
if (my_fwrite(file,data,size,MYF(MY_WME|MY_NABP)))
exit(1);
if (my_fclose(file,MYF(MY_WME)))
exit(1);
}
public:
Load_log_processor()
{
init_dynamic_array(&file_names,sizeof(Create_file_log_event*),
100,100 CALLER_INFO);
}
~Load_log_processor()
{
destroy();
delete_dynamic(&file_names);
}
void init_by_dir_name(const char *atarget_dir_name)
{
char *end= strmov(target_dir_name,atarget_dir_name);
if (end[-1]!=FN_LIBCHAR)
*end++= FN_LIBCHAR;
target_dir_name_len= end-target_dir_name;
}
void init_by_file_name(const char *file_name)
{
int len= strlen(file_name);
const char *end= file_name + len - 1;
while (end>file_name && *end!=FN_LIBCHAR)
end--;
if (*end!=FN_LIBCHAR)
target_dir_name_len= 0;
else
{
target_dir_name_len= end - file_name + 1;
memmove(target_dir_name,file_name,target_dir_name_len);
}
}
void init_by_cur_dir()
{
target_dir_name_len= 0;
}
void destroy()
{
Create_file_log_event **ptr= (Create_file_log_event**)file_names.buffer;
Create_file_log_event **end= ptr + file_names.elements;
for (; ptr<end; ptr++)
{
if (*ptr)
{
my_free((char*)(*ptr)->fname,MYF(MY_WME));
delete *ptr;
*ptr= 0;
}
}
}
Create_file_log_event *grab_event(uint file_id)
{
Create_file_log_event **ptr=
(Create_file_log_event**)file_names.buffer + file_id;
Create_file_log_event *res= *ptr;
*ptr= 0;
return res;
}
void process(Create_file_log_event *ce)
{
const char *fname= create_file(ce);
append_to_file (fname,O_CREAT|O_BINARY,ce->block,ce->block_len);
}
void process(Append_block_log_event *ae)
{
if (ae->file_id >= file_names.elements)
die("Skiped CreateFile event for file_id: %u",ae->file_id);
Create_file_log_event* ce=
*((Create_file_log_event**)file_names.buffer + ae->file_id);
append_to_file(ce->fname,O_APPEND|O_BINARY,ae->block,ae->block_len);
}
};
Load_log_processor load_processor;
static struct my_option my_long_options[] = static struct my_option my_long_options[] =
{ {
#ifndef DBUG_OFF #ifndef DBUG_OFF
...@@ -97,6 +223,9 @@ static struct my_option my_long_options[] = ...@@ -97,6 +223,9 @@ static struct my_option my_long_options[] =
{"user", 'u', "Connect to the remote server as username", {"user", 'u', "Connect to the remote server as username",
(gptr*) &user, (gptr*) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, (gptr*) &user, (gptr*) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0,
0, 0}, 0, 0},
{"local-load", 'l', "Prepare files for local load in directory",
(gptr*) &dirname_for_local_load, (gptr*) &dirname_for_local_load, 0,
GET_STR_ALLOC, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'V', "Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, {"version", 'V', "Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
0, 0, 0, 0, 0}, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
...@@ -209,6 +338,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), ...@@ -209,6 +338,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case 'V': case 'V':
print_version(); print_version();
exit(0); exit(0);
case 'l':
use_local_load= 1;
break;
case '?': case '?':
usage(); usage();
exit(0); exit(0);
...@@ -420,6 +552,8 @@ static void dump_local_log_entries(const char* logname) ...@@ -420,6 +552,8 @@ static void dump_local_log_entries(const char* logname)
MYF(MY_WME | MY_NABP))) MYF(MY_WME | MY_NABP)))
exit(1); exit(1);
old_format = check_header(file); old_format = check_header(file);
if (use_local_load && !dirname_for_local_load)
load_processor.init_by_file_name(logname);
} }
else else
{ {
...@@ -441,6 +575,8 @@ static void dump_local_log_entries(const char* logname) ...@@ -441,6 +575,8 @@ static void dump_local_log_entries(const char* logname)
} }
file->pos_in_file=position; file->pos_in_file=position;
file->seek_not_done=0; file->seek_not_done=0;
if (use_local_load && !dirname_for_local_load)
load_processor.init_by_cur_dir();
} }
if (!position) if (!position)
...@@ -495,11 +631,43 @@ Could not read entry at offset %s : Error in log format or read error", ...@@ -495,11 +631,43 @@ Could not read entry at offset %s : Error in log format or read error",
} }
if (!short_form) if (!short_form)
fprintf(result_file, "# at %s\n",llstr(old_off,llbuff)); fprintf(result_file, "# at %s\n",llstr(old_off,llbuff));
ev->print(result_file, short_form, last_db); if (!use_local_load)
ev->print(result_file, short_form, last_db);
else
{
switch(ev->get_type_code())
{
case CREATE_FILE_EVENT:
{
Create_file_log_event* ce= (Create_file_log_event*)ev;
ce->print(result_file, short_form, last_db,true);
load_processor.process(ce);
ev= 0;
break;
}
case APPEND_BLOCK_EVENT:
ev->print(result_file, short_form, last_db);
load_processor.process((Append_block_log_event*)ev);
break;
case EXEC_LOAD_EVENT:
{
ev->print(result_file, short_form, last_db);
Execute_load_log_event *exv= (Execute_load_log_event*)ev;
Create_file_log_event *ce= load_processor.grab_event(exv->file_id);
ce->print(result_file, short_form, last_db,true);
my_free((char*)ce->fname,MYF(MY_WME));
delete ce;
break;
}
default:
ev->print(result_file, short_form, last_db);
}
}
} }
rec_count++; rec_count++;
delete ev; if (ev)
delete ev;
} }
if (fd >= 0) if (fd >= 0)
my_close(fd, MYF(MY_WME)); my_close(fd, MYF(MY_WME));
...@@ -520,6 +688,8 @@ int main(int argc, char** argv) ...@@ -520,6 +688,8 @@ int main(int argc, char** argv)
if (use_remote) if (use_remote)
mysql = safe_connect(); mysql = safe_connect();
if (dirname_for_local_load)
load_processor.init_by_dir_name(dirname_for_local_load);
if (table) if (table)
{ {
......
...@@ -840,17 +840,19 @@ int Field_decimal::store(longlong nr) ...@@ -840,17 +840,19 @@ int Field_decimal::store(longlong nr)
double Field_decimal::val_real(void) double Field_decimal::val_real(void)
{ {
int err; int not_used;
return my_strntod(my_charset_bin, ptr, field_length, NULL, &err); return my_strntod(my_charset_bin, ptr, field_length, NULL, &not_used);
} }
longlong Field_decimal::val_int(void) longlong Field_decimal::val_int(void)
{ {
int err; int not_used;
if (unsigned_flag) if (unsigned_flag)
return my_strntoull(my_charset_bin, ptr, field_length, 10, NULL, &err); return my_strntoull(my_charset_bin, ptr, field_length, 10, NULL,
&not_used);
else else
return my_strntoll( my_charset_bin, ptr, field_length, 10, NULL, &err); return my_strntoll( my_charset_bin, ptr, field_length, 10, NULL,
&not_used);
} }
...@@ -952,9 +954,9 @@ void Field_decimal::sql_type(String &res) const ...@@ -952,9 +954,9 @@ void Field_decimal::sql_type(String &res) const
int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs) int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
int err; int not_used; // We can ignore result from str2int
char *end; char *end;
long tmp= my_strntol(cs, from, len, 10, &end, &err); long tmp= my_strntol(cs, from, len, 10, &end, &not_used);
int error= 0; int error= 0;
if (unsigned_flag) if (unsigned_flag)
...@@ -1154,10 +1156,11 @@ void Field_tiny::sql_type(String &res) const ...@@ -1154,10 +1156,11 @@ void Field_tiny::sql_type(String &res) const
int Field_short::store(const char *from,uint len,CHARSET_INFO *cs) int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
int err; int not_used; // We can ignore result from str2int
char *end; char *end;
long tmp= my_strntol(cs, from, len, 10, &end, &err); long tmp= my_strntol(cs, from, len, 10, &end, &not_used);
int error= 0; int error= 0;
if (unsigned_flag) if (unsigned_flag)
{ {
if (tmp < 0) if (tmp < 0)
...@@ -1427,9 +1430,9 @@ void Field_short::sql_type(String &res) const ...@@ -1427,9 +1430,9 @@ void Field_short::sql_type(String &res) const
int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs) int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
int err; int not_used; // We can ignore result from str2int
char *end; char *end;
long tmp= my_strntol(cs, from, len, 10, &end, &err); long tmp= my_strntol(cs, from, len, 10, &end, &not_used);
int error= 0; int error= 0;
if (unsigned_flag) if (unsigned_flag)
...@@ -2134,7 +2137,7 @@ void Field_longlong::sql_type(String &res) const ...@@ -2134,7 +2137,7 @@ void Field_longlong::sql_type(String &res) const
int Field_float::store(const char *from,uint len,CHARSET_INFO *cs) int Field_float::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
int err=0; int err;
Field_float::store(my_strntod(cs,(char*) from,len,(char**)NULL,&err)); Field_float::store(my_strntod(cs,(char*) from,len,(char**)NULL,&err));
if (err || current_thd->count_cuted_fields && !test_if_real(from,len,cs)) if (err || current_thd->count_cuted_fields && !test_if_real(from,len,cs))
{ {
...@@ -2407,7 +2410,7 @@ void Field_float::sql_type(String &res) const ...@@ -2407,7 +2410,7 @@ void Field_float::sql_type(String &res) const
int Field_double::store(const char *from,uint len,CHARSET_INFO *cs) int Field_double::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
int err= 0; int err;
double j= my_strntod(cs,(char*) from,len,(char**)0,&err); double j= my_strntod(cs,(char*) from,len,(char**)0,&err);
if (err || current_thd->count_cuted_fields && !test_if_real(from,len,cs)) if (err || current_thd->count_cuted_fields && !test_if_real(from,len,cs))
{ {
...@@ -3193,9 +3196,9 @@ void Field_time::sql_type(String &res) const ...@@ -3193,9 +3196,9 @@ void Field_time::sql_type(String &res) const
int Field_year::store(const char *from, uint len,CHARSET_INFO *cs) int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
{ {
int err; int not_used; // We can ignore result from str2int
char *end; char *end;
long nr= my_strntol(cs, from, len, 10, &end, &err); long nr= my_strntol(cs, from, len, 10, &end, &not_used);
if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155) if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155)
{ {
...@@ -3932,17 +3935,17 @@ int Field_string::store(longlong nr) ...@@ -3932,17 +3935,17 @@ int Field_string::store(longlong nr)
double Field_string::val_real(void) double Field_string::val_real(void)
{ {
int err; int not_used;
CHARSET_INFO *cs=charset(); CHARSET_INFO *cs=charset();
return my_strntod(cs,ptr,field_length,(char**)0,&err); return my_strntod(cs,ptr,field_length,(char**)0,&not_used);
} }
longlong Field_string::val_int(void) longlong Field_string::val_int(void)
{ {
int err; int not_used;
CHARSET_INFO *cs=charset(); CHARSET_INFO *cs=charset();
return my_strntoll(cs,ptr,field_length,10,NULL,&err); return my_strntoll(cs,ptr,field_length,10,NULL,&not_used);
} }
...@@ -4017,7 +4020,6 @@ int Field_string::pack_cmp(const char *a, const char *b, uint length) ...@@ -4017,7 +4020,6 @@ int Field_string::pack_cmp(const char *a, const char *b, uint length)
{ {
uint a_length= (uint) (uchar) *a++; uint a_length= (uint) (uchar) *a++;
uint b_length= (uint) (uchar) *b++; uint b_length= (uint) (uchar) *b++;
return my_strnncoll(field_charset, return my_strnncoll(field_charset,
(const uchar*)a,a_length, (const uchar*)a,a_length,
(const uchar*)b,b_length); (const uchar*)b,b_length);
...@@ -4031,7 +4033,6 @@ int Field_string::pack_cmp(const char *b, uint length) ...@@ -4031,7 +4033,6 @@ int Field_string::pack_cmp(const char *b, uint length)
while (end > ptr && end[-1] == ' ') while (end > ptr && end[-1] == ' ')
end--; end--;
uint a_length = (uint) (end - ptr); uint a_length = (uint) (end - ptr);
return my_strnncoll(field_charset, return my_strnncoll(field_charset,
(const uchar*)ptr,a_length, (const uchar*)ptr,a_length,
(const uchar*)b, b_length); (const uchar*)b, b_length);
...@@ -4101,19 +4102,19 @@ int Field_varstring::store(longlong nr) ...@@ -4101,19 +4102,19 @@ int Field_varstring::store(longlong nr)
double Field_varstring::val_real(void) double Field_varstring::val_real(void)
{ {
int err; int not_used;
uint length=uint2korr(ptr)+2; uint length=uint2korr(ptr)+2;
CHARSET_INFO *cs=charset(); CHARSET_INFO *cs=charset();
return my_strntod(cs,ptr+2,length,(char**)0,&err); return my_strntod(cs,ptr+2,length,(char**)0, &not_used);
} }
longlong Field_varstring::val_int(void) longlong Field_varstring::val_int(void)
{ {
int err; int not_used;
uint length=uint2korr(ptr)+2; uint length=uint2korr(ptr)+2;
CHARSET_INFO *cs=charset(); CHARSET_INFO *cs=charset();
return my_strntoll(cs,ptr+2,length,10,NULL,&err); return my_strntoll(cs,ptr+2,length,10,NULL, &not_used);
} }
...@@ -4421,26 +4422,26 @@ int Field_blob::store(longlong nr) ...@@ -4421,26 +4422,26 @@ int Field_blob::store(longlong nr)
double Field_blob::val_real(void) double Field_blob::val_real(void)
{ {
int err; int not_used;
char *blob; char *blob;
memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
if (!blob) if (!blob)
return 0.0; return 0.0;
uint32 length=get_length(ptr); uint32 length=get_length(ptr);
CHARSET_INFO *cs=charset(); CHARSET_INFO *cs=charset();
return my_strntod(cs,blob,length,(char**)0,&err); return my_strntod(cs,blob,length,(char**)0, &not_used);
} }
longlong Field_blob::val_int(void) longlong Field_blob::val_int(void)
{ {
int err; int not_used;
char *blob; char *blob;
memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
if (!blob) if (!blob)
return 0; return 0;
uint32 length=get_length(ptr); uint32 length=get_length(ptr);
return my_strntoll(charset(),blob,length,10,NULL,&err); return my_strntoll(charset(),blob,length,10,NULL,&not_used);
} }
...@@ -4610,10 +4611,8 @@ void Field_blob::sort_string(char *to,uint length) ...@@ -4610,10 +4611,8 @@ void Field_blob::sort_string(char *to,uint length)
blob_length=my_strnxfrm(field_charset, blob_length=my_strnxfrm(field_charset,
(unsigned char *)to, length, (unsigned char *)to, length,
(unsigned char *)blob, blob_length); (unsigned char *)blob, blob_length);
if (blob_length >= length) if (blob_length < length)
return; bzero(to+blob_length, length-blob_length);
to+=blob_length;
bzero(to,length-blob_length);
} }
} }
......
...@@ -1396,7 +1396,10 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db) ...@@ -1396,7 +1396,10 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db)
if (db && db[0] && !same_db) if (db && db[0] && !same_db)
fprintf(file, "use %s;\n", db); fprintf(file, "use %s;\n", db);
fprintf(file, "LOAD DATA INFILE '%-*s' ", fname_len, fname); fprintf(file, "LOAD ");
if (check_fname_outside_temp_buf())
fprintf(file, "LOCAL ");
fprintf(file, "DATA INFILE '%-*s' ", fname_len, fname);
if (sql_ex.opt_flags && REPLACE_FLAG ) if (sql_ex.opt_flags && REPLACE_FLAG )
fprintf(file," REPLACE "); fprintf(file," REPLACE ");
...@@ -2310,14 +2313,32 @@ Create_file_log_event::Create_file_log_event(const char* buf, int len, ...@@ -2310,14 +2313,32 @@ Create_file_log_event::Create_file_log_event(const char* buf, int len,
****************************************************************************/ ****************************************************************************/
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Create_file_log_event::print(FILE* file, bool short_form, void Create_file_log_event::print(FILE* file, bool short_form,
char* last_db) char* last_db, bool enable_local)
{ {
if (short_form) if (short_form)
{
if (enable_local && check_fname_outside_temp_buf())
Load_log_event::print(file, 1, last_db);
return; return;
Load_log_event::print(file, 1, last_db); }
if (enable_local)
{
if (!check_fname_outside_temp_buf())
fprintf(file, "#");
Load_log_event::print(file, 1, last_db);
fprintf(file, "#");
}
fprintf(file, " file_id: %d block_len: %d\n", file_id, block_len); fprintf(file, " file_id: %d block_len: %d\n", file_id, block_len);
} }
void Create_file_log_event::print(FILE* file, bool short_form,
char* last_db)
{
print(file,short_form,last_db,0);
}
#endif // MYSQL_CLIENT #endif // MYSQL_CLIENT
/***************************************************************************** /*****************************************************************************
......
...@@ -447,6 +447,13 @@ public: ...@@ -447,6 +447,13 @@ public:
uint32 skip_lines; uint32 skip_lines;
sql_ex_info sql_ex; sql_ex_info sql_ex;
/* fname doesn't point to memory inside Log_event::temp_buf */
void set_fname_outside_temp_buf(const char *afname, uint alen)
{fname=afname;fname_len=alen;}
/* fname doesn't point to memory inside Log_event::temp_buf */
int check_fname_outside_temp_buf()
{return fname<temp_buf || fname>temp_buf+cached_event_len;}
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
String field_lens_buf; String field_lens_buf;
String fields_buf; String fields_buf;
...@@ -690,6 +697,7 @@ public: ...@@ -690,6 +697,7 @@ public:
int exec_event(struct st_relay_log_info* rli); int exec_event(struct st_relay_log_info* rli);
#else #else
void print(FILE* file, bool short_form = 0, char* last_db = 0); void print(FILE* file, bool short_form = 0, char* last_db = 0);
void print(FILE* file, bool short_form, char* last_db, bool enable_local);
#endif #endif
Create_file_log_event(const char* buf, int event_len, bool old_format); Create_file_log_event(const char* buf, int event_len, bool old_format);
......
...@@ -242,6 +242,7 @@ static void free_cache_entry(TABLE *table) ...@@ -242,6 +242,7 @@ static void free_cache_entry(TABLE *table)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* Free resources allocated by filesort() and read_record() */
void free_io_cache(TABLE *table) void free_io_cache(TABLE *table)
{ {
......
...@@ -107,7 +107,7 @@ void lex_init(void) ...@@ -107,7 +107,7 @@ void lex_init(void)
state_map[i]=(uchar) STATE_CHAR; state_map[i]=(uchar) STATE_CHAR;
} }
state_map[(uchar)'_']=state_map[(uchar)'$']=(uchar) STATE_IDENT; state_map[(uchar)'_']=state_map[(uchar)'$']=(uchar) STATE_IDENT;
state_map[(uchar)'\'']=state_map[(uchar)'"']=(uchar) STATE_STRING; state_map[(uchar)'\'']=(uchar) STATE_STRING;
state_map[(uchar)'-']=state_map[(uchar)'+']=(uchar) STATE_SIGNED_NUMBER; state_map[(uchar)'-']=state_map[(uchar)'+']=(uchar) STATE_SIGNED_NUMBER;
state_map[(uchar)'.']=(uchar) STATE_REAL_OR_POINT; state_map[(uchar)'.']=(uchar) STATE_REAL_OR_POINT;
state_map[(uchar)'>']=state_map[(uchar)'=']=state_map[(uchar)'!']= (uchar) STATE_CMP_OP; state_map[(uchar)'>']=state_map[(uchar)'=']=state_map[(uchar)'!']= (uchar) STATE_CMP_OP;
...@@ -122,10 +122,7 @@ void lex_init(void) ...@@ -122,10 +122,7 @@ void lex_init(void)
state_map[(uchar)'*']= (uchar) STATE_END_LONG_COMMENT; state_map[(uchar)'*']= (uchar) STATE_END_LONG_COMMENT;
state_map[(uchar)'@']= (uchar) STATE_USER_END; state_map[(uchar)'@']= (uchar) STATE_USER_END;
state_map[(uchar) '`']= (uchar) STATE_USER_VARIABLE_DELIMITER; state_map[(uchar) '`']= (uchar) STATE_USER_VARIABLE_DELIMITER;
if (global_system_variables.sql_mode & MODE_ANSI_QUOTES) state_map[(uchar)'"']= (uchar) STAT_STRING_OR_DELIMITER;
{
state_map[(uchar) '"'] = STATE_USER_VARIABLE_DELIMITER;
}
/* /*
Create a second map to make it faster to find identifiers Create a second map to make it faster to find identifiers
...@@ -652,12 +649,13 @@ int yylex(void *arg, void *yythd) ...@@ -652,12 +649,13 @@ int yylex(void *arg, void *yythd)
return(IDENT); return(IDENT);
case STATE_USER_VARIABLE_DELIMITER: case STATE_USER_VARIABLE_DELIMITER:
{
char delim= c; // Used char
lex->tok_start=lex->ptr; // Skip first ` lex->tok_start=lex->ptr; // Skip first `
#ifdef USE_MB #ifdef USE_MB
if (use_mb(system_charset_info)) if (use_mb(system_charset_info))
{ {
while ((c=yyGet()) && state_map[c] != STATE_USER_VARIABLE_DELIMITER && while ((c=yyGet()) && c != delim && c != (uchar) NAMES_SEP_CHAR)
c != (uchar) NAMES_SEP_CHAR)
{ {
if (my_ismbhead(system_charset_info, c)) if (my_ismbhead(system_charset_info, c))
{ {
...@@ -673,16 +671,15 @@ int yylex(void *arg, void *yythd) ...@@ -673,16 +671,15 @@ int yylex(void *arg, void *yythd)
else else
#endif #endif
{ {
while ((c=yyGet()) && state_map[c] != STATE_USER_VARIABLE_DELIMITER && while ((c=yyGet()) && c != delim && c != (uchar) NAMES_SEP_CHAR) ;
c != (uchar) NAMES_SEP_CHAR) ;
} }
yylval->lex_str=get_token(lex,yyLength()); yylval->lex_str=get_token(lex,yyLength());
if (lex->convert_set) if (lex->convert_set)
lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen); lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
if (state_map[c] == STATE_USER_VARIABLE_DELIMITER) if (c == delim)
yySkip(); // Skip end ` yySkip(); // Skip end `
return(IDENT); return(IDENT);
}
case STATE_SIGNED_NUMBER: // Incomplete signed number case STATE_SIGNED_NUMBER: // Incomplete signed number
if (prev_state == STATE_OPERATOR_OR_IDENT) if (prev_state == STATE_OPERATOR_OR_IDENT)
{ {
...@@ -795,6 +792,13 @@ int yylex(void *arg, void *yythd) ...@@ -795,6 +792,13 @@ int yylex(void *arg, void *yythd)
lex->next_state= STATE_START; // Allow signed numbers lex->next_state= STATE_START; // Allow signed numbers
return(tokval); return(tokval);
case STAT_STRING_OR_DELIMITER:
if (((THD *) yythd)->variables.sql_mode & MODE_ANSI_QUOTES)
{
state= STATE_USER_VARIABLE_DELIMITER;
break;
}
/* " used for strings */
case STATE_STRING: // Incomplete text string case STATE_STRING: // Incomplete text string
if (!(yylval->lex_str.str = get_text(lex))) if (!(yylval->lex_str.str = get_text(lex)))
{ {
...@@ -889,6 +893,7 @@ int yylex(void *arg, void *yythd) ...@@ -889,6 +893,7 @@ int yylex(void *arg, void *yythd)
switch (state_map[yyPeek()]) { switch (state_map[yyPeek()]) {
case STATE_STRING: case STATE_STRING:
case STATE_USER_VARIABLE_DELIMITER: case STATE_USER_VARIABLE_DELIMITER:
case STAT_STRING_OR_DELIMITER:
break; break;
case STATE_USER_END: case STATE_USER_END:
lex->next_state=STATE_SYSTEM_VAR; lex->next_state=STATE_SYSTEM_VAR;
......
...@@ -86,7 +86,8 @@ enum lex_states ...@@ -86,7 +86,8 @@ enum lex_states
STATE_REAL_OR_POINT, STATE_BOOL, STATE_EOL, STATE_ESCAPE, STATE_LONG_COMMENT, STATE_REAL_OR_POINT, STATE_BOOL, STATE_EOL, STATE_ESCAPE, STATE_LONG_COMMENT,
STATE_END_LONG_COMMENT, STATE_COLON, STATE_SET_VAR, STATE_USER_END, STATE_END_LONG_COMMENT, STATE_COLON, STATE_SET_VAR, STATE_USER_END,
STATE_HOSTNAME, STATE_SKIP, STATE_USER_VARIABLE_DELIMITER, STATE_SYSTEM_VAR, STATE_HOSTNAME, STATE_SKIP, STATE_USER_VARIABLE_DELIMITER, STATE_SYSTEM_VAR,
STATE_IDENT_OR_KEYWORD, STATE_IDENT_OR_HEX, STATE_IDENT_OR_BIN STATE_IDENT_OR_KEYWORD, STATE_IDENT_OR_HEX, STATE_IDENT_OR_BIN,
STAT_STRING_OR_DELIMITER
}; };
......
...@@ -214,7 +214,8 @@ long my_strntol_8bit(CHARSET_INFO *cs, ...@@ -214,7 +214,8 @@ long my_strntol_8bit(CHARSET_INFO *cs,
const char *save, *e; const char *save, *e;
int overflow; int overflow;
#if 0 *err= 0; /* Initialize error indicator */
#ifdef NOT_USED
if (base < 0 || base == 1 || base > 36) if (base < 0 || base == 1 || base > 36)
base = 10; base = 10;
#endif #endif
...@@ -243,12 +244,12 @@ long my_strntol_8bit(CHARSET_INFO *cs, ...@@ -243,12 +244,12 @@ long my_strntol_8bit(CHARSET_INFO *cs,
else else
negative = 0; negative = 0;
#if 0 #ifdef NOT_USED
if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x')) if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x'))
s += 2; s += 2;
#endif #endif
#if 0 #ifdef NOT_USED
if (base == 0) if (base == 0)
{ {
if (*s == '0') if (*s == '0')
...@@ -336,7 +337,8 @@ ulong my_strntoul_8bit(CHARSET_INFO *cs, ...@@ -336,7 +337,8 @@ ulong my_strntoul_8bit(CHARSET_INFO *cs,
const char *save, *e; const char *save, *e;
int overflow; int overflow;
#if 0 *err= 0; /* Initialize error indicator */
#ifdef NOT_USED
if (base < 0 || base == 1 || base > 36) if (base < 0 || base == 1 || base > 36)
base = 10; base = 10;
#endif #endif
...@@ -364,12 +366,12 @@ ulong my_strntoul_8bit(CHARSET_INFO *cs, ...@@ -364,12 +366,12 @@ ulong my_strntoul_8bit(CHARSET_INFO *cs,
else else
negative = 0; negative = 0;
#if 0 #ifdef NOT_USED
if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x')) if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x'))
s += 2; s += 2;
#endif #endif
#if 0 #ifdef NOT_USED
if (base == 0) if (base == 0)
{ {
if (*s == '0') if (*s == '0')
...@@ -449,7 +451,8 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)), ...@@ -449,7 +451,8 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)),
const char *save; const char *save;
int overflow; int overflow;
#if 0 *err= 0; /* Initialize error indicator */
#ifdef NOT_USED
if (base < 0 || base == 1 || base > 36) if (base < 0 || base == 1 || base > 36)
base = 10; base = 10;
#endif #endif
...@@ -477,12 +480,12 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)), ...@@ -477,12 +480,12 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)),
else else
negative = 0; negative = 0;
#if 0 #ifdef NOT_USED
if (base == 16 && s[0] == '0' && (s[1]=='X'|| s[1]=='x')) if (base == 16 && s[0] == '0' && (s[1]=='X'|| s[1]=='x'))
s += 2; s += 2;
#endif #endif
#if 0 #ifdef NOT_USED
if (base == 0) if (base == 0)
{ {
if (*s == '0') if (*s == '0')
...@@ -571,7 +574,8 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs, ...@@ -571,7 +574,8 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs,
const char *save; const char *save;
int overflow; int overflow;
#if 0 *err= 0; /* Initialize error indicator */
#ifdef NOT_USED
if (base < 0 || base == 1 || base > 36) if (base < 0 || base == 1 || base > 36)
base = 10; base = 10;
#endif #endif
...@@ -599,12 +603,12 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs, ...@@ -599,12 +603,12 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs,
else else
negative = 0; negative = 0;
#if 0 #ifdef NOT_USED
if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x')) if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x'))
s += 2; s += 2;
#endif #endif
#if 0 #ifdef NOT_USED
if (base == 0) if (base == 0)
{ {
if (*s == '0') if (*s == '0')
...@@ -679,7 +683,8 @@ noconv: ...@@ -679,7 +683,8 @@ noconv:
cs Character set information cs Character set information
str String to convert to double str String to convert to double
length Optional length for string. length Optional length for string.
end pointer to end of converted string end result pointer to end of converted string
err Error number if failed conversion
NOTES: NOTES:
If length is not INT_MAX32 or str[length] != 0 then the given str must If length is not INT_MAX32 or str[length] != 0 then the given str must
...@@ -689,23 +694,28 @@ noconv: ...@@ -689,23 +694,28 @@ noconv:
It's implemented this way to save a buffer allocation and a memory copy. It's implemented this way to save a buffer allocation and a memory copy.
RETURN RETURN
value of number in string Value of number in string
*/ */
double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)), double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)),
char *str, uint length, char *str, uint length,
char **end, int *err __attribute__ ((unused))) char **end, int *err)
{ {
char end_char; char end_char;
double result; double result;
errno= 0; /* Safety */
if (length == INT_MAX32 || str[length] == 0) if (length == INT_MAX32 || str[length] == 0)
return strtod(str, end); result= strtod(str, end);
end_char= str[length]; else
str[length]= 0; {
result= strtod(str, end); end_char= str[length];
str[length]= end_char; /* Restore end char */ str[length]= 0;
result= strtod(str, end);
str[length]= end_char; /* Restore end char */
}
*err= errno;
return result; return result;
} }
......
...@@ -2464,7 +2464,9 @@ long my_strntol_ucs2(CHARSET_INFO *cs, ...@@ -2464,7 +2464,9 @@ long my_strntol_ucs2(CHARSET_INFO *cs,
register const char *e=nptr+l; register const char *e=nptr+l;
const char *save; const char *save;
do { *err= 0;
do
{
if ((cnv=cs->mb_wc(cs,&wc,s,e))>0) if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
{ {
switch (wc) switch (wc)
...@@ -2577,7 +2579,9 @@ ulong my_strntoul_ucs2(CHARSET_INFO *cs, ...@@ -2577,7 +2579,9 @@ ulong my_strntoul_ucs2(CHARSET_INFO *cs,
register const char *e=nptr+l; register const char *e=nptr+l;
const char *save; const char *save;
do { *err= 0;
do
{
if ((cnv=cs->mb_wc(cs,&wc,s,e))>0) if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
{ {
switch (wc) switch (wc)
...@@ -2684,7 +2688,9 @@ longlong my_strntoll_ucs2(CHARSET_INFO *cs, ...@@ -2684,7 +2688,9 @@ longlong my_strntoll_ucs2(CHARSET_INFO *cs,
register const char *e=nptr+l; register const char *e=nptr+l;
const char *save; const char *save;
do { *err= 0;
do
{
if ((cnv=cs->mb_wc(cs,&wc,s,e))>0) if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
{ {
switch (wc) switch (wc)
...@@ -2799,7 +2805,9 @@ ulonglong my_strntoull_ucs2(CHARSET_INFO *cs, ...@@ -2799,7 +2805,9 @@ ulonglong my_strntoull_ucs2(CHARSET_INFO *cs,
register const char *e=nptr+l; register const char *e=nptr+l;
const char *save; const char *save;
do { *err= 0;
do
{
if ((cnv=cs->mb_wc(cs,&wc,s,e))>0) if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
{ {
switch (wc) switch (wc)
...@@ -2834,7 +2842,8 @@ bs: ...@@ -2834,7 +2842,8 @@ bs:
cutoff = (~(ulonglong) 0) / (unsigned long int) base; cutoff = (~(ulonglong) 0) / (unsigned long int) base;
cutlim = (uint) ((~(ulonglong) 0) % (unsigned long int) base); cutlim = (uint) ((~(ulonglong) 0) % (unsigned long int) base);
do { do
{
if ((cnv=cs->mb_wc(cs,&wc,s,e))>0) if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
{ {
s+=cnv; s+=cnv;
...@@ -2891,7 +2900,7 @@ bs: ...@@ -2891,7 +2900,7 @@ bs:
double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
char *nptr, uint length, char *nptr, uint length,
char **endptr, int *err __attribute__ ((unused))) char **endptr, int *err)
{ {
char buf[256]; char buf[256];
double res; double res;
...@@ -2900,7 +2909,8 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), ...@@ -2900,7 +2909,8 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
register const char *end; register const char *end;
my_wc_t wc; my_wc_t wc;
int cnv; int cnv;
*err= 0;
/* Cut too long strings */ /* Cut too long strings */
if (length >= sizeof(buf)) if (length >= sizeof(buf))
length= sizeof(buf)-1; length= sizeof(buf)-1;
...@@ -2915,7 +2925,9 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), ...@@ -2915,7 +2925,9 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
} }
*b= 0; *b= 0;
errno= 0;
res=strtod(buf, endptr); res=strtod(buf, endptr);
*err= errno;
if (endptr) if (endptr)
*endptr=(char*) (*endptr-buf+nptr); *endptr=(char*) (*endptr-buf+nptr);
return res; return res;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment