Drizzled Public API Documentation

replace.cc
1 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2008 Sun Microsystems, Inc.
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 
20 #include <config.h>
21 
22 #include <drizzled/function/str/replace.h>
23 #include <drizzled/error.h>
24 #include <drizzled/session.h>
25 #include <drizzled/system_variables.h>
26 
27 namespace drizzled {
28 
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;
46  uint32_t l;
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  {
83  char *i,*j;
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 >
89  session.variables.max_allowed_packet)
90  {
91  push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
92  ER_WARN_ALLOWED_PACKET_OVERFLOWED,
93  ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
94  func_name(),
95  session.variables.max_allowed_packet);
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 >
117  session.variables.max_allowed_packet)
118  {
119  push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
120  ER_WARN_ALLOWED_PACKET_OVERFLOWED,
121  ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
122  session.variables.max_allowed_packet);
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 
163 } /* namespace drizzled */
bool fixed
Definition: item.h:120
String * val_str(String *)
Definition: replace.cc:38
bool null_value
Definition: item.h:122
bool maybe_null
Definition: item.h:121
virtual String * val_str(String *str)=0
drizzle_system_variables & variables
Definition: session.h:199