Commit 60cc2f91 authored by Sergey Glukhov's avatar Sergey Glukhov

Bug#11766270 59343: YEAR(4): INCORRECT RESULT AND VALGRIND WARNINGS WITH MIN/MAX, UNION

When we create temporary result table for UNION
incorrect max_length for YEAR field is used and
it leads to incorrect field value and incorrect
result string length as YEAR field value calculation
depends on field length.
The fix is to use underlying item max_length for
Item_sum_hybrid::max_length intialization.
parent 56bff852
...@@ -1746,4 +1746,15 @@ MAX(LENGTH(a)) LENGTH(MAX(a)) MIN(a) MAX(a) CONCAT(MIN(a)) CONCAT(MAX(a)) ...@@ -1746,4 +1746,15 @@ MAX(LENGTH(a)) LENGTH(MAX(a)) MIN(a) MAX(a) CONCAT(MIN(a)) CONCAT(MAX(a))
20 20 18446668621106209655 18446668621106209655 18446668621106209655 18446668621106209655 20 20 18446668621106209655 18446668621106209655 18446668621106209655 18446668621106209655
DROP TABLE t1; DROP TABLE t1;
# #
# Bug #11766270 59343: YEAR(4): INCORRECT RESULT AND VALGRIND WARNINGS WITH MIN/MAX, UNION
#
CREATE TABLE t1(f1 YEAR(4));
INSERT INTO t1 VALUES (0000),(2001);
(SELECT MAX(f1) FROM t1) UNION (SELECT MAX(f1) FROM t1);
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def MAX(f1) MAX(f1) 13 4 4 Y 32864 0 63
MAX(f1)
2001
DROP TABLE t1;
#
End of 5.1 tests End of 5.1 tests
...@@ -1127,6 +1127,18 @@ INSERT INTO t1 VALUES (18446668621106209655); ...@@ -1127,6 +1127,18 @@ INSERT INTO t1 VALUES (18446668621106209655);
SELECT MAX(LENGTH(a)), LENGTH(MAX(a)), MIN(a), MAX(a), CONCAT(MIN(a)), CONCAT(MAX(a)) FROM t1; SELECT MAX(LENGTH(a)), LENGTH(MAX(a)), MIN(a), MAX(a), CONCAT(MIN(a)), CONCAT(MAX(a)) FROM t1;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Bug #11766270 59343: YEAR(4): INCORRECT RESULT AND VALGRIND WARNINGS WITH MIN/MAX, UNION
--echo #
CREATE TABLE t1(f1 YEAR(4));
INSERT INTO t1 VALUES (0000),(2001);
--enable_metadata
(SELECT MAX(f1) FROM t1) UNION (SELECT MAX(f1) FROM t1);
--disable_metadata
DROP TABLE t1;
--echo # --echo #
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -5467,6 +5467,7 @@ double Field_year::val_real(void) ...@@ -5467,6 +5467,7 @@ double Field_year::val_real(void)
longlong Field_year::val_int(void) longlong Field_year::val_int(void)
{ {
ASSERT_COLUMN_MARKED_FOR_READ; ASSERT_COLUMN_MARKED_FOR_READ;
DBUG_ASSERT(field_length == 2 || field_length == 4);
int tmp= (int) ptr[0]; int tmp= (int) ptr[0];
if (field_length != 4) if (field_length != 4)
tmp%=100; // Return last 2 char tmp%=100; // Return last 2 char
...@@ -5479,6 +5480,7 @@ longlong Field_year::val_int(void) ...@@ -5479,6 +5480,7 @@ longlong Field_year::val_int(void)
String *Field_year::val_str(String *val_buffer, String *Field_year::val_str(String *val_buffer,
String *val_ptr __attribute__((unused))) String *val_ptr __attribute__((unused)))
{ {
DBUG_ASSERT(field_length < 5);
val_buffer->alloc(5); val_buffer->alloc(5);
val_buffer->length(field_length); val_buffer->length(field_length);
char *to=(char*) val_buffer->ptr(); char *to=(char*) val_buffer->ptr();
......
...@@ -612,17 +612,13 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref) ...@@ -612,17 +612,13 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
switch (hybrid_type= item->result_type()) { switch (hybrid_type= item->result_type()) {
case INT_RESULT: case INT_RESULT:
max_length= 20;
break;
case DECIMAL_RESULT: case DECIMAL_RESULT:
case STRING_RESULT:
max_length= item->max_length; max_length= item->max_length;
break; break;
case REAL_RESULT: case REAL_RESULT:
max_length= float_length(decimals); max_length= float_length(decimals);
break; break;
case STRING_RESULT:
max_length= item->max_length;
break;
case ROW_RESULT: case ROW_RESULT:
default: default:
DBUG_ASSERT(0); DBUG_ASSERT(0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment