~drizzle-trunk/drizzle/development

574.3.3 by Lee
moving functions from item_strfunc to functions/str directory
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
574.3.3 by Lee
moving functions from item_strfunc to functions/str directory
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; version 2 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, write to the Free Software
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 */
19
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
20
#include <config.h>
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
21
670.1.20 by Monty Taylor
Renamed functions to function... everything else is singular.
22
#include <drizzled/function/str/replace.h>
574.3.3 by Lee
moving functions from item_strfunc to functions/str directory
23
#include <drizzled/error.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
24
#include <drizzled/session.h>
2241.3.2 by Olaf van der Spek
Refactor Session::variables
25
#include <drizzled/system_variables.h>
574.3.3 by Lee
moving functions from item_strfunc to functions/str directory
26
2241.3.2 by Olaf van der Spek
Refactor Session::variables
27
namespace drizzled {
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
28
574.3.3 by Lee
moving functions from item_strfunc to functions/str directory
29
/**
30
  Replace all occurences of string2 in string1 with string3.
31
32
  Don't reallocate val_str() if not needed.
33
34
  @todo
1085.3.3 by Monty Taylor
Got rid of #ifdef have utf8 stuff.
35
    Fix that this works with binary strings
574.3.3 by Lee
moving functions from item_strfunc to functions/str directory
36
*/
37
38
String *Item_func_replace::val_str(String *str)
39
{
40
  assert(fixed == 1);
41
  String *res,*res2,*res3;
42
  int offset;
43
  uint32_t from_length,to_length;
44
  bool alloced=0;
45
  const char *ptr,*end,*strend,*search,*search_end;
2187.4.1 by Olaf van der Spek
Remove register keyword
46
  uint32_t l;
574.3.3 by Lee
moving functions from item_strfunc to functions/str directory
47
  bool binary_cmp;
48
49
  null_value=0;
50
  res=args[0]->val_str(str);
51
  if (args[0]->null_value)
52
    goto null;
53
  res2=args[1]->val_str(&tmp_value);
54
  if (args[1]->null_value)
55
    goto null;
56
57
  res->set_charset(collation.collation);
58
59
  binary_cmp = ((res->charset()->state & MY_CS_BINSORT) || !use_mb(res->charset()));
60
61
  if (res2->length() == 0)
62
    return res;
63
  offset=0;
64
  if (binary_cmp && (offset=res->strstr(*res2)) < 0)
65
    return res;
66
  if (!(res3=args[2]->val_str(&tmp_value2)))
67
    goto null;
68
  from_length= res2->length();
69
  to_length=   res3->length();
70
71
  if (!binary_cmp)
72
  {
73
    search=res2->ptr();
74
    search_end=search+from_length;
75
redo:
76
    ptr=res->ptr()+offset;
77
    strend=res->ptr()+res->length();
78
    end=strend-from_length+1;
79
    while (ptr < end)
80
    {
81
        if (*ptr == *search)
82
        {
2187.4.1 by Olaf van der Spek
Remove register keyword
83
          char *i,*j;
574.3.3 by Lee
moving functions from item_strfunc to functions/str directory
84
          i=(char*) ptr+1; j=(char*) search+1;
85
          while (j != search_end)
86
            if (*i++ != *j++) goto skip;
87
          offset= (int) (ptr-res->ptr());
88
          if (res->length()-from_length + to_length >
1633.4.4 by Brian Aker
Remove more of current_session
89
              session.variables.max_allowed_packet)
574.3.3 by Lee
moving functions from item_strfunc to functions/str directory
90
          {
1633.4.4 by Brian Aker
Remove more of current_session
91
            push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
574.3.3 by Lee
moving functions from item_strfunc to functions/str directory
92
                                ER_WARN_ALLOWED_PACKET_OVERFLOWED,
93
                                ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
94
                                func_name(),
1633.4.4 by Brian Aker
Remove more of current_session
95
                                session.variables.max_allowed_packet);
574.3.3 by Lee
moving functions from item_strfunc to functions/str directory
96
97
            goto null;
98
          }
99
          if (!alloced)
100
          {
101
            alloced=1;
102
            res=copy_if_not_alloced(str,res,res->length()+to_length);
103
          }
104
          res->replace((uint) offset,from_length,*res3);
105
          offset+=(int) to_length;
106
          goto redo;
107
        }
108
skip:
109
        if ((l=my_ismbchar(res->charset(), ptr,strend))) ptr+=l;
110
        else ++ptr;
111
    }
112
  }
113
  else
114
    do
115
    {
116
      if (res->length()-from_length + to_length >
1633.4.4 by Brian Aker
Remove more of current_session
117
          session.variables.max_allowed_packet)
574.3.3 by Lee
moving functions from item_strfunc to functions/str directory
118
      {
1633.4.4 by Brian Aker
Remove more of current_session
119
        push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
574.3.3 by Lee
moving functions from item_strfunc to functions/str directory
120
                            ER_WARN_ALLOWED_PACKET_OVERFLOWED,
121
                            ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
1633.4.4 by Brian Aker
Remove more of current_session
122
                            session.variables.max_allowed_packet);
574.3.3 by Lee
moving functions from item_strfunc to functions/str directory
123
        goto null;
124
      }
125
      if (!alloced)
126
      {
127
        alloced=1;
128
        res=copy_if_not_alloced(str,res,res->length()+to_length);
129
      }
130
      res->replace((uint) offset,from_length,*res3);
131
      offset+=(int) to_length;
132
    }
133
    while ((offset=res->strstr(*res2,(uint) offset)) >= 0);
134
  return res;
135
136
null:
137
  null_value=1;
138
  return 0;
139
}
140
141
142
void Item_func_replace::fix_length_and_dec()
143
{
144
  uint64_t max_result_length= args[0]->max_length;
145
  int diff=(int) (args[2]->max_length - args[1]->max_length);
146
  if (diff > 0 && args[1]->max_length)
147
  {                                             // Calculate of maxreplaces
148
    uint64_t max_substrs= max_result_length/args[1]->max_length;
149
    max_result_length+= max_substrs * (uint) diff;
150
  }
151
  if (max_result_length >= MAX_BLOB_WIDTH)
152
  {
153
    max_result_length= MAX_BLOB_WIDTH;
154
    maybe_null= 1;
155
  }
156
  max_length= (ulong) max_result_length;
157
158
  if (agg_arg_charsets(collation, args, 3, MY_COLL_CMP_CONV, 1))
159
    return;
160
}
161
162
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
163
} /* namespace drizzled */