[Commits] Rev 3486: Fixed MDEV-3894: Server crashes in Item_field::Item_field with exists_to_in=on and NOT EXISTS from a merge view.: Correct work with Item_direct_view_ref added. in file:///home/bell/maria/bzr/work-maria-10.0-exists2in/

sanja at montyprogram.com sanja at montyprogram.com
Thu Nov 29 20:42:36 EET 2012


At file:///home/bell/maria/bzr/work-maria-10.0-exists2in/

------------------------------------------------------------
revno: 3486
revision-id: sanja at montyprogram.com-20121129184233-zxp9qe77tfcupomh
parent: sanja at montyprogram.com-20121129101823-k7kt2gjym2mmiqe7
committer: sanja at montyprogram.com
branch nick: work-maria-10.0-exists2in
timestamp: Thu 2012-11-29 20:42:33 +0200
message:
  Fixed MDEV-3894: Server crashes in Item_field::Item_field with exists_to_in=on and NOT EXISTS from a merge view.: Correct work with Item_direct_view_ref added.
  
  Fixed condition about maybe_null local fields.
  
  Removed adding IS NOT NULL for fields which can't be NULL.
-------------- next part --------------
=== modified file 'mysql-test/r/subselect_exists2in.result'
--- a/mysql-test/r/subselect_exists2in.result	2012-11-29 10:18:23 +0000
+++ b/mysql-test/r/subselect_exists2in.result	2012-11-29 18:42:33 +0000
@@ -327,10 +327,10 @@ SELECT ( SELECT b FROM t2 WHERE NOT EXIS
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	2	100.00	
 2	SUBQUERY	t2	system	NULL	NULL	NULL	NULL	1	100.00	
-3	MATERIALIZED	t3	ALL	NULL	NULL	NULL	NULL	2	100.00	
+3	MATERIALIZED	t3	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where
 Warnings:
 Note	1276	Field or reference 'test.t2.b' of SELECT #3 was resolved in SELECT #2
-Note	1003	select (select 1 from dual where (not(((1 is not null) and <in_optimizer>(1,1 in ( <materialize> (select `test`.`t3`.`c` from `test`.`t3` where 1 ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `<subquery3>`.`c`))))))))) AS `( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) )` from `test`.`t1`
+Note	1003	select (select 1 from dual where (not(((1 is not null) and <in_optimizer>(1,1 in ( <materialize> (select `test`.`t3`.`c` from `test`.`t3` where (`test`.`t3`.`c` is not null) ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `<subquery3>`.`c`))))))))) AS `( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) )` from `test`.`t1`
 SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1;
 ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) )
 1
@@ -341,10 +341,10 @@ SELECT ( SELECT b FROM t2 WHERE NOT EXIS
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	2	100.00	
 2	SUBQUERY	t2	system	NULL	NULL	NULL	NULL	1	100.00	
-3	MATERIALIZED	t3	ALL	NULL	NULL	NULL	NULL	2	100.00	
+3	MATERIALIZED	t3	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where
 Warnings:
 Note	1276	Field or reference 'test.t2.b' of SELECT #3 was resolved in SELECT #2
-Note	1003	select (select 1 from dual where (not(((1 is not null) and <in_optimizer>(1,1 in ( <materialize> (select `test`.`t3`.`c` from `test`.`t3` where 1 ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `<subquery3>`.`c`))))))))) AS `( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) )` from `test`.`t1`
+Note	1003	select (select 1 from dual where (not(((1 is not null) and <in_optimizer>(1,1 in ( <materialize> (select `test`.`t3`.`c` from `test`.`t3` where (`test`.`t3`.`c` is not null) ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `<subquery3>`.`c`))))))))) AS `( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) )` from `test`.`t1`
 SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1;
 ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) )
 1
@@ -568,7 +568,7 @@ id	select_type	table	type	possible_keys
 2	DEPENDENT SUBQUERY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
 Warnings:
 Note	1276	Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
-Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where (not(((`test`.`t1`.`a` is not null) and <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`b` from `test`.`t2` where (<cache>(`test`.`t1`.`a`) = `test`.`t2`.`b`)))))))
+Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where (not(((`test`.`t1`.`a` is not null) and <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`b` from `test`.`t2` where ((`test`.`t2`.`b` is not null) and (<cache>(`test`.`t1`.`a`) = `test`.`t2`.`b`))))))))
 drop table t1,t2;
 set optimizer_switch=default;
 set optimizer_switch='exists_to_in=on';

