Commit 052d1bfb authored by Michael Widenius's avatar Michael Widenius

Fixed all reported bugs for dynamic columns.

Bugs fixed:
- Added automatic detection of unsigned arguments to COLUMN_CREATE()
- If string length is not know for COLUMN_GET() use MAX_DYNAMIC_COLUMN_LENGTH instead of MAX_FIELD_BLOBLENGTH
- null_value flag was not propery reset for COLUMN_LIST() and COLUMN_CREATE() which could lead to crashes later:
- lp:778905 Assertion `value->year <= 9999' failed in dynamic_column_date_store
- lp:778912 Assertion `field_pos < field_count' failed in Protocol_text::store in maria-5.3-mwl34

include/ma_dyncol.h:
  Added define for max dynamic column length.
mysql-test/r/cast.result:
  Added test of cast big unsigned int to signed (this test case was missing)
mysql-test/r/dyncol.result:
  Added tests from reported bugs
  Added testing of automatic store of signed/unsigned integers
mysql-test/t/cast.test:
  Added test of cast big unsigned int to signed (this test case was missing)
mysql-test/t/dyncol.test:
  Added tests from reported bugs
  Added testing of automatic store of signed/unsigned integers
sql/item.cc:
  Added assert to catch cases where null_value is not set properly
sql/item_strfunc.cc:
  Added automatic detection of unsigned arguments to COLUMN_CREATE()
  COLUMN_GET() returned wrong value for illegal strings which lead to assert later
  null_value flag was not propery reset for COLUMN_LIST() and COLUMN_CREATE() which could lead to crashes later.
sql/item_strfunc.h:
  If string length is not know for COLUMN_GET() use MAX_DYNAMIC_COLUMN_LENGTH
