summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/type_int.result24
-rw-r--r--mysql-test/t/type_int.test19
-rw-r--r--sql/sql_select.cc22
3 files changed, 65 insertions, 0 deletions
diff --git a/mysql-test/r/type_int.result b/mysql-test/r/type_int.result
new file mode 100644
index 00000000000..aaf35690306
--- /dev/null
+++ b/mysql-test/r/type_int.result
@@ -0,0 +1,24 @@
+#
+# Start of 5.5 tests
+#
+#
+# MDEV-15955 Assertion `field_types == 0 || field_types[field_pos] == MYSQL_TYPE_LONGLONG' failed in Protocol_text::store_longlong
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+SELECT @a := 1 FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar');
+@a := 1
+1
+SELECT COALESCE(1) FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar');
+COALESCE(1)
+1
+SELECT COALESCE(@a:=1) FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar');
+COALESCE(@a:=1)
+1
+SELECT COALESCE(@a) FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar');
+COALESCE(@a)
+1
+DROP TABLE t1;
+#
+# End of 5.5 tests
+#
diff --git a/mysql-test/t/type_int.test b/mysql-test/t/type_int.test
new file mode 100644
index 00000000000..52be12bf494
--- /dev/null
+++ b/mysql-test/t/type_int.test
@@ -0,0 +1,19 @@
+--echo #
+--echo # Start of 5.5 tests
+--echo #
+
+--echo #
+--echo # MDEV-15955 Assertion `field_types == 0 || field_types[field_pos] == MYSQL_TYPE_LONGLONG' failed in Protocol_text::store_longlong
+--echo #
+
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+SELECT @a := 1 FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar');
+SELECT COALESCE(1) FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar');
+SELECT COALESCE(@a:=1) FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar');
+SELECT COALESCE(@a) FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar');
+DROP TABLE t1;
+
+--echo #
+--echo # End of 5.5 tests
+--echo #
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 3d78000b3d4..529ecd78836 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -14762,6 +14762,28 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
if (item->cmp_type() == TIME_RESULT ||
item->field_type() == MYSQL_TYPE_GEOMETRY)
new_field= item->tmp_table_field_from_field_type(table, 1);
+ else if (item->type() == Item::FUNC_ITEM &&
+ static_cast<Item_func*>(item)->functype() == Item_func::SUSERVAR_FUNC)
+ {
+ /*
+ A temporary solution for versions 5.5 .. 10.3.
+ This change should be null-merged to 10.4.
+
+ Item_func_set_user_var is special. It overrides make_field().
+ by adding a special branch `if (result_field)...`.
+ So it's important to preserve the exact data type here,
+ to avoid type mismatch in Protocol_text::store_longlong()
+ See MDEV-15955.
+
+ Other Item_func descendants are not affected by MDEV-15955.
+ They don't override make_field() so they don't use result_field
+ when initializing Send_field.
+
+ This is properly fixed in 10.4 in the method
+ Item_func_user_var::create_tmp_field_ex().
+ */
+ new_field= item->tmp_table_field_from_field_type(table, false);
+ }
else
switch (item->result_type()) {
case REAL_RESULT: