List:Internals« Previous MessageNext Message »
From:gluh Date:July 8 2003 10:06am
Subject:bk commit into 4.1 tree (1.1558)
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of gluh. When gluh does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://www.mysql.com/doc/I/n/Installing_source_tree.html

ChangeSet
  1.1558 03/07/08 15:06:05 gluh@stripped +12 -0
  SAPDB date/time finctions

  sql/time.cc
    1.32 03/07/08 15:06:03 gluh@stripped +1 -0
    SAPDB date/time finctions

  sql/sql_yacc.yy
    1.255 03/07/08 15:06:03 gluh@stripped +6 -3
    SAPDB date/time finctions

  sql/sql_string.h
    1.37 03/07/08 15:06:03 gluh@stripped +2 -0
    SAPDB date/time finctions

  sql/sql_string.cc
    1.63 03/07/08 15:06:03 gluh@stripped +17 -0
    SAPDB date/time finctions

  sql/protocol.cc
    1.65 03/07/08 15:06:03 gluh@stripped +13 -0
    SAPDB date/time finctions

  sql/mysql_priv.h
    1.204 03/07/08 15:06:03 gluh@stripped +2 -0
    SAPDB date/time finctions

  sql/item_timefunc.h
    1.32 03/07/08 15:06:03 gluh@stripped +18 -64
    SAPDB date/time finctions

  sql/item_timefunc.cc
    1.37 03/07/08 15:06:03 gluh@stripped +162 -160
    SAPDB date/time finctions

  sql/item_create.cc
    1.46 03/07/08 15:06:03 gluh@stripped +2 -2
    SAPDB date/time finctions

  mysql-test/t/func_sapdb.test
    1.2 03/07/08 15:06:03 gluh@stripped +4 -2
    SAPDB date/time finctions

  mysql-test/r/func_sapdb.result
    1.2 03/07/08 15:06:03 gluh@stripped +9 -3
    SAPDB date/time finctions

  mysql-test/r/cast.result
    1.8 03/07/08 15:06:03 gluh@stripped +2 -2
    Changes for SAPDB date/time finctions

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	gluh
# Host:	gluh.mysql.r18.ru
# Root:	/home/gluh/mysql-4.1.DTFUNC

--- 1.45/sql/item_create.cc	Tue Jul  8 12:56:56 2003
+++ 1.46/sql/item_create.cc	Tue Jul  8 15:06:03 2003
@@ -709,12 +709,12 @@
 
 Item *create_func_addtime(Item* a,Item* b)
 {
-  return new Item_func_add_time(a, b, 0);
+  return new Item_func_add_time(a, b, 0, 0);
 }
 
 Item *create_func_subtime(Item* a,Item* b)
 {
-  return new Item_func_add_time(a, b, 1);
+  return new Item_func_add_time(a, b, 0, 1);
 }
 
 Item *create_func_timediff(Item* a,Item* b)

--- 1.36/sql/item_timefunc.cc	Mon Jun 23 12:56:31 2003
+++ 1.37/sql/item_timefunc.cc	Tue Jul  8 15:06:03 2003
@@ -29,6 +29,8 @@
 ** Todo: Move month and days to language files
 */
 
+#define MAX_DAY_NUMBER 3652424L
+
 static String month_names[] = 
 { 
   String("January",	&my_charset_latin1), 
@@ -55,10 +57,14 @@
   String("Sunday",	&my_charset_latin1)
 };
 
-enum date_time_format_types { TIME_ONLY= 0, TIME_MICROSECOND,
-			      DATE_ONLY, DATE_TIME, DATE_TIME_MICROSECOND};
+enum date_time_format_types 
+{ 
+  TIME_ONLY= 0, TIME_MICROSECOND,
+  DATE_ONLY, DATE_TIME, DATE_TIME_MICROSECOND
+};
 
-typedef struct date_time_format {
+typedef struct date_time_format 
+{
   const char* format_str;
   uint length;
 };
@@ -73,6 +79,14 @@
 };
 
 
+/*
+  OPTIMIZATION TODO:
+   - Replace the switch with a function that should be called for each
+     date type.
+   - Remove sprintf and opencode the conversion, like we do in
+     Field_datetime.
+*/
+
 String *make_datetime(String *str, TIME *ltime, 
 		      enum date_time_format_types format)
 {
@@ -898,8 +912,8 @@
 	  null_value=1;
 	  return 0;
 	}
