MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Mattias Jonsson Date:August 11 2009 1:04pm
Subject:bzr commit into mysql-pe branch (mattias.jonsson:3526) Bug#32115
View as plain text  
#At file:///Users/mattiasj/clones/bzrroot/topush-60-bugteam/ based on revid:alik@stripped

 3526 Mattias Jonsson	2009-08-11 [merge]
      merge of bug#32115

    modified:
      libmysqld/lib_sql.cc
      sql/event_data_objects.cc
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster_binlog.cc
      sql/slave.cc
      sql/sql_insert.cc
      sql/sql_partition.cc
      sql/table.cc
=== modified file 'libmysqld/lib_sql.cc'
--- a/libmysqld/lib_sql.cc	2009-07-31 07:07:20 +0000
+++ b/libmysqld/lib_sql.cc	2009-08-07 16:25:06 +0000
@@ -119,7 +119,6 @@ emb_advanced_command(MYSQL *mysql, enum 
   thd->current_stmt= stmt;
 
   thd->store_globals();				// Fix if more than one connect
-  lex_start(thd);
   /* 
      We have to call free_old_query before we start to fill mysql->fields 
      for new query. In the case of embedded server we collect field data

=== modified file 'sql/event_data_objects.cc'
--- a/sql/event_data_objects.cc	2009-07-24 16:14:20 +0000
+++ b/sql/event_data_objects.cc	2009-08-07 16:25:06 +0000
@@ -1368,7 +1368,6 @@ Event_job_data::execute(THD *thd, bool d
 
   DBUG_ENTER("Event_job_data::execute");
 
-  lex_start(thd);
   mysql_reset_thd_for_next_command(thd);
 
   /*

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2009-06-19 09:28:44 +0000
+++ b/sql/ha_ndbcluster.cc	2009-08-07 09:26:33 +0000
@@ -7245,7 +7245,6 @@ int ndb_create_table_from_engine(THD *th
   LEX *old_lex= thd->lex, newlex;
   thd->lex= &newlex;
   newlex.current_select= NULL;
-  lex_start(thd);
   int res= ha_create_table_from_engine(thd, db, table_name);
   thd->lex= old_lex;
   return res;
@@ -10098,7 +10097,6 @@ pthread_handler_t ndb_util_thread_func(v
   thd->thread_stack= (char*)&thd; /* remember where our stack is */
   if (thd->store_globals())
     goto ndb_util_thread_fail;
-  lex_start(thd);
   thd->init_for_queries();
   thd->version=refresh_version;
   thd->main_security_ctx.host_or_ip= "";

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2009-08-01 21:59:45 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2009-08-07 16:25:06 +0000
@@ -4707,7 +4707,6 @@ pthread_handler_t ndb_binlog_thread_func
     pthread_exit(0);
     DBUG_RETURN(NULL);
   }
-  lex_start(thd);
 
   thd->init_for_queries();
   thd->command= COM_DAEMON;

=== modified file 'sql/slave.cc'
--- a/sql/slave.cc	2009-07-28 14:16:37 +0000
+++ b/sql/slave.cc	2009-08-07 16:25:06 +0000
@@ -2048,7 +2048,6 @@ static int init_slave_thread(THD* thd, S
     thd->cleanup();
     DBUG_RETURN(-1);
   }
-  lex_start(thd);
 
   if (thd_type == SLAVE_THD_SQL)
     thd_proc_info(thd, "Waiting for the next event in relay log");

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2009-07-31 19:46:24 +0000
+++ b/sql/sql_insert.cc	2009-08-07 16:25:06 +0000
@@ -2399,12 +2399,6 @@ pthread_handler_t handle_delayed_insert(
     goto err;
   }
 
