25 #include <drizzled/charset.h>
26 #include <drizzled/function/str/strfunc.h>
27 #include <drizzled/plugin/function.h>
30 using namespace drizzled;
39 void fix_length_and_dec();
40 const char *func_name()
const {
return "substr"; }
53 void fix_length_and_dec();
54 const char *func_name()
const {
return "substring_index"; }
62 String *res = args[0]->val_str(str);
64 int64_t start= args[1]->val_int();
67 int64_t length= arg_count == 3 ? args[2]->val_int() : INT32_MAX;
70 if ((null_value=(args[0]->null_value || args[1]->null_value ||
71 (arg_count == 3 && args[2]->null_value))))
75 if ((arg_count == 3) && (length <= 0) &&
76 (length == 0 || !args[2]->unsigned_flag))
77 return &my_empty_string;
81 if ((length <= 0) || (length > INT32_MAX))
86 if ((!args[1]->unsigned_flag && (start < INT32_MIN || start > INT32_MAX)) ||
87 (args[1]->unsigned_flag && ((uint64_t) start > INT32_MAX)))
88 return &my_empty_string;
91 static_cast<int64_t>(res->numchars() + start)
93 start= res->charpos((
int) start);
94 if ((start < 0) || ((uint) start + 1 > res->length()))
95 return &my_empty_string;
97 length= res->charpos((
int) length, (uint32_t) start);
98 tmp_length= res->length() - start;
99 length= min(length, tmp_length);
101 if (!start && (int64_t) res->length() == length)
103 tmp_value.set(*res, (uint32_t) start, (uint32_t) length);
107 void SubstrFunction::fix_length_and_dec()
109 max_length=args[0]->max_length;
111 collation.set(args[0]->collation);
112 if (args[1]->const_item())
114 int32_t start= (int32_t) args[1]->val_int();
116 max_length= ((uint)(-start) > max_length) ? 0 : (uint)(-start);
118 max_length-= min((uint)(start - 1), max_length);
120 if (arg_count == 3 && args[2]->const_item())
122 int32_t length= (int32_t) args[2]->val_int();
126 set_if_smaller(max_length,(uint) length);
128 max_length*= collation.collation->mbmaxlen;
132 void SubstrIndexFunction::fix_length_and_dec()
134 max_length= args[0]->max_length;
136 if (agg_arg_charsets(collation, args, 2, MY_COLL_CMP_CONV, 1))
144 String *res= args[0]->val_str(str);
145 String *delimiter= args[1]->val_str(&tmp_value);
146 int32_t count= (int32_t) args[2]->val_int();
149 if (args[0]->null_value || args[1]->null_value || args[2]->null_value)
155 uint32_t delimiter_length= delimiter->length();
156 if (!res->length() || !delimiter_length || !count)
157 return &my_empty_string;
159 res->set_charset(collation.collation);
161 if (use_mb(res->charset()))
163 const char *ptr= res->ptr();
164 const char *strend= ptr+res->length();
165 const char *end= strend-delimiter_length+1;
166 const char *search= delimiter->ptr();
167 const char *search_end= search+delimiter_length;
168 int32_t n=0,c=count,pass;
170 for (pass=(count>0);pass<2;++pass)
177 i=(
char*) ptr+1; j=(
char*) search+1;
178 while (j != search_end)
179 if (*i++ != *j++)
goto skip;
181 else if (!--c)
break;
182 ptr+= delimiter_length;
186 if ((l=my_ismbchar(res->charset(), ptr,strend))) ptr+=l;
192 if (c<=0)
return res;
200 tmp_value.set(*res,0,(ulong) (ptr-res->ptr()));
204 ptr+= delimiter_length;
205 tmp_value.set(*res,(ulong) (ptr-res->ptr()), (ulong) (strend-ptr));
214 for (offset=0; ; offset+= delimiter_length)
216 if ((
int) (offset= res->strstr(*delimiter, offset)) < 0)
220 tmp_value.set(*res,0,offset);
230 for (offset=res->length(); offset ;)
237 if ((
int) (offset= res->strrstr(*delimiter, offset)) < 0)
245 offset+= delimiter_length;
246 tmp_value.set(*res,offset,res->length()- offset);
257 tmp_value.mark_as_const();
261 plugin::Create_function<SubstrFunction> *substr_function= NULL;
262 plugin::Create_function<SubstrIndexFunction> *substr_index_function= NULL;
266 substr_function=
new plugin::Create_function<SubstrFunction>(
"substr");
267 substr_index_function=
new plugin::Create_function<SubstrIndexFunction>(
"substring_index");
268 context.add(substr_function);
269 context.add(substr_index_function);
273 DRIZZLE_DECLARE_PLUGIN
279 N_(
"SUBSTR and SUBSTR functions"),
285 DRIZZLE_DECLARE_PLUGIN_END;
String * val_str(String *)
bool check_argument_count(int n)
String * val_str(String *)
bool check_argument_count(int n)