List:Commits« Previous MessageNext Message »
From:Jorgen Loland Date:March 1 2012 8:09am
Subject:bzr push into mysql-trunk branch (jorgen.loland:3708 to 3709) Bug#11764155
View as plain text  
 3709 Jorgen Loland	2012-03-01
      BUG#11764155 - INCONSISTENT 'OUT OF RANGE' WARNING MESSAGE ON 
                     SELECT
      
      When the optimizer decides to use ref access on a table, the
      conditions that are guaranteed to be satisfied by the ref 
      access itself does not need to be checked in the server.
      
      Removal of such "guaranteed by ref access" conditions is done
      by make_cond_for_table_from_pred(). One way a predicate can be
      guaranteed to be satisfied is if the consition is on the
      form "field = constant" and the field is covered by the index.
      In addition, it is required that the constant can be converted 
      to the field's type without error when test_if_ref() saves the 
      const value in the field.
      
      Consider the following query where the constant is higher than
      the maximum int value:
      
      SELECT * FROM t1 WHERE int_col = 999999999999
      
      The problem in this bug was that the value was stored using
      thd->count_cuted_fields == CHECK_FIELD_WARN. Because of this,
      store_val_in_field() would emit a warning when the too-high
      integer in the above query was stored. There is no use for this
      warning. In fact, when the range optimizer does a similar thing
      when building the ranges, get_mm_leaf() calls
      Item::save_in_field_no_warnings() instead to turn off warnings. 
      
      The fix is a simplification: the function store_val_in_field() 
      is removed and replaced with Item::save_in_field_no_warnings().
      store_val_in_field() was used only to store constants in key
      fields and was almost identical to
      Item::save_in_field_no_warnings(). The difference between these
      functions was that 
        a) the latter did not give warnings (which is desirable), and
        b) the latter accepts storing a 0000-00-00 date even when 
           the SQL mode does not permit it. This is OK and even 
           desirable because store_val_in_field() was only called for
           queries. Before this change, a query of the form 
      
              "SELECT * FROM t1 WHERE date_col = '0000-00-00'" 
      
           that was ref-accessed through an index covering date_col, 
           would not only evaluate the condition by ref-accessing in
           the index but also in the server because 
           store_val_in_field() reported "hey! NULL dates are not 
           allowed".
     @ mysql-test/r/type_date.result
        Queries should not get an "out of range" warning when an
        out-of-range constant is specified.
        Explain changes for some queries with ref-access using
        0000-00-00 date constants as lookup value. The condition is 
        guaranteed to be true in this case.
     @ sql/opt_sum.cc
        Replace store_val_in_field() with 
        Item::save_in_field_no_warnings()
     @ sql/sql_optimizer.cc
        Replace store_val_in_field() with 
        Item::save_in_field_no_warnings()
     @ sql/sql_select.cc
        Remove store_val_in_field()
     @ sql/sql_select.h
        Remove store_val_in_field()

    modified:
      mysql-test/r/type_date.result
      sql/opt_sum.cc
      sql/sql_optimizer.cc
      sql/sql_select.cc
      sql/sql_select.h
 3708 Jimmy Yang	2012-03-01
      Fix Bug #13732540 - FAILING ASSERTION: POS == NODE->FIRST_DOC_ID IF
      FTS_DOC_ID_INDEX IS MISSING
            
      rb://957 approved by Sunny Bains

    modified:
      mysql-test/suite/innodb_fts/r/innodb-fts-fic.result
      mysql-test/suite/innodb_fts/t/innodb-fts-fic.test
      storage/innobase/fts/fts0opt.cc
      storage/innobase/handler/handler0alter.cc
=== modified file 'mysql-test/r/type_date.result'
--- a/mysql-test/r/type_date.result	2012-01-24 13:17:11 +0000
+++ b/mysql-test/r/type_date.result	2012-03-01 08:09:04 +0000
@@ -203,11 +203,10 @@ a
 SET SQL_MODE=TRADITIONAL;
 EXPLAIN SELECT * FROM t1 WHERE a = '0000-00-00';
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t1	ref	i	i	4	const	1	Using where; Using index
+1	SIMPLE	t1	ref	i	i	4	const	1	Using index
 Warnings:
 Warning	1292	Incorrect date value: '0000-00-00' for column 'a' at row 1
 Warning	1292	Incorrect date value: '0000-00-00' for column 'a' at row 1
-Warning	1264	Out of range value for column 'a' at row 1
 SELECT * FROM t1 WHERE a = '0000-00-00';
 a
 0000-00-00
@@ -215,7 +214,6 @@ a
 Warnings:
 Warning	1292	Incorrect date value: '0000-00-00' for column 'a' at row 1
 Warning	1292	Incorrect date value: '0000-00-00' for column 'a' at row 1