-  /*
-    Open table requires an initialized lex in case the table is
-    partitioned. The .frm file contains a partial SQL string which is
-    parsed using a lex, that depends on initialized thd->lex.
-  */
-  lex_start(thd);
   thd->lex->sql_command= SQLCOM_INSERT;        // For innodb::store_lock()
   /*
     Statement-based replication of INSERT DELAYED has problems with RAND()

=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc	2009-08-05 13:08:40 +0000
+++ b/sql/sql_partition.cc	2009-08-07 16:25:06 +0000
@@ -859,6 +859,85 @@ int check_signed_flag(partition_info *pa
   return error;
 }
 
+/**
+  Initialize lex object for use in fix_fields and parsing.
+
+  SYNOPSIS
+    init_lex_with_single_table()
+    @param thd                 The thread object
+    @param table               The table object
+  @return Operation status
+    @retval TRUE                An error occurred, memory allocation error
+    @retval FALSE               Ok
+
+  DESCRIPTION
+    This function is used to initialize a lex object on the
+    stack for use by fix_fields and for parsing. In order to
+    work properly it also needs to initialize the
+    Name_resolution_context object of the lexer.
+    Finally it needs to set a couple of variables to ensure
+    proper functioning of fix_fields.
+*/
+
+static int
+init_lex_with_single_table(THD *thd, TABLE *table, LEX *lex)
+{
+  TABLE_LIST *table_list;
+  Table_ident *table_ident;
+  SELECT_LEX *select_lex= &lex->select_lex;
+  Name_resolution_context *context= &select_lex->context;
+  /*
+    We will call the parser to create a part_info struct based on the
+    partition string stored in the frm file.
+    We will use a local lex object for this purpose. However we also
+    need to set the Name_resolution_object for this lex object. We
+    do this by using add_table_to_list where we add the table that
+    we're working with to the Name_resolution_context.
+  */
+  thd->lex= lex;
+  lex_start(thd);
+  context->init();
+  if ((!(table_ident= new Table_ident(thd,
+                                      table->s->table_name,
+                                      table->s->db, TRUE))) ||
+      (!(table_list= select_lex->add_table_to_list(thd,
+                                                   table_ident,
+                                                   NULL,
+                                                   0))))
+    return TRUE;
+  context->resolve_in_table_list_only(table_list);
+  lex->use_only_table_context= TRUE;
+  select_lex->cur_pos_in_select_list= UNDEF_POS;
+  table->map= 1; //To ensure correct calculation of const item
+  table->get_fields_in_item_tree= TRUE;
+  table_list->table= table;
+  return FALSE;
+}
+
+/**
+  End use of local lex with single table
+
+  SYNOPSIS
+    end_lex_with_single_table()
+    @param thd               The thread object
+    @param table             The table object
+    @param old_lex           The real lex object connected to THD
+
+  DESCRIPTION
+    This function restores the real lex object after calling
+    init_lex_with_single_table and also restores some table
+    variables temporarily set.
+*/
+
+static void
+end_lex_with_single_table(THD *thd, TABLE *table, LEX *old_lex)
+{
+  LEX *lex= thd->lex;
+  table->map= 0;
+  table->get_fields_in_item_tree= FALSE;
+  lex_end(lex);
+  thd->lex= old_lex;
+}
 
 /*
   The function uses a new feature in fix_fields where the flag 
@@ -900,18 +979,16 @@ bool fix_fields_part_func(THD *thd, Item
                           bool is_sub_part, bool is_field_to_be_setup)
 {
   partition_info *part_info= table->part_info;
-  uint dir_length, home_dir_length;
   bool result= TRUE;
-  TABLE_LIST tables;
-  TABLE_LIST *save_table_list, *save_first_table, *save_last_table;
   int error;
-  Name_resolution_context *context;
   const char *save_where;
-  char* db_name;
-  char db_name_string[FN_REFLEN];
-  bool save_use_only_table_context;
+  LEX *old_lex= thd->lex;
+  LEX lex;
   DBUG_ENTER("fix_fields_part_func");
 
+  if (init_lex_with_single_table(thd, table, &lex))
+    goto end;
+
   if (part_info->fixed)
   {
     if (!(is_sub_part || (error= check_signed_flag(part_info))))
@@ -919,43 +996,8 @@ bool fix_fields_part_func(THD *thd, Item
     goto end;
   }
 
-  /*
-    Set-up the TABLE_LIST object to be a list with a single table
-    Set the object to zero to create NULL pointers and set alias
-    and real name to table name and get database name from file name.
-    TODO: Consider generalizing or refactoring Lex::add_table_to_list() so
-    it can be used in all places where we create TABLE_LIST objects.
-    Also consider creating appropriate constructors for TABLE_LIST.
-  */
-
-  bzero((void*)&tables, sizeof(TABLE_LIST));
-  tables.alias= tables.table_name= (char*) table->s->table_name.str;
-  tables.table= table;
-  tables.next_local= 0;
-  tables.next_name_resolution_table= 0;
-  /*
-    Cache the table in Item_fields. All the tables can be cached except
-    the trigger pseudo table.
-  */
-  tables.cacheable_table= TRUE;
-  context= thd->lex->current_context();
-  tables.select_lex= context->select_lex;
-  strmov(db_name_string, table->s->normalized_path.str);
-  dir_length= dirname_length(db_name_string);
-  db_name_string[dir_length - 1]= 0;
-  home_dir_length= dirname_length(db_name_string);
-  db_name= &db_name_string[home_dir_length];
-  tables.db= db_name;
-
-  table->map= 1; //To ensure correct calculation of const item
-  table->get_fields_in_item_tree= TRUE;
-  save_table_list= context->table_list;
-  save_first_table= context->first_name_resolution_table;
-  save_last_table= context->last_name_resolution_table;
-  context->table_list= &tables;
-  context->first_name_resolution_table= &tables;
-  context->last_name_resolution_table= NULL;
-  func_expr->walk(&Item::change_context_processor, 0, (uchar*) context);
+  func_expr->walk(&Item::change_context_processor, 0,
+                  (uchar*) &lex.select_lex.context);
   save_where= thd->where;
   thd->where= "partition function";
   /*
@@ -970,23 +1012,12 @@ bool fix_fields_part_func(THD *thd, Item
     that does this during val_int must be disallowed as partition
     function.
     SEE Bug #21658
-  */
-  /*
+
     This is a tricky call to prepare for since it can have a large number
     of interesting side effects, both desirable and undesirable.
   */
