List:Commits« Previous MessageNext Message »
From:dlenev Date:February 27 2006 4:21pm
Subject:bk commit into 5.1 tree (dlenev:1.2185)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of dlenev. When dlenev 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
  1.2185 06/02/27 19:21:04 dlenev@stripped +24 -0
  Merge mysql.com:/home/dlenev/src/mysql-5.0-bg13525
  into  mysql.com:/home/dlenev/src/mysql-5.1-merges2

  sql/sql_yacc.yy
    1.467 06/02/27 19:20:58 dlenev@stripped +1 -3
    Manual merge.

  sql/sql_trigger.cc
    1.48 06/02/27 19:20:58 dlenev@stripped +17 -23
    Manual merge.

  sql/sql_rename.cc
    1.36 06/02/27 19:20:58 dlenev@stripped +6 -2
    Manual merge.

  storage/myisammrg/myrg_queue.c
    1.13 06/02/27 18:58:33 dlenev@stripped +0 -0
    Auto merged

  sql/sql_table.cc
    1.311 06/02/27 18:58:33 dlenev@stripped +0 -0
    Auto merged

  sql/sql_show.cc
    1.313 06/02/27 18:58:33 dlenev@stripped +0 -0
    Auto merged

  sql/sql_select.h
    1.106 06/02/27 18:58:32 dlenev@stripped +0 -0
    Auto merged

  sql/sql_parse.cc
    1.525 06/02/27 18:58:32 dlenev@stripped +0 -0
    Auto merged

  sql/sql_base.cc
    1.307 06/02/27 18:58:32 dlenev@stripped +0 -0
    Auto merged

  sql/ha_myisammrg.cc
    1.82 06/02/27 18:58:32 dlenev@stripped +0 -0
    Auto merged

  sql/field.h
    1.177 06/02/27 18:58:32 dlenev@stripped +0 -0
    Auto merged

  sql/field.cc
    1.303 06/02/27 18:58:32 dlenev@stripped +0 -0
    Auto merged

  mysql-test/t/view.test
    1.138 06/02/27 18:58:31 dlenev@stripped +0 -0
    Auto merged

  mysql-test/t/trigger.test
    1.36 06/02/27 18:58:31 dlenev@stripped +0 -0
    Auto merged

  mysql-test/t/ps.test
    1.60 06/02/27 18:58:31 dlenev@stripped +0 -0
    Auto merged

  mysql-test/r/view.result
    1.150 06/02/27 18:58:31 dlenev@stripped +0 -0
    Auto merged

  mysql-test/r/trigger.result
    1.31 06/02/27 18:58:31 dlenev@stripped +0 -0
    Auto merged

  mysql-test/r/ps.result
    1.62 06/02/27 18:58:31 dlenev@stripped +0 -0
    Auto merged

  mysql-test/r/merge.result
    1.49 06/02/27 18:58:31 dlenev@stripped +0 -0
    Auto merged

  mysql-test/r/heap.result
    1.45 06/02/27 18:58:31 dlenev@stripped +0 -0
    Auto merged

  mysql-test/mysql-test-run.sh
    1.304 06/02/27 18:58:31 dlenev@stripped +0 -0
    Auto merged

  mysql-test/mysql-test-run.pl
    1.75 06/02/27 18:58:31 dlenev@stripped +0 -0
    Auto merged

  include/my_global.h
    1.122 06/02/27 18:58:31 dlenev@stripped +0 -0
    Auto merged

  client/mysqltest.c
    1.189 06/02/27 18:58:31 dlenev@stripped +0 -0
    Auto merged

  storage/myisammrg/myrg_queue.c
    1.10.2.2 06/02/27 18:58:30 dlenev@stripped +0 -0
    Merge rename: myisammrg/myrg_queue.c -> storage/myisammrg/myrg_queue.c

# 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:	dlenev
# Host:	brandersnatch.site
# Root:	/home/dlenev/src/mysql-5.1-merges2/RESYNC

--- 1.303/mysql-test/mysql-test-run.sh	2006-02-26 16:11:52 +03:00
+++ 1.304/mysql-test/mysql-test-run.sh	2006-02-27 18:58:31 +03:00
@@ -202,6 +202,7 @@
 REALT=0
 FAST_START=""
 MYSQL_TMP_DIR=$MYSQL_TEST_DIR/var/tmp
+export MYSQL_TMP_DIR
 
 # Use a relative path for where the slave will find the dumps
 # generated by "LOAD DATA" on the master. The path is relative

--- 1.302/sql/field.cc	2006-02-25 21:35:07 +03:00
+++ 1.303/sql/field.cc	2006-02-27 18:58:32 +03:00
@@ -8297,13 +8297,11 @@
     create_field::create_length_to_internal_length()
   
   DESCRIPTION
