#include <item_strfunc.h>
Inheritance diagram for Item_func_concat_ws:


Public Member Functions | |
| Item_func_concat_ws (List< Item > &list) | |
| String * | val_str (String *) |
| void | fix_length_and_dec () |
| const char * | func_name () const |
| table_map | not_null_tables () const |
Private Attributes | |
| String | tmp_value |
Definition at line 95 of file item_strfunc.h.
| void Item_func_concat_ws::fix_length_and_dec | ( | ) | [virtual] |
Implements Item_result_field.
Definition at line 726 of file item_strfunc.cc.
References Item_func::agg_arg_charsets(), Item_func::arg_count, Item_func::args, Item::collation, MAX_BLOB_WIDTH, Item::max_length, Item::maybe_null, and MY_COLL_ALLOW_CONV.
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 }
Here is the call graph for this function:

| const char* Item_func_concat_ws::func_name | ( | ) | const [inline, virtual] |
Implements Item_func.
Definition at line 102 of file item_strfunc.h.
Referenced by val_str().
Here is the caller graph for this function:

| table_map Item_func_concat_ws::not_null_tables | ( | ) | const [inline, virtual] |
Implements Item.
Definition at line 613 of file item_strfunc.cc.
References String::alloc(), String::alloced_length(), String::append(), Item_func::arg_count, Item_func::args, DTCollation::collation, Item::collation, String::copy(), current_thd, DBUG_ASSERT, default_charset_info, ER, ER_WARN_ALLOWED_PACKET_OVERFLOWED, Item::fixed, func_name(), String::is_alloced(), String::length(), Item::max_length, my_empty_string(), Item::null_value, String::ptr(), push_warning_printf(), String::replace(), String::set_charset(), tmp_value, and MYSQL_ERROR::WARN_LEVEL_WARN.
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 }
Here is the call graph for this function:

String Item_func_concat_ws::tmp_value [private] |
1.4.7