-	length= my_sprintf(intbuff, (intbuff,"%d",l_time.day));
-	str->append(intbuff, length);
+	length= int10_to_str(l_time.day, intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 1, '0');
 	if (l_time.day >= 10 &&  l_time.day <= 19)
 	  str->append("th");
 	else
@@ -921,45 +935,45 @@
 	}
 	break;
       case 'Y':
-	sprintf(intbuff,"%04d",l_time.year);
-	str->append(intbuff,4);
+	length= int10_to_str(l_time.year, intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 4, '0');
 	break;
       case 'y':
-	sprintf(intbuff,"%02d",l_time.year%100);
-	str->append(intbuff,2);
+	length= int10_to_str(l_time.year%100, intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 2, '0');
 	break;
       case 'm':
-	sprintf(intbuff,"%02d",l_time.month);
-	str->append(intbuff,2);
+	length= int10_to_str(l_time.month, intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 2, '0');
 	break;
       case 'c':
-	sprintf(intbuff,"%d",l_time.month);
-	str->append(intbuff);
+	length= int10_to_str(l_time.month, intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 1, '0');
 	break;
       case 'd':
-	sprintf(intbuff,"%02d",l_time.day);
-	str->append(intbuff,2);
+	length= int10_to_str(l_time.day, intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 2, '0');
 	break;
       case 'e':
-	sprintf(intbuff,"%d",l_time.day);
-	str->append(intbuff);
+	length= int10_to_str(l_time.day, intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 1, '0');
 	break;
       case 'f':
-	sprintf(intbuff,"%06ld",l_time.second_part);
-	str->append(intbuff);
+	length= int10_to_str(l_time.second_part, intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 6, '0');
 	break;
       case 'H':
-	sprintf(intbuff,"%02d",l_time.hour);
-	str->append(intbuff,2);
+	length= int10_to_str(l_time.hour, intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 2, '0');
 	break;
       case 'h':
       case 'I':
-	sprintf(intbuff,"%02d", (l_time.hour+11)%12+1);
-	str->append(intbuff,2);
+	length= int10_to_str((l_time.hour+11)%12+1, intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 2, '0');
 	break;
       case 'i':					/* minutes */
-	sprintf(intbuff,"%02d",l_time.minute);
-	str->append(intbuff,2);
+	length= int10_to_str(l_time.minute, intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 2, '0');
 	break;
       case 'j':
 	if (date_or_time)
@@ -967,52 +981,60 @@
 	  null_value=1;
 	  return 0;
 	}
-	sprintf(intbuff,"%03d",
-		(int) (calc_daynr(l_time.year,l_time.month,l_time.day) -
-		       calc_daynr(l_time.year,1,1)) + 1);
-	str->append(intbuff,3);
+	length= int10_to_str(calc_daynr(l_time.year,l_time.month,l_time.day) - 
+		     calc_daynr(l_time.year,1,1) + 1, intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 3, '0');
 	break;
       case 'k':
-	sprintf(intbuff,"%d",l_time.hour);
-	str->append(intbuff);
+	length= int10_to_str(l_time.hour, intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 1, '0');
 	break;
       case 'l':
-	sprintf(intbuff,"%d", (l_time.hour+11)%12+1);
-	str->append(intbuff);
+	length= int10_to_str((l_time.hour+11)%12+1, intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 1, '0');
 	break;
       case 'p':
 	str->append(l_time.hour < 12 ? "AM" : "PM",2);
 	break;
       case 'r':
-	sprintf(intbuff,(l_time.hour < 12) ? "%02d:%02d:%02d AM" :
-		"%02d:%02d:%02d PM",(l_time.hour+11)%12+1,l_time.minute,
-		l_time.second);
-	str->append(intbuff);
+	length= my_sprintf(intbuff, 
+		   (intbuff, 
+		    (l_time.hour < 12) ? "%02d:%02d:%02d AM" : "%02d:%02d:%02d PM",
+		    (l_time.hour+11)%12+1,
+		    l_time.minute,
+		    l_time.second));
+	str->append(intbuff, length);
 	break;
       case 'S':
       case 's':
