~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/charset.cc

  • Committer: Stewart Smith
  • Date: 2009-05-15 06:57:12 UTC
  • mto: (991.1.5 for-brian)
  • mto: This revision was merged to the branch mainline in revision 1022.
  • Revision ID: stewart@flamingspork.com-20090515065712-bmionylacjmexmmm
Make sql_mode=NO_AUTO_VALUE_ON_ZERO default for Drizzle.

Also fix DEFAULT keyword handling for auto-increment so that it defaults to
NULL and not 0 so that the following is valid and generates two auto-inc
values:

create table t1 (a int auto_increment primary key)
insert into t1 (a) values (default);
insert into t1 (a) values (default);

Important to note that 0 is no longer magic. So this gives you duplicate
primary key error:

insert into t1 (a) values(0);
insert into t1 (a) values(0);

as you've inserted the explicit value of 0 twice.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
 
 
16
 
#include "config.h"
17
 
 
18
 
#include "drizzled/charset.h"
19
 
#include "drizzled/error.h"
20
 
#include "drizzled/charset_info.h"
21
 
#include "drizzled/internal/m_string.h"
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
#include "mysys/mysys_priv.h"
 
17
#include "mysys/mysys_err.h"
 
18
#include <mystrings/m_ctype.h>
 
19
#include <mystrings/m_string.h>
22
20
#include <drizzled/configmake.h>
23
 
#include <vector>
24
 
 
25
 
#include "drizzled/visibility.h"
26
 
 
27
 
using namespace std;
28
 
 
29
 
namespace drizzled
30
 
{
31
 
 
32
 
/*
33
 
  We collect memory in this vector that we free on delete.
34
 
*/
35
 
static vector<void *>memory_vector;
 
21
 
36
22
 
37
23
/*
38
24
  The code below implements this functionality:
58
44
       cs < all_charsets+array_elements(all_charsets)-1 ;
59
45
       cs++)
60
46
  {
61
 
    if ( cs[0] && cs[0]->name && !my_strcasecmp(&my_charset_utf8_general_ci, cs[0]->name, name))
62
 
    {
 
47
    if ( cs[0] && cs[0]->name &&
 
48
         !my_strcasecmp(&my_charset_utf8_general_ci, cs[0]->name, name))
63
49
      return cs[0]->number;
64
 
    }
65
50
  }
66
51
  return 0;
67
52
}
73
58
  unsigned char *state_map;
74
59
  unsigned char *ident_map;
75
60
 
76
 
  if (!(cs->state_map= (unsigned char*) cs_alloc(256)))
 
61
  if (!(cs->state_map= (unsigned char*) malloc(256)))
77
62
    return 1;
78
63
    
79
 
  if (!(cs->ident_map= (unsigned char*) cs_alloc(256)))
 
64
  if (!(cs->ident_map= (unsigned char*) malloc(256)))
80
65
    return 1;
81
66
 
82
67
  state_map= cs->state_map;
89
74
      state_map[i]=(unsigned char) MY_LEX_IDENT;
90
75
    else if (my_isdigit(cs,i))
91
76
      state_map[i]=(unsigned char) MY_LEX_NUMBER_IDENT;
 
77
#if defined(USE_MB) && defined(USE_MB_IDENT)
92
78
    else if (my_mbcharlen(cs, i)>1)
93
79
      state_map[i]=(unsigned char) MY_LEX_IDENT;
 
80
#endif
94
81
    else if (my_isspace(cs,i))
95
82
      state_map[i]=(unsigned char) MY_LEX_SKIP;
96
83
    else
131
118
 
132
119
static bool charset_initialized= false;
133
120
 
134
 
DRIZZLED_API CHARSET_INFO *all_charsets[256];
135
 
const DRIZZLED_API CHARSET_INFO *default_charset_info = &my_charset_utf8_general_ci;
 
121
CHARSET_INFO *all_charsets[256];
 
122
const CHARSET_INFO *default_charset_info = &my_charset_utf8_general_ci;
136
123
 
137
124
void add_compiled_collation(CHARSET_INFO * cs)
138
125
{
142
129
 
143
130
void *cs_alloc(size_t size)
144
131
{
145
 
  void *ptr= malloc(size);
146
 
 
147
 
  memory_vector.push_back(ptr);
148
 
 
149
 
  return ptr;
 
132
  return malloc(size);
150
133
}
151
134
 
152
135
 
153
 
 
154
136
static bool init_available_charsets(myf myflags)
155
137
{
156
138
  bool error= false;
188
170
void free_charsets(void)
189
171
{
190
172
  charset_initialized= true;
191
 
 
192
 
  while (memory_vector.empty() == false)
193
 
  {
194
 
    void *ptr= memory_vector.back();
195
 
    memory_vector.pop_back();
196
 
    free(ptr);
197
 
  }
198
 
  memory_vector.clear();
199
 
 
200
173
}
201
174
 
202
175
 
216
189
       cs < all_charsets+array_elements(all_charsets)-1 ;
217
190
       cs++)
218
191
  {
219
 
    if ( cs[0] && cs[0]->csname && (cs[0]->state & cs_flags) && !my_strcasecmp(&my_charset_utf8_general_ci, cs[0]->csname, charset_name))
 
192
    if ( cs[0] && cs[0]->csname && (cs[0]->state & cs_flags) &&
 
193
         !my_strcasecmp(&my_charset_utf8_general_ci, cs[0]->csname, charset_name))
220
194
      return cs[0]->number;
221
195
  }
222
196
  return 0;
286
260
  const CHARSET_INFO *cs;
287
261
  (void) init_available_charsets(MYF(0));       /* If it isn't initialized */
288
262
 
289
 
  cs_number= get_collation_number(cs_name);
 
263
  cs_number=get_collation_number(cs_name);
290
264
  cs= cs_number ? get_internal_charset(cs_number) : NULL;
291
265
 
292
266
  return cs;
307
281
}
308
282
 
