List:Commits« Previous MessageNext Message »
From:gkodinov Date:September 15 2006 2:14pm
Subject:bk commit into 5.0 tree (gkodinov:1.2266)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of gkodinov. When gkodinov 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, 2006-09-15 14:14:38+02:00, gkodinov@stripped +13 -0
  Merge dl145s.mysql.com:/data/bk/team_tree_merge/MERGE/mysql-4.1-opt
  into  dl145s.mysql.com:/data/bk/team_tree_merge/MERGE/mysql-5.0-opt
  MERGE: 1.1616.2144.216

  mysql-test/r/func_time.result@stripped, 2006-09-15 12:01:11+02:00, gkodinov@stripped
+1 -1
    MERGE: 1.23.6.2

  mysql-test/r/insert_update.result@stripped, 2006-09-15 12:02:56+02:00,
gkodinov@stripped +1 -2
    MERGE: 1.9.7.2

  mysql-test/r/query_cache.result@stripped, 2006-09-15 11:54:09+02:00,
gkodinov@stripped +0 -3
    Auto merged
    MERGE: 1.26.1.36

  mysql-test/r/subselect.result@stripped, 2006-09-15 11:54:09+02:00,
gkodinov@stripped +0 -0
    Auto merged
    MERGE: 1.67.1.115

  mysql-test/r/type_date.result@stripped, 2006-09-15 11:54:09+02:00, gkodinov@stripped
+0 -0
    Auto merged
    MERGE: 1.12.1.2

  mysql-test/t/func_time.test@stripped, 2006-09-15 11:54:09+02:00, gkodinov@stripped
+0 -0
    Auto merged
    MERGE: 1.21.5.2

  mysql-test/t/insert_update.test@stripped, 2006-09-15 11:54:09+02:00,
gkodinov@stripped +0 -0
    Auto merged
    MERGE: 1.13.1.5

  sql/item.h@stripped, 2006-09-15 11:54:09+02:00, gkodinov@stripped +0 -0
    Auto merged
    MERGE: 1.56.1.140

  sql/item_cmpfunc.cc@stripped, 2006-09-15 14:09:06+02:00, gkodinov@stripped +1 -7
    MERGE: 1.111.23.12

  sql/log.cc@stripped, 2006-09-15 11:54:10+02:00, gkodinov@stripped +0 -0
    Auto merged
    MERGE: 1.108.1.58

  sql/sql_parse.cc@stripped, 2006-09-15 11:54:10+02:00, gkodinov@stripped +0 -0
    Auto merged
    MERGE: 1.271.1.216

  sql/sql_select.cc@stripped, 2006-09-15 14:14:34+02:00, gkodinov@stripped +7 -5
    MERGE: 1.216.125.8

  sql/sql_yacc.yy@stripped, 2006-09-15 11:54:10+02:00, gkodinov@stripped +0 -0
    Auto merged
    MERGE: 1.203.1.197

# 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:	gkodinov
# Host:	dl145s.mysql.com
# Root:	/data/bk/team_tree_merge/MERGE/mysql-5.0-opt/RESYNC

--- 1.208/sql/item.h	2006-09-15 14:14:43 +02:00
+++ 1.209/sql/item.h	2006-09-15 14:14:43 +02:00
@@ -2184,7 +2184,11 @@
   {
     return Item_field::save_in_field(field_arg, no_conversions);
   }
