MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Sergey Petrunia Date:June 27 2007 1:22am
Subject:bk commit into 5.1 tree (sergefp:1.2417)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of psergey. When psergey 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-06-27 05:22:39+04:00, sergefp@stripped +11 -0
  Wont push this
  MERGE: 1.2409.1.57

  mysql-test/r/partition_innodb.result@stripped, 2007-06-27 05:20:02+04:00, sergefp@stripped +0 -0
    Auto merged
    MERGE: 1.2.1.1

  mysql-test/r/subselect.result@stripped, 2007-06-27 05:22:35+04:00, sergefp@stripped +0 -0
    Wont push this
    MERGE: 1.160.1.3

  mysql-test/t/ps_1general.test@stripped, 2007-06-27 05:20:02+04:00, sergefp@stripped +0 -0
    Auto merged
    MERGE: 1.37.1.2

  mysql-test/t/subselect.test@stripped, 2007-06-27 05:22:35+04:00, sergefp@stripped +36 -0
    Wont push this
    MERGE: 1.141.1.3

  sql/event_data_objects.cc@stripped, 2007-06-27 05:20:02+04:00, sergefp@stripped +0 -0
    Auto merged
    MERGE: 1.83.1.2

  sql/event_queue.cc@stripped, 2007-06-27 05:20:02+04:00, sergefp@stripped +0 -0
    Auto merged
    MERGE: 1.22.1.1

  sql/event_scheduler.cc@stripped, 2007-06-27 05:22:35+04:00, sergefp@stripped +2 -4
    Wont push this
    MERGE: 1.31.1.1

  sql/item_subselect.cc@stripped, 2007-06-27 05:20:02+04:00, sergefp@stripped +0 -0
    Auto merged
    MERGE: 1.141.2.2

  sql/item_subselect.h@stripped, 2007-06-27 05:20:02+04:00, sergefp@stripped +0 -0
    Auto merged
    MERGE: 1.86.2.2

  sql/sql_parse.cc@stripped, 2007-06-27 05:20:03+04:00, sergefp@stripped +0 -0
    Auto merged
    MERGE: 1.620.1.1

  sql/sql_yacc.yy@stripped, 2007-06-27 05:20:03+04:00, sergefp@stripped +0 -0
    Auto merged
    MERGE: 1.534.1.8

# 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:	sergefp
# Host:	pylon.mylan
# Root:	/home/psergey/mysql-5.2-merge-orig/RESYNC

--- 1.629/sql/sql_parse.cc	2007-06-27 05:22:47 +04:00
+++ 1.630/sql/sql_parse.cc	2007-06-27 05:22:47 +04:00
@@ -3069,8 +3069,7 @@
       if (!(res= Events::get_instance()->drop_event(thd,
                                                     lex->spname->m_db,
                                                     lex->spname->m_name,
-                                                    lex->drop_if_exists,
-                                                    FALSE)))
+                                                    lex->drop_if_exists)))
         send_ok(thd);
     }
     break;

--- 1.538/sql/sql_yacc.yy	2007-06-27 05:22:47 +04:00
+++ 1.539/sql/sql_yacc.yy	2007-06-27 05:22:47 +04:00
@@ -631,7 +631,7 @@
 %token  GLOBAL_SYM                    /* SQL-2003-R */
 %token  GRANT                         /* SQL-2003-R */
 %token  GRANTS
-%token  GROUP                         /* SQL-2003-R */
+%token  GROUP_SYM                     /* SQL-2003-R */
 %token  GROUP_CONCAT_SYM
 %token  GT_SYM                        /* OPERATOR */
 %token  HANDLER_SYM
