~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item_strfunc.cc

  • Committer: Monty Taylor
  • Date: 2008-11-07 04:45:58 UTC
  • mfrom: (574.3.4 drizzle-clean-code)
  • mto: This revision was merged to the branch mainline in revision 579.
  • Revision ID: monty@inaugust.com-20081107044558-2me2c70ksfr3qs9i
Merged from Lee (and from trunk by proxy)

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
 
46
46
String my_empty_string("",default_charset_info);
47
47
 
48
 
 
49
 
 
50
 
 
51
 
bool Item_str_func::fix_fields(Session *session, Item **ref)
52
 
{
53
 
  bool res= Item_func::fix_fields(session, ref);
54
 
  /*
55
 
    In Item_str_func::check_well_formed_result() we may set null_value
56
 
    flag on the same condition as in test() below.
57
 
  */
58
 
  maybe_null= (maybe_null || true);
59
 
  return res;
60
 
}
61
 
 
62
 
 
63
 
my_decimal *Item_str_func::val_decimal(my_decimal *decimal_value)
64
 
{
65
 
  assert(fixed == 1);
66
 
  char buff[64];
67
 
  String *res, tmp(buff,sizeof(buff), &my_charset_bin);
68
 
  res= val_str(&tmp);
69
 
  if (!res)
70
 
    return 0;
71
 
  (void)str2my_decimal(E_DEC_FATAL_ERROR, (char*) res->ptr(),
72
 
                       res->length(), res->charset(), decimal_value);
73
 
  return decimal_value;
74
 
}
75
 
 
76
 
 
77
 
double Item_str_func::val_real()
78
 
{
79
 
  assert(fixed == 1);
80
 
  int err_not_used;
81
 
  char *end_not_used, buff[64];
82
 
  String *res, tmp(buff,sizeof(buff), &my_charset_bin);
83
 
  res= val_str(&tmp);
84
 
  return res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
85
 
                          &end_not_used, &err_not_used) : 0.0;
86
 
}
87
 
 
88
 
 
89
 
int64_t Item_str_func::val_int()
90
 
{
91
 
  assert(fixed == 1);
92
 
  int err;
93
 
  char buff[22];
94
 
  String *res, tmp(buff,sizeof(buff), &my_charset_bin);
95
 
  res= val_str(&tmp);
96
 
  return (res ?
97
 
          my_strntoll(res->charset(), res->ptr(), res->length(), 10, NULL,
98
 
                      &err) :
99
 
          (int64_t) 0);
100
 
}
101
 
 
102
 
/**
103
 
  Concatenate args with the following premises:
104
 
  If only one arg (which is ok), return value of arg;
105
 
  Don't reallocate val_str() if not absolute necessary.
106
 
*/
107
 
 
108
 
String *Item_func_concat::val_str(String *str)
109
 