-	sprintf(intbuff,"%02d",l_time.second);
-	str->append(intbuff);
+	length= int10_to_str(l_time.second, intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 2, '0');
 	break;
       case 'T':
-	sprintf(intbuff,"%02d:%02d:%02d", l_time.hour, l_time.minute,
-		l_time.second);
-	str->append(intbuff);
+	length= my_sprintf(intbuff, 
+		   (intbuff, 
+		    "%02d:%02d:%02d", 
+		    l_time.hour, 
+		    l_time.minute,
+		    l_time.second));
+	str->append(intbuff, length);
 	break;
       case 'U':
       case 'u':
       {
 	uint year;
-	sprintf(intbuff,"%02d",calc_week(&l_time, 0, (*ptr) == 'U', &year));
-	str->append(intbuff,2);
+	length= int10_to_str(calc_week(&l_time, 0, (*ptr) == 'U', &year),
+		     intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 2, '0');
       }
       break;
       case 'v':
       case 'V':
       {
 	uint year;
-	sprintf(intbuff,"%02d",calc_week(&l_time, 1, (*ptr) == 'V', &year));
-	str->append(intbuff,2);
+	length= int10_to_str(calc_week(&l_time, 1, (*ptr) == 'V', &year),
+		     intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 2, '0');
       }
       break;
       case 'x':
@@ -1020,14 +1042,15 @@
       {
 	uint year;
 	(void) calc_week(&l_time, 1, (*ptr) == 'X', &year);
-	sprintf(intbuff,"%04d",year);
-	str->append(intbuff,4);
+	length= int10_to_str(year, intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 4, '0');
       }
       break;
       case 'w':
 	weekday=calc_weekday(calc_daynr(l_time.year,l_time.month,l_time.day),1);
-	sprintf(intbuff,"%d",weekday);
-	str->append(intbuff,1);
+	length= int10_to_str(weekday, intbuff, 10) - intbuff;
+	str->append_with_prefill(intbuff, length, 1, '0');
+
 	break;
       default:
 	str->append(*ptr);
@@ -1109,7 +1132,7 @@
   enum_field_types arg0_field_type;
   set_charset(default_charset());
   maybe_null=1;
