List:Commits« Previous MessageNext Message »
From:Alexander Barkov Date:November 7 2011 7:45am
Subject:bzr push into mysql-trunk branch (alexander.barkov:3549 to 3550) WL#946
View as plain text  
 3550 Alexander Barkov	2011-11-07
      WL#946 Improvements in MYSQL_TIME_cache.

    modified:
      sql/item_timefunc.cc
      sql/item_timefunc.h
      unittest/gunit/item-t.cc
 3549 Alexander Barkov	2011-11-07
      WL#946
      Fixing crash on Windows on:
      
        DBUG_ASSERT(sizeof(time_t) == sizeof(when.tv_sec));

    modified:
      sql/log_event.cc
=== modified file 'sql/item_timefunc.cc'
--- a/sql/item_timefunc.cc	2011-11-03 09:33:45 +0000
+++ b/sql/item_timefunc.cc	2011-11-07 07:44:22 +0000
@@ -1798,11 +1798,9 @@ bool Item_func_from_days::get_date(MYSQL
 }
 
 
-/**
-  Set time and time_packed from a TIME value.
-*/
 void MYSQL_TIME_cache::set_time(MYSQL_TIME *ltime, uint8 dec_arg)
 {
+  DBUG_ASSERT(string_buff[0] == '\0' && string_length == 0);
   DBUG_ASSERT(ltime->time_type == MYSQL_TIMESTAMP_TIME);
   time= *ltime;
   time_packed= TIME_to_longlong_time_packed(&time);
@@ -1810,22 +1808,18 @@ void MYSQL_TIME_cache::set_time(MYSQL_TI
 }
 
 
-/**
-  Set time and time_packed from a DATE value.
-*/
 void MYSQL_TIME_cache::set_date(MYSQL_TIME *ltime)
 {
+  DBUG_ASSERT(string_buff[0] == '\0' && string_length == 0);
   DBUG_ASSERT(ltime->time_type == MYSQL_TIMESTAMP_DATE);
   time= *ltime;
   time_packed= TIME_to_longlong_date_packed(&time);
 }
 
 
-/**
-  Set time and time_packed from a DATETIME value.
-*/
 void MYSQL_TIME_cache::set_datetime(MYSQL_TIME *ltime, uint8 dec_arg)
 {
+  DBUG_ASSERT(string_buff[0] == '\0' && string_length == 0);
   DBUG_ASSERT(ltime->time_type == MYSQL_TIMESTAMP_DATETIME);
   time= *ltime;
   time_packed= TIME_to_longlong_datetime_packed(&time);
@@ -1833,25 +1827,19 @@ void MYSQL_TIME_cache::set_datetime(MYSQ
 }
 
 
-/**
-  Set time and time_packed according to DATETIME value
-  in "struct timeval" representation and its time zone.
-*/
 void MYSQL_TIME_cache::set_datetime(struct timeval tv, uint8 dec_arg,
                                     Time_zone *tz)
 {
+  DBUG_ASSERT(string_buff[0] == '\0' && string_length == 0);
   tz->gmt_sec_to_TIME(&time, tv);
   time_packed= TIME_to_longlong_datetime_packed(&time);
   dec= dec_arg;
 }
 
 
-/**
-  Set time and time_packed according to DATE value
-  in "struct timeval" representation and its time zone.
-*/
 void MYSQL_TIME_cache::set_date(struct timeval tv, Time_zone *tz)
 {
+  DBUG_ASSERT(string_buff[0] == '\0' && string_length == 0);
   tz->gmt_sec_to_TIME(&time, (my_time_t) tv.tv_sec);
   time.time_type= MYSQL_TIMESTAMP_DATE;
   /* We don't need to set second_part and neg because they are already 0 */
@@ -1860,13 +1848,10 @@ void MYSQL_TIME_cache::set_date(struct t
 }
 
 
-/**
-  Set time and time_packed according to TIME value
-  in "struct timeval" representation and its time zone.
-*/
 void MYSQL_TIME_cache::set_time(struct timeval tv, uint8 dec_arg,
                                 Time_zone *tz)
 {
+  DBUG_ASSERT(string_buff[0] == '\0' && string_length == 0);
   tz->gmt_sec_to_TIME(&time, tv);
   datetime_to_time(&time);
   time_packed= TIME_to_longlong_time_packed(&time);
@@ -1874,21 +1859,14 @@ void MYSQL_TIME_cache::set_time(struct t
 }
 
 
-/**
-  Cache string representation from the cached MYSQL_TIME representation.
-  If string representation has already been cached, then nothing happens.
-*/
 void MYSQL_TIME_cache::cache_string()
 {
   DBUG_ASSERT(time.time_type != MYSQL_TIMESTAMP_NONE);
-  if (!string_length)
+  if (string_length == 0)
     string_length= my_TIME_to_str(&time, string_buff, decimals());
 }
 
 
-/**
-  Cache string representation (if needed) and return it as C string.
-*/
 const char *MYSQL_TIME_cache::cptr()
 {
   cache_string();
@@ -1896,9 +1874,6 @@ const char *MYSQL_TIME_cache::cptr()
 }
 
 
-/**
-  Cache string representation (if needed) and return it as String.
-*/
 String *MYSQL_TIME_cache::val_str(String *str)
 {
   cache_string();
@@ -1937,7 +1912,7 @@ void Item_func_curtime::fix_length_and_d
   cached_time.set_time(thd->query_start_timeval_trunc(decimals), decimals,
                        time_zone());
   /*
-    We use 8 instead of MAX_TIME_WIDTH (which is 10) becase:
+    We use 8 instead of MAX_TIME_WIDTH (which is 10) because:
     - there is no sign 
     - hour is in the 2-digit range
   */
@@ -1985,7 +1960,7 @@ Time_zone *Item_func_now_utc::time_zone(
 int Item_func_now::save_in_field(Field *to, bool no_conversions)
 {
   to->set_notnull();
-  return to->store_time(cached_time.get_TIME(), decimals);
+  return to->store_time(cached_time.get_TIME_ptr(), decimals);
 }
 
 

=== modified file 'sql/item_timefunc.h'
--- a/sql/item_timefunc.h	2011-11-03 09:33:45 +0000
+++ b/sql/item_timefunc.h	2011-11-07 07:44:22 +0000
@@ -662,34 +662,65 @@ public:
   
   - MYSQL_TIME representation (time) is initialized during set_XXX().
   - Packed representation (time_packed) is also initialized during set_XXX().
-  - String representation (string_buff) is not initialized during set_XXX(),
-    It's initialized only if val_str() or cptr() are called.
+  - String representation (string_buff) is not initialized during set_XXX();
+    it's initialized only if val_str() or cptr() are called.
 */
 class MYSQL_TIME_cache
 {
-  MYSQL_TIME time;                              // MYSQL_TIME representation
-  longlong time_packed;                         // packed representation
-  char string_buff[MAX_DATE_STRING_REP_LENGTH]; // string representation
-  uint string_length;                           // length of string
-  uint8 dec;                                    // Number of decimals
-  void cache_string(); // Store string representation to string_buff
+  MYSQL_TIME time;                              ///< MYSQL_TIME representation
+  longlong time_packed;                         ///< packed representation
+  char string_buff[MAX_DATE_STRING_REP_LENGTH]; ///< string representation
+  uint string_length;                           ///< length of string
+  uint8 dec;                                    ///< Number of decimals
+  /**
+    Cache string representation from the cached MYSQL_TIME representation.
+    If string representation has already been cached, then nothing happens.
+  */
+  void cache_string();
 public:
+
   MYSQL_TIME_cache()
   {
+    reset();
+  }
+  /**
+    Reset all members.
+  */
+  void reset()
+  {
     time.time_type= MYSQL_TIMESTAMP_NONE;
+    time_packed= 0;
     string_length= 0;
     string_buff[0]= '\0';
     dec= 0;
   }
-  // Initialize time and time_packed from MYSQL_TIME parameter.
+  /**
+    Set time and time_packed from a DATE value.
+  */
   void set_date(MYSQL_TIME *ltime);
+  /**
+    Set time and time_packed from a TIME value.
+  */
   void set_time(MYSQL_TIME *ltime, uint8 dec_arg);
+  /**
+    Set time and time_packed from a DATETIME value.
+  */
   void set_datetime(MYSQL_TIME *ltime, uint8 dec_arg);
-  // Initialize time and time_packed from "struct timeval" and time zone.
+  /**
+    Set time and time_packed according to DATE value
+    in "struct timeval" representation and its time zone.
+  */
   void set_date(struct timeval tv, Time_zone *tz);
+  /**
+    Set time and time_packed according to TIME value
+    in "struct timeval" representation and its time zone.
+  */
   void set_time(struct timeval tv, uint8 dec_arg, Time_zone *tz);
+  /**
+    Set time and time_packed according to DATETIME value
+    in "struct timeval" representation and its time zone.
+  */
   void set_datetime(struct timeval tv, uint8 dec_arg, Time_zone *tz);
-
   /**
     Test if cached value is equal to another MYSQL_TIME_cache value.
   */
@@ -726,7 +757,7 @@ public:
   /**
     Return pointer to MYSQL_TIME representation.
   */
-  MYSQL_TIME *get_TIME()
+  MYSQL_TIME *get_TIME_ptr()
   {
     DBUG_ASSERT(time.time_type != MYSQL_TIMESTAMP_NONE);
     return &time;

=== modified file 'unittest/gunit/item-t.cc'
--- a/unittest/gunit/item-t.cc	2011-05-25 14:19:53 +0000
+++ b/unittest/gunit/item-t.cc	2011-11-07 07:44:22 +0000
@@ -22,6 +22,7 @@
 
 #include "item.h"
 #include "sql_class.h"
+#include "tztime.h"
 
 namespace {
 
@@ -387,4 +388,141 @@ TEST_F(ItemTest, ItemFuncXor)
   EXPECT_TRUE(item_xor_null->is_null());
 }
 
+
+/*
+  Testing MYSQL_TIME_cache.
+*/
+TEST_F(ItemTest, MYSQL_TIME_cache)
+{
+  String str_buff, *str;
+  MYSQL_TIME datetime6=
+  { 2011, 11, 7, 10, 20, 30, 123456, 0, MYSQL_TIMESTAMP_DATETIME };
+  MYSQL_TIME time6=
+  { 0, 0, 0, 10, 20, 30, 123456, 0, MYSQL_TIMESTAMP_TIME };
+  struct timeval tv6= {1320661230, 123456};
+  const MYSQL_TIME *ltime;
+  MYSQL_TIME_cache cache;
+
+  /*
+    Testing DATETIME(6).
+    Initializing from MYSQL_TIME.
+  */
+  cache.set_datetime(&datetime6, 6);
+  EXPECT_EQ(1840440237558456896LL, cache.val_packed());
+  EXPECT_EQ(6, cache.decimals());
+  // Call val_str() then cptr()
+  str= cache.val_str(&str_buff);
+  EXPECT_STREQ("2011-11-07 10:20:30.123456", str->c_ptr_safe());
+  EXPECT_STREQ("2011-11-07 10:20:30.123456", cache.cptr());
+  cache.reset();
+  cache.set_datetime(&datetime6, 6);
+  // Now call the other way around: cptr() then val_str()
+  EXPECT_STREQ("2011-11-07 10:20:30.123456", cache.cptr());
+  EXPECT_STREQ("2011-11-07 10:20:30.123456", str->c_ptr_safe());
+  // Testing get_TIME_ptr()
+  ltime= cache.get_TIME_ptr();
+  EXPECT_EQ(ltime->year, datetime6.year);
+  EXPECT_EQ(ltime->month, datetime6.month);
+  EXPECT_EQ(ltime->day, datetime6.day);
+  EXPECT_EQ(ltime->hour, datetime6.hour);
+  EXPECT_EQ(ltime->minute, datetime6.minute);
+  EXPECT_EQ(ltime->second, datetime6.second);
+  EXPECT_EQ(ltime->second_part, datetime6.second_part);
+  EXPECT_EQ(ltime->neg, datetime6.neg);
+  EXPECT_EQ(ltime->time_type, datetime6.time_type);
+  // Testing eq()
+  {
+    MYSQL_TIME datetime6_2= datetime6;
+    MYSQL_TIME_cache cache2;
+    datetime6_2.second_part+= 1;
+    cache2.set_datetime(&datetime6_2, 6);
+    EXPECT_EQ(cache.eq(cache), true);
+    EXPECT_EQ(cache.eq(cache2), false);
+    EXPECT_EQ(cache2.eq(cache2), true);
+    EXPECT_EQ(cache2.eq(cache), false);
+  }
+
+  /*
+     Testing DATETIME(6).
+     Initializing from "struct timeval".
+  */
+  cache.reset();
+  cache.set_datetime(tv6, 6, my_tz_UTC);
+  EXPECT_EQ(1840440237558456896LL, cache.val_packed());
+  EXPECT_EQ(6, cache.decimals());
+  str= cache.val_str(&str_buff);
+  EXPECT_STREQ("2011-11-07 10:20:30.123456", str->c_ptr_safe());
+  EXPECT_STREQ("2011-11-07 10:20:30.123456", cache.cptr());
+
+  /*
+    Testing TIME(6).
+    Initializing from MYSQL_TIME.
+  */
+  cache.reset();
+  cache.set_time(&time6, 6);
+  EXPECT_EQ(709173043776LL, cache.val_packed());
+  EXPECT_EQ(6, cache.decimals());
+  // Call val_str() then cptr()
+  str= cache.val_str(&str_buff);
+  EXPECT_STREQ("10:20:30.123456", str->c_ptr_safe());
+  EXPECT_STREQ("10:20:30.123456", cache.cptr());
+
+  /*
+    Testing TIME(6).
+    Initializing from "struct timeval".
+  */
+  cache.reset();
+  cache.set_time(tv6, 6, my_tz_UTC);
+  EXPECT_EQ(709173043776LL, cache.val_packed());
+  EXPECT_EQ(6, cache.decimals());
+  str= cache.val_str(&str_buff);
+  EXPECT_STREQ("10:20:30.123456", str->c_ptr_safe());
+  EXPECT_STREQ("10:20:30.123456", cache.cptr());
+
+  /*
+    Testing DATETIME(5)
+  */
+  cache.reset();
+  MYSQL_TIME datetime5=
+  { 2011, 11, 7, 10, 20, 30, 123450, 0, MYSQL_TIMESTAMP_DATETIME };
+  cache.set_datetime(&datetime5, 5);
+  EXPECT_EQ(1840440237558456890LL, cache.val_packed());
+  EXPECT_EQ(5, cache.decimals());
+  /* Call val_str() then cptr() */
+  str= cache.val_str(&str_buff);
+  EXPECT_STREQ("2011-11-07 10:20:30.12345", str->c_ptr_safe());
+  EXPECT_STREQ("2011-11-07 10:20:30.12345", cache.cptr());
+  cache.reset();
+  cache.set_datetime(&datetime5, 5);
+  /* Now call the other way around: cptr() then val_str() */
+  EXPECT_STREQ("2011-11-07 10:20:30.12345", cache.cptr());
+  EXPECT_STREQ("2011-11-07 10:20:30.12345", str->c_ptr_safe());
+
+  /*
+    Testing DATE.
+    Initializing from MYSQL_TIME.
+  */
+  cache.reset();
+  MYSQL_TIME date=
+  { 2011, 11, 7, 0, 0, 0, 0, 0, MYSQL_TIMESTAMP_DATE };
+  cache.set_date(&date);
+  EXPECT_EQ(1840439528385413120LL, cache.val_packed());
+  EXPECT_EQ(0, cache.decimals());
+  str= cache.val_str(&str_buff);
+  EXPECT_STREQ("2011-11-07", str->c_ptr_safe());
+  EXPECT_STREQ("2011-11-07", cache.cptr());
+
+  /*
+    Testing DATE.
+    Initializing from "struct tm".
+  */
+  cache.reset();
+  cache.set_date(tv6, my_tz_UTC);
+  EXPECT_EQ(1840439528385413120LL, cache.val_packed());
+  EXPECT_EQ(0, cache.decimals());
+  str= cache.val_str(&str_buff);
+  EXPECT_STREQ("2011-11-07", str->c_ptr_safe());
+  EXPECT_STREQ("2011-11-07", cache.cptr());
+}
+
 }

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (alexander.barkov:3549 to 3550) WL#946Alexander Barkov7 Nov