summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkonstantin@mysql.com <>2004-09-03 23:28:49 +0400
committerkonstantin@mysql.com <>2004-09-03 23:28:49 +0400
commitbdec2c603b0f15acef0d06ab34b160f4405b81db (patch)
tree80293b4b3ae9f9f5423d4877aa048b372cbf1e48
parentc3cb5980c286eccb00ae088dfd3de4aaa29e239f (diff)
downloadmariadb-git-bdec2c603b0f15acef0d06ab34b160f4405b81db.tar.gz
A fix for bug#4368 '"like" fails in PreparedStatement, crashes
server': the bug occurs when arguments of LIKE function are in differentcharacter sets. If these character sets are compatible, we create an item-converter. In prepared mode, this item needs to be created in memory of current prepared statement.
-rw-r--r--mysql-test/r/ps.result11
-rw-r--r--mysql-test/t/ps.test17
-rw-r--r--sql/item_cmpfunc.cc15
3 files changed, 41 insertions, 2 deletions
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index e161904cd6f..321b8894796 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -259,3 +259,14 @@ execute `ü`;
1234
1234
set names default;
+create table t1 (a varchar(10)) charset=utf8;
+insert into t1 (a) values ('yahoo');
+set character_set_connection=latin1;
+prepare stmt from 'select a from t1 where a like ?';
+set @var='google';
+execute stmt using @var;
+a
+execute stmt using @var;
+a
+deallocate prepare stmt;
+drop table t1;
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index e54bf8076e0..cbc76e02b42 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -261,3 +261,20 @@ execute `ü`;
set names default;
+#
+# BUG#4368 "select * from t1 where a like ?" crashes server if a is in utf8
+# and ? is in latin1
+# Check that Item converting latin1 to utf8 (for LIKE function) is created
+# in memory of prepared statement.
+#
+
+create table t1 (a varchar(10)) charset=utf8;
+insert into t1 (a) values ('yahoo');
+set character_set_connection=latin1;
+prepare stmt from 'select a from t1 where a like ?';
+set @var='google';
+execute stmt using @var;
+execute stmt using @var;
+deallocate prepare stmt;
+drop table t1;
+
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index f473d242b07..85b22d1eddd 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -211,9 +211,20 @@ void Item_bool_func2::fix_length_and_dec()
}
else
{
- conv= new Item_func_conv_charset(args[weak],args[strong]->collation.collation);
+ THD *thd= current_thd;
+ /*
+ In case we're in statement prepare, create conversion item
+ in its memory: it will be reused on each execute.
+ */
+ Item_arena *arena= thd->current_arena, backup;
+ if (arena->is_stmt_prepare())
+ thd->set_n_backup_item_arena(arena, &backup);
+ conv= new Item_func_conv_charset(args[weak],
+ args[strong]->collation.collation);
+ if (arena->is_stmt_prepare())
+ thd->restore_backup_item_arena(arena, &backup);
conv->collation.set(args[weak]->collation.derivation);
- conv->fix_fields(current_thd, 0, &conv);
+ conv->fix_fields(thd, 0, &conv);
}
args[weak]= conv ? conv : args[weak];
}