-  max_length=26*default_charset()->mbmaxlen;
+  max_length=26*MY_CHARSET_BIN_MB_MAXLEN;
   value.alloc(32);
 
   /*
@@ -1197,13 +1220,13 @@
     ltime->hour=sec/3600;
     daynr= calc_daynr(ltime->year,ltime->month,1) + days;
     get_date_from_daynr(daynr,&ltime->year,&ltime->month,&ltime->day);
-    if (daynr < 0 || daynr >= 3652424) // Day number from year 0 to 9999-12-31
+    if (daynr < 0 || daynr >= MAX_DAY_NUMBER) // Day number from year 0 to 9999-12-31
       goto null_date;
     break;
   case INTERVAL_DAY:
     period= calc_daynr(ltime->year,ltime->month,ltime->day) +
       sign*interval.day;
-    if (period < 0 || period >= 3652424) // Daynumber from year 0 to 9999-12-31
+    if (period < 0 || period >= MAX_DAY_NUMBER) // Daynumber from year 0 to 9999-12-31
       goto null_date;
     get_date_from_daynr((long) period,&ltime->year,&ltime->month,&ltime->day);
     break;
@@ -1375,6 +1398,63 @@
   str->append(')');
 }
 
+String *Item_datetime_typecast::val_str(String *str)
+{
+  TIME ltime;
+
+  if (!get_arg0_date(&ltime,1) &&
+      make_datetime(str, &ltime, ltime.second_part ?
+	    DATE_TIME_MICROSECOND : DATE_TIME))
+  return str;
+
+null_date:
+  null_value=1;
+  return 0;
+}
+
+
+bool Item_time_typecast::get_time(TIME *ltime)
+{
+  bool res= get_arg0_time(ltime);
+  ltime->time_type= TIMESTAMP_TIME;
+  return res;
+}
+
+
+String *Item_time_typecast::val_str(String *str)
+{
+  TIME ltime;
+
+  if (!get_arg0_time(&ltime) &&
+      make_datetime(str, &ltime, ltime.second_part ? TIME_MICROSECOND : TIME_ONLY))
+    return str;
+
+  null_value=1;
+  return 0;
+}
+
+
+bool Item_date_typecast::get_date(TIME *ltime, bool fuzzy_date)
+{
+  bool res= get_arg0_date(ltime,1);
+  ltime->time_type= TIMESTAMP_DATE;
+  return res;
+}
+
+
+String *Item_date_typecast::val_str(String *str)
+{
+  TIME ltime;
+
+  if (!get_arg0_date(&ltime,1) &&
+      make_datetime(str, &ltime, DATE_ONLY))
+  return str;
+
+null_date:
+  null_value=1;
+  return 0;
+}
+
 /*
   MAKEDATE(a,b) is a date function that creates a date value 
   from a year and day value.
@@ -1392,7 +1472,7 @@
     goto null_date;
 
   days= calc_daynr(yearnr,1,1) + daynr - 1;
-  if (days > 0 || days < 3652424L) // Day number from year 0 to 9999-12-31
+  if (days > 0 || days < MAX_DAY_NUMBER) // Day number from year 0 to 9999-12-31
   {
     null_value=0;
     get_date_from_daynr(days,&l_time.year,&l_time.month,&l_time.day);
@@ -1410,7 +1490,7 @@
 {
   enum_field_types arg0_field_type;
   decimals=0;
-  max_length=26*my_charset_bin.mbmaxlen;
+  max_length=26*MY_CHARSET_BIN_MB_MAXLEN;
 
   /*
     The field type for the result of an Item_func_add_time function is defined as
@@ -1424,7 +1504,8 @@
 
   cached_field_type= MYSQL_TYPE_STRING;
   arg0_field_type= args[0]->field_type();
-  if (arg0_field_type == MYSQL_TYPE_DATETIME ||
+  if (arg0_field_type == MYSQL_TYPE_DATE ||
+      arg0_field_type == MYSQL_TYPE_DATETIME ||
       arg0_field_type == MYSQL_TYPE_TIMESTAMP)
     cached_field_type= MYSQL_TYPE_DATETIME;
   else if (arg0_field_type == MYSQL_TYPE_TIME)
@@ -1443,20 +1524,28 @@
 String *Item_func_add_time::val_str(String *str)
 {
   TIME l_time1, l_time2, l_time3;
-  bool is_time;
+  bool is_time= 0;
   long microseconds, seconds, days= 0;
   int l_sign= sign;
 
   null_value=0;
-  if (args[0]->get_time(&l_time1) || 
-      args[1]->get_time(&l_time2) ||
-      l_time2.time_type == TIMESTAMP_FULL)
-    goto null_date;
-  is_time= (l_time1.time_type == TIMESTAMP_TIME);
   l_time3.neg= 0;
-  if (is_time)
+  if (is_date)                        // TIMESTAMP function
+  {
+    if (get_arg0_date(&l_time1,1) || 
+        args[1]->get_time(&l_time2) ||
+        l_time1.time_type == TIMESTAMP_TIME || 
+        l_time2.time_type != TIMESTAMP_TIME)
+      goto null_date;
+  }
+  else                                // ADDTIME function
   {
-    if ((l_time2.neg == l_time1.neg) && l_time1.neg)
+    if (args[0]->get_time(&l_time1) || 
+        args[1]->get_time(&l_time2) ||
+        l_time2.time_type == TIMESTAMP_FULL)
+      goto null_date;
+    is_time= (l_time1.time_type == TIMESTAMP_TIME);
+    if (is_time && (l_time2.neg == l_time1.neg && l_time1.neg))
       l_time3.neg= 1;
   }
   if (l_time1.neg != l_time2.neg)
@@ -1504,13 +1593,17 @@
   {
     get_date_from_daynr(days,&l_time3.year,&l_time3.month,&l_time3.day);
     if (l_time3.day &&
-	make_datetime(str, &l_time3, DATE_TIME_MICROSECOND))
+	make_datetime(str, &l_time3,
+	              l_time1.second_part || l_time2.second_part ?
+	              DATE_TIME_MICROSECOND : DATE_TIME))
       return str;
     goto null_date;
   }
 
   l_time3.hour+= days*24;
-  if (make_datetime(str, &l_time3, TIME_MICROSECOND))
+  if (make_datetime(str, &l_time3,
+	    l_time1.second_part || l_time2.second_part ?
+	    TIME_MICROSECOND : TIME_ONLY))
     return str;
 
 null_date:
@@ -1578,7 +1671,9 @@
     l_time3.neg= l_time3.neg ? 0 : 1;
 
   calc_time_from_sec(&l_time3, seconds, microseconds);
-  if (make_datetime(str, &l_time3, TIME_MICROSECOND))
+  if (make_datetime(str, &l_time3, 
+	    l_time1.second_part || l_time2.second_part ?
+	    TIME_MICROSECOND : TIME_ONLY))
     return str;
 
 null_date:
@@ -1621,99 +1716,6 @@
 
 null_date:
     return 0;
-}
-
-/*
-  TIMESTAMP(a,b) is a function ( extraction) that calculates a datetime value
-  comprising a date value, time value.
-
-  a: Date_or_datetime value
-  b: Time value
-  Result: Datetime value
-*/
-
-String *Item_func_timestamp::val_str(String *str)
-{
-  TIME l_time1 ,l_time2, l_time3;
-  long seconds;
-  long microseconds;
-  long days;
-  int l_sign;
-
-  if (get_arg0_date(&l_time1,1) || 
-      args[1]->get_time(&l_time2) ||
-      l_time1.time_type == TIMESTAMP_TIME || 
-      l_time2.time_type != TIMESTAMP_TIME)
-    goto null_date;
-
-  l_sign= l_time2.neg ? -1 : 1;
-  days= (calc_daynr((uint) l_time1.year,(uint) l_time1.month,
-		    (uint) l_time1.day) + l_sign*l_time2.day);
-
-  microseconds= l_time1.second_part + l_sign*l_time2.second_part;
-  seconds= (l_time1.hour*3600L + l_time1.minute*60L + l_time1.second +
-	    (l_time2.day*86400L + l_time2.hour*3600L +
-	     l_time2.minute*60L + l_time2.second)*l_sign);
-  days+= seconds/86400L;
-  seconds%= 86400L;
-  if (microseconds < 0)
-  {
-    microseconds+= 1000000L;
-    seconds--;
-  }
-  if (seconds < 0)
-  {
-    days--;
-    seconds+= 86400L;
-  }
-  if (days < 0)
-    goto null_date;
-
-  calc_time_from_sec(&l_time3, seconds, microseconds);
-  get_date_from_daynr(days,&l_time3.year,&l_time3.month,&l_time3.day);
-  make_datetime(str, &l_time3, DATE_TIME_MICROSECOND);
-  return str;
-
-null_date:
-  null_value=1;
-  return 0;
-}
-
-/*
-  DATE(a) is a function ( extraction) that calculates a date value.
-
-  a: Datetime value
-  Result: Date value
-*/
-String *Item_func_date::val_str(String *str)
-{
-  TIME ltime;
-
-  if (!get_arg0_date(&ltime,1) &&
-      make_datetime(str, &ltime, DATE_ONLY))
-  return str;
-
-null_date:
-  null_value=1;
-  return 0;
-}
-
-/*
-  TIME(a) is a function ( extraction) that calculates a time value.
-
-  a: Datetime value
-  Result: Time value
-*/
-String *Item_func_time::val_str(String *str)
-{
-  TIME ltime;
-
-  if (!get_arg0_time(&ltime) &&
-      make_datetime(str, &ltime, TIME_MICROSECOND))
-    return str;
-
-  null_value=1;
-  return 0;
 }
 
 /*

--- 1.31/sql/item_timefunc.h	Mon Jun 23 12:56:31 2003
+++ 1.32/sql/item_timefunc.h	Tue Jul  8 15:06:03 2003
@@ -557,6 +557,8 @@
 {
 public:
   Item_date_typecast(Item *a) :Item_typecast(a) {}
+  String *val_str(String *str);
+  bool get_date(TIME *ltime, bool fuzzy_date);
   const char *func_name() const { return "date"; }
   enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
   Field *tmp_table_field() { return result_field; }
@@ -571,6 +573,8 @@
 {
 public:
   Item_time_typecast(Item *a) :Item_typecast(a) {}
+  String *val_str(String *str);
+  bool get_time(TIME *ltime);
   const char *func_name() const { return "time"; }
   enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
   Field *tmp_table_field() { return result_field; }
@@ -585,6 +589,7 @@
 {
 public:
   Item_datetime_typecast(Item *a) :Item_typecast(a) {}
+  String *val_str(String *str);
   const char *func_name() const { return "datetime"; }
   enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
   Field *tmp_table_field() { return result_field; }
@@ -604,7 +609,7 @@
   void fix_length_and_dec()
   { 
     decimals=0;
-    max_length=8*my_charset_bin.mbmaxlen;
+    max_length=8*MY_CHARSET_BIN_MB_MAXLEN;
   }
   Field *tmp_table_field() { return result_field; }
   Field *tmp_table_field(TABLE *t_arg)
@@ -613,18 +618,26 @@
   }
 };
 
+
 class Item_func_add_time :public Item_str_func
 {
+  const bool is_date;
   int sign;
   enum_field_types cached_field_type;
 
 public:
-  Item_func_add_time(Item *a, Item *b, bool neg_arg)
-    :Item_str_func(a, b) { sign= neg_arg ? -1 : 1; }
+  Item_func_add_time(Item *a, Item *b, bool type_arg, bool neg_arg)
+    :Item_str_func(a, b), is_date(type_arg) { sign= neg_arg ? -1 : 1; }
   String *val_str(String *str);
   const char *func_name() const { return "addtime"; }
   enum_field_types field_type() const { return cached_field_type; }
   void fix_length_and_dec();
+
+/*
+  TODO:
+       Change this when we support 
+       microseconds in TIME/DATETIME
+*/
   Field *tmp_table_field() { return result_field; }
   Field *tmp_table_field(TABLE *t_arg)
   {
@@ -647,7 +660,7 @@
   void fix_length_and_dec()
   {
     decimals=0;
-    max_length=17*my_charset_bin.mbmaxlen;
+    max_length=17*MY_CHARSET_BIN_MB_MAXLEN;
   }
   Field *tmp_table_field() { return result_field; }
   Field *tmp_table_field(TABLE *t_arg)
@@ -667,66 +680,7 @@
   void fix_length_and_dec()
   {
     decimals=0;
-    max_length=8*my_charset_bin.mbmaxlen;
-  }
-  Field *tmp_table_field() { return result_field; }
-  Field *tmp_table_field(TABLE *t_arg)
-  {
-      return (new Field_time(maybe_null, name, t_arg, &my_charset_bin));
-  }
-};
-
-class Item_func_timestamp :public Item_str_func
-{
-public:
-  Item_func_timestamp(Item *a, Item *b) :Item_str_func(a, b) {}
-  String *val_str(String *str);
-  const char *func_name() const { return "timestamp"; }
-  enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
-  void fix_length_and_dec()
-  { 
-    decimals=0;
-    max_length=26*my_charset_bin.mbmaxlen;
-  }
-  Field *tmp_table_field() { return result_field; }
-  Field *tmp_table_field(TABLE *t_arg)
-  {
-    return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin));
-  }
-};
-
-class Item_func_date :public Item_str_func
-{
-public:
-  Item_func_date(Item *a)
-    :Item_str_func(a) {}
-  String *val_str(String *str);
-  const char *func_name() const { return "date"; }
-  enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
-  void fix_length_and_dec()
-  {
-    decimals=0;
-    max_length=10*my_charset_bin.mbmaxlen;
-  }
-  Field *tmp_table_field() { return result_field; }
-  Field *tmp_table_field(TABLE *t_arg)
-  {
-    return (new Field_date(maybe_null, name, t_arg, &my_charset_bin));
-  }
-};
-
-class Item_func_time :public Item_str_func
-{
-public:
-  Item_func_time(Item *a)
-    :Item_str_func(a) {}
-  String *val_str(String *str);
-  const char *func_name() const { return "time"; }
-  enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
-  void fix_length_and_dec()
-  {
-    decimals=0;
-    max_length=15*my_charset_bin.mbmaxlen;
+    max_length=8*MY_CHARSET_BIN_MB_MAXLEN;
   }
   Field *tmp_table_field() { return result_field; }
   Field *tmp_table_field(TABLE *t_arg)

--- 1.203/sql/mysql_priv.h	Tue Jul  8 12:56:56 2003
+++ 1.204/sql/mysql_priv.h	Tue Jul  8 15:06:03 2003
@@ -224,6 +224,8 @@
 
 #define RAID_BLOCK_SIZE 1024
 
+#define MY_CHARSET_BIN_MB_MAXLEN 1
+
 #ifdef EXTRA_DEBUG
 /*
   Sync points allow us to force the server to reach a certain line of code

--- 1.64/sql/protocol.cc	Tue Jul  8 12:56:56 2003
+++ 1.65/sql/protocol.cc	Tue Jul  8 15:06:03 2003
@@ -823,6 +823,13 @@
 }
 
 
+/*
+   TODO:
+        Second_part format ("%06") needs to change when 
+        we support 0-6 decimals for time.
+*/
+
+
 bool Protocol_simple::store(TIME *tm)
 {
 #ifndef DEBUG_OFF
@@ -862,6 +869,12 @@
   return net_store_data((char*) buff, length);
 }
 
+
+/*
+   TODO:
+        Second_part format ("%06") needs to change when 
+        we support 0-6 decimals for time.
+*/
 
 bool Protocol_simple::store_time(TIME *tm)
 {

--- 1.62/sql/sql_string.cc	Thu Jun  5 02:01:46 2003
+++ 1.63/sql/sql_string.cc	Tue Jul  8 15:06:03 2003
@@ -390,6 +390,23 @@
   return FALSE;
 }
 
+bool String::append_with_prefill(const char *s,uint32 arg_length,
+		 uint32 full_length, char fill_char)
+{
+  int t_length= arg_length > full_length ? arg_length : full_length;
+
+  if (realloc(str_length + t_length))
+    return TRUE;
+  t_length= full_length - arg_length;
+  if (t_length > 0)
+  {
+    bfill(Ptr+str_length, t_length, fill_char);
+    str_length=str_length + t_length;
+  }
+  append(s, arg_length);
+  return FALSE;
+}
+
 uint32 String::numchars()
 {
   return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);

--- 1.36/sql/sql_string.h	Thu Jun  5 02:01:46 2003
+++ 1.37/sql/sql_string.h	Tue Jul  8 15:06:03 2003
@@ -189,6 +189,8 @@
   bool append(const char *s,uint32 arg_length=0);
   bool append(const char *s,uint32 arg_length, CHARSET_INFO *cs);
   bool append(IO_CACHE* file, uint32 arg_length);
+  bool append_with_prefill(const char *s, uint32 arg_length, 
+			   uint32 full_length, char fill_char);
   int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
   int strstr_case(const String &s,uint32 offset=0);
   int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1

--- 1.254/sql/sql_yacc.yy	Tue Jul  8 12:56:56 2003
+++ 1.255/sql/sql_yacc.yy	Tue Jul  8 15:06:03 2003
@@ -2381,7 +2381,7 @@
             Lex->safe_to_cache_query=0;
 	  }
 	| DATE_SYM '(' expr ')'