-Warning	1264	Out of range value for column 'a' at row 1
 SELECT * FROM t2 WHERE a = '0000-00-00';
 a
 0000-00-00
@@ -243,11 +241,10 @@ a
 SET SQL_MODE=TRADITIONAL;
 EXPLAIN SELECT * FROM t1 WHERE a = '1000-00-00';
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t1	ref	i	i	4	const	1	Using where; Using index
+1	SIMPLE	t1	ref	i	i	4	const	1	Using index
 Warnings:
 Warning	1292	Incorrect date value: '1000-00-00' for column 'a' at row 1
 Warning	1292	Incorrect date value: '1000-00-00' for column 'a' at row 1
-Warning	1264	Out of range value for column 'a' at row 1
 SELECT * FROM t1 WHERE a = '1000-00-00';
 a
 1000-00-00
@@ -255,7 +252,6 @@ a
 Warnings:
 Warning	1292	Incorrect date value: '1000-00-00' for column 'a' at row 1
 Warning	1292	Incorrect date value: '1000-00-00' for column 'a' at row 1
-Warning	1264	Out of range value for column 'a' at row 1
 SELECT * FROM t2 WHERE a = '1000-00-00';
 a
 1000-00-00

=== modified file 'sql/opt_sum.cc'
--- a/sql/opt_sum.cc	2012-01-13 09:12:14 +0000
+++ b/sql/opt_sum.cc	2012-03-01 08:09:04 +0000
@@ -774,7 +774,7 @@ static bool matching_cond(bool max_fl, T
     {
       /* Update endpoints for MAX/MIN, see function comment. */
       Item *value= args[between && max_fl ? 2 : 1];
-      store_val_in_field(part->field, value, CHECK_FIELD_IGNORE);
+      value->save_in_field_no_warnings(part->field, true);
       if (part->null_bit) 
         *key_ptr++= (uchar) test(part->field->is_null());
       part->field->get_key_image(key_ptr, part->length, Field::itRAW);

=== modified file 'sql/sql_optimizer.cc'
--- a/sql/sql_optimizer.cc	2012-02-29 11:17:52 +0000
+++ b/sql/sql_optimizer.cc	2012-03-01 08:09:04 +0000
@@ -5938,7 +5938,7 @@ static bool test_if_ref(Item *root_cond,
 	    field->real_type() != MYSQL_TYPE_VARCHAR &&
 	    (field->type() != MYSQL_TYPE_FLOAT || field->decimals() == 0))
 	{
-	  return !store_val_in_field(field, right_item, CHECK_FIELD_WARN);
+	  return !right_item->save_in_field_no_warnings(field, true);
 	}
       }
     }

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2012-02-29 11:17:52 +0000
+++ b/sql/sql_select.cc	2012-03-01 08:09:04 +0000
@@ -1558,36 +1558,6 @@ get_store_key(THD *thd, Key_use *keyuse,
 			    keyuse->val);
 }
 
-/**
-  This function is only called for const items on fields which are keys.
-
-  @return
-    returns 1 if there was some conversion made when the field was stored.
-*/
-
-bool
-store_val_in_field(Field *field, Item *item, enum_check_fields check_flag)
-{
-  bool error;
-  TABLE *table= field->table;
-  THD *thd= table->in_use;
-  ha_rows cuted_fields=thd->cuted_fields;
-  my_bitmap_map *old_map= dbug_tmp_use_all_columns(table,
-                                                   table->write_set);
-
-  /*
-    we should restore old value of count_cuted_fields because
-    store_val_in_field can be called from mysql_insert 
-    with select_insert, which make count_cuted_fields= 1
-   */
-  enum_check_fields old_count_cuted_fields= thd->count_cuted_fields;
-  thd->count_cuted_fields= check_flag;
-  error= item->save_in_field(field, 1);
-  thd->count_cuted_fields= old_count_cuted_fields;
-  dbug_tmp_restore_column_map(table->write_set, old_map);
-  return error || cuted_fields != thd->cuted_fields;
-}
-
 
 /**
   Extend e1 by AND'ing e2 to the condition e1 points to. The resulting

=== modified file 'sql/sql_select.h'
--- a/sql/sql_select.h	2012-02-29 11:17:52 +0000
+++ b/sql/sql_select.h	2012-03-01 08:09:04 +0000
@@ -935,7 +935,6 @@ typedef struct st_select_check {
 } SELECT_CHECK;
 
 /* Extern functions in sql_select.cc */
-bool store_val_in_field(Field *field, Item *val, enum_check_fields check_flag);
 void count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param, 
                        List<Item> &fields, bool reset_with_sum_func);
 uint find_shortest_key(TABLE *table, const key_map *usable_keys);

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (jorgen.loland:3708 to 3709) Bug#11764155Jorgen Loland5 Mar