-  table_map used_tables() const { return (table_map)0L; }
+  /* 
+   We use RAND_TABLE_BIT to prevent Item_insert_value from
+   being treated as a constant and precalculated before execution
+  */
+  table_map used_tables() const { return RAND_TABLE_BIT; }
 
   bool walk(Item_processor processor, byte *args)
   {

--- 1.218/sql/item_cmpfunc.cc	2006-09-15 14:14:43 +02:00
+++ 1.219/sql/item_cmpfunc.cc	2006-09-15 14:14:44 +02:00
@@ -77,131 +77,14 @@
     This function aggregates result types from the array of items. Found type
     supposed to be used later for comparison of values of these items.
     Aggregation itself is performed by the item_cmp_type() function.
-
-  NOTES
-    Aggregation rules:
-    If there are DATE/TIME fields/functions in the list and no string
-    fields/functions in the list then:
-      The INT_RESULT type will be used for aggregation instead of original
-      result type of any DATE/TIME field/function in the list
-      All constant items in the list will be converted to a DATE/TIME using
-      found field or result field of found function.
-
-    Implementation notes:
-      The code is equivalent to:
-      1. Check the list for presence of a STRING field/function.
-         Collect the is_const flag.
-      2. Get a Field* object to use for type coercion
-      3. Perform type conversion.
-      1 and 2 are implemented in 2 loops. The first searches for a DATE/TIME
-      field/function and checks presence of a STRING field/function.
-      The second loop works only if a DATE/TIME field/function is found.
-      It checks presence of a STRING field/function in the rest of the list.
-
-  TODO
-    1) The current implementation can produce false comparison results for
-    expressions like:
-      date_time_field BETWEEN string_field_with_dates AND string_constant
-    if the string_constant will omit some of leading zeroes.
-    In order to fully implement correct comparison of DATE/TIME the new
-    DATETIME_RESULT result type should be introduced and agg_cmp_type()
-    should return the DATE/TIME field used for the conversion. Later
-    this field can be used by comparison functions like Item_func_between to
-    convert string values to ints on the fly and thus return correct results.
-    This modification will affect functions BETWEEN, IN and CASE.
-
-    2) If in the list a DATE field/function and a DATETIME field/function
-    are present in the list then the first found field/function will be
-    used for conversion. This may lead to wrong results and probably should
-    be fixed.
 */
 
 static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
 {
   uint i;
-  Item::Type res= (Item::Type)0;
-  /* Used only for date/time fields, max_length = 19 */
-  char buff[20];
-  uchar null_byte;
-  Field *field= NULL;
-
-  /*
-    Do not convert items while creating a or showing a view in order
-    to store/display the original query in these cases.
-  */
-  if (thd->lex->sql_command != SQLCOM_CREATE_VIEW &&
-      thd->lex->sql_command != SQLCOM_SHOW_CREATE)
-  {
-    /* Search for date/time fields/functions */
-    for (i= 0; i < nitems; i++)
-    {
-      if (!items[i]->result_as_longlong())
-      {
-        /* Do not convert anything if a string field/function is present */
-        if (!items[i]->const_item() && items[i]->result_type() ==
STRING_RESULT)
-        {
-          i= nitems;
-          break;
-        }
-        continue;
-      }
-      if ((res= items[i]->real_item()->type()) == Item::FIELD_ITEM &&
-          items[i]->result_type() != INT_RESULT)
-      {
-        field= ((Item_field *)items[i]->real_item())->field;
-        break;
-      }
-      else if (res == Item::FUNC_ITEM)
-      {
-        field= items[i]->tmp_table_field_from_field_type(0);
-        if (field)
-          field->move_field(buff, &null_byte, 0);
-        break;
-      }
-    }
-  }
-  if (field)
-  {
-    /* Check the rest of the list for presence of a string field/function. */
-    for (i++ ; i < nitems; i++)
-    {
-      if (!items[i]->const_item() && items[i]->result_type() ==
STRING_RESULT &&
-          !items[i]->result_as_longlong())
-      {
-        if (res == Item::FUNC_ITEM)
-          delete field;
-        field= 0;
-        break;
-      }
-    }
-  }
-  /*
-    If the first item is a date/time function then its result should be
-    compared as int
-  */
-  if (field)
-    /* Suppose we are comparing dates */
-    type[0]= INT_RESULT;
-  else
-    type[0]= items[0]->result_type();
-
-  for (i= 0; i < nitems ; i++)
-  {
-    Item_result result= items[i]->result_type();
-    /*
-      Use INT_RESULT as result type for DATE/TIME fields/functions and
-      for constants successfully converted to DATE/TIME
-    */
-    if (field &&
-         ((!items[i]->const_item() && items[i]->result_as_longlong()) ||
-         (items[i]->const_item() && convert_constant_item(thd, field,
-                                                          &items[i]))))
-      result= INT_RESULT;
-    type[0]= item_cmp_type(type[0], result);
-  }
-
-  if (res == Item::FUNC_ITEM && field)
-    delete field;
+  type[0]= items[0]->result_type();
+  for (i= 1 ; i < nitems ; i++)
+    type[0]= item_cmp_type(type[0], items[i]->result_type());
 }
 
 
