List:Commits« Previous MessageNext Message »
From:dlenev Date:April 19 2006 11:15pm
Subject:bk commit into 5.0 tree (dlenev:1.2166) BUG#11081
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 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.2166 06/04/20 01:15:08 dlenev@stripped +4 -0
  Fix for bug#11081 "Using a CONVERT_TZ function in a stored function or
  trigger fails".
  
  In cases when CONVERT_TZ() function was used in trigger or stored function
  (or in stored procedure which was called from trigger or stored function)
  error about non existing '.' table was reported.
  
  Statements that use CONVERT_TZ() function should have time zone related
  tables in their table list. tz_init_table_list() function which is used
  to produce part of table list containing those tables didn't set
  TABLE_LIST::db_length/table_name_length members properly. As result time
  zone tables needed for CONVERT_TZ() function were incorrectly handled by
  prelocking algorithm and "Table '.' doesn't exist' error was emitted.
  This fix changes tz_init_table_list() in such way that it properly inits
  TABLE_LIST::table_name_length/db_length members and thus produces table list
  which can be handled by prelocking algorithm correctly.

  sql/tztime.h
    1.14 06/04/20 01:15:03 dlenev@stripped +11 -2
    Added MY_TZ_TABLES_COUNT constant to be used as number of time zone related
    tables which are needed for dynamical loading of time zone descriptions.

  sql/tztime.cc
    1.31 06/04/20 01:15:03 dlenev@stripped +42 -21
    Now tz_init_table_list() inits table_name_length and db_length members in
    TABLE_LIST objects, so table lists produced with its help can be handled 
    by prelocking algorithm properly.
    
    Also now we use MY_TZ_TABLES_COUNT instead of magical number 4 in places 
    where it is appropriate.

  mysql-test/t/timezone2.test
    1.10 06/04/20 01:15:03 dlenev@stripped +20 -0
    Added test for bug #11081 "Using a CONVERT_TZ function in a stored function
    or trigger fails".

  mysql-test/r/timezone2.result
    1.13 06/04/20 01:15:03 dlenev@stripped +15 -0
    Added test for bug #11081 "Using a CONVERT_TZ function in a stored function
    or trigger fails".

# 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:	jabberwock.site
# Root:	/home/dlenev/mysql-5.0-bg11081

--- 1.12/mysql-test/r/timezone2.result	2005-07-19 03:12:40 +04:00
+++ 1.13/mysql-test/r/timezone2.result	2006-04-20 01:15:03 +04:00
@@ -1,4 +1,5 @@
 drop table if exists t1, t2;
+drop function if exists f1;
 create table t1 (ts timestamp);
 set time_zone='+00:00';
 select unix_timestamp(utc_timestamp())-unix_timestamp(current_timestamp());
@@ -268,3 +269,17 @@
 convert_tz(NULL, NULL, NULL)
 NULL
 drop table t1;
+create table t1 (ldt datetime, udt datetime);
+create function f1(i datetime) returns datetime
+return convert_tz(i, 'UTC', 'Europe/Moscow');
+create trigger t1_bi before insert on t1 for each row
+set new.udt:= convert_tz(new.ldt, 'Europe/Moscow', 'UTC');
+insert into t1 (ldt) values ('2006-04-19 16:30:00');
+select * from t1;
+ldt	udt
+2006-04-19 16:30:00	2006-04-19 12:30:00
+select ldt, f1(udt) as ldt2 from t1;
+ldt	ldt2
+2006-04-19 16:30:00	2006-04-19 16:30:00
+drop table t1;
+drop function f1;

--- 1.9/mysql-test/t/timezone2.test	2005-07-28 17:12:37 +04:00
+++ 1.10/mysql-test/t/timezone2.test	2006-04-20 01:15:03 +04:00
@@ -3,6 +3,7 @@
 # Preparing playground
 --disable_warnings
 drop table if exists t1, t2;
+drop function if exists f1;
 --enable_warnings
 
 
@@ -222,3 +223,22 @@
 drop table t1;
 
 # End of 4.1 tests
