diff options
author | unknown <monty@hundin.mysql.fi> | 2002-04-13 15:34:39 +0300 |
---|---|---|
committer | unknown <monty@hundin.mysql.fi> | 2002-04-13 15:34:39 +0300 |
commit | fdc446d0c621c3be38b5b11cc0e40308679fb996 (patch) | |
tree | 6bb12842fb04d64fa854f04ec3d07da1e1f7c48b /client | |
parent | 54373c16f8435db653ffbad55466e457eb816976 (diff) | |
parent | adc7a375368892eac433e19aab29ecefcf867d4b (diff) | |
download | mariadb-git-fdc446d0c621c3be38b5b11cc0e40308679fb996.tar.gz |
merge
BitKeeper/etc/ignore:
auto-union
BitKeeper/etc/logging_ok:
auto-union
BUILD/FINISH.sh:
Auto merged
BUILD/SETUP.sh:
Auto merged
BUILD/compile-pentium-debug:
Auto merged
acconfig.h:
Auto merged
client/mysql.cc:
Auto merged
client/mysqldump.c:
Auto merged
client/mysqltest.c:
Auto merged
heap/hp_rfirst.c:
Auto merged
heap/hp_rnext.c:
Auto merged
include/my_sys.h:
Auto merged
include/myisam.h:
Auto merged
libmysql/Makefile.shared:
Auto merged
myisam/mi_write.c:
Auto merged
mysql-test/mysql-test-run.sh:
Auto merged
mysql-test/r/heap.result:
Auto merged
mysql-test/r/select_found.result:
Auto merged
mysql-test/r/union.result:
Auto merged
mysql-test/t/heap.test:
Auto merged
mysql-test/t/select_found.test:
Auto merged
mysql-test/t/union.test:
Auto merged
mysys/mf_iocache2.c:
Auto merged
mysys/my_vsnprintf.c:
Auto merged
sql/convert.cc:
Auto merged
sql/field.cc:
Auto merged
sql/field.h:
Auto merged
sql/filesort.cc:
Auto merged
sql/ha_myisam.cc:
Auto merged
sql/item.cc:
Auto merged
sql/item.h:
Auto merged
sql/item_cmpfunc.cc:
Auto merged
sql/item_func.cc:
Auto merged
sql/item_func.h:
Auto merged
sql/item_strfunc.cc:
Auto merged
sql/item_timefunc.cc:
Auto merged
sql/lex.h:
Auto merged
sql/log.cc:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/mysqld.cc:
Auto merged
sql/opt_range.cc:
Auto merged
sql/opt_range.h:
Auto merged
sql/opt_sum.cc:
Auto merged
sql/slave.cc:
Auto merged
sql/sql_base.cc:
Auto merged
sql/sql_cache.cc:
Auto merged
sql/sql_class.cc:
Auto merged
sql/sql_db.cc:
Auto merged
sql/sql_handler.cc:
Auto merged
sql/sql_lex.cc:
Auto merged
sql/sql_lex.h:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_show.cc:
Auto merged
sql/sql_table.cc:
Auto merged
sql/sql_union.cc:
Auto merged
sql/sql_yacc.yy:
Auto merged
sql/structs.h:
Auto merged
sql/table.cc:
Auto merged
sql/table.h:
Auto merged
strings/Makefile.am:
Auto merged
Diffstat (limited to 'client')
-rw-r--r-- | client/mysql.cc | 53 | ||||
-rw-r--r-- | client/mysqldump.c | 11 | ||||
-rw-r--r-- | client/mysqltest.c | 51 | ||||
-rw-r--r-- | client/sql_string.cc | 206 | ||||
-rw-r--r-- | client/sql_string.h | 94 |
5 files changed, 297 insertions, 118 deletions
diff --git a/client/mysql.cc b/client/mysql.cc index c9b80ebb2f8..c4dbf1688ef 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -342,6 +342,7 @@ int main(int argc,char *argv[]) if (!status.batch) ignore_errors=1; // Don't abort monitor signal(SIGINT, mysql_end); // Catch SIGINT to clean up + signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up /* ** Run in interactive mode like the ingres/postgres monitor @@ -915,14 +916,14 @@ static COMMANDS *find_command (char *name,char cmd_char) } else { - while (isspace(*name)) + while (my_isspace(system_charset_info,*name)) name++; if (strchr(name,';') || strstr(name,"\\g")) return ((COMMANDS *) 0); if ((end=strcont(name," \t"))) { len=(uint) (end - name); - while (isspace(*end)) + while (my_isspace(system_charset_info,*end)) end++; if (!*end) end=0; // no arguments to function @@ -934,7 +935,8 @@ static COMMANDS *find_command (char *name,char cmd_char) for (uint i= 0; commands[i].name; i++) { if (commands[i].func && - ((name && !my_casecmp(name,commands[i].name,len) && + ((name && + !my_strncasecmp(system_charset_info,name,commands[i].name,len) && !commands[i].name[len] && (!end || (end && commands[i].takes_params))) || !name && commands[i].cmd_char == cmd_char)) @@ -962,12 +964,13 @@ static bool add_line(String &buffer,char *line,char *in_string) for (pos=out=line ; (inchar= (uchar) *pos) ; pos++) { - if (isspace(inchar) && out == line && buffer.is_empty()) + if (my_isspace(system_charset_info,inchar) && out == line && + buffer.is_empty()) continue; #ifdef USE_MB int l; - if (use_mb(default_charset_info) && - (l = my_ismbchar(default_charset_info, pos, strend))) { + if (use_mb(system_charset_info) && + (l = my_ismbchar(system_charset_info, pos, strend))) { while (l--) *out++ = *pos++; pos--; @@ -1030,7 +1033,7 @@ static bool add_line(String &buffer,char *line,char *in_string) } else if (!*in_string && (inchar == '#' || inchar == '-' && pos[1] == '-' && - isspace(pos[2]))) + my_isspace(system_charset_info,pos[2]))) break; // comment to end of line else { // Add found char to buffer @@ -1430,7 +1433,8 @@ com_go(String *buffer,char *line __attribute__((unused))) (void) com_print(buffer,0); if (skip_updates && - (buffer->length() < 4 || my_sortcmp(buffer->ptr(),"SET ",4))) + (buffer->length() < 4 || my_sortcmp(system_charset_info,buffer->ptr(), + "SET ",4))) { (void) put_info("Ignoring query to other database",INFO_INFO); return 0; @@ -1801,8 +1805,8 @@ safe_put_field(const char *pos,ulong length) { #ifdef USE_MB int l; - if (use_mb(default_charset_info) && - (l = my_ismbchar(default_charset_info, pos, end))) { + if (use_mb(system_charset_info) && + (l = my_ismbchar(system_charset_info, pos, end))) { while (l--) tee_putc(*pos++, PAGER); pos--; @@ -1862,7 +1866,7 @@ com_tee(String *buffer, char *line __attribute__((unused))) if (status.batch) return 0; - while (isspace(*line)) + while (my_isspace(system_charset_info,*line)) line++; if (!(param = strchr(line, ' '))) // if outfile wasn't given, use the default { @@ -1875,10 +1879,11 @@ com_tee(String *buffer, char *line __attribute__((unused))) } else { - while (isspace(*param)) + while (my_isspace(system_charset_info,*param)) param++; end=strmake(file_name, param, sizeof(file_name)-1); - while (end > file_name && (isspace(end[-1]) || iscntrl(end[-1]))) + while (end > file_name && (my_isspace(system_charset_info,end[-1]) || + my_iscntrl(system_charset_info,end[-1]))) end--; end[0]=0; strmov(outfile, file_name); @@ -1921,7 +1926,7 @@ com_pager(String *buffer, char *line __attribute__((unused))) if (status.batch) return 0; /* Skip space from file name */ - while (isspace(*line)) + while (my_isspace(system_charset_info,*line)) line++; if (!(param = strchr(line, ' '))) // if pager was not given, use the default { @@ -1937,10 +1942,11 @@ com_pager(String *buffer, char *line __attribute__((unused))) } else { - while (isspace(*param)) + while (my_isspace(system_charset_info,*param)) param++; end=strmake(pager_name, param, sizeof(pager_name)-1); - while (end > pager_name && (isspace(end[-1]) || iscntrl(end[-1]))) + while (end > pager_name && (my_isspace(system_charset_info,end[-1]) || + my_iscntrl(system_charset_info,end[-1]))) end--; end[0]=0; strmov(pager, pager_name); @@ -2074,7 +2080,7 @@ com_connect(String *buffer, char *line) if (buffer) { - while (isspace(*line)) + while (my_isspace(system_charset_info,*line)) line++; strnmov(buff,line,sizeof(buff)-1); // Don't destroy history if (buff[0] == '\\') // Short command @@ -2120,15 +2126,16 @@ static int com_source(String *buffer, char *line) FILE *sql_file; /* Skip space from file name */ - while (isspace(*line)) + while (my_isspace(system_charset_info,*line)) line++; if (!(param = strchr(line, ' '))) // Skip command name return put_info("Usage: \\. <filename> | source <filename>", INFO_ERROR, 0); - while (isspace(*param)) + while (my_isspace(system_charset_info,*param)) param++; end=strmake(source_name,param,sizeof(source_name)-1); - while (end > source_name && (isspace(end[-1]) || iscntrl(end[-1]))) + while (end > source_name && (my_isspace(system_charset_info,end[-1]) || + my_iscntrl(system_charset_info,end[-1]))) end--; end[0]=0; unpack_filename(source_name,source_name); @@ -2169,7 +2176,7 @@ com_use(String *buffer __attribute__((unused)), char *line) char *tmp; char buff[256]; - while (isspace(*line)) + while (my_isspace(system_charset_info,*line)) line++; strnmov(buff,line,sizeof(buff)-1); // Don't destroy history if (buff[0] == '\\') // Short command @@ -2346,7 +2353,7 @@ com_status(String *buffer __attribute__((unused)), tee_fprintf(stdout, "Protocol version:\t%d\n", mysql_get_proto_info(&mysql)); tee_fprintf(stdout, "Connection:\t\t%s\n", mysql_get_host_info(&mysql)); tee_fprintf(stdout, "Client characterset:\t%s\n", - default_charset_info->name); + system_charset_info->name); tee_fprintf(stdout, "Server characterset:\t%s\n", mysql.charset->name); if (strstr(mysql_get_host_info(&mysql),"TCP/IP") || ! mysql.unix_socket) tee_fprintf(stdout, "TCP port:\t\t%d\n", mysql.port); @@ -2455,7 +2462,7 @@ static void remove_cntrl(String &buffer) { char *start,*end; end=(start=(char*) buffer.ptr())+buffer.length(); - while (start < end && !isgraph(end[-1])) + while (start < end && !my_isgraph(system_charset_info,end[-1])) end--; buffer.length((uint) (end-start)); } diff --git a/client/mysqldump.c b/client/mysqldump.c index b1c4707e211..833f28bba98 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -545,7 +545,7 @@ static my_bool test_if_special_chars(const char *str) { #if MYSQL_VERSION_ID >= 32300 for ( ; *str ; str++) - if (!isvar(*str) && *str != '$') + if (!my_isvar(system_charset_info,*str) && *str != '$') return 1; #endif return 0; @@ -1061,7 +1061,8 @@ static void dumpTable(uint numFields, char *table) /* change any strings ("inf","nan",..) into NULL */ char *ptr = row[i]; dynstr_append(&extended_row, - (!isalpha(*ptr)) ? ptr : "NULL"); + (!my_isalpha(system_charset_info,*ptr)) ? + ptr : "NULL"); } } else @@ -1093,9 +1094,11 @@ static void dumpTable(uint numFields, char *table) char *ptr = row[i]; if (opt_xml) fprintf(md_result_file, "\t\t<%s>%s</%s>\n", - field->name,!isalpha(*ptr) ?ptr: "NULL",field->name); + field->name, + !my_isalpha(system_charset_info,*ptr) ?ptr: "NULL",field->name); else - fputs((!isalpha(*ptr)) ? ptr : "NULL", md_result_file); + fputs((!my_isalpha(system_charset_info,*ptr)) ? + ptr : "NULL", md_result_file); } } else diff --git a/client/mysqltest.c b/client/mysqltest.c index a007c7778e0..e75cc9190e5 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -456,9 +456,9 @@ void init_parser() int hex_val(int c) { - if (isdigit(c)) + if (my_isdigit(system_charset_info,c)) return c - '0'; - else if ((c = tolower(c)) >= 'a' && c <= 'f') + else if ((c = my_tolower(system_charset_info,c)) >= 'a' && c <= 'f') return c - 'a' + 10; else return -1; @@ -569,7 +569,7 @@ VAR* var_get(const char* var_name, const char** var_name_end, my_bool raw, { const char* save_var_name = var_name, *end; end = (var_name_end) ? *var_name_end : 0; - while (isvar(*var_name) && var_name != end) + while (my_isvar(system_charset_info,*var_name) && var_name != end) ++var_name; if (var_name == save_var_name) { @@ -729,7 +729,7 @@ int do_server_op(struct st_query* q,const char* op) com_p=strmov(com_p,"_exec "); if (!*p) die("Missing server name in server_%s\n",op); - while (*p && !isspace(*p)) + while (*p && !my_isspace(system_charset_info,*p)) { *com_p++=*p++; } @@ -762,7 +762,7 @@ int do_require_version(struct st_query* q) if (!*p) die("Missing version argument in require_version\n"); ver_arg = p; - while (*p && !isspace(*p)) + while (*p && !my_isspace(system_charset_info,*p)) p++; *p = 0; ver_arg_len = p - ver_arg; @@ -792,7 +792,7 @@ int do_source(struct st_query* q) if (!*p) die("Missing file name in source\n"); name = p; - while (*p && !isspace(*p)) + while (*p && !my_isspace(system_charset_info,*p)) p++; *p = 0; @@ -1012,11 +1012,11 @@ int do_let(struct st_query* q) if (!*p) die("Missing variable name in let\n"); var_name = p; - while(*p && (*p != '=' || isspace(*p))) + while(*p && (*p != '=' || my_isspace(system_charset_info,*p))) p++; var_name_end = p; if (*p == '=') p++; - while(*p && isspace(*p)) + while(*p && my_isspace(system_charset_info,*p)) p++; var_val_start = p; return var_set(var_name, var_name_end, var_val_start, q->end); @@ -1047,7 +1047,7 @@ int do_sleep(struct st_query* q) char* p=q->first_argument; struct timeval t; int dec_mul = 1000000; - while(*p && isspace(*p)) p++; + while(*p && my_isspace(system_charset_info,*p)) p++; if (!*p) die("Missing argument in sleep\n"); t.tv_usec = 0; @@ -1067,7 +1067,7 @@ int do_sleep(struct st_query* q) else { t.tv_sec = atoi(p); - while(*p && *p != '.' && !isspace(*p)) + while(*p && *p != '.' && !my_isspace(system_charset_info,*p)) p++; if (*p == '.') { @@ -1099,7 +1099,7 @@ static void get_file_name(char *filename, struct st_query* q) char* p=q->first_argument; strnmov(filename, p, FN_REFLEN); /* Remove end space */ - while (p > filename && isspace(p[-1])) + while (p > filename && my_isspace(system_charset_info,p[-1])) p--; p[0]=0; } @@ -1185,7 +1185,7 @@ static char *get_string(char **to_ptr, char **from_ptr, if (*from != ' ' && *from) die("Wrong string argument in %s\n", q->query); - while (isspace(*from)) /* Point to next string */ + while (my_isspace(system_charset_info,*from)) /* Point to next string */ from++; *to =0; /* End of string marker */ @@ -1243,7 +1243,7 @@ static void get_replace(struct st_query *q) insert_pointer_name(&to_array,to); } for (i=1,pos=word_end_chars ; i < 256 ; i++) - if (isspace(i)) + if (my_isspace(system_charset_info,i)) *pos++=i; *pos=0; /* End pointer */ if (!(glob_replace=init_replace((char**) from_array.typelib.type_names, @@ -1278,7 +1278,7 @@ int select_connection(struct st_query* q) if (!*p) die("Missing connection name in connect\n"); name = p; - while(*p && !isspace(*p)) + while(*p && !my_isspace(system_charset_info,*p)) p++; *p = 0; @@ -1304,7 +1304,7 @@ int close_connection(struct st_query* q) if (!*p) die("Missing connection name in connect\n"); name = p; - while(*p && !isspace(*p)) + while(*p && !my_isspace(system_charset_info,*p)) p++; *p = 0; @@ -1340,11 +1340,11 @@ int close_connection(struct st_query* q) char* safe_get_param(char* str, char** arg, const char* msg) { DBUG_ENTER("safe_get_param"); - while (*str && isspace(*str)) str++; + while (*str && my_isspace(system_charset_info,*str)) str++; *arg = str; for (; *str && *str != ',' && *str != ')' ; str++) { - if (isspace(*str)) *str = 0; + if (my_isspace(system_charset_info,*str)) *str = 0; } if (!*str) die(msg); @@ -1626,7 +1626,7 @@ int read_line(char* buf, int size) { state = R_COMMENT; } - else if (isspace(c)) + else if (my_isspace(system_charset_info,c)) { if (c == '\n') start_lineno= ++*lineno; /* Query hasn't started yet */ @@ -1752,7 +1752,7 @@ int read_query(struct st_query** q_ptr) { expected_errno = 0; p++; - for (;isdigit(*p);p++) + for (;my_isdigit(system_charset_info,*p);p++) expected_errno = expected_errno * 10 + *p - '0'; q->expected_errno[0] = expected_errno; q->expected_errno[1] = 0; @@ -1760,25 +1760,25 @@ int read_query(struct st_query** q_ptr) } } - while(*p && isspace(*p)) p++ ; + while(*p && my_isspace(system_charset_info,*p)) p++ ; if (*p == '@') { p++; p1 = q->record_file; - while (!isspace(*p) && + while (!my_isspace(system_charset_info,*p) && p1 < q->record_file + sizeof(q->record_file) - 1) *p1++ = *p++; *p1 = 0; } } - while (*p && isspace(*p)) p++; + while (*p && my_isspace(system_charset_info,*p)) p++; if (!(q->query_buf=q->query=my_strdup(p,MYF(MY_WME)))) die(NullS); /* Calculate first word and first argument */ - for (p=q->query; *p && !isspace(*p) ; p++) ; + for (p=q->query; *p && !my_isspace(system_charset_info,*p) ; p++) ; q->first_word_len = (uint) (p - q->query); - while (*p && isspace(*p)) p++; + while (*p && my_isspace(system_charset_info,*p)) p++; q->first_argument=p; q->end = strend(q->query); parser.read_lines++; @@ -2326,7 +2326,8 @@ static void var_from_env(const char* name, const char* def_val) static void init_var_hash() { VAR* v; - if (hash_init(&var_hash, 1024, 0, 0, get_var_key, var_free, MYF(0))) + if (hash_init(&var_hash, system_charset_info, + 1024, 0, 0, get_var_key, var_free, MYF(0))) die("Variable hash initialization failed"); var_from_env("MASTER_MYPORT", "9306"); var_from_env("SLAVE_MYPORT", "9307"); diff --git a/client/sql_string.cc b/client/sql_string.cc index 3c5e481eaad..cf9e9f62507 100644 --- a/client/sql_string.cc +++ b/client/sql_string.cc @@ -234,7 +234,7 @@ bool String::fill(uint32 max_length,char fill_char) void String::strip_sp() { - while (str_length && isspace(Ptr[str_length-1])) + while (str_length && my_isspace(str_charset,Ptr[str_length-1])) str_length--; } @@ -296,10 +296,10 @@ uint32 String::numchars() register uint32 n=0,mblen; register const char *mbstr=Ptr; register const char *end=mbstr+str_length; - if (use_mb(default_charset_info)) + if (use_mb(str_charset)) { while (mbstr < end) { - if ((mblen=my_ismbchar(default_charset_info, mbstr,end))) mbstr+=mblen; + if ((mblen=my_ismbchar(str_charset, mbstr,end))) mbstr+=mblen; else ++mbstr; ++n; } @@ -316,11 +316,11 @@ int String::charpos(int i,uint32 offset) register uint32 mblen; register const char *mbstr=Ptr+offset; register const char *end=Ptr+str_length; - if (use_mb(default_charset_info)) + if (use_mb(str_charset)) { if (i<=0) return i; while (i && mbstr < end) { - if ((mblen=my_ismbchar(default_charset_info, mbstr,end))) mbstr+=mblen; + if ((mblen=my_ismbchar(str_charset, mbstr,end))) mbstr+=mblen; else ++mbstr; --i; } @@ -361,6 +361,39 @@ skipp: return -1; } +/* + Search after a string without regarding to case + This needs to be replaced when we have character sets per string +*/ + +int String::strstr_case(const String &s,uint32 offset) +{ + if (s.length()+offset <= str_length) + { + if (!s.length()) + return ((int) offset); // Empty string is always found + + register const char *str = Ptr+offset; + register const char *search=s.ptr(); + const char *end=Ptr+str_length-s.length()+1; + const char *search_end=s.ptr()+s.length(); +skipp: + while (str != end) + { + if (str_charset->sort_order[*str++] == str_charset->sort_order[*search]) + { + register char *i,*j; + i=(char*) str; j=(char*) search+1; + while (j != search_end) + if (str_charset->sort_order[*i++] != + str_charset->sort_order[*j++]) + goto skipp; + return (int) (str-Ptr) -1; + } + } + } + return -1; +} /* ** Search string from end. Offset is offset to the end of string @@ -428,6 +461,44 @@ bool String::replace(uint32 offset,uint32 arg_length,const String &to) return FALSE; } +// added by Holyfoot for "geometry" needs +int String::reserve(uint32 space_needed, uint32 grow_by) +{ + if (Alloced_length < str_length + space_needed) + { + if (realloc(Alloced_length + max(space_needed, grow_by) - 1)) + return TRUE; + } + return FALSE; +} + +void String::qs_append(const char *str) +{ + int len = strlen(str); + memcpy(Ptr + str_length, str, len + 1); + str_length += len; +} + +void String::qs_append(double d) +{ + char *buff = Ptr + str_length; + sprintf(buff,"%.14g", d); + str_length += strlen(buff); +} + +void String::qs_append(double *d) +{ + double ld; + float8get(ld, d); + qs_append(ld); +} + +void String::qs_append(const char &c) +{ + Ptr[str_length] = c; + str_length += sizeof(c); +} + int sortcmp(const String *x,const String *y) { @@ -436,15 +507,15 @@ int sortcmp(const String *x,const String *y) uint32 x_len=x->length(),y_len=y->length(),len=min(x_len,y_len); #ifdef USE_STRCOLL - if (use_strcoll(default_charset_info)) + if (use_strcoll(x->str_charset)) { #ifndef CMP_ENDSPACE - while (x_len && isspace(s[x_len-1])) + while (x_len && my_isspace(x->str_charset,s[x_len-1])) x_len--; - while (y_len && isspace(t[y_len-1])) + while (y_len && my_isspace(x->str_charset,t[y_len-1])) y_len--; #endif - return my_strnncoll(default_charset_info, + return my_strnncoll(x->str_charset, (unsigned char *)s,x_len,(unsigned char *)t,y_len); } else @@ -454,9 +525,10 @@ int sortcmp(const String *x,const String *y) y_len-=len; while (len--) { - if (my_sort_order[(uchar) *s++] != my_sort_order[(uchar) *t++]) - return ((int) my_sort_order[(uchar) s[-1]] - - (int) my_sort_order[(uchar) t[-1]]); + 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]]); } #ifndef CMP_ENDSPACE /* Don't compare end space in strings */ @@ -465,14 +537,14 @@ int sortcmp(const String *x,const String *y) { const char *end=t+y_len; for (; t != end ; t++) - if (!isspace(*t)) + if (!my_isspace(x->str_charset,*t)) return -1; } else { const char *end=s+x_len; for (; s != end ; s++) - if (!isspace(*s)) + if (!my_isspace(x->str_charset,*s)) return 1; } return 0; @@ -520,11 +592,10 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length) /* Make it easier to handle different charactersets */ #ifdef USE_MB -#define INC_PTR(A,B) A+=((use_mb_flag && \ - my_ismbchar(default_charset_info,A,B)) ? \ - my_ismbchar(default_charset_info,A,B) : 1) +#define INC_PTR(cs,A,B) A+=((use_mb_flag && \ + my_ismbchar(cs,A,B)) ? my_ismbchar(cs,A,B) : 1) #else -#define INC_PTR(A,B) A++ +#define INC_PTR(cs,A,B) A++ #endif /* @@ -535,18 +606,18 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length) */ #ifdef LIKE_CMP_TOUPPER -#define likeconv(A) (uchar) toupper(A) +#define likeconv(s,A) (uchar) my_toupper(s,A) #else -#define likeconv(A) (uchar) my_sort_order[(uchar) (A)] +#define likeconv(s,A) (uchar) (s)->sort_order[(uchar) (A)] #endif -static int wild_case_compare(const char *str,const char *str_end, - const char *wildstr,const char *wildend, - char escape) +int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *str_end, + const char *wildstr,const char *wildend, + char escape) { int result= -1; // Not found, using wildcards #ifdef USE_MB - bool use_mb_flag=use_mb(default_charset_info); + bool use_mb_flag=use_mb(cs); #endif while (wildstr != wildend) { @@ -557,7 +628,7 @@ static int wild_case_compare(const char *str,const char *str_end, #ifdef USE_MB int l; if (use_mb_flag && - (l = my_ismbchar(default_charset_info, wildstr, wildend))) + (l = my_ismbchar(cs, wildstr, wildend))) { if (str+l > str_end || memcmp(str, wildstr, l) != 0) return 1; @@ -566,7 +637,7 @@ static int wild_case_compare(const char *str,const char *str_end, } else #endif - if (str == str_end || likeconv(*wildstr++) != likeconv(*str++)) + if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++)) return(1); // No match if (wildstr == wildend) return (str != str_end); // Match if both are at end @@ -576,9 +647,9 @@ static int wild_case_compare(const char *str,const char *str_end, { do { - if (str == str_end) // Skipp one char if possible + if (str == str_end) // Skip one char if possible return (result); - INC_PTR(str,str_end); + INC_PTR(cs,str,str_end); } while (++wildstr < wildend && *wildstr == wild_one); if (wildstr == wildend) break; @@ -595,7 +666,7 @@ static int wild_case_compare(const char *str,const char *str_end, { if (str == str_end) return (-1); - INC_PTR(str,str_end); + INC_PTR(cs,str,str_end); continue; } break; // Not a wild character @@ -613,10 +684,10 @@ static int wild_case_compare(const char *str,const char *str_end, int mblen; LINT_INIT(mblen); if (use_mb_flag) - mblen = my_ismbchar(default_charset_info, wildstr, wildend); + mblen = my_ismbchar(cs, wildstr, wildend); #endif - INC_PTR(wildstr,wildend); // This is compared trough cmp - cmp=likeconv(cmp); + INC_PTR(cs,wildstr,wildend); // This is compared trough cmp + cmp=likeconv(cs,cmp); do { #ifdef USE_MB @@ -634,26 +705,26 @@ static int wild_case_compare(const char *str,const char *str_end, break; } } - else if (!my_ismbchar(default_charset_info, str, str_end) && - likeconv(*str) == cmp) + else if (!my_ismbchar(cs, str, str_end) && + likeconv(cs,*str) == cmp) { str++; break; } - INC_PTR(str, str_end); + INC_PTR(cs,str, str_end); } } else { #endif /* USE_MB */ - while (str != str_end && likeconv(*str) != cmp) + while (str != str_end && likeconv(cs,*str) != cmp) str++; if (str++ == str_end) return (-1); #ifdef USE_MB } #endif { - int tmp=wild_case_compare(str,str_end,wildstr,wildend,escape); + int tmp=wild_case_compare(cs,str,str_end,wildstr,wildend,escape); if (tmp <= 0) return (tmp); } @@ -667,17 +738,23 @@ static int wild_case_compare(const char *str,const char *str_end, int wild_case_compare(String &match,String &wild, char escape) { - return wild_case_compare(match.ptr(),match.ptr()+match.length(), - wild.ptr(), wild.ptr()+wild.length(),escape); + DBUG_ENTER("wild_case_compare"); + DBUG_PRINT("enter",("match='%s', wild='%s', escape='%c'" + ,match.ptr(),wild.ptr(),escape)); + DBUG_RETURN(wild_case_compare(match.str_charset,match.ptr(),match.ptr()+match.length(), + wild.ptr(), wild.ptr()+wild.length(),escape)); } /* ** The following is used when using LIKE on binary strings */ -static int wild_compare(const char *str,const char *str_end, - const char *wildstr,const char *wildend,char escape) +int wild_compare(const char *str,const char *str_end, + const char *wildstr,const char *wildend,char escape) { + DBUG_ENTER("wild_compare"); + DBUG_PRINT("enter",("str='%s', str_end='%s', wildstr='%s', wildend='%s', escape='%c'" + ,str,str_end,wildstr,wildend,escape)); int result= -1; // Not found, using wildcards while (wildstr != wildend) { @@ -686,17 +763,21 @@ static int wild_compare(const char *str,const char *str_end, if (*wildstr == escape && wildstr+1 != wildend) wildstr++; if (str == str_end || *wildstr++ != *str++) - return(1); + { + DBUG_RETURN(1); + } if (wildstr == wildend) - return (str != str_end); // Match if both are at end + { + DBUG_RETURN(str != str_end); // Match if both are at end + } result=1; // Found an anchor char } if (*wildstr == wild_one) { do { - if (str == str_end) // Skipp one char if possible - return (result); + if (str == str_end) // Skip one char if possible + DBUG_RETURN(result); str++; } while (*++wildstr == wild_one && wildstr != wildend); if (wildstr == wildend) @@ -713,17 +794,22 @@ static int wild_compare(const char *str,const char *str_end, if (*wildstr == wild_one) { if (str == str_end) - return (-1); + { + DBUG_RETURN(-1); + } str++; continue; } break; // Not a wild character } if (wildstr == wildend) - return(0); // Ok if wild_many is last + { + DBUG_RETURN(0); // Ok if wild_many is last + } if (str == str_end) - return -1; - + { + DBUG_RETURN(-1); + } char cmp; if ((cmp= *wildstr) == escape && wildstr+1 != wildend) cmp= *++wildstr; @@ -732,22 +818,32 @@ static int wild_compare(const char *str,const char *str_end, { while (str != str_end && *str != cmp) str++; - if (str++ == str_end) return (-1); + if (str++ == str_end) + { + DBUG_RETURN(-1); + } { int tmp=wild_compare(str,str_end,wildstr,wildend,escape); if (tmp <= 0) - return (tmp); + { + DBUG_RETURN(tmp); + } } } while (str != str_end && wildstr[0] != wild_many); - return(-1); + DBUG_RETURN(-1); } } - return (str != str_end ? 1 : 0); + DBUG_RETURN(str != str_end ? 1 : 0); } int wild_compare(String &match,String &wild, char escape) { - return wild_compare(match.ptr(),match.ptr()+match.length(), - wild.ptr(), wild.ptr()+wild.length(),escape); + DBUG_ENTER("wild_compare"); + DBUG_PRINT("enter",("match='%s', wild='%s', escape='%c'" + ,match.ptr(),wild.ptr(),escape)); + DBUG_RETURN(wild_compare(match.ptr(),match.ptr()+match.length(), + wild.ptr(), wild.ptr()+wild.length(),escape)); } + + diff --git a/client/sql_string.h b/client/sql_string.h index cffe78936a0..811e49a0d02 100644 --- a/client/sql_string.h +++ b/client/sql_string.h @@ -24,31 +24,57 @@ #define NOT_FIXED_DEC 31 #endif +class String; +int sortcmp(const String *a,const String *b); +int stringcmp(const String *a,const String *b); +String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); +int wild_case_compare(String &match,String &wild,char escape); +int wild_compare(String &match,String &wild,char escape); + class String { char *Ptr; uint32 str_length,Alloced_length; bool alloced; + CHARSET_INFO *str_charset; public: String() - { Ptr=0; str_length=Alloced_length=0; alloced=0; } + { + Ptr=0; str_length=Alloced_length=0; alloced=0; + str_charset=default_charset_info; + } String(uint32 length_arg) - { alloced=0; Alloced_length=0; (void) real_alloc(length_arg); } + { + alloced=0; Alloced_length=0; (void) real_alloc(length_arg); + str_charset=default_charset_info; + } String(const char *str) - { Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0;} + { + Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0; + str_charset=default_charset_info; + } String(const char *str,uint32 len) - { Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0;} + { + Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0; + str_charset=default_charset_info; + } String(char *str,uint32 len) - { Ptr=(char*) str; Alloced_length=str_length=len; alloced=0;} + { + Ptr=(char*) str; Alloced_length=str_length=len; alloced=0; + str_charset=default_charset_info; + } String(const String &str) - { Ptr=str.Ptr ; str_length=str.str_length ; - Alloced_length=str.Alloced_length; alloced=0; } - + { + Ptr=str.Ptr ; str_length=str.str_length ; + Alloced_length=str.Alloced_length; alloced=0; + str_charset=str.str_charset; + } static void *operator new(size_t size) { return (void*) sql_alloc((uint) size); } static void operator delete(void *ptr_arg,size_t size) /*lint -e715 */ { sql_element_free(ptr_arg); } ~String() { free(); } + inline CHARSET_INFO *charset() const { return str_charset; } inline uint32 length() const { return str_length;} inline uint32 alloced_length() const { return Alloced_length;} inline char& operator [] (uint32 i) const { return Ptr[i]; } @@ -124,7 +150,7 @@ public: char *new_ptr; if (!(new_ptr=(char*) my_realloc(Ptr,arg_length,MYF(0)))) { - (void) my_free(Ptr,MYF(0)); + Alloced_length = 0; real_alloc(arg_length); } else @@ -153,6 +179,7 @@ public: bool append(const char *s,uint32 arg_length=0); bool append(IO_CACHE* file, uint32 arg_length); int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1 + int strstr_case(const String &s,uint32 offset=0); int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1 bool replace(uint32 offset,uint32 arg_length,const String &to); inline bool append(char chr) @@ -171,8 +198,8 @@ public: } bool fill(uint32 max_length,char fill); void strip_sp(); - inline void caseup() { ::caseup(Ptr,str_length); } - inline void casedn() { ::casedn(Ptr,str_length); } + inline void caseup() { my_caseup(str_charset,Ptr,str_length); } + inline void casedn() { my_casedn(str_charset,Ptr,str_length); } friend int sortcmp(const String *a,const String *b); friend int stringcmp(const String *a,const String *b); friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); @@ -180,4 +207,49 @@ public: friend int wild_compare(String &match,String &wild,char escape); uint32 numchars(); int charpos(int i,uint32 offset=0); + +// added by Holyfoot for "geometry" needs + int reserve(uint32 space_needed) + { + return realloc(str_length + space_needed); + } + int reserve(uint32 space_needed, uint32 grow_by); + +// these append operations do NOT check alloced memory +// q_*** methods writes values of parameters itself +// qs_*** methods writes string representation of value + void q_append(const char &c) + { + Ptr[str_length++] = c; + } + void q_append(const uint32 &n) + { + int4store(Ptr + str_length, n); + str_length += 4; + } + void q_append(double d) + { + float8store(Ptr + str_length, d); + str_length += 8; + } + void q_append(double *d) + { + float8store(Ptr + str_length, *d); + str_length += 8; + } + void q_append(const char *data, uint32 data_len) + { + memcpy(Ptr + str_length, data, data_len); + str_length += data_len; + } + + void WriteAtPosition(int position, uint32 value) + { + int4store(Ptr + position,value); + } + + void qs_append(const char *str); + void qs_append(double d); + void qs_append(double *d); + void qs_append(const char &c); }; |