Commit f781e154 authored by igor@olga.mysql.com's avatar igor@olga.mysql.com
Browse files

Merge olga.mysql.com:/home/igor/mysql-5.0-opt

into  olga.mysql.com:/home/igor/dev-opt/mysql-5.0-opt-bug27545
parents c04d3727 be5485ce
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -1213,4 +1213,16 @@ a b
3	2
1	1
DROP TABLE t1;
CREATE TABLE t1 (id int, type char(6), d int, INDEX idx(id,d)) ENGINE=InnoDB;
INSERT INTO t1 VALUES 
(191, 'member', 1), (NULL, 'member', 3), (NULL, 'member', 4), (201, 'member', 2);
EXPLAIN SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	t1	ALL	idx	NULL	NULL	NULL	3	Using where; Using filesort
SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d;
id	type	d
191	member	1
NULL	member	3
NULL	member	4
DROP TABLE t1;
End of 5.0 tests
+55 −0
Original line number Diff line number Diff line
@@ -505,4 +505,59 @@ select sum(a) from t1 group by convert(a, datetime);
sum(a)
NULL
drop table t1;
create table t1 (id int(10) not null, cur_date datetime not null);
create table t2 (id int(10) not null, cur_date date not null);
insert into t1 (id, cur_date) values (1, '2007-04-25 18:30:22');
insert into t2 (id, cur_date) values (1, '2007-04-25');
explain extended
select * from t1
where id in (select id from t1 as x1 where (t1.cur_date is null));
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	PRIMARY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
2	DEPENDENT SUBQUERY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE
Warnings:
Note	1276	Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1
Note	1003	select '1' AS `id`,'2007-04-25 18:30:22' AS `cur_date` from `test`.`t1` where <in_optimizer>('1',<exists>(select 1 AS `Not_used` from `test`.`t1` `x1` where 0))
select * from t1
where id in (select id from t1 as x1 where (t1.cur_date is null));
id	cur_date
explain extended
select * from t2
where id in (select id from t2 as x1 where (t2.cur_date is null));
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	PRIMARY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
2	DEPENDENT SUBQUERY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE
Warnings:
Note	1276	Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1
Note	1003	select '1' AS `id`,'2007-04-25' AS `cur_date` from `test`.`t2` where <in_optimizer>('1',<exists>(select 1 AS `Not_used` from `test`.`t2` `x1` where 0))
select * from t2
where id in (select id from t2 as x1 where (t2.cur_date is null));
id	cur_date
insert into t1 (id, cur_date) values (2, '2007-04-26 18:30:22');
insert into t2 (id, cur_date) values (2, '2007-04-26');
explain extended
select * from t1
where id in (select id from t1 as x1 where (t1.cur_date is null));
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	2	Using where
2	DEPENDENT SUBQUERY	x1	ALL	NULL	NULL	NULL	NULL	2	Using where
Warnings:
Note	1276	Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1
Note	1003	select `test`.`t1`.`id` AS `id`,`test`.`t1`.`cur_date` AS `cur_date` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`id`,<exists>(select 1 AS `Not_used` from `test`.`t1` `x1` where ((`test`.`t1`.`cur_date` = 0) and (<cache>(`test`.`t1`.`id`) = `test`.`x1`.`id`))))
select * from t1
where id in (select id from t1 as x1 where (t1.cur_date is null));
id	cur_date
explain extended
select * from t2
where id in (select id from t2 as x1 where (t2.cur_date is null));
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where
2	DEPENDENT SUBQUERY	x1	ALL	NULL	NULL	NULL	NULL	2	Using where
Warnings:
Note	1276	Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1
Note	1003	select `test`.`t2`.`id` AS `id`,`test`.`t2`.`cur_date` AS `cur_date` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`id`,<exists>(select 1 AS `Not_used` from `test`.`t2` `x1` where ((`test`.`t2`.`cur_date` = 0) and (<cache>(`test`.`t2`.`id`) = `test`.`x1`.`id`))))
select * from t2
where id in (select id from t2 as x1 where (t2.cur_date is null));
id	cur_date
drop table t1,t2;
End of 5.0 tests
+15 −0
Original line number Diff line number Diff line
@@ -960,4 +960,19 @@ SELECT * FROM t1 ORDER BY b DESC, a ASC;

