~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/function/str/concat.cc

Merge Stewart's dead code removal

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#include "config.h"
21
 
 
 
20
#include <drizzled/server_includes.h>
 
21
#include CSTDINT_H
22
22
#include <drizzled/function/str/concat.h>
23
23
#include <drizzled/error.h>
24
24
#include <drizzled/session.h>
27
27
 
28
28
using namespace std;
29
29
 
30
 
namespace drizzled
31
 
{
32
 
 
33
30
String *Item_func_concat::val_str(String *str)
34
31
{
35
32
  assert(fixed == 1);
48
45
    if (res->length() == 0)
49
46
    {
50
47
      if (!(res=args[i]->val_str(str)))
51
 
        goto null;
 
48
        goto null;
52
49
    }
53
50
    else
54
51
    {
55
52
      if (!(res2=args[i]->val_str(use_as_buff)))
56
 
        goto null;
 
53
        goto null;
57
54
      if (res2->length() == 0)
58
 
        continue;
 
55
        continue;
59
56
      if (res->length()+res2->length() >
60
 
          session.variables.max_allowed_packet)
 
57
          current_session->variables.max_allowed_packet)
61
58
      {
62
 
        push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
63
 
                            ER_WARN_ALLOWED_PACKET_OVERFLOWED,
64
 
                            ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
65
 
                            session.variables.max_allowed_packet);
66
 
        goto null;
 
59
        push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
60
                            ER_WARN_ALLOWED_PACKET_OVERFLOWED,
 
61
                            ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
 
62
                            current_session->variables.max_allowed_packet);
 
63
        goto null;
67
64
      }
68
65
      if (!is_const && res->alloced_length() >= res->length()+res2->length())
69
66
      {                                         // Use old buffer
70
 
        res->append(*res2);
 
67
        res->append(*res2);
71
68
      }
72
69
      else if (str->alloced_length() >= res->length()+res2->length())
73
70
      {
74
 
        if (str == res2)
75
 
          str->replace(0,0,*res);
76
 
        else
77
 
        {
78
 
          str->copy(*res);
79
 
          str->append(*res2);
80
 
        }
 
71
        if (str == res2)
 
72
          str->replace(0,0,*res);
 
73
        else
 
74
        {
 
75
          str->copy(*res);
 
76
          str->append(*res2);
 
77
        }
81
78
        res= str;
82
79
        use_as_buff= &tmp_value;
83
80
      }
84
81
      else if (res == &tmp_value)
85
82
      {
86
 
        if (res->append(*res2))                 // Must be a blob
87
 
          goto null;
 
83
        if (res->append(*res2))                 // Must be a blob
 
84
          goto null;
88
85
      }
89
86
      else if (res2 == &tmp_value)
90
87
      {                                         // This can happend only 1 time
91
 
        if (tmp_value.replace(0,0,*res))
92
 
          goto null;
93
 
        res= &tmp_value;
94
 
        use_as_buff=str;                        // Put next arg here
 
88
        if (tmp_value.replace(0,0,*res))
 
89
          goto null;
 
90
        res= &tmp_value;
 
91
        use_as_buff=str;                        // Put next arg here
95
92
      }
96
93
      else if (tmp_value.is_alloced() && res2->ptr() >= tmp_value.ptr() &&
97
 
               res2->ptr() <= tmp_value.ptr() + tmp_value.alloced_length())
 
94
               res2->ptr() <= tmp_value.ptr() + tmp_value.alloced_length())