{
110
 
  assert(fixed == 1);
111
 
  String *res,*res2,*use_as_buff;
112
 
  uint32_t i;
113
 
  bool is_const= 0;
114
 
 
115
 
  null_value=0;
116
 
  if (!(res=args[0]->val_str(str)))
117
 
    goto null;
118
 
  use_as_buff= &tmp_value;
119
 
  /* Item_subselect in --ps-protocol mode will state it as a non-const */
120
 
  is_const= args[0]->const_item() || !args[0]->used_tables();
121
 
  for (i=1 ; i < arg_count ; i++)
122
 
  {
123
 
    if (res->length() == 0)
124
 
    {
125
 
      if (!(res=args[i]->val_str(str)))
126
 
        goto null;
127
 
    }
128
 
    else
129
 
    {
130
 
      if (!(res2=args[i]->val_str(use_as_buff)))
131
 
        goto null;
132
 
      if (res2->length() == 0)
133
 
        continue;
134
 
      if (res->length()+res2->length() >
135
 
          current_session->variables.max_allowed_packet)
136
 
      {
137
 
        push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
138
 
                            ER_WARN_ALLOWED_PACKET_OVERFLOWED,
139
 
                            ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
140
 
                            current_session->variables.max_allowed_packet);
141
 
        goto null;
142
 
      }
143
 
      if (!is_const && res->alloced_length() >= res->length()+res2->length())
144
 
      {                                         // Use old buffer
145
 
        res->append(*res2);
146
 
      }
147
 
      else if (str->alloced_length() >= res->length()+res2->length())
148
 
      {
149
 
        if (str == res2)
150
 
          str->replace(0,0,*res);
151
 
        else
152
 
        {
153
 
          str->copy(*res);
154
 
          str->append(*res2);
155
 
        }
156
 
        res= str;
157
 
        use_as_buff= &tmp_value;
158
 
      }
159
 
      else if (res == &tmp_value)
160
 
      {
161
 
        if (res->append(*res2))                 // Must be a blob
162
 
          goto null;
163
 
      }
164
 
      else if (res2 == &tmp_value)
165
 
      {                                         // This can happend only 1 time
166
 
        if (tmp_value.replace(0,0,*res))
167
 
          goto null;
168
 
        res= &tmp_value;
169
 
        use_as_buff=str;                        // Put next arg here
170
 
      }
171
 
      else if (tmp_value.is_alloced() && res2->ptr() >= tmp_value.ptr() &&
172
 
               res2->ptr() <= tmp_value.ptr() + tmp_value.alloced_length())
173
 
      {
174
 
        /*
175
 
          This happens really seldom:
176
 
          In this case res2 is sub string of tmp_value.  We will
177
 
          now work in place in tmp_value to set it to res | res2
178
 
        */
179
 
        /* Chop the last characters in tmp_value that isn't in res2 */
180
 
        tmp_value.length((uint32_t) (res2->ptr() - tmp_value.ptr()) +
181
 
                         res2->length());
182
 
        /* Place res2 at start of tmp_value, remove chars before res2 */
183
 
        if (tmp_value.replace(0,(uint32_t) (res2->ptr() - tmp_value.ptr()),
184
 
                              *res))
185
 
          goto null;
186
 
        res= &tmp_value;
187
 
        use_as_buff=str;                        // Put next arg here
188
 
      }
189
 
      else
190
 
      {                                         // Two big const strings
191
 
        /*
192
 
          NOTE: We should be prudent in the initial allocation unit -- the
193
 
          size of the arguments is a function of data distribution, which
194
 
          can be any. Instead of overcommitting at the first row, we grow
195
 
          the allocated amount by the factor of 2. This ensures that no
196
 
          more than 25% of memory will be overcommitted on average.
197
 
        */
198
 
 
199
 
        uint32_t concat_len= res->length() + res2->length();
200
 
 
201
 
        if (tmp_value.alloced_length() < concat_len)
202
 
        {
203
 
          if (tmp_value.alloced_length() == 0)
204
 
          {
205
 
            if (tmp_value.alloc(concat_len))
206
 
              goto null;
207
 
          }
208
 
          else
209
 
          {
210
 
            uint32_t new_len = cmax(tmp_value.alloced_length() * 2, concat_len);
211
 
 
212
 
            if (tmp_value.realloc(new_len))
213
 
              goto null;
214
 
          }
215
 
        }
216
 
 
217
 
        if (tmp_value.copy(*res) || tmp_value.append(*res2))
218
 
          goto null;
219
 
 
220
 
        res= &tmp_value;
221
 
        use_as_buff=str;
222
 
      }
223
 
      is_const= 0;
224
 
    }
225
 
  }
226
 
  res->set_charset(collation.collation);
227
 
  return res;
228
 
 
229
 
null:
230
 
  null_value=1;
231
 
  return 0;
232
 
}
233
 
 
234
 
 
235
 
void Item_func_concat::fix_length_and_dec()
236
 
{
237
 
  uint64_t max_result_length= 0;
238
 
 
239
 
  if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1))
240
 
    return;
241
 
 
242
 
  for (uint32_t i=0 ; i < arg_count ; i++)
243
 
  {
244
 
    if (args[i]->collation.collation->mbmaxlen != collation.collation->mbmaxlen)
245
 
      max_result_length+= (args[i]->max_length /
246
 
                           args[i]->collation.collation->mbmaxlen) *
247
 
                           collation.collation->mbmaxlen;
248
 
    else
249
 
      max_result_length+= args[i]->max_length;
250
 
  }
251
 
 
252
 
  if (max_result_length >= MAX_BLOB_WIDTH)
253
 
  {
254
 
    max_result_length= MAX_BLOB_WIDTH;
255
 
    maybe_null= 1;
256
 
  }
257
 
  max_length= (ulong) max_result_length;
258
 
}
259
 
 
260
 
 
261
 