parent 03483e7b
......@@ -33,6 +33,12 @@
#include <my_decimal_limits.h>
#include <mysql_time.h>
/*
Max length for data in a dynamic colums. This comes from how the
how the offset are stored.
*/
#define MAX_DYNAMIC_COLUMN_LENGTH 0X1FFFFFFFL
/* NO and OK is the same used just to show semantics */
#define ER_DYNCOL_NO ER_DYNCOL_OK
......
......@@ -33,6 +33,9 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select ~(5) AS `~5`,cast(~(5) as signed) AS `cast(~5 as signed)`
select cast(18446744073709551615 as signed);
cast(18446744073709551615 as signed)
-1
select cast(5 as unsigned) -6.0;
cast(5 as unsigned) -6.0
-1.0
......
......@@ -37,6 +37,12 @@ hex(COLUMN_CREATE(1, 128 AS unsigned int))
select hex(COLUMN_CREATE(1, 12.12 AS unsigned int));
hex(COLUMN_CREATE(1, 12.12 AS unsigned int))
0001000100010C
select hex(COLUMN_CREATE(1, ~0));
hex(COLUMN_CREATE(1, ~0))
000100010001FFFFFFFFFFFFFFFF
select hex(COLUMN_CREATE(1, -1));
hex(COLUMN_CREATE(1, -1))
00010001000001
select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS unsigned int));
hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS unsigned int))
000100010001FFFFFFFFFFFFFF7F
......@@ -323,6 +329,22 @@ column_get(column_create(1, "1212III" AS char), 1 as int)
1212
Warnings:
Warning 1659 Encountered illegal value '1212III' when converting to INT
select column_get(COLUMN_CREATE(1, ~0), 1 as signed);
column_get(COLUMN_CREATE(1, ~0), 1 as signed)
-1
Warnings:
Warning 1105 Cast to signed converted positive out-of-range integer to it's negative complement
select column_get(COLUMN_CREATE(1, ~0), 1 as unsigned);
column_get(COLUMN_CREATE(1, ~0), 1 as unsigned)
18446744073709551615
select column_get(COLUMN_CREATE(1, -1), 1 as signed);
column_get(COLUMN_CREATE(1, -1), 1 as signed)
-1
select column_get(COLUMN_CREATE(1, -1), 1 as unsigned);
column_get(COLUMN_CREATE(1, -1), 1 as unsigned)
18446744073709551615
Warnings:
Warning 1105 Cast to unsigned converted negative integer to it's positive complement
#
#column get char
#
......@@ -1185,3 +1207,24 @@ select id, column_list(str), length(str) from t1 where id=5;
id column_list(str) length(str)
5 1,2,4,10 34
drop table t1;
#
# LP#778905: Assertion `value->year <= 9999' failed in
# dynamic_column_date_store
#
SELECT COLUMN_GET( 'a' , 2 AS DATE );
ERROR HY000: Encountered illegal format of dynamic column string
SELECT COLUMN_CREATE( 1 , COLUMN_GET( 'a' , 2 AS DATE ) );
ERROR HY000: Encountered illegal format of dynamic column string
#
# LP#778912: Assertion `field_pos < field_count' failed in
# Protocol_text::store in maria-5.3-mwl34
#
CREATE TABLE t1 ( f1 blob );
INSERT INTO t1 VALUES (NULL);
INSERT INTO t1 SET f1 = COLUMN_CREATE( 2 , 'cde' );
SELECT HEX(COLUMN_ADD(f1, 1, 'abc')), COLUMN_LIST(f1) FROM t1;
HEX(COLUMN_ADD(f1, 1, 'abc')) COLUMN_LIST(f1)
NULL NULL
0002000100030200230861626308636465 2
SELECT COLUMN_ADD(f1, 1, 'abc'), COLUMN_LIST(f1) FROM t1;
DROP TABLE t1;
......@@ -9,6 +9,7 @@ select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
select ~5, cast(~5 as signed);
explain extended select ~5, cast(~5 as signed);
select cast(18446744073709551615 as signed);
select cast(5 as unsigned) -6.0;
select cast(NULL as signed), cast(1/0 as signed);
select cast(1 as double(5,2));
......
......@@ -17,6 +17,8 @@ select hex(COLUMN_CREATE(1, 8 AS unsigned int));
select hex(COLUMN_CREATE(1, 127 AS unsigned int));
select hex(COLUMN_CREATE(1, 128 AS unsigned int));
select hex(COLUMN_CREATE(1, 12.12 AS unsigned int));
select hex(COLUMN_CREATE(1, ~0));
select hex(COLUMN_CREATE(1, -1));
select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS unsigned int));
select hex(COLUMN_CREATE(1, NULL AS int));
select hex(COLUMN_CREATE(1, 1212 AS int));
......@@ -116,6 +118,10 @@ select column_get(column_create(1, 999.9 AS double), 1 as int);
select column_get(column_create(1, -99999999999999999999999999999 AS double), 1 as int);
select column_get(column_create(1, "-1212III" AS char), 1 as int);
select column_get(column_create(1, "1212III" AS char), 1 as int);
select column_get(COLUMN_CREATE(1, ~0), 1 as signed);
select column_get(COLUMN_CREATE(1, ~0), 1 as unsigned);
select column_get(COLUMN_CREATE(1, -1), 1 as signed);
select column_get(COLUMN_CREATE(1, -1), 1 as unsigned);
--echo #
--echo #column get char
......@@ -460,3 +466,29 @@ update t1 set str=column_delete(str, 5) where id=5;
select id, column_list(str), length(str) from t1 where id=5;
drop table t1;
--echo #
--echo # LP#778905: Assertion `value->year <= 9999' failed in
--echo # dynamic_column_date_store
--echo #
--error ER_DYN_COL_WRONG_FORMAT
SELECT COLUMN_GET( 'a' , 2 AS DATE );
--error ER_DYN_COL_WRONG_FORMAT
SELECT COLUMN_CREATE( 1 , COLUMN_GET( 'a' , 2 AS DATE ) );
--echo #
--echo # LP#778912: Assertion `field_pos < field_count' failed in
--echo # Protocol_text::store in maria-5.3-mwl34
--echo #
CREATE TABLE t1 ( f1 blob );
INSERT INTO t1 VALUES (NULL);
INSERT INTO t1 SET f1 = COLUMN_CREATE( 2 , 'cde' );
SELECT HEX(COLUMN_ADD(f1, 1, 'abc')), COLUMN_LIST(f1) FROM t1;
# Don't print strange characters on screen
--disable_result_log
SELECT COLUMN_ADD(f1, 1, 'abc'), COLUMN_LIST(f1) FROM t1;
--enable_result_log
DROP TABLE t1;
......@@ -5781,7 +5781,10 @@ bool Item::send(Protocol *protocol, String *buffer)
{
String *res;
if ((res=val_str(buffer)))
{
DBUG_ASSERT(!null_value);
result= protocol->store(res->ptr(),res->length(),res->charset());
}
else
{
DBUG_ASSERT(null_value);
......
......@@ -3511,7 +3511,7 @@ void Item_func_dyncol_create::prepare_arguments()
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_BIT:
type= DYN_COL_INT;
type= args[valpos]->unsigned_flag ? DYN_COL_UINT : DYN_COL_INT;
break;
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
......@@ -3653,6 +3653,7 @@ String *Item_func_dyncol_create::val_str(String *str)
str_value.reassociate(ptr, (uint32) length, (uint32) alloc_length,
&my_charset_bin);
res= &str_value;
null_value= FALSE;
}
/* cleanup */
......@@ -3756,6 +3757,7 @@ String *Item_func_dyncol_add::val_str(String *str)
dynamic_column_reassociate(&col, &ptr, &length, &alloc_length);
str->reassociate(ptr, (uint32) length, (uint32) alloc_length,
&my_charset_bin);
null_value= FALSE;
}
/* cleanup */
......@@ -3781,6 +3783,14 @@ void Item_func_dyncol_add::print(String *str,
str->append(')');
}
/**
Get value for a column stored in a dynamic column
@notes
This function ensures that null_value is set correctly
*/
bool Item_dyncol_get::get_dyn_value(DYNAMIC_COLUMN_VALUE *val, String *tmp)
{
DYNAMIC_COLUMN dyn_str;
......@@ -4104,7 +4114,7 @@ bool Item_dyncol_get::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
bool signed_value= 0;
if (get_dyn_value(&val, &tmp))
return 0;
return 1; // Error
switch (val.type) {
case DYN_COL_NULL:
......@@ -4208,6 +4218,7 @@ String *Item_func_dyncol_list::val_str(String *str)
str->qs_append(',');
}
null_value= FALSE;
delete_dynamic(&arr);
return str;
......
......@@ -913,7 +913,7 @@ class Item_dyncol_get: public Item_str_func
Item_dyncol_get(Item *str, Item *num)
:Item_str_func(str, num)
{
max_length= MAX_FIELD_BLOBLENGTH;
max_length= MAX_DYNAMIC_COLUMN_LENGTH;
}
void fix_length_and_dec()
{ maybe_null= 1; }
......
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