From 0c8b4f6509014cda011c42916c714d0f4619d35f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2002 13:03:38 +0400 Subject: [PATCH 1/5] new version of sql/gen_lex_hash.cc sql/gen_lex_hash.cc: new version --- sql/gen_lex_hash.cc | 790 +++++++++++++++++++------------------------- 1 file changed, 336 insertions(+), 454 deletions(-) diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 4da5496c201..0d92397b616 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -14,11 +14,68 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* + +The idea of presented algorithm see in +"The Art of Computer Programming" by Donald E. Knuth +Volume 3 "Sorting and searching" +(chapter 6.3 "Digital searching" - name and number of chapter + is back translation from Russian edition :)) + +as illustration of data structures, imagine next table: + +static SYMBOL symbols[] = { + { "ADD", SYM(ADD),0,0}, + { "AND", SYM(AND),0,0}, + { "DAY", SYM(DAY_SYM),0,0}, +}; + +for this structure, presented program generate next searching-structure: + ++-----------+-+-+-+ +| len |1|2|3| ++-----------+-+-+-+ +|first_char |0|0|a| +|last_char |0|0|d| +|link |0|0|+| + | + V + +----------+-+-+-+--+ + | 1 char|a|b|c|d | + +----------+-+-+-+--+ + |first_char|b|0|0|0 | + |last_char |n|0|0|-1| + |link |+|0|0|+ | + | | + | V + | symbols[2] ( "DAY" ) + V ++----------+--+-+-+-+-+-+-+-+-+-+--+ +| 2 char|d |e|f|j|h|i|j|k|l|m|n | ++----------+--+-+-+-+-+-+-+-+-+-+--+ +|first_char|0 |0|0|0|0|0|0|0|0|0|0 | +|last_char |-1|0|0|0|0|0|0|0|0|0|-1| +|link |+ |0|0|0|0|0|0|0|0|0|+ | + | | + V V + symbols[0] ( "ADD" ) symbols[1] ( "AND" ) + +for optimization, link is the 16-bit index in 'symbols' or 'sql_functions' +or search-array.. + +So, we can read full search-structure as 32-bit word + +TODO: +1. use instead to_upper_lex, special array + (substitute chars) without skip codes.. +2. try use reverse order of comparing.. + +*/ #define NO_YACC_SYMBOLS -#include -#include -#include +#include "my_global.h" +#include "my_sys.h" +#include "m_string.h" #ifndef __GNU_LIBRARY__ #define __GNU_LIBRARY__ // Skip warnings in getopt.h #endif @@ -26,348 +83,248 @@ #include "mysql_version.h" #include "lex.h" -my_bool opt_search; -int opt_verbose; -ulong opt_count; - -#define max_allowed_array 16000 // Don't generate bigger arrays than this -#define max_symbol 32767 // Use this for 'not found' -#define how_much_for_plus 8 // 2-8 -#define type_count 1 // 1-5 -#define char_table_count 5 -#define total_symbols (sizeof(symbols)/sizeof(SYMBOL) +\ - sizeof(sql_functions)/sizeof(SYMBOL)) - -#define how_much_and INT_MAX24 - -/* - The following only have to work with characters in the set - used by SQL commands -*/ - -#undef tolower -#define tolower(a) ((a) >= 'A' && (a) <= 'Z') ? ((a)- 'A' + 'a') : (a) - -static uint how_long_symbols,function_plus,function_mod,function_type; -static uint char_table[256]; -static uchar unique_length[256]; -static uchar bits[how_much_and/8+1]; -static uint primes[max_allowed_array+1]; -static ulong hash_results[type_count][how_much_for_plus+1][total_symbols]; -static ulong start_value=0; -static uint best_type; -static ulong best_t1,best_t2, best_start_value; - static struct my_option my_long_options[] = { {"help", '?', "Display help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"count", 'c', "Try count times to find a optimal hash table", - (gptr*) &opt_count, (gptr*) &opt_count, 0, GET_ULONG, REQUIRED_ARG, - 100000, 0, 0, 0, 0, 0}, - {"search", 'S', "Search after good rnd1 and rnd2 values", - (gptr*) &opt_search, (gptr*) &opt_search, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, - 0, 0}, - {"verbose", 'v', "Write some information while the program executes", - (gptr*) &opt_verbose, (gptr*) &opt_verbose, 0, GET_INT, NO_ARG, 0, 0, 0, - 0, 0, 0}, {"version", 'V', "Output version information and exit", 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} }; -struct rand_struct { - unsigned long seed1,seed2,max_value; - double max_value_dbl; +struct hash_lex_struct +{ + char first_char; + char last_char; + union{ + hash_lex_struct *char_tails; + int iresult; + }; + int ithis; +}; + +hash_lex_struct *get_hash_struct_by_len(hash_lex_struct **root_by_len, + int len, int *max_len) +{ + if (*max_lenfirst_char= 0; + *max_len= len; + } + return (*root_by_len)+(len-1); +} + +void insert_into_hash(hash_lex_struct *root, const char *name, + int len_from_begin, int index, int function) +{ + hash_lex_struct *end, *cur, *tails; + + if (!root->first_char){ + root->first_char= -1; + root->iresult= index; + return; + } + + if (root->first_char==-1){ + int index2= root->iresult; + const char *name2= + (index2<0 ? sql_functions[-index2-1] : symbols[index2]).name + len_from_begin; + root->first_char= name2[0]; + root->last_char= root->first_char; + tails= (hash_lex_struct*)malloc(sizeof(hash_lex_struct)); + root->char_tails= tails; + tails->first_char= -1; + tails->iresult= index2; + } + + size_t real_size= (root->last_char-root->first_char+1); + + if (root->first_char>(*name)){ + size_t new_size= root->last_char-(*name)+1; + if (new_sizechar_tails; + tails= (hash_lex_struct*)realloc((char*)tails, + sizeof(hash_lex_struct)*new_size); + root->char_tails= tails; + memmove(tails+(new_size-real_size),tails,real_size*sizeof(hash_lex_struct)); + end= tails + new_size - real_size; + for (cur= tails; curfirst_char= 0; + root->first_char= (*name); + } + + if (root->last_char<(*name)){ + size_t new_size= (*name)-root->first_char+1; + if (new_sizechar_tails; + tails= (hash_lex_struct*)realloc((char*)tails, + sizeof(hash_lex_struct)*new_size); + root->char_tails= tails; + end= tails + new_size; + for (cur= tails+real_size; curfirst_char= 0; + root->last_char= (*name); + } + + insert_into_hash (root->char_tails+(*name)-root->first_char, + name+1,len_from_begin+1,index,function); +} + +hash_lex_struct *root_by_len= 0; +int max_len=0; + +hash_lex_struct *root_by_len2= 0; +int max_len2=0; + +void insert_symbols() +{ + size_t i= 0; + SYMBOL *cur; + for (cur= symbols; ilength,&max_len); + insert_into_hash(root,cur->name,0,i,0); + } +} + +void insert_sql_functions() +{ + size_t i= 0; + SYMBOL *cur; + for (cur= sql_functions; ilength,&max_len); + insert_into_hash(root,cur->name,0,-i-1,1); + } +} + +void generate_find_structs() +{ + root_by_len= 0; + max_len=0; + size_t i; + + SYMBOL *cur, *end= symbols + array_elements(symbols); + for (cur= symbols; cur < end; cur++) + cur->length=(uchar) strlen(cur->name); + end= sql_functions + array_elements(sql_functions); + for (cur= sql_functions; curlength=(uchar) strlen(cur->name); + + insert_symbols(); + + root_by_len2= root_by_len; + max_len2= max_len; + + root_by_len= 0; + max_len= 0; + + insert_symbols(); + insert_sql_functions(); +} + +char *hash_map= 0; +int size_hash_map= 0; + +void add_struct_to_map(hash_lex_struct *st) +{ + st->ithis= size_hash_map/4; + size_hash_map+= 4; + hash_map= (char*)realloc((char*)hash_map,size_hash_map); + hash_map[size_hash_map-4]= st->first_char==-1 ? 0 : st->first_char; + hash_map[size_hash_map-3]= + st->first_char==-1 || st->first_char==0 ? 0 : st->last_char; + if (st->first_char==-1) + { + hash_map[size_hash_map-2]= ((unsigned int)(int16)st->iresult)&255; + hash_map[size_hash_map-1]= ((unsigned int)(int16)st->iresult)>>8; + } + else if (st->first_char==0) + { + hash_map[size_hash_map-2]= ((unsigned int)(int16)array_elements(symbols))&255; + hash_map[size_hash_map-1]= ((unsigned int)(int16)array_elements(symbols))>>8; + } }; -void randominit(struct rand_struct *rand_st,ulong seed1, ulong seed2) -{ /* For mysql 3.21.# */ - rand_st->max_value= 0x3FFFFFFFL; - rand_st->max_value_dbl=(double) rand_st->max_value; - rand_st->seed1=seed1%rand_st->max_value ; - rand_st->seed2=seed2%rand_st->max_value; +void add_structs_to_map(hash_lex_struct *st, int len) +{ + hash_lex_struct *cur, *end= st+len; + for (cur= st; curfirst_char && cur->first_char!=-1) + add_structs_to_map(cur->char_tails,cur->last_char-cur->first_char+1); } -double rnd(struct rand_struct *rand_st) +void set_links(hash_lex_struct *st, int len) { - rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value; - rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value; - return (((double) rand_st->seed1)/rand_st->max_value_dbl); + hash_lex_struct *cur, *end= st+len; + for (cur= st; curfirst_char!=0 && cur->first_char!=-1){ + int ilink= cur->char_tails->ithis; + hash_map[cur->ithis*4+2]= ilink%256; + hash_map[cur->ithis*4+3]= ilink/256; + set_links(cur->char_tails,cur->last_char-cur->first_char+1); + } } - -static void make_char_table(ulong t1,ulong t2,int type) +void print_hash_map(const char *name) { - uint i; - struct rand_struct rand_st; - randominit(&rand_st,t1,t2); - - for (i=0 ; i < 256 ; i++) - { - switch (type) { - case 0: char_table[i]= i + (i << 8); break; - case 1: char_table[i]= i + ((i ^255 ) << 8); break; - case 2: char_table[i]= i; break; - case 3: char_table[i]= i + ((uint) (rnd(&rand_st)*255) << 8); break; - case 4: char_table[i]= (uint) (rnd(&rand_st)*255) + (i << 8); break; + printf("uchar %s[%d]= {\n",name,size_hash_map); + char *cur; + int i; + for (i=0, cur= hash_map; i 0) - { - switch (type) { - case 0: - nr= (nr ^ (char_table[(uchar) *s] + (nr << add))); - break; - case 1: - nr= (nr + (char_table[(uchar) *s] + (nr << add))); - break; - case 2: - nr= (nr ^ (char_table[(uchar) *s] ^ (nr << add))); - break; - case 3: - nr= (char_table[(uchar) *s] ^ (nr << add)); - break; - case 4: - nr+= nr+nr+((nr & 63)+pos)*((ulong) char_table[(uchar) *s]); - pos+=add; - break; - } - } - return nr & INT_MAX24; -} - -static int search(bool write_warning) -{ - uint size_symbols = sizeof(symbols)/sizeof(SYMBOL); - uint size_functions = sizeof(sql_functions)/sizeof(SYMBOL); - uint size=size_symbols + size_functions; - uint i=0,found,*prime,type; - int igra[max_allowed_array],test_count=INT_MAX; - uint possible_plus[how_much_for_plus*type_count+type_count]; - - how_long_symbols = sizeof(symbols)/sizeof(SYMBOL); - - bzero((char*) possible_plus,sizeof(possible_plus)); - found=0; - - /* Check first which function_plus are possible */ - for (type=0 ; type < type_count ; type ++) - { - for (function_plus = 1; - function_plus <= how_much_for_plus; - function_plus++) - { - bzero((char*) bits,sizeof(bits)); - for (i=0; i < size; i++) - { - ulong order= tab_index_function ((i < how_long_symbols) ? - symbols[i].name : - sql_functions[i-how_long_symbols].name, - function_plus, type); - hash_results[type][function_plus][i]=order; - uint pos=order/8; - uint bit=order & 7; - if (bits[pos] & (1 << bit)) - break; - bits[pos]|=1 << bit; - } - if (i == size) - { - possible_plus[found++]=function_plus; - } - } - possible_plus[found++]=0; // End marker - } - if (found == type_count) - { - if (write_warning) - fprintf(stderr,"\ -The hash function didn't return a unique value for any parameter\n\ -You have to change gen_lex_code.cc, function 'tab_index_function' to\n\ -generate unique values for some parameter. When you have succeeded in this,\n\ -you have to change 'main' to print out the new function\n"); - return(1); - } - - if (opt_verbose > 1) - fprintf (stderr,"Info: Possible add values: %d\n",found-type_count); - - for (prime=primes; (function_mod=*prime) ; prime++) - { - uint *plus_ptr=possible_plus; - for (type=0 ; type < type_count ; type++ ) - { - while ((function_plus= *plus_ptr++)) - { - ulong *order_pos= &hash_results[type][function_plus][0]; - if (test_count++ == INT_MAX) - { - test_count=1; - bzero((char*) igra,sizeof(igra)); - } - for (i=0; i= 1) { - fprintf(stderr,"%s: Too many arguments\n", my_progname); usage(0); - exit(1); + exit(1); } return(0); } -static uint max_prefix(const char *name) -{ - uint i; - uint max_length=1; - for (i=0 ; i < sizeof(symbols)/sizeof(SYMBOL) ; i++) - { - const char *str=symbols[i].name; - if (str != name) - { - const char *str2=name; - uint length; - while (*str && *str == *str2) - { - str++; - str2++; - } - length=(uint) (str2 - name)+1; - if (length > max_length) - max_length=length; - } - } - for (i=0 ; i < sizeof(sql_functions)/sizeof(SYMBOL) ; i++) - { - const char *str=sql_functions[i].name; - if (str != name) - { - const char *str2=name; - uint length; - while (*str && *str == *str2) - { - str++; - str2++; - } - length=(uint) (str2 - name)+1; - if (length > max_length) - max_length=length; - } - } - return max_length; -} - - -static void make_max_length_table(void) -{ - uint i; - for (i=0 ; i < sizeof(symbols)/sizeof(SYMBOL) ; i++) - { - uint length=max_prefix(symbols[i].name); - if (length > unique_length[(uchar) symbols[i].name[0]]) - { - unique_length[(uchar) symbols[i].name[0]]=length; - unique_length[(uchar) tolower(symbols[i].name[0])]=length; - } - } - for (i=0 ; i < sizeof(sql_functions)/sizeof(SYMBOL) ; i++) - { - uint length=max_prefix(sql_functions[i].name); - if (length > unique_length[(uchar) sql_functions[i].name[0]]) - { - unique_length[(uchar) sql_functions[i].name[0]]=length; - unique_length[(uchar) tolower(sql_functions[i].name[0])]=length; - } - } -} - - int main(int argc,char **argv) { - struct rand_struct rand_st; - static uint best_mod,best_add,best_functype; - int error; - MY_INIT(argv[0]); - start_value=2925024L; best_t1=654916L; best_t2=1723390L; best_type=3; /* mode=4943 add=1 type: 0 */ + if (get_options(argc,(char **) argv)) exit(1); - make_max_length_table(); - make_char_table(best_t1,best_t2,best_type); - make_prime_array(sizeof(symbols)/sizeof(SYMBOL) + - sizeof(sql_functions)/sizeof(SYMBOL)); - - if ((error=search(1)) > 0 || error && !opt_search) - exit(1); // This should work - best_mod=function_mod; best_add=function_plus; best_functype=function_type; - - if (opt_search) - { - time_t start_time=time((time_t*) 0); - randominit(&rand_st,start_time,start_time/2); // Some random values - printf("start_value=%ldL; best_t1=%ldL; best_t2=%ldL; best_type=%d; /* mode=%d add=%d type: %d */\n", - start_value, best_t1,best_t2,best_type,best_mod,best_add, - best_functype); - best_start_value=start_value; - for (uint i=1 ; i <= opt_count ; i++) - { - if (i % 10 == 0) - { - putchar('.'); - fflush(stdout); - } - ulong t1=(ulong) (rnd(&rand_st)*INT_MAX24); - ulong t2=(ulong) (rnd(&rand_st)*INT_MAX24); - uint type=(int) (rnd(&rand_st)*char_table_count); - start_value=(ulong) (rnd(&rand_st)*INT_MAX24); - make_char_table(t1,t2,type); - if (!search(0)) - { - best_mod=function_mod; best_add=function_plus; - best_functype=function_type; - best_t1=t1; best_t2=t2; best_type=type; - best_start_value=start_value; - printf("\nstart_value=%ldL; best_t1=%ldL; best_t2=%ldL; best_type=%d; /* mode=%d add=%d type: %d */\n", - best_start_value,best_t1,best_t2,best_type,best_mod,best_add, - best_functype); - } - if (opt_verbose && (i % 20000) == 0) - printf("\nstart_value=%ldL; best_t1=%ldL; best_t2=%ldL; best_type=%d; /* mode=%d add=%d type: %d */\n", - best_start_value,best_t1,best_t2,best_type,best_mod,best_add, - best_functype); - } - } - - function_mod=best_mod; function_plus=best_add; - make_char_table(best_t1,best_t2,best_type); - printf("/* Copyright (C) 2001 MySQL AB\n\ This program is free software; you can redistribute it and/or modify\n\ it under the terms of the GNU General Public License as published by\n\ @@ -533,38 +369,84 @@ int main(int argc,char **argv) GNU General Public License for more details.\n\n\ You should have received a copy of the GNU General Public License\n\ along with this program; if not, write to the Free Software\n\ - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */\n\n"); + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307\ + USA */\n\n"); -printf("/* This code is generated by gen_lex_hash.cc that seeks for a perfect\nhash function */\n\n"); + printf("/* This code is generated by gen_lex_hash.cc that seeks for\ + a perfect\nhash function */\n\n"); printf("#include \"lex.h\"\n\n"); - print_arrays(); + generate_find_structs(); + print_find_structs(); - printf("/* start_value=%ldL; best_t1=%ldL; best_t2=%ldL; best_type=%d; */ /* mode=%d add=%d type: %d */\n\n", - best_start_value, best_t1, best_t2, best_type, - best_mod, best_add, best_functype); + printf("\nunsigned int sql_functions_max_len=%d;\n",max_len); + printf("\nunsigned int symbols_max_len=%d;\n\n",max_len2); - printf("inline SYMBOL *get_hash_symbol(const char *s,unsigned int length,bool function)\n\ + printf +( +"inline SYMBOL *get_hash_symbol(const char *s,\n\ + unsigned int len,bool function)\n\ {\n\ - ulong idx = %lu+char_table[(uchar) *s];\n\ - SYMBOL *sim;\n\ - const char *start=s;\n\ - int i=unique_length[(uchar) *s++];\n\ - if (i > (int) length) i=(int) length;\n\ - while (--i > 0)\n\ - idx= (idx ^ (char_table[(uchar) *s++] + (idx << %d)));\n\ - idx=my_function_table[(idx & %d) %% %d];\n\ - if (idx >= %d)\n\ - {\n\ - if (!function || idx >= %d) return (SYMBOL*) 0;\n\ - sim=sql_functions + (idx - %d);\n\ + register uchar *hash_map;\n\ + register const char *cur_str= s;\n\ + if (function){\n\ + if (len>sql_functions_max_len) return 0;\n\ + hash_map= sql_functions_map;\n\ + register uint32 cur_struct= uint4korr(hash_map+((len-1)*4));\n\ +\n\ + for(;;){\n\ + register uchar first_char= (uchar)cur_struct;\n\ +\n\ + if (first_char==0){\n\ + register int16 ires= (int16)(cur_struct>>16);\n\ + if (ires==array_elements(symbols)) return 0;\n\ + register SYMBOL *res;\n\ + if (ires>=0) \n\ + res= symbols+ires;\n\ + else\n\ + res= sql_functions-ires-1;\n\ + register uint count= cur_str-s;\n\ + return lex_casecmp(cur_str,res->name+count,len-count) ? 0 : res;\n\ + }\n\ +\n\ + register uchar cur_char= (uchar)to_upper_lex[(uchar)*cur_str];\n\ + if (cur_char>=8;\n\ + if (cur_char>(uchar)cur_struct) return 0;\n\ +\n\ + cur_struct>>=8;\n\ + cur_struct= uint4korr(hash_map+\n\ + (((uint16)cur_struct + cur_char - first_char)*4));\n\ + cur_str++;\n\ + }\n\ + }else{\n\ + if (len>symbols_max_len) return 0;\n\ + hash_map= symbols_map;\n\ + register uint32 cur_struct= uint4korr(hash_map+((len-1)*4));\n\ +\n\ + for(;;){\n\ + register uchar first_char= (uchar)cur_struct;\n\ +\n\ + if (first_char==0){\n\ + register int16 ires= (int16)(cur_struct>>16);\n\ + if (ires==array_elements(symbols)) return 0;\n\ + register SYMBOL *res= symbols+ires;\n\ + register uint count= cur_str-s;\n\ + return lex_casecmp(cur_str,res->name+count,len-count)!=0 ? 0 : res;\n\ + }\n\ +\n\ + register uchar cur_char= (uchar)to_upper_lex[(uchar)*cur_str];\n\ + if (cur_char>=8;\n\ + if (cur_char>(uchar)cur_struct) return 0;\n\ +\n\ + cur_struct>>=8;\n\ + cur_struct= uint4korr(hash_map+\n\ + (((uint16)cur_struct + cur_char - first_char)*4));\n\ + cur_str++;\n\ + }\n\ }\n\ - else\n\ - sim=symbols + idx;\n\ - if ((length != sim->length) || lex_casecmp(start,sim->name,length))\n\ - return (SYMBOL *)0;\n\ - return sim;\n\ -}\n",(ulong) start_value,(int) function_plus,(int) how_much_and,function_mod,how_long_symbols,max_symbol,how_long_symbols); - exit(0); - return 0; +}\n" +); } + From b0b72e4d52d525b82f9649cc7d57d647950ec59b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2002 15:49:53 +0400 Subject: [PATCH 2/5] Item->thd_charset() - returns a default charset which should be used to compose strings appeared without charset context, for example, in convertion from numer into string type. --- sql/field.cc | 4 ++-- sql/item.cc | 19 ++++++++++++------- sql/item.h | 1 + sql/item_func.cc | 34 +++++++++++++++++----------------- sql/item_strfunc.cc | 2 +- sql/item_subselect.cc | 2 +- sql/item_sum.cc | 16 ++++++++-------- sql/item_timefunc.h | 18 +++++++++--------- sql/sql_analyse.cc | 4 ++-- 9 files changed, 53 insertions(+), 47 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index d8742d487f9..a219a23ec70 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4316,14 +4316,14 @@ int Field_blob::store(const char *from,uint len,CHARSET_INFO *cs) int Field_blob::store(double nr) { - value.set(nr,2,my_thd_charset); + value.set(nr,2,current_thd->thd_charset); return Field_blob::store(value.ptr(),(uint) value.length(), value.charset()); } int Field_blob::store(longlong nr) { - value.set(nr,my_thd_charset); + value.set(nr,current_thd->thd_charset); return Field_blob::store(value.ptr(), (uint) value.length(), value.charset()); } diff --git a/sql/item.cc b/sql/item.cc index 037e57b2b8a..d97f8dc4b71 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -117,6 +117,11 @@ bool Item::get_time(TIME *ltime) return 0; } +CHARSET_INFO * Item::thd_charset() const +{ + return current_thd->thd_charset; +} + Item_field::Item_field(Field *f) :Item_ident(NullS,f->table_name,f->field_name) { set_field(f); @@ -234,7 +239,7 @@ table_map Item_field::used_tables() const String *Item_int::val_str(String *str) { - str->set(value, my_thd_charset); + str->set(value, thd_charset()); return str; } @@ -242,7 +247,7 @@ void Item_int::print(String *str) { if (!name) { - str_value.set(value, my_thd_charset); + str_value.set(value, thd_charset()); name=str_value.c_ptr(); } str->append(name); @@ -250,7 +255,7 @@ void Item_int::print(String *str) String *Item_uint::val_str(String *str) { - str->set((ulonglong) value, my_thd_charset); + str->set((ulonglong) value, thd_charset()); return str; } @@ -258,7 +263,7 @@ void Item_uint::print(String *str) { if (!name) { - str_value.set((ulonglong) value, my_thd_charset); + str_value.set((ulonglong) value, thd_charset()); name=str_value.c_ptr(); } str->append(name); @@ -267,7 +272,7 @@ void Item_uint::print(String *str) String *Item_real::val_str(String *str) { - str->set(value,decimals,my_thd_charset); + str->set(value,decimals,thd_charset()); return str; } @@ -384,10 +389,10 @@ String *Item_param::val_str(String* str) { switch (item_result_type) { case INT_RESULT: - str->set(int_value, my_thd_charset); + str->set(int_value, thd_charset()); return str; case REAL_RESULT: - str->set(real_value, 2, my_thd_charset); + str->set(real_value, 2, thd_charset()); return str; default: return (String*) &str_value; diff --git a/sql/item.h b/sql/item.h index fc36148e443..c7c66102b43 100644 --- a/sql/item.h +++ b/sql/item.h @@ -84,6 +84,7 @@ public: virtual bool get_date(TIME *ltime,bool fuzzydate); virtual bool get_time(TIME *ltime); virtual bool is_null() { return 0; }; + virtual CHARSET_INFO *thd_charset() const; virtual CHARSET_INFO *charset() const { return str_value.charset(); }; virtual bool binary() const { return str_value.charset()->state & MY_CS_BINSORT ? 1 : 0 ; } virtual void set_charset(CHARSET_INFO *cs) { str_value.set_charset(cs); } diff --git a/sql/item_func.cc b/sql/item_func.cc index 8b2b2fc83a3..6cb98d4ed90 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -243,7 +243,7 @@ String *Item_real_func::val_str(String *str) if (null_value) return 0; /* purecov: inspected */ else - str->set(nr,decimals,my_thd_charset); + str->set(nr,decimals,thd_charset()); return str; } @@ -256,9 +256,9 @@ String *Item_num_func::val_str(String *str) if (null_value) return 0; /* purecov: inspected */ else if (!unsigned_flag) - str->set(nr,my_thd_charset); + str->set(nr,thd_charset()); else - str->set((ulonglong) nr,my_thd_charset); + str->set((ulonglong) nr,thd_charset()); } else { @@ -266,7 +266,7 @@ String *Item_num_func::val_str(String *str) if (null_value) return 0; /* purecov: inspected */ else - str->set(nr,decimals,my_thd_charset); + str->set(nr,decimals,thd_charset()); } return str; } @@ -286,9 +286,9 @@ String *Item_int_func::val_str(String *str) if (null_value) return 0; else if (!unsigned_flag) - str->set(nr,my_thd_charset); + str->set(nr,thd_charset()); else - str->set((ulonglong) nr,my_thd_charset); + str->set((ulonglong) nr,thd_charset()); return str; } @@ -315,9 +315,9 @@ String *Item_num_op::val_str(String *str) if (null_value) return 0; /* purecov: inspected */ else if (!unsigned_flag) - str->set(nr,my_thd_charset); + str->set(nr,thd_charset()); else - str->set((ulonglong) nr,my_thd_charset); + str->set((ulonglong) nr,thd_charset()); } else { @@ -325,7 +325,7 @@ String *Item_num_op::val_str(String *str) if (null_value) return 0; /* purecov: inspected */ else - str->set(nr,decimals,my_thd_charset); + str->set(nr,decimals,thd_charset()); } return str; } @@ -813,9 +813,9 @@ String *Item_func_min_max::val_str(String *str) if (null_value) return 0; else if (!unsigned_flag) - str->set(nr,my_thd_charset); + str->set(nr,thd_charset()); else - str->set((ulonglong) nr,my_thd_charset); + str->set((ulonglong) nr,thd_charset()); return str; } case REAL_RESULT: @@ -824,7 +824,7 @@ String *Item_func_min_max::val_str(String *str) if (null_value) return 0; /* purecov: inspected */ else - str->set(nr,decimals,my_thd_charset); + str->set(nr,decimals,thd_charset()); return str; } case STRING_RESULT: @@ -1447,7 +1447,7 @@ String *Item_func_udf_float::val_str(String *str) if (null_value) return 0; /* purecov: inspected */ else - str->set(nr,decimals,my_thd_charset); + str->set(nr,decimals,thd_charset()); return str; } @@ -1468,9 +1468,9 @@ String *Item_func_udf_int::val_str(String *str) if (null_value) return 0; else if (!unsigned_flag) - str->set(nr,my_thd_charset); + str->set(nr,thd_charset()); else - str->set((ulonglong) nr,my_thd_charset); + str->set((ulonglong) nr,thd_charset()); return str; } @@ -2034,10 +2034,10 @@ Item_func_get_user_var::val_str(String *str) return NULL; switch (entry->type) { case REAL_RESULT: - str->set(*(double*) entry->value,decimals,my_thd_charset); + str->set(*(double*) entry->value,decimals,thd_charset()); break; case INT_RESULT: - str->set(*(longlong*) entry->value,my_thd_charset); + str->set(*(longlong*) entry->value,thd_charset()); break; case STRING_RESULT: if (str->copy(entry->value, entry->length-1)) diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 20b01c9f1e8..40e9315d786 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1469,7 +1469,7 @@ String *Item_func_format::val_str(String *str) if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ dec= decimals ? decimals+1 : 0; - str->set(nr,decimals,my_thd_charset); + str->set(nr,decimals,thd_charset()); str_length=str->length(); if (nr < 0) str_length--; // Don't count sign diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index f45f386fe46..703173b191c 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -200,7 +200,7 @@ String *Item_exists_subselect::val_str(String *str) assign_null(); return 0; } - str->set(value,my_thd_charset); + str->set(value,thd_charset()); return str; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 22b5e47fab5..e28e878e57f 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -93,7 +93,7 @@ Item_sum_num::val_str(String *str) double nr=val(); if (null_value) return 0; - str->set(nr,decimals,my_thd_charset); + str->set(nr,decimals,thd_charset()); return str; } @@ -359,13 +359,13 @@ Item_sum_hybrid::val_str(String *str) case STRING_RESULT: return &value; case REAL_RESULT: - str->set(sum,decimals,my_thd_charset); + str->set(sum,decimals,thd_charset()); break; case INT_RESULT: if (unsigned_flag) - str->set((ulonglong) sum_int,my_thd_charset); + str->set((ulonglong) sum_int,thd_charset()); else - str->set((longlong) sum_int,my_thd_charset); + str->set((longlong) sum_int,thd_charset()); break; } return str; // Keep compiler happy @@ -810,7 +810,7 @@ String *Item_avg_field::val_str(String *str) double nr=Item_avg_field::val(); if (null_value) return 0; - str->set(nr,decimals,my_thd_charset); + str->set(nr,decimals,thd_charset()); return str; } @@ -847,7 +847,7 @@ String *Item_std_field::val_str(String *str) double nr=val(); if (null_value) return 0; - str->set(nr,decimals,my_thd_charset); + str->set(nr,decimals,thd_charset()); return str; } @@ -1177,7 +1177,7 @@ String *Item_sum_udf_float::val_str(String *str) if (null_value) return 0; /* purecov: inspected */ else - str->set(nr,decimals,my_thd_charset); + str->set(nr,decimals,thd_charset()); return str; } @@ -1196,7 +1196,7 @@ String *Item_sum_udf_int::val_str(String *str) if (null_value) return 0; else - str->set(nr,my_thd_charset); + str->set(nr,thd_charset()); return str; } diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index fab8ea9fa9c..de2860d24ef 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -69,7 +69,7 @@ public: double val() { return (double) Item_func_month::val_int(); } String *val_str(String *str) { - str->set(val_int(), my_thd_charset); + str->set(val_int(), thd_charset()); return null_value ? 0 : str; } const char *func_name() const { return "month"; } @@ -177,7 +177,7 @@ public: longlong val_int(); double val() { return (double) val_int(); } String *val_str(String *str) { - str->set(val_int(), my_thd_charset); + str->set(val_int(), thd_charset()); return null_value ? 0 : str; } const char *func_name() const { return "weekday"; } @@ -243,7 +243,7 @@ public: } Field *tmp_table_field(TABLE *t_arg) { - return (!t_arg) ? result_field : new Field_date(maybe_null, name, t_arg, my_thd_charset); + return (!t_arg) ? result_field : new Field_date(maybe_null, name, t_arg, thd_charset()); } }; @@ -261,7 +261,7 @@ public: Field *tmp_table_field(TABLE *t_arg) { return (!t_arg) ? result_field : new Field_datetime(maybe_null, name, - t_arg, my_thd_charset); + t_arg, thd_charset()); } }; @@ -288,7 +288,7 @@ public: Field *tmp_table_field(TABLE *t_arg) { return (!t_arg) ? result_field : - new Field_time(maybe_null, name, t_arg, my_thd_charset); + new Field_time(maybe_null, name, t_arg, thd_charset()); } }; @@ -381,7 +381,7 @@ public: Field *tmp_table_field(TABLE *t_arg) { return (!t_arg) ? result_field : - new Field_time(maybe_null, name, t_arg, my_thd_charset); + new Field_time(maybe_null, name, t_arg, thd_charset()); } }; @@ -446,7 +446,7 @@ public: Field *tmp_table_field(TABLE *t_arg) { return (!t_arg) ? result_field : - new Field_date(maybe_null, name, t_arg, my_thd_charset); + new Field_date(maybe_null, name, t_arg, thd_charset()); } }; @@ -462,7 +462,7 @@ public: Field *tmp_table_field(TABLE *t_arg) { return (!t_arg) ? result_field : - new Field_time(maybe_null, name, t_arg, my_thd_charset); + new Field_time(maybe_null, name, t_arg, thd_charset()); } }; @@ -478,6 +478,6 @@ public: Field *tmp_table_field(TABLE *t_arg) { return (!t_arg) ? result_field : new Field_datetime(maybe_null, name, - t_arg, my_thd_charset); + t_arg, thd_charset()); } }; diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index d1ecdd029d5..5c735ab35d5 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -896,14 +896,14 @@ int collect_real(double *element, element_count count __attribute__((unused)), TREE_INFO *info) { char buff[MAX_FIELD_WIDTH]; - String s(buff, sizeof(buff),default_charset_info); + String s(buff, sizeof(buff),current_thd->thd_charset); if (info->found) info->str->append(','); else info->found = 1; info->str->append('\''); - s.set(*element, info->item->decimals, my_thd_charset); + s.set(*element, info->item->decimals, current_thd->thd_charset); info->str->append(s); info->str->append('\''); return 0; From 6d7d19b860e0b3b9443b8059d36fb497029481d6 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2002 17:01:12 +0400 Subject: [PATCH 3/5] Some charset code clean-ups --- sql/field.h | 7 ++++--- sql/field_conv.cc | 6 ++---- sql/filesort.cc | 7 +++---- sql/ha_heap.cc | 2 +- sql/ha_myisam.cc | 3 +-- sql/item.cc | 18 ++++++++---------- sql/item.h | 12 ++++++------ sql/item_strfunc.cc | 2 +- sql/item_timefunc.cc | 38 +++++++++++++++++++------------------- sql/opt_range.cc | 2 +- sql/sql_prepare.cc | 4 ++-- sql/sql_select.cc | 4 +--- sql/table.cc | 3 +-- 13 files changed, 50 insertions(+), 58 deletions(-) diff --git a/sql/field.h b/sql/field.h index 6505b2c8462..685b2c95d1f 100644 --- a/sql/field.h +++ b/sql/field.h @@ -198,7 +198,8 @@ public: uint fill_cache_field(struct st_cache_field *copy); virtual bool get_date(TIME *ltime,bool fuzzydate); virtual bool get_time(TIME *ltime); - virtual CHARSET_INFO *charset(void) { return my_charset_bin; } + virtual CHARSET_INFO *charset(void) const { return my_charset_bin; } + virtual void set_charset(CHARSET_INFO *charset) { } friend bool reopen_table(THD *,struct st_table *,bool); friend int cre_myisam(my_string name, register TABLE *form, uint options, ulonglong auto_increment_value); @@ -260,9 +261,9 @@ public: uint decimals() const { return NOT_FIXED_DEC; } void make_field(Send_field *); uint size_of() const { return sizeof(*this); } - CHARSET_INFO *charset(void) { return field_charset; } + CHARSET_INFO *charset(void) const { return field_charset; } - inline void set_charset(CHARSET_INFO *charset) { field_charset=charset; } + void set_charset(CHARSET_INFO *charset) { field_charset=charset; } bool binary() const { return field_charset->state & MY_CS_BINSORT ? 1 : 0; } inline int cmp_image(char *buff,uint length) { diff --git a/sql/field_conv.cc b/sql/field_conv.cc index efb7401779c..ab71f324732 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -525,8 +525,7 @@ void field_conv(Field *to,Field *from) if (!blob->value.is_alloced() && from->real_type() != FIELD_TYPE_STRING) blob->value.copy(); - blob->store(blob->value.ptr(),blob->value.length(), - to->binary()?default_charset_info:((Field_str*)to)->charset()); + blob->store(blob->value.ptr(),blob->value.length(),to->charset()); return; } if ((from->result_type() == STRING_RESULT && @@ -538,8 +537,7 @@ void field_conv(Field *to,Field *from) char buff[MAX_FIELD_WIDTH]; String result(buff,sizeof(buff),default_charset_info); from->val_str(&result,&result); - to->store(result.c_ptr_quick(),result.length(), - to->binary()?default_charset_info:((Field_str*)to)->charset()); + to->store(result.c_ptr_quick(),result.length(),to->charset()); // QQ: what to do if "from" and "to" are of dirrent charsets? } else if (from->result_type() == REAL_RESULT) diff --git a/sql/filesort.cc b/sql/filesort.cc index 13c48b745cd..53af60b0370 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -75,7 +75,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, uchar **sort_keys; IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile; SORTPARAM param; - CHARSET_INFO *charset=table->table_charset; + CHARSET_INFO *charset=my_charset_bin; DBUG_ENTER("filesort"); DBUG_EXECUTE("info",TEST_filesort(sortorder,s_length);); #ifdef SKIP_DBUG_IN_FILESORT @@ -85,8 +85,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, // BAR TODO: this is not absolutely correct, but OK for now for(i=0;ifields;i++) if (!table->field[i]->binary()) - charset=((Field_str*)(table->field[i]))->charset(); - charset=charset?charset:default_charset_info; + charset=table->field[i]->charset(); // /BAR TODO outfile= table->io_cache; @@ -930,7 +929,7 @@ sortlength(SORT_FIELD *sortorder, uint s_length) #ifdef USE_STRCOLL if (!sortorder->field->binary()) { - CHARSET_INFO *cs=((Field_str*)(sortorder->field))->charset(); + CHARSET_INFO *cs=sortorder->field->charset(); if (use_strnxfrm(cs)) sortorder->length= sortorder->length*cs->strxfrm_multiply; } diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 6cfd3c881cc..c06421617dd 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -291,7 +291,7 @@ int ha_heap::create(const char *name, TABLE *table, seg->start= (uint) key_part->offset; seg->length= (uint) key_part->length; seg->flag = 0; - seg->charset= field->binary() ? NULL : ((Field_str*)field)->charset(); + seg->charset= field->charset(); if (field->null_ptr) { seg->null_bit= field->null_bit; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 64dbcfe2056..c7f0ccf69ee 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1078,8 +1078,7 @@ int ha_myisam::create(const char *name, register TABLE *table, keydef[i].seg[j].start= pos->key_part[j].offset; keydef[i].seg[j].length= pos->key_part[j].length; keydef[i].seg[j].bit_start=keydef[i].seg[j].bit_end=0; - keydef[i].seg[j].language = field->binary() ? MY_CHARSET_CURRENT : - ((Field_str*)field)->charset()->number; + keydef[i].seg[j].language = field->charset()->number; if (field->null_ptr) { diff --git a/sql/item.cc b/sql/item.cc index d97f8dc4b71..9c70dad045c 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -313,15 +313,15 @@ void Item_param::set_double(double value) } -void Item_param::set_value(const char *str, uint length) +void Item_param::set_value(const char *str, uint length, CHARSET_INFO *cs) { - str_value.set(str,length,default_charset_info); + str_value.set(str,length,cs); item_result_type = STRING_RESULT; item_type = STRING_ITEM; } -void Item_param::set_longdata(const char *str, ulong length) +void Item_param::set_longdata(const char *str, ulong length, CHARSET_INFO *cs) { /* TODO: Fix this for binary handling by making use of buffer_type.. @@ -346,10 +346,8 @@ int Item_param::save_in_field(Field *field) double nr=val(); return (field->store(nr)) ? -1 : 0; } - String *result; - CHARSET_INFO *cs=default_charset_info; //fix this - result=val_str(&str_value); - return (field->store(result->ptr(),result->length(),cs)) ? -1 : 0; + String *result=val_str(&str_value); + return (field->store(result->ptr(),result->length(),field->charset())) ? -1 : 0; } @@ -658,7 +656,7 @@ int Item::save_in_field(Field *field) field->result_type() == STRING_RESULT) { String *result; - CHARSET_INFO *cs=field->binary()?my_charset_bin:((Field_str*)field)->charset(); + CHARSET_INFO *cs=field->charset(); char buff[MAX_FIELD_WIDTH]; // Alloc buffer for small columns str_value.set_quick(buff,sizeof(buff),cs); result=val_str(&str_value); @@ -690,7 +688,7 @@ int Item::save_in_field(Field *field) int Item_string::save_in_field(Field *field) { String *result; - CHARSET_INFO *cs=field->binary()?my_charset_bin:((Field_str*)field)->charset(); + CHARSET_INFO *cs=field->charset(); result=val_str(&str_value); if (null_value) return set_field_to_null(field); @@ -763,7 +761,7 @@ longlong Item_varbinary::val_int() int Item_varbinary::save_in_field(Field *field) { int error; - CHARSET_INFO *cs=field->binary()?default_charset_info:((Field_str*)field)->charset(); + CHARSET_INFO *cs=field->charset(); field->set_notnull(); if (field->result_type() == STRING_RESULT) { diff --git a/sql/item.h b/sql/item.h index c7c66102b43..fb6bed75d51 100644 --- a/sql/item.h +++ b/sql/item.h @@ -196,14 +196,14 @@ public: void set_null(); void set_int(longlong i); void set_double(double i); - void set_value(const char *str, uint length); - void set_long_str(const char *str, ulong length); - void set_long_binary(const char *str, ulong length); - void set_longdata(const char *str, ulong length); - void set_long_end(); + void set_value(const char *str, uint length, CHARSET_INFO *cs); + void set_long_str(const char *str, ulong length, CHARSET_INFO *cs); + void set_long_binary(const char *str, ulong length, CHARSET_INFO *cs); + void set_longdata(const char *str, ulong length, CHARSET_INFO *cs); + void set_long_end(); void reset() {} enum Item_result result_type () const - { return item_result_type; } + { return item_result_type; } Item *new_item() { return new Item_param(name); } }; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 40e9315d786..f930afe14a2 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1637,7 +1637,7 @@ String *Item_func_char::val_str(String *str) int32 num=(int32) args[i]->val_int(); if (!args[i]->null_value) #ifdef USE_MB - if (use_mb(default_charset_info)) + if (use_mb(charset())) { if (num&0xFF000000L) { str->append((char)(num>>24)); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index b42b78c9c91..e81fecabe96 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -31,28 +31,28 @@ static String month_names[] = { - String("January", default_charset_info), - String("February", default_charset_info), - String("March", default_charset_info), - String("April", default_charset_info), - String("May", default_charset_info), - String("June", default_charset_info), - String("July", default_charset_info), - String("August", default_charset_info), - String("September", default_charset_info), - String("October", default_charset_info), - String("November", default_charset_info), - String("December", default_charset_info) + String("January", my_charset_latin1), + String("February", my_charset_latin1), + String("March", my_charset_latin1), + String("April", my_charset_latin1), + String("May", my_charset_latin1), + String("June", my_charset_latin1), + String("July", my_charset_latin1), + String("August", my_charset_latin1), + String("September", my_charset_latin1), + String("October", my_charset_latin1), + String("November", my_charset_latin1), + String("December", my_charset_latin1) }; static String day_names[] = { - String("Monday", default_charset_info), - String("Tuesday", default_charset_info), - String("Wednesday", default_charset_info), - String("Thursday", default_charset_info), - String("Friday", default_charset_info), - String("Saturday", default_charset_info), - String("Sunday", default_charset_info) + String("Monday", my_charset_latin1), + String("Tuesday", my_charset_latin1), + String("Wednesday", my_charset_latin1), + String("Thursday", my_charset_latin1), + String("Friday", my_charset_latin1), + String("Saturday", my_charset_latin1), + String("Sunday", my_charset_latin1) }; /* diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 39e6b83221d..9a644553f26 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -976,7 +976,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, &min_length,&max_length); else { - CHARSET_INFO *charset=((Field_str*)(field))->charset(); + CHARSET_INFO *charset=field->charset(); #ifdef USE_STRCOLL if (use_strnxfrm(charset)) like_error= my_like_range(charset, diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 2cf51f5d72e..08377a10501 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -271,7 +271,7 @@ static uchar* setup_param_field(Item_param *item_param, default: { ulong len=get_param_length(&pos); - item_param->set_value((const char*)pos,len); + item_param->set_value((const char*)pos,len,current_thd->thd_charset); pos+=len; } } @@ -829,7 +829,7 @@ void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length) sprintf(stmt->last_error, ER(ER_WRONG_ARGUMENTS), "get_longdata"); DBUG_VOID_RETURN; } - stmt->param[param_number].set_longdata(pos, packet_length-9); + stmt->param[param_number].set_longdata(pos, packet_length-9, current_thd->thd_charset); stmt->long_data_used= 1; DBUG_VOID_RETURN; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 93d48e3e1e0..20d9c1ca208 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4231,9 +4231,7 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param, { Field *field=keyinfo->key_part[i].field; seg->flag= 0; - seg->language= field->binary() ? MY_CHARSET_CURRENT : - ((Field_str*)field)->charset()->number; - + seg->language= field->charset()->number; seg->length= keyinfo->key_part[i].length; seg->start= keyinfo->key_part[i].offset; if (field->flags & BLOB_FLAG) diff --git a/sql/table.cc b/sql/table.cc index 6e2df849700..bad453f2cad 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -392,8 +392,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, outparam->fieldnames.type_names[i], outparam); reg_field->comment=comment; - if (!reg_field->binary()) - ((Field_str*) reg_field)->set_charset(charset); + reg_field->set_charset(charset); if (!(reg_field->flags & NOT_NULL_FLAG)) { if ((null_bit<<=1) == 256) From dedb5843256aa897147a2de4bfb37c87ffd0648d Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2002 17:43:22 +0400 Subject: [PATCH 4/5] String->copy() now has a charset arg --- sql/field.cc | 2 +- sql/field.h | 2 +- sql/item_func.cc | 5 ++--- sql/item_strfunc.cc | 12 +++++++----- sql/item_sum.cc | 2 +- sql/item_timefunc.cc | 4 ++-- sql/procedure.h | 2 +- sql/sql_string.cc | 7 ++++--- sql/sql_string.h | 2 +- 9 files changed, 20 insertions(+), 18 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index a219a23ec70..73ef4439bc9 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4302,7 +4302,7 @@ int Field_blob::store(const char *from,uint len,CHARSET_INFO *cs) } } #endif /* USE_TIS620 */ - value.copy(from,len); + value.copy(from,len,charset()); from=value.ptr(); #ifdef USE_TIS620 my_free(th_ptr,MYF(MY_ALLOW_ZERO_PTR)); diff --git a/sql/field.h b/sql/field.h index 685b2c95d1f..8c4c48968c4 100644 --- a/sql/field.h +++ b/sql/field.h @@ -887,7 +887,7 @@ public: inline bool copy() { char *tmp; get_ptr(&tmp); - if (value.copy(tmp,get_length())) + if (value.copy(tmp,get_length(),charset())) { Field_blob::reset(); return 1; diff --git a/sql/item_func.cc b/sql/item_func.cc index 6cb98d4ed90..543a96107dc 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1568,7 +1568,7 @@ void item_user_lock_release(ULL *ull) char buf[256]; const char *command="DO RELEASE_LOCK(\""; String tmp(buf,sizeof(buf), system_charset_info); - tmp.copy(command, strlen(command)); + tmp.copy(command, strlen(command), tmp.charset()); tmp.append(ull->key,ull->key_length); tmp.append("\")"); Query_log_event qev(current_thd,tmp.ptr(), tmp.length()); @@ -2040,12 +2040,11 @@ Item_func_get_user_var::val_str(String *str) str->set(*(longlong*) entry->value,thd_charset()); break; case STRING_RESULT: - if (str->copy(entry->value, entry->length-1)) + if (str->copy(entry->value, entry->length-1, entry->var_charset)) { null_value=1; return NULL; } - str->set_charset(entry->var_charset); break; } return str; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index f930afe14a2..6f121ecdc06 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1373,7 +1373,7 @@ String *Item_func_database::val_str(String *str) String *Item_func_user::val_str(String *str) { THD *thd=current_thd; - if (str->copy((const char*) thd->user,(uint) strlen(thd->user)) || + if (str->copy((const char*) thd->user,(uint) strlen(thd->user), system_charset_info) || str->append('@') || str->append(thd->host ? thd->host : thd->ip ? thd->ip : "")) return &empty_string; @@ -1899,7 +1899,7 @@ String *Item_func_conv::val_str(String *str) else dec= (longlong) strtoull(res->c_ptr(),&endptr,from_base); ptr= longlong2str(dec,ans,to_base); - if (str->copy(ans,(uint32) (ptr-ans))) + if (str->copy(ans,(uint32) (ptr-ans), thd_charset())) return &empty_string; return str; } @@ -2120,7 +2120,7 @@ String *Item_func_charset::val_str(String *str) if ((null_value=(args[0]->null_value || !res->charset()))) return 0; - str->copy(res->charset()->name,strlen(res->charset()->name)); + str->copy(res->charset()->name,strlen(res->charset()->name),default_charset_info); return str; } @@ -2135,7 +2135,7 @@ String *Item_func_hex::val_str(String *str) if ((null_value= args[0]->null_value)) return 0; ptr= longlong2str(dec,ans,16); - if (str->copy(ans,(uint32) (ptr-ans))) + if (str->copy(ans,(uint32) (ptr-ans),default_charset_info)) return &empty_string; // End of memory return str; } @@ -2454,7 +2454,9 @@ String *Item_func_geometry_type::val_str(String *str) if ((null_value=(args[0]->null_value || geom.create_from_wkb(wkt->ptr(),wkt->length())))) return 0; - str->copy(geom.get_class_info()->m_name,strlen(geom.get_class_info()->m_name)); + str->copy(geom.get_class_info()->m_name, + strlen(geom.get_class_info()->m_name), + default_charset_info); return str; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index e28e878e57f..db4c45fc412 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -106,7 +106,7 @@ Item_sum_int::val_str(String *str) return 0; char buff[21]; uint length= (uint) (longlong10_to_str(nr,buff,-10)-buff); - str->copy(buff,length); + str->copy(buff,length,thd_charset()); return str; } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index e81fecabe96..8a1bd0be291 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -396,7 +396,7 @@ String *Item_date::val_str(String *str) return (String*) 0; if (!value) // zero daynr { - str->copy("0000-00-00",10); + str->copy("0000-00-00",10,my_charset_latin1); return str; } if (str->alloc(11)) @@ -547,7 +547,7 @@ String *Item_func_sec_to_time::val_str(String *str) uint sec= (uint) ((ulonglong) seconds % 3600); length= my_sprintf(buff,(buff,"%s%02lu:%02u:%02u",sign,(long) (seconds/3600), sec/60, sec % 60)); - str->copy(buff, length); + str->copy(buff, length, my_charset_latin1); return str; } diff --git a/sql/procedure.h b/sql/procedure.h index 3792d823b12..3434079a8fb 100644 --- a/sql/procedure.h +++ b/sql/procedure.h @@ -94,7 +94,7 @@ public: enum_field_types field_type() const { return FIELD_TYPE_STRING; } void set(double nr) { str_value.set(nr, 2, my_thd_charset); } void set(longlong nr) { str_value.set(nr, my_thd_charset); } - void set(const char *str, uint length) { str_value.copy(str,length); } + void set(const char *str, uint length) { str_value.copy(str,length, my_thd_charset); } double val() { return atof(str_value.ptr()); } longlong val_int() { return strtoll(str_value.ptr(),NULL,10); } String *val_str(String*) diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 1276020e3c3..f0f31004544 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -117,7 +117,7 @@ bool String::set(double num,uint decimals, CHARSET_INFO *cs) if (decimals >= NOT_FIXED_DEC) { sprintf(buff,"%.14g",num); // Enough for a DATETIME - return copy(buff, (uint32) strlen(buff)); + return copy(buff, (uint32) strlen(buff), my_charset_latin1); } #ifdef HAVE_FCONVERT int decpt,sign; @@ -182,7 +182,7 @@ end: #else sprintf(buff,"%.*f",(int) decimals,num); #endif - return copy(buff,(uint32) strlen(buff)); + return copy(buff,(uint32) strlen(buff), my_charset_latin1); #endif } @@ -208,13 +208,14 @@ bool String::copy(const String &str) return FALSE; } -bool String::copy(const char *str,uint32 arg_length) +bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs) { if (alloc(arg_length)) return TRUE; if ((str_length=arg_length)) memcpy(Ptr,str,arg_length); Ptr[arg_length]=0; + str_charset=cs; return FALSE; } diff --git a/sql/sql_string.h b/sql/sql_string.h index c881cb22c5c..4ac4308f113 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -178,7 +178,7 @@ public: bool copy(); // Alloc string if not alloced bool copy(const String &s); // Allocate new string - bool copy(const char *s,uint32 arg_length); // Allocate new string + bool copy(const char *s,uint32 arg_length, CHARSET_INFO *cs); // Allocate new string bool append(const String &s); bool append(const char *s,uint32 arg_length=0); bool append(IO_CACHE* file, uint32 arg_length); From 115812157ccbdf9cec5db115382fb72089a89719 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2002 15:01:03 +0100 Subject: [PATCH 5/5] - configure.in: replaced AM_PROG_LIBTOOL with AC_PROG_LIBTOOL, since the old macro name is deprecated (according to the libtool 1.4.2 docs). configure.in: - replaced AM_PROG_LIBTOOL with AC_PROG_LIBTOOL, since the old macro name is deprecated (according to the libtool 1.4.2 docs). --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index f55ed69b348..5de157a49c9 100644 --- a/configure.in +++ b/configure.in @@ -161,7 +161,7 @@ fi AC_PROG_RANLIB # We use libtool #AC_LIBTOOL_WIN32_DLL -AM_PROG_LIBTOOL +AC_PROG_LIBTOOL #AC_LIBTOOL_DLOPEN AC_LIBTOOL_WIN32_DLL AC_DISABLE_FAST_INSTALL AC_DISABLE_SHARED AC_DISABLE_STATIC