Commit 046e489b authored by malff/marcsql@weblab.(none)'s avatar malff/marcsql@weblab.(none)
Browse files

Merge weblab.(none):/home/marcsql/TREE/mysql-5.0-base

into  weblab.(none):/home/marcsql/TREE/mysql-5.0-rt-merge
parents d870247d 8725f457
Loading
Loading
Loading
Loading
+14 −10
Original line number Diff line number Diff line
@@ -4254,7 +4254,7 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg,
				 const char *field_name_arg,
				 struct st_table *table_arg,
				 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)
{
  /* For 4.0 MYD and 4.0 InnoDB compatibility */
@@ -4272,7 +4272,8 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg,
Field_timestamp::Field_timestamp(bool maybe_null_arg,
                                 const char *field_name_arg,
                                 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)
{
  /* For 4.0 MYD and 4.0 InnoDB compatibility */
@@ -4803,7 +4804,7 @@ String *Field_time::val_str(String *val_buffer,
			    String *val_ptr __attribute__((unused)))
{
  MYSQL_TIME ltime;
  val_buffer->alloc(19);
  val_buffer->alloc(MAX_DATE_STRING_REP_LENGTH);
  long tmp=(long) sint3korr(ptr);
  ltime.neg= 0;
  if (tmp < 0)
@@ -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_INVALID_DATES))), &error))
    {
      char buff[12];
      char buff[MAX_DATE_STRING_REP_LENGTH];
      String str(buff, sizeof(buff), &my_charset_latin1);
      make_date((DATE_TIME_FORMAT *) 0, ltime, &str);
      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)
                     (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
                      MODE_INVALID_DATES))), &error))
    {
      char buff[19];
      char buff[MAX_DATE_STRING_REP_LENGTH];
      String str(buff, sizeof(buff), &my_charset_latin1);
      make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str);
      set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
@@ -5638,7 +5639,7 @@ String *Field_datetime::val_str(String *val_buffer,
  part1=(long) (tmp/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--= (char) ('0'+(char) (part2%10)); part2/=10;
  *pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10);
@@ -8536,15 +8537,18 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
    break;
  case FIELD_TYPE_TIMESTAMP:
    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
        and 19 as length of 4.1 compatible representation.
      */
      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;
    if (fld_default_value)
@@ -8597,7 +8601,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
    length= 10;
    break;
  case FIELD_TYPE_DATETIME:
    length= 19;
    length= MAX_DATETIME_WIDTH;
    break;
  case FIELD_TYPE_SET:
    {
+21 −11
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ static bool make_datetime(date_time_format_types format, MYSQL_TIME *ltime,
{
  char *buff;
  CHARSET_INFO *cs= &my_charset_bin;
  uint length= 30;
  uint length= MAX_DATE_STRING_REP_LENGTH;

  if (str->alloc(length))
    return 1;
@@ -1400,7 +1400,7 @@ String *Item_date::val_str(String *str)
  MYSQL_TIME ltime;
  if (get_date(&ltime, TIME_FUZZY_DATE))
    return (String *) 0;
  if (str->alloc(11))
  if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
  {
    null_value= 1;
    return (String *) 0;
@@ -1449,7 +1449,7 @@ void Item_func_curdate::fix_length_and_dec()
String *Item_func_curdate::val_str(String *str)
{
  DBUG_ASSERT(fixed == 1);
  if (str->alloc(11))
  if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
  {
    null_value= 1;
    return (String *) 0;
@@ -1678,7 +1678,8 @@ String *Item_func_sec_to_time::val_str(String *str)
  MYSQL_TIME ltime;
  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;
    return (String*) 0;
@@ -1863,6 +1864,10 @@ String *Item_func_date_format::val_str(String *str)
    size=max_length;
  else
    size=format_length(format);

  if (size < MAX_DATE_STRING_REP_LENGTH)
    size= MAX_DATE_STRING_REP_LENGTH;

  if (format == str)
    str= &value;				// Save result here
  if (str->alloc(size))
@@ -1906,13 +1911,14 @@ String *Item_func_from_unixtime::val_str(String *str)
  if (get_date(&time_tmp, 0))
    return 0;

  if (str->alloc(20*MY_CHARSET_BIN_MB_MAXLEN))
  if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
  {
    null_value= 1;
    return 0;
  }

  make_datetime((DATE_TIME_FORMAT *) 0, &time_tmp, str);

  return str;
}

@@ -1975,13 +1981,14 @@ String *Item_func_convert_tz::val_str(String *str)
  if (get_date(&time_tmp, 0))
    return 0;

  if (str->alloc(20*MY_CHARSET_BIN_MB_MAXLEN))
  if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
  {
    null_value= 1;
    return 0;
  }

  make_datetime((DATE_TIME_FORMAT *) 0, &time_tmp, str);

  return str;
}

@@ -2561,6 +2568,7 @@ String *Item_datetime_typecast::val_str(String *str)
{
  DBUG_ASSERT(fixed == 1);
  MYSQL_TIME ltime;

  if (!get_arg0_date(&ltime, TIME_FUZZY_DATE) &&
      !make_datetime(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME, 
		     &ltime, str))
@@ -2639,7 +2647,8 @@ String *Item_date_typecast::val_str(String *str)
  DBUG_ASSERT(fixed == 1);
  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);
    return str;
@@ -2692,7 +2701,7 @@ String *Item_func_makedate::val_str(String *str)
  {
    null_value=0;
    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;
    make_date((DATE_TIME_FORMAT *) 0, &l_time, str);
    return str;
@@ -2828,6 +2837,7 @@ String *Item_func_add_time::val_str(String *str)
  days= (long)(seconds/86400L);

  calc_time_from_sec(&l_time3, (long)(seconds%86400L), microseconds);

  if (!is_time)
  {
    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)
                   args[2]->null_value ||
                   minute < 0 || minute > 59 ||
                   second < 0 || second > 59 ||
                   str->alloc(19))))
                   str->alloc(MAX_DATE_STRING_REP_LENGTH))))
    return 0;

  bzero((char *)&ltime, sizeof(ltime));
+1 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@
#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_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 PARAM_TABLE_BIT	(((table_map) 1) << (sizeof(table_map)*8-3))
+54 −0
Original line number Diff line number Diff line
@@ -15623,6 +15623,59 @@ static void test_bug27876()
}


/*
  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
*/
@@ -15904,6 +15957,7 @@ static struct my_tests_st my_tests[]= {
  { "test_bug21635", test_bug21635 },
  { "test_bug24179", test_bug24179 },
  { "test_bug27876", test_bug27876 },
  { "test_bug27592", test_bug27592 },
  { 0, 0 }
};