@@ -1297,7 +1297,7 @@
 deallocate:
         deallocate_or_drop PREPARE_SYM ident
         {
-          THD *thd=YYTHD;
+          THD *thd= YYTHD;
           LEX *lex= thd->lex;
           if (lex->stmt_prepare_mode)
           {
@@ -1317,7 +1317,7 @@
 prepare:
         PREPARE_SYM ident FROM prepare_src
         {
-          THD *thd=YYTHD;
+          THD *thd= YYTHD;
           LEX *lex= thd->lex;
           if (lex->stmt_prepare_mode)
           {
@@ -1331,14 +1331,14 @@
 prepare_src:
         TEXT_STRING_sys
         {
-          THD *thd=YYTHD;
+          THD *thd= YYTHD;
           LEX *lex= thd->lex;
           lex->prepared_stmt_code= $1;
           lex->prepared_stmt_code_is_varref= FALSE;
         }
         | '@' ident_or_text
         {
-          THD *thd=YYTHD;
+          THD *thd= YYTHD;
           LEX *lex= thd->lex;
           lex->prepared_stmt_code= $2;
           lex->prepared_stmt_code_is_varref= TRUE;
@@ -1347,7 +1347,7 @@
 execute:
         EXECUTE_SYM ident
         {
-          THD *thd=YYTHD;
+          THD *thd= YYTHD;
           LEX *lex= thd->lex;
           if (lex->stmt_prepare_mode)
           {
@@ -1508,7 +1508,7 @@
 	CREATE opt_table_options TABLE_SYM opt_if_not_exists table_ident
 	{
 	  THD *thd= YYTHD;
-	  LEX *lex=Lex;
+	  LEX *lex= thd->lex;
 	  lex->sql_command= SQLCOM_CREATE_TABLE;
 	  if (!lex->select_lex.add_table_to_list(thd, $5, NULL,
 						 TL_OPTION_UPDATING,
@@ -1580,7 +1580,7 @@
 	  {
 	    Lex->sql_command = SQLCOM_CREATE_USER;
           }
-	| CREATE LOGFILE_SYM GROUP logfile_group_info 
+	| CREATE LOGFILE_SYM GROUP_SYM logfile_group_info 
           {
             Lex->alter_tablespace_info->ts_cmd_type= CREATE_LOGFILE_GROUP;
           }
@@ -1886,7 +1886,7 @@
 	  RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
 	  {
             THD *thd= YYTHD;
-	    LEX *lex=Lex;
+	    LEX *lex= thd->lex;
             if (lex->definer != NULL)
             {
               /*
@@ -1993,7 +1993,7 @@
 	  sp_proc_stmt
 	  {
             THD *thd= YYTHD;
-	    LEX *lex= Lex;
+	    LEX *lex= thd->lex;
 	    sp_head *sp= lex->sphead;
 
             if (sp->is_not_allowed_in_function("function"))
@@ -3156,11 +3156,11 @@
   ALTER TABLESPACE name CHANGE DATAFILE ...
   ALTER TABLESPACE name ADD DATAFILE ...
   ALTER TABLESPACE name access_mode
-  CREATE LOGFILE GROUP name ...
-  ALTER LOGFILE GROUP name ADD UNDOFILE ..
-  ALTER LOGFILE GROUP name ADD REDOFILE ..
+  CREATE LOGFILE GROUP_SYM name ...
+  ALTER LOGFILE GROUP_SYM name ADD UNDOFILE ..
+  ALTER LOGFILE GROUP_SYM name ADD REDOFILE ..
   DROP TABLESPACE name
-  DROP LOGFILE GROUP name
+  DROP LOGFILE GROUP_SYM name
 */
 change_tablespace_access:
           tablespace_name
@@ -3182,7 +3182,7 @@
 
 opt_logfile_group_name:
           /* empty */ {}
-          | USE_SYM LOGFILE_SYM GROUP ident
+          | USE_SYM LOGFILE_SYM GROUP_SYM ident
           {
             LEX *lex= Lex;
             lex->alter_tablespace_info->logfile_group_name= $4.str;
@@ -3533,8 +3533,8 @@
           create3 {}
         | LIKE table_ident
           {
-            LEX *lex=Lex;
-            THD *thd= lex->thd;
+            THD *thd= YYTHD;
+            LEX *lex= thd->lex;
             if (!(lex->like_name= $2))
               YYABORT;
             if ($2->db.str == NULL &&
@@ -3545,8 +3545,8 @@
           }
         | '(' LIKE table_ident ')'
           {
-            LEX *lex=Lex;
-            THD *thd= lex->thd;
+            THD *thd= YYTHD;
+            LEX *lex= thd->lex;
             if (!(lex->like_name= $3))
               YYABORT;
             if ($3->db.str == NULL &&
@@ -3835,7 +3835,6 @@
           LEX *lex= Lex;
           partition_info *part_info= lex->part_info;
           partition_element *p_elem= new partition_element();
-          uint part_id= part_info->partitions.elements;
 
           if (!p_elem || part_info->partitions.push_back(p_elem))
           {
@@ -3987,9 +3986,8 @@
         bit_expr
         {
           Item *part_expr= $1;
-          int part_expression_ok= 1;
-          LEX *lex= Lex;
           THD *thd= YYTHD;
+          LEX *lex= thd->lex;
           Name_resolution_context *context= &lex->current_select->context;
           TABLE_LIST *save_list= context->table_list;
           const char *save_where= thd->where;
@@ -5048,8 +5046,8 @@
           }
           opt_create_database_options
 	  {
-	    LEX *lex=Lex;
-            THD *thd= Lex->thd;
+            THD *thd= YYTHD;
+	    LEX *lex= thd->lex;
 	    lex->sql_command=SQLCOM_ALTER_DB;
 	    lex->name= $3;
             if (lex->name.str == NULL &&
@@ -5162,7 +5160,7 @@
             LEX *lex= Lex;
             lex->alter_tablespace_info->ts_cmd_type= ALTER_TABLESPACE;
           }
-        | ALTER LOGFILE_SYM GROUP alter_logfile_group_info
+        | ALTER LOGFILE_SYM GROUP_SYM alter_logfile_group_info
           {
             LEX *lex= Lex;
             lex->alter_tablespace_info->ts_cmd_type= ALTER_LOGFILE_GROUP;
@@ -5180,9 +5178,9 @@
         | ALTER SERVER_SYM ident_or_text OPTIONS_SYM '(' server_options_list ')'
           {
             LEX *lex= Lex;
-            Lex->sql_command= SQLCOM_ALTER_SERVER;
-            Lex->server_options.server_name= $3.str;
-            Lex->server_options.server_name_length= $3.length;
+            lex->sql_command= SQLCOM_ALTER_SERVER;
+            lex->server_options.server_name= $3.str;
+            lex->server_options.server_name_length= $3.length;
           }
 	;
 
@@ -5486,8 +5484,8 @@
 	  }
 	| RENAME opt_to table_ident
 	  {
-	    LEX *lex=Lex;
-            THD *thd= lex->thd;
+            THD *thd= YYTHD;
+	    LEX *lex= thd->lex;
 	    uint dummy;
 	    lex->select_lex.db=$3->db.str;
             if (lex->select_lex.db == NULL &&
@@ -5854,9 +5852,9 @@
 	ident TO_SYM ident
 	{
 	  LEX *lex=Lex;
-          if (Lex->db_list.push_back((LEX_STRING*)
+          if (lex->db_list.push_back((LEX_STRING*)
                                      sql_memdup(&$1, sizeof(LEX_STRING))) ||
-              Lex->db_list.push_back((LEX_STRING*)
+              lex->db_list.push_back((LEX_STRING*)
                                      sql_memdup(&$3, sizeof(LEX_STRING))))
               YYABORT;
 	};
@@ -6030,8 +6028,13 @@
 	| select_from into;
 
 select_from:
-	  FROM join_table_list where_clause group_clause having_clause
+        FROM join_table_list where_clause group_clause having_clause
 	       opt_order_clause opt_limit_clause procedure_clause
+          {
+            Select->context.table_list=
+              Select->context.first_name_resolution_table= 
+                (TABLE_LIST *) Select->table_list.first;
+          }
         | FROM DUAL_SYM where_clause opt_limit_clause
           /* oracle compatibility: oracle always requires FROM clause,
              and DUAL is system table without fields.
@@ -6788,7 +6791,6 @@
         udf_expr_list ')'
         {
           THD *thd= YYTHD;
-          LEX *lex= Lex;
           Create_func *builder;
           Item *item= NULL;
 
@@ -6811,7 +6813,6 @@
 #ifdef HAVE_DLOPEN
             /* Retrieving the result of find_udf */
             udf_func *udf= $<udf>3;
-            LEX *lex= Lex;
 
             if (udf)
             {
@@ -7205,15 +7206,14 @@
 	| table_ref normal_join table_ref
 	  USING
 	  {
-	    SELECT_LEX *sel= Select;
             YYERROR_UNLESS($1 && $3);
 	  }
 	  '(' using_list ')'
-          { add_join_natural($1,$3,$7); $$=$3; }
+          { add_join_natural($1,$3,$7,Select); $$=$3; }
 	| table_ref NATURAL JOIN_SYM table_factor
 	  {
             YYERROR_UNLESS($1 && ($$=$4));
-            add_join_natural($1,$4,NULL);
+            add_join_natural($1,$4,NULL,Select);
           }
 
 /* LEFT JOIN variants */
@@ -7236,15 +7236,18 @@
           }
 	| table_ref LEFT opt_outer JOIN_SYM table_factor
 	  {
-	    SELECT_LEX *sel= Select;
             YYERROR_UNLESS($1 && $5);
 	  }
 	  USING '(' using_list ')'
-          { add_join_natural($1,$5,$9); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; }
+          { 
+            add_join_natural($1,$5,$9,Select); 
+            $5->outer_join|=JOIN_TYPE_LEFT; 
+            $$=$5; 
+          }
 	| table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor
 	  {
             YYERROR_UNLESS($1 && $6);
- 	    add_join_natural($1,$6,NULL);
+ 	    add_join_natural($1,$6,NULL,Select);
 	    $6->outer_join|=JOIN_TYPE_LEFT;
 	    $$=$6;
 	  }
@@ -7270,7 +7273,6 @@
           }
 	| table_ref RIGHT opt_outer JOIN_SYM table_factor
 	  {
-	    SELECT_LEX *sel= Select;
             YYERROR_UNLESS($1 && $5);
 	  }
 	  USING '(' using_list ')'
@@ -7278,12 +7280,12 @@
 	    LEX *lex= Lex;
             if (!($$= lex->current_select->convert_right_join()))
               YYABORT;
-            add_join_natural($$,$5,$9);
+            add_join_natural($$,$5,$9,Select);
           }
 	| table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor
 	  {
             YYERROR_UNLESS($1 && $6);
-	    add_join_natural($6,$1,NULL);
+	    add_join_natural($6,$1,NULL,Select);
 	    LEX *lex= Lex;
             if (!($$= lex->current_select->convert_right_join()))
               YYABORT;
@@ -7648,7 +7650,7 @@
 
 group_clause:
 	/* empty */
-	| GROUP BY group_list olap_opt;
+	| GROUP_SYM BY group_list olap_opt;
 
 group_list:
 	group_list ',' order_ident order_dir
@@ -8112,7 +8114,7 @@
             LEX *lex= Lex;
             lex->alter_tablespace_info->ts_cmd_type= DROP_TABLESPACE;
           }
-        | DROP LOGFILE_SYM GROUP logfile_group_name opt_ts_engine opt_ts_wait
+        | DROP LOGFILE_SYM GROUP_SYM logfile_group_name opt_ts_engine opt_ts_wait
           {
             LEX *lex= Lex;
             lex->alter_tablespace_info->ts_cmd_type= DROP_LOGFILE_GROUP;
@@ -9219,7 +9221,7 @@
 param_marker:
         PARAM_MARKER
         {
-          THD *thd=YYTHD;
+          THD *thd= YYTHD;
 	  LEX *lex= thd->lex;
           Item_param *item;
           if (! lex->parsing_options.allows_variable)
@@ -9761,6 +9763,7 @@
 	| COMPLETION_SYM	{}
 	| COMPRESSED_SYM	{}
 	| CONCURRENT		{}
+	| CONNECTION_SYM	{}
 	| CONSISTENT_SYM	{}
 	| CONTRIBUTORS_SYM	{}
 	| CUBE_SYM		{}
@@ -10207,7 +10210,7 @@
 	| charset old_or_new_charset_name_or_default
 	{
 	  THD *thd= YYTHD;
-	  LEX *lex= Lex;
+	  LEX *lex= thd->lex;
 	  $2= $2 ? $2: global_system_variables.character_set_client;
 	  lex->var_list.push_back(new set_var_collation_client($2,thd->variables.collation_database,$2));
 	}
@@ -10241,9 +10244,9 @@
 	}
 	| PASSWORD equal text_or_password
 	  {
-	    THD *thd=YYTHD;
+	    THD *thd= YYTHD;
+	    LEX *lex= thd->lex;
 	    LEX_USER *user;
-	    LEX *lex= Lex;	    
             sp_pcontext *spc= lex->spcont;
 	    LEX_STRING pw;
 
@@ -10724,8 +10727,8 @@
 grant_ident:
 	'*'
 	  {
-	    LEX *lex= Lex;
-            THD *thd= lex->thd;
+            THD *thd= YYTHD;
+	    LEX *lex= thd->lex;
             uint dummy;
             if (thd->copy_db_to(&lex->current_select->db, &dummy))
               YYABORT;
@@ -11088,7 +11091,6 @@
         }
         | '(' subselect_start subselect ')'
           {
-            LEX *lex= Lex;
 	    THD *thd= YYTHD;
             /*
               note that a local variable can't be used for
@@ -11139,6 +11141,12 @@
 	  lex->current_select = lex->current_select->return_after_parsing();
           lex->nest_level--;
           lex->current_select->n_child_sum_items += child->n_sum_items;
+          /*
+            A subselect can add fields to an outer select. Reserve space for
+            them.
+          */
+          lex->current_select->select_n_where_fields+=
+            child->select_n_where_fields;
 	};
 
 /**************************************************************************
@@ -11288,7 +11296,7 @@
 view_select_aux:
 	SELECT_SYM remember_name select_init2
 	{
-          THD *thd=YYTHD;
+          THD *thd= YYTHD;
           LEX *lex= thd->lex;
           char *stmt_beg= (lex->sphead ?
                            (char *)lex->sphead->m_tmp_query :
@@ -11297,7 +11305,7 @@
 	}
 	| '(' remember_name select_paren ')' union_opt
 	{
-          THD *thd=YYTHD;
+          THD *thd= YYTHD;
           LEX *lex= thd->lex;
           char *stmt_beg= (lex->sphead ?
                            (char *)lex->sphead->m_tmp_query :

--- 1.23/sql/event_queue.cc	2007-06-27 05:22:47 +04:00
+++ 1.24/sql/event_queue.cc	2007-06-27 05:22:47 +04:00
@@ -16,7 +16,6 @@
 #include "mysql_priv.h"
 #include "event_queue.h"
 #include "event_data_objects.h"
-#include "event_db_repository.h"
 
 
 #define EVENT_QUEUE_INITIAL_SIZE 30
@@ -136,14 +135,12 @@
 */
 
 bool
-Event_queue::init_queue(THD *thd, Event_db_repository *db_repo)
+Event_queue::init_queue(THD *thd)
 {
-  bool res;
   DBUG_ENTER("Event_queue::init_queue");
   DBUG_PRINT("enter", ("this: 0x%lx", (long) this));
 
   LOCK_QUEUE_DATA();
-  db_repository= db_repo;
 
   if (init_queue_ex(&queue, EVENT_QUEUE_INITIAL_SIZE , 0 /*offset*/,
                     0 /*max_on_top*/, event_queue_element_compare_q,
@@ -160,12 +157,8 @@
     goto err;
   }
 
-  res= load_events_from_db(thd);
   UNLOCK_QUEUE_DATA();
-  if (res)
-    deinit_queue();
-
-  DBUG_RETURN(res);
+  DBUG_RETURN(FALSE);
 
 err:
   UNLOCK_QUEUE_DATA();
@@ -202,37 +195,29 @@
     Event_queue::create_event()
       dbname  The schema of the new event
       name    The name of the new event
-
-  RETURN VALUE
-    OP_OK             OK or scheduler not working
-    OP_LOAD_ERROR     Error during loading from disk
 */
 
-int
-Event_queue::create_event(THD *thd, LEX_STRING dbname, LEX_STRING name)
+void
+Event_queue::create_event(THD *thd, Event_queue_element *new_element)
 {
-  int res;
-  Event_queue_element *new_element;
   DBUG_ENTER("Event_queue::create_event");
-  DBUG_PRINT("enter", ("thd: 0x%lx  et=%s.%s", (long) thd, dbname.str, name.str));
+  DBUG_PRINT("enter", ("thd=0x%lx et=%s.%s",thd,
+             new_element->dbname.str, new_element->name.str));
 
-  new_element= new Event_queue_element();
-  res= db_repository->load_named_event(thd, dbname, name, new_element);
-  if (res || new_element->status == Event_queue_element::DISABLED)
+  if (new_element->status == Event_queue_element::DISABLED)
     delete new_element;
   else
   {
     new_element->compute_next_execution_time();
+    DBUG_PRINT("info", ("new event in the queue 0x%lx", new_element));
 
     LOCK_QUEUE_DATA();
-    DBUG_PRINT("info", ("new event in the queue: 0x%lx", (long) new_element));
     queue_insert_safe(&queue, (byte *) new_element);
     dbug_dump_queue(thd->query_start());
     pthread_cond_broadcast(&COND_queue_state);  
     UNLOCK_QUEUE_DATA();
   }
-
-  DBUG_RETURN(res);
+  DBUG_VOID_RETURN;
 }
 
 
@@ -246,32 +231,16 @@
       name       Name of the event
       new_schema New schema, in case of RENAME TO, otherwise NULL
       new_name   New name, in case of RENAME TO, otherwise NULL
-
-  RETURN VALUE
-    OP_OK             OK or scheduler not working
-    OP_LOAD_ERROR     Error during loading from disk
 */
 
-int
+void
 Event_queue::update_event(THD *thd, LEX_STRING dbname, LEX_STRING name,
-                          LEX_STRING *new_schema, LEX_STRING *new_name)
+                          Event_queue_element *new_element)
 {
-  int res;
-  Event_queue_element *new_element;
-
   DBUG_ENTER("Event_queue::update_event");
   DBUG_PRINT("enter", ("thd: 0x%lx  et=[%s.%s]", (long) thd, dbname.str, name.str));
 
-  new_element= new Event_queue_element();
-
-  res= db_repository->load_named_event(thd, new_schema ? *new_schema:dbname,
-                                       new_name ? *new_name:name, new_element);
-  if (res)
-  {
-    delete new_element;
-    goto end;
-  }
-  else if (new_element->status == Event_queue_element::DISABLED)
+  if (new_element->status == Event_queue_element::DISABLED)
   {
     DBUG_PRINT("info", ("The event is disabled."));
     /*
@@ -298,9 +267,7 @@
   dbug_dump_queue(thd->query_start());
   UNLOCK_QUEUE_DATA();
 
-end:
-  DBUG_PRINT("info", ("res=%d", res));
-  DBUG_RETURN(res);
+  DBUG_VOID_RETURN;
 }
 
 
@@ -452,133 +419,6 @@
 
 
 /*
-  Loads all ENABLED events from mysql.event into the prioritized
-  queue. Called during scheduler main thread initialization. Compiles
-  the events. Creates Event_queue_element instances for every ENABLED event
-  from mysql.event.
-
-  SYNOPSIS
-    Event_queue::load_events_from_db()
-      thd - Thread context. Used for memory allocation in some cases.
-
-  RETURN VALUE
-    0  OK
-   !0  Error (EVEX_OPEN_TABLE_FAILED, EVEX_MICROSECOND_UNSUP, 
-              EVEX_COMPILE_ERROR) - in all these cases mysql.event was
-              tampered.
-
-  NOTES
-    Reports the error to the console
-*/
-
-int
-Event_queue::load_events_from_db(THD *thd)
-{
-  TABLE *table;
-  READ_RECORD read_record_info;
-  int ret= -1;
-  uint count= 0;
-  bool clean_the_queue= TRUE;
-
-  DBUG_ENTER("Event_queue::load_events_from_db");
-  DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd));
-
-  if ((ret= db_repository->open_event_table(thd, TL_READ, &table)))
-  {
-    sql_print_error("SCHEDULER: Table mysql.event is damaged. Can not open");
-    DBUG_RETURN(EVEX_OPEN_TABLE_FAILED);
-  }
-
-  init_read_record(&read_record_info, thd, table ,NULL,1,0);
-  while (!(read_record_info.read_record(&read_record_info)))
-  {
-    Event_queue_element *et;
-    if (!(et= new Event_queue_element))
-    {
-      DBUG_PRINT("info", ("Out of memory"));
-      break;
-    }
-    DBUG_PRINT("info", ("Loading event from row."));
-
-    if ((ret= et->load_from_row(table)))
-    {
-      sql_print_error("SCHEDULER: Error while loading from mysql.event. "
-                      "Table probably corrupted");
-      break;
-    }
-    if (et->status != Event_queue_element::ENABLED)
-    {
-      DBUG_PRINT("info",("%s is disabled",et->name.str));
-      delete et;
-      continue;
-    }
-
-    /* let's find when to be executed */
-    if (et->compute_next_execution_time())
-    {
-      sql_print_error("SCHEDULER: Error while computing execution time of %s.%s."
-                      " Skipping", et->dbname.str, et->name.str);
-      continue;
-    }
-
-    {
-      Event_job_data temp_job_data;
-      DBUG_PRINT("info", ("Event %s loaded from row. ", et->name.str));
-
-      temp_job_data.load_from_row(table);
-
-      /*
-        We load only on scheduler root just to check whether the body
-        compiles.
-      */
-      switch (ret= temp_job_data.compile(thd, thd->mem_root)) {
-      case EVEX_MICROSECOND_UNSUP:
-        sql_print_error("SCHEDULER: mysql.event is tampered. MICROSECOND is not "
-                        "supported but found in mysql.event");
-        break;
-      case EVEX_COMPILE_ERROR:
-        sql_print_error("SCHEDULER: Error while compiling %s.%s. Aborting load",
-                        et->dbname.str, et->name.str);
-        break;
-      default:
-        break;
-      }
-      thd->end_statement();
-      thd->cleanup_after_query();
-    }
-    if (ret)
-    {
-      delete et;
-      goto end;
-    }
-
-    queue_insert_safe(&queue,  (byte *) et);
-    count++;
-  }
-  clean_the_queue= FALSE;
-end:
-  end_read_record(&read_record_info);
-
-  if (clean_the_queue)
-  {
-    empty_queue();
-    ret= -1;
-  }
-  else
-  {
-    ret= 0;
-    sql_print_information("SCHEDULER: Loaded %d event%s", count,
-                          (count == 1)?"":"s");
-  }
-
-  close_thread_tables(thd);
-
-  DBUG_PRINT("info", ("Status code %d. Loaded %d event(s)", ret, count));
-  DBUG_RETURN(ret);
-}
-
-
-/*
   Recalculates activation times in the queue. There is one reason for
   that. Because the values (execute_at) by which the queue is ordered are
   changed by calls to compute_next_execution_time() on a request from the
@@ -627,7 +467,7 @@
 {
   uint i;
   DBUG_ENTER("Event_queue::empty_queue");
-  DBUG_PRINT("enter", ("Purging the queue. %d element(s)", queue.elements));
+  DBUG_PRINT("enter", ("Purging the queue. %u element(s)", queue.elements));
   sql_print_information("SCHEDULER: Purging queue. %u events", queue.elements);
   /* empty the queue */
   for (i= 0; i < queue.elements; ++i)
@@ -688,31 +528,27 @@
 
   SYNOPSIS
     Event_queue::get_top_for_execution_if_time()
-      thd      [in]  Thread
-      job_data [out] The object to execute
+      thd        [in]  Thread
+      event_name [out] The object to execute
 
   RETURN VALUE
-    FALSE  No error. If *job_data==NULL then top not elligible for execution.
-           Could be that there is no top.
-    TRUE   Error
-    
+    FALSE  No error. event_name != NULL
+    TRUE   Serious error
 */
 
 bool
-Event_queue::get_top_for_execution_if_time(THD *thd, Event_job_data **job_data)
+Event_queue::get_top_for_execution_if_time(THD *thd,
+                Event_queue_element_for_exec **event_name)
 {
   bool ret= FALSE;
   struct timespec top_time;
-  Event_queue_element *top= NULL;
-  bool to_free= FALSE;
-  bool to_drop= FALSE;
-  *job_data= NULL;
+  *event_name= NULL;
   DBUG_ENTER("Event_queue::get_top_for_execution_if_time");
 
   LOCK_QUEUE_DATA();
   for (;;)
   {
-    int res;
+    Event_queue_element *top= NULL;
 
     /* Break loop if thd has been killed */
     if (thd->killed)
@@ -751,39 +587,30 @@
       continue;
     }
 
-    DBUG_PRINT("info", ("Ready for execution"));
-    if (!(*job_data= new Event_job_data()))
-    {
-      ret= TRUE;
-      break;
-    }
-    if ((res= db_repository->load_named_event(thd, top->dbname, top->name,
-                                              *job_data)))
+    if (!(*event_name= new Event_queue_element_for_exec()) ||
+        (*event_name)->init(top->dbname, top->name))
     {
-      DBUG_PRINT("error", ("Got %d from load_named_event", res));
-      delete *job_data;
-      *job_data= NULL;
       ret= TRUE;
       break;
     }
 
+    DBUG_PRINT("info", ("Ready for execution"));
     top->mark_last_executed(thd);
     if (top->compute_next_execution_time())
       top->status= Event_queue_element::DISABLED;
     DBUG_PRINT("info", ("event %s status is %d", top->name.str, top->status));
 
-    (*job_data)->execution_count= top->execution_count;
+    top->execution_count++;
+    (*event_name)->dropped= top->dropped;
 
     top->update_timing_fields(thd);
-    if (((top->execute_at.year && !top->expression) || top->execute_at_null) ||
-        (top->status == Event_queue_element::DISABLED))
+    if (top->status == Event_queue_element::DISABLED)
     {
       DBUG_PRINT("info", ("removing from the queue"));
       sql_print_information("SCHEDULER: Last execution of %s.%s. %s",
                             top->dbname.str, top->name.str,
                             top->dropped? "Dropping.":"");
-      to_free= TRUE;
-      to_drop= top->dropped;
+      delete top;
       queue_remove(&queue, 0);
     }
     else
@@ -794,19 +621,13 @@
   }
 end:
   UNLOCK_QUEUE_DATA();
-  if (to_drop)
-  {
-    DBUG_PRINT("info", ("Dropping from disk"));
-    top->drop(thd);
-  }
-  if (to_free)
-    delete top;
 
-  DBUG_PRINT("info", ("returning %d  et_new: 0x%lx ", ret, (long) *job_data));
+  DBUG_PRINT("info", ("returning %d  et_new: 0x%lx ",
+                      ret, (long) *event_name));
 
-  if (*job_data)
-    DBUG_PRINT("info", ("db: %s  name: %s  definer=%s", (*job_data)->dbname.str,
-               (*job_data)->name.str, (*job_data)->definer.str));
+  if (*event_name)
+    DBUG_PRINT("info", ("db: %s  name: %s",
+                        (*event_name)->dbname.str, (*event_name)->name.str));
 
   DBUG_RETURN(ret);
 }

--- 1.33/sql/event_scheduler.cc	2007-06-27 05:22:47 +04:00
+++ 1.34/sql/event_scheduler.cc	2007-06-27 05:22:47 +04:00
@@ -110,25 +110,22 @@
   SYNOPSIS
     post_init_event_thread()
       thd  Thread
+
+  NOTES
+    Before this is called, one should not do any DBUG_XXX() calls.
+
 */
 
 bool
 post_init_event_thread(THD *thd)
 {
-  my_thread_init();
-  pthread_detach_this_thread();
-  thd->real_id= pthread_self();
+  (void) init_new_connection_handler_thread();
   if (init_thr_lock() || thd->store_globals())
   {
     thd->cleanup();
     return TRUE;
   }
 
-#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
-  sigset_t set;
-    VOID(sigemptyset(&set));                    // Get mask in use
-  VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
-#endif
   pthread_mutex_lock(&LOCK_thread_count);
   threads.append(thd);
   thread_count++;
@@ -193,7 +190,7 @@
   thd->options|= OPTION_AUTO_IS_NULL;
   thd->client_capabilities|= CLIENT_MULTI_RESULTS;
   pthread_mutex_lock(&LOCK_thread_count);
-  thd->thread_id= thread_id++;
+  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
   pthread_mutex_unlock(&LOCK_thread_count);
 
   /*
@@ -224,20 +221,20 @@
 event_scheduler_thread(void *arg)
 {
   /* needs to be first for thread_stack */
-  THD *thd= (THD *)((struct scheduler_param *) arg)->thd;
+  THD *thd= (THD *) ((struct scheduler_param *) arg)->thd;
   Event_scheduler *scheduler= ((struct scheduler_param *) arg)->scheduler;
+  bool res;
 
-  my_free((char*)arg, MYF(0));
-
-  thd->thread_stack= (char *)&thd;              // remember where our stack is
+  thd->thread_stack= (char*) &thd;              // remember where our stack is
+  res= post_init_event_thread(thd);
 
   DBUG_ENTER("event_scheduler_thread");
-
-  if (!post_init_event_thread(thd))
+  my_free((char*)arg, MYF(0));
+  if (!res)
     scheduler->run(thd);
 
   deinit_event_thread(thd);
-
+  pthread_exit(0);
   DBUG_RETURN(0);                               // Against gcc warnings
 }
 
@@ -260,10 +257,12 @@
   /* needs to be first for thread_stack */
   THD *thd; 
   Event_queue_element_for_exec *event= (Event_queue_element_for_exec *)arg;
+  bool res;
 
   thd= event->thd;
   thd->thread_stack= (char *) &thd;             // remember where our stack is
-
+  res= post_init_event_thread(thd);
+  if (!res)
   Event_worker_thread worker_thread;
   worker_thread.run(thd, (Event_queue_element_for_exec *)arg);
 
@@ -350,8 +349,8 @@
   }
   DBUG_PRINT("info", ("BURAN %s.%s is landing!", event->dbname.str,
              event->name.str));
-
   delete event;
+  pthread_exit(0);
 }
 
 

--- 1.84/sql/event_data_objects.cc	2007-06-27 05:22:47 +04:00
+++ 1.85/sql/event_data_objects.cc	2007-06-27 05:22:47 +04:00
@@ -20,6 +20,8 @@
 #include "event_db_repository.h"
 #include "sp_head.h"
 
+/* That's a provisional solution */
+extern Event_db_repository events_event_db_repository;
 
 #define EVEX_MAX_INTERVAL_VALUE 1000000000L
 
@@ -30,6 +32,47 @@
 static void
 event_restore_security_context(THD *thd, Security_context *backup);
 
+
+/*
+  Initiliazes dbname and name of an Event_queue_element_for_exec
+  object
+
+  SYNOPSIS
+    Event_queue_element_for_exec::init()
+
+  RETURN VALUE
+    FALSE  OK
+    TRUE   Error (OOM)
+*/
+
+bool
+Event_queue_element_for_exec::init(LEX_STRING db, LEX_STRING n)
+{
+  if (!(dbname.str= my_strndup(db.str, dbname.length= db.length, MYF(MY_WME))))
+    return TRUE;
+  if (!(name.str= my_strndup(n.str, name.length= n.length, MYF(MY_WME))))
+  {
+    my_free((gptr) dbname.str, MYF(0));
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+/*
+  Destructor
+
+  SYNOPSIS
+    Event_queue_element_for_exec::~Event_queue_element_for_exec()
+*/
+
+Event_queue_element_for_exec::~Event_queue_element_for_exec()
+{
+  my_free((gptr) dbname.str, MYF(0));
+  my_free((gptr) name.str, MYF(0));
+}
+
+
 /*
   Returns a new instance
 
@@ -743,7 +786,7 @@
 */
 
 Event_job_data::Event_job_data()
-  :thd(NULL), sphead(NULL), sql_mode(0)
+  :sphead(NULL), sql_mode(0)
 {
 }
 
@@ -1239,6 +1282,7 @@
     DBUG_PRINT("info", ("Dropped: %d", dropped));
     status= Event_queue_element::DISABLED;
     status_changed= TRUE;
+    dropped= TRUE;
 
     goto ret;
   }
@@ -1447,32 +1491,6 @@
 
 
 /*
-  Drops the event
-
-  SYNOPSIS
-    Event_queue_element::drop()
-      thd   thread context
-
-  RETURN VALUE
-    0       OK
-   -1       Cannot open mysql.event
-   -2       Cannot find the event in mysql.event (already deleted?)
-
-   others   return code from SE in case deletion of the event row
-            failed.
-*/
-
-int
-Event_queue_element::drop(THD *thd)
-{
-  DBUG_ENTER("Event_queue_element::drop");
-
-  DBUG_RETURN(Events::get_instance()->
-                    drop_event(thd, dbname, name, FALSE, TRUE));
-}
-
-
-/*
   Saves status and last_executed_at to the disk if changed.
 
   SYNOPSIS
@@ -1503,13 +1521,13 @@
 
   thd->reset_n_backup_open_tables_state(&backup);
 
-  if (Events::get_instance()->open_event_table(thd, TL_WRITE, &table))
+  if (events_event_db_repository.open_event_table(thd, TL_WRITE, &table))
   {
     ret= TRUE;
     goto done;
   }
   fields= table->field;
-  if ((ret= Events::get_instance()->db_repository->
+  if ((ret= events_event_db_repository.
                                  find_named_event(thd, dbname, name, table)))
     goto done;
 
@@ -1792,16 +1810,21 @@
     DBUG_PRINT("error", ("error during compile or thd->is_fatal_error: %d",
                           thd->is_fatal_error));
     /*
-      Free lex associated resources
-      QQ: Do we really need all this stuff here?
+      The first thing we do after parse error is freeing sp_head to
+      ensure that we have restored original memroot.
     */
+    if (lex.sphead)
+    {
+      /* Clean up after failed stored procedure/function */
+      delete lex.sphead;
+      lex.sphead= NULL;
+    }
+    lex.unit.cleanup();
+
     sql_print_error("SCHEDULER: Error during compilation of %s.%s or "
                     "thd->is_fatal_error: %d",
                     dbname.str, name.str, thd->is_fatal_error);
 
-    lex.unit.cleanup();
-    delete lex.sphead;
-    sphead= lex.sphead= NULL;
     ret= EVEX_COMPILE_ERROR;
     goto done;
   }

--- 1.166/mysql-test/r/subselect.result	2007-06-27 05:22:47 +04:00
+++ 1.167/mysql-test/r/subselect.result	2007-06-27 05:22:47 +04:00
@@ -3760,3 +3760,116 @@
 2	3	h
 3	4	i
 DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t1xt2;
+CREATE TABLE t1 (
+id_1 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t2 (
+id_2 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t1xt2 (
+id_1 int(5) NOT NULL,
+id_2 int(5) NOT NULL
+);
+INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd');
+INSERT INTO t2 VALUES (2, 'bb'), (3, 'cc'), (4, 'dd'), (12, 'aa');
+INSERT INTO t1xt2 VALUES (2, 2), (3, 3), (4, 4);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+3
+4
+insert INTO t1xt2 VALUES (1, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+2
+3
+4
+insert INTO t1xt2 VALUES (2, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+3
+4
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t1xt2;

--- 1.145/mysql-test/t/subselect.test	2007-06-27 05:22:47 +04:00
+++ 1.146/mysql-test/t/subselect.test	2007-06-27 05:22:47 +04:00
@@ -2636,3 +2636,109 @@
       (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)) AS test      
   FROM t1 GROUP BY a;                                                         
 DROP TABLE t1;      
+# Bug#20835 (literal string with =any values)
+#
+CREATE TABLE t1 (s1 char(1));
+INSERT INTO t1 VALUES ('a');
+SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1);
+DROP TABLE t1;
+
+#
+# Bug#21904 (parser problem when using IN with a double "(())")
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t1xt2;
+--enable_warnings
+
+CREATE TABLE t1 (
+  id_1 int(5) NOT NULL,
+  t varchar(4) DEFAULT NULL
+);
+
+CREATE TABLE t2 (
+  id_2 int(5) NOT NULL,
+  t varchar(4) DEFAULT NULL
+);
+
+CREATE TABLE t1xt2 (
+  id_1 int(5) NOT NULL,
+  id_2 int(5) NOT NULL
+);
+
+INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd');
+
+INSERT INTO t2 VALUES (2, 'bb'), (3, 'cc'), (4, 'dd'), (12, 'aa');
+
+INSERT INTO t1xt2 VALUES (2, 2), (3, 3), (4, 4);
+
+# subselect returns 0 rows
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1)));
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1))));
+
+insert INTO t1xt2 VALUES (1, 12);
+
+# subselect returns 1 row
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+
+insert INTO t1xt2 VALUES (2, 12);
+
+# subselect returns more than 1 row
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t1xt2;
+

--- 1.146/sql/item_subselect.cc	2007-06-27 05:22:47 +04:00
+++ 1.147/sql/item_subselect.cc	2007-06-27 05:22:47 +04:00
@@ -51,6 +51,10 @@
 void Item_subselect::init(st_select_lex *select_lex,
 			  select_subselect *result)
 {
+  /*
+    Please see Item_singlerow_subselect::invalidate_and_restore_select_lex(),
+    which depends on alterations to the parse tree implemented here.
+  */
 
   DBUG_ENTER("Item_subselect::init");
   DBUG_PRINT("enter", ("select_lex: 0x%lx", (long) select_lex));
@@ -91,6 +95,12 @@
   DBUG_VOID_RETURN;
 }
 
+st_select_lex *
+Item_subselect::get_select_lex()
+{
+  return unit->first_select();
+}
+
 void Item_subselect::cleanup()
 {
   DBUG_ENTER("Item_subselect::cleanup");
@@ -309,6 +319,26 @@
   maybe_null= 1;
   max_columns= UINT_MAX;
   DBUG_VOID_RETURN;
+}
+
+st_select_lex *
+Item_singlerow_subselect::invalidate_and_restore_select_lex()
+{
+  DBUG_ENTER("Item_singlerow_subselect::invalidate_and_restore_select_lex");
+  st_select_lex *result= get_select_lex();
+
+  DBUG_ASSERT(result);
+
+  /*
+    This code restore the parse tree in it's state before the execution of
+    Item_singlerow_subselect::Item_singlerow_subselect(),
+    and in particular decouples this object from the SELECT_LEX,
+    so that the SELECT_LEX can be used with a different flavor
+    or Item_subselect instead, as part of query rewriting.
+  */
+  unit->item= NULL;
+
+  DBUG_RETURN(result);
 }
 
 Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,

--- 1.89/sql/item_subselect.h	2007-06-27 05:22:47 +04:00
+++ 1.90/sql/item_subselect.h	2007-06-27 05:22:47 +04:00
@@ -127,6 +127,12 @@
   enum_parsing_place place() { return parsing_place; }
   bool walk(Item_processor processor, bool walk_subquery, byte *arg);
 
+  /**
+    Get the SELECT_LEX structure associated with this Item.
+    @return the SELECT_LEX structure associated with this Item
+  */
+  st_select_lex* get_select_lex();
+
   friend class select_subselect;
   friend class Item_in_optimizer;
   friend bool Item_field::fix_fields(THD *, Item **);
@@ -169,6 +175,20 @@
   bool check_cols(uint c);
   bool null_inside();
   void bring_value();
+
+  /**
+    This method is used to implement a special case of semantic tree
+    rewriting, mandated by a SQL:2003 exception in the specification.
+    The only caller of this method is handle_sql2003_note184_exception(),
+    see the code there for more details.
+    Note that this method breaks the object internal integrity, by
+    removing it's association with the corresponding SELECT_LEX,
+    making this object orphan from the parse tree.
+    No other method, beside the destructor, should be called on this
+    object, as it is now invalid.
+    @return the SELECT_LEX structure that was given in the constructor.
+  */
+  st_select_lex* invalidate_and_restore_select_lex();
 
   friend class select_singlerow_subselect;
 };

--- 1.38/mysql-test/t/ps_1general.test	2007-06-27 05:22:47 +04:00
+++ 1.39/mysql-test/t/ps_1general.test	2007-06-27 05:22:47 +04:00
@@ -575,7 +575,7 @@
 create table t5 (a int) ;
 # rename must fail, t7 does not exist
 # Clean up the filename here because embedded server reports whole path
---replace_result \\ / $MYSQL_TEST_DIR . /var/master-data/ "" t7.frm t7
+--replace_result \\ / $MYSQLTEST_VARDIR . /master-data/ "" t7.frm t7
 --error 1017
 execute stmt1 ;
 create table t7 (a int) ;

--- 1.3/mysql-test/r/partition_innodb.result	2007-06-27 05:22:47 +04:00
+++ 1.4/mysql-test/r/partition_innodb.result	2007-06-27 05:22:47 +04:00
@@ -74,3 +74,57 @@
   `a` int(11) DEFAULT NULL
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (a) (PARTITION p0 VALUES IN (0) ENGINE = InnoDB) */
 drop table t1;
+create table t1
+(
+id int unsigned auto_increment,
+time datetime not null,
+first_name varchar(40),
+last_name varchar(50),
+primary key (id, time),
+index first_index (first_name),
+index last_index (last_name)	
+) engine=Innodb partition by range (to_days(time)) (
+partition p1 values less than (to_days('2007-02-07')),
+partition p2 values less than (to_days('2007-02-08')),
+partition p3 values less than MAXVALUE
+);
+insert into t1 (time, first_name, last_name) values ('2007-02-07', 'Q', 'Robert'),
+('2007-02-07', 'Mark', 'Nate'), ('2007-02-07', 'Nate', 'Oscar'),
+('2007-02-07', 'Zack', 'Alice'), ('2007-02-07', 'Jack', 'Kathy'),
+('2007-02-06', 'Alice', 'Alice'), ('2007-02-06', 'Brian', 'Charles'),
+('2007-02-06', 'Charles', 'David'), ('2007-02-06', 'David', 'Eric'),
+('2007-02-07', 'Hector', 'Isaac'), ('2007-02-07', 'Oscar', 'Patricia'),
+('2007-02-07', 'Patricia', 'Q'), ('2007-02-07', 'X', 'Yuri'),
+('2007-02-07', 'Robert', 'Shawn'), ('2007-02-07', 'Kathy', 'Lois'),
+('2007-02-07', 'Eric', 'Francis'), ('2007-02-06', 'Shawn', 'Theron'),
+('2007-02-06', 'U', 'Vincent'), ('2007-02-06', 'Francis', 'George'),
+('2007-02-06', 'George', 'Hector'), ('2007-02-06', 'Vincent', 'Walter'),
+('2007-02-06', 'Walter', 'X'), ('2007-02-07', 'Lois', 'Mark'),
+('2007-02-07', 'Yuri', 'Zack'), ('2007-02-07', 'Isaac', 'Jack'),
+('2007-02-07', 'Sharon', 'Mark'), ('2007-02-07', 'Michael', 'Michelle'),
+('2007-02-07', 'Derick', 'Nathan'), ('2007-02-07', 'Peter', 'Xavier'),
+('2007-02-07', 'Fred', 'Harold'), ('2007-02-07', 'Katherine', 'Lisa'),
+('2007-02-07', 'Tom', 'Rina'), ('2007-02-07', 'Jerry', 'Victor'),
+('2007-02-07', 'Alexander', 'Terry'), ('2007-02-07', 'Justin', 'John'),
+('2007-02-07', 'Greg', 'Ernest'), ('2007-02-07', 'Robert', 'Q'),
+('2007-02-07', 'Nate', 'Mark'), ('2007-02-07', 'Oscar', 'Nate'),
+('2007-02-07', 'Alice', 'Zack'), ('2007-02-07', 'Kathy', 'Jack'),
+('2007-02-06', 'Alice', 'Alice'), ('2007-02-06', 'Charles', 'Brian'),
+('2007-02-06', 'David', 'Charles'), ('2007-02-06', 'Eric', 'David'),
+('2007-02-07', 'Isaac', 'Hector'), ('2007-02-07', 'Patricia', 'Oscar'),
+('2007-02-07', 'Q', 'Patricia'), ('2007-02-07', 'Yuri', 'X'),
+('2007-02-07', 'Shawn', 'Robert'), ('2007-02-07', 'Lois', 'Kathy'),
+('2007-02-07', 'Francis', 'Eric'), ('2007-02-06', 'Theron', 'Shawn'),
+('2007-02-06', 'Vincent', 'U'), ('2007-02-06', 'George', 'Francis'),
+('2007-02-06', 'Hector', 'George'), ('2007-02-06', 'Walter', 'Vincent'),
+('2007-02-06', 'X', 'Walter'), ('2007-02-07', 'Mark', 'Lois'),
+('2007-02-07', 'Zack', 'Yuri'), ('2007-02-07', 'Jack', 'Isaac'),
+('2007-02-07', 'Mark', 'Sharon'), ('2007-02-07', 'Michelle', 'Michael'),
+('2007-02-07', 'Nathan', 'Derick'), ('2007-02-07', 'Xavier', 'Peter'),
+('2007-02-07', 'Harold', 'Fred'), ('2007-02-07', 'Lisa', 'Katherine'),
+('2007-02-07', 'Rina', 'Tom'), ('2007-02-07', 'Victor', 'Jerry'),
+('2007-02-07', 'Terry', 'Alexander'), ('2007-02-07', 'John', 'Justin'),
+('2007-02-07', 'Ernest', 'Greg');
+SELECT * FROM t1 WHERE first_name='Andy' OR last_name='Jake';
+id	time	first_name	last_name
+drop table t1;
Thread
bk commit into 5.1 tree (sergefp:1.2417)Sergey Petrunia27 Jun