~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_string.h

  • Committer: Jay Pipes
  • Date: 2009-01-30 04:01:12 UTC
  • mto: This revision was merged to the branch mainline in revision 830.
  • Revision ID: jpipes@serialcoder-20090130040112-svbn774guj98pwi4
To remain in compatibility with MySQL, added ability to interpret
decimal arguments as datetime strings for temporal functions.

Fixed YEAR(), MONTH(), DAYOFMONTH(), DAYOFYEAR(), HOUR(), MINUTE(), SECOND(), and MICROSECOND()
to accept decimal parameters and interpret them the same way as MySQL.

Fixed an issue with the TemporalFormat::matches() method which was 
incorrectly assuming all microsecond arguments were specified as 6 digits.
Added power of 10 multiplier to usecond calculation. This fixes issues with
failures in type_date and func_sapdb test cases.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#ifndef DRIZZLED_SQL_STRING_H
21
 
#define DRIZZLED_SQL_STRING_H
 
20
#ifndef DRIZZLE_SERVER_SQL_STRING_H
 
21
#define DRIZZLE_SERVER_SQL_STRING_H
22
22
 
23
23
/* This file is originally from the mysql distribution. Coded by monty */
24
24
 
 
25
 
 
26
#ifndef NOT_FIXED_DEC
 
27
#define NOT_FIXED_DEC                   31
 
28
#endif
 
29
 
25
30
#include <drizzled/common.h>
26
 
#include <cassert>
27
 
#include <cstdlib>
28
 
#include <cstring>
29
 
#include <string>
30
 
 
31
 
#ifndef NOT_FIXED_DEC
32
 
#define NOT_FIXED_DEC                   (uint8_t)31
33
 
#endif
34
 
 
35
 
namespace drizzled
36
 