309
283
 
 
284
/**
 
285
  Resolve character set by the character set name (utf8, latin1, ...).
 
286
 
 
287
  The function tries to resolve character set by the specified name. If
 
288
  there is character set with the given name, it is assigned to the "cs"
 
289
  parameter and false is returned. If there is no such character set,
 
290
  "default_cs" is assigned to the "cs" and true is returned.
 
291
 
 
292
  @param[in] cs_name    Character set name.
 
293
  @param[in] default_cs Default character set.
 
294
  @param[out] cs        Variable to store character set.
 
295
 
 
296
  @return false if character set was resolved successfully; true if there
 
297
  is no character set with given name.
 
298
*/
 
299
 
 
300
bool resolve_charset(const char *cs_name,
 
301
                     const CHARSET_INFO *default_cs,
 
302
                     const CHARSET_INFO **cs)
 
303
{
 
304
  *cs= get_charset_by_csname(cs_name, MY_CS_PRIMARY);
 
305
 
 
306
  if (*cs == NULL)
 
307
  {
 
308
    *cs= default_cs;
 
309
    return true;
 
310
  }
 
311
 
 
312
  return false;
 
313
}
 
314
 
 
315
 
 
316
/**
 
317
  Resolve collation by the collation name (utf8_general_ci, ...).
 
318
 
 
319
  The function tries to resolve collation by the specified name. If there
 
320
  is collation with the given name, it is assigned to the "cl" parameter
 
321
  and false is returned. If there is no such collation, "default_cl" is
 
322
  assigned to the "cl" and true is returned.
 
323
 
 
324
  @param[out] cl        Variable to store collation.
 
325
  @param[in] cl_name    Collation name.
 
326
  @param[in] default_cl Default collation.
 
327
 
 
328
  @return false if collation was resolved successfully; true if there is no
 
329
  collation with given name.
 
330
*/
 
331
 
 
332
bool resolve_collation(const char *cl_name,
 
333
                       const CHARSET_INFO *default_cl,
 
334
                       const CHARSET_INFO **cl)
 
335
{
 
336
  *cl= get_charset_by_name(cl_name);
 
337
 
 
338
  if (*cl == NULL)
 
339
  {
 
340
    *cl= default_cl;
 
341
    return true;
 
342
  }
 
343
 
 
344
  return false;
 
345
}
 
346
 
 
347
 
 
348
#ifdef BACKSLASH_MBTAIL
 
349
static CHARSET_INFO *fs_cset_cache= NULL;
 
350
 
 
351
CHARSET_INFO *fs_character_set()
 
352
{
 
353
  if (!fs_cset_cache)
 
354
  {
 
355
    char buf[10]= "cp";
 
356
    GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE,
 
357
                  buf+2, sizeof(buf)-3);
 
358
    /*
 
359
      We cannot call get_charset_by_name here
 
360
      because fs_character_set() is executed before
 
361
      LOCK_THD_charset mutex initialization, which
 
362
      is used inside get_charset_by_name.
 
363
      As we're now interested in cp932 only,
 
364
      let's just detect it using strcmp().
 
365
    */
 
366
    fs_cset_cache= !strcmp(buf, "cp932") ?
 
367
                   &my_charset_cp932_japanese_ci : &my_charset_bin;
 
368
  }
 
369
  return fs_cset_cache;
 
370
}
 
371
#endif
 
372
 
310
373
/*
311
374
  Escape apostrophes by doubling them up
312
375
 
339
402
  const char *to_start= to;
340
403
  const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
341
404
  bool overflow= false;
 
405
#ifdef USE_MB
342
406
  bool use_mb_flag= use_mb(charset_info);
 
407
#endif
343
408
  for (end= from + length; from < end; from++)
344
409
  {
 
410
#ifdef USE_MB
345
411
    int tmp_length;
346
412
    if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
347
413
    {
360
426
      turned into a multi-byte character by the addition of an escaping
361
427
      character, because we are only escaping the ' character with itself.
362
428
     */
 
429
#endif
363
430
    if (*from == '\'')
364
431
    {
365
432
      if (to + 2 > to_end)
383
450
  *to= 0;
384
451
  return overflow ? UINT32_MAX : (uint32_t) (to - to_start);
385
452
}
386
 
 
387
 
} /* namespace drizzled */