summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <kaa@kaamos.(none)>2008-02-13 12:12:00 +0300
committerunknown <kaa@kaamos.(none)>2008-02-13 12:12:00 +0300
commit91123903145baffbfdc4a864ef02f1f0b6b66744 (patch)
tree32093b4d9c9eff7578d39bb14fee8bbbdcf1dc4b
parent00b17696efc6e4ffc70abdbea4b76b88b397b910 (diff)
parentc6610b57912ba010acf9ead06095309bf71f7c96 (diff)
downloadmariadb-git-91123903145baffbfdc4a864ef02f1f0b6b66744.tar.gz
Merge kaamos.(none):/data/src/opt/mysql-5.0-opt
into kaamos.(none):/data/src/opt/mysql-5.1-opt mysql-test/r/heap.result: Auto merged mysql-test/r/innodb.result: Auto merged mysql-test/r/myisam.result: Auto merged BitKeeper/deleted/.del-bdb.result: Auto merged mysql-test/r/strict.result: Auto merged mysql-test/r/type_binary.result: Auto merged mysql-test/r/type_set.result: Auto merged mysql-test/r/variables.result: Auto merged mysql-test/r/warnings.result: Auto merged mysql-test/t/range.test: Auto merged mysql-test/t/variables.test: Auto merged mysql-test/t/warnings.test: Auto merged sql/field.cc: Auto merged sql/field.h: Auto merged sql/item.cc: Auto merged sql/item.h: Auto merged sql/item_func.cc: Auto merged sql/sql_select.cc: Auto merged sql/mysqld.cc: Null merge. mysql-test/include/mix1.inc: Manual merge. mysql-test/r/innodb_mysql.result: Manual merge. mysql-test/r/range.result: Manual merge. mysql-test/r/sp.result: Manual merge. mysql-test/t/sp.test: Manual merge. sql/handler.cc: Manual merge.
-rw-r--r--mysql-test/include/mix1.inc13
-rw-r--r--mysql-test/r/heap.result1
-rw-r--r--mysql-test/r/innodb.result1
-rw-r--r--mysql-test/r/innodb_mysql.result6
-rw-r--r--mysql-test/r/myisam.result1
-rw-r--r--mysql-test/r/range.result13
-rw-r--r--mysql-test/r/sp.result17
-rw-r--r--mysql-test/r/strict.result2
-rw-r--r--mysql-test/r/type_binary.result1
-rw-r--r--mysql-test/r/type_set.result8
-rw-r--r--mysql-test/r/warnings.result38
-rw-r--r--mysql-test/t/range.test17
-rw-r--r--mysql-test/t/sp.test19
-rw-r--r--mysql-test/t/type_set.test20
-rw-r--r--mysql-test/t/warnings.test33
-rw-r--r--sql/field.cc80
-rw-r--r--sql/field.h2
-rw-r--r--sql/handler.cc11
-rw-r--r--sql/item.cc43
-rw-r--r--sql/item.h1
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/sql_select.cc4
22 files changed, 285 insertions, 48 deletions
diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc
index 703dfa44df0..9ea02a12890 100644
--- a/mysql-test/include/mix1.inc
+++ b/mysql-test/include/mix1.inc
@@ -1090,6 +1090,19 @@ SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d;
DROP TABLE t1;
+#
+# Bug #34223: Assertion failed: (optp->var_type & 127) == 8,
+# file .\my_getopt.c, line 830
+#
+
+set @my_innodb_autoextend_increment=@@global.innodb_autoextend_increment;
+set global innodb_autoextend_increment=8;
+set global innodb_autoextend_increment=@my_innodb_autoextend_increment;
+
+set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency;
+set global innodb_commit_concurrency=0;
+set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
+
--echo End of 5.0 tests
# Fix for BUG#19243 "wrong LAST_INSERT_ID() after ON DUPLICATE KEY
diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result
index ddf675e2f73..a2c208ee3e1 100644
--- a/mysql-test/r/heap.result
+++ b/mysql-test/r/heap.result
@@ -256,6 +256,7 @@ set @a=repeat(' ',20);
insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a));
Warnings:
Note 1265 Data truncated for column 'v' at row 1
+Note 1265 Data truncated for column 'c' at row 1
select concat('*',v,'*',c,'*',t,'*') from t1;
concat('*',v,'*',c,'*',t,'*')
*+ *+*+ *
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index d0c586de8d4..2e8a21c78f9 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1823,6 +1823,7 @@ set @a=repeat(' ',20);
insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a));
Warnings:
Note 1265 Data truncated for column 'v' at row 1
+Note 1265 Data truncated for column 'c' at row 1
select concat('*',v,'*',c,'*',t,'*') from t1;
concat('*',v,'*',c,'*',t,'*')
*+ *+*+ *
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index e9f00a667c0..f51d35d45c1 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -1356,6 +1356,12 @@ id type d
NULL member 3
NULL member 4
DROP TABLE t1;
+set @my_innodb_autoextend_increment=@@global.innodb_autoextend_increment;
+set global innodb_autoextend_increment=8;
+set global innodb_autoextend_increment=@my_innodb_autoextend_increment;
+set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency;
+set global innodb_commit_concurrency=0;
+set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
End of 5.0 tests
CREATE TABLE `t2` (
`k` int(11) NOT NULL auto_increment,
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index 1c8b5e9d7d9..264d1567003 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -1086,6 +1086,7 @@ set @a=repeat(' ',20);
insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a));
Warnings:
Note 1265 Data truncated for column 'v' at row 1
+Note 1265 Data truncated for column 'c' at row 1
select concat('*',v,'*',c,'*',t,'*') from t1;
concat('*',v,'*',c,'*',t,'*')
*+ *+*+ *
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index 92db6d8429f..3a22a38074f 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -1167,3 +1167,16 @@ explain select * from t2 where a=1000 and b<11;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref a a 5 const 502 Using where
drop table t1, t2;
+CREATE TABLE t1 (
+a varchar(32), index (a)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_bin;
+INSERT INTO t1 VALUES
+('B'), ('A'), ('A'), ('C'), ('B'), ('A'), ('A');
+SELECT a FROM t1 WHERE a='b' OR a='B';
+a
+B
+B
+EXPLAIN SELECT a FROM t1 WHERE a='b' OR a='B';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 35 NULL 3 Using where; Using index
+DROP TABLE t1;
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 68aa278585f..b99a38a4825 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -6812,6 +6812,23 @@ DROP PROCEDURE db28318_b.t2;
DROP DATABASE db28318_a;
DROP DATABASE db28318_b;
use test;
+#
+# Bug#30787: Stored function ignores user defined alias.
+#
+use test;
+drop function if exists func30787;
+create table t1(f1 int);
+insert into t1 values(1),(2);
+create function func30787(p1 int) returns int
+begin
+return p1;
+end |
+select (select func30787(f1)) as ttt from t1;
+ttt
+1
+2
+drop function func30787;
+drop table t1;
End of 5.0 tests
#
diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result
index cc1a2535896..243c6192cc6 100644
--- a/mysql-test/r/strict.result
+++ b/mysql-test/r/strict.result
@@ -934,6 +934,8 @@ NULL NULL
DROP TABLE t1;
CREATE TABLE t1 (col1 CHAR(5), col2 VARCHAR(6));
INSERT INTO t1 VALUES ('hello', 'hello'),('he', 'he'),('hello ', 'hello ');
+Warnings:
+Note 1265 Data truncated for column 'col1' at row 3
INSERT INTO t1 (col1) VALUES ('hellobob');
ERROR 22001: Data too long for column 'col1' at row 1
INSERT INTO t1 (col2) VALUES ('hellobob');
diff --git a/mysql-test/r/type_binary.result b/mysql-test/r/type_binary.result
index 432c58272a2..00f4183aec3 100644
--- a/mysql-test/r/type_binary.result
+++ b/mysql-test/r/type_binary.result
@@ -125,6 +125,7 @@ create table t1 (c char(2), vc varchar(2));
insert into t1 values(0x4120, 0x4120);
insert into t1 values(0x412020, 0x412020);
Warnings:
+Note 1265 Data truncated for column 'c' at row 1
Note 1265 Data truncated for column 'vc' at row 1
drop table t1;
set @old_sql_mode= @@sql_mode, sql_mode= 'traditional';
diff --git a/mysql-test/r/type_set.result b/mysql-test/r/type_set.result
index 877400ab7e1..659215eda33 100644
--- a/mysql-test/r/type_set.result
+++ b/mysql-test/r/type_set.result
@@ -85,3 +85,11 @@ t1 CREATE TABLE `t1` (
`f1` set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','1') DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
+CREATE TABLE t1(c set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64'));
+INSERT INTO t1 VALUES(7);
+INSERT INTO t1 VALUES(9223372036854775808);
+SELECT * FROM t1;
+c
+1,2,3
+64
+DROP TABLE t1;
diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result
index 249cd583345..653309efa42 100644
--- a/mysql-test/r/warnings.result
+++ b/mysql-test/r/warnings.result
@@ -276,4 +276,42 @@ DROP TABLE t3;
DROP PROCEDURE sp1;
DROP PROCEDURE sp2;
DROP PROCEDURE sp3;
+create table t1 (c_char char(255), c_varchar varchar(255), c_tinytext tinytext);
+create table t2 (c_tinyblob tinyblob);
+set @c = repeat(' ', 256);
+set @q = repeat('q', 256);
+set sql_mode = '';
+insert into t1 values(@c, @c, @c);
+Warnings:
+Note 1265 Data truncated for column 'c_char' at row 1
+Note 1265 Data truncated for column 'c_varchar' at row 1
+Note 1265 Data truncated for column 'c_tinytext' at row 1
+insert into t2 values(@c);
+Warnings:
+Warning 1265 Data truncated for column 'c_tinyblob' at row 1
+insert into t1 values(@q, @q, @q);
+Warnings:
+Warning 1265 Data truncated for column 'c_char' at row 1
+Warning 1265 Data truncated for column 'c_varchar' at row 1
+Warning 1265 Data truncated for column 'c_tinytext' at row 1
+insert into t2 values(@q);
+Warnings:
+Warning 1265 Data truncated for column 'c_tinyblob' at row 1
+set sql_mode = 'traditional';
+insert into t1 values(@c, @c, @c);
+Warnings:
+Note 1265 Data truncated for column 'c_char' at row 1
+Note 1265 Data truncated for column 'c_varchar' at row 1
+Note 1265 Data truncated for column 'c_tinytext' at row 1
+insert into t2 values(@c);
+ERROR 22001: Data too long for column 'c_tinyblob' at row 1
+insert into t1 values(@q, NULL, NULL);
+ERROR 22001: Data too long for column 'c_char' at row 1
+insert into t1 values(NULL, @q, NULL);
+ERROR 22001: Data too long for column 'c_varchar' at row 1
+insert into t1 values(NULL, NULL, @q);
+ERROR 22001: Data too long for column 'c_tinytext' at row 1
+insert into t2 values(@q);
+ERROR 22001: Data too long for column 'c_tinyblob' at row 1
+drop table t1, t2;
End of 5.0 tests
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index e20f0370e2c..514e3074292 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -955,6 +955,23 @@ explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= '
drop table t1;
+#
+# Bug #33833: different or-ed predicates were erroneously merged into one that
+# resulted in ref access instead of range access and a wrong result set
+#
+
+CREATE TABLE t1 (
+ a varchar(32), index (a)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_bin;
+
+INSERT INTO t1 VALUES
+ ('B'), ('A'), ('A'), ('C'), ('B'), ('A'), ('A');
+
+SELECT a FROM t1 WHERE a='b' OR a='B';
+EXPLAIN SELECT a FROM t1 WHERE a='b' OR a='B';
+
+DROP TABLE t1;
+
# End of 5.0 tests
# BUG#22393 fix: Adjust 'ref' estimate if we have 'range' estimate for
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 004e1c4ddd2..45bd0d8003f 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -7900,6 +7900,25 @@ DROP DATABASE db28318_a;
DROP DATABASE db28318_b;
use test;
+--echo #
+--echo # Bug#30787: Stored function ignores user defined alias.
+--echo #
+use test;
+--disable_warnings
+drop function if exists func30787;
+--enable_warnings
+create table t1(f1 int);
+insert into t1 values(1),(2);
+delimiter |;
+create function func30787(p1 int) returns int
+begin
+ return p1;
+end |
+delimiter ;|
+select (select func30787(f1)) as ttt from t1;
+drop function func30787;
+drop table t1;
+
###########################################################################
--echo End of 5.0 tests
diff --git a/mysql-test/t/type_set.test b/mysql-test/t/type_set.test
index b1c816f3371..c7f8c59de28 100644
--- a/mysql-test/t/type_set.test
+++ b/mysql-test/t/type_set.test
@@ -56,3 +56,23 @@ set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17',
'50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','1'));
show create table t1;
drop table t1;
+
+#
+# Bug#15409: Columns with SET datatype with 64-element sets
+# may not be updated with integers
+#
+
+let $i=64;
+let $s='$i';
+dec $i;
+while ($i) {
+ let $s='$i',$s;
+ dec $i;
+}
+--eval CREATE TABLE t1(c set($s))
+INSERT INTO t1 VALUES(7);
+INSERT INTO t1 VALUES(9223372036854775808);
+SELECT * FROM t1;
+DROP TABLE t1;
+
+--# echo End of 5.0 tests
diff --git a/mysql-test/t/warnings.test b/mysql-test/t/warnings.test
index d0eaaf1a764..9e7e3e4f945 100644
--- a/mysql-test/t/warnings.test
+++ b/mysql-test/t/warnings.test
@@ -193,4 +193,37 @@ DROP PROCEDURE sp1;
DROP PROCEDURE sp2;
DROP PROCEDURE sp3;
+
+#
+# Bug#30059: End-space truncation warnings are inconsistent or incorrect
+#
+
+create table t1 (c_char char(255), c_varchar varchar(255), c_tinytext tinytext);
+create table t2 (c_tinyblob tinyblob); # not affected by bug, for regression testing
+set @c = repeat(' ', 256);
+set @q = repeat('q', 256);
+
+set sql_mode = '';
+
+insert into t1 values(@c, @c, @c);
+insert into t2 values(@c);
+insert into t1 values(@q, @q, @q);
+insert into t2 values(@q);
+
+set sql_mode = 'traditional';
+
+insert into t1 values(@c, @c, @c);
+--error 1406
+insert into t2 values(@c);
+--error 1406
+insert into t1 values(@q, NULL, NULL);
+--error 1406
+insert into t1 values(NULL, @q, NULL);
+--error 1406
+insert into t1 values(NULL, NULL, @q);
+--error 1406
+insert into t2 values(@q);
+
+drop table t1, t2;
+
--echo End of 5.0 tests
diff --git a/sql/field.cc b/sql/field.cc
index 668ced4a229..fabce5fdc9c 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -6326,26 +6326,41 @@ check_string_copy_error(Field_str *field,
}
-
/*
- Send a truncation warning or a truncation error
- after storing a too long character string info a field.
+ Check if we lost any important data and send a truncation error/warning
SYNOPSIS
- report_data_too_long()
- field - Field
+ Field_longstr::report_if_important_data()
+ ptr - Truncated rest of string
+ end - End of truncated string
- RETURN
- N/A
+ RETURN VALUES
+ 0 - None was truncated (or we don't count cut fields)
+ 2 - Some bytes was truncated
+
+ NOTE
+ Check if we lost any important data (anything in a binary string,
+ or any non-space in others). If only trailing spaces was lost,
+ send a truncation note, otherwise send a truncation error.
*/
-inline void
-report_data_too_long(Field_str *field)
+int
+Field_longstr::report_if_important_data(const char *ptr, const char *end)
{
- if (field->table->in_use->abort_on_warning)
- field->set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
- else
- field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
+ if ((ptr < end) && table->in_use->count_cuted_fields)
+ {
+ if (test_if_important_data(field_charset, ptr, end))
+ {
+ if (table->in_use->abort_on_warning)
+ set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
+ else
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
+ }
+ else /* If we lost only spaces then produce a NOTE, not a WARNING */
+ set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
+ return 2;
+ }
+ return 0;
}
@@ -6380,19 +6395,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
cannot_convert_error_pos, from + length, cs))
return 2;
- /*
- Check if we lost any important data (anything in a binary string,
- or any non-space in others).
- */
- if ((from_end_pos < from + length) && table->in_use->count_cuted_fields)
- {
- if (test_if_important_data(field_charset, from_end_pos, from + length))
- {
- report_data_too_long(this);
- return 2;
- }
- }
- return 0;
+ return report_if_important_data(from_end_pos, from + length);
}
@@ -6970,16 +6973,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
cannot_convert_error_pos, from + length, cs))
return 2;
- // Check if we lost something other than just trailing spaces
- if ((from_end_pos < from + length) && table->in_use->count_cuted_fields)
- {
- if (test_if_important_data(field_charset, from_end_pos, from + length))
- report_data_too_long(this);
- else /* If we lost only spaces then produce a NOTE, not a WARNING */
- set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
- return 2;
- }
- return 0;
+ return report_if_important_data(from_end_pos, from + length);
}
@@ -7681,13 +7675,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
cannot_convert_error_pos, from + length, cs))
return 2;
- if (from_end_pos < from + length)
- {
- report_data_too_long(this);
- return 2;
- }
-
- return 0;
+ return report_if_important_data(from_end_pos, from + length);
oom_error:
/* Fatal OOM error */
@@ -8636,10 +8624,10 @@ int Field_set::store(longlong nr, bool unsigned_val)
{
ASSERT_COLUMN_MARKED_FOR_WRITE;
int error= 0;
- if ((ulonglong) nr > (ulonglong) (((longlong) 1 << typelib->count) -
- (longlong) 1))
+ ulonglong max_nr= set_bits(ulonglong, typelib->count);
+ if ((ulonglong) nr > max_nr)
{
- nr&= (longlong) (((longlong) 1 << typelib->count) - (longlong) 1);
+ nr&= max_nr;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
error=1;
}
diff --git a/sql/field.h b/sql/field.h
index a6a1d8bfabc..9855ec563d5 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -593,6 +593,8 @@ public:
class Field_longstr :public Field_str
{
+protected:
+ int report_if_important_data(const char *ptr, const char *end);
public:
Field_longstr(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg,
diff --git a/sql/handler.cc b/sql/handler.cc
index a4926071598..0d546eef8dd 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1512,6 +1512,13 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
handler *handler::clone(MEM_ROOT *mem_root)
{
handler *new_handler= get_new_handler(table->s, mem_root, table->s->db_type());
+ /*
+ Allocate handler->ref here because otherwise ha_open will allocate it
+ on this->table->mem_root and we will not be able to reclaim that memory
+ when the clone handler object is destroyed.
+ */
+ if (!(new_handler->ref= (uchar*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
+ return NULL;
if (new_handler && !new_handler->ha_open(table,
table->s->normalized_path.str,
table->db_stat,
@@ -1580,7 +1587,9 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode,
table->db_stat|=HA_READ_ONLY;
(void) extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
- if (!(ref= (uchar*) alloc_root(&table->mem_root, ALIGN_SIZE(ref_length)*2)))
+ /* ref is already allocated for us if we're called from handler::clone() */
+ if (!ref && !(ref= (uchar*) alloc_root(&table->mem_root,
+ ALIGN_SIZE(ref_length)*2)))
{
close();
error=HA_ERR_OUT_OF_MEM;
diff --git a/sql/item.cc b/sql/item.cc
index e5018dd4ecb..0e1db376c1e 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -4370,6 +4370,49 @@ String *Item::check_well_formed_result(String *str, bool send_error)
return str;
}
+/*
+ Compare two items using a given collation
+
+ SYNOPSIS
+ eq_by_collation()
+ item item to compare with
+ binary_cmp TRUE <-> compare as binaries
+ cs collation to use when comparing strings
+
+ DESCRIPTION
+ This method works exactly as Item::eq if the collation cs coincides with
+ the collation of the compared objects. Otherwise, first the collations that
+ differ from cs are replaced for cs and then the items are compared by
+ Item::eq. After the comparison the original collations of items are
+ restored.
+
+ RETURN
+ 1 compared items has been detected as equal
+ 0 otherwise
+*/
+
+bool Item::eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs)
+{
+ CHARSET_INFO *save_cs= 0;
+ CHARSET_INFO *save_item_cs= 0;
+ if (collation.collation != cs)
+ {
+ save_cs= collation.collation;
+ collation.collation= cs;
+ }
+ if (item->collation.collation != cs)
+ {
+ save_item_cs= item->collation.collation;
+ item->collation.collation= cs;
+ }
+ bool res= eq(item, binary_cmp);
+ if (save_cs)
+ collation.collation= save_cs;
+ if (save_item_cs)
+ item->collation.collation= save_item_cs;
+ return res;
+}
+
/*
Create a field to hold a string value from an item
diff --git a/sql/item.h b/sql/item.h
index b98389bc8d4..a4b23072e01 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1004,6 +1004,7 @@ public:
virtual Field::geometry_type get_geometry_type() const
{ return Field::GEOM_GEOMETRY; };
String *check_well_formed_result(String *str, bool send_error= 0);
+ bool eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs);
};
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 8fd6f0966ad..cd936412241 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -5500,6 +5500,8 @@ Item_func_sp::make_field(Send_field *tmp_field)
DBUG_ENTER("Item_func_sp::make_field");
DBUG_ASSERT(sp_result_field);
sp_result_field->make_field(tmp_field);
+ if (name)
+ tmp_field->col_name= name;
DBUG_VOID_RETURN;
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index ef9f9fd4359..281b38dd6c1 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2931,7 +2931,9 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
}
}
else if (old->eq_func && new_fields->eq_func &&
- old->val->eq(new_fields->val, old->field->binary()))
+ old->val->eq_by_collation(new_fields->val,
+ old->field->binary(),
+ old->field->charset()))
{
old->level= and_level;