summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2015-06-08 20:50:40 +0400
committerAlexander Barkov <bar@mariadb.org>2015-06-08 20:50:40 +0400
commita765cca69fb054ebf389565bfebb506768bf300d (patch)
treeb9cae5db308b8f9e82ce6ce17114be71c74f2323
parentb37b52a3a2c21ed87d92e7c0d3c292f4bd1c52dc (diff)
downloadmariadb-git-a765cca69fb054ebf389565bfebb506768bf300d.tar.gz
MDEV-8067 correct fix for MySQL Bug # 19699237: UNINITIALIZED VARIABLE IN ITEM_FIELD::STR_RESULT
-rw-r--r--mysql-test/r/ctype_utf8.result15
-rw-r--r--mysql-test/t/ctype_utf8.test16
-rw-r--r--sql/item.cc30
-rw-r--r--sql/item.h1
4 files changed, 62 insertions, 0 deletions
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index b8ecc055347..a964384336a 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -5762,5 +5762,20 @@ DROP TABLE t1;
# End of ctype_utf8_ilseq.inc
#
#
+# MDEV-8067 correct fix for MySQL Bug # 19699237: UNINITIALIZED VARIABLE IN ITEM_FIELD::STR_RESULT
+#
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8);
+CREATE TABLE t2 (a VARCHAR(10) CHARACTER SET latin1);
+INSERT INTO t1 VALUES ('aaa');
+INSERT INTO t2 VALUES ('aaa');
+SELECT (SELECT CONCAT(a),1 FROM t1) <=> (SELECT CONCAT(a),1 FROM t2);
+(SELECT CONCAT(a),1 FROM t1) <=> (SELECT CONCAT(a),1 FROM t2)
+1
+INSERT INTO t1 VALUES ('aaa');
+INSERT INTO t2 VALUES ('aaa');
+SELECT (SELECT CONCAT(a),1 FROM t1) <=> (SELECT CONCAT(a),1 FROM t2);
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t1, t2;
+#
# End of 5.5 tests
#
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index f4b16c95135..bed026ac8ce 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -1617,5 +1617,21 @@ SET NAMES utf8 COLLATE utf8_general_ci;
--source include/ctype_utf8_ilseq.inc
--echo #
+--echo # MDEV-8067 correct fix for MySQL Bug # 19699237: UNINITIALIZED VARIABLE IN ITEM_FIELD::STR_RESULT
+--echo #
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8);
+CREATE TABLE t2 (a VARCHAR(10) CHARACTER SET latin1);
+INSERT INTO t1 VALUES ('aaa');
+INSERT INTO t2 VALUES ('aaa');
+SELECT (SELECT CONCAT(a),1 FROM t1) <=> (SELECT CONCAT(a),1 FROM t2);
+INSERT INTO t1 VALUES ('aaa');
+INSERT INTO t2 VALUES ('aaa');
+# Running the below query crashed with two rows
+--error ER_SUBQUERY_NO_1_ROW
+SELECT (SELECT CONCAT(a),1 FROM t1) <=> (SELECT CONCAT(a),1 FROM t2);
+DROP TABLE t1, t2;
+
+
+--echo #
--echo # End of 5.5 tests
--echo #
diff --git a/sql/item.cc b/sql/item.cc
index 6f782e69b89..f8d1c85f447 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1136,6 +1136,36 @@ Item *Item::safe_charset_converter(CHARSET_INFO *tocs)
/**
+ Some pieces of the code do not support changing of
+ Item_cache to other Item types.
+
+ Example:
+ Item_singlerow_subselect has "Item_cache **row".
+ Creating of Item_func_conv_charset followed by THD::change_item_tree()
+ should not change row[i] from Item_cache directly to Item_func_conv_charset, because Item_singlerow_subselect
+ because Item_singlerow_subselect later calls Item_cache-specific methods,
+ e.g. row[i]->store() and row[i]->cache_value().
+
+ Let's wrap Item_func_conv_charset to a new Item_cache,
+ so the Item_cache-specific methods can still be used for
+ Item_singlerow_subselect::row[i] safely.
+
+ TODO: we should eventually check all other use cases of change_item_tree().
+ Perhaps some more potentially dangerous substitution examples exist.
+*/
+Item *Item_cache::safe_charset_converter(CHARSET_INFO *tocs)
+{
+ Item_func_conv_charset *conv= new Item_func_conv_charset(example, tocs, 1);
+ Item_cache *cache;
+ if (!conv || !conv->safe || !(cache= new Item_cache_str(conv)))
+ return NULL; // Safe conversion is not possible, or OEM
+ cache->setup(conv);
+ cache->fixed= false; // Make Item::fix_fields() happy
+ return cache;
+}
+
+
+/**
@details
Created mostly for mysql_prepare_table(). Important
when a string ENUM/SET column is described with a numeric default value:
diff --git a/sql/item.h b/sql/item.h
index ac4fa866349..8bd5751c6e4 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -4161,6 +4161,7 @@ public:
return TRUE;
return (this->*processor)(arg);
}
+ virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
};