summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorunknown <monty@hundin.mysql.fi>2002-04-13 15:34:39 +0300
committerunknown <monty@hundin.mysql.fi>2002-04-13 15:34:39 +0300
commitfdc446d0c621c3be38b5b11cc0e40308679fb996 (patch)
tree6bb12842fb04d64fa854f04ec3d07da1e1f7c48b /client
parent54373c16f8435db653ffbad55466e457eb816976 (diff)
parentadc7a375368892eac433e19aab29ecefcf867d4b (diff)
downloadmariadb-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.cc53
-rw-r--r--client/mysqldump.c11
-rw-r--r--client/mysqltest.c51
-rw-r--r--client/sql_string.cc206
-rw-r--r--client/sql_string.h94
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);
};