00001 /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 00018 /* This file defines all string functions 00019 ** Warning: Some string functions doesn't always put and end-null on a String 00020 ** (This shouldn't be needed) 00021 */ 00022 00023 #ifdef USE_PRAGMA_IMPLEMENTATION 00024 #pragma implementation // gcc: Class implementation 00025 #endif 00026 00027 #include "mysql_priv.h" 00028 #include <m_ctype.h> 00029 #ifdef HAVE_OPENSSL 00030 #include <openssl/des.h> 00031 #endif /* HAVE_OPENSSL */ 00032 #include "md5.h" 00033 #include "sha1.h" 00034 #include "my_aes.h" 00035 C_MODE_START 00036 #include "../mysys/my_static.h" // For soundex_map 00037 C_MODE_END 00038 00039 String my_empty_string("",default_charset_info); 00040 00041 static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, 00042 const char *fname) 00043 { 00044 my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0), 00045 c1.collation->name, c1.derivation_name(), 00046 c2.collation->name, c2.derivation_name(), 00047 fname); 00048 } 00049 00050 00051 String *Item_str_func::check_well_formed_result(String *str) 00052 { 00053 /* Check whether we got a well-formed string */ 00054 CHARSET_INFO *cs= str->charset(); 00055 int well_formed_error; 00056 uint wlen= cs->cset->well_formed_len(cs, 00057 str->ptr(), str->ptr() + str->length(), 00058 str->length(), &well_formed_error); 00059 if (wlen < str->length()) 00060 { 00061 THD *thd= current_thd; 00062 char hexbuf[7]; 00063 enum MYSQL_ERROR::enum_warning_level level; 00064 uint diff= str->length() - wlen; 00065 set_if_smaller(diff, 3); 00066 octet2hex(hexbuf, str->ptr() + wlen, diff); 00067 if (thd->variables.sql_mode & 00068 (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)) 00069 { 00070 level= MYSQL_ERROR::WARN_LEVEL_ERROR; 00071 null_value= 1; 00072 str= 0; 00073 } 00074 else 00075 level= MYSQL_ERROR::WARN_LEVEL_WARN; 00076 push_warning_printf(thd, level, ER_INVALID_CHARACTER_STRING, 00077 ER(ER_INVALID_CHARACTER_STRING), cs->csname, hexbuf); 00078 } 00079 return str; 00080 } 00081 00082 00083 my_decimal *Item_str_func::val_decimal(my_decimal *decimal_value) 00084 { 00085 DBUG_ASSERT(fixed == 1); 00086 char buff[64]; 00087 String *res, tmp(buff,sizeof(buff), &my_charset_bin); 00088 res= val_str(&tmp); 00089 if (!res) 00090 return 0; 00091 (void)str2my_decimal(E_DEC_FATAL_ERROR, (char*) res->ptr(), 00092 res->length(), res->charset(), decimal_value); 00093 return decimal_value; 00094 } 00095 00096 00097 double Item_str_func::val_real() 00098 { 00099 DBUG_ASSERT(fixed == 1); 00100 int err_not_used; 00101 char *end_not_used, buff[64]; 00102 String *res, tmp(buff,sizeof(buff), &my_charset_bin); 00103 res= val_str(&tmp); 00104 return res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(), 00105 &end_not_used, &err_not_used) : 0.0; 00106 } 00107 00108 00109 longlong Item_str_func::val_int() 00110 { 00111 DBUG_ASSERT(fixed == 1); 00112 int err; 00113 char buff[22]; 00114 String *res, tmp(buff,sizeof(buff), &my_charset_bin); 00115 res= val_str(&tmp); 00116 return (res ? 00117 my_strntoll(res->charset(), res->ptr(), res->length(), 10, NULL, 00118 &err) : 00119 (longlong) 0); 00120 } 00121 00122 00123 String *Item_func_md5::val_str(String *str) 00124 { 00125 DBUG_ASSERT(fixed == 1); 00126 String * sptr= args[0]->val_str(str); 00127 if (sptr) 00128 { 00129 my_MD5_CTX context; 00130 uchar digest[16]; 00131 00132 null_value=0; 00133 my_MD5Init (&context); 00134 my_MD5Update (&context,(uchar *) sptr->ptr(), sptr->length()); 00135 my_MD5Final (digest, &context); 00136 if (str->alloc(32)) // Ensure that memory is free 00137 { 00138 null_value=1; 00139 return 0; 00140 } 00141 sprintf((char *) str->ptr(), 00142 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 00143 digest[0], digest[1], digest[2], digest[3], 00144 digest[4], digest[5], digest[6], digest[7], 00145 digest[8], digest[9], digest[10], digest[11], 00146 digest[12], digest[13], digest[14], digest[15]); 00147 str->length((uint) 32); 00148 return str; 00149 } 00150 null_value=1; 00151 return 0; 00152 } 00153 00154 00155 void Item_func_md5::fix_length_and_dec() 00156 { 00157 max_length=32; 00158 /* 00159 The MD5() function treats its parameter as being a case sensitive. Thus 00160 we set binary collation on it so different instances of MD5() will be 00161 compared properly. 00162 */ 00163 args[0]->collation.set( 00164 get_charset_by_csname(args[0]->collation.collation->csname, 00165 MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE); 00166 } 00167 00168 00169 String *Item_func_sha::val_str(String *str) 00170 { 00171 DBUG_ASSERT(fixed == 1); 00172 String * sptr= args[0]->val_str(str); 00173 if (sptr) /* If we got value different from NULL */ 00174 { 00175 SHA1_CONTEXT context; /* Context used to generate SHA1 hash */ 00176 /* Temporary buffer to store 160bit digest */ 00177 uint8 digest[SHA1_HASH_SIZE]; 00178 mysql_sha1_reset(&context); /* We do not have to check for error here */ 00179 /* No need to check error as the only case would be too long message */ 00180 mysql_sha1_input(&context, 00181 (const uchar *) sptr->ptr(), sptr->length()); 00182 /* Ensure that memory is free and we got result */ 00183 if (!( str->alloc(SHA1_HASH_SIZE*2) || 00184 (mysql_sha1_result(&context,digest)))) 00185 { 00186 sprintf((char *) str->ptr(), 00187 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\ 00188 %02x%02x%02x%02x%02x%02x%02x%02x", 00189 digest[0], digest[1], digest[2], digest[3], 00190 digest[4], digest[5], digest[6], digest[7], 00191 digest[8], digest[9], digest[10], digest[11], 00192 digest[12], digest[13], digest[14], digest[15], 00193 digest[16], digest[17], digest[18], digest[19]); 00194 00195 str->length((uint) SHA1_HASH_SIZE*2); 00196 null_value=0; 00197 return str; 00198 } 00199 } 00200 null_value=1; 00201 return 0; 00202 } 00203 00204 void Item_func_sha::fix_length_and_dec() 00205 { 00206 max_length=SHA1_HASH_SIZE*2; // size of hex representation of hash 00207 /* 00208 The SHA() function treats its parameter as being a case sensitive. Thus 00209 we set binary collation on it so different instances of MD5() will be 00210 compared properly. 00211 */ 00212 args[0]->collation.set( 00213 get_charset_by_csname(args[0]->collation.collation->csname, 00214 MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE); 00215 } 00216 00217 00218 /* Implementation of AES encryption routines */ 00219 00220 String *Item_func_aes_encrypt::val_str(String *str) 00221 { 00222 DBUG_ASSERT(fixed == 1); 00223 char key_buff[80]; 00224 String tmp_key_value(key_buff, sizeof(key_buff), system_charset_info); 00225 String *sptr= args[0]->val_str(str); // String to encrypt 00226 String *key= args[1]->val_str(&tmp_key_value); // key 00227 int aes_length; 00228 if (sptr && key) // we need both arguments to be not NULL 00229 { 00230 null_value=0; 00231 aes_length=my_aes_get_size(sptr->length()); // Calculate result length 00232 00233 if (!str_value.alloc(aes_length)) // Ensure that memory is free 00234 { 00235 // finally encrypt directly to allocated buffer. 00236 if (my_aes_encrypt(sptr->ptr(),sptr->length(), (char*) str_value.ptr(), 00237 key->ptr(), key->length()) == aes_length) 00238 { 00239 // We got the expected result length 00240 str_value.length((uint) aes_length); 00241 return &str_value; 00242 } 00243 } 00244 } 00245 null_value=1; 00246 return 0; 00247 } 00248 00249 00250 void Item_func_aes_encrypt::fix_length_and_dec() 00251 { 00252 max_length=my_aes_get_size(args[0]->max_length); 00253 } 00254 00255 00256 String *Item_func_aes_decrypt::val_str(String *str) 00257 { 00258 DBUG_ASSERT(fixed == 1); 00259 char key_buff[80]; 00260 String tmp_key_value(key_buff, sizeof(key_buff), system_charset_info); 00261 String *sptr, *key; 00262 DBUG_ENTER("Item_func_aes_decrypt::val_str"); 00263 00264 sptr= args[0]->val_str(str); // String to decrypt 00265 key= args[1]->val_str(&tmp_key_value); // Key 00266 if (sptr && key) // Need to have both arguments not NULL 00267 { 00268 null_value=0; 00269 if (!str_value.alloc(sptr->length())) // Ensure that memory is free 00270 { 00271 // finally decrypt directly to allocated buffer. 00272 int length; 00273 length=my_aes_decrypt(sptr->ptr(), sptr->length(), 00274 (char*) str_value.ptr(), 00275 key->ptr(), key->length()); 00276 if (length >= 0) // if we got correct data data 00277 { 00278 str_value.length((uint) length); 00279 DBUG_RETURN(&str_value); 00280 } 00281 } 00282 } 00283 // Bad parameters. No memory or bad data will all go here 00284 null_value=1; 00285 DBUG_RETURN(0); 00286 } 00287 00288 00289 void Item_func_aes_decrypt::fix_length_and_dec() 00290 { 00291 max_length=args[0]->max_length; 00292 maybe_null= 1; 00293 } 00294 00295 00296 /* 00297 Concatenate args with the following premises: 00298 If only one arg (which is ok), return value of arg 00299 Don't reallocate val_str() if not absolute necessary. 00300 */ 00301 00302 String *Item_func_concat::val_str(String *str) 00303 { 00304 DBUG_ASSERT(fixed == 1); 00305 String *res,*res2,*use_as_buff; 00306 uint i; 00307 bool is_const= 0; 00308 00309 null_value=0; 00310 if (!(res=args[0]->val_str(str))) 00311 goto null; 00312 use_as_buff= &tmp_value; 00313 /* Item_subselect in --ps-protocol mode will state it as a non-const */ 00314 is_const= args[0]->const_item() || !args[0]->used_tables(); 00315 for (i=1 ; i < arg_count ; i++) 00316 { 00317 if (res->length() == 0) 00318 { 00319 if (!(res=args[i]->val_str(str))) 00320 goto null; 00321 } 00322 else 00323 { 00324 if (!(res2=args[i]->val_str(use_as_buff))) 00325 goto null; 00326 if (res2->length() == 0) 00327 continue; 00328 if (res->length()+res2->length() > 00329 current_thd->variables.max_allowed_packet) 00330 { 00331 push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, 00332 ER_WARN_ALLOWED_PACKET_OVERFLOWED, 00333 ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(), 00334 current_thd->variables.max_allowed_packet); 00335 goto null; 00336 } 00337 if (!is_const && res->alloced_length() >= res->length()+res2->length()) 00338 { // Use old buffer 00339 res->append(*res2); 00340 } 00341 else if (str->alloced_length() >= res->length()+res2->length()) 00342 { 00343 if (str == res2) 00344 str->replace(0,0,*res); 00345 else 00346 { 00347 str->copy(*res); 00348 str->append(*res2); 00349 } 00350 res= str; 00351 use_as_buff= &tmp_value; 00352 } 00353 else if (res == &tmp_value) 00354 { 00355 if (res->append(*res2)) // Must be a blob 00356 goto null; 00357 } 00358 else if (res2 == &tmp_value) 00359 { // This can happend only 1 time 00360 if (tmp_value.replace(0,0,*res)) 00361 goto null; 00362 res= &tmp_value; 00363 use_as_buff=str; // Put next arg here 00364 } 00365 else if (tmp_value.is_alloced() && res2->ptr() >= tmp_value.ptr() && 00366 res2->ptr() <= tmp_value.ptr() + tmp_value.alloced_length()) 00367 { 00368 /* 00369 This happens really seldom: 00370 In this case res2 is sub string of tmp_value. We will 00371 now work in place in tmp_value to set it to res | res2 00372 */ 00373 /* Chop the last characters in tmp_value that isn't in res2 */ 00374 tmp_value.length((uint32) (res2->ptr() - tmp_value.ptr()) + 00375 res2->length()); 00376 /* Place res2 at start of tmp_value, remove chars before res2 */ 00377 if (tmp_value.replace(0,(uint32) (res2->ptr() - tmp_value.ptr()), 00378 *res)) 00379 goto null; 00380 res= &tmp_value; 00381 use_as_buff=str; // Put next arg here 00382 } 00383 else 00384 { // Two big const strings 00385 if (tmp_value.alloc(max_length) || 00386 tmp_value.copy(*res) || 00387 tmp_value.append(*res2)) 00388 goto null; 00389 res= &tmp_value; 00390 use_as_buff=str; 00391 } 00392 is_const= 0; 00393 } 00394 } 00395 res->set_charset(collation.collation); 00396 return res; 00397 00398 null: 00399 null_value=1; 00400 return 0; 00401 } 00402 00403 00404 void Item_func_concat::fix_length_and_dec() 00405 { 00406 ulonglong max_result_length= 0; 00407 00408 if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1)) 00409 return; 00410 00411 for (uint i=0 ; i < arg_count ; i++) 00412 { 00413 if (args[i]->collation.collation->mbmaxlen != collation.collation->mbmaxlen) 00414 max_result_length+= (args[i]->max_length / 00415 args[i]->collation.collation->mbmaxlen) * 00416 collation.collation->mbmaxlen; 00417 else 00418 max_result_length+= args[i]->max_length; 00419 } 00420 00421 if (max_result_length >= MAX_BLOB_WIDTH) 00422 { 00423 max_result_length= MAX_BLOB_WIDTH; 00424 maybe_null= 1; 00425 } 00426 max_length= (ulong) max_result_length; 00427 } 00428 00429 /* 00430 Function des_encrypt() by tonu@spam.ee & monty 00431 Works only if compiled with OpenSSL library support. 00432 This returns a binary string where first character is CHAR(128 | key-number). 00433 If one uses a string key key_number is 127. 00434 Encryption result is longer than original by formula: 00435 new_length= org_length + (8-(org_length % 8))+1 00436 */ 00437 00438 String *Item_func_des_encrypt::val_str(String *str) 00439 { 00440 DBUG_ASSERT(fixed == 1); 00441 #ifdef HAVE_OPENSSL 00442 uint code= ER_WRONG_PARAMETERS_TO_PROCEDURE; 00443 DES_cblock ivec; 00444 struct st_des_keyblock keyblock; 00445 struct st_des_keyschedule keyschedule; 00446 const char *append_str="********"; 00447 uint key_number, res_length, tail; 00448 String *res= args[0]->val_str(str); 00449 00450 if ((null_value= args[0]->null_value)) 00451 return 0; // ENCRYPT(NULL) == NULL 00452 if ((res_length=res->length()) == 0) 00453 return &my_empty_string; 00454 00455 if (arg_count == 1) 00456 { 00457 /* Protect against someone doing FLUSH DES_KEY_FILE */ 00458 VOID(pthread_mutex_lock(&LOCK_des_key_file)); 00459 keyschedule= des_keyschedule[key_number=des_default_key]; 00460 VOID(pthread_mutex_unlock(&LOCK_des_key_file)); 00461 } 00462 else if (args[1]->result_type() == INT_RESULT) 00463 { 00464 key_number= (uint) args[1]->val_int(); 00465 if (key_number > 9) 00466 goto error; 00467 VOID(pthread_mutex_lock(&LOCK_des_key_file)); 00468 keyschedule= des_keyschedule[key_number]; 00469 VOID(pthread_mutex_unlock(&LOCK_des_key_file)); 00470 } 00471 else 00472 { 00473 String *keystr=args[1]->val_str(&tmp_value); 00474 if (!keystr) 00475 goto error; 00476 key_number=127; // User key string 00477 00478 /* We make good 24-byte (168 bit) key from given plaintext key with MD5 */ 00479 bzero((char*) &ivec,sizeof(ivec)); 00480 EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL, 00481 (uchar*) keystr->ptr(), (int) keystr->length(), 00482 1, (uchar*) &keyblock,ivec); 00483 DES_set_key_unchecked(&keyblock.key1,&keyschedule.ks1); 00484 DES_set_key_unchecked(&keyblock.key2,&keyschedule.ks2); 00485 DES_set_key_unchecked(&keyblock.key3,&keyschedule.ks3); 00486 } 00487 00488 /* 00489 The problem: DES algorithm requires original data to be in 8-bytes 00490 chunks. Missing bytes get filled with '*'s and result of encryption 00491 can be up to 8 bytes longer than original string. When decrypted, 00492 we do not know the size of original string :( 00493 We add one byte with value 0x1..0x8 as the last byte of the padded 00494 string marking change of string length. 00495 */ 00496 00497 tail= (8-(res_length) % 8); // 1..8 marking extra length 00498 res_length+=tail; 00499 code= ER_OUT_OF_RESOURCES; 00500 if (tail && res->append(append_str, tail) || tmp_value.alloc(res_length+1)) 00501 goto error; 00502 (*res)[res_length-1]=tail; // save extra length 00503 tmp_value.length(res_length+1); 00504 tmp_value[0]=(char) (128 | key_number); 00505 // Real encryption 00506 bzero((char*) &ivec,sizeof(ivec)); 00507 DES_ede3_cbc_encrypt((const uchar*) (res->ptr()), 00508 (uchar*) (tmp_value.ptr()+1), 00509 res_length, 00510 &keyschedule.ks1, 00511 &keyschedule.ks2, 00512 &keyschedule.ks3, 00513 &ivec, TRUE); 00514 return &tmp_value; 00515 00516 error: 00517 push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, 00518 code, ER(code), 00519 "des_encrypt"); 00520 #else 00521 push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, 00522 ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED), 00523 "des_encrypt","--with-openssl"); 00524 #endif /* HAVE_OPENSSL */ 00525 null_value=1; 00526 return 0; 00527 } 00528 00529 00530 String *Item_func_des_decrypt::val_str(String *str) 00531 { 00532 DBUG_ASSERT(fixed == 1); 00533 #ifdef HAVE_OPENSSL 00534 uint code= ER_WRONG_PARAMETERS_TO_PROCEDURE; 00535 DES_cblock ivec; 00536 struct st_des_keyblock keyblock; 00537 struct st_des_keyschedule keyschedule; 00538 String *res= args[0]->val_str(str); 00539 uint length,tail; 00540 00541 if ((null_value= args[0]->null_value)) 00542 return 0; 00543 length= res->length(); 00544 if (length < 9 || (length % 8) != 1 || !((*res)[0] & 128)) 00545 return res; // Skip decryption if not encrypted 00546 00547 if (arg_count == 1) // If automatic uncompression 00548 { 00549 uint key_number=(uint) (*res)[0] & 127; 00550 // Check if automatic key and that we have privilege to uncompress using it 00551 if (!(current_thd->security_ctx->master_access & SUPER_ACL) || 00552 key_number > 9) 00553 goto error; 00554 00555 VOID(pthread_mutex_lock(&LOCK_des_key_file)); 00556 keyschedule= des_keyschedule[key_number]; 00557 VOID(pthread_mutex_unlock(&LOCK_des_key_file)); 00558 } 00559 else 00560 { 00561 // We make good 24-byte (168 bit) key from given plaintext key with MD5 00562 String *keystr=args[1]->val_str(&tmp_value); 00563 if (!keystr) 00564 goto error; 00565 00566 bzero((char*) &ivec,sizeof(ivec)); 00567 EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL, 00568 (uchar*) keystr->ptr(),(int) keystr->length(), 00569 1,(uchar*) &keyblock,ivec); 00570 // Here we set all 64-bit keys (56 effective) one by one 00571 DES_set_key_unchecked(&keyblock.key1,&keyschedule.ks1); 00572 DES_set_key_unchecked(&keyblock.key2,&keyschedule.ks2); 00573 DES_set_key_unchecked(&keyblock.key3,&keyschedule.ks3); 00574 } 00575 code= ER_OUT_OF_RESOURCES; 00576 if (tmp_value.alloc(length-1)) 00577 goto error; 00578 00579 bzero((char*) &ivec,sizeof(ivec)); 00580 DES_ede3_cbc_encrypt((const uchar*) res->ptr()+1, 00581 (uchar*) (tmp_value.ptr()), 00582 length-1, 00583 &keyschedule.ks1, 00584 &keyschedule.ks2, 00585 &keyschedule.ks3, 00586 &ivec, FALSE); 00587 /* Restore old length of key */ 00588 if ((tail=(uint) (uchar) tmp_value[length-2]) > 8) 00589 goto wrong_key; // Wrong key 00590 tmp_value.length(length-1-tail); 00591 return &tmp_value; 00592 00593 error: 00594 push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, 00595 code, ER(code), 00596 "des_decrypt"); 00597 wrong_key: 00598 #else 00599 push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, 00600 ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED), 00601 "des_decrypt","--with-openssl"); 00602 #endif /* HAVE_OPENSSL */ 00603 null_value=1; 00604 return 0; 00605 } 00606 00607 00608 /* 00609 concat with separator. First arg is the separator 00610 concat_ws takes at least two arguments. 00611 */ 00612 00613 String *Item_func_concat_ws::val_str(String *str) 00614 { 00615 DBUG_ASSERT(fixed == 1); 00616 char tmp_str_buff[10]; 00617 String tmp_sep_str(tmp_str_buff, sizeof(tmp_str_buff),default_charset_info), 00618 *sep_str, *res, *res2,*use_as_buff; 00619 uint i; 00620 00621 null_value=0; 00622 if (!(sep_str= args[0]->val_str(&tmp_sep_str))) 00623 goto null; 00624 00625 use_as_buff= &tmp_value; 00626 str->length(0); // QQ; Should be removed 00627 res=str; 00628 00629 // Skip until non-null argument is found. 00630 // If not, return the empty string 00631 for (i=1; i < arg_count; i++) 00632 if ((res= args[i]->val_str(str))) 00633 break; 00634 if (i == arg_count) 00635 return &my_empty_string; 00636 00637 for (i++; i < arg_count ; i++) 00638 { 00639 if (!(res2= args[i]->val_str(use_as_buff))) 00640 continue; // Skip NULL 00641 00642 if (res->length() + sep_str->length() + res2->length() > 00643 current_thd->variables.max_allowed_packet) 00644 { 00645 push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, 00646 ER_WARN_ALLOWED_PACKET_OVERFLOWED, 00647 ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(), 00648 current_thd->variables.max_allowed_packet); 00649 goto null; 00650 } 00651 if (res->alloced_length() >= 00652 res->length() + sep_str->length() + res2->length()) 00653 { // Use old buffer 00654 res->append(*sep_str); // res->length() > 0 always 00655 res->append(*res2); 00656 } 00657 else if (str->alloced_length() >= 00658 res->length() + sep_str->length() + res2->length()) 00659 { 00660 /* We have room in str; We can't get any errors here */ 00661 if (str == res2) 00662 { // This is quote uncommon! 00663 str->replace(0,0,*sep_str); 00664 str->replace(0,0,*res); 00665 } 00666 else 00667 { 00668 str->copy(*res); 00669 str->append(*sep_str); 00670 str->append(*res2); 00671 } 00672 res=str; 00673 use_as_buff= &tmp_value; 00674 } 00675 else if (res == &tmp_value) 00676 { 00677 if (res->append(*sep_str) || res->append(*res2)) 00678 goto null; // Must be a blob 00679 } 00680 else if (res2 == &tmp_value) 00681 { // This can happend only 1 time 00682 if (tmp_value.replace(0,0,*sep_str) || tmp_value.replace(0,0,*res)) 00683 goto null; 00684 res= &tmp_value; 00685 use_as_buff=str; // Put next arg here 00686 } 00687 else if (tmp_value.is_alloced() && res2->ptr() >= tmp_value.ptr() && 00688 res2->ptr() < tmp_value.ptr() + tmp_value.alloced_length()) 00689 { 00690 /* 00691 This happens really seldom: 00692 In this case res2 is sub string of tmp_value. We will 00693 now work in place in tmp_value to set it to res | sep_str | res2 00694 */ 00695 /* Chop the last characters in tmp_value that isn't in res2 */ 00696 tmp_value.length((uint32) (res2->ptr() - tmp_value.ptr()) + 00697 res2->length()); 00698 /* Place res2 at start of tmp_value, remove chars before res2 */ 00699 if (tmp_value.replace(0,(uint32) (res2->ptr() - tmp_value.ptr()), 00700 *res) || 00701 tmp_value.replace(res->length(),0, *sep_str)) 00702 goto null; 00703 res= &tmp_value; 00704 use_as_buff=str; // Put next arg here 00705 } 00706 else 00707 { // Two big const strings 00708 if (tmp_value.alloc(max_length) || 00709 tmp_value.copy(*res) || 00710 tmp_value.append(*sep_str) || 00711 tmp_value.append(*res2)) 00712 goto null; 00713 res= &tmp_value; 00714 use_as_buff=str; 00715 } 00716 } 00717 res->set_charset(collation.collation); 00718 return res; 00719 00720 null: 00721 null_value=1; 00722 return 0; 00723 } 00724 00725 00726 void Item_func_concat_ws::fix_length_and_dec() 00727 { 00728 ulonglong max_result_length; 00729 00730 if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1)) 00731 return; 00732 00733 /* 00734 arg_count cannot be less than 2, 00735 it is done on parser level in sql_yacc.yy 00736 so, (arg_count - 2) is safe here. 00737 */ 00738 max_result_length= (ulonglong) args[0]->max_length * (arg_count - 2); 00739 for (uint i=1 ; i < arg_count ; i++) 00740 max_result_length+=args[i]->max_length; 00741 00742 if (max_result_length >= MAX_BLOB_WIDTH) 00743 { 00744 max_result_length= MAX_BLOB_WIDTH; 00745 maybe_null= 1; 00746 } 00747 max_length= (ulong) max_result_length; 00748 } 00749 00750 00751 String *Item_func_reverse::val_str(String *str) 00752 { 00753 DBUG_ASSERT(fixed == 1); 00754 String *res = args[0]->val_str(str); 00755 char *ptr, *end, *tmp; 00756 00757 if ((null_value=args[0]->null_value)) 00758 return 0; 00759 /* An empty string is a special case as the string pointer may be null */ 00760 if (!res->length()) 00761 return &my_empty_string; 00762 if (tmp_value.alloced_length() < res->length() && 00763 tmp_value.realloc(res->length())) 00764 { 00765 null_value= 1; 00766 return 0; 00767 } 00768 tmp_value.length(res->length()); 00769 tmp_value.set_charset(res->charset()); 00770 ptr= (char *) res->ptr(); 00771 end= ptr + res->length(); 00772 tmp= (char *) tmp_value.ptr() + tmp_value.length(); 00773 #ifdef USE_MB 00774 if (use_mb(res->charset())) 00775 { 00776 register uint32 l; 00777 while (ptr < end) 00778 { 00779 if ((l= my_ismbchar(res->charset(),ptr,end))) 00780 { 00781 tmp-= l; 00782 memcpy(tmp,ptr,l); 00783 ptr+= l; 00784 } 00785 else 00786 *--tmp= *ptr++; 00787 } 00788 } 00789 else 00790 #endif /* USE_MB */ 00791 { 00792 while (ptr < end) 00793 *--tmp= *ptr++; 00794 } 00795 return &tmp_value; 00796 } 00797 00798 00799 void Item_func_reverse::fix_length_and_dec() 00800 { 00801 collation.set(args[0]->collation); 00802 max_length = args[0]->max_length; 00803 } 00804 00805 /* 00806 ** Replace all occurences of string2 in string1 with string3. 00807 ** Don't reallocate val_str() if not needed 00808 */ 00809 00810 /* TODO: Fix that this works with binary strings when using USE_MB */ 00811 00812 String *Item_func_replace::val_str(String *str) 00813 { 00814 DBUG_ASSERT(fixed == 1); 00815 String *res,*res2,*res3; 00816 int offset; 00817 uint from_length,to_length; 00818 bool alloced=0; 00819 #ifdef USE_MB 00820 const char *ptr,*end,*strend,*search,*search_end; 00821 register uint32 l; 00822 bool binary_cmp; 00823 #endif 00824 00825 null_value=0; 00826 res=args[0]->val_str(str); 00827 if (args[0]->null_value) 00828 goto null; 00829 res2=args[1]->val_str(&tmp_value); 00830 if (args[1]->null_value) 00831 goto null; 00832 00833 res->set_charset(collation.collation); 00834 00835 #ifdef USE_MB 00836 binary_cmp = ((res->charset()->state & MY_CS_BINSORT) || !use_mb(res->charset())); 00837 #endif 00838 00839 if (res2->length() == 0) 00840 return res; 00841 #ifndef USE_MB 00842 if ((offset=res->strstr(*res2)) < 0) 00843 return res; 00844 #else 00845 offset=0; 00846 if (binary_cmp && (offset=res->strstr(*res2)) < 0) 00847 return res; 00848 #endif 00849 if (!(res3=args[2]->val_str(&tmp_value2))) 00850 goto null; 00851 from_length= res2->length(); 00852 to_length= res3->length(); 00853 00854 #ifdef USE_MB 00855 if (!binary_cmp) 00856 { 00857 search=res2->ptr(); 00858 search_end=search+from_length; 00859 redo: 00860 ptr=res->ptr()+offset; 00861 strend=res->ptr()+res->length(); 00862 end=strend-from_length+1; 00863 while (ptr < end) 00864 { 00865 if (*ptr == *search) 00866 { 00867 register char *i,*j; 00868 i=(char*) ptr+1; j=(char*) search+1; 00869 while (j != search_end) 00870 if (*i++ != *j++) goto skip; 00871 offset= (int) (ptr-res->ptr()); 00872 if (res->length()-from_length + to_length > 00873 current_thd->variables.max_allowed_packet) 00874 { 00875 push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, 00876 ER_WARN_ALLOWED_PACKET_OVERFLOWED, 00877 ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), 00878 func_name(), 00879 current_thd->variables.max_allowed_packet); 00880 00881 goto null; 00882 } 00883 if (!alloced) 00884 { 00885 alloced=1; 00886 res=copy_if_not_alloced(str,res,res->length()+to_length); 00887 } 00888 res->replace((uint) offset,from_length,*res3); 00889 offset+=(int) to_length; 00890 goto redo; 00891 } 00892 skip: 00893 if ((l=my_ismbchar(res->charset(), ptr,strend))) ptr+=l; 00894 else ++ptr; 00895 } 00896 } 00897 else 00898 #endif /* USE_MB */ 00899 do 00900 { 00901 if (res->length()-from_length + to_length > 00902 current_thd->variables.max_allowed_packet) 00903 { 00904 push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, 00905 ER_WARN_ALLOWED_PACKET_OVERFLOWED, 00906 ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(), 00907 current_thd->variables.max_allowed_packet); 00908 goto null; 00909 } 00910 if (!alloced) 00911 { 00912 alloced=1; 00913 res=copy_if_not_alloced(str,res,res->length()+to_length); 00914 } 00915 res->replace((uint) offset,from_length,*res3); 00916 offset+=(int) to_length; 00917 } 00918 while ((offset=res->strstr(*res2,(uint) offset)) >= 0); 00919 return res; 00920 00921 null: 00922 null_value=1; 00923 return 0; 00924 } 00925 00926 00927 void Item_func_replace::fix_length_and_dec() 00928 { 00929 ulonglong max_result_length= args[0]->max_length; 00930 int diff=(int) (args[2]->max_length - args[1]->max_length); 00931 if (diff > 0 && args[1]->max_length) 00932 { // Calculate of maxreplaces 00933 ulonglong max_substrs= max_result_length/args[1]->max_length; 00934 max_result_length+= max_substrs * (uint) diff; 00935 } 00936 if (max_result_length >= MAX_BLOB_WIDTH) 00937 { 00938 max_result_length= MAX_BLOB_WIDTH; 00939 maybe_null= 1; 00940 } 00941 max_length= (ulong) max_result_length; 00942 00943 if (agg_arg_charsets(collation, args, 3, MY_COLL_CMP_CONV, 1)) 00944 return; 00945 } 00946 00947 00948 String *Item_func_insert::val_str(String *str) 00949 { 00950 DBUG_ASSERT(fixed == 1); 00951 String *res,*res2; 00952 uint start,length; 00953 00954 null_value=0; 00955 res=args[0]->val_str(str); 00956 res2=args[3]->val_str(&tmp_value); 00957 start=(uint) args[1]->val_int()-1; 00958 length=(uint) args[2]->val_int(); 00959 if (args[0]->null_value || args[1]->null_value || args[2]->null_value || 00960 args[3]->null_value) 00961 goto null; /* purecov: inspected */ 00962 start=res->charpos(start); 00963 length=res->charpos(length,start); 00964 if (start > res->length()+1) 00965 return res; // Wrong param; skip insert 00966 if (length > res->length()-start) 00967 length=res->length()-start; 00968 if (res->length() - length + res2->length() > 00969 current_thd->variables.max_allowed_packet) 00970 { 00971 push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, 00972 ER_WARN_ALLOWED_PACKET_OVERFLOWED, 00973 ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), 00974 func_name(), current_thd->variables.max_allowed_packet); 00975 goto null; 00976 } 00977 res=copy_if_not_alloced(str,res,res->length()); 00978 res->replace(start,length,*res2); 00979 return res; 00980 null: 00981 null_value=1; 00982 return 0; 00983 } 00984 00985 00986 void Item_func_insert::fix_length_and_dec() 00987 { 00988 ulonglong max_result_length; 00989 00990 // Handle character set for args[0] and args[3]. 00991 if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 3)) 00992 return; 00993 max_result_length= ((ulonglong) args[0]->max_length+ 00994 (ulonglong) args[3]->max_length); 00995 if (max_result_length >= MAX_BLOB_WIDTH) 00996 { 00997 max_result_length= MAX_BLOB_WIDTH; 00998 maybe_null= 1; 00999 } 01000 max_length= (ulong) max_result_length; 01001 } 01002 01003 01004 String *Item_str_conv::val_str(String *str) 01005 { 01006 DBUG_ASSERT(fixed == 1); 01007 String *res; 01008 if (!(res=args[0]->val_str(str))) 01009 { 01010 null_value=1; /* purecov: inspected */ 01011 return 0; /* purecov: inspected */ 01012 } 01013 null_value=0; 01014 if (multiply == 1) 01015 { 01016 uint len; 01017 res= copy_if_not_alloced(str,res,res->length()); 01018 len= converter(collation.collation, (char*) res->ptr(), res->length(), 01019 (char*) res->ptr(), res->length()); 01020 DBUG_ASSERT(len <= res->length()); 01021 res->length(len); 01022 } 01023 else 01024 { 01025 uint len= res->length() * multiply; 01026 tmp_value.alloc(len); 01027 tmp_value.set_charset(collation.collation); 01028 len= converter(collation.collation, (char*) res->ptr(), res->length(), 01029 (char*) tmp_value.ptr(), len); 01030 tmp_value.length(len); 01031 res= &tmp_value; 01032 } 01033 return res; 01034 } 01035 01036 01037 String *Item_func_left::val_str(String *str) 01038 { 01039 DBUG_ASSERT(fixed == 1); 01040 String *res =args[0]->val_str(str); 01041 long length =(long) args[1]->val_int(); 01042 uint char_pos; 01043 01044 if ((null_value=(args[0]->null_value || args[1]->null_value))) 01045 return 0; 01046 if (length <= 0) 01047 return &my_empty_string; 01048 if (res->length() <= (uint) length || 01049 res->length() <= (char_pos= res->charpos(length))) 01050 return res; 01051 01052 tmp_value.set(*res, 0, char_pos); 01053 return &tmp_value; 01054 } 01055 01056 01057 void Item_str_func::left_right_max_length() 01058 { 01059 max_length=args[0]->max_length; 01060 if (args[1]->const_item()) 01061 { 01062 int length=(int) args[1]->val_int()*collation.collation->mbmaxlen; 01063 if (length <= 0) 01064 max_length=0; 01065 else 01066 set_if_smaller(max_length,(uint) length); 01067 } 01068 } 01069 01070 01071 void Item_func_left::fix_length_and_dec() 01072 { 01073 collation.set(args[0]->collation); 01074 left_right_max_length(); 01075 } 01076 01077 01078 String *Item_func_right::val_str(String *str) 01079 { 01080 DBUG_ASSERT(fixed == 1); 01081 String *res =args[0]->val_str(str); 01082 long length =(long) args[1]->val_int(); 01083 01084 if ((null_value=(args[0]->null_value || args[1]->null_value))) 01085 return 0; /* purecov: inspected */ 01086 if (length <= 0) 01087 return &my_empty_string; /* purecov: inspected */ 01088 if (res->length() <= (uint) length) 01089 return res; /* purecov: inspected */ 01090 01091 uint start=res->numchars(); 01092 if (start <= (uint) length) 01093 return res; 01094 start=res->charpos(start - (uint) length); 01095 tmp_value.set(*res,start,res->length()-start); 01096 return &tmp_value; 01097 } 01098 01099 01100 void Item_func_right::fix_length_and_dec() 01101 { 01102 collation.set(args[0]->collation); 01103 left_right_max_length(); 01104 } 01105 01106 01107 String *Item_func_substr::val_str(String *str) 01108 { 01109 DBUG_ASSERT(fixed == 1); 01110 String *res = args[0]->val_str(str); 01111 int32 start = (int32) args[1]->val_int(); 01112 int32 length = arg_count == 3 ? (int32) args[2]->val_int() : INT_MAX32; 01113 int32 tmp_length; 01114 01115 if ((null_value=(args[0]->null_value || args[1]->null_value || 01116 (arg_count == 3 && args[2]->null_value)))) 01117 return 0; /* purecov: inspected */ 01118 start= (int32)((start < 0) ? res->numchars() + start : start -1); 01119 start=res->charpos(start); 01120 length=res->charpos(length,start); 01121 if (start < 0 || (uint) start+1 > res->length() || length <= 0) 01122 return &my_empty_string; 01123 01124 tmp_length=(int32) res->length()-start; 01125 length=min(length,tmp_length); 01126 01127 if (!start && res->length() == (uint) length) 01128 return res; 01129 tmp_value.set(*res,(uint) start,(uint) length); 01130 return &tmp_value; 01131 } 01132 01133 01134 void Item_func_substr::fix_length_and_dec() 01135 { 01136 max_length=args[0]->max_length; 01137 01138 collation.set(args[0]->collation); 01139 if (args[1]->const_item()) 01140 { 01141 int32 start= (int32) args[1]->val_int(); 01142 start= (int32)((start < 0) ? max_length + start : start - 1); 01143 if (start < 0 || start >= (int32) max_length) 01144 max_length=0; /* purecov: inspected */ 01145 else 01146 max_length-= (uint) start; 01147 } 01148 if (arg_count == 3 && args[2]->const_item()) 01149 { 01150 int32 length= (int32) args[2]->val_int() * collation.collation->mbmaxlen; 01151 if (length <= 0) 01152 max_length=0; /* purecov: inspected */ 01153 else 01154 set_if_smaller(max_length,(uint) length); 01155 } 01156 } 01157 01158 01159 void Item_func_substr_index::fix_length_and_dec() 01160 { 01161 max_length= args[0]->max_length; 01162 01163 if (agg_arg_charsets(collation, args, 2, MY_COLL_CMP_CONV, 1)) 01164 return; 01165 } 01166 01167 01168 String *Item_func_substr_index::val_str(String *str) 01169 { 01170 DBUG_ASSERT(fixed == 1); 01171 String *res= args[0]->val_str(str); 01172 String *delimiter= args[1]->val_str(&tmp_value); 01173 int32 count= (int32) args[2]->val_int(); 01174 uint offset; 01175 01176 if (args[0]->null_value || args[1]->null_value || args[2]->null_value) 01177 { // string and/or delim are null 01178 null_value=1; 01179 return 0; 01180 } 01181 null_value=0; 01182 uint delimiter_length= delimiter->length(); 01183 if (!res->length() || !delimiter_length || !count) 01184 return &my_empty_string; // Wrong parameters 01185 01186 res->set_charset(collation.collation); 01187 01188 #ifdef USE_MB 01189 if (use_mb(res->charset())) 01190 { 01191 const char *ptr= res->ptr(); 01192 const char *strend= ptr+res->length(); 01193 const char *end= strend-delimiter_length+1; 01194 const char *search= delimiter->ptr(); 01195 const char *search_end= search+delimiter_length; 01196 int32 n=0,c=count,pass; 01197 register uint32 l; 01198 for (pass=(count>0);pass<2;++pass) 01199 { 01200 while (ptr < end) 01201 { 01202 if (*ptr == *search) 01203 { 01204 register char *i,*j; 01205 i=(char*) ptr+1; j=(char*) search+1; 01206 while (j != search_end) 01207 if (*i++ != *j++) goto skip; 01208 if (pass==0) ++n; 01209 else if (!--c) break; 01210 ptr+= delimiter_length; 01211 continue; 01212 } 01213 skip: 01214 if ((l=my_ismbchar(res->charset(), ptr,strend))) ptr+=l; 01215 else ++ptr; 01216 } /* either not found or got total number when count<0 */ 01217 if (pass == 0) /* count<0 */ 01218 { 01219 c+=n+1; 01220 if (c<=0) return res; /* not found, return original string */ 01221 ptr=res->ptr(); 01222 } 01223 else 01224 { 01225 if (c) return res; /* Not found, return original string */ 01226 if (count>0) /* return left part */ 01227 { 01228 tmp_value.set(*res,0,(ulong) (ptr-res->ptr())); 01229 } 01230 else /* return right part */ 01231 { 01232 ptr+= delimiter_length; 01233 tmp_value.set(*res,(ulong) (ptr-res->ptr()), (ulong) (strend-ptr)); 01234 } 01235 } 01236 } 01237 } 01238 else 01239 #endif /* USE_MB */ 01240 { 01241 if (count > 0) 01242 { // start counting from the beginning 01243 for (offset=0; ; offset+= delimiter_length) 01244 { 01245 if ((int) (offset= res->strstr(*delimiter, offset)) < 0) 01246 return res; // Didn't find, return org string 01247 if (!--count) 01248 { 01249 tmp_value.set(*res,0,offset); 01250 break; 01251 } 01252 } 01253 } 01254 else 01255 { 01256 /* 01257 Negative index, start counting at the end 01258 */ 01259 for (offset=res->length(); offset ;) 01260 { 01261 /* 01262 this call will result in finding the position pointing to one 01263 address space less than where the found substring is located 01264 in res 01265 */ 01266 if ((int) (offset= res->strrstr(*delimiter, offset)) < 0) 01267 return res; // Didn't find, return org string 01268 /* 01269 At this point, we've searched for the substring 01270 the number of times as supplied by the index value 01271 */ 01272 if (!++count) 01273 { 01274 offset+= delimiter_length; 01275 tmp_value.set(*res,offset,res->length()- offset); 01276 break; 01277 } 01278 } 01279 } 01280 } 01281 /* 01282 We always mark tmp_value as const so that if val_str() is called again 01283 on this object, we don't disrupt the contents of tmp_value when it was 01284 derived from another String. 01285 */ 01286 tmp_value.mark_as_const(); 01287 return (&tmp_value); 01288 } 01289 01290 /* 01291 ** The trim functions are extension to ANSI SQL because they trim substrings 01292 ** They ltrim() and rtrim() functions are optimized for 1 byte strings 01293 ** They also return the original string if possible, else they return 01294 ** a substring that points at the original string. 01295 */ 01296 01297 01298 String *Item_func_ltrim::val_str(String *str) 01299 { 01300 DBUG_ASSERT(fixed == 1); 01301 char buff[MAX_FIELD_WIDTH], *ptr, *end; 01302 String tmp(buff,sizeof(buff),system_charset_info); 01303 String *res, *remove_str; 01304 uint remove_length; 01305 LINT_INIT(remove_length); 01306 01307 res= args[0]->val_str(str); 01308 if ((null_value=args[0]->null_value)) 01309 return 0; 01310 remove_str= &remove; /* Default value. */ 01311 if (arg_count == 2) 01312 { 01313 remove_str= args[1]->val_str(&tmp); 01314 if ((null_value= args[1]->null_value)) 01315 return 0; 01316 } 01317 01318 if ((remove_length= remove_str->length()) == 0 || 01319 remove_length > res->length()) 01320 return res; 01321 01322 ptr= (char*) res->ptr(); 01323 end= ptr+res->length(); 01324 if (remove_length == 1) 01325 { 01326 char chr=(*remove_str)[0]; 01327 while (ptr != end && *ptr == chr) 01328 ptr++; 01329 } 01330 else 01331 { 01332 const char *r_ptr=remove_str->ptr(); 01333 end-=remove_length; 01334 while (ptr <= end && !memcmp(ptr, r_ptr, remove_length)) 01335 ptr+=remove_length; 01336 end+=remove_length; 01337 } 01338 if (ptr == res->ptr()) 01339 return res; 01340 tmp_value.set(*res,(uint) (ptr - res->ptr()),(uint) (end-ptr)); 01341 return &tmp_value; 01342 } 01343 01344 01345 String *Item_func_rtrim::val_str(String *str) 01346 { 01347 DBUG_ASSERT(fixed == 1); 01348 char buff[MAX_FIELD_WIDTH], *ptr, *end; 01349 String tmp(buff, sizeof(buff), system_charset_info); 01350 String *res, *remove_str; 01351 uint remove_length; 01352 LINT_INIT(remove_length); 01353 01354 res= args[0]->val_str(str); 01355 if ((null_value=args[0]->null_value)) 01356 return 0; 01357 remove_str= &remove; /* Default value. */ 01358 if (arg_count == 2) 01359 { 01360 remove_str= args[1]->val_str(&tmp); 01361 if ((null_value= args[1]->null_value)) 01362 return 0; 01363 } 01364 01365 if ((remove_length= remove_str->length()) == 0 || 01366 remove_length > res->length()) 01367 return res; 01368 01369 ptr= (char*) res->ptr(); 01370 end= ptr+res->length(); 01371 #ifdef USE_MB 01372 char *p=ptr; 01373 register uint32 l; 01374 #endif 01375 if (remove_length == 1) 01376 { 01377 char chr=(*remove_str)[0]; 01378 #ifdef USE_MB 01379 if (use_mb(res->charset())) 01380 { 01381 while (ptr < end) 01382 { 01383 if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l,p=ptr; 01384 else ++ptr; 01385 } 01386 ptr=p; 01387 } 01388 #endif 01389 while (ptr != end && end[-1] == chr) 01390 end--; 01391 } 01392 else 01393 { 01394 const char *r_ptr=remove_str->ptr(); 01395 #ifdef USE_MB 01396 if (use_mb(res->charset())) 01397 { 01398 loop: 01399 while (ptr + remove_length < end) 01400 { 01401 if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l; 01402 else ++ptr; 01403 } 01404 if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length)) 01405 { 01406 end-=remove_length; 01407 ptr=p; 01408 goto loop; 01409 } 01410 } 01411 else 01412 #endif /* USE_MB */ 01413 { 01414 while (ptr + remove_length <= end && 01415 !memcmp(end-remove_length, r_ptr, remove_length)) 01416 end-=remove_length; 01417 } 01418 } 01419 if (end == res->ptr()+res->length()) 01420 return res; 01421 tmp_value.set(*res,0,(uint) (end-res->ptr())); 01422 return &tmp_value; 01423 } 01424 01425 01426 String *Item_func_trim::val_str(String *str) 01427 { 01428 DBUG_ASSERT(fixed == 1); 01429 char buff[MAX_FIELD_WIDTH], *ptr, *end; 01430 const char *r_ptr; 01431 String tmp(buff, sizeof(buff), system_charset_info); 01432 String *res, *remove_str; 01433 uint remove_length; 01434 LINT_INIT(remove_length); 01435 01436 res= args[0]->val_str(str); 01437 if ((null_value=args[0]->null_value)) 01438 return 0; 01439 remove_str= &remove; /* Default value. */ 01440 if (arg_count == 2) 01441 { 01442 remove_str= args[1]->val_str(&tmp); 01443 if ((null_value= args[1]->null_value)) 01444 return 0; 01445 } 01446 01447 if ((remove_length= remove_str->length()) == 0 || 01448 remove_length > res->length()) 01449 return res; 01450 01451 ptr= (char*) res->ptr(); 01452 end= ptr+res->length(); 01453 r_ptr= remove_str->ptr(); 01454 while (ptr+remove_length <= end && !memcmp(ptr,r_ptr,remove_length)) 01455 ptr+=remove_length; 01456 #ifdef USE_MB 01457 if (use_mb(res->charset())) 01458 { 01459 char *p=ptr; 01460 register uint32 l; 01461 loop: 01462 while (ptr + remove_length < end) 01463 { 01464 if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l; 01465 else ++ptr; 01466 } 01467 if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length)) 01468 { 01469 end-=remove_length; 01470 ptr=p; 01471 goto loop; 01472 } 01473 ptr=p; 01474 } 01475 else 01476 #endif /* USE_MB */ 01477 { 01478 while (ptr + remove_length <= end && 01479 !memcmp(end-remove_length,r_ptr,remove_length)) 01480 end-=remove_length; 01481 } 01482 if (ptr == res->ptr() && end == ptr+res->length()) 01483 return res; 01484 tmp_value.set(*res,(uint) (ptr - res->ptr()),(uint) (end-ptr)); 01485 return &tmp_value; 01486 } 01487 01488 void Item_func_trim::fix_length_and_dec() 01489 { 01490 max_length= args[0]->max_length; 01491 if (arg_count == 1) 01492 { 01493 collation.set(args[0]->collation); 01494 remove.set_charset(collation.collation); 01495 remove.set_ascii(" ",1); 01496 } 01497 else 01498 { 01499 // Handle character set for args[1] and args[0]. 01500 // Note that we pass args[1] as the first item, and args[0] as the second. 01501 if (agg_arg_charsets(collation, &args[1], 2, MY_COLL_CMP_CONV, -1)) 01502 return; 01503 } 01504 } 01505 01506 void Item_func_trim::print(String *str) 01507 { 01508 if (arg_count == 1) 01509 { 01510 Item_func::print(str); 01511 return; 01512 } 01513 str->append(Item_func_trim::func_name()); 01514 str->append('('); 01515 str->append(mode_name()); 01516 str->append(' '); 01517 args[1]->print(str); 01518 str->append(STRING_WITH_LEN(" from ")); 01519 args[0]->print(str); 01520 str->append(')'); 01521 } 01522 01523 01524 /* Item_func_password */ 01525 01526 String *Item_func_password::val_str(String *str) 01527 { 01528 DBUG_ASSERT(fixed == 1); 01529 String *res= args[0]->val_str(str); 01530 if ((null_value=args[0]->null_value)) 01531 return 0; 01532 if (res->length() == 0) 01533 return &my_empty_string; 01534 make_scrambled_password(tmp_value, res->c_ptr()); 01535 str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH, res->charset()); 01536 return str; 01537 } 01538 01539 char *Item_func_password::alloc(THD *thd, const char *password) 01540 { 01541 char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1); 01542 if (buff) 01543 make_scrambled_password(buff, password); 01544 return buff; 01545 } 01546 01547 /* Item_func_old_password */ 01548 01549 String *Item_func_old_password::val_str(String *str) 01550 { 01551 DBUG_ASSERT(fixed == 1); 01552 String *res= args[0]->val_str(str); 01553 if ((null_value=args[0]->null_value)) 01554 return 0; 01555 if (res->length() == 0) 01556 return &my_empty_string; 01557 make_scrambled_password_323(tmp_value, res->c_ptr()); 01558 str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH_323, res->charset()); 01559 return str; 01560 } 01561 01562 char *Item_func_old_password::alloc(THD *thd, const char *password) 01563 { 01564 char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1); 01565 if (buff) 01566 make_scrambled_password_323(buff, password); 01567 return buff; 01568 } 01569 01570 01571 #define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.') 01572 01573 String *Item_func_encrypt::val_str(String *str) 01574 { 01575 DBUG_ASSERT(fixed == 1); 01576 String *res =args[0]->val_str(str); 01577 01578 #ifdef HAVE_CRYPT 01579 char salt[3],*salt_ptr; 01580 if ((null_value=args[0]->null_value)) 01581 return 0; 01582 if (res->length() == 0) 01583 return &my_empty_string; 01584 01585 if (arg_count == 1) 01586 { // generate random salt 01587 time_t timestamp=current_thd->query_start(); 01588 salt[0] = bin_to_ascii( (ulong) timestamp & 0x3f); 01589 salt[1] = bin_to_ascii(( (ulong) timestamp >> 5) & 0x3f); 01590 salt[2] = 0; 01591 salt_ptr=salt; 01592 } 01593 else 01594 { // obtain salt from the first two bytes 01595 String *salt_str=args[1]->val_str(&tmp_value); 01596 if ((null_value= (args[1]->null_value || salt_str->length() < 2))) 01597 return 0; 01598 salt_ptr= salt_str->c_ptr(); 01599 } 01600 pthread_mutex_lock(&LOCK_crypt); 01601 char *tmp= crypt(res->c_ptr(),salt_ptr); 01602 if (!tmp) 01603 { 01604 pthread_mutex_unlock(&LOCK_crypt); 01605 null_value= 1; 01606 return 0; 01607 } 01608 str->set(tmp,(uint) strlen(tmp),res->charset()); 01609 str->copy(); 01610 pthread_mutex_unlock(&LOCK_crypt); 01611 return str; 01612 #else 01613 null_value=1; 01614 return 0; 01615 #endif /* HAVE_CRYPT */ 01616 } 01617 01618 void Item_func_encode::fix_length_and_dec() 01619 { 01620 max_length=args[0]->max_length; 01621 maybe_null=args[0]->maybe_null; 01622 collation.set(&my_charset_bin); 01623 } 01624 01625 String *Item_func_encode::val_str(String *str) 01626 { 01627 DBUG_ASSERT(fixed == 1); 01628 String *res; 01629 if (!(res=args[0]->val_str(str))) 01630 { 01631 null_value=1; /* purecov: inspected */ 01632 return 0; /* purecov: inspected */ 01633 } 01634 null_value=0; 01635 res=copy_if_not_alloced(str,res,res->length()); 01636 sql_crypt.init(); 01637 sql_crypt.encode((char*) res->ptr(),res->length()); 01638 res->set_charset(&my_charset_bin); 01639 return res; 01640 } 01641 01642 String *Item_func_decode::val_str(String *str) 01643 { 01644 DBUG_ASSERT(fixed == 1); 01645 String *res; 01646 if (!(res=args[0]->val_str(str))) 01647 { 01648 null_value=1; /* purecov: inspected */ 01649 return 0; /* purecov: inspected */ 01650 } 01651 null_value=0; 01652 res=copy_if_not_alloced(str,res,res->length()); 01653 sql_crypt.init(); 01654 sql_crypt.decode((char*) res->ptr(),res->length()); 01655 return res; 01656 } 01657 01658 01659 Item *Item_func_sysconst::safe_charset_converter(CHARSET_INFO *tocs) 01660 { 01661 Item_string *conv; 01662 uint conv_errors; 01663 String tmp, cstr, *ostr= val_str(&tmp); 01664 cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors); 01665 if (conv_errors || 01666 !(conv= new Item_static_string_func(fully_qualified_func_name(), 01667 cstr.ptr(), cstr.length(), 01668 cstr.charset(), 01669 collation.derivation))) 01670 { 01671 return NULL; 01672 } 01673 conv->str_value.copy(); 01674 conv->str_value.mark_as_const(); 01675 return conv; 01676 } 01677 01678 01679 String *Item_func_database::val_str(String *str) 01680 { 01681 DBUG_ASSERT(fixed == 1); 01682 THD *thd= current_thd; 01683 if (thd->db == NULL) 01684 { 01685 null_value= 1; 01686 return 0; 01687 } 01688 else 01689 str->copy(thd->db, thd->db_length, system_charset_info); 01690 return str; 01691 } 01692 01693 01694 /* 01695 TODO: make USER() replicate properly (currently it is replicated to "") 01696 */ 01697 bool Item_func_user::init(const char *user, const char *host) 01698 { 01699 DBUG_ASSERT(fixed == 1); 01700 01701 // For system threads (e.g. replication SQL thread) user may be empty 01702 if (user) 01703 { 01704 CHARSET_INFO *cs= str_value.charset(); 01705 uint res_length= (strlen(user)+strlen(host)+2) * cs->mbmaxlen; 01706 01707 if (str_value.alloc(res_length)) 01708 { 01709 null_value=1; 01710 return TRUE; 01711 } 01712 01713 res_length=cs->cset->snprintf(cs, (char*)str_value.ptr(), res_length, 01714 "%s@%s", user, host); 01715 str_value.length(res_length); 01716 str_value.mark_as_const(); 01717 } 01718 return FALSE; 01719 } 01720 01721 01722 bool Item_func_user::fix_fields(THD *thd, Item **ref) 01723 { 01724 return (Item_func_sysconst::fix_fields(thd, ref) || 01725 init(thd->main_security_ctx.user, 01726 thd->main_security_ctx.host_or_ip)); 01727 } 01728 01729 01730 bool Item_func_current_user::fix_fields(THD *thd, Item **ref) 01731 { 01732 if (Item_func_sysconst::fix_fields(thd, ref)) 01733 return TRUE; 01734 01735 Security_context *ctx= (context->security_ctx 01736 ? context->security_ctx : thd->security_ctx); 01737 return init(ctx->priv_user, ctx->priv_host); 01738 } 01739 01740 01741 void Item_func_soundex::fix_length_and_dec() 01742 { 01743 collation.set(args[0]->collation); 01744 max_length=args[0]->max_length; 01745 set_if_bigger(max_length,4); 01746 } 01747 01748 01749 /* 01750 If alpha, map input letter to soundex code. 01751 If not alpha and remove_garbage is set then skip to next char 01752 else return 0 01753 */ 01754 01755 static char soundex_toupper(char ch) 01756 { 01757 return (ch >= 'a' && ch <= 'z') ? ch - 'a' + 'A' : ch; 01758 } 01759 01760 static char get_scode(char *ptr) 01761 { 01762 uchar ch= soundex_toupper(*ptr); 01763 if (ch < 'A' || ch > 'Z') 01764 { 01765 // Thread extended alfa (country spec) 01766 return '0'; // as vokal 01767 } 01768 return(soundex_map[ch-'A']); 01769 } 01770 01771 01772 String *Item_func_soundex::val_str(String *str) 01773 { 01774 DBUG_ASSERT(fixed == 1); 01775 String *res =args[0]->val_str(str); 01776 char last_ch,ch; 01777 CHARSET_INFO *cs= collation.collation; 01778 01779 if ((null_value=args[0]->null_value)) 01780 return 0; /* purecov: inspected */ 01781 01782 if (tmp_value.alloc(max(res->length(),4))) 01783 return str; /* purecov: inspected */ 01784 char *to= (char *) tmp_value.ptr(); 01785 char *from= (char *) res->ptr(), *end=from+res->length(); 01786 tmp_value.set_charset(cs); 01787 01788 while (from != end && !my_isalpha(cs,*from)) // Skip pre-space 01789 from++; /* purecov: inspected */ 01790 if (from == end) 01791 return &my_empty_string; // No alpha characters. 01792 *to++ = soundex_toupper(*from); // Copy first letter 01793 last_ch = get_scode(from); // code of the first letter 01794 // for the first 'double-letter check. 01795 // Loop on input letters until 01796 // end of input (null) or output 01797 // letter code count = 3 01798 for (from++ ; from < end ; from++) 01799 { 01800 if (!my_isalpha(cs,*from)) 01801 continue; 01802 ch=get_scode(from); 01803 if ((ch != '0') && (ch != last_ch)) // if not skipped or double 01804 { 01805 *to++ = ch; // letter, copy to output 01806 last_ch = ch; // save code of last input letter 01807 } // for next double-letter check 01808 } 01809 for (end=(char*) tmp_value.ptr()+4 ; to < end ; to++) 01810 *to = '0'; 01811 *to=0; // end string 01812 tmp_value.length((uint) (to-tmp_value.ptr())); 01813 return &tmp_value; 01814 } 01815 01816 01817 /* 01818 ** Change a number to format '3,333,333,333.000' 01819 ** This should be 'internationalized' sometimes. 01820 */ 01821 01822 Item_func_format::Item_func_format(Item *org,int dec) :Item_str_func(org) 01823 { 01824 decimals=(uint) set_zone(dec,0,30); 01825 } 01826 01827 01828 /* 01829 TODO: This needs to be fixed for multi-byte character set where numbers 01830 are stored in more than one byte 01831 */ 01832 01833 String *Item_func_format::val_str(String *str) 01834 { 01835 uint32 length, str_length ,dec; 01836 int diff; 01837 DBUG_ASSERT(fixed == 1); 01838 dec= decimals ? decimals+1 : 0; 01839 01840 if (args[0]->result_type() == DECIMAL_RESULT || 01841 args[0]->result_type() == INT_RESULT) 01842 { 01843 my_decimal dec_val, rnd_dec, *res; 01844 res= args[0]->val_decimal(&dec_val); 01845 if ((null_value=args[0]->null_value)) 01846 return 0; /* purecov: inspected */ 01847 my_decimal_round(E_DEC_FATAL_ERROR, res, decimals, false, &rnd_dec); 01848 my_decimal2string(E_DEC_FATAL_ERROR, &rnd_dec, 0, 0, 0, str); 01849 str_length= str->length(); 01850 if (rnd_dec.sign()) 01851 str_length--; 01852 } 01853 else 01854 { 01855 double nr= args[0]->val_real(); 01856 if ((null_value=args[0]->null_value)) 01857 return 0; /* purecov: inspected */ 01858 nr= my_double_round(nr, decimals, FALSE); 01859 /* Here default_charset() is right as this is not an automatic conversion */ 01860 str->set_real(nr,decimals, default_charset()); 01861 if (isnan(nr)) 01862 return str; 01863 str_length=str->length(); 01864 if (nr < 0) 01865 str_length--; // Don't count sign 01866 } 01867 /* We need this test to handle 'nan' values */ 01868 if (str_length >= dec+4) 01869 { 01870 char *tmp,*pos; 01871 length= str->length()+(diff=((int)(str_length- dec-1))/3); 01872 str= copy_if_not_alloced(&tmp_str,str,length); 01873 str->length(length); 01874 tmp= (char*) str->ptr()+length - dec-1; 01875 for (pos= (char*) str->ptr()+length-1; pos != tmp; pos--) 01876 pos[0]= pos[-diff]; 01877 while (diff) 01878 { 01879 *pos= *(pos - diff); 01880 pos--; 01881 *pos= *(pos - diff); 01882 pos--; 01883 *pos= *(pos - diff); 01884 pos--; 01885 pos[0]=','; 01886 pos--; 01887 diff--; 01888 } 01889 } 01890 return str; 01891 } 01892 01893 01894 void Item_func_format::print(String *str) 01895 { 01896 str->append(STRING_WITH_LEN("format(")); 01897 args[0]->print(str); 01898 str->append(','); 01899 // my_charset_bin is good enough for numbers 01900 char buffer[20]; 01901 String st(buffer, sizeof(buffer), &my_charset_bin); 01902 st.set((ulonglong)decimals, &my_charset_bin); 01903 str->append(st); 01904 str->append(')'); 01905 } 01906 01907 void Item_func_elt::fix_length_and_dec() 01908 { 01909 max_length=0; 01910 decimals=0; 01911 01912 if (agg_arg_charsets(collation, args+1, arg_count-1, MY_COLL_ALLOW_CONV, 1)) 01913 return; 01914 01915 for (uint i= 1 ; i < arg_count ; i++) 01916 { 01917 set_if_bigger(max_length,args[i]->max_length); 01918 set_if_bigger(decimals,args[i]->decimals); 01919 } 01920 maybe_null=1; // NULL if wrong first arg 01921 } 01922 01923 01924 double Item_func_elt::val_real() 01925 { 01926 DBUG_ASSERT(fixed == 1); 01927 uint tmp; 01928 null_value=1; 01929 if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count) 01930 return 0.0; 01931 double result= args[tmp]->val_real(); 01932 null_value= args[tmp]->null_value; 01933 return result; 01934 } 01935 01936 01937 longlong Item_func_elt::val_int() 01938 { 01939 DBUG_ASSERT(fixed == 1); 01940 uint tmp; 01941 null_value=1; 01942 if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count) 01943 return 0; 01944 01945 longlong result= args[tmp]->val_int(); 01946 null_value= args[tmp]->null_value; 01947 return result; 01948 } 01949 01950 01951 String *Item_func_elt::val_str(String *str) 01952 { 01953 DBUG_ASSERT(fixed == 1); 01954 uint tmp; 01955 null_value=1; 01956 if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count) 01957 return NULL; 01958 01959 String *result= args[tmp]->val_str(str); 01960 if (result) 01961 result->set_charset(collation.collation); 01962 null_value= args[tmp]->null_value; 01963 return result; 01964 } 01965 01966 01967 void Item_func_make_set::split_sum_func(THD *thd, Item **ref_pointer_array, 01968 List<Item> &fields) 01969 { 01970 item->split_sum_func2(thd, ref_pointer_array, fields, &item, TRUE); 01971 Item_str_func::split_sum_func(thd, ref_pointer_array, fields); 01972 } 01973 01974 01975 void Item_func_make_set::fix_length_and_dec() 01976 { 01977 max_length=arg_count-1; 01978 01979 if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1)) 01980 return; 01981 01982 for (uint i=0 ; i < arg_count ; i++) 01983 max_length+=args[i]->max_length; 01984 01985 used_tables_cache|= item->used_tables(); 01986 not_null_tables_cache&= item->not_null_tables(); 01987 const_item_cache&= item->const_item(); 01988 with_sum_func= with_sum_func || item->with_sum_func; 01989 } 01990 01991 01992 void Item_func_make_set::update_used_tables() 01993 { 01994 Item_func::update_used_tables(); 01995 item->update_used_tables(); 01996 used_tables_cache|=item->used_tables(); 01997 const_item_cache&=item->const_item(); 01998 } 01999 02000 02001 String *Item_func_make_set::val_str(String *str) 02002 { 02003 DBUG_ASSERT(fixed == 1); 02004 ulonglong bits; 02005 bool first_found=0; 02006 Item **ptr=args; 02007 String *result=&my_empty_string; 02008 02009 bits=item->val_int(); 02010 if ((null_value=item->null_value)) 02011 return NULL; 02012 02013 if (arg_count < 64) 02014 bits &= ((ulonglong) 1 << arg_count)-1; 02015 02016 for (; bits; bits >>= 1, ptr++) 02017 { 02018 if (bits & 1) 02019 { 02020 String *res= (*ptr)->val_str(str); 02021 if (res) // Skip nulls 02022 { 02023 if (!first_found) 02024 { // First argument 02025 first_found=1; 02026 if (res != str) 02027 result=res; // Use original string 02028 else 02029 { 02030 if (tmp_str.copy(*res)) // Don't use 'str' 02031 return &my_empty_string; 02032 result= &tmp_str; 02033 } 02034 } 02035 else 02036 { 02037 if (result != &tmp_str) 02038 { // Copy data to tmp_str 02039 if (tmp_str.alloc(result->length()+res->length()+1) || 02040 tmp_str.copy(*result)) 02041 return &my_empty_string; 02042 result= &tmp_str; 02043 } 02044 if (tmp_str.append(',') || tmp_str.append(*res)) 02045 return &my_empty_string; 02046 } 02047 } 02048 } 02049 } 02050 return result; 02051 } 02052 02053 02054 void Item_func_make_set::print(String *str) 02055 { 02056 str->append(STRING_WITH_LEN("make_set(")); 02057 item->print(str); 02058 if (arg_count) 02059 { 02060 str->append(','); 02061 print_args(str, 0); 02062 } 02063 str->append(')'); 02064 } 02065 02066 02067 String *Item_func_char::val_str(String *str) 02068 { 02069 DBUG_ASSERT(fixed == 1); 02070 str->length(0); 02071 for (uint i=0 ; i < arg_count ; i++) 02072 { 02073 int32 num=(int32) args[i]->val_int(); 02074 if (!args[i]->null_value) 02075 { 02076 if (num&0xFF000000L) { 02077 str->append((char)(num>>24)); 02078 goto b2; 02079 } else if (num&0xFF0000L) { 02080 b2: str->append((char)(num>>16)); 02081 goto b1; 02082 } else if (num&0xFF00L) { 02083 b1: str->append((char)(num>>8)); 02084 } 02085 str->append((char) num); 02086 } 02087 } 02088 str->set_charset(collation.collation); 02089 str->realloc(str->length()); // Add end 0 (for Purify) 02090 return check_well_formed_result(str); 02091 } 02092 02093 02094 inline String* alloc_buffer(String *res,String *str,String *tmp_value, 02095 ulong length) 02096 { 02097 if (res->alloced_length() < length) 02098 { 02099 if (str->alloced_length() >= length) 02100 { 02101 (void) str->copy(*res); 02102 str->length(length); 02103 return str; 02104 } 02105 if (tmp_value->alloc(length)) 02106 return 0; 02107 (void) tmp_value->copy(*res); 02108 tmp_value->length(length); 02109 return tmp_value; 02110 } 02111 res->length(length); 02112 return res; 02113 } 02114 02115 02116 void Item_func_repeat::fix_length_and_dec() 02117 { 02118 collation.set(args[0]->collation); 02119 if (args[1]->const_item()) 02120 { 02121 ulonglong max_result_length= ((ulonglong) args[0]->max_length * 02122 args[1]->val_int()); 02123 if (max_result_length >= MAX_BLOB_WIDTH) 02124 { 02125 max_result_length= MAX_BLOB_WIDTH; 02126 maybe_null= 1; 02127 } 02128 max_length= (ulong) max_result_length; 02129 } 02130 else 02131 { 02132 max_length= MAX_BLOB_WIDTH; 02133 maybe_null= 1; 02134 } 02135 } 02136 02137 /* 02138 ** Item_func_repeat::str is carefully written to avoid reallocs 02139 ** as much as possible at the cost of a local buffer 02140 */ 02141 02142 String *Item_func_repeat::val_str(String *str) 02143 { 02144 DBUG_ASSERT(fixed == 1); 02145 uint length,tot_length; 02146 char *to; 02147 long count= (long) args[1]->val_int(); 02148 String *res =args[0]->val_str(str); 02149 02150 if (args[0]->null_value || args[1]->null_value) 02151 goto err; // string and/or delim are null 02152 null_value=0; 02153 if (count <= 0) // For nicer SQL code 02154 return &my_empty_string; 02155 if (count == 1) // To avoid reallocs 02156 return res; 02157 length=res->length(); 02158 // Safe length check 02159 if (length > current_thd->variables.max_allowed_packet/count) 02160 { 02161 push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, 02162 ER_WARN_ALLOWED_PACKET_OVERFLOWED, 02163 ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), 02164 func_name(), current_thd->variables.max_allowed_packet); 02165 goto err; 02166 } 02167 tot_length= length*(uint) count; 02168 if (!(res= alloc_buffer(res,str,&tmp_value,tot_length))) 02169 goto err; 02170 02171 to=(char*) res->ptr()+length; 02172 while (--count) 02173 { 02174 memcpy(to,res->ptr(),length); 02175 to+=length; 02176 } 02177 return (res); 02178 02179 err: 02180 null_value=1; 02181 return 0; 02182 } 02183 02184 02185 void Item_func_rpad::fix_length_and_dec() 02186 { 02187 // Handle character set for args[0] and args[2]. 02188 if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 2)) 02189 return; 02190 if (args[1]->const_item()) 02191 { 02192 ulonglong length= ((ulonglong) args[1]->val_int() * 02193 collation.collation->mbmaxlen); 02194 if (length >= MAX_BLOB_WIDTH) 02195 { 02196 length= MAX_BLOB_WIDTH; 02197 maybe_null= 1; 02198 } 02199 max_length= (ulong) length; 02200 } 02201 else 02202 { 02203 max_length= MAX_BLOB_WIDTH; 02204 maybe_null= 1; 02205 } 02206 } 02207 02208 02209 String *Item_func_rpad::val_str(String *str) 02210 { 02211 DBUG_ASSERT(fixed == 1); 02212 uint32 res_byte_length,res_char_length,pad_char_length,pad_byte_length; 02213 char *to; 02214 const char *ptr_pad; 02215 int32 count= (int32) args[1]->val_int(); 02216 int32 byte_count= count * collation.collation->mbmaxlen; 02217 String *res =args[0]->val_str(str); 02218 String *rpad = args[2]->val_str(&rpad_str); 02219 02220 if (!res || args[1]->null_value || !rpad || count < 0) 02221 goto err; 02222 null_value=0; 02223 if (count <= (int32) (res_char_length=res->numchars())) 02224 { // String to pad is big enough 02225 res->length(res->charpos(count)); // Shorten result if longer 02226 return (res); 02227 } 02228 pad_char_length= rpad->numchars(); 02229 if ((ulong) byte_count > current_thd->variables.max_allowed_packet) 02230 { 02231 push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, 02232 ER_WARN_ALLOWED_PACKET_OVERFLOWED, 02233 ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), 02234 func_name(), current_thd->variables.max_allowed_packet); 02235 goto err; 02236 } 02237 if (args[2]->null_value || !pad_char_length) 02238 goto err; 02239 res_byte_length= res->length(); /* Must be done before alloc_buffer */ 02240 if (!(res= alloc_buffer(res,str,&tmp_value,byte_count))) 02241 goto err; 02242 02243 to= (char*) res->ptr()+res_byte_length; 02244 ptr_pad=rpad->ptr(); 02245 pad_byte_length= rpad->length(); 02246 count-= res_char_length; 02247 for ( ; (uint32) count > pad_char_length; count-= pad_char_length) 02248 { 02249 memcpy(to,ptr_pad,pad_byte_length); 02250 to+= pad_byte_length; 02251 } 02252 if (count) 02253 { 02254 pad_byte_length= rpad->charpos(count); 02255 memcpy(to,ptr_pad,(size_t) pad_byte_length); 02256 to+= pad_byte_length; 02257 } 02258 res->length(to- (char*) res->ptr()); 02259 return (res); 02260 02261 err: 02262 null_value=1; 02263 return 0; 02264 } 02265 02266 02267 void Item_func_lpad::fix_length_and_dec() 02268 { 02269 // Handle character set for args[0] and args[2]. 02270 if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 2)) 02271 return; 02272 02273 if (args[1]->const_item()) 02274 { 02275 ulonglong length= ((ulonglong) args[1]->val_int() * 02276 collation.collation->mbmaxlen); 02277 if (length >= MAX_BLOB_WIDTH) 02278 { 02279 length= MAX_BLOB_WIDTH; 02280 maybe_null= 1; 02281 } 02282 max_length= (ulong) length; 02283 } 02284 else 02285 { 02286 max_length= MAX_BLOB_WIDTH; 02287 maybe_null= 1; 02288 } 02289 } 02290 02291 02292 String *Item_func_lpad::val_str(String *str) 02293 { 02294 DBUG_ASSERT(fixed == 1); 02295 uint32 res_char_length,pad_char_length; 02296 ulong count= (long) args[1]->val_int(), byte_count; 02297 String *res= args[0]->val_str(&tmp_value); 02298 String *pad= args[2]->val_str(&lpad_str); 02299 02300 if (!res || args[1]->null_value || !pad) 02301 goto err; 02302 02303 null_value=0; 02304 res_char_length= res->numchars(); 02305 02306 if (count <= res_char_length) 02307 { 02308 res->length(res->charpos(count)); 02309 return res; 02310 } 02311 02312 pad_char_length= pad->numchars(); 02313 byte_count= count * collation.collation->mbmaxlen; 02314 02315 if (byte_count > current_thd->variables.max_allowed_packet) 02316 { 02317 push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, 02318 ER_WARN_ALLOWED_PACKET_OVERFLOWED, 02319 ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), 02320 func_name(), current_thd->variables.max_allowed_packet); 02321 goto err; 02322 } 02323 02324 if (args[2]->null_value || !pad_char_length || str->alloc(byte_count)) 02325 goto err; 02326 02327 str->length(0); 02328 str->set_charset(collation.collation); 02329 count-= res_char_length; 02330 while (count >= pad_char_length) 02331 { 02332 str->append(*pad); 02333 count-= pad_char_length; 02334 } 02335 if (count > 0) 02336 str->append(pad->ptr(), pad->charpos(count), collation.collation); 02337 02338 str->append(*res); 02339 null_value= 0; 02340 return str; 02341 02342 err: 02343 null_value= 1; 02344 return 0; 02345 } 02346 02347 02348 String *Item_func_conv::val_str(String *str) 02349 { 02350 DBUG_ASSERT(fixed == 1); 02351 String *res= args[0]->val_str(str); 02352 char *endptr,ans[65],*ptr; 02353 longlong dec; 02354 int from_base= (int) args[1]->val_int(); 02355 int to_base= (int) args[2]->val_int(); 02356 int err; 02357 02358 if (args[0]->null_value || args[1]->null_value || args[2]->null_value || 02359 abs(to_base) > 36 || abs(to_base) < 2 || 02360 abs(from_base) > 36 || abs(from_base) < 2 || !(res->length())) 02361 { 02362 null_value=1; 02363 return 0; 02364 } 02365 null_value=0; 02366 unsigned_flag= !(from_base < 0); 02367 if (from_base < 0) 02368 dec= my_strntoll(res->charset(),res->ptr(),res->length(),-from_base,&endptr,&err); 02369 else 02370 dec= (longlong) my_strntoull(res->charset(),res->ptr(),res->length(),from_base,&endptr,&err); 02371 ptr= longlong2str(dec,ans,to_base); 02372 if (str->copy(ans,(uint32) (ptr-ans), default_charset())) 02373 return &my_empty_string; 02374 return str; 02375 } 02376 02377 02378 String *Item_func_conv_charset::val_str(String *str) 02379 { 02380 DBUG_ASSERT(fixed == 1); 02381 if (use_cached_value) 02382 return null_value ? 0 : &str_value; 02383 String *arg= args[0]->val_str(str); 02384 uint dummy_errors; 02385 if (!arg) 02386 { 02387 null_value=1; 02388 return 0; 02389 } 02390 null_value= str_value.copy(arg->ptr(),arg->length(),arg->charset(), 02391 conv_charset, &dummy_errors); 02392 return null_value ? 0 : check_well_formed_result(&str_value); 02393 } 02394 02395 void Item_func_conv_charset::fix_length_and_dec() 02396 { 02397 collation.set(conv_charset, DERIVATION_IMPLICIT); 02398 max_length = args[0]->max_length*conv_charset->mbmaxlen; 02399 } 02400 02401 void Item_func_conv_charset::print(String *str) 02402 { 02403 str->append(STRING_WITH_LEN("convert(")); 02404 args[0]->print(str); 02405 str->append(STRING_WITH_LEN(" using ")); 02406 str->append(conv_charset->csname); 02407 str->append(')'); 02408 } 02409 02410 String *Item_func_set_collation::val_str(String *str) 02411 { 02412 DBUG_ASSERT(fixed == 1); 02413 str=args[0]->val_str(str); 02414 if ((null_value=args[0]->null_value)) 02415 return 0; 02416 str->set_charset(collation.collation); 02417 return str; 02418 } 02419 02420 void Item_func_set_collation::fix_length_and_dec() 02421 { 02422 CHARSET_INFO *set_collation; 02423 const char *colname; 02424 String tmp, *str= args[1]->val_str(&tmp); 02425 colname= str->c_ptr(); 02426 if (colname == binary_keyword) 02427 set_collation= get_charset_by_csname(args[0]->collation.collation->csname, 02428 MY_CS_BINSORT,MYF(0)); 02429 else 02430 { 02431 if (!(set_collation= get_charset_by_name(colname,MYF(0)))) 02432 { 02433 my_error(ER_UNKNOWN_COLLATION, MYF(0), colname); 02434 return; 02435 } 02436 } 02437 02438 if (!set_collation || 02439 !my_charset_same(args[0]->collation.collation,set_collation)) 02440 { 02441 my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), 02442 colname, args[0]->collation.collation->csname); 02443 return; 02444 } 02445 collation.set(set_collation, DERIVATION_EXPLICIT); 02446 max_length= args[0]->max_length; 02447 } 02448 02449 02450 bool Item_func_set_collation::eq(const Item *item, bool binary_cmp) const 02451 { 02452 /* Assume we don't have rtti */ 02453 if (this == item) 02454 return 1; 02455 if (item->type() != FUNC_ITEM) 02456 return 0; 02457 Item_func *item_func=(Item_func*) item; 02458 if (arg_count != item_func->arg_count || 02459 functype() != item_func->functype()) 02460 return 0; 02461 Item_func_set_collation *item_func_sc=(Item_func_set_collation*) item; 02462 if (collation.collation != item_func_sc->collation.collation) 02463 return 0; 02464 for (uint i=0; i < arg_count ; i++) 02465 if (!args[i]->eq(item_func_sc->args[i], binary_cmp)) 02466 return 0; 02467 return 1; 02468 } 02469 02470 02471 void Item_func_set_collation::print(String *str) 02472 { 02473 str->append('('); 02474 args[0]->print(str); 02475 str->append(STRING_WITH_LEN(" collate ")); 02476 DBUG_ASSERT(args[1]->basic_const_item() && 02477 args[1]->type() == Item::STRING_ITEM); 02478 args[1]->str_value.print(str); 02479 str->append(')'); 02480 } 02481 02482 String *Item_func_charset::val_str(String *str) 02483 { 02484 DBUG_ASSERT(fixed == 1); 02485 uint dummy_errors; 02486 02487 CHARSET_INFO *cs= args[0]->collation.collation; 02488 null_value= 0; 02489 str->copy(cs->csname, strlen(cs->csname), 02490 &my_charset_latin1, collation.collation, &dummy_errors); 02491 return str; 02492 } 02493 02494 String *Item_func_collation::val_str(String *str) 02495 { 02496 DBUG_ASSERT(fixed == 1); 02497 uint dummy_errors; 02498 CHARSET_INFO *cs= args[0]->collation.collation; 02499 02500 null_value= 0; 02501 str->copy(cs->name, strlen(cs->name), 02502 &my_charset_latin1, collation.collation, &dummy_errors); 02503 return str; 02504 } 02505 02506 02507 String *Item_func_hex::val_str(String *str) 02508 { 02509 String *res; 02510 DBUG_ASSERT(fixed == 1); 02511 if (args[0]->result_type() != STRING_RESULT) 02512 { 02513 ulonglong dec; 02514 char ans[65],*ptr; 02515 /* Return hex of unsigned longlong value */ 02516 if (args[0]->result_type() == REAL_RESULT || 02517 args[0]->result_type() == DECIMAL_RESULT) 02518 { 02519 double val= args[0]->val_real(); 02520 if ((val <= (double) LONGLONG_MIN) || 02521 (val >= (double) (ulonglong) ULONGLONG_MAX)) 02522 dec= ~(longlong) 0; 02523 else 02524 dec= (ulonglong) (val + (val > 0 ? 0.5 : -0.5)); 02525 } 02526 else 02527 dec= (ulonglong) args[0]->val_int(); 02528 02529 if ((null_value= args[0]->null_value)) 02530 return 0; 02531 ptr= longlong2str(dec,ans,16); 02532 if (str->copy(ans,(uint32) (ptr-ans),default_charset())) 02533 return &my_empty_string; // End of memory 02534 return str; 02535 } 02536 02537 /* Convert given string to a hex string, character by character */ 02538 res= args[0]->val_str(str); 02539 if (!res || tmp_value.alloc(res->length()*2+1)) 02540 { 02541 null_value=1; 02542 return 0; 02543 } 02544 null_value=0; 02545 tmp_value.length(res->length()*2); 02546 02547 octet2hex((char*) tmp_value.ptr(), res->ptr(), res->length()); 02548 return &tmp_value; 02549 } 02550 02551 /* Convert given hex string to a binary string */ 02552 02553 String *Item_func_unhex::val_str(String *str) 02554 { 02555 const char *from, *end; 02556 char *to; 02557 String *res; 02558 uint length; 02559 DBUG_ASSERT(fixed == 1); 02560 02561 res= args[0]->val_str(str); 02562 if (!res || tmp_value.alloc(length= (1+res->length())/2)) 02563 { 02564 null_value=1; 02565 return 0; 02566 } 02567 02568 from= res->ptr(); 02569 null_value= 0; 02570 tmp_value.length(length); 02571 to= (char*) tmp_value.ptr(); 02572 if (res->length() % 2) 02573 { 02574 int hex_char; 02575 *to++= hex_char= hexchar_to_int(*from++); 02576 if ((null_value= (hex_char == -1))) 02577 return 0; 02578 } 02579 for (end=res->ptr()+res->length(); from < end ; from+=2, to++) 02580 { 02581 int hex_char; 02582 *to= (hex_char= hexchar_to_int(from[0])) << 4; 02583 if ((null_value= (hex_char == -1))) 02584 return 0; 02585 *to|= hex_char= hexchar_to_int(from[1]); 02586 if ((null_value= (hex_char == -1))) 02587 return 0; 02588 } 02589 return &tmp_value; 02590 } 02591 02592 02593 void Item_func_binary::print(String *str) 02594 { 02595 str->append(STRING_WITH_LEN("cast(")); 02596 args[0]->print(str); 02597 str->append(STRING_WITH_LEN(" as binary)")); 02598 } 02599 02600 02601 #include <my_dir.h> // For my_stat 02602 02603 String *Item_load_file::val_str(String *str) 02604 { 02605 DBUG_ASSERT(fixed == 1); 02606 String *file_name; 02607 File file; 02608 MY_STAT stat_info; 02609 char path[FN_REFLEN]; 02610 DBUG_ENTER("load_file"); 02611 02612 if (!(file_name= args[0]->val_str(str)) 02613 #ifndef NO_EMBEDDED_ACCESS_CHECKS 02614 || !(current_thd->security_ctx->master_access & FILE_ACL) 02615 #endif 02616 ) 02617 goto err; 02618 02619 (void) fn_format(path, file_name->c_ptr(), mysql_real_data_home, "", 02620 MY_RELATIVE_PATH | MY_UNPACK_FILENAME); 02621 02622 if (!my_stat(path, &stat_info, MYF(0))) 02623 goto err; 02624 02625 if (!(stat_info.st_mode & S_IROTH)) 02626 { 02627 /* my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), file_name->c_ptr()); */ 02628 goto err; 02629 } 02630 if (stat_info.st_size > (long) current_thd->variables.max_allowed_packet) 02631 { 02632 push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, 02633 ER_WARN_ALLOWED_PACKET_OVERFLOWED, 02634 ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), 02635 func_name(), current_thd->variables.max_allowed_packet); 02636 goto err; 02637 } 02638 if (tmp_value.alloc(stat_info.st_size)) 02639 goto err; 02640 if ((file = my_open(file_name->c_ptr(), O_RDONLY, MYF(0))) < 0) 02641 goto err; 02642 if (my_read(file, (byte*) tmp_value.ptr(), stat_info.st_size, MYF(MY_NABP))) 02643 { 02644 my_close(file, MYF(0)); 02645 goto err; 02646 } 02647 tmp_value.length(stat_info.st_size); 02648 my_close(file, MYF(0)); 02649 null_value = 0; 02650 DBUG_RETURN(&tmp_value); 02651 02652 err: 02653 null_value = 1; 02654 DBUG_RETURN(0); 02655 } 02656 02657 02658 String* Item_func_export_set::val_str(String* str) 02659 { 02660 DBUG_ASSERT(fixed == 1); 02661 ulonglong the_set = (ulonglong) args[0]->val_int(); 02662 String yes_buf, *yes; 02663 yes = args[1]->val_str(&yes_buf); 02664 String no_buf, *no; 02665 no = args[2]->val_str(&no_buf); 02666 String *sep = NULL, sep_buf ; 02667 02668 uint num_set_values = 64; 02669 ulonglong mask = 0x1; 02670 str->length(0); 02671 str->set_charset(collation.collation); 02672 02673 /* Check if some argument is a NULL value */ 02674 if (args[0]->null_value || args[1]->null_value || args[2]->null_value) 02675 { 02676 null_value=1; 02677 return 0; 02678 } 02679 /* 02680 Arg count can only be 3, 4 or 5 here. This is guaranteed from the 02681 grammar for EXPORT_SET() 02682 */ 02683 switch(arg_count) { 02684 case 5: 02685 num_set_values = (uint) args[4]->val_int(); 02686 if (num_set_values > 64) 02687 num_set_values=64; 02688 if (args[4]->null_value) 02689 { 02690 null_value=1; 02691 return 0; 02692 } 02693 /* Fall through */ 02694 case 4: 02695 if (!(sep = args[3]->val_str(&sep_buf))) // Only true if NULL 02696 { 02697 null_value=1; 02698 return 0; 02699 } 02700 break; 02701 case 3: 02702 sep_buf.set(STRING_WITH_LEN(","), default_charset()); 02703 sep = &sep_buf; 02704 break; 02705 default: 02706 DBUG_ASSERT(0); // cannot happen 02707 } 02708 null_value=0; 02709 02710 for (uint i = 0; i < num_set_values; i++, mask = (mask << 1)) 02711 { 02712 if (the_set & mask) 02713 str->append(*yes); 02714 else 02715 str->append(*no); 02716 if (i != num_set_values - 1) 02717 str->append(*sep); 02718 } 02719 return str; 02720 } 02721 02722 void Item_func_export_set::fix_length_and_dec() 02723 { 02724 uint length=max(args[1]->max_length,args[2]->max_length); 02725 uint sep_length=(arg_count > 3 ? args[3]->max_length : 1); 02726 max_length=length*64+sep_length*63; 02727 02728 if (agg_arg_charsets(collation, args+1, min(4,arg_count)-1, 02729 MY_COLL_ALLOW_CONV, 1)) 02730 return; 02731 } 02732 02733 String* Item_func_inet_ntoa::val_str(String* str) 02734 { 02735 DBUG_ASSERT(fixed == 1); 02736 uchar buf[8], *p; 02737 ulonglong n = (ulonglong) args[0]->val_int(); 02738 char num[4]; 02739 02740 /* 02741 We do not know if args[0] is NULL until we have called 02742 some val function on it if args[0] is not a constant! 02743 02744 Also return null if n > 255.255.255.255 02745 */ 02746 if ((null_value= (args[0]->null_value || n > (ulonglong) LL(4294967295)))) 02747 return 0; // Null value 02748 02749 str->length(0); 02750 int4store(buf,n); 02751 02752 /* Now we can assume little endian. */ 02753 02754 num[3]='.'; 02755 for (p=buf+4 ; p-- > buf ; ) 02756 { 02757 uint c = *p; 02758 uint n1,n2; // Try to avoid divisions 02759 n1= c / 100; // 100 digits 02760 c-= n1*100; 02761 n2= c / 10; // 10 digits 02762 c-=n2*10; // last digit 02763 num[0]=(char) n1+'0'; 02764 num[1]=(char) n2+'0'; 02765 num[2]=(char) c+'0'; 02766 uint length=(n1 ? 4 : n2 ? 3 : 2); // Remove pre-zero 02767 02768 (void) str->append(num+4-length,length); 02769 } 02770 str->length(str->length()-1); // Remove last '.'; 02771 return str; 02772 } 02773 02774 02775 /* 02776 QUOTE() function returns argument string in single quotes suitable for 02777 using in a SQL statement. 02778 02779 DESCRIPTION 02780 Adds a \ before all characters that needs to be escaped in a SQL string. 02781 We also escape '^Z' (END-OF-FILE in windows) to avoid probelms when 02782 running commands from a file in windows. 02783 02784 This function is very useful when you want to generate SQL statements 02785 02786 NOTE 02787 QUOTE(NULL) returns the string 'NULL' (4 letters, without quotes). 02788 02789 RETURN VALUES 02790 str Quoted string 02791 NULL Out of memory. 02792 */ 02793 02794 #define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7)) 02795 02796 String *Item_func_quote::val_str(String *str) 02797 { 02798 DBUG_ASSERT(fixed == 1); 02799 /* 02800 Bit mask that has 1 for set for the position of the following characters: 02801 0, \, ' and ^Z 02802 */ 02803 02804 static uchar escmask[32]= 02805 { 02806 0x01, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 02807 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 02808 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 02809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 02810 }; 02811 02812 char *from, *to, *end, *start; 02813 String *arg= args[0]->val_str(str); 02814 uint arg_length, new_length; 02815 if (!arg) // Null argument 02816 { 02817 /* Return the string 'NULL' */ 02818 str->copy(STRING_WITH_LEN("NULL"), collation.collation); 02819 null_value= 0; 02820 return str; 02821 } 02822 02823 arg_length= arg->length(); 02824 new_length= arg_length+2; /* for beginning and ending ' signs */ 02825 02826 for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++) 02827 new_length+= get_esc_bit(escmask, (uchar) *from); 02828 02829 if (tmp_value.alloc(new_length)) 02830 goto null; 02831 02832 /* 02833 We replace characters from the end to the beginning 02834 */ 02835 to= (char*) tmp_value.ptr() + new_length - 1; 02836 *to--= '\''; 02837 for (start= (char*) arg->ptr(),end= start + arg_length; end-- != start; to--) 02838 { 02839 /* 02840 We can't use the bitmask here as we want to replace \O and ^Z with 0 02841 and Z 02842 */ 02843 switch (*end) { 02844 case 0: 02845 *to--= '0'; 02846 *to= '\\'; 02847 break; 02848 case '\032': 02849 *to--= 'Z'; 02850 *to= '\\'; 02851 break; 02852 case '\'': 02853 case '\\': 02854 *to--= *end; 02855 *to= '\\'; 02856 break; 02857 default: 02858 *to= *end; 02859 break; 02860 } 02861 } 02862 *to= '\''; 02863 tmp_value.length(new_length); 02864 tmp_value.set_charset(collation.collation); 02865 null_value= 0; 02866 return &tmp_value; 02867 02868 null: 02869 null_value= 1; 02870 return 0; 02871 } 02872 02873 longlong Item_func_uncompressed_length::val_int() 02874 { 02875 DBUG_ASSERT(fixed == 1); 02876 String *res= args[0]->val_str(&value); 02877 if (!res) 02878 { 02879 null_value=1; 02880 return 0; /* purecov: inspected */ 02881 } 02882 null_value=0; 02883 if (res->is_empty()) return 0; 02884 02885 /* 02886 res->ptr() using is safe because we have tested that string is not empty, 02887 res->c_ptr() is not used because: 02888 - we do not need \0 terminated string to get first 4 bytes 02889 - c_ptr() tests simbol after string end (uninitialiozed memory) which 02890 confuse valgrind 02891 */ 02892 return uint4korr(res->ptr()) & 0x3FFFFFFF; 02893 } 02894 02895 longlong Item_func_crc32::val_int() 02896 { 02897 DBUG_ASSERT(fixed == 1); 02898 String *res=args[0]->val_str(&value); 02899 if (!res) 02900 { 02901 null_value=1; 02902 return 0; /* purecov: inspected */ 02903 } 02904 null_value=0; 02905 return (longlong) crc32(0L, (uchar*)res->ptr(), res->length()); 02906 } 02907 02908 #ifdef HAVE_COMPRESS 02909 #include "zlib.h" 02910 02911 String *Item_func_compress::val_str(String *str) 02912 { 02913 int err= Z_OK, code; 02914 ulong new_size; 02915 String *res; 02916 Byte *body; 02917 char *tmp, *last_char; 02918 DBUG_ASSERT(fixed == 1); 02919 02920 if (!(res= args[0]->val_str(str))) 02921 { 02922 null_value= 1; 02923 return 0; 02924 } 02925 if (res->is_empty()) return res; 02926 02927 /* 02928 Citation from zlib.h (comment for compress function): 02929 02930 Compresses the source buffer into the destination buffer. sourceLen is 02931 the byte length of the source buffer. Upon entry, destLen is the total 02932 size of the destination buffer, which must be at least 0.1% larger than 02933 sourceLen plus 12 bytes. 02934 We assume here that the buffer can't grow more than .25 %. 02935 */ 02936 new_size= res->length() + res->length() / 5 + 12; 02937 02938 // Check new_size overflow: new_size <= res->length() 02939 if (((uint32) (new_size+5) <= res->length()) || 02940 buffer.realloc((uint32) new_size + 4 + 1)) 02941 { 02942 null_value= 1; 02943 return 0; 02944 } 02945 02946 body= ((Byte*)buffer.ptr()) + 4; 02947 02948 // As far as we have checked res->is_empty() we can use ptr() 02949 if ((err= compress(body, &new_size, 02950 (const Bytef*)res->ptr(), res->length())) != Z_OK) 02951 { 02952 code= err==Z_MEM_ERROR ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_BUF_ERROR; 02953 push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,code,ER(code)); 02954 null_value= 1; 02955 return 0; 02956 } 02957 02958 tmp= (char*)buffer.ptr(); // int4store is a macro; avoid side effects 02959 int4store(tmp, res->length() & 0x3FFFFFFF); 02960 02961 /* This is to ensure that things works for CHAR fields, which trim ' ': */ 02962 last_char= ((char*)body)+new_size-1; 02963 if (*last_char == ' ') 02964 { 02965 *++last_char= '.'; 02966 new_size++; 02967 } 02968 02969 buffer.length((uint32)new_size + 4); 02970 return &buffer; 02971 } 02972 02973 02974 String *Item_func_uncompress::val_str(String *str) 02975 { 02976 DBUG_ASSERT(fixed == 1); 02977 String *res= args[0]->val_str(str); 02978 ulong new_size; 02979 int err; 02980 uint code; 02981 02982 if (!res) 02983 goto err; 02984 null_value= 0; 02985 if (res->is_empty()) 02986 return res; 02987 02988 /* If length is less than 4 bytes, data is corrupt */ 02989 if (res->length() <= 4) 02990 { 02991 push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, 02992 ER_ZLIB_Z_DATA_ERROR, 02993 ER(ER_ZLIB_Z_DATA_ERROR)); 02994 goto err; 02995 } 02996 02997 /* Size of uncompressed data is stored as first 4 bytes of field */ 02998 new_size= uint4korr(res->ptr()) & 0x3FFFFFFF; 02999 if (new_size > current_thd->variables.max_allowed_packet) 03000 { 03001 push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, 03002 ER_TOO_BIG_FOR_UNCOMPRESS, 03003 ER(ER_TOO_BIG_FOR_UNCOMPRESS), 03004 current_thd->variables.max_allowed_packet); 03005 goto err; 03006 } 03007 if (buffer.realloc((uint32)new_size)) 03008 goto err; 03009 03010 if ((err= uncompress((Byte*)buffer.ptr(), &new_size, 03011 ((const Bytef*)res->ptr())+4,res->length())) == Z_OK) 03012 { 03013 buffer.length((uint32) new_size); 03014 return &buffer; 03015 } 03016 03017 code= ((err == Z_BUF_ERROR) ? ER_ZLIB_Z_BUF_ERROR : 03018 ((err == Z_MEM_ERROR) ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_DATA_ERROR)); 03019 push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,code,ER(code)); 03020 03021 err: 03022 null_value= 1; 03023 return 0; 03024 } 03025 #endif 03026 03027 /* 03028 UUID, as in 03029 DCE 1.1: Remote Procedure Call, 03030 Open Group Technical Standard Document Number C706, October 1997, 03031 (supersedes C309 DCE: Remote Procedure Call 8/1994, 03032 which was basis for ISO/IEC 11578:1996 specification) 03033 */ 03034 03035 static struct rand_struct uuid_rand; 03036 static uint nanoseq; 03037 static ulonglong uuid_time=0; 03038 static char clock_seq_and_node_str[]="-0000-000000000000"; 03039 03040 /* number of 100-nanosecond intervals between 03041 1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00 */ 03042 #define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * 1000 * 10 ) 03043 03044 #define UUID_VERSION 0x1000 03045 #define UUID_VARIANT 0x8000 03046 03047 static void tohex(char *to, uint from, uint len) 03048 { 03049 to+= len; 03050 while (len--) 03051 { 03052 *--to= _dig_vec_lower[from & 15]; 03053 from >>= 4; 03054 } 03055 } 03056 03057 static void set_clock_seq_str() 03058 { 03059 uint16 clock_seq= ((uint)(my_rnd(&uuid_rand)*16383)) | UUID_VARIANT; 03060 tohex(clock_seq_and_node_str+1, clock_seq, 4); 03061 nanoseq= 0; 03062 } 03063 03064 String *Item_func_uuid::val_str(String *str) 03065 { 03066 DBUG_ASSERT(fixed == 1); 03067 char *s; 03068 THD *thd= current_thd; 03069 03070 pthread_mutex_lock(&LOCK_uuid_generator); 03071 if (! uuid_time) /* first UUID() call. initializing data */ 03072 { 03073 ulong tmp=sql_rnd_with_mutex(); 03074 uchar mac[6]; 03075 int i; 03076 if (my_gethwaddr(mac)) 03077 { 03078 /* 03079 generating random "hardware addr" 03080 and because specs explicitly specify that it should NOT correlate 03081 with a clock_seq value (initialized random below), we use a separate 03082 randominit() here 03083 */ 03084 randominit(&uuid_rand, tmp + (ulong) thd, tmp + (ulong)query_id); 03085 for (i=0; i < (int)sizeof(mac); i++) 03086 mac[i]=(uchar)(my_rnd(&uuid_rand)*255); 03087 } 03088 s=clock_seq_and_node_str+sizeof(clock_seq_and_node_str)-1; 03089 for (i=sizeof(mac)-1 ; i>=0 ; i--) 03090 { 03091 *--s=_dig_vec_lower[mac[i] & 15]; 03092 *--s=_dig_vec_lower[mac[i] >> 4]; 03093 } 03094 randominit(&uuid_rand, tmp + (ulong)start_time, 03095 tmp + thd->status_var.bytes_sent); 03096 set_clock_seq_str(); 03097 } 03098 03099 ulonglong tv=my_getsystime() + UUID_TIME_OFFSET + nanoseq; 03100 if (unlikely(tv < uuid_time)) 03101 set_clock_seq_str(); 03102 else if (unlikely(tv == uuid_time)) 03103 { 03104 /* special protection from low-res system clocks */ 03105 nanoseq++; 03106 tv++; 03107 } 03108 else 03109 { 03110 if (nanoseq) 03111 { 03112 tv-=nanoseq; 03113 nanoseq=0; 03114 } 03115 DBUG_ASSERT(tv > uuid_time); 03116 } 03117 uuid_time=tv; 03118 pthread_mutex_unlock(&LOCK_uuid_generator); 03119 03120 uint32 time_low= (uint32) (tv & 0xFFFFFFFF); 03121 uint16 time_mid= (uint16) ((tv >> 32) & 0xFFFF); 03122 uint16 time_hi_and_version= (uint16) ((tv >> 48) | UUID_VERSION); 03123 03124 str->realloc(UUID_LENGTH+1); 03125 str->length(UUID_LENGTH); 03126 str->set_charset(system_charset_info); 03127 s=(char *) str->ptr(); 03128 s[8]=s[13]='-'; 03129 tohex(s, time_low, 8); 03130 tohex(s+9, time_mid, 4); 03131 tohex(s+14, time_hi_and_version, 4); 03132 strmov(s+18, clock_seq_and_node_str); 03133 return str; 03134 } 03135
1.4.7