=== modified file 'sql/item_subselect.cc'
--- a/sql/item_subselect.cc	2012-11-29 10:18:23 +0000
+++ b/sql/item_subselect.cc	2012-11-29 18:42:33 +0000
@@ -2559,7 +2559,7 @@ bool Item_exists_subselect::select_prepa
 */
 
 static bool check_equality_for_exist2in(Item_func *func,
-                                        Item_field **local_field,
+                                        Item_ident **local_field,
                                         Item **outer_exp)
 {
   Item **args;
@@ -2571,7 +2571,10 @@ static bool check_equality_for_exist2in(
       args[0]->all_used_tables() != OUTER_REF_TABLE_BIT &&
       args[1]->all_used_tables() == OUTER_REF_TABLE_BIT)
   {
-    *local_field= (Item_field *)args[0];
+    /* It is Item_field or Item_direct_view_ref) */
+    DBUG_ASSERT(args[0]->type() == Item::FIELD_ITEM ||
+                args[0]->type() == Item::REF_ITEM);
+    *local_field= (Item_ident *)args[0];
     *outer_exp= args[1];
     return TRUE;
   }
@@ -2579,7 +2582,10 @@ static bool check_equality_for_exist2in(
            args[1]->all_used_tables() != OUTER_REF_TABLE_BIT &&
            args[0]->all_used_tables() == OUTER_REF_TABLE_BIT)
   {
-    *local_field= (Item_field *)args[1];
+    /* It is Item_field or Item_direct_view_ref) */
+    DBUG_ASSERT(args[0]->type() == Item::FIELD_ITEM ||
+                args[0]->type() == Item::REF_ITEM);
+    *local_field= (Item_ident *)args[1];
     *outer_exp= args[0];
     return TRUE;
   }
@@ -2590,7 +2596,7 @@ static bool check_equality_for_exist2in(
 typedef struct st_eq_field_outer
 {
   Item_func **eq_ref;
-  Item_field *local_field;
+  Item_ident *local_field;
   Item *outer_exp;
 } EQ_FIELD_OUTER;
 
@@ -2664,7 +2670,7 @@ bool Item_exists_subselect::exists2in_pr
   SELECT_LEX *first_select=unit->first_select(), *save_select;
   JOIN *join= first_select->join;
   Item_func *eq= NULL, **eq_ref= NULL;
-  Item_field *local_field= NULL;
+  Item_ident *local_field= NULL;
   Item *outer_exp= NULL;
   Item *left_exp= NULL; Item_in_subselect *in_subs;
   Query_arena *arena= NULL, backup;
@@ -2751,16 +2757,17 @@ bool Item_exists_subselect::exists2in_pr
       first_select->ref_pointer_array[i]= (Item *)local_field;
 
       /* remove the parts from condition */
-      if (!upper_not || local_field->maybe_null)
+      if (!upper_not || !local_field->maybe_null)
       {
         eq->arguments()[0]= new Item_int(1);
         eq->arguments()[1]= new Item_int(1);
       }
       else
       {
-        *eq_ref= new Item_func_isnotnull(new Item_field(thd,
-                                                        local_field->context,
-                                                        local_field->field));
+        *eq_ref= new Item_func_isnotnull(
+          new Item_field(thd,
+                         ((Item_field*)(local_field->real_item()))->context,
+                         ((Item_field*)(local_field->real_item()))->field));
         if((*eq_ref)->fix_fields(thd, (Item **)eq_ref))
         {
           res= TRUE;
@@ -2864,14 +2871,16 @@ bool Item_exists_subselect::exists2in_pr
     Item *exp;
     if (eqs.elements() == 1)
     {
-      exp=
-       new Item_cond_and(
-          new Item_func_isnotnull(
-            new Item_direct_ref(&unit->outer_select()->context,
-                                optimizer->arguments(),
-                                (char *)"<no matter>",
-                                (char *)exists_outer_expr_name)),
-            optimizer);
+      exp= (optimizer->arguments()[0]->maybe_null ?
+            (Item*)
+            new Item_cond_and(
+              new Item_func_isnotnull(
+                new Item_direct_ref(&unit->outer_select()->context,
+                                    optimizer->arguments(),
+                                    (char *)"<no matter>",
+                                    (char *)exists_outer_expr_name)),
+              optimizer) :
+            (Item *)optimizer);
     }
     else
     {
@@ -2883,19 +2892,27 @@ bool Item_exists_subselect::exists2in_pr
       }
       for (int i= 0; i < eqs.elements(); i++)
       {
-        and_list->
-          push_front(
-            new Item_func_isnotnull(
-              new Item_direct_ref(&unit->outer_select()->context,
-                                  optimizer->arguments()[0]->addr(i),
-                                  (char *)"<no matter>",
-                                  (char *)exists_outer_expr_name)));
+        if (optimizer->arguments()[0]->maybe_null)
+        {
+          and_list->
+            push_front(
+              new Item_func_isnotnull(
+                new Item_direct_ref(&unit->outer_select()->context,
+                                    optimizer->arguments()[0]->addr(i),
+                                    (char *)"<no matter>",
+                                    (char *)exists_outer_expr_name)));
+        }
       }
-      and_list->push_front(optimizer);
-      exp= new Item_cond_and(*and_list);
+      if (and_list->elements > 0)
+      {
+        and_list->push_front(optimizer);
+        exp= new Item_cond_and(*and_list);
+      }
+      else
+        exp= optimizer;
     }
     upper_not->arguments()[0]= exp;
-    if (exp->fix_fields(thd, upper_not->arguments()))
+    if (!exp->fixed && exp->fix_fields(thd, upper_not->arguments()))
     {
       res= TRUE;
       goto out;



More information about the commits mailing list