#include <item_cmpfunc.h>
Inheritance diagram for Item_func_like:


Public Member Functions | |
| Item_func_like (Item *a, Item *b, Item *escape_arg, bool escape_used) | |
| longlong | val_int () |
| enum Functype | functype () const |
| optimize_type | select_optimize () const |
| cond_result | eq_cmp_result () const |
| const char * | func_name () const |
| bool | fix_fields (THD *thd, Item **ref) |
| void | cleanup () |
| bool | check_partition_func_processor (byte *bool_arg) |
Public Attributes | |
| int | escape |
Private Types | |
| alphabet_size = 256 | |
| enum | { alphabet_size = 256 } |
Private Member Functions | |
| void | turboBM_compute_suffixes (int *suff) |
| void | turboBM_compute_good_suffix_shifts (int *suff) |
| void | turboBM_compute_bad_character_shifts () |
| bool | turboBM_matches (const char *text, int text_len) const |
Private Attributes | |
| bool | canDoTurboBM |
| const char * | pattern |
| int | pattern_len |
| int * | bmGs |
| int * | bmBc |
| Item * | escape_item |
| bool | escape_used_in_parsing |
Definition at line 1073 of file item_cmpfunc.h.
anonymous enum [private] |
Definition at line 1097 of file item_cmpfunc.h.
01098 :Item_bool_func2(a,b), canDoTurboBM(FALSE), pattern(0), pattern_len(0), 01099 bmGs(0), bmBc(0), escape_item(escape_arg), 01100 escape_used_in_parsing(escape_used) {}
| void Item_func_like::cleanup | ( | ) | [virtual] |
Reimplemented from Item_result_field.
Definition at line 3216 of file item_cmpfunc.cc.
References canDoTurboBM, Item_result_field::cleanup(), and FALSE.
03217 { 03218 canDoTurboBM= FALSE; 03219 Item_bool_func2::cleanup(); 03220 }
Here is the call graph for this function:

