List:Commits« Previous MessageNext Message »
From:eugene Date:July 15 2007 5:51pm
Subject:bk commit into 5.0 tree (evgen:1.2526) BUG#29555
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of evgen. When evgen 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://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-07-15 21:51:36+04:00, evgen@stripped +4 -0
  Extended fix for the bug#29555.
  
  The get_time_value function is added. It is used to obtain TIME values both
  from items the can return time as an integer and from items that can return
  time only as a string.
  The Arg_comparator::compare_datetime function now uses pointer to a getter
  function to obtain values to compare. Now this function is also used for
  comparison of TIME values.
  The get_value_func variable is added to the Arg_comparator class.
  It points to a getter function for the DATE/DATETIME/TIME comparator.

  mysql-test/r/type_time.result@stripped, 2007-07-15 21:11:41+04:00, evgen@stripped +6 -0
    Extended test case for the bug#29555.

  mysql-test/t/type_time.test@stripped, 2007-07-15 21:11:26+04:00, evgen@stripped +4 -0
    Extended test case for the bug#29555.

  sql/item_cmpfunc.cc@stripped, 2007-07-15 21:42:46+04:00, evgen@stripped +74 -7
    Extended fix for the bug#29555.
    The get_time_value function is added. It is used to obtain TIME values both
    from items the can return time as an integer and from items that can return
    time only as a string.
    The Arg_comparator::compare_datetime function now uses pointer to a getter
    function to obtain values to compare. Now this function is also used for
    comparison of TIME values.

  sql/item_cmpfunc.h@stripped, 2007-07-15 21:49:58+04:00, evgen@stripped +2 -0
    Extended fix for the bug#29555.
    The get_value_func variable is added to the Arg_comparator class.
    It points to a getter function for the DATE/DATETIME/TIME comparator.