DROP TABLE t1;

#
# Bug #32815: query with ORDER BY and a possible ref_or_null access
#

CREATE TABLE t1 (id int, type char(6), d int, INDEX idx(id,d)) ENGINE=InnoDB;
INSERT INTO t1 VALUES 
  (191, 'member', 1), (NULL, 'member', 3), (NULL, 'member', 4), (201, 'member', 2); 

EXPLAIN SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d;
SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d;

DROP TABLE t1;



--echo End of 5.0 tests
+37 −0
Original line number Diff line number Diff line
@@ -338,4 +338,41 @@ insert into t1 values (), (), ();
select sum(a) from t1 group by convert(a, datetime);
drop table t1;

#
# Bug #32694: NOT NULL table field in a subquery produces invalid results
#
create table t1 (id int(10) not null, cur_date datetime not null);
create table t2 (id int(10) not null, cur_date date not null);
insert into t1 (id, cur_date) values (1, '2007-04-25 18:30:22');
insert into t2 (id, cur_date) values (1, '2007-04-25');

explain extended
select * from t1
where id in (select id from t1 as x1 where (t1.cur_date is null));
select * from t1
where id in (select id from t1 as x1 where (t1.cur_date is null));

explain extended
select * from t2
where id in (select id from t2 as x1 where (t2.cur_date is null));
select * from t2
where id in (select id from t2 as x1 where (t2.cur_date is null));

insert into t1 (id, cur_date) values (2, '2007-04-26 18:30:22');
insert into t2 (id, cur_date) values (2, '2007-04-26');

explain extended
select * from t1
where id in (select id from t1 as x1 where (t1.cur_date is null));
select * from t1
where id in (select id from t1 as x1 where (t1.cur_date is null));

explain extended
select * from t2
where id in (select id from t2 as x1 where (t2.cur_date is null));
select * from t2
where id in (select id from t2 as x1 where (t2.cur_date is null));

drop table t1,t2;

--echo End of 5.0 tests
+41 −26
Original line number Diff line number Diff line
@@ -24,7 +24,8 @@
#include <m_ctype.h>
#include "sql_select.h"

static bool convert_constant_item(THD *thd, Field *field, Item **item);
static bool convert_constant_item(THD *thd, Item_field *field_item,
                                  Item **item);

static Item_result item_store_type(Item_result a, Item *item,
                                   my_bool unsigned_flag)
@@ -317,7 +318,7 @@ longlong Item_func_nop_all::val_int()
  SYNOPSIS
    convert_constant_item()
    thd             thread handle
    field           item will be converted using the type of this field
    field_item      item will be converted using the type of this field
    item  [in/out]  reference to the item to convert

  DESCRIPTION
@@ -340,30 +341,46 @@ longlong Item_func_nop_all::val_int()
  1	Item was replaced with an integer version of the item
*/

static bool convert_constant_item(THD *thd, Field *field, Item **item)
static bool convert_constant_item(THD *thd, Item_field *field_item,
                                  Item **item)
{
  Field *field= field_item->field;
  int result= 0;

  if (!(*item)->with_subselect && (*item)->const_item())
  {
    /* For comparison purposes allow invalid dates like 2000-01-32 */
    ulong orig_sql_mode= thd->variables.sql_mode;
    enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
    ulonglong orig_field_val; /* original field value if valid */
    thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | 
                             MODE_INVALID_DATES;
    thd->count_cuted_fields= CHECK_FIELD_IGNORE;
    /*
      Store the value of the field if it references an outer field because
      the call to save_in_field below overrides that value.
    */
    if (field_item->depended_from)
      orig_field_val= field->val_int();
    if (!(*item)->is_null() && !(*item)->save_in_field(field, 1))
    {
      Item *tmp=new Item_int_with_ref(field->val_int(), *item,
                                      test(field->flags & UNSIGNED_FLAG));
      thd->variables.sql_mode= orig_sql_mode;
      thd->count_cuted_fields= orig_count_cuted_fields;
      if (tmp)
        thd->change_item_tree(item, tmp);
      return 1;					// Item was replaced
      result= 1;					// Item was replaced
    }
    /* Restore the original field value. */
    if (field_item->depended_from)
    {
      result= field->store(orig_field_val, TRUE);
      /* orig_field_val must be a valid value that can be restored back. */
      DBUG_ASSERT(!result);
    }
    thd->variables.sql_mode= orig_sql_mode;
    thd->count_cuted_fields= orig_count_cuted_fields;
  }
  return 0;
  return result;
}