@@ -1220,10 +1103,30 @@
   if (!args[0] || !args[1] || !args[2])
     return;
   agg_cmp_type(thd, &cmp_type, args, 3);
-  args[0]->cmp_context= args[1]->cmp_context= args[2]->cmp_context= cmp_type;
+  if (cmp_type == STRING_RESULT &&
+      agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1))
+   return;
 
-  if (cmp_type == STRING_RESULT)
-      agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1);
+  /*
+    Make a special case of compare with date/time and longlong fields.
+    They are compared as integers, so for const item this time-consuming
+    conversion can be done only once, not for every single comparison
+  */
+  if (args[0]->type() == FIELD_ITEM)
+  {
+    Field *field=((Item_field*) args[0])->field;
+    if (field->can_be_compared_as_longlong())
+    {
+      /*
+        The following can't be recoded with || as convert_constant_item
+        changes the argument
+      */
+      if (convert_constant_item(thd, field,&args[1]))
+	cmp_type=INT_RESULT;			// Works for all types.
+      if (convert_constant_item(thd, field,&args[2]))
+	cmp_type=INT_RESULT;			// Works for all types.
+    }
+  }
 }
 
 

--- 1.452/sql/sql_select.cc	2006-09-15 14:14:44 +02:00
+++ 1.453/sql/sql_select.cc	2006-09-15 14:14:44 +02:00
@@ -9114,10 +9114,11 @@
     keyinfo->rec_per_key=0;
     keyinfo->algorithm= HA_KEY_ALG_UNDEF;
     keyinfo->name= (char*) "group_key";
