summaryrefslogtreecommitdiff
path: root/sql/item_strfunc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_strfunc.cc')
-rw-r--r--sql/item_strfunc.cc51
1 files changed, 34 insertions, 17 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index ebfca684ccb..cce99ec2991 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -3299,23 +3299,21 @@ err:
String* Item_func_export_set::val_str(String* str)
{
DBUG_ASSERT(fixed == 1);
- ulonglong the_set = (ulonglong) args[0]->val_int();
- String yes_buf, *yes;
- yes = args[1]->val_str(&yes_buf);
- String no_buf, *no;
- no = args[2]->val_str(&no_buf);
- String *sep = NULL, sep_buf ;
+ String yes_buf, no_buf, sep_buf;
+ const ulonglong the_set = (ulonglong) args[0]->val_int();
+ const String *yes= args[1]->val_str(&yes_buf);
+ const String *no= args[2]->val_str(&no_buf);
+ const String *sep= NULL;
uint num_set_values = 64;
- ulonglong mask = 0x1;
str->length(0);
str->set_charset(collation.collation);
/* Check if some argument is a NULL value */
if (args[0]->null_value || args[1]->null_value || args[2]->null_value)
{
- null_value=1;
- return 0;
+ null_value= true;
+ return NULL;
}
/*
Arg count can only be 3, 4 or 5 here. This is guaranteed from the
@@ -3328,37 +3326,56 @@ String* Item_func_export_set::val_str(String* str)
num_set_values=64;
if (args[4]->null_value)
{
- null_value=1;
- return 0;
+ null_value= true;
+ return NULL;
}
/* Fall through */
case 4:
if (!(sep = args[3]->val_str(&sep_buf))) // Only true if NULL
{
- null_value=1;
- return 0;
+ null_value= true;
+ return NULL;
}
break;
case 3:
{
/* errors is not checked - assume "," can always be converted */
uint errors;
- sep_buf.copy(STRING_WITH_LEN(","), &my_charset_bin, collation.collation, &errors);
+ sep_buf.copy(STRING_WITH_LEN(","), &my_charset_bin,
+ collation.collation, &errors);
sep = &sep_buf;
}
break;
default:
DBUG_ASSERT(0); // cannot happen
}
- null_value=0;
+ null_value= false;
+
+ const ulong max_allowed_packet= current_thd->variables.max_allowed_packet;
+ const uint num_separators= num_set_values > 0 ? num_set_values - 1 : 0;
+ const ulonglong max_total_length=
+ num_set_values * max(yes->length(), no->length()) +
+ num_separators * sep->length();
+
+ if (unlikely(max_total_length > max_allowed_packet))
+ {
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
+ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
+ func_name(), max_allowed_packet);
+ null_value= true;
+ return NULL;
+ }
- for (uint i = 0; i < num_set_values; i++, mask = (mask << 1))
+ uint ix;
+ ulonglong mask;
+ for (ix= 0, mask=0x1; ix < num_set_values; ++ix, mask = (mask << 1))
{
if (the_set & mask)
str->append(*yes);
else
str->append(*no);
- if (i != num_set_values - 1)
+ if (ix != num_separators)
str->append(*sep);
}
return str;