Drizzled Public API Documentation

pad.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/pad.h>
23 #include <drizzled/error.h>
24 #include <drizzled/function/str/alloc_buffer.h>
25 #include <drizzled/session.h>
26 #include <drizzled/system_variables.h>
27 
28 namespace drizzled {
29 
30 void Item_func_rpad::fix_length_and_dec()
31 {
32  // Handle character set for args[0] and args[2].
33  if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 2))
34  return;
35  if (args[1]->const_item())
36  {
37  uint64_t length= 0;
38 
39  if (collation.collation->mbmaxlen > 0)
40  {
41  uint64_t temp= (uint64_t) args[1]->val_int();
42 
43  /* Assumes that the maximum length of a String is < INT32_MAX. */
44  /* Set here so that rest of code sees out-of-bound value as such. */
45  if (temp > INT32_MAX)
46  temp = INT32_MAX;
47 
48  length= temp * collation.collation->mbmaxlen;
49  }
50 
51  if (length >= MAX_BLOB_WIDTH)
52  {
53  length= MAX_BLOB_WIDTH;
54  maybe_null= 1;
55  }
56  max_length= (ulong) length;
57  }
58  else
59  {
60  max_length= MAX_BLOB_WIDTH;
61  maybe_null= 1;
62  }
63 }
64 
65 
67 {
68  assert(fixed == 1);
69  null_value=1;
70  uint32_t res_byte_length,res_char_length,pad_char_length,pad_byte_length;
71  const char *ptr_pad;
72  /* must be int64_t to avoid truncation */
73  int64_t count= args[1]->val_int();
74  String *res= args[0]->val_str(str);
75  String *rpad= args[2]->val_str(&rpad_str);
76 
77  if (!res || args[1]->null_value || !rpad || ((count < 0) && !args[1]->unsigned_flag))
78  return 0;
79  /* Assumes that the maximum length of a String is < INT32_MAX. */
80  /* Set here so that rest of code sees out-of-bound value as such. */
81  if ((uint64_t) count > INT32_MAX)
82  count= INT32_MAX;
83  if (count <= (res_char_length= res->numchars()))
84  { // String to pad is big enough
85  res->length(res->charpos((int) count)); // Shorten result if longer
86  null_value=0;
87  return res;
88  }
89  pad_char_length= rpad->numchars();
90 
91  int64_t byte_count= count * collation.collation->mbmaxlen;
92  if ((uint64_t) byte_count > session.variables.max_allowed_packet)
93  {
94  push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
95  ER_WARN_ALLOWED_PACKET_OVERFLOWED,
96  ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
97  func_name(), session.variables.max_allowed_packet);
98  return 0;
99  }
100  if (args[2]->null_value || !pad_char_length)
101  return 0;
102  res_byte_length= res->length(); /* Must be done before alloc_buffer */
103  res= alloc_buffer(res,str,&tmp_value, (ulong) byte_count);
104  char* to= (char*) res->ptr()+res_byte_length;
105  ptr_pad=rpad->ptr();
106  pad_byte_length= rpad->length();
107  count-= res_char_length;
108  for ( ; (uint32_t) count > pad_char_length; count-= pad_char_length)
109  {
110  memcpy(to,ptr_pad,pad_byte_length);
111  to+= pad_byte_length;
112  }
113  if (count)
114  {
115  pad_byte_length= rpad->charpos((int) count);
116  memcpy(to,ptr_pad,(size_t) pad_byte_length);
117  to+= pad_byte_length;
118  }
119  res->length(to- (char*) res->ptr());
120  null_value=0;
121  return res;
122 }
123 
124 
125 void Item_func_lpad::fix_length_and_dec()
126 {
127  // Handle character set for args[0] and args[2].
128  if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 2))
129  return;
130 
131  if (args[1]->const_item())
132  {
133  uint64_t length= 0;
134 
135  if (collation.collation->mbmaxlen > 0)
136  {
137  uint64_t temp= (uint64_t) args[1]->val_int();
138 
139  /* Assumes that the maximum length of a String is < INT32_MAX. */
140  /* Set here so that rest of code sees out-of-bound value as such. */
141  if (temp > INT32_MAX)
142  temp= INT32_MAX;
143 
144  length= temp * collation.collation->mbmaxlen;
145  }
146 
147  if (length >= MAX_BLOB_WIDTH)
148  {
149  length= MAX_BLOB_WIDTH;
150  maybe_null= 1;
151  }
152  max_length= (ulong) length;
153  }
154  else
155  {
156  max_length= MAX_BLOB_WIDTH;
157  maybe_null= 1;
158  }
159 }
160 
161 
163 {
164  assert(fixed == 1);
165  uint32_t res_char_length,pad_char_length;
166  /* must be int64_t to avoid truncation */
167  int64_t count= args[1]->val_int();
168  int64_t byte_count;
169  String *res= args[0]->val_str(&tmp_value);
170  String *pad= args[2]->val_str(&lpad_str);
171 
172  if (!res || args[1]->null_value || !pad ||
173  ((count < 0) && !args[1]->unsigned_flag))
174  goto err;
175  null_value=0;
176  /* Assumes that the maximum length of a String is < INT32_MAX. */
177  /* Set here so that rest of code sees out-of-bound value as such. */
178  if ((uint64_t) count > INT32_MAX)
179  count= INT32_MAX;
180 
181  res_char_length= res->numchars();
182 
183  if (count <= res_char_length)
184  {
185  res->length(res->charpos((int) count));
186  return res;
187  }
188 
189  pad_char_length= pad->numchars();
190  byte_count= count * collation.collation->mbmaxlen;
191 
192  if ((uint64_t) byte_count > session.variables.max_allowed_packet)
193  {
194  push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
195  ER_WARN_ALLOWED_PACKET_OVERFLOWED,
196  ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
197  func_name(), session.variables.max_allowed_packet);
198  goto err;
199  }
200 
201  if (args[2]->null_value || !pad_char_length)
202  goto err;
203  str->alloc((size_t) byte_count);
204  str->length(0);
205  str->set_charset(collation.collation);
206  count-= res_char_length;
207  while (count >= pad_char_length)
208  {
209  str->append(*pad);
210  count-= pad_char_length;
211  }
212  if (count > 0)
213  str->append(pad->ptr(), pad->charpos((int) count));
214 
215  str->append(*res);
216  null_value= 0;
217  return str;
218 
219 err:
220  null_value= 1;
221  return 0;
222 }
223 
224 } /* namespace drizzled */
String * val_str(String *)
Definition: pad.cc:66
virtual int64_t val_int()=0
bool fixed
Definition: item.h:120
bool null_value
Definition: item.h:122
String * val_str(String *)
Definition: pad.cc:162
virtual bool const_item() const
Definition: func.h:108
bool maybe_null
Definition: item.h:121
virtual String * val_str(String *str)=0
drizzle_system_variables & variables
Definition: session.h:199