-	  { $$= new Item_func_date($3); }
+	  { $$= new Item_date_typecast($3); }
 	| DAY_SYM '(' expr ')'
 	  { $$= new Item_func_dayofmonth($3); }
 	| ELT_FUNC '(' expr ',' expr_list ')'
@@ -2580,9 +2580,11 @@
 	| SUBSTRING_INDEX '(' expr ',' expr ',' expr ')'
 	  { $$= new Item_func_substr_index($3,$5,$7); }
 	| TIME_SYM '(' expr ')'
-	  { $$= new Item_func_time($3); }
+	  { $$= new Item_time_typecast($3); }
+	| TIMESTAMP '(' expr ')'
+	  { $$= new Item_datetime_typecast($3); }
 	| TIMESTAMP '(' expr ',' expr ')'
-	  { $$= new Item_func_timestamp($3, $5); }
+	  { $$= new Item_func_add_time($3, $5, 1, 0); }
 	| TRIM '(' expr ')'
 	  { $$= new Item_func_trim($3); }
 	| TRIM '(' LEADING expr FROM expr ')'
@@ -4427,6 +4429,7 @@
 	| MEDIUM_SYM		{}
 	| MERGE_SYM		{}
 	| MEMORY_SYM		{}
+	| MICROSECOND_SYM	{}
 	| MINUTE_SYM		{}
 	| MIN_ROWS		{}
 	| MODIFY_SYM		{}