{
 
31
#include <mysys/iocache.h>
 
32
#include <stdlib.h>
 
33
#include <string.h>
37
34
 
38
35
class String;
39
36
 
40
 
extern String my_empty_string;
41
 
extern const String my_null_string;
42
 
namespace memory { class Root; }
43
 
typedef struct charset_info_st CHARSET_INFO;
44
 
 
45
 
std::string String_to_std_string(String const& s);
46
 
String* set_String_from_std_string(String* s, std::string const& cs);
47
 
 
48
 
int sortcmp(const String *a,const String *b, const CHARSET_INFO * const cs);
49
 
int stringcmp(const String *a,const String *b);
50
 
String *copy_if_not_alloced(String *a,String *b,size_t arg_length);
51
 
size_t well_formed_copy_nchars(const CHARSET_INFO * const to_cs,
52
 
                                 char *to, size_t to_length,
53
 
                                 const CHARSET_INFO * const from_cs,
54
 
                                 const char *from, size_t from_length,
55
 
                                 size_t nchars,
56
 
                                 const char **well_formed_error_pos,
57
 
                                 const char **cannot_convert_error_pos,
58
 
                                 const char **from_end_pos);
59
 
 
 
37
#if defined(__cplusplus)
 
38
extern "C" {
 
39
#endif
 
40
 
 
41
  int sortcmp(const String *a,const String *b, const CHARSET_INFO * const cs);
 
42
  int stringcmp(const String *a,const String *b);
 
43
  String *copy_if_not_alloced(String *a,String *b,uint32_t arg_length);
 
44
  uint32_t copy_and_convert(char *to, uint32_t to_length,
 
45
                            const CHARSET_INFO * const to_cs,
 
46
                            const char *from, uint32_t from_length,
 
47
                            const CHARSET_INFO * const from_cs,
 
48
                            uint32_t *errors);
 
49
  uint32_t well_formed_copy_nchars(const CHARSET_INFO * const to_cs,
 
50
                                   char *to, uint32_t to_length,
 
51
                                   const CHARSET_INFO * const from_cs,
 
52
                                   const char *from, uint32_t from_length,
 
53
                                   uint32_t nchars,
 
54
                                   const char **well_formed_error_pos,
 
55
                                   const char **cannot_convert_error_pos,
 
56
                                   const char **from_end_pos);
 
57
  size_t my_copy_with_hex_escaping(const CHARSET_INFO * const cs,
 
58
                                   char *dst, size_t dstlen,
 
59
                                   const char *src, size_t srclen);
 
60
 
 
61
#if defined(__cplusplus)
 
62
}
 
63
#endif
60
64
 
61
65
class String
62
66
{
63
67
  char *Ptr;
64
 
  size_t str_length,Alloced_length;
 
68
  uint32_t str_length,Alloced_length;
65
69
  bool alloced;
66
70
  const CHARSET_INFO *str_charset;
67
71
 
68
72
public:
69
 
  String();
70
 
  String(size_t length_arg);
71
 
  String(const char *str, const CHARSET_INFO * const cs);
72
 
  String(const char *str, size_t len, const CHARSET_INFO * const cs);
73
 
  String(char *str, size_t len, const CHARSET_INFO * const cs);
74
 
  String(const String &str);
75
 
 
76
 
  static void *operator new(size_t size, memory::Root *mem_root);
 
73
  String()
 
74
  {
 
75
    Ptr=0; str_length=Alloced_length=0; alloced=0;
 
76
    str_charset= &my_charset_bin;
 
77
  }
 
78
  String(uint32_t length_arg)
 
79
  {
 
80
    alloced=0; Alloced_length=0; (void) real_alloc(length_arg);
 
81
    str_charset= &my_charset_bin;
 
82
  }
 
83
  String(const char *str, const CHARSET_INFO * const cs)
 
84
  {
 
85
    Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0;
 
86
    str_charset=cs;
 
87
  }
 
88
  String(const char *str,uint32_t len, const CHARSET_INFO * const cs)
 
89
  {
 
90
    Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0;
 
91
    str_charset=cs;
 
92
  }
 
93
  String(char *str,uint32_t len, const CHARSET_INFO * const cs)
 
94
  {
 
95
    Ptr=(char*) str; Alloced_length=str_length=len; alloced=0;
 
96
    str_charset=cs;
 
97
  }
 
98
  String(const String &str)
 
99
  {
 
100
    Ptr=str.Ptr ; str_length=str.str_length ;
 
101
    Alloced_length=str.Alloced_length; alloced=0;
 
102
    str_charset=str.str_charset;
 
103
  }
 
104
  static void *operator new(size_t size, MEM_ROOT *mem_root)
 
105
  { return (void*) alloc_root(mem_root, (uint) size); }
77
106
  static void operator delete(void *, size_t)
78
 
  { }
79
 
  static void operator delete(void *, memory::Root *)
80
 
  { }
81
 
  ~String();
 
107
  { TRASH(ptr_arg, size); }
 
108
  static void operator delete(void *, MEM_ROOT *)
 
109
  { /* never called */ }
 
110
  ~String() { free(); }
82
111
 
83
112
  inline void set_charset(const CHARSET_INFO * const charset_arg)
84
113
  { str_charset= charset_arg; }
85
114
  inline const CHARSET_INFO *charset() const { return str_charset; }
86
 
  inline size_t length() const { return str_length;}
87
 
  inline size_t alloced_length() const { return Alloced_length;}
88
 
  inline char& operator [] (size_t i) const { return Ptr[i]; }
89
 
  inline void length(size_t len) { str_length=len ; }
 
115
  inline uint32_t length() const { return str_length;}
 
116
  inline uint32_t alloced_length() const { return Alloced_length;}
 
117
  inline char& operator [] (uint32_t i) const { return Ptr[i]; }
 
118
  inline void length(uint32_t len) { str_length=len ; }
90
119
  inline bool is_empty() { return (str_length == 0); }
91
120
  inline void mark_as_const() { Alloced_length= 0;}
92
121
  inline char *ptr() { return Ptr; }
93
122
  inline const char *ptr() const { return Ptr; }
94
123
  inline char *c_ptr()
95
124
  {
96
 
    if (str_length == Alloced_length)
 
125
    if (!Ptr || Ptr[str_length])                /* Should be safe */
97
126
      (void) realloc(str_length);
98
 
    else
99
 
      Ptr[str_length]= 0;
100
 
 
101
127
    return Ptr;
102
128
  }
103
129
  inline char *c_ptr_quick()
114
140
      (void) realloc(str_length);
115
141
    return Ptr;
116
142
  }
117
 
  inline char *c_str()
118
 
  {
119
 
    if (Ptr && str_length < Alloced_length)
120
 
      Ptr[str_length]=0;
121
 
    else
122
 
      (void) realloc(str_length);
123
 
    return Ptr;
124
 
  }
125
 
  void append_identifier(const char *name, size_t length);
 
143
  void append_identifier(const char *name, uint32_t length);
126
144
 
127
 
  void set(String &str,size_t offset,size_t arg_length)
 
145
  void set(String &str,uint32_t offset,uint32_t arg_length)
128
146
  {
129
147
    assert(&str != this);
130
148
    free();
131
 
    Ptr= str.ptr()+offset; str_length=arg_length; alloced=0;
 
149
    Ptr=(char*) str.ptr()+offset; str_length=arg_length; alloced=0;
132
150
    if (str.Alloced_length)
133
151
      Alloced_length=str.Alloced_length-offset;
134
152
    else
135
153
      Alloced_length=0;
136
154
    str_charset=str.str_charset;
137
155
  }
138
 
  inline void set(char *str,size_t arg_length, const CHARSET_INFO * const cs)
139
 
  {
140
 
    free();
141
 
    Ptr= str; str_length=Alloced_length=arg_length ; alloced=0;
142
 
    str_charset=cs;
143
 
  }
144
 
  inline void set(const char *str,size_t arg_length, const CHARSET_INFO * const cs)
145
 
  {
146
 
    free();
147
 
    Ptr= const_cast<char*>(str);
148
 
    str_length=arg_length; Alloced_length=0 ; alloced=0;
149
 
    str_charset=cs;
150
 
  }
151
 
  bool set_ascii(const char *str, size_t arg_length);
152
 
  inline void set_quick(char *str,size_t arg_length, const CHARSET_INFO * const cs)
 
156
  inline void set(char *str,uint32_t arg_length, const CHARSET_INFO * const cs)
 
157
  {
 
158
    free();
 
159
    Ptr=(char*) str; str_length=Alloced_length=arg_length ; alloced=0;
 
160
    str_charset=cs;
 
161
  }
 
162
  inline void set(const char *str,uint32_t arg_length, const CHARSET_INFO * const cs)
 
163
  {
 
164
    free();
 
165
    Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0;
 
166
    str_charset=cs;
 
167
  }
 
168
  bool set_ascii(const char *str, uint32_t arg_length);
 
169
  inline void set_quick(char *str,uint32_t arg_length, const CHARSET_INFO * const cs)
153
170
  {
154
171
    if (!alloced)
155
172
    {
156
 
      Ptr= str; str_length= Alloced_length= arg_length;
 
173
      Ptr=(char*) str; str_length=Alloced_length=arg_length;
157
174
    }
158
 
    str_charset= cs;
 
175
    str_charset=cs;
159
176
  }
160
177
  bool set_int(int64_t num, bool unsigned_flag, const CHARSET_INFO * const cs);
161
178
  bool set(int64_t num, const CHARSET_INFO * const cs)
162
179
  { return set_int(num, false, cs); }
163
180
  bool set(uint64_t num, const CHARSET_INFO * const cs)
164
 
  { return set_int(static_cast<int64_t>(num), true, cs); }
165
 
  bool set_real(double num,size_t decimals, const CHARSET_INFO * const cs);
 
181
  { return set_int((int64_t)num, true, cs); }
 
182
  bool set_real(double num,uint32_t decimals, const CHARSET_INFO * const cs);
166
183
 
167
184
  /*
168
185
    PMG 2004.11.12
202
219
      str_length=0;                             /* Safety */
203
220
    }
