diff options
author | Alexander Barkov <bar@mariadb.com> | 2019-08-13 11:42:31 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2019-08-13 11:42:31 +0400 |
commit | 95cdc1ca5f006965e1b0e53a8567f6dbb87e01a1 (patch) | |
tree | 20f91c9dfc995df26363073737c34e8fe565bfe6 /sql/item_strfunc.cc | |
parent | ae1d17f52de045b37e0894e1e6684a911a43696c (diff) | |
parent | 43882e764d6867c6855b1ff057758a3f08b25c55 (diff) | |
download | mariadb-git-95cdc1ca5f006965e1b0e53a8567f6dbb87e01a1.tar.gz |
Merge commit '43882e764d6867c6855b1ff057758a3f08b25c55' into 10.4
Diffstat (limited to 'sql/item_strfunc.cc')
-rw-r--r-- | sql/item_strfunc.cc | 100 |
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; } |