| cond_result Item_func_like::eq_cmp_result | ( | ) | const [inline, virtual] |
Reimplemented from Item.
Definition at line 1104 of file item_cmpfunc.h.
References Item::COND_TRUE.
01104 { return COND_TRUE; }
Reimplemented from Item_func.
Definition at line 3106 of file item_cmpfunc.cc.
References alphabet_size, Item_func::args, bmBc, bmGs, canDoTurboBM, Item_bool_func2::cmp, Arg_comparator::cmp_collation, Item::collation, DTCollation::collation, Item::const_during_execution(), Item_func::const_item(), Item::const_item(), copy_and_convert(), charset_info_st::cset, DBUG_ASSERT, DBUG_PRINT, ER_WRONG_ARGUMENTS, escape, escape_item, escape_used_in_parsing, FALSE, Item::fix_fields(), Item_func::fix_fields(), Item::fixed, int(), String::length(), my_charset_handler_st::mb_wc, MIN_TURBOBM_PATTERN_LEN, MODE_NO_BACKSLASH_ESCAPES, my_error(), my_wc_t, MYF, pattern, pattern_len, String::ptr(), SPECIAL_NO_NEW_FUNC, specialflag, Item_bool_func2::tmp_value1, Item_bool_func2::tmp_value2, TRUE, turboBM_compute_bad_character_shifts(), turboBM_compute_good_suffix_shifts(), use_mb, use_strnxfrm, Item::val_str(), wild_many, and wild_one.
03107 { 03108 DBUG_ASSERT(fixed == 0); 03109 if (Item_bool_func2::fix_fields(thd, ref) || 03110 escape_item->fix_fields(thd, &escape_item)) 03111 return TRUE; 03112 03113 if (!escape_item->const_during_execution()) 03114 { 03115 my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE"); 03116 return TRUE; 03117 } 03118 03119 if (escape_item->const_item()) 03120 { 03121 /* If we are on execution stage */ 03122 String *escape_str= escape_item->val_str(&tmp_value1); 03123 if (escape_str) 03124 { 03125 if (escape_used_in_parsing && ( 03126 (((thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) && 03127 escape_str->numchars() != 1) || 03128 escape_str->numchars() > 1))) 03129 { 03130 my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE"); 03131 return TRUE; 03132 } 03133 03134 if (use_mb(cmp.cmp_collation.collation)) 03135 { 03136 CHARSET_INFO *cs= escape_str->charset(); 03137 my_wc_t wc; 03138 int rc= cs->cset->mb_wc(cs, &wc, 03139 (const uchar*) escape_str->ptr(), 03140 (const uchar*) escape_str->ptr() + 03141 escape_str->length()); 03142 escape= (int) (rc > 0 ? wc : '\\'); 03143 } 03144 else 03145 { 03146 /* 03147 In the case of 8bit character set, we pass native 03148 code instead of Unicode code as "escape" argument. 03149 Convert to "cs" if charset of escape differs. 03150 */ 03151 CHARSET_INFO *cs= cmp.cmp_collation.collation; 03152 uint32 unused; 03153 if (escape_str->needs_conversion(escape_str->length(), 03154 escape_str->charset(), cs, &unused)) 03155 { 03156 char ch; 03157 uint errors; 03158 uint32 cnvlen= copy_and_convert(&ch, 1, cs, escape_str->ptr(), 03159 escape_str->length(), 03160 escape_str->charset(), &errors); 03161 escape= cnvlen ? ch : '\\'; 03162 } 03163 else 03164 escape= *(escape_str->ptr()); 03165 } 03166 } 03167 else 03168 escape= '\\'; 03169 03170 /* 03171 We could also do boyer-more for non-const items, but as we would have to 03172 recompute the tables for each row it's not worth it. 03173 */ 03174 if (args[1]->const_item() && !use_strnxfrm(collation.collation) && 03175 !(specialflag & SPECIAL_NO_NEW_FUNC)) 03176 { 03177 String* res2 = args[1]->val_str(&tmp_value2); 03178 if (!res2) 03179 return FALSE; // Null argument 03180 03181 const size_t len = res2->length(); 03182 const char* first = res2->ptr(); 03183 const char* last = first + len - 1; 03184 /* 03185 len must be > 2 ('%pattern%') 03186 heuristic: only do TurboBM for pattern_len > 2 03187 */ 03188 03189 if (len > MIN_TURBOBM_PATTERN_LEN + 2 && 03190 *first == wild_many && 03191 *last == wild_many) 03192 { 03193 const char* tmp = first + 1; 03194 for (; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ; 03195 canDoTurboBM = (tmp == last) && !use_mb(args[0]->collation.collation); 03196 } 03197 if (canDoTurboBM) 03198 { 03199 pattern = first + 1; 03200 pattern_len = (int) len - 2; 03201 DBUG_PRINT("info", ("Initializing pattern: '%s'", first)); 03202 int *suff = (int*) thd->alloc((int) (sizeof(int)* 03203 ((pattern_len + 1)*2+ 03204 alphabet_size))); 03205 bmGs = suff + pattern_len + 1; 03206 bmBc = bmGs + pattern_len + 1; 03207 turboBM_compute_good_suffix_shifts(suff); 03208 turboBM_compute_bad_character_shifts(); 03209 DBUG_PRINT("info",("done")); 03210 } 03211 } 03212 } 03213 return FALSE; 03214 }
Here is the call graph for this function:

| const char* Item_func_like::func_name | ( | ) | const [inline, virtual] |
| enum Functype Item_func_like::functype | ( | ) | const [inline, virtual] |
Reimplemented from Item_func.
Definition at line 1102 of file item_cmpfunc.h.
References Item_func::LIKE_FUNC.
01102 { return LIKE_FUNC; }
| Item_func::optimize_type Item_func_like::select_optimize | ( | ) | const [virtual] |
Reimplemented from Item_bool_func2.
Definition at line 3087 of file item_cmpfunc.cc.
References Item_func::args, Item_func::const_item(), Item_func::OPTIMIZE_NONE, Item_func::OPTIMIZE_OP, String::ptr(), Item_int_func::result_type(), STRING_RESULT, Item_bool_func2::tmp_value2, Item::val_str(), wild_many, and wild_one.
03088 { 03089 if (args[1]->const_item()) 03090 { 03091 String* res2= args[1]->val_str((String *)&tmp_value2); 03092 03093 if (!res2) 03094 return OPTIMIZE_NONE; 03095 03096 if (*res2->ptr() != wild_many) 03097 { 03098 if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != wild_one) 03099 return OPTIMIZE_OP; 03100 } 03101 } 03102 return OPTIMIZE_NONE; 03103 }
Here is the call graph for this function:

