summaryrefslogtreecommitdiff
path: root/sql/item_strfunc.cc
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2019-08-13 11:42:31 +0400
committerAlexander Barkov <bar@mariadb.com>2019-08-13 11:42:31 +0400
commit95cdc1ca5f006965e1b0e53a8567f6dbb87e01a1 (patch)
tree20f91c9dfc995df26363073737c34e8fe565bfe6 /sql/item_strfunc.cc
parentae1d17f52de045b37e0894e1e6684a911a43696c (diff)
parent43882e764d6867c6855b1ff057758a3f08b25c55 (diff)
downloadmariadb-git-95cdc1ca5f006965e1b0e53a8567f6dbb87e01a1.tar.gz
Merge commit '43882e764d6867c6855b1ff057758a3f08b25c55' into 10.4
Diffstat (limited to 'sql/item_strfunc.cc')
-rw-r--r--sql/item_strfunc.cc100
1 files changed, 43 insertions, 57 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 190df1b9f5a..7151e8966ee 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -58,6 +58,27 @@ C_MODE_END
size_t username_char_length= 80;
+
+class Repeat_count
+{
+ ulonglong m_count;
+public:
+ Repeat_count(Item *item)
+ :m_count(0)
+ {
+ Longlong_hybrid nr= item->to_longlong_hybrid();
+ if (!item->null_value && !nr.neg())
+ {
+ // Assume that the maximum length of a String is < INT_MAX32
+ m_count= (ulonglong) nr.value();
+ if (m_count > (ulonglong) INT_MAX32)
+ m_count= (ulonglong) INT_MAX32;
+ }
+ }
+ ulonglong count() const { return m_count; }
+};
+
+
/*
For the Items which have only val_str_ascii() method
and don't have their own "native" val_str(),
@@ -1633,13 +1654,10 @@ String *Item_func_left::val_str(String *str)
void Item_str_func::left_right_max_length()
{
uint32 char_length= args[0]->max_char_length();
- if (args[1]->const_item())
+ if (args[1]->const_item() && !args[1]->is_expensive())
{
- int length= (int) args[1]->val_int();
- if (args[1]->null_value || length <= 0)
- char_length=0;
- else
- set_if_smaller(char_length, (uint) length);
+ Repeat_count tmp(args[1]);
+ set_if_smaller(char_length, (uint) tmp.count());
}
fix_char_length(char_length);
}
@@ -2963,27 +2981,16 @@ bool Item_func_repeat::fix_length_and_dec()
if (agg_arg_charsets_for_string_result(collation, args, 1))
return TRUE;
DBUG_ASSERT(collation.collation != NULL);
- if (args[1]->const_item())
+ if (args[1]->const_item() && !args[1]->is_expensive())
{
- /* must be longlong to avoid truncation */
- longlong count= args[1]->val_int();
-
- /* Assumes that the maximum length of a String is < INT_MAX32. */
- /* Set here so that rest of code sees out-of-bound value as such. */
- if (args[1]->null_value)
- count= 0;
- else if (count > INT_MAX32)
- count= INT_MAX32;
-
- ulonglong char_length= (ulonglong) args[0]->max_char_length() * count;
+ Repeat_count tmp(args[1]);
+ ulonglong char_length= (ulonglong) args[0]->max_char_length() * tmp.count();
fix_char_length_ulonglong(char_length);
+ return false;
}
- else
- {
- max_length= MAX_BLOB_WIDTH;
- maybe_null= 1;
- }
- return FALSE;
+ max_length= MAX_BLOB_WIDTH;
+ maybe_null= true;
+ return false;
}
/**
@@ -3048,26 +3055,14 @@ err:
bool Item_func_space::fix_length_and_dec()
{
collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
- if (args[0]->const_item())
+ if (args[0]->const_item() && !args[0]->is_expensive())
{
- /* must be longlong to avoid truncation */
- longlong count= args[0]->val_int();
- if (args[0]->null_value)
- goto end;
- /*
- Assumes that the maximum length of a String is < INT_MAX32.
- Set here so that rest of code sees out-of-bound value as such.
- */
- if (count > INT_MAX32)
- count= INT_MAX32;
- fix_char_length_ulonglong(count);
- return FALSE;
+ fix_char_length_ulonglong(Repeat_count(args[0]).count());
+ return false;
}
-
-end:
max_length= MAX_BLOB_WIDTH;
- maybe_null= 1;
- return FALSE;
+ maybe_null= true;
+ return false;
}
@@ -3178,24 +3173,15 @@ bool Item_func_pad::fix_length_and_dec()
pad_str.append(" ", 1);
}
- if (args[1]->const_item())
+ DBUG_ASSERT(collation.collation->mbmaxlen > 0);
+ if (args[1]->const_item() && !args[1]->is_expensive())
{
- ulonglong char_length= (ulonglong) args[1]->val_int();
- DBUG_ASSERT(collation.collation->mbmaxlen > 0);
- /* Assumes that the maximum length of a String is < INT_MAX32. */
- /* Set here so that rest of code sees out-of-bound value as such. */
- if (args[1]->null_value)
- char_length= 0;
- else if (char_length > INT_MAX32)
- char_length= INT_MAX32;
- fix_char_length_ulonglong(char_length);
- }
- else
- {
- max_length= MAX_BLOB_WIDTH;
- maybe_null= 1;
+ fix_char_length(Repeat_count(args[1]).count());
+ return false;
}
- return FALSE;
+ max_length= MAX_BLOB_WIDTH;
+ maybe_null= true;
+ return false;
}