98
95
      {
99
 
        /*
100
 
          This happens really seldom:
101
 
          In this case res2 is sub string of tmp_value.  We will
102
 
          now work in place in tmp_value to set it to res | res2
103
 
        */
104
 
        /* Chop the last characters in tmp_value that isn't in res2 */
105
 
        tmp_value.length((uint32_t) (res2->ptr() - tmp_value.ptr()) +
106
 
                         res2->length());
107
 
        /* Place res2 at start of tmp_value, remove chars before res2 */
108
 
        if (tmp_value.replace(0,(uint32_t) (res2->ptr() - tmp_value.ptr()),
109
 
                              *res))
110
 
          goto null;
111
 
        res= &tmp_value;
112
 
        use_as_buff=str;                        // Put next arg here
 
96
        /*
 
97
          This happens really seldom:
 
98
          In this case res2 is sub string of tmp_value.  We will
 
99
          now work in place in tmp_value to set it to res | res2
 
100
        */
 
101
        /* Chop the last characters in tmp_value that isn't in res2 */
 
102
        tmp_value.length((uint32_t) (res2->ptr() - tmp_value.ptr()) +
 
103
                         res2->length());
 
104
        /* Place res2 at start of tmp_value, remove chars before res2 */
 
105
        if (tmp_value.replace(0,(uint32_t) (res2->ptr() - tmp_value.ptr()),
 
106
                              *res))
 
107
          goto null;
 
108
        res= &tmp_value;
 
109
        use_as_buff=str;                        // Put next arg here
113
110
      }
114
111
      else
115
112
      {                                         // Two big const strings
116
113
        /*
117
 
          @note We should be prudent in the initial allocation unit -- the
 
114
          NOTE: We should be prudent in the initial allocation unit -- the
118
115
          size of the arguments is a function of data distribution, which
119
116
          can be any. Instead of overcommitting at the first row, we grow
120
117
          the allocated amount by the factor of 2. This ensures that no
121
118
          more than 25% of memory will be overcommitted on average.
122
119
        */
123
120
 
124
 
        size_t concat_len= res->length() + res2->length();
 
121
        uint32_t concat_len= res->length() + res2->length();
125
122
 
126
123
        if (tmp_value.alloced_length() < concat_len)
127
124
        {
139
136
          }
140
137
        }
141
138
 
142
 
        if (tmp_value.copy(*res) || tmp_value.append(*res2))
143
 
          goto null;
 
139
        if (tmp_value.copy(*res) || tmp_value.append(*res2))
 
140
          goto null;
144
141
 
145
 
        res= &tmp_value;
146
 
        use_as_buff=str;
 
142
        res= &tmp_value;
 
143
        use_as_buff=str;
147
144
      }
148
145
      is_const= 0;
149
146
    }
169
166
    if (args[i]->collation.collation->mbmaxlen != collation.collation->mbmaxlen)
170
167
      max_result_length+= (args[i]->max_length /
171
168
                           args[i]->collation.collation->mbmaxlen) *
172
 
        collation.collation->mbmaxlen;
 
169
                           collation.collation->mbmaxlen;
173
170
    else
174
171
      max_result_length+= args[i]->max_length;
175
172
  }
218
215
      continue;                                 // Skip NULL
219
216
 
220
217
    if (res->length() + sep_str->length() + res2->length() >
221
 
        session.variables.max_allowed_packet)
 
218
        current_session->variables.max_allowed_packet)
222
219
    {
223
 
      push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
224
 
                          ER_WARN_ALLOWED_PACKET_OVERFLOWED,
225
 
                          ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
226
 
                          session.variables.max_allowed_packet);
 
220
      push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
221
                          ER_WARN_ALLOWED_PACKET_OVERFLOWED,
 
222
                          ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
 
223
                          current_session->variables.max_allowed_packet);
227
224
      goto null;
228
225
    }
229
226
    if (res->alloced_length() >=
230
 
        res->length() + sep_str->length() + res2->length())
 
227
        res->length() + sep_str->length() + res2->length())
231
228
    {                                           // Use old buffer
232
229
      res->append(*sep_str);                    // res->length() > 0 always
233
230
      res->append(*res2);
234
231
    }
235
232
    else if (str->alloced_length() >=
236
 
             res->length() + sep_str->length() + res2->length())
 
233
             res->length() + sep_str->length() + res2->length())