@@ -411,15 +428,14 @@ void Item_bool_func2::fix_length_and_dec()
  thd= current_thd;
  if (!thd->is_context_analysis_only())
  {
    Item *arg_real_item= args[0]->real_item();
    if (arg_real_item->type() == FIELD_ITEM)
    if (args[0]->real_item()->type() == FIELD_ITEM)
    {
      Field *field=((Item_field*) arg_real_item)->field;
      if (field->can_be_compared_as_longlong() &&
          !(arg_real_item->is_datetime() &&
      Item_field *field_item= (Item_field*) (args[0]->real_item());
      if (field_item->field->can_be_compared_as_longlong() &&
          !(field_item->is_datetime() &&
            args[1]->result_type() == STRING_RESULT))
      {
        if (convert_constant_item(thd, field,&args[1]))
        if (convert_constant_item(thd, field_item, &args[1]))
        {
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
                           INT_RESULT);		// Works for all types.
@@ -428,15 +444,14 @@ void Item_bool_func2::fix_length_and_dec()
        }
      }
    }
    arg_real_item= args[1]->real_item();
    if (arg_real_item->type() == FIELD_ITEM)
    if (args[1]->real_item()->type() == FIELD_ITEM)
    {
      Field *field=((Item_field*) arg_real_item)->field;
      if (field->can_be_compared_as_longlong() &&
          !(arg_real_item->is_datetime() &&
      Item_field *field_item= (Item_field*) (args[1]->real_item());
      if (field_item->field->can_be_compared_as_longlong() &&
          !(field_item->is_datetime() &&
            args[0]->result_type() == STRING_RESULT))
      {
        if (convert_constant_item(thd, field,&args[0]))
        if (convert_constant_item(thd, field_item, &args[0]))
        {
          cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
                           INT_RESULT); // Works for all types.
@@ -1889,16 +1904,16 @@ void Item_func_between::fix_length_and_dec()
           thd->lex->sql_command != SQLCOM_CREATE_VIEW &&
           thd->lex->sql_command != SQLCOM_SHOW_CREATE)
  {
    Field *field=((Item_field*) (args[0]->real_item()))->field;
    if (field->can_be_compared_as_longlong())
    Item_field *field_item= (Item_field*) (args[0]->real_item());
    if (field_item->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]))
      if (convert_constant_item(thd, field_item, &args[1]))
        cmp_type=INT_RESULT;			// Works for all types.
      if (convert_constant_item(thd, field,&args[2]))
      if (convert_constant_item(thd, field_item, &args[2]))
        cmp_type=INT_RESULT;			// Works for all types.
    }
  }
@@ -3491,13 +3506,13 @@ void Item_func_in::fix_length_and_dec()
          thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
          cmp_type != INT_RESULT)
      {
        Field *field= ((Item_field*) (args[0]->real_item()))->field;
        if (field->can_be_compared_as_longlong())
        Item_field *field_item= (Item_field*) (args[0]->real_item());
        if (field_item->field->can_be_compared_as_longlong())
        {
          bool all_converted= TRUE;
          for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
          {
            if (!convert_constant_item (thd, field, &arg[0]))
            if (!convert_constant_item (thd, field_item, &arg[0]))
              all_converted= FALSE;
          }
          if (all_converted)
Loading