diff -Nrup a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result
--- a/mysql-test/r/type_time.result	2007-07-14 22:43:52 +04:00
+++ b/mysql-test/r/type_time.result	2007-07-15 21:11:41 +04:00
@@ -103,6 +103,12 @@ cast('100:55:50' as time) > cast('024:00
 select cast('300:55:50' as time) > cast('240:00:00' as time);
 cast('300:55:50' as time) > cast('240:00:00' as time)
 1
+create table t1 (f1 time);
+insert into t1 values ('24:00:00');
+select cast('24:00:00' as time) = (select f1 from t1);
+cast('24:00:00' as time) = (select f1 from t1)
+1
+drop table t1;
 create table t1(f1 time, f2 time);
 insert into t1 values('20:00:00','150:00:00');
 select 1 from t1 where cast('100:00:00' as time) between f1 and f2;
diff -Nrup a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test
--- a/mysql-test/t/type_time.test	2007-07-14 22:43:49 +04:00
+++ b/mysql-test/t/type_time.test	2007-07-15 21:11:26 +04:00
@@ -50,6 +50,10 @@ select cast('300:55:50' as time) < cast(
 select cast('100:55:50' as time) > cast('24:00:00' as time);
 select cast('100:55:50' as time) > cast('024:00:00' as time);
 select cast('300:55:50' as time) > cast('240:00:00' as time);
+create table t1 (f1 time);
+insert into t1 values ('24:00:00');
+select cast('24:00:00' as time) = (select f1 from t1);
+drop table t1;
 
 #
 # Bug#29739: Incorrect time comparison in BETWEEN.
diff -Nrup a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
--- a/sql/item_cmpfunc.cc	2007-07-12 23:08:13 +04:00
+++ b/sql/item_cmpfunc.cc	2007-07-15 21:42:46 +04:00
@@ -666,6 +666,68 @@ Arg_comparator::can_compare_as_dates(Ite
 }
 
 
+/*
+  Retrieves correct TIME value from the given item.
+
+  SYNOPSIS
+    get_time_value()
+    thd                 thread handle
+    item_arg   [in/out] item to retrieve TIME value from
+    cache_arg  [in/out] pointer to place to store the caching item to
+    warn_item  [in]     unused
+    is_null    [out]    TRUE <=> the item_arg is null
+
+  DESCRIPTION
+    Retrieves the correct TIME value from given item for comparison by the
+    compare_datetime() function.
+    If item's result can be compared as longlong then its int value is used
+    and a value returned by get_time function is used otherwise.
+    If an item is a constant one then its value is cached and it isn't
+    get parsed again. An Item_cache_int object is used for caching values. It
+    seamlessly substitutes the original item.  The cache item is marked as
+    non-constant to prevent re-caching it again.
+
+  RETURN
+    obtained value
+*/
+
+ulonglong
+get_time_value(THD *thd, Item ***item_arg, Item **cache_arg,
+               Item *warn_item, bool *is_null)
+{
+  ulonglong value;
+  Item *item= **item_arg;
+  MYSQL_TIME ltime;
+
+  if (item->result_as_longlong())
+  {
+    value= item->val_int();
+    *is_null= item->null_value;
+  }
+  else
+  {
+    *is_null= item->get_time(&ltime);
+    if (!is_null)
+      value= TIME_to_ulonglong_datetime(&ltime);
+  }
+  /*
+    Do not cache GET_USER_VAR() function as its const_item() may return TRUE
+    for the current thread but it still may change during the execution.
+  */
+  if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
+      ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
+  {
+    Item_cache_int *cache= new Item_cache_int();
+    /* Mark the cache as non-const to prevent re-caching. */
+    cache->set_used_tables(1);
+    cache->store(item, value);
+    *cache_arg= cache;
+    *item_arg= cache_arg;
+  }
+  return value;
+}
+
+
 int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
                                         Item **a1, Item **a2,
                                         Item_result type)
@@ -704,6 +766,7 @@ int Arg_comparator::set_cmp_func(Item_bo
     }
     is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
     func= &Arg_comparator::compare_datetime;
+    get_value_func= &get_datetime_value;
     return 0;
   }
   else if (type == STRING_RESULT && (*a)->field_type() == MYSQL_TYPE_TIME &&
@@ -712,9 +775,11 @@ int Arg_comparator::set_cmp_func(Item_bo
     /* Compare TIME values as integers. */
     thd= current_thd;
     owner= owner_arg;
-    func= ((test(owner && owner->functype() == Item_func::EQUAL_FUNC)) ?
-           &Arg_comparator::compare_e_int :
-           &Arg_comparator::compare_int_unsigned);
+    a_cache= 0;
+    b_cache= 0;
+    is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
+    func= &Arg_comparator::compare_datetime;
+    get_value_func= &get_time_value;
     return 0;
   }
 
@@ -735,8 +800,10 @@ void Arg_comparator::set_datetime_cmp_fu
   b_cache= 0;
   is_nulls_eq= FALSE;
   func= &Arg_comparator::compare_datetime;
+  get_value_func= &get_datetime_value;
 }
 
+
 /*
   Retrieves correct DATETIME value from given item.
 
@@ -850,8 +917,8 @@ int Arg_comparator::compare_datetime()
   bool is_null= FALSE;
   ulonglong a_value, b_value;
 
-  /* Get DATE/DATETIME value of the 'a' item. */
-  a_value= get_datetime_value(thd, &a, &a_cache, *b, &is_null);
+  /* Get DATE/DATETIME/TIME value of the 'a' item. */
+  a_value= (*get_value_func)(thd, &a, &a_cache, *b, &is_null);
   if (!is_nulls_eq && is_null)
   {
     if (owner)
@@ -859,8 +926,8 @@ int Arg_comparator::compare_datetime()
     return -1;
   }
 
-  /* Get DATE/DATETIME value of the 'b' item. */
-  b_value= get_datetime_value(thd, &b, &b_cache, *a, &is_null);
+  /* Get DATE/DATETIME/TIME value of the 'b' item. */
+  b_value= (*get_value_func)(thd, &b, &b_cache, *a, &is_null);
   if (is_null)
   {
     if (owner)
diff -Nrup a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
--- a/sql/item_cmpfunc.h	2007-05-07 22:19:37 +04:00
+++ b/sql/item_cmpfunc.h	2007-07-15 21:49:58 +04:00
@@ -42,6 +42,8 @@ class Arg_comparator: public Sql_alloc
   bool is_nulls_eq;                // TRUE <=> compare for the EQUAL_FUNC
   enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
                             CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
+  ulonglong (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg,
+                              Item *warn_item, bool *is_null);
 public:
   DTCollation cmp_collation;
 
Thread
bk commit into 5.0 tree (evgen:1.2526) BUG#29555eugene15 Jul