--- 1.31/sql/time.cc	Mon Jun 23 13:02:25 2003
+++ 1.32/sql/time.cc	Tue Jul  8 15:06:03 2003
@@ -432,6 +432,7 @@
   l_time->minute=date[4];
   l_time->second=date[5];
   l_time->second_part=date[6];
+  l_time->neg= 0;
   DBUG_RETURN(l_time->time_type=
 	      (number_of_fields <= 3 ? TIMESTAMP_DATE : TIMESTAMP_FULL));
 }

--- 1.1/mysql-test/r/func_sapdb.result	Mon Jun 23 12:56:31 2003
+++ 1.2/mysql-test/r/func_sapdb.result	Tue Jul  8 15:06:03 2003
@@ -101,8 +101,8 @@
 select timediff("1997-12-31 23:59:59.000001","23:59:59.000001");
 timediff("1997-12-31 23:59:59.000001","23:59:59.000001")
 NULL
-select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.1");
-timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.1")
+select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001");
+timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001")
 -00:00:00.000001
 select maketime(10,11,12);
 maketime(10,11,12)
@@ -122,6 +122,12 @@
 select timestamp("2001-12-01", "25:01:01");
 timestamp("2001-12-01", "25:01:01")
 2001-12-02 01:01:01
+select timestamp("2001-12-01 01:01:01.000100");
+timestamp("2001-12-01 01:01:01.000100")
+2001-12-01 01:01:01.000100
+select timestamp("2001-12-01");
+timestamp("2001-12-01")
+2001-12-01 00:00:00
 select day("1997-12-31 23:59:59.000001");
 day("1997-12-31 23:59:59.000001")
 31