/**
262
 
  concat with separator. First arg is the separator
263
 
  concat_ws takes at least two arguments.
264
 
*/
265
 
 
266
 
String *Item_func_concat_ws::val_str(String *str)
267
 
{
268
 
  assert(fixed == 1);
269
 
  char tmp_str_buff[10];
270
 
  String tmp_sep_str(tmp_str_buff, sizeof(tmp_str_buff),default_charset_info),
271
 
         *sep_str, *res, *res2,*use_as_buff;
272
 
  uint32_t i;
273
 
 
274
 
  null_value=0;
275
 
  if (!(sep_str= args[0]->val_str(&tmp_sep_str)))
276
 
    goto null;
277
 
 
278
 
  use_as_buff= &tmp_value;
279
 
  str->length(0);                               // QQ; Should be removed
280
 
  res=str;
281
 
 
282
 
  // Skip until non-null argument is found.
283
 
  // If not, return the empty string
284
 
  for (i=1; i < arg_count; i++)
285
 
    if ((res= args[i]->val_str(str)))
286
 
      break;
287
 
  if (i ==  arg_count)
288
 
    return &my_empty_string;
289
 
 
290
 
  for (i++; i < arg_count ; i++)
291
 
  {
292
 
    if (!(res2= args[i]->val_str(use_as_buff)))
293
 
      continue;                                 // Skip NULL
294
 
 
295
 
    if (res->length() + sep_str->length() + res2->length() >
296
 
        current_session->variables.max_allowed_packet)
297
 
    {
298
 
      push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
299
 
                          ER_WARN_ALLOWED_PACKET_OVERFLOWED,
300
 
                          ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
301
 
                          current_session->variables.max_allowed_packet);
302
 
      goto null;
303
 
    }
304
 
    if (res->alloced_length() >=
305
 
        res->length() + sep_str->length() + res2->length())
306
 
    {                                           // Use old buffer
307
 
      res->append(*sep_str);                    // res->length() > 0 always
308
 
      res->append(*res2);
309
 
    }
310
 
    else if (str->alloced_length() >=
311
 
             res->length() + sep_str->length() + res2->length())
312
 
    {
313
 
      /* We have room in str;  We can't get any errors here */
314
 
      if (str == res2)
315
 
      {                                         // This is quote uncommon!
316
 
        str->replace(0,0,*sep_str);
317
 
        str->replace(0,0,*res);
318
 
      }
319
 
      else
320
 
      {
321
 
        str->copy(*res);
322
 
        str->append(*sep_str);
323
 
        str->append(*res2);
324
 
      }
325
 
      res=str;
326
 
      use_as_buff= &tmp_value;
327
 
    }
328
 
    else if (res == &tmp_value)
329
 
    {
330
 
      if (res->append(*sep_str) || res->append(*res2))
331
 
        goto null; // Must be a blob
332
 
    }
333
 
    else if (res2 == &tmp_value)
334
 
    {                                           // This can happend only 1 time
335
 
      if (tmp_value.replace(0,0,*sep_str) || tmp_value.replace(0,0,*res))
336
 
        goto null;
337
 
      res= &tmp_value;
338
 
      use_as_buff=str;                          // Put next arg here
339
 
    }
340
 
    else if (tmp_value.is_alloced() && res2->ptr() >= tmp_value.ptr() &&
341
 
             res2->ptr() < tmp_value.ptr() + tmp_value.alloced_length())
342
 
    {
343
 
      /*
344
 
        This happens really seldom:
345
 
        In this case res2 is sub string of tmp_value.  We will
346
 
        now work in place in tmp_value to set it to res | sep_str | res2
347
 
      */
348
 
      /* Chop the last characters in tmp_value that isn't in res2 */
349
 
      tmp_value.length((uint32_t) (res2->ptr() - tmp_value.ptr()) +
350
 
                       res2->length());
351
 
      /* Place res2 at start of tmp_value, remove chars before res2 */
352
 
      if (tmp_value.replace(0,(uint32_t) (res2->ptr() - tmp_value.ptr()),
353
 
                            *res) ||
354
 
          tmp_value.replace(res->length(),0, *sep_str))
355
 
        goto null;
356
 
      res= &tmp_value;
357
 
      use_as_buff=str;                  // Put next arg here
358
 
    }
359
 
    else
360
 
    {                                           // Two big const strings
361
 
      /*
362
 
        NOTE: We should be prudent in the initial allocation unit -- the
363
 
        size of the arguments is a function of data distribution, which can
364
 
        be any. Instead of overcommitting at the first row, we grow the
365
 
        allocated amount by the factor of 2. This ensures that no more than
366
 
        25% of memory will be overcommitted on average.
367
 
      */
368
 
 
369
 
      uint32_t concat_len= res->length() + sep_str->length() + res2->length();
370
 
 
371
 
      if (tmp_value.alloced_length() < concat_len)
372
 
      {
373
 
        if (tmp_value.alloced_length() == 0)
374
 
        {
375
 
          if (tmp_value.alloc(concat_len))
376
 
            goto null;
377
 
        }
378
 
        else
379
 
        {
380
 
          uint32_t new_len = cmax(tmp_value.alloced_length() * 2, concat_len);
381
 
 
382
 
          if (tmp_value.realloc(new_len))
383
 
            goto null;
384
 
        }
385
 
      }
386
 
 
387
 
      if (tmp_value.copy(*res) ||
388
 
          tmp_value.append(*sep_str) ||
389
 
          tmp_value.append(*res2))
390
 
        goto null;
391
 
      res= &tmp_value;
392
 
      use_as_buff=str;
393
 
    }
394
 
  }