-    for (; group ; group=group->next,key_part_info++)
+    ORDER *cur_group= group;
+    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
     {
-      Field *field=(*group->item)->get_tmp_table_field();
-      bool maybe_null=(*group->item)->maybe_null;
+      Field *field=(*cur_group->item)->get_tmp_table_field();
+      bool maybe_null=(*cur_group->item)->maybe_null;
       key_part_info->null_bit=0;
       key_part_info->field=  field;
       key_part_info->offset= field->offset();
@@ -9130,8 +9131,8 @@
 	0 : FIELDFLAG_BINARY;
       if (!using_unique_constraint)
       {
-	group->buff=(char*) group_buff;
-	if (!(group->field= field->new_key_field(thd->mem_root,table,
+	cur_group->buff=(char*) group_buff;
+	if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
                                                  (char*) group_buff +
                                                  test(maybe_null),
                                                  field->null_ptr,
@@ -9149,12 +9150,12 @@
 	  key_part_info->null_bit=field->null_bit;
 	  key_part_info->null_offset= (uint) (field->null_ptr -
 					      (uchar*) table->record[0]);
-          group->buff++;                        // Pointer to field data
+          cur_group->buff++;                        // Pointer to field data
 	  group_buff++;                         // Skipp null flag
 	}
         /* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */
         key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL;
-	group_buff+= group->field->pack_length();
+	group_buff+= cur_group->field->pack_length();
       }
       keyinfo->key_length+=  key_part_info->length;
     }

--- 1.67/mysql-test/r/func_time.result	2006-09-15 14:14:44 +02:00
+++ 1.68/mysql-test/r/func_time.result	2006-09-15 14:14:44 +02:00
@@ -840,34 +840,34 @@
 create table t1(f1 date, f2 time, f3 datetime);
 insert into t1 values ("2006-01-01", "12:01:01", "2006-01-01 12:01:01");
 insert into t1 values ("2006-01-02", "12:01:02", "2006-01-02 12:01:02");
-select f1 from t1 where f1 between "2006-1-1" and 20060101;
+select f1 from t1 where f1 between CAST("2006-1-1" as date) and CAST(20060101 as date);
 f1
 2006-01-01
-select f1 from t1 where f1 between "2006-1-1" and "2006.1.1";
+select f1 from t1 where f1 between cast("2006-1-1" as date) and cast("2006.1.1" as date);
 f1
 2006-01-01
-select f1 from t1 where date(f1) between "2006-1-1" and "2006.1.1";
+select f1 from t1 where date(f1) between cast("2006-1-1" as date) and cast("2006.1.1" as
date);
 f1
 2006-01-01
-select f2 from t1 where f2 between "12:1:2" and "12:2:2";
+select f2 from t1 where f2 between cast("12:1:2" as time) and cast("12:2:2" as time);
 f2
 12:01:02
-select f2 from t1 where time(f2) between "12:1:2" and "12:2:2";
+select f2 from t1 where time(f2) between cast("12:1:2" as time) and cast("12:2:2" as
time);
 f2
 12:01:02
-select f3 from t1 where f3 between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
+select f3 from t1 where f3 between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1
12:1:2" as datetime);
 f3
 2006-01-01 12:01:01
-select f3 from t1 where timestamp(f3) between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
+select f3 from t1 where timestamp(f3) between cast("2006-1-1 12:1:1" as datetime) and
cast("2006-1-1 12:1:2" as datetime);
 f3
 2006-01-01 12:01:01
-select f1 from t1 where "2006-1-1" between f1 and f3;
+select f1 from t1 where cast("2006-1-1" as date) between f1 and f3;
 f1
 2006-01-01
-select f1 from t1 where "2006-1-1" between date(f1) and date(f3);
+select f1 from t1 where cast("2006-1-1" as date) between date(f1) and date(f3);
 f1
 2006-01-01
-select f1 from t1 where "2006-1-1" between f1 and 'zzz';
+select f1 from t1 where cast("2006-1-1" as date) between f1 and 'zzz';
 f1
 Warnings:
 Warning	1292	Incorrect date value: 'zzz' for column 'f1' at row 1

--- 1.13/mysql-test/r/type_date.result	2006-09-15 14:14:44 +02:00
+++ 1.14/mysql-test/r/type_date.result	2006-09-15 14:14:44 +02:00
@@ -27,12 +27,12 @@
 INSERT INTO t1 VALUES ( "2000-1-3" );
 INSERT INTO t1 VALUES ( "2000-1-4" );
 INSERT INTO t1 VALUES ( "2000-1-5" );
-SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND "2000-1-4";
+SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND cast("2000-1-4" as
date);
 datum
 2000-01-02
 2000-01-03
 2000-01-04
-SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND datum - INTERVAL 100 DAY;
+SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND datum - INTERVAL 100
DAY;
 datum
 DROP TABLE t1;
 CREATE TABLE t1 (
@@ -104,3 +104,9 @@
 y
 0000
 DROP TABLE t1;
+create table t1(start_date date, end_date date);
+insert into t1 values ('2000-01-01','2000-01-02');
+select 1 from t1 where cast('2000-01-01 12:01:01' as datetime) between start_date and
end_date;
+1
+1
+drop table t1;

--- 1.55/mysql-test/t/func_time.test	2006-09-15 14:14:44 +02:00
+++ 1.56/mysql-test/t/func_time.test	2006-09-15 14:14:44 +02:00
@@ -419,20 +419,20 @@
 #
 # Bug#16377 result of DATE/TIME functions were compared as strings which
 #           can lead to a wrong result.
-#
+# Now wrong dates should be compared only with CAST()
 create table t1(f1 date, f2 time, f3 datetime);
 insert into t1 values ("2006-01-01", "12:01:01", "2006-01-01 12:01:01");
 insert into t1 values ("2006-01-02", "12:01:02", "2006-01-02 12:01:02");
-select f1 from t1 where f1 between "2006-1-1" and 20060101;
-select f1 from t1 where f1 between "2006-1-1" and "2006.1.1";
-select f1 from t1 where date(f1) between "2006-1-1" and "2006.1.1";
-select f2 from t1 where f2 between "12:1:2" and "12:2:2";
-select f2 from t1 where time(f2) between "12:1:2" and "12:2:2";
-select f3 from t1 where f3 between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
-select f3 from t1 where timestamp(f3) between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
-select f1 from t1 where "2006-1-1" between f1 and f3;
-select f1 from t1 where "2006-1-1" between date(f1) and date(f3);
-select f1 from t1 where "2006-1-1" between f1 and 'zzz';
+select f1 from t1 where f1 between CAST("2006-1-1" as date) and CAST(20060101 as date);
+select f1 from t1 where f1 between cast("2006-1-1" as date) and cast("2006.1.1" as date);
+select f1 from t1 where date(f1) between cast("2006-1-1" as date) and cast("2006.1.1" as
date);
+select f2 from t1 where f2 between cast("12:1:2" as time) and cast("12:2:2" as time);
+select f2 from t1 where time(f2) between cast("12:1:2" as time) and cast("12:2:2" as
time);
+select f3 from t1 where f3 between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1
12:1:2" as datetime);
+select f3 from t1 where timestamp(f3) between cast("2006-1-1 12:1:1" as datetime) and
cast("2006-1-1 12:1:2" as datetime);
+select f1 from t1 where cast("2006-1-1" as date) between f1 and f3;
+select f1 from t1 where cast("2006-1-1" as date) between date(f1) and date(f3);
+select f1 from t1 where cast("2006-1-1" as date) between f1 and 'zzz';
 select f1 from t1 where makedate(2006,1) between date(f1) and date(f3);
 select f1 from t1 where makedate(2006,2) between date(f1) and date(f3);
 drop table t1;

--- 1.19/mysql-test/r/insert_update.result	2006-09-15 14:14:44 +02:00
+++ 1.20/mysql-test/r/insert_update.result	2006-09-15 14:14:44 +02:00
@@ -63,9 +63,9 @@
 Note	1003	select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS
`c`,values(`test`.`t1`.`a`) AS `VALUES(a)` from `test`.`t1`
 explain extended select * from t1 where values(a);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	5	Using where
 Warnings:
-Note	1003	select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`
from `test`.`t1`
+Note	1003	select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`
from `test`.`t1` where values(`test`.`t1`.`a`)
 DROP TABLE t1;
 create table t1(a int primary key, b int);
 insert into t1 values(1,1),(2,2),(3,3),(4,4),(5,5);
@@ -196,4 +196,26 @@
 PRIMARY KEY  (a)
 ) ENGINE=MyISAM;
 INSERT INTO t1 ( a ) SELECT 0 ON DUPLICATE KEY UPDATE a = a + VALUES (a) ;
+DROP TABLE t1;
+CREATE TABLE t1
+(
+a   BIGINT UNSIGNED,
+b   BIGINT UNSIGNED,
+PRIMARY KEY (a)
+);
+INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b =
+IF(VALUES(b) > t1.b, VALUES(b), t1.b);
+SELECT * FROM t1;
+a	b
+45	1
+INSERT INTO t1 VALUES (45, 2) ON DUPLICATE KEY UPDATE b =
+IF(VALUES(b) > t1.b, VALUES(b), t1.b);
+SELECT * FROM t1;
+a	b
+45	2
+INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b = 
+IF(VALUES(b) > t1.b, VALUES(b), t1.b);
+SELECT * FROM t1;
+a	b
+45	2
 DROP TABLE t1;

--- 1.19/mysql-test/t/insert_update.test	2006-09-15 14:14:44 +02:00
+++ 1.20/mysql-test/t/insert_update.test	2006-09-15 14:14:44 +02:00
@@ -115,4 +115,27 @@
 
 DROP TABLE t1;
 
+#
+# Bug#21555: incorrect behavior with INSERT ... ON DUPL KEY UPDATE and VALUES
+#
+
+
 # End of 4.1 tests
+CREATE TABLE t1
+(
+  a   BIGINT UNSIGNED,
+  b   BIGINT UNSIGNED,
+  PRIMARY KEY (a)
+);
+
+INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b =
+  IF(VALUES(b) > t1.b, VALUES(b), t1.b);
+SELECT * FROM t1;
+INSERT INTO t1 VALUES (45, 2) ON DUPLICATE KEY UPDATE b =
+  IF(VALUES(b) > t1.b, VALUES(b), t1.b);
+SELECT * FROM t1;
+INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b = 
+  IF(VALUES(b) > t1.b, VALUES(b), t1.b);
+SELECT * FROM t1;
+
+DROP TABLE t1;
Thread
bk commit into 5.0 tree (gkodinov:1.2266)gkodinov15 Sep