-    Convert create_field::length from number of characters to number of bytes,
-    save original value in chars_length.
+    Convert create_field::length from number of characters to number of bytes.
 */
 
 void create_field::create_length_to_internal_length(void)
 {
-  chars_length= length;
   switch (sql_type) {
   case MYSQL_TYPE_TINY_BLOB:
   case MYSQL_TYPE_MEDIUM_BLOB:
@@ -8355,7 +8353,7 @@
 {
   field_name= "";
   sql_type= sql_type_arg;
-  length= length_arg;;
+  char_length= length= length_arg;;
   unireg_check= Field::NONE;
   interval= 0;
   charset= &my_charset_bin;
@@ -8683,6 +8681,8 @@
   case FIELD_TYPE_DECIMAL:
     DBUG_ASSERT(0); /* Was obsolete */
   }
+  /* Remember the value of length */
+  char_length= length;
 
   if (!(flags & BLOB_FLAG) &&
       ((length > max_field_charlength && fld_type != FIELD_TYPE_SET &&
@@ -9023,6 +9023,7 @@
   else
     interval=0;
   def=0;
+  char_length= length;
 
   if (!(flags & (NO_DEFAULT_VALUE_FLAG | BLOB_FLAG)) &&
       old_field->ptr && orig_field &&

--- 1.176/sql/field.h	2006-02-02 16:48:04 +03:00
+++ 1.177/sql/field.h	2006-02-27 18:58:32 +03:00
@@ -1410,9 +1410,10 @@
   */
   ulong length;
   /*
-    The value of 'length' before a call to create_length_to_internal_length
+    The value of `length' as set by parser: is the number of characters
+    for most of the types, or of bytes for BLOBs or numeric types.
   */
-  uint32 chars_length;
+  uint32 char_length;
   uint  decimals, flags, pack_length, key_length;
   Field::utype unireg_check;
   TYPELIB *interval;			// Which interval to use

--- 1.81/sql/ha_myisammrg.cc	2006-02-26 00:20:52 +03:00
+++ 1.82/sql/ha_myisammrg.cc	2006-02-27 18:58:32 +03:00
@@ -308,7 +308,27 @@
   table->s->keys_in_use.set_prefix(table->s->keys);
   table->s->db_options_in_use= info.options;
   mean_rec_length= info.reclength;
-  block_size=0;
+  
+  /* 
+    The handler::block_size is used all over the code in index scan cost
+    calculations. It is used to get number of disk seeks required to
+    retrieve a number of index tuples.
+    If the merge table has N underlying tables, then (assuming underlying
+    tables have equal size, the only "simple" approach we can use)
+    retrieving X index records from a merge table will require N times more
+    disk seeks compared to doing the same on a MyISAM table with equal
+    number of records.
+    In the edge case (file_tables > myisam_block_size) we'll get
+    block_size==0, and index calculation code will act as if we need one
+    disk seek to retrieve one index tuple.
+
+    TODO: In 5.2 index scan cost calculation will be factored out into a
+    virtual function in class handler and we'll be able to remove this hack.
+  */
+  block_size= 0;
+  if (file->tables)
+    block_size= myisam_block_size / file->tables;
+  
   update_time=0;
 #if SIZEOF_OFF_T > 4
   ref_length=6;					// Should be big enough

--- 1.306/sql/sql_base.cc	2006-02-26 16:12:51 +03:00
+++ 1.307/sql/sql_base.cc	2006-02-27 18:58:32 +03:00
@@ -4416,7 +4416,6 @@
 {
   Field_iterator_table_ref it_1, it_2;
   Natural_join_column *nj_col_1, *nj_col_2;
-  const char *field_name_1;
   Query_arena *arena, backup;
   bool add_columns= TRUE;
   bool result= TRUE;
@@ -4449,6 +4448,7 @@
   {
     bool is_created_1;
     bool found= FALSE;
+    const char *field_name_1;
     if (!(nj_col_1= it_1.get_or_create_column_ref(&is_created_1)))
       goto err;
     field_name_1= nj_col_1->name();
@@ -4649,7 +4649,6 @@
 {
   Field_iterator_table_ref it_1, it_2;
   Natural_join_column *nj_col_1, *nj_col_2;
-  bool is_created;
   Query_arena *arena, backup;
   bool result= TRUE;
   List<Natural_join_column> *non_join_columns;

--- 1.105/sql/sql_select.h	2006-02-25 21:35:09 +03:00
+++ 1.106/sql/sql_select.h	2006-02-27 18:58:32 +03:00
@@ -176,7 +176,9 @@
 
 class JOIN :public Sql_alloc
 {
- public:
+  JOIN(const JOIN &rhs);                        /* not implemented */
+  JOIN& operator=(const JOIN &rhs);             /* not implemented */
+public:
   JOIN_TAB *join_tab,**best_ref;
   JOIN_TAB **map2table;    // mapping between table indexes and JOIN_TABs
   JOIN_TAB *join_tab_save; // saved join_tab for subquery reexecution
@@ -286,13 +288,6 @@
     :fields_list(fields_arg)
   {
     init(thd_arg, fields_arg, select_options_arg, result_arg);
-  }
-
-  JOIN(JOIN &join)
-    :Sql_alloc(), fields_list(join.fields_list)
-  {
-    init(join.thd, join.fields_list, join.select_options,
-         join.result);
   }
 
   void init(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg,

--- 1.312/sql/sql_show.cc	2006-02-26 00:22:06 +03:00
+++ 1.313/sql/sql_show.cc	2006-02-27 18:58:33 +03:00
@@ -513,12 +513,15 @@
   {
     if (!table_list->view || thd->net.last_errno != ER_VIEW_INVALID)
       DBUG_RETURN(TRUE);
+
     /*
       Clear all messages with 'error' level status and
       issue a warning with 'warning' level status in 
       case of invalid view and last error is ER_VIEW_INVALID
     */
     mysql_reset_errors(thd, true);
+    thd->clear_error();
+
     push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN,
                         ER_VIEW_INVALID,
                         ER(ER_VIEW_INVALID),

--- 1.310/sql/sql_table.cc	2006-02-26 00:22:06 +03:00
+++ 1.311/sql/sql_table.cc	2006-02-27 18:58:33 +03:00
@@ -1127,6 +1127,12 @@
   {
     CHARSET_INFO *save_cs;
 
+    /*
+      Initialize length from its original value (number of characters),
+      which was set in the parser. This is necessary if we're
+      executing a prepared statement for the second time.
+    */
+    sql_field->length= sql_field->char_length;
     if (!sql_field->charset)
       sql_field->charset= create_info->default_table_charset;
     /*
@@ -1311,7 +1317,7 @@
 	  sql_field->charset=		(dup_field->charset ?
 					 dup_field->charset :
 					 create_info->default_table_charset);
-	  sql_field->length=		dup_field->chars_length;
+	  sql_field->length=		dup_field->char_length;
           sql_field->pack_length=	dup_field->pack_length;
           sql_field->key_length=	dup_field->key_length;
 	  sql_field->create_length_to_internal_length();
@@ -4031,6 +4037,13 @@
 	close_cached_table(thd, table);
 	if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias))
 	  error= -1;
+        else if (Table_triggers_list::change_table_name(thd, db, table_name,
+                                                        new_db, new_alias))
+        {
+          VOID(mysql_rename_table(old_db_type, new_db, new_alias, db,
+                                  table_name));
+          error= -1;
+        }
       }
       VOID(pthread_mutex_unlock(&LOCK_open));
     }
@@ -4933,7 +4946,11 @@
     VOID(quick_rm_table(new_db_type,new_db,tmp_name));
   }
   else if (mysql_rename_table(new_db_type,new_db,tmp_name,new_db,
-			      new_alias))
+			      new_alias) ||
+           (new_name != table_name || new_db != db) && // we also do rename
+           Table_triggers_list::change_table_name(thd, db, table_name,
+                                                  new_db, new_alias))
+       
   {						// Try to get everything back
     error=1;
     VOID(quick_rm_table(new_db_type,new_db,new_alias));

--- 1.466/sql/sql_yacc.yy	2006-02-24 14:00:29 +03:00
+++ 1.467/sql/sql_yacc.yy	2006-02-27 19:20:58 +03:00
@@ -10931,7 +10931,7 @@
 
 trigger_tail:
 	TRIGGER_SYM remember_name sp_name trg_action_time trg_event
-	ON table_ident FOR_SYM EACH_SYM ROW_SYM
+	ON remember_name table_ident remember_end FOR_SYM EACH_SYM ROW_SYM
 	{
 	  LEX *lex= Lex;
 	  sp_head *sp;
@@ -10948,6 +10948,8 @@
 	  sp->init(lex);
 
 	  lex->trigger_definition_begin= $2;
+          lex->ident.str= $7;
+          lex->ident.length= $9 - $7;
 
 	  sp->m_type= TYPE_ENUM_TRIGGER;
 	  lex->sphead= sp;
@@ -10975,7 +10977,7 @@
 	  sp->init_strings(YYTHD, lex, $3);
 	  /* Restore flag if it was cleared above */
 
-	  YYTHD->client_capabilities |= $<ulong_num>11;
+	  YYTHD->client_capabilities |= $<ulong_num>13;
 	  sp->restore_thd_mem_root(YYTHD);
 
 	  if (sp->is_not_allowed_in_function("trigger"))
@@ -10985,15 +10987,11 @@
 	    We have to do it after parsing trigger body, because some of
 	    sp_proc_stmt alternatives are not saving/restoring LEX, so
 	    lex->query_tables can be wiped out.
-
-	    QQ: What are other consequences of this?
-
-	    QQ: Could we loosen lock type in certain cases ?
 	  */
-	  if (!lex->select_lex.add_table_to_list(YYTHD, $7,
+	  if (!lex->select_lex.add_table_to_list(YYTHD, $8,
 	                                         (LEX_STRING*) 0,
 	                                         TL_OPTION_UPDATING,
-	                                         TL_WRITE))
+                                                 TL_IGNORE))
 	    YYABORT;
 	}
 	;

--- 1.149/mysql-test/r/view.result	2006-02-25 21:35:06 +03:00
+++ 1.150/mysql-test/r/view.result	2006-02-27 18:58:31 +03:00
@@ -2529,3 +2529,13 @@
 Warning	1052	Column 'x' in group statement is ambiguous
 DROP VIEW v1;
 DROP TABLE t1;
+drop table if exists t1; 
+drop view if exists v1; 
+create table t1 (id int); 
+create view v1 as select * from t1; 
+drop table t1; 
+show create view v1; 
+drop view v1;
+//
+View	Create View
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_no_cache `test`.`t1`.`id` AS `id` from `t1`

--- 1.137/mysql-test/t/view.test	2006-02-25 22:54:29 +03:00
+++ 1.138/mysql-test/t/view.test	2006-02-27 18:58:31 +03:00
@@ -2375,3 +2375,18 @@
 
 DROP VIEW v1;
 DROP TABLE t1;
+
+#
+# BUG#15943: mysql_next_result hangs on invalid SHOW CREATE VIEW
+#
+
+delimiter //;
+drop table if exists t1; 
+drop view if exists v1; 
+create table t1 (id int); 
+create view v1 as select * from t1; 
+drop table t1; 
+show create view v1; 
+drop view v1;
+//
+delimiter ;//

--- 1.30/mysql-test/r/trigger.result	2006-02-08 13:11:36 +03:00
+++ 1.31/mysql-test/r/trigger.result	2006-02-27 18:58:31 +03:00
@@ -1,4 +1,4 @@
-drop table if exists t1, t2, t3;
+drop table if exists t1, t2, t3, t4;
 drop view if exists v1;
 drop database if exists mysqltest;
 drop function if exists f1;
@@ -785,6 +785,107 @@
 ERROR 3D000: No database selected
 drop trigger t1_bi;
 ERROR 3D000: No database selected
+create table t1 (id int);
+create trigger t1_bi before insert on t1 for each row set @a:=new.id;
+insert into t1 values (101);
+select @a;
+@a
+101
+select trigger_schema, trigger_name, event_object_schema,
+event_object_table, action_statement from information_schema.triggers
+where event_object_schema = 'test';
+trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
+test	t1_bi	test	t1	set @a:=new.id
+rename table t1 to t2;
+insert into t2 values (102);
+select @a;
+@a
+102
+select trigger_schema, trigger_name, event_object_schema,
+event_object_table, action_statement from information_schema.triggers
+where event_object_schema = 'test';
+trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
+test	t1_bi	test	t2	set @a:=new.id
+alter table t2 rename to t3;
+insert into t3 values (103);
+select @a;
+@a
+103
+select trigger_schema, trigger_name, event_object_schema,
+event_object_table, action_statement from information_schema.triggers
+where event_object_schema = 'test';
+trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
+test	t1_bi	test	t3	set @a:=new.id
+alter table t3 rename to t4, add column val int default 0;
+insert into t4 values (104, 1);
+select @a;
+@a
+104
+select trigger_schema, trigger_name, event_object_schema,
+event_object_table, action_statement from information_schema.triggers
+where event_object_schema = 'test';
+trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
+test	t1_bi	test	t4	set @a:=new.id
+drop trigger t1_bi;
+drop table t4;
+create database mysqltest;
+use mysqltest;
+create table t1 (id int);
+create trigger t1_bi before insert on t1 for each row set @a:=new.id;
+insert into t1 values (101);
+select @a;
+@a
+101
+select trigger_schema, trigger_name, event_object_schema,
+event_object_table, action_statement from information_schema.triggers
+where event_object_schema = 'test' or event_object_schema = 'mysqltest';
+trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
+mysqltest	t1_bi	mysqltest	t1	set @a:=new.id
+rename table t1 to test.t2;
+ERROR HY000: Trigger in wrong schema
+insert into t1 values (102);
+select @a;
+@a
+102
+select trigger_schema, trigger_name, event_object_schema,
+event_object_table, action_statement from information_schema.triggers
+where event_object_schema = 'test' or event_object_schema = 'mysqltest';
+trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
+mysqltest	t1_bi	mysqltest	t1	set @a:=new.id
+drop trigger test.t1_bi;
+ERROR HY000: Trigger does not exist
+drop trigger t1_bi;
+drop table t1;
+drop database mysqltest;
+use test;
+create table t1 (id int);
+create trigger t1_bi before insert on t1 for each row set @a:=new.id;
+create trigger t1_ai after insert on t1 for each row set @b:=new.id;
+insert into t1 values (101);
+select @a, @b;
+@a	@b
+101	101
+select trigger_schema, trigger_name, event_object_schema,
+event_object_table, action_statement from information_schema.triggers
+where event_object_schema = 'test';
+trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
+test	t1_bi	test	t1	set @a:=new.id
+test	t1_ai	test	t1	set @b:=new.id
+rename table t1 to t2;
+ERROR HY000: Can't create/write to file './test/t1_ai.TRN~' (Errcode: 13)
+insert into t1 values (102);
+select @a, @b;
+@a	@b
+102	102
+select trigger_schema, trigger_name, event_object_schema,
+event_object_table, action_statement from information_schema.triggers
+where event_object_schema = 'test';
+trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
+test	t1_bi	test	t1	set @a:=new.id
+test	t1_ai	test	t1	set @b:=new.id
+drop trigger t1_bi;
+drop trigger t1_ai;
+drop table t1;
 create table t1 (i int);
 create trigger t1_bi before insert on t1 for each row return 0;
 ERROR 42000: RETURN is only allowed in a FUNCTION

--- 1.35/mysql-test/t/trigger.test	2006-02-08 13:11:36 +03:00
+++ 1.36/mysql-test/t/trigger.test	2006-02-27 18:58:31 +03:00
@@ -3,7 +3,7 @@
 #
 
 --disable_warnings
-drop table if exists t1, t2, t3;
+drop table if exists t1, t2, t3, t4;
 drop view if exists v1;
 drop database if exists mysqltest;
 drop function if exists f1;
@@ -958,6 +958,91 @@
 --error ER_NO_DB_ERROR
 drop trigger t1_bi;
 connection default;
+
+#
+# Test for bug #13525 "Rename table does not keep info of triggers"
+#
+create table t1 (id int);
+create trigger t1_bi before insert on t1 for each row set @a:=new.id;
+insert into t1 values (101);
+select @a;
+select trigger_schema, trigger_name, event_object_schema,
+       event_object_table, action_statement from information_schema.triggers
+       where event_object_schema = 'test';
+rename table t1 to t2;
+# Trigger should work after rename
+insert into t2 values (102);
+select @a;
+select trigger_schema, trigger_name, event_object_schema,
+       event_object_table, action_statement from information_schema.triggers
+       where event_object_schema = 'test';
+# Let us check that the same works for simple ALTER TABLE ... RENAME
+alter table t2 rename to t3;
+insert into t3 values (103);
+select @a;
+select trigger_schema, trigger_name, event_object_schema,
+       event_object_table, action_statement from information_schema.triggers
+       where event_object_schema = 'test';
+# And for more complex ALTER TABLE
+alter table t3 rename to t4, add column val int default 0;
+insert into t4 values (104, 1);
+select @a;
+select trigger_schema, trigger_name, event_object_schema,
+       event_object_table, action_statement from information_schema.triggers
+       where event_object_schema = 'test';
+# .TRN file should be updated with new table name
+drop trigger t1_bi;
+drop table t4;
+# Rename between different databases if triggers exist should fail
+create database mysqltest;
+use mysqltest;
+create table t1 (id int);
+create trigger t1_bi before insert on t1 for each row set @a:=new.id;
+insert into t1 values (101);
+select @a;
+select trigger_schema, trigger_name, event_object_schema,
+       event_object_table, action_statement from information_schema.triggers
+       where event_object_schema = 'test' or event_object_schema = 'mysqltest';
+--error ER_TRG_IN_WRONG_SCHEMA
+rename table t1 to test.t2;
+insert into t1 values (102);
+select @a;
+select trigger_schema, trigger_name, event_object_schema,
+       event_object_table, action_statement from information_schema.triggers
+       where event_object_schema = 'test' or event_object_schema = 'mysqltest';
+# There should be no fantom .TRN files 
+--error ER_TRG_DOES_NOT_EXIST
+drop trigger test.t1_bi;
+drop trigger t1_bi;
+drop table t1;
+drop database mysqltest;
+use test;
+# And now let us check that the properly handle rename if there is some
+# error during it (that we rollback such renames completely).
+create table t1 (id int);
+create trigger t1_bi before insert on t1 for each row set @a:=new.id;
+create trigger t1_ai after insert on t1 for each row set @b:=new.id;
+insert into t1 values (101);
+select @a, @b;
+select trigger_schema, trigger_name, event_object_schema,
+       event_object_table, action_statement from information_schema.triggers
+       where event_object_schema = 'test';
+# Trick which makes update of second .TRN file impossible
+system echo dummy >var/master-data/test/t1_ai.TRN~;
+system chmod 000 var/master-data/test/t1_ai.TRN~;
+--error 1
+rename table t1 to t2;
+# 't1' should be still there and triggers should work correctly
+insert into t1 values (102);
+select @a, @b;
+select trigger_schema, trigger_name, event_object_schema,
+       event_object_table, action_statement from information_schema.triggers
+       where event_object_schema = 'test';
+system chmod 600 var/master-data/test/t1_ai.TRN;
+# Let us check that updates to .TRN files were rolled back too
+drop trigger t1_bi;
+drop trigger t1_ai;
+drop table t1;
 
 # Test for bug #16829 "Firing trigger with RETURN crashes the server"
 # RETURN is not supposed to be used anywhere except functions, so error

--- 1.47/sql/sql_trigger.cc	2006-02-13 14:59:57 +03:00
+++ 1.48/sql/sql_trigger.cc	2006-02-27 19:20:58 +03:00
@@ -65,7 +65,6 @@
 */
 
 static const int TRG_NUM_REQUIRED_PARAMETERS= 4;
-static const int TRG_MAX_VERSIONS= 3;
 
 /*
   Structure representing contents of .TRN file which are used to support
@@ -318,8 +317,7 @@
 {
   LEX *lex= thd->lex;
   TABLE *table= tables->table;
-  char file_buff[FN_REFLEN], trigname_buff[FN_REFLEN],
-       trigname_path[FN_REFLEN];
+  char file_buff[FN_REFLEN], trigname_buff[FN_REFLEN];
   LEX_STRING file, trigname_file;
   LEX_STRING *trg_def, *name;
   ulonglong *trg_sql_mode;
@@ -472,12 +470,11 @@
                                definer_host->str, NullS) - trg_definer->str;
 
   if (!sql_create_definition_file(NULL, &file, &triggers_file_type,
-                                  (gptr)this, triggers_file_parameters,
-                                  TRG_MAX_VERSIONS))
+                                  (gptr)this, triggers_file_parameters, 0))
     return 0;
 
 err_with_cleanup:
-  my_delete(trigname_path, MYF(MY_WME));
+  my_delete(trigname_buff, MYF(MY_WME));
   return 1;
 }
 
@@ -497,7 +494,8 @@
     True  - error
 */
 
-static bool rm_trigger_file(char *path, char *db, char *table_name)
+static bool rm_trigger_file(char *path, const char *db,
+                            const char *table_name)
 {
   build_table_filename(path, FN_REFLEN-1, db, table_name, triggers_file_ext);
   return my_delete(path, MYF(MY_WME));
@@ -519,7 +517,8 @@
     True  - error
 */
 
-static bool rm_trigname_file(char *path, char *db, char *trigger_name)
+static bool rm_trigname_file(char *path, const char *db,
+                             const char *trigger_name)
 {
   build_table_filename(path, FN_REFLEN-1, db, trigger_name, trigname_file_ext);
   return my_delete(path, MYF(MY_WME));
@@ -527,6 +526,35 @@
 
 
 /*
+  Helper function that saves .TRG file for Table_triggers_list object.
+
+  SYNOPSIS
+    save_trigger_file()
+      triggers    Table_triggers_list object for which file should be saved
+      db          Name of database for subject table
+      table_name  Name of subject table
+
+  RETURN VALUE
+    FALSE  Success
+    TRUE   Error
+*/
+
+static bool save_trigger_file(Table_triggers_list *triggers, const char *db,
+                              const char *table_name)
+{
+  char file_buff[FN_REFLEN];
+  LEX_STRING file;
+
+  file.length= build_table_filename(file_buff, FN_REFLEN-1, db, table_name,
+                                    triggers_file_ext);
+  file.str= file_buff;
+  return sql_create_definition_file(NULL, &file, &triggers_file_type,
+                                    (gptr)triggers, triggers_file_parameters,
+                                    0);
+}
+
+
+/*
   Drop trigger for table.
 
   SYNOPSIS
@@ -579,16 +607,7 @@
       }
       else
       {
-        char file_buff[FN_REFLEN];
-        LEX_STRING file;
-
-        file.length= build_table_filename(file_buff, FN_REFLEN-1,
-                                          tables->db, tables->table_name,
-                                          triggers_file_ext);
-        file.str= file_buff;
-        if (sql_create_definition_file(NULL, &file, &triggers_file_type,
-                                       (gptr)this, triggers_file_parameters,
-                                       TRG_MAX_VERSIONS))
+        if (save_trigger_file(this, tables->db, tables->table_name))
           return 1;
       }
 
@@ -827,12 +846,12 @@
       if (!names_only && triggers->prepare_record1_accessors(table))
         DBUG_RETURN(1);
 
-      char *trg_name_buff;
       List_iterator_fast<ulonglong> itm(triggers->definition_modes_list);
       List_iterator_fast<LEX_STRING> it_definer(triggers->definers_list);
       LEX *old_lex= thd->lex, lex;
       sp_rcontext *save_spcont= thd->spcont;
       ulong save_sql_mode= thd->variables.sql_mode;
+      LEX_STRING *on_table_name;
 
       thd->lex= &lex;
 
@@ -898,6 +917,21 @@
                                            &table->mem_root))
             goto err_with_lex_cleanup;
 
+        if (!(on_table_name= (LEX_STRING*) alloc_root(&table->mem_root,
+                                                      sizeof(LEX_STRING))))
+          goto err_with_lex_cleanup;
+        *on_table_name= lex.ident;
+        if (triggers->on_table_names_list.push_back(on_table_name, &table->mem_root))
+          goto err_with_lex_cleanup;
+
+        /*
+          Let us check that we correctly update trigger definitions when we
+          rename tables with triggers.
+        */
+        DBUG_ASSERT(!my_strcasecmp(table_alias_charset, lex.query_tables->db, db) &&
+                    !my_strcasecmp(table_alias_charset, lex.query_tables->table_name,
+                                   table_name));
+
         if (names_only)
         {
           lex_end(&lex);
@@ -1063,7 +1097,7 @@
   lex->query_tables= 0;
   lex->query_tables_last= &lex->query_tables;
   DBUG_RETURN(sp_add_to_query_tables(thd, lex, trig->m_db.str,
-                                     trigname.trigger_table.str, TL_WRITE));
+                                     trigname.trigger_table.str, TL_IGNORE));
 }
 
 
@@ -1132,6 +1166,218 @@
   DBUG_RETURN(result);
 }
 
+
+/*
+  Update .TRG file after renaming triggers' subject table
+  (change name of table in triggers' definitions).
+
+  SYNOPSIS
+    change_table_name_in_triggers()
+      thd                 Thread context
+      db_name             Database of subject table
+      old_table_name      Old subject table's name
+      new_table_name      New subject table's name
+
+  RETURN VALUE
+    FALSE  Success
+    TRUE   Failure
+*/
+
+bool
+Table_triggers_list::change_table_name_in_triggers(THD *thd,
+                                                   const char *db_name,
+                                                   LEX_STRING *old_table_name,
+                                                   LEX_STRING *new_table_name)
+{
+  char path_buff[FN_REFLEN];
+  LEX_STRING *def, *on_table_name, new_def;
+  ulonglong *sql_mode;
+  ulong save_sql_mode= thd->variables.sql_mode;
+  List_iterator_fast<LEX_STRING> it_def(definitions_list);
+  List_iterator_fast<LEX_STRING> it_on_table_name(on_table_names_list);
+  List_iterator_fast<ulonglong> it_mode(definition_modes_list);
+  uint on_q_table_name_len, before_on_len;
+  String buff;
+
+  DBUG_ASSERT(definitions_list.elements == on_table_names_list.elements &&
+              definitions_list.elements == definition_modes_list.elements);
+
+  while ((def= it_def++))
+  {
+    on_table_name= it_on_table_name++;
+    thd->variables.sql_mode= *(it_mode++);
+
+    /* Construct CREATE TRIGGER statement with new table name. */
+    buff.length(0);
+    before_on_len= on_table_name->str - def->str;
+    buff.append(def->str, before_on_len);
+    buff.append(STRING_WITH_LEN("ON "));
+    append_identifier(thd, &buff, new_table_name->str, new_table_name->length);
+    on_q_table_name_len= buff.length() - before_on_len;
+    buff.append(on_table_name->str + on_table_name->length,
+                def->length - (before_on_len + on_table_name->length));
+    /*
+      It is OK to allocate some memory on table's MEM_ROOT since this
+      table instance will be thrown out at the end of rename anyway.
+    */
+    new_def.str= memdup_root(&table->mem_root, buff.ptr(), buff.length());
+    new_def.length= buff.length();
+    on_table_name->str= new_def.str + before_on_len;
+    on_table_name->length= on_q_table_name_len;
+    *def= new_def;
+  }
+
+  thd->variables.sql_mode= save_sql_mode;
+
+  if (thd->is_fatal_error)
+    return TRUE; /* OOM */
+
+  if (save_trigger_file(this, db_name, new_table_name->str))
+    return TRUE;
+  if (rm_trigger_file(path_buff, db_name, old_table_name->str))
+  {
+    (void) rm_trigger_file(path_buff, db_name, new_table_name->str);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+/*
+  Iterate though Table_triggers_list::names_list list and update .TRN files
+  after renaming triggers' subject table.
+
+  SYNOPSIS
+    change_table_name_in_trignames()
+      db_name             Database of subject table
+      new_table_name      New subject table's name
+      stopper             Pointer to Table_triggers_list::names_list at
+                          which we should stop updating.
+
+  RETURN VALUE
+    0      Success
+    non-0  Failure, pointer to Table_triggers_list::names_list element
+           for which update failed.
+*/
+
+LEX_STRING*
+Table_triggers_list::change_table_name_in_trignames(const char *db_name,
+                                                    LEX_STRING *new_table_name,
+                                                    LEX_STRING *stopper)
+{
+  char trigname_buff[FN_REFLEN];
+  struct st_trigname trigname;
+  LEX_STRING trigname_file;
+  LEX_STRING *trigger;
+  List_iterator_fast<LEX_STRING> it_name(names_list);
+
+  while ((trigger= it_name++) != stopper)
+  {
+    trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1,
+                                               db_name, trigger->str,
+                                               trigname_file_ext);
+    trigname_file.str= trigname_buff;
+
+    trigname.trigger_table= *new_table_name;
+
+    if (sql_create_definition_file(NULL, &trigname_file, &trigname_file_type,
+                                   (gptr)&trigname, trigname_file_parameters,
+                                   0))
+      return trigger;
+  }
+
+  return 0;
+}
+
+
+/*
+  Update .TRG and .TRN files after renaming triggers' subject table.
+
+  SYNOPSIS
+    change_table_name()
+      thd        Thread context
+      db         Old database of subject table
+      old_table  Old name of subject table
+      new_db     New database for subject table
+      new_table  New name of subject table
+
+  NOTE
+    This method tries to leave trigger related files in consistent state,
+    i.e. it either will complete successfully, or will fail leaving files
+    in their initial state.
+
+  RETURN VALUE
+    FALSE  Success
+    TRUE   Error
+*/
+
+bool Table_triggers_list::change_table_name(THD *thd, const char *db,
+                                            const char *old_table,
+                                            const char *new_db,
+                                            const char *new_table)
+{
+  TABLE table;
+  bool result= 0;
+  LEX_STRING *err_trigname;
+  DBUG_ENTER("change_table_name");
+
+  bzero(&table, sizeof(table));
+  init_alloc_root(&table.mem_root, 8192, 0);
+
+  safe_mutex_assert_owner(&LOCK_open);
+
+  if (Table_triggers_list::check_n_load(thd, db, old_table, &table, TRUE))
+  {
+    result= 1;
+    goto end;
+  }
+  if (table.triggers)
+  {
+    LEX_STRING_WITH_INIT old_table_name(old_table, strlen(old_table));
+    LEX_STRING_WITH_INIT new_table_name(new_table, strlen(new_table));
+    /*
+      Since triggers should be in the same schema as their subject tables
+      moving table with them between two schemas raises too many questions.
+      (E.g. what should happen if in new schema we already have trigger
+       with same name ?).
+    */
+    if (my_strcasecmp(table_alias_charset, db, new_db))
+    {
+      my_error(ER_TRG_IN_WRONG_SCHEMA, MYF(0));
+      result= 1;
+      goto end;
+    }
+    if (table.triggers->change_table_name_in_triggers(thd, db,
+                                                      &old_table_name,
+                                                      &new_table_name))
+    {
+      result= 1;
+      goto end;
+    }
+    if ((err_trigname= table.triggers->change_table_name_in_trignames(
+                                         db, &new_table_name, 0)))
+    {
+      /*
+        If we were unable to update one of .TRN files properly we will
+        revert all changes that we have done and report about error.
+        We assume that we will be able to undo our changes without errors
+        (we can't do much if there will be an error anyway).
+      */
+      (void) table.triggers->change_table_name_in_trignames(db,
+                                                            &old_table_name,
+                                                            err_trigname);
+      (void) table.triggers->change_table_name_in_triggers(thd, db,
+                                                           &new_table_name,
+                                                           &old_table_name);
+      result= 1;
+      goto end;
+    }
+  }
+end:
+  delete table.triggers;
+  free_root(&table.mem_root, MYF(0));
+  DBUG_RETURN(result);
+}
 
 
 bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event,

--- 1.74/mysql-test/mysql-test-run.pl	2006-02-23 12:49:35 +03:00
+++ 1.75/mysql-test/mysql-test-run.pl	2006-02-27 18:58:31 +03:00
@@ -1156,6 +1156,7 @@
   $ENV{'USE_RUNNING_SERVER'}= $glob_use_running_server;
   $ENV{'MYSQL_TEST_DIR'}=     $glob_mysql_test_dir;
   $ENV{'MYSQLTEST_VARDIR'}=   $opt_vardir;
+  $ENV{'MYSQL_TMP_DIR'}=      $opt_tmpdir;
   $ENV{'MASTER_MYSOCK'}=      $master->[0]->{'path_mysock'};
   $ENV{'MASTER_MYSOCK1'}=     $master->[1]->{'path_mysock'};
   $ENV{'MASTER_MYPORT'}=      $master->[0]->{'path_myport'};
@@ -2876,7 +2877,7 @@
   if ( $opt_debug )
   {
     $cmdline_mysqlcheck .=
-      " --debug=d:t:A,$opt_vardir_trace/log/mysqldump.trace";
+      " --debug=d:t:A,$opt_vardir_trace/log/mysqlcheck.trace";
   }
 
   my $cmdline_mysqldump= "$exe_mysqldump --no-defaults -uroot " .

--- 1.48/mysql-test/r/merge.result	2006-02-17 22:06:00 +03:00
+++ 1.49/mysql-test/r/merge.result	2006-02-27 18:58:31 +03:00
@@ -56,8 +56,8 @@
 4	Testing
 5	table
 5	table
-6	t1
 6	t2
+6	t1
 7	Testing
 7	Testing
 8	table

--- 1.35/sql/sql_rename.cc	2006-02-13 10:48:10 +03:00
+++ 1.36/sql/sql_rename.cc	2006-02-27 19:20:58 +03:00
@@ -19,6 +19,7 @@
 */
 
 #include "mysql_priv.h"
+#include "sql_trigger.h"
 
 
 static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
@@ -173,9 +174,30 @@
         if (table_type == DB_TYPE_UNKNOWN) 
           my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
         else
-          rc= mysql_rename_table(ha_resolve_by_legacy_type(thd, table_type),
-                                 ren_table->db, old_alias,
-                                 new_table->db, new_alias);
+        {
+          if (!(rc= mysql_rename_table(ha_resolve_by_legacy_type(thd,
+                                                                 table_type),
+                                       ren_table->db, old_alias,
+                                       new_table->db, new_alias)))
+          {
+            if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db,
+                                                            old_alias,
+                                                            new_table->db,
+                                                            new_alias)))
+            {
+              /*
+                We've succeeded in renaming table's .frm and in updating
+                corresponding handler data, but have failed to update table's
+                triggers appropriately. So let us revert operations on .frm
+                and handler's data and report about failure to rename table.
+              */
+              (void) mysql_rename_table(ha_resolve_by_legacy_type(thd,
+                                                                  table_type),
+                                        new_table->db, new_alias,
+                                        ren_table->db, old_alias);
+            }
+          }
+        }
         break;
       }
       case FRMTYPE_VIEW:

--- 1.121/include/my_global.h	2006-01-05 12:54:08 +03:00
+++ 1.122/include/my_global.h	2006-02-27 18:58:31 +03:00
@@ -43,6 +43,15 @@
 #define HAVE_ERRNO_AS_DEFINE
 #endif /* __CYGWIN__ */
 
+#if defined(__QNXNTO__) && !defined(FD_SETSIZE)
+#define FD_SETSIZE 1024         /* Max number of file descriptor bits in
+                                   fd_set, used when calling 'select'
+                                   Must be defined before including
+                                   "sys/select.h" and "sys/time.h"
+                                 */
+#endif
+
+
 /* to make command line shorter we'll define USE_PRAGMA_INTERFACE here */
 #ifdef USE_PRAGMA_IMPLEMENTATION
 #define USE_PRAGMA_INTERFACE

--- 1.188/client/mysqltest.c	2006-02-23 22:55:54 +03:00
+++ 1.189/client/mysqltest.c	2006-02-27 18:58:31 +03:00
@@ -3662,8 +3662,10 @@
 static void init_win_path_patterns()
 {
   /* List of string patterns to match in order to find paths */
-  const char* paths[] = { "$MYSQL_TEST_DIR", "./test/", 0 };
-  int num_paths= 2;
+  const char* paths[] = { "$MYSQL_TEST_DIR",
+                          "$MYSQL_TMP_DIR",
+                          "./test/", 0 };
+  int num_paths= 3;
   int i;
   char* p;
 

--- 1.61/mysql-test/r/ps.result	2006-02-02 11:59:18 +03:00
+++ 1.62/mysql-test/r/ps.result	2006-02-27 18:58:31 +03:00
@@ -859,6 +859,20 @@
 5
 deallocate prepare stmt;
 drop table t1;
+prepare stmt from 'create table t1 (a varchar(10) character set utf8)';
+execute stmt;
+insert into t1 (a) values (repeat('a', 20));
+select length(a) from t1;
+length(a)
+10
+drop table t1;
+execute stmt;
+insert into t1 (a) values (repeat('a', 20));
+select length(a) from t1;
+length(a)
+10
+drop table t1;
+deallocate prepare stmt;
 create table t1 (id int);
 prepare ins_call from "insert into t1 (id) values (1)";
 execute ins_call;

--- 1.59/mysql-test/t/ps.test	2006-02-02 11:59:18 +03:00
+++ 1.60/mysql-test/t/ps.test	2006-02-27 18:58:31 +03:00
@@ -900,6 +900,27 @@
 deallocate prepare stmt;
 drop table t1;
 
+#
+# Bug#13134 "Length of VARCHAR() utf8 column is increasing when table is
+# recreated with PS/SP"
+#
+
+prepare stmt from 'create table t1 (a varchar(10) character set utf8)';
+execute stmt;
+--disable_warnings
+insert into t1 (a) values (repeat('a', 20));
+--enable_warnings
+select length(a) from t1;
+drop table t1;
+execute stmt;
+--disable_warnings
+insert into t1 (a) values (repeat('a', 20));
+--enable_warnings
+# Check that the data is truncated to the same length
+select length(a) from t1;
+drop table t1;
+deallocate prepare stmt;
+
 # End of 4.1 tests
 
 #
Thread
bk commit into 5.1 tree (dlenev:1.2185)dlenev27 Feb