List:Commits« Previous MessageNext Message »
From:Vladimir Shebordaev Date:January 18 2007 9:31am
Subject:bk commit into 5.0 tree (ted:1.2382) BUG#25219
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of ted. When ted 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-01-18 11:31:14+03:00, ted@stripped +1 -0
  BUG#25219: SELECT with subqueries causes MySQL server crash <QUITE UNRELATED!>
  
  fix: make_cond_for_table() cleaned up; hacks to workaround bug with quick selects
avoided; 
       see rejects against current test results attached to the bug page 

  sql/sql_select.cc@stripped, 2007-01-18 11:31:12+03:00, ted@stripped +60 -63
    make_cond_for_table() now looks a little bit more manageable and hopefully consistent 

# 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:	ted
# Host:	ted.mysql.internal
# Root:	/usr/local/src/mysql/bug25219/50

--- 1.478/sql/sql_select.cc	2007-01-18 11:31:20 +03:00
+++ 1.479/sql/sql_select.cc	2007-01-18 11:31:20 +03:00
@@ -5468,8 +5468,9 @@
 	  &thd->lex->unit)		// not upper level SELECT
         join->const_table_map|=RAND_TABLE_BIT;
       {						// Check const tables
-        COND *const_cond=
-	  make_cond_for_table(cond,
+        COND *const_cond= (COND*) 0;
+	if (join->const_table_map)
+	  const_cond= make_cond_for_table(cond,
                               join->const_table_map,
                               (table_map) 0);
         DBUG_EXECUTE("where",print_where(const_cond,"constants"););
@@ -5536,31 +5537,7 @@
       tmp= NULL;
       if (cond)
         tmp= make_cond_for_table(cond,used_tables,current_map);
-      if (cond && !tmp && tab->quick)
-      {						// Outer join
-        if (tab->type != JT_ALL)
-        {
-          /*
-            Don't use the quick method
-            We come here in the case where we have 'key=constant' and
-            the test is removed by make_cond_for_table()
-          */
-          delete tab->quick;
-          tab->quick= 0;
-        }
-        else
-        {
-          /*
-            Hack to handle the case where we only refer to a table
-            in the ON part of an OUTER JOIN. In this case we want the code
-            below to check if we should use 'quick' instead.
-          */
-          DBUG_PRINT("info", ("Item_int"));
-          tmp= new Item_int((longlong) 1,1);	// Always true
-          DBUG_PRINT("info", ("Item_int 0x%lx", (ulong)tmp));
-        }
 
-      }
       if (tmp || !cond)
       {
 	DBUG_EXECUTE("where",print_where(tmp,tab->table->alias););
@@ -11591,16 +11568,20 @@
 static COND *
 make_cond_for_table(COND *cond, table_map tables, table_map used_table)
 {
-  if (used_table && !(cond->used_tables() & used_table))
-    return (COND*) 0;				// Already checked
-  if (cond->type() == Item::COND_ITEM)
-  {
+  COND *ret = (COND*) 0;
+  table_map used_tables = cond->used_tables();
+  
+  if (used_table && used_tables && !(used_tables & used_table))
+    return ret;				// Already checked
+
+  switch (cond->type()) {
+  case Item::COND_ITEM:
     if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
     {
       /* Create new top level AND item */
       Item_cond_and *new_cond=new Item_cond_and;
       if (!new_cond)
-	return (COND*) 0;			// OOM /* purecov: inspected */
+	return ret;			// OOM /* purecov: inspected */
       List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
       Item *item;
       while ((item=li++))
@@ -11611,9 +11592,10 @@
       }
       switch (new_cond->argument_list()->elements) {
       case 0:
-	return (COND*) 0;			// Always true
+	break;			// Always true
       case 1:
-	return new_cond->argument_list()->head();
+	ret = new_cond->argument_list()->head();
+        break;
       default:
 	/*
 	  Item_cond_and do not need fix_fields for execution, its parameters
@@ -11623,21 +11605,21 @@
 	new_cond->used_tables_cache=
 	  ((Item_cond_and*) cond)->used_tables_cache &
 	  tables;
-	return new_cond;
+	ret= new_cond;
       }
     }
     else
     {						// Or list
       Item_cond_or *new_cond=new Item_cond_or;
       if (!new_cond)
-	return (COND*) 0;			// OOM /* purecov: inspected */
+	return ret;			// OOM /* purecov: inspected */
       List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
       Item *item;
       while ((item=li++))
       {
 	Item *fix=make_cond_for_table(item,tables,0L);
 	if (!fix)
-	  return (COND*) 0;			// Always true
+	  return ret;			// Always true
 	new_cond->argument_list()->push_back(fix);
       }
       /*
@@ -11647,40 +11629,55 @@
       new_cond->quick_fix_field();
       new_cond->used_tables_cache= ((Item_cond_or*) cond)->used_tables_cache;
       new_cond->top_level_item();
-      return new_cond;
+      ret= new_cond;
     }
-  }
-
-  /*
-    Because the following test takes a while and it can be done
-    table_count times, we mark each item that we have examined with the result
-    of the test
-  */
-
-  if (cond->marker == 3 || (cond->used_tables() & ~tables))
-    return (COND*) 0;				// Can't check this yet
-  if (cond->marker == 2 || cond->eq_cmp_result() == Item::COND_OK)
-    return cond;				// Not boolean op
+    break;
+  case Item::FUNC_ITEM:
+    /*
+      Because the following test takes a while and it can be done
+      table_count times, we mark each item that we have examined 
+      with the result of the test
+     */
 
-  if (((Item_func*) cond)->functype() == Item_func::EQ_FUNC)
-  {
-    Item *left_item=	((Item_func*) cond)->arguments()[0];
-    Item *right_item= ((Item_func*) cond)->arguments()[1];
-    if (left_item->type() == Item::FIELD_ITEM &&
-	test_if_ref((Item_field*) left_item,right_item))
+    if (cond->marker == 3 || (used_tables & ~tables))
+      break;				   // Can't check this yet
+    if (cond->marker == 2 || cond->eq_cmp_result() == Item::COND_OK)
     {
-      cond->marker=3;			// Checked when read
-      return (COND*) 0;
+      ret= cond;			  	 // Not boolean op
+      break;
     }
-    if (right_item->type() == Item::FIELD_ITEM &&
-	test_if_ref((Item_field*) right_item,left_item))
+    if (((Item_func*) cond)->functype() == Item_func::EQ_FUNC)
     {
-      cond->marker=3;			// Checked when read
-      return (COND*) 0;
+      Item *left_item=	((Item_func*) cond)->arguments()[0];
+      Item *right_item= ((Item_func*) cond)->arguments()[1];
+      if (left_item->type() == Item::FIELD_ITEM &&
+	  test_if_ref((Item_field*) left_item,right_item))
+      {
+        cond->marker= 3;			// Checked when read
+        break;
+      }
+      if (right_item->type() == Item::FIELD_ITEM &&
+	  test_if_ref((Item_field*) right_item,left_item))
+      {
+        cond->marker= 3;			// Checked when read
+        break;
+      }
     }
+    cond->marker= 2;
+    ret= cond;
+    break;
+  case Item::SUBSELECT_ITEM: 
+    if (used_table || !(used_tables & ~tables))
+      ret= cond;
+    break;
+  default:
+    /*
+       Nothing special so far, just check used tables map
+     */
+    if ((used_tables && !(used_tables & ~tables)) ||
cond->real_item()->const_item())
+      ret= cond;
   }
-  cond->marker=2;
-  return cond;
+  return ret;
 }
 
 static Item *
Thread
bk commit into 5.0 tree (ted:1.2382) BUG#25219Vladimir Shebordaev18 Jan