Commit 325b8835 authored by kostja@bodhi.(none)'s avatar kostja@bodhi.(none)

Merge bk-internal.mysql.com:/home/bk/mysql-5.0

into  bodhi.(none):/opt/local/work/mysql-5.0-runtime
parents 7eea7fff 4b427bde
...@@ -145,11 +145,11 @@ select @@optimizer_prune_level; ...@@ -145,11 +145,11 @@ select @@optimizer_prune_level;
# #
# These are the values for the parameters that control the greedy optimizer # These are the values for the parameters that control the greedy optimizer
# (total 6 combinations - 3 for optimizer_search_depth, 2 for optimizer_prune_level): # (total 6 combinations - 3 for optimizer_search_depth, 2 for optimizer_prune_level):
-- # 3:
# set optimizer_search_depth=0; - automatic # set optimizer_search_depth=0; - automatic
# set optimizer_search_depth=1; - min # set optimizer_search_depth=1; - min
# set optimizer_search_depth=62; - max (default) # set optimizer_search_depth=62; - max (default)
-- # 2:
# set optimizer_prune_level=0 - exhaustive; # set optimizer_prune_level=0 - exhaustive;
# set optimizer_prune_level=1 - heuristic; # default # set optimizer_prune_level=1 - heuristic; # default
......
...@@ -512,10 +512,12 @@ select * from v1a join (t3 natural join t4) on a = y; ...@@ -512,10 +512,12 @@ select * from v1a join (t3 natural join t4) on a = y;
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# Negative tests (tests for errors) # Negative tests (tests for errors)
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# works in Oracle - bug
-- error 1052 -- error 1052
select * from t1 natural join (t3 cross join t4); -- works in Oracle - bug select * from t1 natural join (t3 cross join t4);
# works in Oracle - bug
-- error 1052 -- error 1052
select * from (t3 cross join t4) natural join t1; -- works in Oracle - bug select * from (t3 cross join t4) natural join t1;
-- error 1052 -- error 1052
select * from t1 join (t2, t3) using (b); select * from t1 join (t2, t3) using (b);
-- error 1052 -- error 1052
......
...@@ -50,7 +50,7 @@ update t1 set c = 13 where b <= 3; ...@@ -50,7 +50,7 @@ update t1 set c = 13 where b <= 3;
select * from t1 order by a; select * from t1 order by a;
update t1 set b = b + 1 where b > 4 and b < 7; update t1 set b = b + 1 where b > 4 and b < 7;
select * from t1 order by a; select * from t1 order by a;
-- Update primary key # Update primary key
update t1 set a = a + 10 where b > 1 and b < 7; update t1 set a = a + 10 where b > 1 and b < 7;
select * from t1 order by a; select * from t1 order by a;
......
...@@ -4254,7 +4254,7 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, ...@@ -4254,7 +4254,7 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg,
const char *field_name_arg, const char *field_name_arg,
struct st_table *table_arg, struct st_table *table_arg,
CHARSET_INFO *cs) CHARSET_INFO *cs)
:Field_str(ptr_arg, 19, null_ptr_arg, null_bit_arg, :Field_str(ptr_arg, MAX_DATETIME_WIDTH, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg, cs) unireg_check_arg, field_name_arg, table_arg, cs)
{ {
/* For 4.0 MYD and 4.0 InnoDB compatibility */ /* For 4.0 MYD and 4.0 InnoDB compatibility */
...@@ -4272,7 +4272,8 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, ...@@ -4272,7 +4272,8 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg,
Field_timestamp::Field_timestamp(bool maybe_null_arg, Field_timestamp::Field_timestamp(bool maybe_null_arg,
const char *field_name_arg, const char *field_name_arg,
struct st_table *table_arg, CHARSET_INFO *cs) struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str((char*) 0, 19, maybe_null_arg ? (uchar*) "": 0, 0, :Field_str((char*) 0, MAX_DATETIME_WIDTH,
maybe_null_arg ? (uchar*) "": 0, 0,
NONE, field_name_arg, table_arg, cs) NONE, field_name_arg, table_arg, cs)
{ {
/* For 4.0 MYD and 4.0 InnoDB compatibility */ /* For 4.0 MYD and 4.0 InnoDB compatibility */
...@@ -4803,7 +4804,7 @@ String *Field_time::val_str(String *val_buffer, ...@@ -4803,7 +4804,7 @@ String *Field_time::val_str(String *val_buffer,
String *val_ptr __attribute__((unused))) String *val_ptr __attribute__((unused)))
{ {
MYSQL_TIME ltime; MYSQL_TIME ltime;
val_buffer->alloc(19); val_buffer->alloc(MAX_DATE_STRING_REP_LENGTH);
long tmp=(long) sint3korr(ptr); long tmp=(long) sint3korr(ptr);
ltime.neg= 0; ltime.neg= 0;
if (tmp < 0) if (tmp < 0)
...@@ -5339,7 +5340,7 @@ int Field_newdate::store_time(MYSQL_TIME *ltime, timestamp_type time_type) ...@@ -5339,7 +5340,7 @@ int Field_newdate::store_time(MYSQL_TIME *ltime, timestamp_type time_type)
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
MODE_INVALID_DATES))), &error)) MODE_INVALID_DATES))), &error))
{ {
char buff[12]; char buff[MAX_DATE_STRING_REP_LENGTH];
String str(buff, sizeof(buff), &my_charset_latin1); String str(buff, sizeof(buff), &my_charset_latin1);
make_date((DATE_TIME_FORMAT *) 0, ltime, &str); make_date((DATE_TIME_FORMAT *) 0, ltime, &str);
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
...@@ -5564,7 +5565,7 @@ int Field_datetime::store_time(MYSQL_TIME *ltime,timestamp_type time_type) ...@@ -5564,7 +5565,7 @@ int Field_datetime::store_time(MYSQL_TIME *ltime,timestamp_type time_type)
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
MODE_INVALID_DATES))), &error)) MODE_INVALID_DATES))), &error))
{ {
char buff[19]; char buff[MAX_DATE_STRING_REP_LENGTH];
String str(buff, sizeof(buff), &my_charset_latin1); String str(buff, sizeof(buff), &my_charset_latin1);
make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str); make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str);
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
...@@ -5638,7 +5639,7 @@ String *Field_datetime::val_str(String *val_buffer, ...@@ -5638,7 +5639,7 @@ String *Field_datetime::val_str(String *val_buffer,
part1=(long) (tmp/LL(1000000)); part1=(long) (tmp/LL(1000000));
part2=(long) (tmp - (ulonglong) part1*LL(1000000)); part2=(long) (tmp - (ulonglong) part1*LL(1000000));
pos=(char*) val_buffer->ptr()+19; pos= (char*) val_buffer->ptr() + MAX_DATETIME_WIDTH;
*pos--=0; *pos--=0;
*pos--= (char) ('0'+(char) (part2%10)); part2/=10; *pos--= (char) ('0'+(char) (part2%10)); part2/=10;
*pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10); *pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10);
...@@ -8537,15 +8538,18 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, ...@@ -8537,15 +8538,18 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
break; break;
case FIELD_TYPE_TIMESTAMP: case FIELD_TYPE_TIMESTAMP:
if (!fld_length) if (!fld_length)
length= 14; /* Full date YYYYMMDDHHMMSS */ {
else if (length != 19) /* Compressed date YYYYMMDDHHMMSS */
length= MAX_DATETIME_COMPRESSED_WIDTH;
}
else if (length != MAX_DATETIME_WIDTH)
{ {
/* /*
We support only even TIMESTAMP lengths less or equal than 14 We support only even TIMESTAMP lengths less or equal than 14
and 19 as length of 4.1 compatible representation. and 19 as length of 4.1 compatible representation.
*/ */
length= ((length+1)/2)*2; /* purecov: inspected */ length= ((length+1)/2)*2; /* purecov: inspected */
length= min(length,14); /* purecov: inspected */ length= min(length, MAX_DATETIME_COMPRESSED_WIDTH); /* purecov: inspected */
} }
flags|= ZEROFILL_FLAG | UNSIGNED_FLAG; flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
if (fld_default_value) if (fld_default_value)
...@@ -8598,7 +8602,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, ...@@ -8598,7 +8602,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
length= 10; length= 10;
break; break;
case FIELD_TYPE_DATETIME: case FIELD_TYPE_DATETIME:
length= 19; length= MAX_DATETIME_WIDTH;
break; break;
case FIELD_TYPE_SET: case FIELD_TYPE_SET:
{ {
......
...@@ -51,7 +51,7 @@ static bool make_datetime(date_time_format_types format, MYSQL_TIME *ltime, ...@@ -51,7 +51,7 @@ static bool make_datetime(date_time_format_types format, MYSQL_TIME *ltime,
{ {
char *buff; char *buff;
CHARSET_INFO *cs= &my_charset_bin; CHARSET_INFO *cs= &my_charset_bin;
uint length= 30; uint length= MAX_DATE_STRING_REP_LENGTH;
if (str->alloc(length)) if (str->alloc(length))
return 1; return 1;
...@@ -1400,7 +1400,7 @@ String *Item_date::val_str(String *str) ...@@ -1400,7 +1400,7 @@ String *Item_date::val_str(String *str)
MYSQL_TIME ltime; MYSQL_TIME ltime;
if (get_date(&ltime, TIME_FUZZY_DATE)) if (get_date(&ltime, TIME_FUZZY_DATE))
return (String *) 0; return (String *) 0;
if (str->alloc(11)) if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
{ {
null_value= 1; null_value= 1;
return (String *) 0; return (String *) 0;
...@@ -1449,7 +1449,7 @@ void Item_func_curdate::fix_length_and_dec() ...@@ -1449,7 +1449,7 @@ void Item_func_curdate::fix_length_and_dec()
String *Item_func_curdate::val_str(String *str) String *Item_func_curdate::val_str(String *str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
if (str->alloc(11)) if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
{ {
null_value= 1; null_value= 1;
return (String *) 0; return (String *) 0;
...@@ -1678,7 +1678,8 @@ String *Item_func_sec_to_time::val_str(String *str) ...@@ -1678,7 +1678,8 @@ String *Item_func_sec_to_time::val_str(String *str)
MYSQL_TIME ltime; MYSQL_TIME ltime;
longlong arg_val= args[0]->val_int(); longlong arg_val= args[0]->val_int();
if ((null_value=args[0]->null_value) || str->alloc(19)) if ((null_value=args[0]->null_value) ||
str->alloc(MAX_DATE_STRING_REP_LENGTH))
{ {
null_value= 1; null_value= 1;
return (String*) 0; return (String*) 0;
...@@ -1863,6 +1864,10 @@ String *Item_func_date_format::val_str(String *str) ...@@ -1863,6 +1864,10 @@ String *Item_func_date_format::val_str(String *str)
size=max_length; size=max_length;
else else
size=format_length(format); size=format_length(format);
if (size < MAX_DATE_STRING_REP_LENGTH)
size= MAX_DATE_STRING_REP_LENGTH;
if (format == str) if (format == str)
str= &value; // Save result here str= &value; // Save result here
if (str->alloc(size)) if (str->alloc(size))
...@@ -1906,13 +1911,14 @@ String *Item_func_from_unixtime::val_str(String *str) ...@@ -1906,13 +1911,14 @@ String *Item_func_from_unixtime::val_str(String *str)
if (get_date(&time_tmp, 0)) if (get_date(&time_tmp, 0))
return 0; return 0;
if (str->alloc(20*MY_CHARSET_BIN_MB_MAXLEN)) if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
{ {
null_value= 1; null_value= 1;
return 0; return 0;
} }
make_datetime((DATE_TIME_FORMAT *) 0, &time_tmp, str); make_datetime((DATE_TIME_FORMAT *) 0, &time_tmp, str);
return str; return str;
} }
...@@ -1974,14 +1980,15 @@ String *Item_func_convert_tz::val_str(String *str) ...@@ -1974,14 +1980,15 @@ String *Item_func_convert_tz::val_str(String *str)
if (get_date(&time_tmp, 0)) if (get_date(&time_tmp, 0))
return 0; return 0;
if (str->alloc(20*MY_CHARSET_BIN_MB_MAXLEN)) if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
{ {
null_value= 1; null_value= 1;
return 0; return 0;
} }
make_datetime((DATE_TIME_FORMAT *) 0, &time_tmp, str); make_datetime((DATE_TIME_FORMAT *) 0, &time_tmp, str);
return str; return str;
} }
...@@ -2561,6 +2568,7 @@ String *Item_datetime_typecast::val_str(String *str) ...@@ -2561,6 +2568,7 @@ String *Item_datetime_typecast::val_str(String *str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
MYSQL_TIME ltime; MYSQL_TIME ltime;
if (!get_arg0_date(&ltime, TIME_FUZZY_DATE) && if (!get_arg0_date(&ltime, TIME_FUZZY_DATE) &&
!make_datetime(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME, !make_datetime(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME,
&ltime, str)) &ltime, str))
...@@ -2639,7 +2647,8 @@ String *Item_date_typecast::val_str(String *str) ...@@ -2639,7 +2647,8 @@ String *Item_date_typecast::val_str(String *str)
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
MYSQL_TIME ltime; MYSQL_TIME ltime;
if (!get_arg0_date(&ltime, TIME_FUZZY_DATE) && !str->alloc(11)) if (!get_arg0_date(&ltime, TIME_FUZZY_DATE) &&
!str->alloc(MAX_DATE_STRING_REP_LENGTH))
{ {
make_date((DATE_TIME_FORMAT *) 0, &ltime, str); make_date((DATE_TIME_FORMAT *) 0, &ltime, str);
return str; return str;
...@@ -2692,7 +2701,7 @@ String *Item_func_makedate::val_str(String *str) ...@@ -2692,7 +2701,7 @@ String *Item_func_makedate::val_str(String *str)
{ {
null_value=0; null_value=0;
get_date_from_daynr(days,&l_time.year,&l_time.month,&l_time.day); get_date_from_daynr(days,&l_time.year,&l_time.month,&l_time.day);
if (str->alloc(11)) if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
goto err; goto err;
make_date((DATE_TIME_FORMAT *) 0, &l_time, str); make_date((DATE_TIME_FORMAT *) 0, &l_time, str);
return str; return str;
...@@ -2828,6 +2837,7 @@ String *Item_func_add_time::val_str(String *str) ...@@ -2828,6 +2837,7 @@ String *Item_func_add_time::val_str(String *str)
days= (long)(seconds/86400L); days= (long)(seconds/86400L);
calc_time_from_sec(&l_time3, (long)(seconds%86400L), microseconds); calc_time_from_sec(&l_time3, (long)(seconds%86400L), microseconds);
if (!is_time) if (!is_time)
{ {
get_date_from_daynr(days,&l_time3.year,&l_time3.month,&l_time3.day); get_date_from_daynr(days,&l_time3.year,&l_time3.month,&l_time3.day);
...@@ -2943,7 +2953,7 @@ String *Item_func_maketime::val_str(String *str) ...@@ -2943,7 +2953,7 @@ String *Item_func_maketime::val_str(String *str)
args[2]->null_value || args[2]->null_value ||
minute < 0 || minute > 59 || minute < 0 || minute > 59 ||
second < 0 || second > 59 || second < 0 || second > 59 ||
str->alloc(19)))) str->alloc(MAX_DATE_STRING_REP_LENGTH))))
return 0; return 0;
bzero((char *)&ltime, sizeof(ltime)); bzero((char *)&ltime, sizeof(ltime));
......
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
#define MAX_TIME_WIDTH 23 /* -DDDDDD HH:MM:SS.###### */ #define MAX_TIME_WIDTH 23 /* -DDDDDD HH:MM:SS.###### */
#define MAX_DATETIME_FULL_WIDTH 29 /* YYYY-MM-DD HH:MM:SS.###### AM */ #define MAX_DATETIME_FULL_WIDTH 29 /* YYYY-MM-DD HH:MM:SS.###### AM */
#define MAX_DATETIME_WIDTH 19 /* YYYY-MM-DD HH:MM:SS */ #define MAX_DATETIME_WIDTH 19 /* YYYY-MM-DD HH:MM:SS */
#define MAX_DATETIME_COMPRESSED_WIDTH 14 /* YYYYMMDDHHMMSS */
#define MAX_TABLES (sizeof(table_map)*8-3) /* Max tables in join */ #define MAX_TABLES (sizeof(table_map)*8-3) /* Max tables in join */
#define PARAM_TABLE_BIT (((table_map) 1) << (sizeof(table_map)*8-3)) #define PARAM_TABLE_BIT (((table_map) 1) << (sizeof(table_map)*8-3))
......
...@@ -15680,6 +15680,59 @@ static void test_bug28934() ...@@ -15680,6 +15680,59 @@ static void test_bug28934()
} }
/*
Bug#27592 (stack overrun when storing datetime value using prepared statements)
*/
static void test_bug27592()
{
const int NUM_ITERATIONS= 40;
int i;
int rc;
MYSQL_STMT *stmt= NULL;
MYSQL_BIND bind[1];
MYSQL_TIME time_val;
DBUG_ENTER("test_bug27592");
myheader("test_bug27592");
mysql_query(mysql, "DROP TABLE IF EXISTS t1");
mysql_query(mysql, "CREATE TABLE t1(c2 DATETIME)");
stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES (?)");
DIE_UNLESS(stmt);
memset(bind, 0, sizeof(bind));
bind[0].buffer_type= MYSQL_TYPE_DATETIME;
bind[0].buffer= (char *) &time_val;
bind[0].length= NULL;
for (i= 0; i < NUM_ITERATIONS; i++)
{
time_val.year= 2007;
time_val.month= 6;
time_val.day= 7;
time_val.hour= 18;
time_val.minute= 41;
time_val.second= 3;
time_val.second_part=0;
time_val.neg=0;
rc= mysql_stmt_bind_param(stmt, bind);
check_execute(stmt, rc);
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
}
mysql_stmt_close(stmt);
DBUG_VOID_RETURN;
}
/* /*
Read and parse arguments and MySQL options from my.cnf Read and parse arguments and MySQL options from my.cnf
*/ */
...@@ -15963,6 +16016,7 @@ static struct my_tests_st my_tests[]= { ...@@ -15963,6 +16016,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug27876", test_bug27876 }, { "test_bug27876", test_bug27876 },
{ "test_bug28505", test_bug28505 }, { "test_bug28505", test_bug28505 },
{ "test_bug28934", test_bug28934 }, { "test_bug28934", test_bug28934 },
{ "test_bug27592", test_bug27592 },
{ 0, 0 } { 0, 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