54
45
cs < all_charsets+array_elements(all_charsets)-1 ;
57
if ( cs[0] && cs[0]->name &&
58
!my_strcasecmp(&my_charset_utf8_general_ci, cs[0]->name, name))
48
if ( cs[0] && cs[0]->name &&
49
!my_strcasecmp(&my_charset_latin1, cs[0]->name, name))
59
50
return cs[0]->number;
65
56
static bool init_state_maps(CHARSET_INFO *cs)
68
unsigned char *state_map;
69
unsigned char *ident_map;
71
if (!(cs->state_map= (unsigned char*) cs_alloc(256)))
62
if (!(cs->state_map= (uchar*) my_once_alloc(256, MYF(MY_WME))))
74
if (!(cs->ident_map= (unsigned char*) cs_alloc(256)))
65
if (!(cs->ident_map= (uchar*) my_once_alloc(256, MYF(MY_WME))))
77
68
state_map= cs->state_map;
78
69
ident_map= cs->ident_map;
80
71
/* Fill state_map with states to get a faster parser */
81
72
for (i=0; i < 256 ; i++)
83
74
if (my_isalpha(cs,i))
84
state_map[i]=(unsigned char) MY_LEX_IDENT;
75
state_map[i]=(uchar) MY_LEX_IDENT;
85
76
else if (my_isdigit(cs,i))
86
state_map[i]=(unsigned char) MY_LEX_NUMBER_IDENT;
77
state_map[i]=(uchar) MY_LEX_NUMBER_IDENT;
78
#if defined(USE_MB) && defined(USE_MB_IDENT)
87
79
else if (my_mbcharlen(cs, i)>1)
88
state_map[i]=(unsigned char) MY_LEX_IDENT;
80
state_map[i]=(uchar) MY_LEX_IDENT;
89
82
else if (my_isspace(cs,i))
90
state_map[i]=(unsigned char) MY_LEX_SKIP;
83
state_map[i]=(uchar) MY_LEX_SKIP;
92
state_map[i]=(unsigned char) MY_LEX_CHAR;
85
state_map[i]=(uchar) MY_LEX_CHAR;
94
state_map[(unsigned char)'_']=state_map[(unsigned char)'$']=(unsigned char) MY_LEX_IDENT;
95
state_map[(unsigned char)'\'']=(unsigned char) MY_LEX_STRING;
96
state_map[(unsigned char)'.']=(unsigned char) MY_LEX_REAL_OR_POINT;
97
state_map[(unsigned char)'>']=state_map[(unsigned char)'=']=state_map[(unsigned char)'!']= (unsigned char) MY_LEX_CMP_OP;
98
state_map[(unsigned char)'<']= (unsigned char) MY_LEX_LONG_CMP_OP;
99
state_map[(unsigned char)'&']=state_map[(unsigned char)'|']=(unsigned char) MY_LEX_BOOL;
100
state_map[(unsigned char)'#']=(unsigned char) MY_LEX_COMMENT;
101
state_map[(unsigned char)';']=(unsigned char) MY_LEX_SEMICOLON;
102
state_map[(unsigned char)':']=(unsigned char) MY_LEX_SET_VAR;
103
state_map[0]=(unsigned char) MY_LEX_EOL;
104
state_map[(unsigned char)'\\']= (unsigned char) MY_LEX_ESCAPE;
105
state_map[(unsigned char)'/']= (unsigned char) MY_LEX_LONG_COMMENT;
106
state_map[(unsigned char)'*']= (unsigned char) MY_LEX_END_LONG_COMMENT;
107
state_map[(unsigned char)'@']= (unsigned char) MY_LEX_USER_END;
108
state_map[(unsigned char) '`']= (unsigned char) MY_LEX_USER_VARIABLE_DELIMITER;
109
state_map[(unsigned char)'"']= (unsigned char) MY_LEX_STRING_OR_DELIMITER;
87
state_map[(uchar)'_']=state_map[(uchar)'$']=(uchar) MY_LEX_IDENT;
88
state_map[(uchar)'\'']=(uchar) MY_LEX_STRING;
89
state_map[(uchar)'.']=(uchar) MY_LEX_REAL_OR_POINT;
90
state_map[(uchar)'>']=state_map[(uchar)'=']=state_map[(uchar)'!']= (uchar) MY_LEX_CMP_OP;
91
state_map[(uchar)'<']= (uchar) MY_LEX_LONG_CMP_OP;
92
state_map[(uchar)'&']=state_map[(uchar)'|']=(uchar) MY_LEX_BOOL;
93
state_map[(uchar)'#']=(uchar) MY_LEX_COMMENT;
94
state_map[(uchar)';']=(uchar) MY_LEX_SEMICOLON;
95
state_map[(uchar)':']=(uchar) MY_LEX_SET_VAR;
96
state_map[0]=(uchar) MY_LEX_EOL;
97
state_map[(uchar)'\\']= (uchar) MY_LEX_ESCAPE;
98
state_map[(uchar)'/']= (uchar) MY_LEX_LONG_COMMENT;
99
state_map[(uchar)'*']= (uchar) MY_LEX_END_LONG_COMMENT;
100
state_map[(uchar)'@']= (uchar) MY_LEX_USER_END;
101
state_map[(uchar) '`']= (uchar) MY_LEX_USER_VARIABLE_DELIMITER;
102
state_map[(uchar)'"']= (uchar) MY_LEX_STRING_OR_DELIMITER;
112
105
Create a second map to make it faster to find identifiers
114
107
for (i=0; i < 256 ; i++)
116
ident_map[i]= (unsigned char) (state_map[i] == MY_LEX_IDENT ||
109
ident_map[i]= (uchar) (state_map[i] == MY_LEX_IDENT ||
117
110
state_map[i] == MY_LEX_NUMBER_IDENT);
120
113
/* Special handling of hex and binary strings */
121
state_map[(unsigned char)'x']= state_map[(unsigned char)'X']= (unsigned char) MY_LEX_IDENT_OR_HEX;
122
state_map[(unsigned char)'b']= state_map[(unsigned char)'B']= (unsigned char) MY_LEX_IDENT_OR_BIN;
127
static bool charset_initialized= false;
114
state_map[(uchar)'x']= state_map[(uchar)'X']= (uchar) MY_LEX_IDENT_OR_HEX;
115
state_map[(uchar)'b']= state_map[(uchar)'B']= (uchar) MY_LEX_IDENT_OR_BIN;
116
state_map[(uchar)'n']= state_map[(uchar)'N']= (uchar) MY_LEX_IDENT_OR_NCHAR;
121
static void simple_cs_init_functions(CHARSET_INFO *cs)
123
if (cs->state & MY_CS_BINSORT)
124
cs->coll= &my_collation_8bit_bin_handler;
126
cs->coll= &my_collation_8bit_simple_ci_handler;
128
cs->cset= &my_charset_8bit_handler;
133
static int cs_copy_data(CHARSET_INFO *to, CHARSET_INFO *from)
135
to->number= from->number ? from->number : to->number;
138
if (!(to->csname= my_once_strdup(from->csname,MYF(MY_WME))))
142
if (!(to->name= my_once_strdup(from->name,MYF(MY_WME))))
146
if (!(to->comment= my_once_strdup(from->comment,MYF(MY_WME))))
151
if (!(to->ctype= (uchar*) my_once_memdup((char*) from->ctype,
152
MY_CS_CTYPE_TABLE_SIZE,
155
if (init_state_maps(to))
159
if (!(to->to_lower= (uchar*) my_once_memdup((char*) from->to_lower,
160
MY_CS_TO_LOWER_TABLE_SIZE,
165
if (!(to->to_upper= (uchar*) my_once_memdup((char*) from->to_upper,
166
MY_CS_TO_UPPER_TABLE_SIZE,
169
if (from->sort_order)
171
if (!(to->sort_order= (uchar*) my_once_memdup((char*) from->sort_order,
172
MY_CS_SORT_ORDER_TABLE_SIZE,
177
if (from->tab_to_uni)
179
uint sz= MY_CS_TO_UNI_TABLE_SIZE*sizeof(uint16_t);
180
if (!(to->tab_to_uni= (uint16_t*) my_once_memdup((char*)from->tab_to_uni,
185
if (!(to->tailoring= my_once_strdup(from->tailoring,MYF(MY_WME))))
196
static bool simple_cs_is_full(CHARSET_INFO *cs)
198
return ((cs->csname && cs->tab_to_uni && cs->ctype && cs->to_upper &&
200
(cs->number && cs->name &&
201
(cs->sort_order || (cs->state & MY_CS_BINSORT) )));
206
copy_uca_collation(CHARSET_INFO *to, CHARSET_INFO *from)
208
to->cset= from->cset;
209
to->coll= from->coll;
210
to->strxfrm_multiply= from->strxfrm_multiply;
211
to->min_sort_char= from->min_sort_char;
212
to->max_sort_char= from->max_sort_char;
213
to->mbminlen= from->mbminlen;
214
to->mbmaxlen= from->mbmaxlen;
218
static int add_collation(CHARSET_INFO *cs)
220
if (cs->name && (cs->number ||
221
(cs->number=get_collation_number_internal(cs->name))))
223
if (!all_charsets[cs->number])
225
if (!(all_charsets[cs->number]=
226
(CHARSET_INFO*) my_once_alloc(sizeof(CHARSET_INFO),MYF(0))))
228
bzero((void*)all_charsets[cs->number],sizeof(CHARSET_INFO));
231
if (cs->primary_number == cs->number)
232
cs->state |= MY_CS_PRIMARY;
234
if (cs->binary_number == cs->number)
235
cs->state |= MY_CS_BINSORT;
237
all_charsets[cs->number]->state|= cs->state;
239
if (!(all_charsets[cs->number]->state & MY_CS_COMPILED))
241
CHARSET_INFO *newcs= all_charsets[cs->number];
242
if (cs_copy_data(all_charsets[cs->number],cs))
245
newcs->levels_for_compare= 1;
246
newcs->levels_for_order= 1;
248
if (!strcmp(cs->csname,"ucs2") )
250
#if defined(HAVE_CHARSET_ucs2) && defined(HAVE_UCA_COLLATIONS)
251
copy_uca_collation(newcs, &my_charset_ucs2_unicode_ci);
252
newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII;
255
else if (!strcmp(cs->csname, "utf8"))
257
#if defined (HAVE_CHARSET_utf8mb3) && defined(HAVE_UCA_COLLATIONS)
258
copy_uca_collation(newcs, &my_charset_utf8mb4_unicode_ci);
259
newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED;
262
else if (!strcmp(cs->csname, "utf8mb3"))
264
#if defined (HAVE_CHARSET_utf8mb3) && defined(HAVE_UCA_COLLATIONS)
265
copy_uca_collation(newcs, &my_charset_utf8mb3_unicode_ci);
266
newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED;
269
else if (!strcmp(cs->csname, "utf16"))
271
#if defined (HAVE_CHARSET_utf16) && defined(HAVE_UCA_COLLATIONS)
272
copy_uca_collation(newcs, &my_charset_utf16_unicode_ci);
273
newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII;
276
else if (!strcmp(cs->csname, "utf32"))
278
#if defined (HAVE_CHARSET_utf32) && defined(HAVE_UCA_COLLATIONS)
279
copy_uca_collation(newcs, &my_charset_utf32_unicode_ci);
280
newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII;
285
uchar *sort_order= all_charsets[cs->number]->sort_order;
286
simple_cs_init_functions(all_charsets[cs->number]);
289
if (simple_cs_is_full(all_charsets[cs->number]))
291
all_charsets[cs->number]->state |= MY_CS_LOADED;
293
all_charsets[cs->number]->state|= MY_CS_AVAILABLE;
296
Check if case sensitive sort order: A < a < B.
297
We need MY_CS_FLAG for regex library, and for
298
case sensitivity flag for 5.0 client protocol,
299
to support isCaseSensitive() method in JDBC driver
301
if (sort_order && sort_order['A'] < sort_order['a'] &&
302
sort_order['a'] < sort_order['B'])
303
all_charsets[cs->number]->state|= MY_CS_CSSORT;
305
if (my_charset_is_8bit_pure_ascii(all_charsets[cs->number]))
306
all_charsets[cs->number]->state|= MY_CS_PUREASCII;
307
if (!my_charset_is_ascii_compatible(cs))
308
all_charsets[cs->number]->state|= MY_CS_NONASCII;
314
We need the below to make get_charset_name()
315
and get_charset_number() working even if a
316
character set has not been really incompiled.
317
The above functions are used for example
318
in error message compiler extra/comp_err.c.
319
If a character set was compiled, this information
320
will get lost and overwritten in add_compiled_collation().
322
CHARSET_INFO *dst= all_charsets[cs->number];
323
dst->number= cs->number;
325
if (!(dst->comment= my_once_strdup(cs->comment,MYF(MY_WME))))
327
if (cs->csname && !dst->csname)
328
if (!(dst->csname= my_once_strdup(cs->csname,MYF(MY_WME))))
330
if (cs->name && !dst->name)
331
if (!(dst->name= my_once_strdup(cs->name,MYF(MY_WME))))
335
cs->primary_number= 0;
336
cs->binary_number= 0;
339
cs->sort_order= NULL;
346
#define MY_MAX_ALLOWED_BUF 1024*1024
347
#define MY_CHARSET_INDEX "Index.xml"
349
const char *charsets_dir= NULL;
350
static int charset_initialized=0;
353
static bool my_read_charset_file(const char *filename, myf myflags)
358
struct stat stat_info;
360
if (stat(filename, &stat_info) ||
361
((len= (uint)stat_info.st_size) > MY_MAX_ALLOWED_BUF) ||
362
!(buf= (uchar*) my_malloc(len,myflags)))
365
if ((fd=my_open(filename,O_RDONLY,myflags)) < 0)
367
tmp_len=my_read(fd, buf, len, myflags);
368
my_close(fd,myflags);
372
if (my_parse_charset_xml((char*) buf,len,add_collation))
375
printf("ERROR at line %d pos %d '%s'\n",
376
my_xml_error_lineno(&p)+1,
377
my_xml_error_pos(&p),
378
my_xml_error_string(&p));
382
my_free(buf, myflags);
386
my_free(buf, myflags);
391
char *get_charsets_dir(char *buf)
393
const char *sharedir= SHAREDIR;
396
if (charsets_dir != NULL)
397
strmake(buf, charsets_dir, FN_REFLEN-1);
400
if (test_if_hard_path(sharedir) ||
401
is_prefix(sharedir, DEFAULT_CHARSET_HOME))
402
strxmov(buf, sharedir, "/", CHARSET_DIR, NullS);
404
strxmov(buf, DEFAULT_CHARSET_HOME, "/", sharedir, "/", CHARSET_DIR,
407
res= convert_dirname(buf,buf,NullS);
129
411
CHARSET_INFO *all_charsets[256];
130
const CHARSET_INFO *default_charset_info = &my_charset_utf8_general_ci;
412
CHARSET_INFO *default_charset_info = &my_charset_latin1;
132
void add_compiled_collation(CHARSET_INFO * cs)
414
void add_compiled_collation(CHARSET_INFO *cs)
134
416
all_charsets[cs->number]= cs;
135
417
cs->state|= MY_CS_AVAILABLE;
138
void *cs_alloc(size_t size)
420
static void *cs_alloc(size_t size)
140
void *ptr= malloc(size);
142
memory_vector.push_back(ptr);
422
return my_once_alloc(size, MYF(MY_WME));
149
426
static bool init_available_charsets(myf myflags)
428
char fname[FN_REFLEN + sizeof(MY_CHARSET_INDEX)];
153
431
We have to use charset_initialized to not lock on THR_LOCK_charset
154
432
inside get_internal_charset...
156
if (charset_initialized == false)
434
if (!charset_initialized)
158
436
CHARSET_INFO **cs;
159
memset(&all_charsets, 0, sizeof(all_charsets));
160
init_compiled_charsets(myflags);
162
/* Copy compiled charsets */
163
for (cs=all_charsets;
164
cs < all_charsets+array_elements(all_charsets)-1 ;
438
To make things thread safe we are not allowing other threads to interfere
439
while we may changing the cs_info_table
441
pthread_mutex_lock(&THR_LOCK_charset);
442
if (!charset_initialized)
444
bzero(&all_charsets,sizeof(all_charsets));
445
init_compiled_charsets(myflags);
447
/* Copy compiled charsets */
448
for (cs=all_charsets;
449
cs < all_charsets+array_elements(all_charsets)-1 ;
170
if (init_state_maps(*cs))
455
if (init_state_maps(*cs))
460
strmov(get_charsets_dir(fname), MY_CHARSET_INDEX);
461
error= my_read_charset_file(fname,myflags);
462
charset_initialized=1;
175
charset_initialized= true;
464
pthread_mutex_unlock(&THR_LOCK_charset);
177
assert(charset_initialized);
183
470
void free_charsets(void)
185
charset_initialized= true;
187
while (memory_vector.empty() == false)
189
void *ptr= memory_vector.back();
190
memory_vector.pop_back();
193
memory_vector.clear();
472
charset_initialized=0;
198
uint32_t get_collation_number(const char *name)
476
uint get_collation_number(const char *name)
200
478
init_available_charsets(MYF(0));
201
479
return get_collation_number_internal(name);
205
uint32_t get_charset_number(const char *charset_name, uint32_t cs_flags)
483
uint get_charset_number(const char *charset_name, uint cs_flags)
207
485
CHARSET_INFO **cs;
208
486
init_available_charsets(MYF(0));
210
488
for (cs= all_charsets;
211
489
cs < all_charsets+array_elements(all_charsets)-1 ;
214
492
if ( cs[0] && cs[0]->csname && (cs[0]->state & cs_flags) &&
215
!my_strcasecmp(&my_charset_utf8_general_ci, cs[0]->csname, charset_name))
493
!my_strcasecmp(&my_charset_latin1, cs[0]->csname, charset_name))
216
494
return cs[0]->number;
222
const char *get_charset_name(uint32_t charset_number)
500
const char *get_charset_name(uint charset_number)
224
const CHARSET_INFO *cs;
225
503
init_available_charsets(MYF(0));
227
505
cs=all_charsets[charset_number];
228
506
if (cs && (cs->number == charset_number) && cs->name )
229
507
return (char*) cs->name;
231
509
return (char*) "?"; /* this mimics find_type() */
235
static const CHARSET_INFO *get_internal_charset(uint32_t cs_number)
513
static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags)
237
516
CHARSET_INFO *cs;
239
518
To make things thread safe we are not allowing other threads to interfere
240
519
while we may changing the cs_info_table
521
pthread_mutex_lock(&THR_LOCK_charset);
242
522
if ((cs= all_charsets[cs_number]))
244
524
if (!(cs->state & MY_CS_COMPILED) && !(cs->state & MY_CS_LOADED))
526
strxmov(get_charsets_dir(buf), cs->csname, ".xml", NullS);
527
my_read_charset_file(buf,flags);
248
529
cs= (cs->state & MY_CS_AVAILABLE) ? cs : NULL;
256
537
cs->state|= MY_CS_READY;
539
pthread_mutex_unlock(&THR_LOCK_charset);
263
const CHARSET_INFO *get_charset(uint32_t cs_number)
544
CHARSET_INFO *get_charset(uint cs_number, myf flags)
265
const CHARSET_INFO *cs;
266
547
if (cs_number == default_charset_info->number)
267
548
return default_charset_info;
269
550
(void) init_available_charsets(MYF(0)); /* If it isn't initialized */
271
552
if (!cs_number || cs_number >= array_elements(all_charsets)-1)
274
cs= get_internal_charset(cs_number);
555
cs=get_internal_charset(cs_number, flags);
557
if (!cs && (flags & MY_WME))
559
char index_file[FN_REFLEN + sizeof(MY_CHARSET_INDEX)], cs_string[23];
560
strmov(get_charsets_dir(index_file),MY_CHARSET_INDEX);
562
int10_to_str(cs_number, cs_string+1, 10);
563
my_error(EE_UNKNOWN_CHARSET, MYF(ME_BELL), cs_string, index_file);
279
const CHARSET_INFO *get_charset_by_name(const char *cs_name)
568
CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags)
282
const CHARSET_INFO *cs;
283
572
(void) init_available_charsets(MYF(0)); /* If it isn't initialized */
285
cs_number= get_collation_number(cs_name);
286
cs= cs_number ? get_internal_charset(cs_number) : NULL;
574
cs_number=get_collation_number(cs_name);
575
cs= cs_number ? get_internal_charset(cs_number,flags) : NULL;
577
if (!cs && (flags & MY_WME))
579
char index_file[FN_REFLEN + sizeof(MY_CHARSET_INDEX)];
580
strmov(get_charsets_dir(index_file),MY_CHARSET_INDEX);
581
my_error(EE_UNKNOWN_COLLATION, MYF(ME_BELL), cs_name, index_file);
292
const CHARSET_INFO *get_charset_by_csname(const char *cs_name, uint32_t cs_flags)
588
CHARSET_INFO *get_charset_by_csname(const char *cs_name,
295
const CHARSET_INFO *cs;
297
595
(void) init_available_charsets(MYF(0)); /* If it isn't initialized */
299
597
cs_number= get_charset_number(cs_name, cs_flags);
300
cs= cs_number ? get_internal_charset(cs_number) : NULL;
598
cs= cs_number ? get_internal_charset(cs_number, flags) : NULL;
600
if (!cs && (flags & MY_WME))
602
char index_file[FN_REFLEN + sizeof(MY_CHARSET_INDEX)];
603
strmov(get_charsets_dir(index_file),MY_CHARSET_INDEX);
604
my_error(EE_UNKNOWN_CHARSET, MYF(ME_BELL), cs_name, index_file);
612
Resolve character set by the character set name (utf8, latin1, ...).
614
The function tries to resolve character set by the specified name. If
615
there is character set with the given name, it is assigned to the "cs"
616
parameter and false is returned. If there is no such character set,
617
"default_cs" is assigned to the "cs" and true is returned.
619
@param[in] cs_name Character set name.
620
@param[in] default_cs Default character set.
621
@param[out] cs Variable to store character set.
623
@return false if character set was resolved successfully; true if there
624
is no character set with given name.
627
bool resolve_charset(const char *cs_name,
628
CHARSET_INFO *default_cs,
631
*cs= get_charset_by_csname(cs_name, MY_CS_PRIMARY, MYF(0));
644
Resolve collation by the collation name (utf8_general_ci, ...).
646
The function tries to resolve collation by the specified name. If there
647
is collation with the given name, it is assigned to the "cl" parameter
648
and false is returned. If there is no such collation, "default_cl" is
649
assigned to the "cl" and true is returned.
651
@param[out] cl Variable to store collation.
652
@param[in] cl_name Collation name.
653
@param[in] default_cl Default collation.
655
@return false if collation was resolved successfully; true if there is no
656
collation with given name.
659
bool resolve_collation(const char *cl_name,
660
CHARSET_INFO *default_cl,
663
*cl= get_charset_by_name(cl_name, MYF(0));
676
Escape string with backslashes (\)
679
escape_string_for_mysql()
680
charset_info Charset of the strings
681
to Buffer for escaped string
682
to_length Length of destination buffer, or 0
683
from The string to escape
684
length The length of the string to escape
687
This escapes the contents of a string by adding backslashes before special
688
characters, and turning others into specific escape sequences, such as
689
turning newlines into \n and null bytes into \0.
692
To maintain compatibility with the old C API, to_length may be 0 to mean
696
(size_t) -1 The escaped string did not fit in the to buffer
697
# The length of the escaped string
700
size_t escape_string_for_mysql(CHARSET_INFO *charset_info,
701
char *to, size_t to_length,
702
const char *from, size_t length)
704
const char *to_start= to;
705
const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
706
bool overflow= false;
708
bool use_mb_flag= use_mb(charset_info);
710
for (end= from + length; from < end; from++)
715
if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
717
if (to + tmp_length > to_end)
728
If the next character appears to begin a multi-byte character, we
729
escape that first byte of that apparent multi-byte character. (The
730
character just looks like a multi-byte character -- if it were actually
731
a multi-byte character, it would have been passed through in the test
734
Without this check, we can create a problem by converting an invalid
735
multi-byte character into a valid one. For example, 0xbf27 is not
736
a valid GBK character, but 0xbf5c is. (0x27 = ', 0x5c = \)
738
if (use_mb_flag && (tmp_length= my_mbcharlen(charset_info, *from)) > 1)
743
case 0: /* Must be escaped for 'mysql' */
746
case '\n': /* Must be escaped for logs */
758
case '"': /* Better safe than sorry */
761
case '\032': /* This gives problems on Win32 */
786
return overflow ? (size_t) -1 : (size_t) (to - to_start);
790
#ifdef BACKSLASH_MBTAIL
791
static CHARSET_INFO *fs_cset_cache= NULL;
793
CHARSET_INFO *fs_character_set()
798
GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE,
799
buf+2, sizeof(buf)-3);
801
We cannot call get_charset_by_name here
802
because fs_character_set() is executed before
803
LOCK_THD_charset mutex initialization, which
804
is used inside get_charset_by_name.
805
As we're now interested in cp932 only,
806
let's just detect it using strcmp().
808
fs_cset_cache= !strcmp(buf, "cp932") ?
809
&my_charset_cp932_japanese_ci : &my_charset_bin;
811
return fs_cset_cache;
307
816
Escape apostrophes by doubling them up
310
escape_quotes_for_drizzle()
819
escape_quotes_for_mysql()
311
820
charset_info Charset of the strings
312
821
to Buffer for escaped string
313
822
to_length Length of destination buffer, or 0