204
221
  }
205
 
  inline bool alloc(size_t arg_length)
 
222
  inline bool alloc(uint32_t arg_length)
206
223
  {
207
224
    if (arg_length < Alloced_length)
208
225
      return 0;
209
226
    return real_alloc(arg_length);
210
227
  }
211
 
  bool real_alloc(size_t arg_length);                   // Empties old string
212
 
  bool realloc(size_t arg_length);
213
 
  inline void shrink(size_t arg_length)         // Shrink buffer
 
228
  bool real_alloc(uint32_t arg_length);                 // Empties old string
 
229
  bool realloc(uint32_t arg_length);
 
230
  inline void shrink(uint32_t arg_length)               // Shrink buffer
214
231
  {
215
232
    if (arg_length < Alloced_length)
216
233
    {
217
234
      char *new_ptr;
218
 
      if (!(new_ptr= reinterpret_cast<char*>(::realloc(Ptr,arg_length))))
 
235
      if (!(new_ptr=(char*) ::realloc(Ptr,arg_length)))
219
236
      {
220
237
        Alloced_length = 0;
221
238
        real_alloc(arg_length);
246
263
 
247
264
  bool copy();                                  // Alloc string if not alloced
248
265
  bool copy(const String &s);                   // Allocate new string
249
 
  bool copy(const char *s,size_t arg_length, const CHARSET_INFO * const cs);    // Allocate new string
250
 
  static bool needs_conversion(size_t arg_length,
 
266
  bool copy(const char *s,uint32_t arg_length, const CHARSET_INFO * const cs);  // Allocate new string
 
267
  static bool needs_conversion(uint32_t arg_length,
251
268
                               const CHARSET_INFO * const cs_from, const CHARSET_INFO * const cs_to,
252
 
                               size_t *offset);
253
 
  bool set_or_copy_aligned(const char *s, size_t arg_length, const CHARSET_INFO * const cs);
254
 
  bool copy(const char*s,size_t arg_length, const CHARSET_INFO * const csfrom,
255
 
            const CHARSET_INFO * const csto, size_t *errors);
 
269
                               uint32_t *offset);
 
270
  bool copy_aligned(const char *s, uint32_t arg_length, uint32_t offset,
 
271
                    const CHARSET_INFO * const cs);
 
272
  bool set_or_copy_aligned(const char *s, uint32_t arg_length, const CHARSET_INFO * const cs);
 
273
  bool copy(const char*s,uint32_t arg_length, const CHARSET_INFO * const csfrom,
 
274
            const CHARSET_INFO * const csto, uint32_t *errors);
256
275
  bool append(const String &s);
257
276
  bool append(const char *s);
258
 
  bool append(const char *s,size_t arg_length);
259
 
  bool append(const char *s,size_t arg_length, const CHARSET_INFO * const cs);
260
 
  bool append_with_prefill(const char *s, size_t arg_length,
261
 
                           size_t full_length, char fill_char);
262
 
  int strstr(const String &search,size_t offset=0); // Returns offset to substring or -1
263
 
  int strrstr(const String &search,size_t offset=0); // Returns offset to substring or -1
264
 
  bool replace(size_t offset,size_t arg_length,const char *to,size_t length);
265
 
  bool replace(size_t offset,size_t arg_length,const String &to);
 
277
  bool append(const char *s,uint32_t arg_length);
 
278
  bool append(const char *s,uint32_t arg_length, const CHARSET_INFO * const cs);
 
279
  bool append(IO_CACHE* file, uint32_t arg_length);
 
280
  bool append_with_prefill(const char *s, uint32_t arg_length,
 
281
                           uint32_t full_length, char fill_char);
 
282
  int strstr(const String &search,uint32_t offset=0); // Returns offset to substring or -1
 
283
  int strrstr(const String &search,uint32_t offset=0); // Returns offset to substring or -1
 
284
  bool replace(uint32_t offset,uint32_t arg_length,const char *to,uint32_t length);
 
285
  bool replace(uint32_t offset,uint32_t arg_length,const String &to);
266
286
  inline bool append(char chr)
267
287
  {
268
288
    if (str_length < Alloced_length)
277
297
    }
278
298
    return 0;
279
299
  }
 
300
  bool fill(uint32_t max_length,char fill);
280
301
  friend int sortcmp(const String *a,const String *b, const CHARSET_INFO * const cs);
281
302
  friend int stringcmp(const String *a,const String *b);
282
 
  friend String *copy_if_not_alloced(String *a,String *b,size_t arg_length);
283
 
  size_t numchars();
284
 
  int charpos(int i,size_t offset=0);
 
303
  friend String *copy_if_not_alloced(String *a,String *b,uint32_t arg_length);
 
304
  uint32_t numchars();
 
305
  int charpos(int i,uint32_t offset=0);
285
306
 
286
 
  int reserve(size_t space_needed)
 
307
  int reserve(uint32_t space_needed)
287
308
  {
288
309
    return realloc(str_length + space_needed);
289
310
  }
290
 
  int reserve(size_t space_needed, size_t grow_by);
 
311
  int reserve(uint32_t space_needed, uint32_t grow_by);
291
312
 
292
313
  /*
293
314
    The following append operations do NOT check alloced memory
294
315
    q_*** methods writes values of parameters itself
295
316
    qs_*** methods writes string representation of value
296
317
  */
297
 
  void q_append(const char c);
298
 
  void q_append(const size_t n);
299
 
  void q_append(double d);
300
 
  void q_append(double *d);
301
 
  void q_append(const char *data, size_t data_len);
302
 
  void write_at_position(int position, size_t value);
 
318
  void q_append(const char c)
 
319
  {
 
320
    Ptr[str_length++] = c;
 
321
  }
 
322
  void q_append(const uint32_t n)
 
323
  {
 
324
    int4store(Ptr + str_length, n);
 
325
    str_length += 4;
 
326
  }
 
327
  void q_append(double d)
 
328
  {
 
329
    float8store(Ptr + str_length, d);
 
330
    str_length += 8;
 
331
  }
 
332
  void q_append(double *d)
 
333
  {
 
334
    float8store(Ptr + str_length, *d);
 
335
    str_length += 8;
 
336
  }
 
337
  void q_append(const char *data, uint32_t data_len)
 
338
  {
 
339
    memcpy(Ptr + str_length, data, data_len);
 
340
    str_length += data_len;
 
341
  }
 
342
 
 
343
  void write_at_position(int position, uint32_t value)
 
344
  {
 
345
    int4store(Ptr + position,value);
 
346
  }
 
347
 
 
348
  void qs_append(const char *str, uint32_t len);
 
349
  void qs_append(double d);
 
350
  void qs_append(double *d);
 
351
  inline void qs_append(const char c)
 
352
  {
 
353
     Ptr[str_length]= c;
 
354
     str_length++;
 
355
  }
 
356
  void qs_append(int i);
 
357
  void qs_append(uint32_t i);
303
358
 
304
359
  /* Inline (general) functions used by the protocol functions */
305
360
 
306
 
  inline char *prep_append(size_t arg_length, size_t step_alloc)
 
361
  inline char *prep_append(uint32_t arg_length, uint32_t step_alloc)
307
362
  {
308
 
    size_t new_length= arg_length + str_length;
 
363
    uint32_t new_length= arg_length + str_length;
309
364
    if (new_length > Alloced_length)
310
365
    {
311
366
      if (realloc(new_length + step_alloc))
312
367
        return 0;
313
368
    }
314
 
    size_t old_length= str_length;
 
369
    uint32_t old_length= str_length;
315
370
    str_length+= arg_length;
316
371
    return Ptr+ old_length;                     /* Area to use */
317
372
  }
318
373
 
319
 
  inline bool append(const char *s, size_t arg_length, size_t step_alloc)
 
374
  inline bool append(const char *s, uint32_t arg_length, uint32_t step_alloc)
320
375
  {
321
 
    size_t new_length= arg_length + str_length;
 
376
    uint32_t new_length= arg_length + str_length;
322
377
    if (new_length > Alloced_length && realloc(new_length + step_alloc))
323
378
      return true;
324
379
    memcpy(Ptr+str_length, s, arg_length);
336
391
  }
337
392
};
338
393
 
339
 
bool check_if_only_end_space(const CHARSET_INFO * const cs, char *str,
340
 
                             char *end);
341
 
 
342
 
} /* namespace drizzled */
343
 
 
344
 
bool operator==(const drizzled::String &s1, const drizzled::String &s2);
345
 
bool operator!=(const drizzled::String &s1, const drizzled::String &s2);
346
 
 
347
 
 
348
 
#endif /* DRIZZLED_SQL_STRING_H */
 
394
static inline bool check_if_only_end_space(const CHARSET_INFO * const cs, char *str,
 
395
                                           char *end)
 
396
{
 
397
  return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end;
 
398
}
 
399
 
 
400
extern "C++" {
 
401
bool operator==(const String &s1, const String &s2);
 
402
bool operator!=(const String &s1, const String &s2);
 
403
}
 
404
 
 
405
#endif /* DRIZZLE_SERVER_SQL_STRING_H */