395
 
  res->set_charset(collation.collation);
396
 
  return res;
397
 
 
398
 
null:
399
 
  null_value=1;
400
 
  return 0;
401
 
}
402
 
 
403
 
 
404
 
void Item_func_concat_ws::fix_length_and_dec()
405
 
{
406
 
  uint64_t max_result_length;
407
 
 
408
 
  if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1))
409
 
    return;
410
 
 
411
 
  /*
412
 
     arg_count cannot be less than 2,
413
 
     it is done on parser level in sql_yacc.yy
414
 
     so, (arg_count - 2) is safe here.
415
 
  */
416
 
  max_result_length= (uint64_t) args[0]->max_length * (arg_count - 2);
417
 
  for (uint32_t i=1 ; i < arg_count ; i++)
418
 
    max_result_length+=args[i]->max_length;
419
 
 
420
 
  if (max_result_length >= MAX_BLOB_WIDTH)
421
 
  {
422
 
    max_result_length= MAX_BLOB_WIDTH;
423
 
    maybe_null= 1;
424
 
  }
425
 
  max_length= (ulong) max_result_length;
426
 
}
427
 
 
428
 
 
429
 
String *Item_func_reverse::val_str(String *str)
430
 
{
431
 
  assert(fixed == 1);
432
 
  String *res = args[0]->val_str(str);
433
 
  char *ptr, *end, *tmp;
434
 
 
435
 
  if ((null_value=args[0]->null_value))
436
 
    return 0;
437
 
  /* An empty string is a special case as the string pointer may be null */
438
 
  if (!res->length())
439
 
    return &my_empty_string;
440
 
  if (tmp_value.alloced_length() < res->length() &&
441
 
      tmp_value.realloc(res->length()))
442
 
  {
443
 
    null_value= 1;
444
 
    return 0;
445
 
  }
446
 
  tmp_value.length(res->length());
447
 
  tmp_value.set_charset(res->charset());
448
 
  ptr= (char *) res->ptr();
449
 
  end= ptr + res->length();
450
 
  tmp= (char *) tmp_value.ptr() + tmp_value.length();
451
 
#ifdef USE_MB
452
 
  if (use_mb(res->charset()))
453
 
  {
454
 
    register uint32_t l;
455
 
    while (ptr < end)
456
 
    {
457
 
      if ((l= my_ismbchar(res->charset(),ptr,end)))
458
 
      {
459
 
        tmp-= l;
460
 
        memcpy(tmp,ptr,l);
461
 
        ptr+= l;
462
 
      }
463
 
      else
464
 
        *--tmp= *ptr++;
465
 
    }
466
 
  }
467
 
  else
468
 
#endif /* USE_MB */
469
 
  {
470
 
    while (ptr < end)
471
 
      *--tmp= *ptr++;
472
 
  }
473
 
  return &tmp_value;
474
 
}
475
 
 
476
 
 
477
 
void Item_func_reverse::fix_length_and_dec()
478
 
{
479
 
  collation.set(args[0]->collation);
480
 
  max_length = args[0]->max_length;
481
 
}
482
 
 
483
 