-
-  save_use_only_table_context= thd->lex->use_only_table_context;
-  thd->lex->use_only_table_context= TRUE;
-  thd->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
-  
   error= func_expr->fix_fields(thd, (Item**)&func_expr);
 
-  thd->lex->use_only_table_context= save_use_only_table_context;
-
-  context->table_list= save_table_list;
-  context->first_name_resolution_table= save_first_table;
-  context->last_name_resolution_table= save_last_table;
   if (unlikely(error))
   {
     DBUG_PRINT("info", ("Field in partition function not part of table"));
@@ -994,7 +1025,6 @@ bool fix_fields_part_func(THD *thd, Item
       clear_field_flag(table);
     goto end;
   }
-  thd->where= save_where;
   if (unlikely(func_expr->const_item()))
   {
     my_error(ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR, MYF(0));
@@ -1009,8 +1039,11 @@ bool fix_fields_part_func(THD *thd, Item
   if (!is_sub_part)
     part_info->fixed= TRUE;
 end:
-  table->get_fields_in_item_tree= FALSE;
-  table->map= 0; //Restore old value
+  end_lex_with_single_table(thd, table, old_lex);
+#if !defined(DBUG_OFF)
+  func_expr->walk(&Item::change_context_processor, 0,
+                  (uchar*) 0);
+#endif
   DBUG_RETURN(result);
 }
 
@@ -3804,26 +3837,13 @@ bool mysql_unpack_partition(THD *thd,
   LEX lex;
   DBUG_ENTER("mysql_unpack_partition");
 
-  thd->lex= &lex;
   thd->variables.character_set_client= system_charset_info;
 
   Parser_state parser_state(thd, part_buf, part_info_len);
 
-  lex_start(thd);
-  *work_part_info_used= false;
-  /*
-    We need to use the current SELECT_LEX since I need to keep the
-    Name_resolution_context object which is referenced from the
-    Item_field objects.
-    This is not a nice solution since if the parser uses current_select
-    for anything else it will corrupt the current LEX object.
-    Also, we need to make sure there even is a select -- if the statement
-    was a "USE ...", current_select will be NULL, but we may still end up
-    here if we try to log to a partitioned table. This is currently
-    unsupported, but should still fail rather than crash!
-  */
-  if (!(thd->lex->current_select= old_lex->current_select))
+  if (init_lex_with_single_table(thd, table, &lex))
     goto end;
+
   /*
     All Items created is put into a free list on the THD object. This list
     is used to free all Item objects after completing a query. We don't
@@ -3833,6 +3853,7 @@ bool mysql_unpack_partition(THD *thd,
     Thus we move away the current list temporarily and start a new list that
     we then save in the partition info structure.
   */
+  *work_part_info_used= FALSE;
   lex.part_info= new partition_info();/* Indicates MYSQLparse from this place */
   if (!lex.part_info)
   {
@@ -3948,8 +3969,7 @@ bool mysql_unpack_partition(THD *thd,
 
   result= FALSE;
 end:
-  lex_end(thd->lex);
-  thd->lex= old_lex;
+  end_lex_with_single_table(thd, table, old_lex);
   thd->variables.character_set_client= old_character_set_client;
   DBUG_RETURN(result);
 }

=== modified file 'sql/table.cc'
--- a/sql/table.cc	2009-07-29 10:25:07 +0000
+++ b/sql/table.cc	2009-08-07 16:25:06 +0000
@@ -1964,8 +1964,6 @@ int open_table_from_share(THD *thd, TABL
       thd->restore_active_arena(&part_func_arena, &backup_arena);
       goto partititon_err;
     }
-    /* fix_partition_func needs thd->lex set up. TODO: fix! */
-    DBUG_ASSERT(thd->lex->is_lex_started);
     outparam->part_info->is_auto_partitioned= share->auto_partitioned;
     DBUG_PRINT("info", ("autopartitioned: %u", share->auto_partitioned));
     /* we should perform the fix_partition_func in either local or


Attachment: [text/bzr-bundle]
Thread
bzr commit into mysql-pe branch (mattias.jonsson:3526) Bug#32115Mattias Jonsson11 Aug