| void Item_func_like::turboBM_compute_bad_character_shifts | ( | ) | [private] |
Definition at line 3455 of file item_cmpfunc.cc.
References alphabet_size, bmBc, Item_bool_func2::cmp, Arg_comparator::cmp_collation, DTCollation::collation, pattern, pattern_len, and charset_info_st::sort_order.
Referenced by fix_fields().
03456 { 03457 int *i; 03458 int *end = bmBc + alphabet_size; 03459 int j; 03460 const int plm1 = pattern_len - 1; 03461 CHARSET_INFO *cs= cmp.cmp_collation.collation; 03462 03463 for (i = bmBc; i < end; i++) 03464 *i = pattern_len; 03465 03466 if (!cs->sort_order) 03467 { 03468 for (j = 0; j < plm1; j++) 03469 bmBc[(uint) (uchar) pattern[j]] = plm1 - j; 03470 } 03471 else 03472 { 03473 for (j = 0; j < plm1; j++) 03474 bmBc[(uint) likeconv(cs,pattern[j])] = plm1 - j; 03475 } 03476 }
Here is the caller graph for this function:

| void Item_func_like::turboBM_compute_good_suffix_shifts | ( | int * | suff | ) | [private] |
Definition at line 3410 of file item_cmpfunc.cc.
References bmGs, pattern_len, and turboBM_compute_suffixes().
Referenced by fix_fields().
03411 { 03412 turboBM_compute_suffixes(suff); 03413 03414 int *end = bmGs + pattern_len; 03415 int *k; 03416 for (k = bmGs; k < end; k++) 03417 *k = pattern_len; 03418 03419 int tmp; 03420 int i; 03421 int j = 0; 03422 const int plm1 = pattern_len - 1; 03423 for (i = plm1; i > -1; i--) 03424 { 03425 if (suff[i] == i + 1) 03426 { 03427 for (tmp = plm1 - i; j < tmp; j++) 03428 { 03429 int *tmp2 = bmGs + j; 03430 if (*tmp2 == pattern_len) 03431 *tmp2 = tmp; 03432 } 03433 } 03434 } 03435 03436 int *tmp2; 03437 for (tmp = plm1 - i; j < tmp; j++) 03438 { 03439 tmp2 = bmGs + j; 03440 if (*tmp2 == pattern_len) 03441 *tmp2 = tmp; 03442 } 03443 03444 tmp2 = bmGs + plm1; 03445 for (i = 0; i <= pattern_len - 2; i++) 03446 *(tmp2 - suff[i]) = plm1 - i; 03447 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void Item_func_like::turboBM_compute_suffixes | ( | int * | suff | ) | [private] |
Definition at line 3353 of file item_cmpfunc.cc.
References Item_bool_func2::cmp, Arg_comparator::cmp_collation, DTCollation::collation, f, likeconv, pattern, pattern_len, and charset_info_st::sort_order.
Referenced by turboBM_compute_good_suffix_shifts().
03354 { 03355 const int plm1 = pattern_len - 1; 03356 int f = 0; 03357 int g = plm1; 03358 int *const splm1 = suff + plm1; 03359 CHARSET_INFO *cs= cmp.cmp_collation.collation; 03360 03361 *splm1 = pattern_len; 03362 03363 if (!cs->sort_order) 03364 { 03365 int i; 03366 for (i = pattern_len - 2; i >= 0; i--) 03367 { 03368 int tmp = *(splm1 + i - f); 03369 if (g < i && tmp < i - g) 03370 suff[i] = tmp; 03371 else 03372 { 03373 if (i < g) 03374 g = i; // g = min(i, g) 03375 f = i; 03376 while (g >= 0 && pattern[g] == pattern[g + plm1 - f]) 03377 g--; 03378 suff[i] = f - g; 03379 } 03380 } 03381 } 03382 else 03383 { 03384 int i; 03385 for (i = pattern_len - 2; 0 <= i; --i) 03386 { 03387 int tmp = *(splm1 + i - f); 03388 if (g < i && tmp < i - g) 03389 suff[i] = tmp; 03390 else 03391 { 03392 if (i < g) 03393 g = i; // g = min(i, g) 03394 f = i; 03395 while (g >= 0 && 03396 likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f])) 03397 g--; 03398 suff[i] = f - g; 03399 } 03400 } 03401 } 03402 }
Here is the caller graph for this function:

| bool Item_func_like::turboBM_matches | ( | const char * | text, | |
| int | text_len | |||
| ) | const [private] |
Definition at line 3484 of file item_cmpfunc.cc.
References bmBc, bmGs, Item_bool_func2::cmp, Arg_comparator::cmp_collation, DTCollation::collation, likeconv, max, min, pattern, pattern_len, and charset_info_st::sort_order.
Referenced by val_int().
03485 { 03486 register int bcShift; 03487 register int turboShift; 03488 int shift = pattern_len; 03489 int j = 0; 03490 int u = 0; 03491 CHARSET_INFO *cs= cmp.cmp_collation.collation; 03492 03493 const int plm1= pattern_len - 1; 03494 const int tlmpl= text_len - pattern_len; 03495 03496 /* Searching */ 03497 if (!cs->sort_order) 03498 { 03499 while (j <= tlmpl) 03500 { 03501 register int i= plm1; 03502 while (i >= 0 && pattern[i] == text[i + j]) 03503 { 03504 i--; 03505 if (i == plm1 - shift) 03506 i-= u; 03507 } 03508 if (i < 0) 03509 return 1; 03510 03511 register const int v = plm1 - i; 03512 turboShift = u - v; 03513 bcShift = bmBc[(uint) (uchar) text[i + j]] - plm1 + i; 03514 shift = max(turboShift, bcShift); 03515 shift = max(shift, bmGs[i]); 03516 if (shift == bmGs[i]) 03517 u = min(pattern_len - shift, v); 03518 else 03519 { 03520 if (turboShift < bcShift) 03521 shift = max(shift, u + 1); 03522 u = 0; 03523 } 03524 j+= shift; 03525 } 03526 return 0; 03527 } 03528 else 03529 { 03530 while (j <= tlmpl) 03531 { 03532 register int i = plm1; 03533 while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j])) 03534 { 03535 i--; 03536 if (i == plm1 - shift) 03537 i-= u; 03538 } 03539 if (i < 0) 03540 return 1; 03541 03542 register const int v = plm1 - i; 03543 turboShift = u - v; 03544 bcShift = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i; 03545 shift = max(turboShift, bcShift); 03546 shift = max(shift, bmGs[i]); 03547 if (shift == bmGs[i]) 03548 u = min(pattern_len - shift, v); 03549 else 03550 { 03551 if (turboShift < bcShift) 03552 shift = max(shift, u + 1); 03553 u = 0; 03554 } 03555 j+= shift; 03556 } 03557 return 0; 03558 } 03559 }
Here is the caller graph for this function:

| longlong Item_func_like::val_int | ( | ) | [virtual] |
Implements Item.
Definition at line 3060 of file item_cmpfunc.cc.
References Item_func::args, canDoTurboBM, Item_bool_func2::cmp, Arg_comparator::cmp_collation, DTCollation::collation, DBUG_ASSERT, escape, Item::fixed, String::length(), my_wildcmp, Item::null_value, String::ptr(), Item_bool_func2::tmp_value1, Item_bool_func2::tmp_value2, turboBM_matches(), Item::val_str(), wild_many, and wild_one.
03061 { 03062 DBUG_ASSERT(fixed == 1); 03063 String* res = args[0]->val_str(&tmp_value1); 03064 if (args[0]->null_value) 03065 { 03066 null_value=1; 03067 return 0; 03068 } 03069 String* res2 = args[1]->val_str(&tmp_value2); 03070 if (args[1]->null_value) 03071 { 03072 null_value=1; 03073 return 0; 03074 } 03075 null_value=0; 03076 if (canDoTurboBM) 03077 return turboBM_matches(res->ptr(), res->length()) ? 1 : 0; 03078 return my_wildcmp(cmp.cmp_collation.collation, 03079 res->ptr(),res->ptr()+res->length(), 03080 res2->ptr(),res2->ptr()+res2->length(), 03081 escape,wild_one,wild_many) ? 0 : 1; 03082 }
Here is the call graph for this function:

int* Item_func_like::bmBc [private] |
Definition at line 1082 of file item_cmpfunc.h.
Referenced by fix_fields(), turboBM_compute_bad_character_shifts(), and turboBM_matches().
int* Item_func_like::bmGs [private] |
Definition at line 1081 of file item_cmpfunc.h.
Referenced by fix_fields(), turboBM_compute_good_suffix_shifts(), and turboBM_matches().
bool Item_func_like::canDoTurboBM [private] |
Definition at line 1076 of file item_cmpfunc.h.
Referenced by cleanup(), fix_fields(), and val_int().
Item* Item_func_like::escape_item [private] |
bool Item_func_like::escape_used_in_parsing [private] |
const char* Item_func_like::pattern [private] |
Definition at line 1077 of file item_cmpfunc.h.
Referenced by fix_fields(), turboBM_compute_bad_character_shifts(), turboBM_compute_suffixes(), and turboBM_matches().
int Item_func_like::pattern_len [private] |
Definition at line 1078 of file item_cmpfunc.h.
Referenced by fix_fields(), turboBM_compute_bad_character_shifts(), turboBM_compute_good_suffix_shifts(), turboBM_compute_suffixes(), and turboBM_matches().
1.4.7

