~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2003 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
17
/* This file defines all string functions */
18
19
#ifdef USE_PRAGMA_INTERFACE
20
#pragma interface			/* gcc class implementation */
21
#endif
22
23
class Item_str_func :public Item_func
24
{
25
public:
26
  Item_str_func() :Item_func() { decimals=NOT_FIXED_DEC; }
27
  Item_str_func(Item *a) :Item_func(a) {decimals=NOT_FIXED_DEC; }
28
  Item_str_func(Item *a,Item *b) :Item_func(a,b) { decimals=NOT_FIXED_DEC; }
29
  Item_str_func(Item *a,Item *b,Item *c) :Item_func(a,b,c) { decimals=NOT_FIXED_DEC; }
30
  Item_str_func(Item *a,Item *b,Item *c,Item *d) :Item_func(a,b,c,d) {decimals=NOT_FIXED_DEC; }
31
  Item_str_func(Item *a,Item *b,Item *c,Item *d, Item* e) :Item_func(a,b,c,d,e) {decimals=NOT_FIXED_DEC; }
32
  Item_str_func(List<Item> &list) :Item_func(list) {decimals=NOT_FIXED_DEC; }
152 by Brian Aker
longlong replacement
33
  int64_t val_int();
1 by brian
clean slate
34
  double val_real();
35
  my_decimal *val_decimal(my_decimal *);
36
  enum Item_result result_type () const { return STRING_RESULT; }
37
  void left_right_max_length();
38
  bool fix_fields(THD *thd, Item **ref);
39
};
40
41
42
class Item_func_concat :public Item_str_func
43
{
44
  String tmp_value;
45
public:
46
  Item_func_concat(List<Item> &list) :Item_str_func(list) {}
47
  Item_func_concat(Item *a,Item *b) :Item_str_func(a,b) {}
48
  String *val_str(String *);
49
  void fix_length_and_dec();
50
  const char *func_name() const { return "concat"; }
51
};
52
53
class Item_func_concat_ws :public Item_str_func
54
{
55
  String tmp_value;
56
public:
57
  Item_func_concat_ws(List<Item> &list) :Item_str_func(list) {}
58
  String *val_str(String *);
59
  void fix_length_and_dec();
60
  const char *func_name() const { return "concat_ws"; }
61
  table_map not_null_tables() const { return 0; }
62
};
63
64
class Item_func_reverse :public Item_str_func
65
{
66
  String tmp_value;
67
public:
68
  Item_func_reverse(Item *a) :Item_str_func(a) {}
69
  String *val_str(String *);
70
  void fix_length_and_dec();
71
  const char *func_name() const { return "reverse"; }
72
};
73
74
75
class Item_func_replace :public Item_str_func
76
{
77
  String tmp_value,tmp_value2;
78
public:
79
  Item_func_replace(Item *org,Item *find,Item *replace)
80
    :Item_str_func(org,find,replace) {}
81
  String *val_str(String *);
82
  void fix_length_and_dec();
83
  const char *func_name() const { return "replace"; }
84
};
85
86
87
class Item_func_insert :public Item_str_func
88
{
89
  String tmp_value;
90
public:
91
  Item_func_insert(Item *org,Item *start,Item *length,Item *new_str)
92
    :Item_str_func(org,start,length,new_str) {}
93
  String *val_str(String *);
94
  void fix_length_and_dec();
95
  const char *func_name() const { return "insert"; }
96
};
97
98
99
class Item_str_conv :public Item_str_func
100
{
101
protected:
102
  uint multiply;
103
  my_charset_conv_case converter;
104
  String tmp_value;
105
public:
106
  Item_str_conv(Item *item) :Item_str_func(item) {}
107
  String *val_str(String *);
108
};
109
110
111
class Item_func_lcase :public Item_str_conv
112
{
113
public:
114
  Item_func_lcase(Item *item) :Item_str_conv(item) {}
115
  const char *func_name() const { return "lcase"; }
116
  void fix_length_and_dec();
117
};
118
119
class Item_func_ucase :public Item_str_conv
120
{
121
public:
122
  Item_func_ucase(Item *item) :Item_str_conv(item) {}
123
  const char *func_name() const { return "ucase"; }
124
  void fix_length_and_dec();
125
};
126
127
128
class Item_func_left :public Item_str_func
129
{
130
  String tmp_value;
131
public:
132
  Item_func_left(Item *a,Item *b) :Item_str_func(a,b) {}
133
  String *val_str(String *);
134
  void fix_length_and_dec();
135
  const char *func_name() const { return "left"; }
136
};
137
138
139
class Item_func_right :public Item_str_func
140
{
141
  String tmp_value;
142
public:
143
  Item_func_right(Item *a,Item *b) :Item_str_func(a,b) {}
144
  String *val_str(String *);
145
  void fix_length_and_dec();
146
  const char *func_name() const { return "right"; }
147
};
148
149
150
class Item_func_substr :public Item_str_func
151
{
152
  String tmp_value;
153
public:
154
  Item_func_substr(Item *a,Item *b) :Item_str_func(a,b) {}
155
  Item_func_substr(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
156
  String *val_str(String *);
157
  void fix_length_and_dec();
158
  const char *func_name() const { return "substr"; }
159
};
160
161
162
class Item_func_substr_index :public Item_str_func
163
{
164
  String tmp_value;
165
public:
166
  Item_func_substr_index(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
167
  String *val_str(String *);
168
  void fix_length_and_dec();
169
  const char *func_name() const { return "substring_index"; }
170
};
171
172
173
class Item_func_trim :public Item_str_func
174
{
175
protected:
176
  String tmp_value;
177
  String remove;
178
public:
179
  Item_func_trim(Item *a,Item *b) :Item_str_func(a,b) {}
180
  Item_func_trim(Item *a) :Item_str_func(a) {}
181
  String *val_str(String *);
182
  void fix_length_and_dec();
183
  const char *func_name() const { return "trim"; }
184
  virtual void print(String *str, enum_query_type query_type);
185
  virtual const char *mode_name() const { return "both"; }
186
};
187
188
189
class Item_func_ltrim :public Item_func_trim
190
{
191
public:
192
  Item_func_ltrim(Item *a,Item *b) :Item_func_trim(a,b) {}
193
  Item_func_ltrim(Item *a) :Item_func_trim(a) {}
194
  String *val_str(String *);
195
  const char *func_name() const { return "ltrim"; }
196
  const char *mode_name() const { return "leading"; }
197
};
198
199
200
class Item_func_rtrim :public Item_func_trim
201
{
202
public:
203
  Item_func_rtrim(Item *a,Item *b) :Item_func_trim(a,b) {}
204
  Item_func_rtrim(Item *a) :Item_func_trim(a) {}
205
  String *val_str(String *);
206
  const char *func_name() const { return "rtrim"; }
207
  const char *mode_name() const { return "trailing"; }
208
};
209
210
211
class Item_func_sysconst :public Item_str_func
212
{
213
public:
214
  Item_func_sysconst()
215
  { collation.set(system_charset_info,DERIVATION_SYSCONST); }
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
216
  Item *safe_charset_converter(const CHARSET_INFO * const tocs);
1 by brian
clean slate
217
  /*
218
    Used to create correct Item name in new converted item in
219
    safe_charset_converter, return string representation of this function
220
    call
221
  */
222
  virtual const char *fully_qualified_func_name() const = 0;
223
};
224
225
226
class Item_func_database :public Item_func_sysconst
227
{
228
public:
229
  Item_func_database() :Item_func_sysconst() {}
230
  String *val_str(String *);
231
  void fix_length_and_dec()
232
  {
233
    max_length= MAX_FIELD_NAME * system_charset_info->mbmaxlen;
234
    maybe_null=1;
235
  }
236
  const char *func_name() const { return "database"; }
237
  const char *fully_qualified_func_name() const { return "database()"; }
238
};
239
240
241
class Item_func_user :public Item_func_sysconst
242
{
243
protected:
244
  bool init (const char *user, const char *host);
245
246
public:
247
  Item_func_user()
248
  {
249
    str_value.set("", 0, system_charset_info);
250
  }
251
  String *val_str(String *)
252
  {
51.1.23 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
253
    assert(fixed == 1);
1 by brian
clean slate
254
    return (null_value ? 0 : &str_value);
255
  }
256
  bool fix_fields(THD *thd, Item **ref);
257
  void fix_length_and_dec()
258
  {
259
    max_length= (USERNAME_CHAR_LENGTH + HOSTNAME_LENGTH + 1) *
260
                system_charset_info->mbmaxlen;
261
  }
262
  const char *func_name() const { return "user"; }
263
  const char *fully_qualified_func_name() const { return "user()"; }
77.1.7 by Monty Taylor
Heap builds clean.
264
  int save_in_field(Field *field,
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
265
                    bool no_conversions __attribute__((unused)))
1 by brian
clean slate
266
  {
267
    return save_str_value_in_field(field, &str_value);
268
  }
269
};
270
271
272
class Item_func_current_user :public Item_func_user
273
{
274
  Name_resolution_context *context;
275
276
public:
277
  Item_func_current_user(Name_resolution_context *context_arg)
278
    : context(context_arg) {}
279
  bool fix_fields(THD *thd, Item **ref);
280
  const char *func_name() const { return "current_user"; }
281
  const char *fully_qualified_func_name() const { return "current_user()"; }
282
};
283
284
285
class Item_func_soundex :public Item_str_func
286
{
287
  String tmp_value;
288
public:
289
  Item_func_soundex(Item *a) :Item_str_func(a) {}
290
  String *val_str(String *);
291
  void fix_length_and_dec();
292
  const char *func_name() const { return "soundex"; }
293
};
294
295
296
class Item_func_elt :public Item_str_func
297
{
298
public:
299
  Item_func_elt(List<Item> &list) :Item_str_func(list) {}
300
  double val_real();
152 by Brian Aker
longlong replacement
301
  int64_t val_int();
1 by brian
clean slate
302
  String *val_str(String *str);
303
  void fix_length_and_dec();
304
  const char *func_name() const { return "elt"; }
305
};
306
307
308
class Item_func_make_set :public Item_str_func
309
{
310
  Item *item;
311
  String tmp_str;
312
313
public:
314
  Item_func_make_set(Item *a,List<Item> &list) :Item_str_func(list),item(a) {}
315
  String *val_str(String *str);
316
  bool fix_fields(THD *thd, Item **ref)
317
  {
51.1.23 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
318
    assert(fixed == 0);
1 by brian
clean slate
319
    return ((!item->fixed && item->fix_fields(thd, &item)) ||
320
	    item->check_cols(1) ||
321
	    Item_func::fix_fields(thd, ref));
322
  }
323
  void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
324
  void fix_length_and_dec();
325
  void update_used_tables();
326
  const char *func_name() const { return "make_set"; }
327
328
  bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
329
  {
330
    return item->walk(processor, walk_subquery, arg) ||
331
      Item_str_func::walk(processor, walk_subquery, arg);
332
  }
333
  Item *transform(Item_transformer transformer, uchar *arg);
334
  virtual void print(String *str, enum_query_type query_type);
335
};
336
337
338
class Item_func_format :public Item_str_func
339
{
340
  String tmp_str;
341
public:
342
  Item_func_format(Item *org, Item *dec);
343
  String *val_str(String *);
344
  void fix_length_and_dec();
345
  const char *func_name() const { return "format"; }
346
  virtual void print(String *str, enum_query_type query_type);
347
};
348
349
350
class Item_func_char :public Item_str_func
351
{
352
public:
353
  Item_func_char(List<Item> &list) :Item_str_func(list)
354
  { collation.set(&my_charset_bin); }
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
355
  Item_func_char(List<Item> &list, const CHARSET_INFO * const cs) :Item_str_func(list)
1 by brian
clean slate
356
  { collation.set(cs); }  
357
  String *val_str(String *);
358
  void fix_length_and_dec() 
359
  {
360
    max_length= arg_count * 4;
361
  }
362
  const char *func_name() const { return "char"; }
363
};
364
365
366
class Item_func_repeat :public Item_str_func
367
{
368
  String tmp_value;
369
public:
370
  Item_func_repeat(Item *arg1,Item *arg2) :Item_str_func(arg1,arg2) {}
371
  String *val_str(String *);
372
  void fix_length_and_dec();
373
  const char *func_name() const { return "repeat"; }
374
};
375
376
377
class Item_func_rpad :public Item_str_func
378
{
379
  String tmp_value, rpad_str;
380
public:
381
  Item_func_rpad(Item *arg1,Item *arg2,Item *arg3)
382
    :Item_str_func(arg1,arg2,arg3) {}
383
  String *val_str(String *);
384
  void fix_length_and_dec();
385
  const char *func_name() const { return "rpad"; }
386
};
387
388
389
class Item_func_lpad :public Item_str_func
390
{
391
  String tmp_value, lpad_str;
392
public:
393
  Item_func_lpad(Item *arg1,Item *arg2,Item *arg3)
394
    :Item_str_func(arg1,arg2,arg3) {}
395
  String *val_str(String *);
396
  void fix_length_and_dec();
397
  const char *func_name() const { return "lpad"; }
398
};
399
400
401
class Item_func_conv :public Item_str_func
402
{
403
public:
404
  Item_func_conv(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
405
  const char *func_name() const { return "conv"; }
406
  String *val_str(String *);
407
  void fix_length_and_dec()
408
  {
409
    collation.set(default_charset());
410
    max_length=64;
411
    maybe_null= 1;
412
  }
413
};
414
415
416
class Item_func_hex :public Item_str_func
417
{
418
  String tmp_value;
419
public:
420
  Item_func_hex(Item *a) :Item_str_func(a) {}
421
  const char *func_name() const { return "hex"; }
422
  String *val_str(String *);
423
  void fix_length_and_dec()
424
  {
425
    collation.set(default_charset());
426
    decimals=0;
427
    max_length=args[0]->max_length*2*collation.collation->mbmaxlen;
428
  }
429
};
430
431
class Item_func_unhex :public Item_str_func
432
{
433
  String tmp_value;
434
public:
435
  Item_func_unhex(Item *a) :Item_str_func(a) 
436
  { 
437
    /* there can be bad hex strings */
438
    maybe_null= 1; 
439
  }
440
  const char *func_name() const { return "unhex"; }
441
  String *val_str(String *);
442
  void fix_length_and_dec()
443
  {
444
    collation.set(&my_charset_bin);
445
    decimals=0;
446
    max_length=(1+args[0]->max_length)/2;
447
  }
448
};
449
450
451
class Item_func_binary :public Item_str_func
452
{
453
public:
454
  Item_func_binary(Item *a) :Item_str_func(a) {}
455
  String *val_str(String *a)
456
  {
51.1.23 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
457
    assert(fixed == 1);
1 by brian
clean slate
458
    String *tmp=args[0]->val_str(a);
459
    null_value=args[0]->null_value;
460
    if (tmp)
461
      tmp->set_charset(&my_charset_bin);
462
    return tmp;
463
  }
464
  void fix_length_and_dec()
465
  {
466
    collation.set(&my_charset_bin);
467
    max_length=args[0]->max_length;
468
  }
469
  virtual void print(String *str, enum_query_type query_type);
470
  const char *func_name() const { return "cast_as_binary"; }
471
};
472
473
474
class Item_load_file :public Item_str_func
475
{
476
  String tmp_value;
477
public:
478
  Item_load_file(Item *a) :Item_str_func(a) {}
479
  String *val_str(String *);
480
  const char *func_name() const { return "load_file"; }
481
  void fix_length_and_dec()
482
  {
483
    collation.set(&my_charset_bin, DERIVATION_COERCIBLE);
484
    maybe_null=1;
485
    max_length=MAX_BLOB_WIDTH;
486
  }
487
};
488
489
490
class Item_func_export_set: public Item_str_func
491
{
492
 public:
493
  Item_func_export_set(Item *a,Item *b,Item* c) :Item_str_func(a,b,c) {}
494
  Item_func_export_set(Item *a,Item *b,Item* c,Item* d) :Item_str_func(a,b,c,d) {}
495
  Item_func_export_set(Item *a,Item *b,Item* c,Item* d,Item* e) :Item_str_func(a,b,c,d,e) {}
496
  String  *val_str(String *str);
497
  void fix_length_and_dec();
498
  const char *func_name() const { return "export_set"; }
499
};
500
501
class Item_func_quote :public Item_str_func
502
{
503
  String tmp_value;
504
public:
505
  Item_func_quote(Item *a) :Item_str_func(a) {}
506
  const char *func_name() const { return "quote"; }
507
  String *val_str(String *);
508
  void fix_length_and_dec()
509
  {
510
    collation.set(args[0]->collation);
511
    max_length= args[0]->max_length * 2 + 2;
512
  }
513
};
514
515
class Item_func_conv_charset :public Item_str_func
516
{
517
  bool use_cached_value;
518
public:
519
  bool safe;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
520
  const CHARSET_INFO *conv_charset; // keep it public
521
  Item_func_conv_charset(Item *a, const CHARSET_INFO * const cs) :Item_str_func(a) 
1 by brian
clean slate
522
  { conv_charset= cs; use_cached_value= 0; safe= 0; }
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
523
  Item_func_conv_charset(Item *a, const CHARSET_INFO * const cs, bool cache_if_const) 
1 by brian
clean slate
524
    :Item_str_func(a) 
525
  {
51.1.23 by Jay Pipes
Removed DBUG symbols and fixed TRUE/FALSE
526
    assert(args[0]->fixed);
1 by brian
clean slate
527
    conv_charset= cs;
528
    if (cache_if_const && args[0]->const_item())
529
    {
530
      uint errors= 0;
531
      String tmp, *str= args[0]->val_str(&tmp);
532
      if (!str || str_value.copy(str->ptr(), str->length(),
533
                                 str->charset(), conv_charset, &errors))
534
        null_value= 1;
535
      use_cached_value= 1;
536
      str_value.mark_as_const();
537
      safe= (errors == 0);
538
    }
539
    else
540
    {
541
      use_cached_value= 0;
542
      /*
543
        Conversion from and to "binary" is safe.
544
        Conversion to Unicode is safe.
545
        Other kind of conversions are potentially lossy.
546
      */
547
      safe= (args[0]->collation.collation == &my_charset_bin ||
548
             cs == &my_charset_bin ||
549
             (cs->state & MY_CS_UNICODE));
550
    }
551
  }
552
  String *val_str(String *);
553
  void fix_length_and_dec();
554
  const char *func_name() const { return "convert"; }
555
  virtual void print(String *str, enum_query_type query_type);
556
};
557
558
class Item_func_set_collation :public Item_str_func
559
{
560
public:
561
  Item_func_set_collation(Item *a, Item *b) :Item_str_func(a,b) {};
562
  String *val_str(String *);
563
  void fix_length_and_dec();
564
  bool eq(const Item *item, bool binary_cmp) const;
565
  const char *func_name() const { return "collate"; }
566
  enum Functype functype() const { return COLLATE_FUNC; }
567
  virtual void print(String *str, enum_query_type query_type);
568
  Item_field *filed_for_view_update()
569
  {
570
    /* this function is transparent for view updating */
571
    return args[0]->filed_for_view_update();
572
  }
573
};
574
575
class Item_func_charset :public Item_str_func
576
{
577
public:
578
  Item_func_charset(Item *a) :Item_str_func(a) {}
579
  String *val_str(String *);
580
  const char *func_name() const { return "charset"; }
581
  void fix_length_and_dec()
582
  {
583
     collation.set(system_charset_info);
584
     max_length= 64 * collation.collation->mbmaxlen; // should be enough
585
     maybe_null= 0;
586
  };
587
  table_map not_null_tables() const { return 0; }
588
};
589
590
class Item_func_collation :public Item_str_func
591
{
592
public:
593
  Item_func_collation(Item *a) :Item_str_func(a) {}
594
  String *val_str(String *);
595
  const char *func_name() const { return "collation"; }
596
  void fix_length_and_dec()
597
  {
598
     collation.set(system_charset_info);
599
     max_length= 64 * collation.collation->mbmaxlen; // should be enough
600
     maybe_null= 0;
601
  };
602
  table_map not_null_tables() const { return 0; }
603
};
604
605
606
class Item_func_weight_string :public Item_str_func
607
{
608
  String tmp_value;
609
  uint flags;
610
  uint nweights;
611
public:
612
  Item_func_weight_string(Item *a, uint nweights_arg, uint flags_arg)
613
  :Item_str_func(a) { nweights= nweights_arg; flags= flags_arg; }
614
  const char *func_name() const { return "weight_string"; }
615
  String *val_str(String *);
616
  void fix_length_and_dec();
617
};
618
619
class Item_func_uncompressed_length : public Item_int_func
620
{
621
  String value;
622
public:
623
  Item_func_uncompressed_length(Item *a):Item_int_func(a){}
624
  const char *func_name() const{return "uncompressed_length";}
625
  void fix_length_and_dec() { max_length=10; }
152 by Brian Aker
longlong replacement
626
  int64_t val_int();
1 by brian
clean slate
627
};
628
629
#ifdef HAVE_COMPRESS
630
#define ZLIB_DEPENDED_FUNCTION ;
631
#else
632
#define ZLIB_DEPENDED_FUNCTION { null_value=1; return 0; }
633
#endif
634
635
class Item_func_compress: public Item_str_func
636
{
637
  String buffer;
638
public:
639
  Item_func_compress(Item *a):Item_str_func(a){}
640
  void fix_length_and_dec(){max_length= (args[0]->max_length*120)/100+12;}
641
  const char *func_name() const{return "compress";}
642
  String *val_str(String *) ZLIB_DEPENDED_FUNCTION
643
};
644
645
class Item_func_uncompress: public Item_str_func
646
{
647
  String buffer;
648
public:
649
  Item_func_uncompress(Item *a): Item_str_func(a){}
650
  void fix_length_and_dec(){ maybe_null= 1; max_length= MAX_BLOB_WIDTH; }
651
  const char *func_name() const{return "uncompress";}
652
  String *val_str(String *) ZLIB_DEPENDED_FUNCTION
653
};
654
655
#define UUID_LENGTH (8+1+4+1+4+1+4+1+12)
656
class Item_func_uuid: public Item_str_func
657
{
658
public:
659
  Item_func_uuid(): Item_str_func() {}
660
  void fix_length_and_dec() {
661
    collation.set(system_charset_info);
662
    /*
663
       NOTE! uuid() should be changed to use 'ascii'
664
       charset when hex(), format(), md5(), etc, and implicit
665
       number-to-string conversion will use 'ascii'
666
    */
667
    max_length= UUID_LENGTH * system_charset_info->mbmaxlen;
668
  }
669
  const char *func_name() const{ return "uuid"; }
670
  String *val_str(String *);
671
};
672