Skip to content

Commit d53f340

Browse files
author
Xing Zhang
committed
Bug #27041543: ASSERTION `MAX_LENGTH >= LENGTH' FAILED.
In Item_func_set_user_var::resolve_type(), collation is changed but max_length is not accordingly. Fix by changing max_length if collation is changed. Change-Id: Iffe50a6b100a2bf5fe4bdd07651b3e11232db0de
1 parent dcaeded commit d53f340

File tree

4 files changed

+72
-8
lines changed

4 files changed

+72
-8
lines changed

mysql-test/r/filesort_debug.result

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,29 @@ HEX(WEIGHT_STRING(a COLLATE utf8mb4_0900_ai_ci, 4, 3, 0xC0))
142142
1C3E1C3D
143143
1C3F1C3D
144144
DROP TABLE t1;
145+
#
146+
# Bug #27041543: ASSERTION `MAX_LENGTH >= LENGTH' FAILED.
147+
#
148+
SET NAMES utf8,@@character_set_results=NULL;
149+
CREATE TEMPORARY TABLE t1(a INT);
150+
INSERT INTO t1 VALUES(1);
151+
SELECT 1 FROM t1 ORDER BY @x:=makedate(a,a);
152+
1
153+
1
154+
DROP TABLE t1;
155+
CREATE TABLE t1 AS SELECT 1 AS a WHERE false;
156+
CREATE TABLE t2 AS SELECT @x:=makedate(a,a) FROM t1;
157+
SHOW CREATE TABLE t2;
158+
Table Create Table
159+
t2 CREATE TABLE `t2` (
160+
`@x:=makedate(a,a)` varchar(10) CHARACTER SET utf8 DEFAULT NULL
161+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
162+
DROP TABLE t2;
163+
CREATE TABLE t2 AS SELECT @a:=@b:=@x:=makedate(a,a) FROM t1;
164+
SHOW CREATE TABLE t2;
165+
Table Create Table
166+
t2 CREATE TABLE `t2` (
167+
`@a:=@b:=@x:=makedate(a,a)` varchar(10) CHARACTER SET utf8 DEFAULT NULL
168+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
169+
DROP TABLE t2;
170+
DROP TABLE t1;

mysql-test/t/filesort_debug.test

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,20 @@ SELECT HEX(WEIGHT_STRING(a COLLATE utf8mb4_0900_ai_ci, 3, 3, 0xC0)) FROM t1;
214214
# and get even number's weight.
215215
SELECT HEX(WEIGHT_STRING(a COLLATE utf8mb4_0900_ai_ci, 4, 3, 0xC0)) FROM t1;
216216
DROP TABLE t1;
217+
--echo #
218+
--echo # Bug #27041543: ASSERTION `MAX_LENGTH >= LENGTH' FAILED.
219+
--echo #
220+
SET NAMES utf8,@@character_set_results=NULL;
221+
CREATE TEMPORARY TABLE t1(a INT);
222+
INSERT INTO t1 VALUES(1);
223+
SELECT 1 FROM t1 ORDER BY @x:=makedate(a,a);
224+
DROP TABLE t1;
225+
226+
CREATE TABLE t1 AS SELECT 1 AS a WHERE false;
227+
CREATE TABLE t2 AS SELECT @x:=makedate(a,a) FROM t1;
228+
SHOW CREATE TABLE t2;
229+
DROP TABLE t2;
230+
CREATE TABLE t2 AS SELECT @a:=@b:=@x:=makedate(a,a) FROM t1;
231+
SHOW CREATE TABLE t2;
232+
DROP TABLE t2;
233+
DROP TABLE t1;

sql/item.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -738,11 +738,12 @@ class Item : public Parse_tree_node
738738
Provide data type for a user or system variable, based on the type of
739739
the item that is assigned to the variable.
740740
741+
@note MYSQL_TYPE_VARCHAR is returned for all string types, but must be
742+
further adjusted based on maximum string length by the caller.
743+
741744
@param src_type Source type that variable's type is derived from
742-
@param max_bytes Maximum string size in bytes, used for string types
743745
*/
744-
static enum_field_types type_for_variable(enum_field_types src_type,
745-
uint32 max_bytes)
746+
static enum_field_types type_for_variable(enum_field_types src_type)
746747
{
747748
switch (src_type)
748749
{
@@ -778,12 +779,11 @@ class Item : public Parse_tree_node
778779
case MYSQL_TYPE_SET:
779780
case MYSQL_TYPE_GEOMETRY:
780781
case MYSQL_TYPE_NULL:
781-
return MYSQL_TYPE_VARCHAR;
782782
case MYSQL_TYPE_TINY_BLOB:
783783
case MYSQL_TYPE_BLOB:
784784
case MYSQL_TYPE_MEDIUM_BLOB:
785785
case MYSQL_TYPE_LONG_BLOB:
786-
return string_field_type(max_bytes);
786+
return MYSQL_TYPE_VARCHAR;
787787
default:
788788
DBUG_ASSERT(false);
789789
return MYSQL_TYPE_NULL;

sql/item_func.cc

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6009,10 +6009,31 @@ bool Item_func_set_user_var::resolve_type(THD*)
60096009
else
60106010
collation.collation= args[0]->collation.collation;
60116011

6012-
set_data_type(Item::type_for_variable(args[0]->data_type(),
6013-
args[0]->max_length));
6014-
max_length= args[0]->max_length;
6012+
enum_field_types data_type= Item::type_for_variable(args[0]->data_type());
6013+
switch (data_type)
6014+
{
6015+
case MYSQL_TYPE_LONGLONG:
6016+
set_data_type_longlong();
6017+
max_length= args[0]->max_length; // Preserves "length" of integer constants
6018+
break;
6019+
case MYSQL_TYPE_NEWDECIMAL:
6020+
set_data_type_decimal(args[0]->decimal_precision(), args[0]->decimals);
6021+
break;
6022+
case MYSQL_TYPE_DOUBLE:
6023+
set_data_type_double();
6024+
break;
6025+
case MYSQL_TYPE_VARCHAR:
6026+
set_data_type_string(args[0]->max_char_length());
6027+
break;
6028+
case MYSQL_TYPE_NULL:
6029+
default:
6030+
DBUG_ASSERT(false);
6031+
set_data_type(MYSQL_TYPE_NULL);
6032+
break;
6033+
}
6034+
60156035
unsigned_flag= args[0]->unsigned_flag;
6036+
60166037
return false;
60176038
}
60186039

0 commit comments

Comments
 (0)