237
234
    {
238
235
      /* We have room in str;  We can't get any errors here */
239
236
      if (str == res2)
240
237
      {                                         // This is quote uncommon!
241
 
        str->replace(0,0,*sep_str);
242
 
        str->replace(0,0,*res);
 
238
        str->replace(0,0,*sep_str);
 
239
        str->replace(0,0,*res);
243
240
      }
244
241
      else
245
242
      {
246
 
        str->copy(*res);
247
 
        str->append(*sep_str);
248
 
        str->append(*res2);
 
243
        str->copy(*res);
 
244
        str->append(*sep_str);
 
245
        str->append(*res2);
249
246
      }
250
247
      res=str;
251
248
      use_as_buff= &tmp_value;
253
250
    else if (res == &tmp_value)
254
251
    {
255
252
      if (res->append(*sep_str) || res->append(*res2))
256
 
        goto null; // Must be a blob
 
253
        goto null; // Must be a blob
257
254
    }
258
255
    else if (res2 == &tmp_value)
259
256
    {                                           // This can happend only 1 time
260
257
      if (tmp_value.replace(0,0,*sep_str) || tmp_value.replace(0,0,*res))
261
 
        goto null;
 
258
        goto null;
262
259
      res= &tmp_value;
263
260
      use_as_buff=str;                          // Put next arg here
264
261
    }
265
262
    else if (tmp_value.is_alloced() && res2->ptr() >= tmp_value.ptr() &&
266
 
             res2->ptr() < tmp_value.ptr() + tmp_value.alloced_length())
 
263
             res2->ptr() < tmp_value.ptr() + tmp_value.alloced_length())
267
264
    {
268
265
      /*
269
 
        This happens really seldom:
270
 
        In this case res2 is sub string of tmp_value.  We will
271
 
        now work in place in tmp_value to set it to res | sep_str | res2
 
266
        This happens really seldom:
 
267
        In this case res2 is sub string of tmp_value.  We will
 
268
        now work in place in tmp_value to set it to res | sep_str | res2
272
269
      */
273
270
      /* Chop the last characters in tmp_value that isn't in res2 */
274
271
      tmp_value.length((uint32_t) (res2->ptr() - tmp_value.ptr()) +
275
 
                       res2->length());
 
272
                       res2->length());
276
273
      /* Place res2 at start of tmp_value, remove chars before res2 */
277
274
      if (tmp_value.replace(0,(uint32_t) (res2->ptr() - tmp_value.ptr()),
278
 
                            *res) ||
279
 
          tmp_value.replace(res->length(),0, *sep_str))
280
 
        goto null;
 
275
                            *res) ||
 
276
          tmp_value.replace(res->length(),0, *sep_str))
 
277
        goto null;
281
278
      res= &tmp_value;
282
279
      use_as_buff=str;                  // Put next arg here
283
280
    }
284
281
    else
285
282
    {                                           // Two big const strings
286
283
      /*
287
 
        @note We should be prudent in the initial allocation unit -- the
 
284
        NOTE: We should be prudent in the initial allocation unit -- the
288
285
        size of the arguments is a function of data distribution, which can
289
286
        be any. Instead of overcommitting at the first row, we grow the
290
287
        allocated amount by the factor of 2. This ensures that no more than
291
288
        25% of memory will be overcommitted on average.
292
289
      */
293
290
 
294
 
      size_t concat_len= res->length() + sep_str->length() + res2->length();
 
291
      uint32_t concat_len= res->length() + sep_str->length() + res2->length();
295
292
 
296
293
      if (tmp_value.alloced_length() < concat_len)
297
294
      {
310
307
      }
311
308
 
312
309
      if (tmp_value.copy(*res) ||
313
 
          tmp_value.append(*sep_str) ||
314
 
          tmp_value.append(*res2))
315
 
        goto null;
 
310
          tmp_value.append(*sep_str) ||
 
311
          tmp_value.append(*res2))
 
312
        goto null;
316
313
      res= &tmp_value;
317
314
      use_as_buff=str;
318
315
    }
334
331
    return;
335
332
 
336
333
  /*
337
 
    arg_count cannot be less than 2,
338
 
    it is done on parser level in sql_yacc.yy
339
 
    so, (arg_count - 2) is safe here.
 
334
     arg_count cannot be less than 2,
 
335
     it is done on parser level in sql_yacc.yy
 
336
     so, (arg_count - 2) is safe here.
340
337
  */
341
338
  max_result_length= (uint64_t) args[0]->max_length * (arg_count - 2);
342
339
  for (uint32_t i=1 ; i < arg_count ; i++)
350
347
  max_length= (ulong) max_result_length;
351
348
}
352
349
 
353
 
} /* namespace drizzled */