summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkaa@kaamos.(none) <>2008-02-17 16:57:07 +0300
committerkaa@kaamos.(none) <>2008-02-17 16:57:07 +0300
commit443c1a8b1950f2a4d9965609e8cc0ebfbac87392 (patch)
tree5ca41575997313d46f10c9e9954c5370613d545a
parentcb80b23e23175f1a7c5a770a49838cd90e14d099 (diff)
parenta781c1b140129a6d0296e76c0fc96d02d4a52d11 (diff)
downloadmariadb-git-443c1a8b1950f2a4d9965609e8cc0ebfbac87392.tar.gz
Merge ssh://bk-internal.mysql.com//home/bk/mysql-5.0-opt
into kaamos.(none):/data/src/opt/mysql-5.0-opt
-rw-r--r--mysql-test/r/compare.result38
-rw-r--r--mysql-test/t/compare.test31
-rw-r--r--sql/item.cc31
-rw-r--r--sql/mysql_priv.h1
4 files changed, 101 insertions, 0 deletions
diff --git a/mysql-test/r/compare.result b/mysql-test/r/compare.result
index c141b255716..c9ef41e0582 100644
--- a/mysql-test/r/compare.result
+++ b/mysql-test/r/compare.result
@@ -53,3 +53,41 @@ a b
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: ''
drop table if exists t1;
+CREATE TABLE t1 (b int(2) zerofill, c int(2) zerofill);
+INSERT INTO t1 (b,c) VALUES (1,2), (1,1), (2,2);
+SELECT CONCAT(b,c), CONCAT(b,c) = '0101' FROM t1;
+CONCAT(b,c) CONCAT(b,c) = '0101'
+0102 0
+0101 1
+0202 0
+EXPLAIN EXTENDED SELECT b,c FROM t1 WHERE b = 1 AND CONCAT(b,c) = '0101';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`b` = 1) and (concat(_binary'01',`test`.`t1`.`c`) = _latin1'0101'))
+SELECT b,c FROM t1 WHERE b = 1 AND CONCAT(b,c) = '0101';
+b c
+01 01
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (1),(2);
+SELECT a,
+(SELECT COUNT(*) FROM t1
+WHERE b = t2.a AND CONCAT(b,c) = CONCAT('0',t2.a,'01')) x
+FROM t2 ORDER BY a;
+a x
+1 1
+2 0
+EXPLAIN EXTENDED
+SELECT a,
+(SELECT COUNT(*) FROM t1
+WHERE b = t2.a AND CONCAT(b,c) = CONCAT('0',t2.a,'01')) x
+FROM t2 ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using filesort
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
+Warnings:
+Note 1276 Field or reference 'test.t2.a' of SELECT #2 was resolved in SELECT #1
+Note 1276 Field or reference 'test.t2.a' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t2`.`a` AS `a`,(select count(0) AS `COUNT(*)` from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t2`.`a`) and (concat(`test`.`t1`.`b`,`test`.`t1`.`c`) = concat(_latin1'0',`test`.`t2`.`a`,_latin1'01')))) AS `x` from `test`.`t2` order by `test`.`t2`.`a`
+DROP TABLE t1,t2;
+End of 5.0 tests
diff --git a/mysql-test/t/compare.test b/mysql-test/t/compare.test
index 337035a8095..8863ed825c2 100644
--- a/mysql-test/t/compare.test
+++ b/mysql-test/t/compare.test
@@ -46,3 +46,34 @@ insert into t1 values (0x01,0x01);
select * from t1 where a=b;
select * from t1 where a=b and b=0x01;
drop table if exists t1;
+
+#
+# Bug #31887: DML Select statement not returning same results when executed
+# in version 5
+#
+
+CREATE TABLE t1 (b int(2) zerofill, c int(2) zerofill);
+INSERT INTO t1 (b,c) VALUES (1,2), (1,1), (2,2);
+
+SELECT CONCAT(b,c), CONCAT(b,c) = '0101' FROM t1;
+
+EXPLAIN EXTENDED SELECT b,c FROM t1 WHERE b = 1 AND CONCAT(b,c) = '0101';
+SELECT b,c FROM t1 WHERE b = 1 AND CONCAT(b,c) = '0101';
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (1),(2);
+
+SELECT a,
+ (SELECT COUNT(*) FROM t1
+ WHERE b = t2.a AND CONCAT(b,c) = CONCAT('0',t2.a,'01')) x
+FROM t2 ORDER BY a;
+
+EXPLAIN EXTENDED
+SELECT a,
+ (SELECT COUNT(*) FROM t1
+ WHERE b = t2.a AND CONCAT(b,c) = CONCAT('0',t2.a,'01')) x
+FROM t2 ORDER BY a;
+
+DROP TABLE t1,t2;
+
+--echo End of 5.0 tests
diff --git a/sql/item.cc b/sql/item.cc
index a3ed420b2ce..53e7f124ccd 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -4087,6 +4087,30 @@ bool Item_field::subst_argument_checker(byte **arg)
}
+/**
+ Convert a numeric value to a zero-filled string
+
+ @param[in,out] item the item to operate on
+ @param field The field that this value is equated to
+
+ This function converts a numeric value to a string. In this conversion
+ the zero-fill flag of the field is taken into account.
+ This is required so the resulting string value can be used instead of
+ the field reference when propagating equalities.
+*/
+
+static void convert_zerofill_number_to_string(Item **item, Field_num *field)
+{
+ char buff[MAX_FIELD_WIDTH],*pos;
+ String tmp(buff,sizeof(buff), field->charset()), *res;
+
+ res= (*item)->val_str(&tmp);
+ field->prepend_zeros(res);
+ pos= (char *) sql_strmake (res->ptr(), res->length());
+ *item= new Item_string(pos, res->length(), field->charset());
+}
+
+
/*
Set a pointer to the multiple equality the field reference belongs to
(if any)
@@ -4135,6 +4159,13 @@ Item *Item_field::equal_fields_propagator(byte *arg)
if (!item ||
(cmp_context != (Item_result)-1 && item->cmp_context != cmp_context))
item= this;
+ else if (field && (field->flags & ZEROFILL_FLAG) && IS_NUM(field->type()))
+ {
+ if (item && cmp_context != INT_RESULT)
+ convert_zerofill_number_to_string(&item, (Field_num *)field);
+ else
+ item= this;
+ }
return item;
}
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 4334dedfe4e..a45fda8e9f8 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -73,6 +73,7 @@ extern const char *primary_key_name;
#include "mysql_com.h"
#include <violite.h>
#include "unireg.h"
+#define IS_NUM(t) ((t) <= FIELD_TYPE_INT24 || (t) == FIELD_TYPE_YEAR || (t) == FIELD_TYPE_NEWDECIMAL)
void init_sql_alloc(MEM_ROOT *root, uint block_size, uint pre_alloc_size);
gptr sql_alloc(unsigned size);