+
+#
+# Test for bug #11081 "Using a CONVERT_TZ function in a stored function
+# or trigger fails".
+#
+create table t1 (ldt datetime, udt datetime);
+create function f1(i datetime) returns datetime
+  return convert_tz(i, 'UTC', 'Europe/Moscow');
+create trigger t1_bi before insert on t1 for each row
+  set new.udt:= convert_tz(new.ldt, 'Europe/Moscow', 'UTC');
+# This should work without errors
+insert into t1 (ldt) values ('2006-04-19 16:30:00');
+select * from t1;
+# This should work without errors as well
+select ldt, f1(udt) as ldt2 from t1;
+drop table t1;
+drop function f1;
+
+# End of 5.0 tests

--- 1.30/sql/tztime.cc	2006-02-25 18:46:27 +03:00
+++ 1.31/sql/tztime.cc	2006-04-20 01:15:03 +04:00
@@ -1370,6 +1370,24 @@
 static bool time_zone_tables_exist= 1;
 
 
+/*
+  Names of tables (with their lengths) that are needed
+  for dynamical loading of time zone descriptions.
+*/
+
+static const LEX_STRING tz_tables_names[MY_TZ_TABLES_COUNT]=
+{
+  {(char *) STRING_WITH_LEN("time_zone_name")},
+  {(char *) STRING_WITH_LEN("time_zone")},
+  {(char *) STRING_WITH_LEN("time_zone_transition_type")},
+  {(char *) STRING_WITH_LEN("time_zone_transition")}
+};
+
+/* Name of database to which those tables belong. */
+
+static const LEX_STRING tz_tables_db_name= {(char *) STRING_WITH_LEN("mysql")};
+
+
 typedef struct st_tz_names_entry: public Sql_alloc
 {
   String name;
@@ -1403,7 +1421,8 @@
 
   SYNOPSIS
     tz_init_table_list()
-      tz_tabs         - pointer to preallocated array of 4 TABLE_LIST objects
+      tz_tabs         - pointer to preallocated array of MY_TZ_TABLES_COUNT
+                        TABLE_LIST objects
       global_next_ptr - pointer to variable which points to global_next member
                         of last element of global table list (or list root
                         then list is empty) (in/out).
@@ -1418,27 +1437,27 @@
 static void
 tz_init_table_list(TABLE_LIST *tz_tabs, TABLE_LIST ***global_next_ptr)
 {
-  bzero(tz_tabs, sizeof(TABLE_LIST) * 4);
-  tz_tabs[0].alias= tz_tabs[0].table_name= (char*)"time_zone_name";
-  tz_tabs[1].alias= tz_tabs[1].table_name= (char*)"time_zone";
-  tz_tabs[2].alias= tz_tabs[2].table_name= (char*)"time_zone_transition_type";
-  tz_tabs[3].alias= tz_tabs[3].table_name= (char*)"time_zone_transition";
-  tz_tabs[0].next_global= tz_tabs[0].next_local= tz_tabs+1;
-  tz_tabs[1].next_global= tz_tabs[1].next_local= tz_tabs+2;
-  tz_tabs[2].next_global= tz_tabs[2].next_local= tz_tabs+3;
-  tz_tabs[0].lock_type= tz_tabs[1].lock_type= tz_tabs[2].lock_type=
-    tz_tabs[3].lock_type= TL_READ;
-  tz_tabs[0].db= tz_tabs[1].db= tz_tabs[2].db= tz_tabs[3].db= (char *)"mysql";
+  bzero(tz_tabs, sizeof(TABLE_LIST) * MY_TZ_TABLES_COUNT);
+
+  for (int i= 0; i < MY_TZ_TABLES_COUNT; i++)
+  {
+    tz_tabs[i].alias= tz_tabs[i].table_name= tz_tables_names[i].str;
+    tz_tabs[i].table_name_length= tz_tables_names[i].length;
+    tz_tabs[i].db= tz_tables_db_name.str;
+    tz_tabs[i].db_length= tz_tables_db_name.length;
+    tz_tabs[i].lock_type= TL_READ;
+
+    if (i != MY_TZ_TABLES_COUNT - 1)
+      tz_tabs[i].next_global= tz_tabs[i].next_local= &tz_tabs[i+1];
+    if (i != 0)
+      tz_tabs[i].prev_global= &tz_tabs[i-1].next_global;
+  }
 
   /* Link into global list */
   tz_tabs[0].prev_global= *global_next_ptr;
-  tz_tabs[1].prev_global= &tz_tabs[0].next_global;
-  tz_tabs[2].prev_global= &tz_tabs[1].next_global;
-  tz_tabs[3].prev_global= &tz_tabs[2].next_global;
-
   **global_next_ptr= tz_tabs;
   /* Update last-global-pointer to point to pointer in last table */
-  *global_next_ptr= &tz_tabs[3].next_global;
+  *global_next_ptr= &tz_tabs[MY_TZ_TABLES_COUNT-1].next_global;
 }
 
 
@@ -1467,7 +1486,8 @@
 
   NOTE
     my_tz_check_n_skip_implicit_tables() function depends on fact that
-    elements of list created are allocated as TABLE_LIST[4] array.
+    elements of list created are allocated as TABLE_LIST[MY_TZ_TABLES_COUNT]
+    array.
 
   RETURN VALUES
     Returns pointer to first TABLE_LIST object, (could be 0 if time zone
@@ -1483,7 +1503,8 @@
   if (!time_zone_tables_exist)
     DBUG_RETURN(0);
 
-  if (!(tz_tabs= (TABLE_LIST *)thd->alloc(sizeof(TABLE_LIST) * 4)))
+  if (!(tz_tabs= (TABLE_LIST *)thd->alloc(sizeof(TABLE_LIST) *
+                                          MY_TZ_TABLES_COUNT)))
     DBUG_RETURN(&fake_time_zone_tables_list);
 
   tz_init_table_list(tz_tabs, global_next_ptr);
@@ -1522,7 +1543,7 @@
 {
   THD *thd;
   TABLE_LIST *tables= 0;
-  TABLE_LIST tables_buff[5], **last_global_next_ptr;
+  TABLE_LIST tables_buff[1+MY_TZ_TABLES_COUNT], **last_global_next_ptr;
   TABLE *table;
   TZ_NAMES_ENTRY *tmp_tzname;
   my_bool return_val= 1;
@@ -2262,7 +2283,7 @@
       our time zone tables. Note that if we don't have tz tables on this
       slave, we don't even try.
     */
-    TABLE_LIST tables[4];
+    TABLE_LIST tables[MY_TZ_TABLES_COUNT];
     TABLE_LIST *dummy;
     TABLE_LIST **dummyp= &dummy;
     tz_init_table_list(tables, &dummyp);

--- 1.13/sql/tztime.h	2006-02-25 18:46:27 +03:00
+++ 1.14/sql/tztime.h	2006-04-20 01:15:03 +04:00
@@ -69,6 +69,15 @@
 extern TABLE_LIST fake_time_zone_tables_list;
 
 /*
+  Number of elements in table list produced by my_tz_get_table_list()
+  (this table list contains tables which are needed for dynamical loading
+  of time zone descriptions). Actually it is imlementation detail that
+  should not be used anywhere outside of tztime.h and tztime.cc.
+*/
+
+static const int MY_TZ_TABLES_COUNT= 4;
+
+/*
   Check if we have pointer to the begining of list of implicitly used time
   zone tables, set SELECT_ACL for them and fast-forward to its end.
 
@@ -90,9 +99,9 @@
 {
   if (*table == tz_tables)
   {
-    for (int i= 0; i < 4; i++)
+    for (int i= 0; i < MY_TZ_TABLES_COUNT; i++)
       (*table)[i].grant.privilege= SELECT_ACL;
-    (*table)+= 3;
+    (*table)+= MY_TZ_TABLES_COUNT - 1;
     return TRUE;
   }
   return FALSE;
Thread
bk commit into 5.0 tree (dlenev:1.2166) BUG#11081dlenev19 Apr