/**
484
 
  Replace all occurences of string2 in string1 with string3.
485
 
 
486
 
  Don't reallocate val_str() if not needed.
487
 
 
488
 
  @todo
489
 
    Fix that this works with binary strings when using USE_MB 
490
 
*/
491
 
 
492
 
String *Item_func_replace::val_str(String *str)
493
 
{
494
 
  assert(fixed == 1);
495
 
  String *res,*res2,*res3;
496
 
  int offset;
497
 
  uint32_t from_length,to_length;
498
 
  bool alloced=0;
499
 
#ifdef USE_MB
500
 
  const char *ptr,*end,*strend,*search,*search_end;
501
 
  register uint32_t l;
502
 
  bool binary_cmp;
503
 
#endif
504
 
 
505
 
  null_value=0;
506
 
  res=args[0]->val_str(str);
507
 
  if (args[0]->null_value)
508
 
    goto null;
509
 
  res2=args[1]->val_str(&tmp_value);
510
 
  if (args[1]->null_value)
511
 
    goto null;
512
 
 
513
 
  res->set_charset(collation.collation);
514
 
 
515
 
#ifdef USE_MB
516
 
  binary_cmp = ((res->charset()->state & MY_CS_BINSORT) || !use_mb(res->charset()));
517
 
#endif
518
 
 
519
 
  if (res2->length() == 0)
520
 
    return res;
521
 
#ifndef USE_MB
522
 
  if ((offset=res->strstr(*res2)) < 0)
523
 
    return res;
524
 
#else
525
 
  offset=0;
526
 
  if (binary_cmp && (offset=res->strstr(*res2)) < 0)
527
 
    return res;
528
 
#endif
529
 
  if (!(res3=args[2]->val_str(&tmp_value2)))
530
 
    goto null;
531
 
  from_length= res2->length();
532
 
  to_length=   res3->length();
533
 
 
534
 
#ifdef USE_MB
535
 
  if (!binary_cmp)
536
 
  {
537
 
    search=res2->ptr();
538
 
    search_end=search+from_length;
539
 
redo:
540
 
    ptr=res->ptr()+offset;
541
 
    strend=res->ptr()+res->length();
542
 
    end=strend-from_length+1;
543
 
    while (ptr < end)
544
 
    {
545
 
        if (*ptr == *search)
546
 
        {
547
 
          register char *i,*j;
548
 
          i=(char*) ptr+1; j=(char*) search+1;
549
 
          while (j != search_end)
550
 
            if (*i++ != *j++) goto skip;
551
 
          offset= (int) (ptr-res->ptr());
552
 
          if (res->length()-from_length + to_length >
553
 
              current_session->variables.max_allowed_packet)
554
 
          {
555
 
            push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
556
 
                                ER_WARN_ALLOWED_PACKET_OVERFLOWED,
557
 
                                ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
558
 
                                func_name(),
559
 
                                current_session->variables.max_allowed_packet);
560
 
 
561
 
            goto null;
562
 
          }
563
 
          if (!alloced)
564
 
          {
565
 
            alloced=1;
566
 
            res=copy_if_not_alloced(str,res,res->length()+to_length);
567
 
          }
568
 
          res->replace((uint) offset,from_length,*res3);
569
 
          offset+=(int) to_length;
570
 
          goto redo;
571
 
        }
572
 
skip:
573
 
        if ((l=my_ismbchar(res->charset(), ptr,strend))) ptr+=l;
574
 
        else ++ptr;
575
 
    }
576
 
  }
577
 
  else
578
 
#endif /* USE_MB */
579
 
    do
580
 
    {
581
 
      if (res->length()-from_length + to_length >
582
 
          current_session->variables.max_allowed_packet)
583
 
      {
584
 
        push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
585
 
                            ER_WARN_ALLOWED_PACKET_OVERFLOWED,
586
 
                            ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
587
 
                            current_session->variables.max_allowed_packet);
588
 
        goto null;
589
 
      }
590
 
      if (!alloced)
591
 
      {
592
 
        alloced=1;
593
 
        res=copy_if_not_alloced(str,res,res->length()+to_length);
594
 
      }
595
 
      res->replace((uint) offset,from_length,*res3);
596
 
      offset+=(int) to_length;
597
 
    }
598
 
    while ((offset=res->strstr(*res2,(uint) offset)) >= 0);
599
 
  return res;
600
 
 
601
 
null:
602
 
  null_value=1;
603
 
  return 0;
