List:Commits« Previous MessageNext Message »
From:ramil Date:November 23 2007 12:14pm
Subject:bk commit into 5.0 tree (ramil:1.2578) BUG#32560
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of ram. When ram 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-11-23 16:14:29+04:00, ramil@stripped +3 -0
  Fix for bug #32560: crash with interval function and count(*)
  
  Problem: INTERVAL function implementation doesn't handle NULL range values.
  
  Fix: skip NULL ranges looking for a proper one.

  mysql-test/r/func_set.result@stripped, 2007-11-23 16:14:28+04:00, ramil@stripped +30 -0
    Fix for bug #32560: crash with interval function and count(*)
      - test result.

  mysql-test/t/func_set.test@stripped, 2007-11-23 16:14:28+04:00, ramil@stripped +18 -1
    Fix for bug #32560: crash with interval function and count(*)
      - test case.

  sql/item_cmpfunc.cc@stripped, 2007-11-23 16:14:28+04:00, ramil@stripped +26 -13
    Fix for bug #32560: crash with interval function and count(*)
      - skip NULL ranges calculating INTERVAL(...).

diff -Nrup a/mysql-test/r/func_set.result b/mysql-test/r/func_set.result
--- a/mysql-test/r/func_set.result	2005-02-19 20:58:20 +04:00
+++ b/mysql-test/r/func_set.result	2007-11-23 16:14:28 +04:00
@@ -73,3 +73,33 @@ find_in_set(binary 'a', 'A,B,C')
 select find_in_set('1','3,1,');
 find_in_set('1','3,1,')
 2
+End of 4.1 tests
+SELECT INTERVAL(0.0, NULL);
+INTERVAL(0.0, NULL)
+1
+SELECT INTERVAL(0.0, CAST(NULL AS DECIMAL));
+INTERVAL(0.0, CAST(NULL AS DECIMAL))
+1
+SELECT INTERVAL(0.0, CAST(DATE(NULL) AS DECIMAL));
+INTERVAL(0.0, CAST(DATE(NULL) AS DECIMAL))
+1
+SELECT INTERVAL(0.0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+INTERVAL(0.0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
+8
+SELECT INTERVAL(0.0, CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), 
+CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), 
+CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL));
+INTERVAL(0.0, CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), 
+CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), 
+CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL))
+8
+SELECT INTERVAL(0.0, CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL),
+CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL),
+CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL),
+CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL));
+INTERVAL(0.0, CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL),
+CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL),
+CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL),
+CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL))
+8
+End of 5.0 tests
diff -Nrup a/mysql-test/t/func_set.test b/mysql-test/t/func_set.test
--- a/mysql-test/t/func_set.test	2005-07-28 18:12:33 +05:00
+++ b/mysql-test/t/func_set.test	2007-11-23 16:14:28 +04:00
@@ -54,4 +54,21 @@ select find_in_set(binary 'a', 'A,B,C');
 #
 select find_in_set('1','3,1,');
 
-# End of 4.1 tests
+--echo End of 4.1 tests
+
+#
+# Bug #32560: crash with interval function and count(*)
+#
+SELECT INTERVAL(0.0, NULL);
+SELECT INTERVAL(0.0, CAST(NULL AS DECIMAL));
+SELECT INTERVAL(0.0, CAST(DATE(NULL) AS DECIMAL));
+SELECT INTERVAL(0.0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+SELECT INTERVAL(0.0, CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), 
+  CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), 
+  CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL), CAST(NULL AS DECIMAL));
+SELECT INTERVAL(0.0, CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL),
+  CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL),
+  CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL),
+  CAST(DATE(NULL) AS DECIMAL), CAST(DATE(NULL) AS DECIMAL));
+
+--echo End of 5.0 tests
diff -Nrup a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
--- a/sql/item_cmpfunc.cc	2007-11-10 23:58:21 +04:00
+++ b/sql/item_cmpfunc.cc	2007-11-23 16:14:28 +04:00
@@ -1638,24 +1638,27 @@ bool Item_func_opt_neg::eq(const Item *i
 
 void Item_func_interval::fix_length_and_dec()
 {
+  uint rows= row->cols();
+  
   use_decimal_comparison= (row->element_index(0)->result_type() == DECIMAL_RESULT) ||
     (row->element_index(0)->result_type() == INT_RESULT);
-  if (row->cols() > 8)
+  if (rows > 8)
   {
-    bool consts=1;
+    bool not_null_consts= TRUE;
 
-    for (uint i=1 ; consts && i < row->cols() ; i++)
+    for (uint i= 1; not_null_consts && i < rows; i++)
     {
-      consts&= row->element_index(i)->const_item();
+      Item *el= row->element_index(i);
+      not_null_consts&= el->const_item() & !el->is_null();
     }
 
-    if (consts &&
+    if (not_null_consts &&
         (intervals=
-          (interval_range*) sql_alloc(sizeof(interval_range)*(row->cols()-1))))
+          (interval_range*) sql_alloc(sizeof(interval_range) * (rows - 1))))
     {
       if (use_decimal_comparison)
       {
-        for (uint i=1 ; i < row->cols(); i++)
+        for (uint i= 1; i < rows; i++)
         {
           Item *el= row->element_index(i);
           interval_range *range= intervals + (i-1);
@@ -1680,7 +1683,7 @@ void Item_func_interval::fix_length_and_
       }
       else
       {
-        for (uint i=1 ; i < row->cols(); i++)
+        for (uint i= 1; i < rows; i++)
         {
           intervals[i-1].dbl= row->element_index(i)->val_real();
         }
@@ -1771,12 +1774,22 @@ longlong Item_func_interval::val_int()
         ((el->result_type() == DECIMAL_RESULT) ||
          (el->result_type() == INT_RESULT)))
     {
-      my_decimal e_dec_buf, *e_dec= row->element_index(i)->val_decimal(&e_dec_buf);
-      if (my_decimal_cmp(e_dec, dec) > 0)
-        return i-1;
+      my_decimal e_dec_buf, *e_dec= el->val_decimal(&e_dec_buf);
+      /* Skip NULL ranges. */
+      if (el->null_value)
+        continue;
+      else if (my_decimal_cmp(e_dec, dec) > 0)
+        return i - 1;
+    }
+    else 
+    {
+      double val= el->val_real();
+      /* Skip NULL ranges. */
+      if (el->null_value)
+        continue;
+      else if (val > value)
+        return i - 1;
     }
-    else if (row->element_index(i)->val_real() > value)
-      return i-1;
   }
   return i-1;
 }
Thread
bk commit into 5.0 tree (ramil:1.2578) BUG#32560ramil23 Nov