List:Commits« Previous MessageNext Message »
From:timour Date:July 9 2007 3:50pm
Subject:bk commit into 5.2 tree (timour:1.2549)
View as plain text  
Below is the list of changes that have just been committed into a local
5.2 repository of tkatchaounov. When tkatchaounov 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-07-09 18:50:36+03:00, timour@stripped +4 -0
  WL#1110: Subquery optimization: materialization
  
  Changed the way we setup IN predicates for execution via hash semi-join so
  that it works correctly with UNION queries.
  
  Enabled the corresponding regression test case.

  mysql-test/r/information_schema.result@stripped, 2007-07-09 18:50:25+03:00, timour@stripped +8 -0
    Re-enabled test case that now passes.

  mysql-test/t/information_schema.test@stripped, 2007-07-09 18:50:25+03:00, timour@stripped +7 -8
    Re-enabled test case that now passes.

  sql/sql_select.cc@stripped, 2007-07-09 18:50:25+03:00, timour@stripped +46 -23
    Changed the way IN predicates are set-up for execution.
    Before the approach was to identify the top-most query, and then go through
    the list of all subqueries and invoke the setup method for each IN predicate
    for which the subquery is an argument. This approach doesn't work with UNION
    queries that contain subqueries, because the hash semi-join setup is called
    too late.
    
    This patch performs the setup one level higher, where we walk over all
    subqueries of a query, test if they are under IN predicate, and if the
    the optimizer chose to execute it via hash semi-join, we invoke the
    corresponding setup method for the IN predicate. 

  sql/sql_select.h@stripped, 2007-07-09 18:50:26+03:00, timour@stripped +1 -0
    Encapsulated all setup of IN predicates that should be executed via hash semi-join
    in one method.

# 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:	timour
# Host:	zmeiux.home
# Root:	/home/tkatchaounov/mysql/src/5.2-1110

--- 1.549/sql/sql_select.cc	2007-07-03 07:02:35 +03:00
+++ 1.550/sql/sql_select.cc	2007-07-09 18:50:25 +03:00
@@ -1742,29 +1742,9 @@
   if (!(select_options & SELECT_DESCRIBE))
     init_ftfuncs(thd, select_lex, test(order));
 
-  /*
-    Create all structures needed for materialized subquery execution,
-    assuming this is the outer-most query. This phase must be after
-    substitute_for_best_equal_field() because that function may replace
-    items with other items from a multiple equality, and we need to reference
-    the correct items in the index access method of the IN predicate.
-  */
-  if (is_top_level_join())
-     /* Alternatively check: (&lex.select_lex == join->select) */
-  {
-    for (SELECT_LEX *sl= thd->lex->all_selects_list; sl;
-         sl= sl->next_select_in_list())
-    {
-      Item_subselect *subquery_predicate= sl->master_unit()->item;
-      if (subquery_predicate &&
-          subquery_predicate->substype() == Item_subselect::IN_SUBS)
-      {
-        Item_in_subselect *in_subs= (Item_in_subselect*) subquery_predicate;
-        if (in_subs->use_hash_sj && in_subs->setup_hash_sj_engine())
-          DBUG_RETURN(1);
-      }
-    }
-  }
+  /* Create all structures needed for materialized subquery execution. */
+  if (setup_subquery_materialization())
+    DBUG_RETURN(1);
 
   /*
     is this simple IN subquery?
@@ -3330,6 +3310,49 @@
   }
   sj_subselects.clear();
   DBUG_RETURN(FALSE);
+}
+
+
+/**
+  Setup for execution all subqueries of a query, for which the optimizer
+  chose hash semi-join.
+
+  @detail Iterate over all subqueries of the query, and if they are under an
+  IN predicate, and the optimizer chose to compute it via hash semi-join,
+  initialize all data structures needed for the execution of the IN
+  predicate.
+
+  This method is part of the "code generation" query processing phase.
+
+  This phase must be called after substitute_for_best_equal_field() because
+  that function may replace items with other items from a multiple equality,
+  and we need to reference the correct items in the index access method of the
+  IN predicate.
+
+  @return Operation status
+  @retval FALSE     success.
+  @retval TRUE      error occurred.
+*/
+
+bool JOIN::setup_subquery_materialization()
+{
+  for (SELECT_LEX_UNIT *un= select_lex->first_inner_unit(); un;
+       un= un->next_unit())
+  {
+    for (SELECT_LEX *sl= un->first_select(); sl;
+         sl= sl->next_select())
+    {
+      Item_subselect *subquery_predicate= sl->master_unit()->item;
+      if (subquery_predicate &&
+          subquery_predicate->substype() == Item_subselect::IN_SUBS)
+      {
+        Item_in_subselect *in_subs= (Item_in_subselect*) subquery_predicate;
+        if (in_subs->use_hash_sj && in_subs->setup_hash_sj_engine())
+          return TRUE;
+      }
+    }
+  }
+  return FALSE;
 }
 
 

--- 1.127/sql/sql_select.h	2007-06-30 01:19:08 +03:00
+++ 1.128/sql/sql_select.h	2007-07-09 18:50:26 +03:00
@@ -586,6 +586,7 @@
   void restore_tmp();
   bool alloc_func_list();
   bool flatten_subqueries();
+  bool setup_subquery_materialization();
   bool make_sum_func_list(List<Item> &all_fields, List<Item> &send_fields,
 			  bool before_group_by, bool recompute= FALSE);
 

--- 1.158/mysql-test/r/information_schema.result	2007-06-29 01:47:29 +03:00
+++ 1.159/mysql-test/r/information_schema.result	2007-07-09 18:50:25 +03:00
@@ -506,6 +506,14 @@
 AUTO_INCREMENT
 4
 drop table t1;
+create table t1 (s1 int);
+insert into t1 values (0),(9),(0);
+select s1 from t1 where s1 in (select version from
+information_schema.tables) union select version from
+information_schema.tables;
+s1
+10
+drop table t1;
 SHOW CREATE TABLE INFORMATION_SCHEMA.character_sets;
 Table	Create Table
 CHARACTER_SETS	CREATE TEMPORARY TABLE `CHARACTER_SETS` (

--- 1.100/mysql-test/t/information_schema.test	2007-06-29 01:47:29 +03:00
+++ 1.101/mysql-test/t/information_schema.test	2007-07-09 18:50:25 +03:00
@@ -292,14 +292,13 @@
 insert into t1 values (1,1),(NULL,3),(NULL,4);
 select AUTO_INCREMENT from information_schema.tables where table_name = 't1';
 drop table t1;
-# WL#1110 - disabled test - wrong result
-# the problem is not IS specific.
-#create table t1 (s1 int);
-#insert into t1 values (0),(9),(0);
-#select s1 from t1 where s1 in (select version from
-#information_schema.tables) union select version from
-#information_schema.tables;
-#drop table t1;
+
+create table t1 (s1 int);
+insert into t1 values (0),(9),(0);
+select s1 from t1 where s1 in (select version from
+information_schema.tables) union select version from
+information_schema.tables;
+drop table t1;
 
 SHOW CREATE TABLE INFORMATION_SCHEMA.character_sets;
 set names latin2;
Thread
bk commit into 5.2 tree (timour:1.2549)timour9 Jul