604
 
}
605
 
 
606
 
 
607
 
void Item_func_replace::fix_length_and_dec()
608
 
{
609
 
  uint64_t max_result_length= args[0]->max_length;
610
 
  int diff=(int) (args[2]->max_length - args[1]->max_length);
611
 
  if (diff > 0 && args[1]->max_length)
612
 
  {                                             // Calculate of maxreplaces
613
 
    uint64_t max_substrs= max_result_length/args[1]->max_length;
614
 
    max_result_length+= max_substrs * (uint) diff;
615
 
  }
616
 
  if (max_result_length >= MAX_BLOB_WIDTH)
617
 
  {
618
 
    max_result_length= MAX_BLOB_WIDTH;
619
 
    maybe_null= 1;
620
 
  }
621
 
  max_length= (ulong) max_result_length;
622
 
  
623
 
  if (agg_arg_charsets(collation, args, 3, MY_COLL_CMP_CONV, 1))
624
 
    return;
625
 
}
626
 
 
627
 
 
628
 
String *Item_func_insert::val_str(String *str)
629
 
{
630
 
  assert(fixed == 1);
631
 
  String *res,*res2;
632
 
  int64_t start, length;  /* must be int64_t to avoid truncation */
633
 
 
634
 
  null_value=0;
635
 
  res=args[0]->val_str(str);
636
 
  res2=args[3]->val_str(&tmp_value);
637
 
  start= args[1]->val_int() - 1;
638
 
  length= args[2]->val_int();
639
 
 
640
 
  if (args[0]->null_value || args[1]->null_value || args[2]->null_value ||
641
 
      args[3]->null_value)
642
 
    goto null; /* purecov: inspected */
643
 
 
644
 
  if ((start < 0) || (start > res->length()))
645
 
    return res;                                 // Wrong param; skip insert
646
 
  if ((length < 0) || (length > res->length()))
647
 
    length= res->length();
648
 
 
649
 
  /* start and length are now sufficiently valid to pass to charpos function */
650
 
   start= res->charpos((int) start);
651
 
   length= res->charpos((int) length, (uint32_t) start);
652
 
 
653
 
  /* Re-testing with corrected params */
654
 
  if (start > res->length())
655
 
    return res; /* purecov: inspected */        // Wrong param; skip insert
656
 
  if (length > res->length() - start)
657
 
    length= res->length() - start;
658
 
 
659
 
  if ((uint64_t) (res->length() - length + res2->length()) >
660
 
      (uint64_t) current_session->variables.max_allowed_packet)
661
 
  {
662
 
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
663
 
                        ER_WARN_ALLOWED_PACKET_OVERFLOWED,
664
 
                        ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
665
 
                        func_name(), current_session->variables.max_allowed_packet);
666
 
    goto null;
667
 
  }
668
 
  res=copy_if_not_alloced(str,res,res->length());
669
 
  res->replace((uint32_t) start,(uint32_t) length,*res2);
670
 
  return res;
671
 
null:
672
 
  null_value=1;
673
 
  return 0;
674
 
}
675
 
 
676
 
 
677
 
void Item_func_insert::fix_length_and_dec()
678
 
{
679
 
  uint64_t max_result_length;
680
 
 
681
 
  // Handle character set for args[0] and args[3].
682
 
  if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 3))
683
 
    return;
684
 
  max_result_length= ((uint64_t) args[0]->max_length+
685
 
                      (uint64_t) args[3]->max_length);
686
 
  if (max_result_length >= MAX_BLOB_WIDTH)
687
 
  {
688
 
    max_result_length= MAX_BLOB_WIDTH;
689
 
    maybe_null= 1;
690
 
  }
691
 
  max_length= (ulong) max_result_length;
692
 
}
693
 
 
694
 
 
695
 
String *Item_str_conv::val_str(String *str)
696
 