@@ -147,7 +153,7 @@
 timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") as f4,
 timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002") as f5,
 maketime(10,11,12) as f6,
-timestamp("2001-12-01", "01:01:01") as f7,
+timestamp(cast("2001-12-01" as date), "01:01:01") as f7,
 date("1997-12-31 23:59:59.000001") as f8,
 time("1997-12-31 23:59:59.000001") as f9;
 describe t1;

--- 1.1/mysql-test/t/func_sapdb.test	Mon Jun 23 12:56:32 2003
+++ 1.2/mysql-test/t/func_sapdb.test	Tue Jul  8 15:06:03 2003
@@ -51,7 +51,7 @@
 select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002");
 select timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002");
 select timediff("1997-12-31 23:59:59.000001","23:59:59.000001");
-select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.1");
+select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001");
 
 select maketime(10,11,12);
 select maketime(25,11,12);
@@ -61,6 +61,8 @@
 select timestamp("2001-12-01", "01:01:01.999999");
 select timestamp("2001-13-01", "01:01:01.000001");
 select timestamp("2001-12-01", "25:01:01");
+select timestamp("2001-12-01 01:01:01.000100");
+select timestamp("2001-12-01");
 select day("1997-12-31 23:59:59.000001");
 select date("1997-12-31 23:59:59.000001");
 select date("1997-13-31 23:59:59.000001");
@@ -75,7 +77,7 @@
    timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") as f4,
    timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002") as f5,
    maketime(10,11,12) as f6,
-   timestamp("2001-12-01", "01:01:01") as f7,
+   timestamp(cast("2001-12-01" as date), "01:01:01") as f7,
    date("1997-12-31 23:59:59.000001") as f8,
    time("1997-12-31 23:59:59.000001") as f9;
 describe t1;

--- 1.7/mysql-test/r/cast.result	Fri May 30 17:14:52 2003
+++ 1.8/mysql-test/r/cast.result	Tue Jul  8 15:06:03 2003
@@ -44,10 +44,10 @@
 drop table t1;
 select cast("2001-1-1" as date) = "2001-01-01";
 cast("2001-1-1" as date) = "2001-01-01"
-0
+1
 select cast("2001-1-1" as datetime) = "2001-01-01 00:00:00";
 cast("2001-1-1" as datetime) = "2001-01-01 00:00:00"
-0
+1
 select cast("1:2:3" as TIME) = "1:02:03";
 cast("1:2:3" as TIME) = "1:02:03"
 0
Thread
bk commit into 4.1 tree (1.1558)gluh8 Jul