{
697
 
  assert(fixed == 1);
698
 
  String *res;
699
 
  if (!(res=args[0]->val_str(str)))
700
 
  {
701
 
    null_value=1; /* purecov: inspected */
702
 
    return 0; /* purecov: inspected */
703
 
  }
704
 
  null_value=0;
705
 
  if (multiply == 1)
706
 
  {
707
 
    uint32_t len;
708
 
    res= copy_if_not_alloced(str,res,res->length());
709
 
    len= converter(collation.collation, (char*) res->ptr(), res->length(),
710
 
                                        (char*) res->ptr(), res->length());
711
 
    assert(len <= res->length());
712
 
    res->length(len);
713
 
  }
714
 
  else
715
 
  {
716
 
    uint32_t len= res->length() * multiply;
717
 
    tmp_value.alloc(len);
718
 
    tmp_value.set_charset(collation.collation);
719
 
    len= converter(collation.collation, (char*) res->ptr(), res->length(),
720
 
                                        (char*) tmp_value.ptr(), len);
721
 
    tmp_value.length(len);
722
 
    res= &tmp_value;
723
 
  }
724
 
  return res;
725
 
}
726
 
 
727
 
 
728
 
void Item_func_lcase::fix_length_and_dec()
729
 
{
730
 
  collation.set(args[0]->collation);
731
 
  multiply= collation.collation->casedn_multiply;
732
 
  converter= collation.collation->cset->casedn;
733
 
  max_length= args[0]->max_length * multiply;
734
 
}
735
 
 
736
 
void Item_func_ucase::fix_length_and_dec()
737
 
{
738
 
  collation.set(args[0]->collation);
739
 
  multiply= collation.collation->caseup_multiply;
740
 
  converter= collation.collation->cset->caseup;
741
 
  max_length= args[0]->max_length * multiply;
742
 
}
743
 
 
744
 
 
745
 
String *Item_func_left::val_str(String *str)
746
 
{
747
 
  assert(fixed == 1);
748
 
  String *res= args[0]->val_str(str);
749
 
 
750
 
  /* must be int64_t to avoid truncation */
751
 
  int64_t length= args[1]->val_int();
752
 
  uint32_t char_pos;
753
 
 
754
 
  if ((null_value=(args[0]->null_value || args[1]->null_value)))
755
 
    return 0;
756
 
 
757
 
  /* if "unsigned_flag" is set, we have a *huge* positive number. */
758
 
  if ((length <= 0) && (!args[1]->unsigned_flag))
759
 
    return &my_empty_string;
760
 
 
761
 
  if ((res->length() <= (uint64_t) length) ||
762
 
      (res->length() <= (char_pos= res->charpos((int) length))))
763
 
    return res;
764
 
 
765
 
  tmp_value.set(*res, 0, char_pos);
766
 
  return &tmp_value;
767
 
}
768
 
 
769
 
 
770
 
void Item_str_func::left_right_max_length()
771
 
{
772
 
  max_length=args[0]->max_length;
773
 
  if (args[1]->const_item())
774
 
  {
775
 
    int length=(int) args[1]->val_int()*collation.collation->mbmaxlen;
776
 
    if (length <= 0)
777
 
      max_length=0;
778
 
    else
779
 
      set_if_smaller(max_length,(uint) length);
780
 
  }
781
 
}
782
 
 
783
 
 
784
 
void Item_func_left::fix_length_and_dec()
785
 
{
786
 
  collation.set(args[0]->collation);
787
 
  left_right_max_length();
788
 
}
789
 
 
790
 
 
791
 
String *Item_func_right::val_str(String *str)
792
 
{
793
 
  assert(fixed == 1);
794
 
  String *res= args[0]->val_str(str);
795
 
  /* must be int64_t to avoid truncation */
796
 
  int64_t length= args[1]->val_int();
797
 
 
798
 
  if ((null_value=(args[0]->null_value || args[1]->null_value)))
799
 
    return 0; /* purecov: inspected */
800
 
 
801
 
  /* if "unsigned_flag" is set, we have a *huge* positive number. */
802
 
  if ((length <= 0) && (!args[1]->unsigned_flag))
803
 
    return &my_empty_string; /* purecov: inspected */
804
 
 
805
 
  if (res->length() <= (uint64_t) length)
806
 
    return res; /* purecov: inspected */
807
 
 
808
 
  uint32_t start=res->numchars();
809
 
  if (start <= (uint) length)
810
 
    return res;
811
 
  start=res->charpos(start - (uint) length);
812
 
  tmp_value.set(*res,start,res->length()-start);
813
 
  return &tmp_value;
814
 
}
815
 
 
816
 
 
817
 
void Item_func_right::fix_length_and_dec()
818
 
{
819
 
  collation.set(args[0]->collation);
820
 
  left_right_max_length();
821
 
}
822
 
 
823
 
 
824
48
String *Item_func_substr::val_str(String *str)
825
49
{
826
50
  assert(fixed == 1);