List:Internals« Previous MessageNext Message »
From:sanja Date:July 22 2005 2:35pm
Subject:bk commit into 5.0 tree (bell:1.1883) BUG#5891
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of bell. When bell 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.1883 05/07/22 15:34:54 bell@stripped +6 -0
  store/restore sql_mode which was in force during ctrigger creation (BUG#5891)

  sql/sql_trigger.h
    1.11 05/07/22 15:34:49 bell@stripped +1 -0
    store/restore sql_mode which was in force during ctrigger creation

  sql/sql_trigger.cc
    1.23 05/07/22 15:34:49 bell@stripped +68 -12
    store/restore sql_mode which was in force during ctrigger creation

  sql/parse_file.h
    1.8 05/07/22 15:34:49 bell@stripped +3 -1
    new type of list (ulonglong)

  sql/parse_file.cc
    1.14 05/07/22 15:34:49 bell@stripped +64 -4
    new type of list (ulonglong)

  mysql-test/t/trigger.test
    1.19 05/07/22 15:34:49 bell@stripped +14 -0
    storing and restoring parsing modes for triggers

  mysql-test/r/trigger.result
    1.14 05/07/22 15:34:49 bell@stripped +15 -0
    storing and restoring parsing modes for triggers

# 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:	bell
# Host:	sanja.is.com.ua
# Root:	/home/bell/mysql/bk/work-trigger-5.0

--- 1.13/sql/parse_file.cc	2005-07-18 15:31:59 +03:00
+++ 1.14/sql/parse_file.cc	2005-07-22 15:34:49 +03:00
@@ -166,6 +166,25 @@
     }
     break;
   }
+  case FILE_OPTIONS_ULLLIST:
+  {
+    List_iterator_fast<ulonglong> it(*((List<ulonglong>*)
+                                       (base + parameter->offset)));
+    bool first= 1;
+    ulonglong *val;
+    while ((val= it++))
+    {
+      num.set(*val, &my_charset_bin);
+      // We need ' ' after string to detect list continuation
+      if ((!first && my_b_append(file, (const byte *)" ", 1)) ||
+          my_b_append(file, (const byte *)num.ptr(), num.length()))
+      {
+        DBUG_RETURN(TRUE);
+      }
+      first= 0;
+    }
+    break;
+  }
   default:
     DBUG_ASSERT(0); // never should happened
   }
@@ -615,6 +634,8 @@
   char *eol;
   LEX_STRING *str;
   List<LEX_STRING> *list;
+  ulonglong *num;
+  List<ulonglong> *nlist;
   DBUG_ENTER("File_parser::parse");
 
   while (ptr < end && found < required)
@@ -719,7 +740,7 @@
 	case FILE_OPTIONS_STRLIST:
 	{
           list= (List<LEX_STRING>*)(base + parameter->offset);
-	    
+
 	  list->empty();
 	  // list parsing
 	  while (ptr < end)
@@ -741,17 +762,56 @@
 	      goto list_err_w_message;
 	    }
 	  }
-      end_of_list:
+
+end_of_list:
 	  if (*(ptr++) != '\n')
 	    goto list_err;
 	  break;
 
-      list_err_w_message:
+list_err_w_message:
 	  my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0),
                    parameter->name.str, line);
-      list_err:
+list_err:
 	  DBUG_RETURN(TRUE);
 	}
+        case FILE_OPTIONS_ULLLIST:
+        {
+          nlist= (List<ulonglong>*)(base + parameter->offset);
+          nlist->empty();
+	  // list parsing
+	  while (ptr < end)
+          {
+            int not_used;
+            char *num_end= end;
+            if (!(num= (ulonglong*)alloc_root(mem_root, sizeof(ulonglong))) ||
+		nlist->push_back(num, mem_root))
+	      goto nlist_err;
+	    *num= my_strtoll10(ptr, &num_end, &not_used);
+            ptr= num_end;
+            switch (*ptr) {
+	    case '\n':
+	      goto end_of_nlist;
+	    case ' ':
+	      // we cant go over buffer bounds, because we have \0 at the end
+	      ptr++;
+	      break;
+	    default:
+	      goto nlist_err_w_message;
+	    }
+          }
+
+end_of_nlist:
+	  if (*(ptr++) != '\n')
+	    goto list_err;
+	  break;
+
+nlist_err_w_message:
+	  my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0),
+                   parameter->name.str, line);
+nlist_err:
+	  DBUG_RETURN(TRUE);
+
+        }
 	default:
 	  DBUG_ASSERT(0); // never should happened
 	}

--- 1.7/sql/parse_file.h	2004-10-07 01:44:11 +03:00
+++ 1.8/sql/parse_file.h	2005-07-22 15:34:49 +03:00
@@ -27,8 +27,10 @@
   FILE_OPTIONS_REV,		/* Revision version number (ulonglong) */
   FILE_OPTIONS_TIMESTAMP,	/* timestamp (LEX_STRING have to be
 				   allocated with length 20 (19+1) */
-  FILE_OPTIONS_STRLIST          /* list of escaped strings
+  FILE_OPTIONS_STRLIST,         /* list of escaped strings
                                    (List<LEX_STRING>) */
+  FILE_OPTIONS_ULLLIST          /* list of ulonglong values
+                                   (List<ulonglong>) */
 };
 
 struct File_option

--- 1.13/mysql-test/r/trigger.result	2005-07-19 19:06:42 +03:00
+++ 1.14/mysql-test/r/trigger.result	2005-07-22 15:34:49 +03:00
@@ -595,3 +595,18 @@
 ERROR 42000: FUNCTION test.bug5893 does not exist
 drop trigger t1_bu;
 drop table t1;
+set sql_mode='ansi';
+create table t1 ("t1 column" int);
+create trigger t1_bi before insert on t1 for each row set new."t1 column" = 5;
+set sql_mode=default;
+insert into t1 values (0);
+create trigger t1_af after insert on t1 for each row set @a=10;
+insert into t1 values (0);
+select * from t1;
+t1 column
+5
+5
+select @a;
+@a
+10
+drop table t1;

--- 1.18/mysql-test/t/trigger.test	2005-07-19 20:38:06 +03:00
+++ 1.19/mysql-test/t/trigger.test	2005-07-22 15:34:49 +03:00
@@ -610,3 +610,17 @@
 # This should not crash server too.
 drop trigger t1_bu;
 drop table t1;
+
+#
+# storing and restoring parsing modes for triggers (BUG#5891)
+#
+set sql_mode='ansi';
+create table t1 ("t1 column" int);
+create trigger t1_bi before insert on t1 for each row set new."t1 column" = 5;
+set sql_mode=default;
+insert into t1 values (0);
+create trigger t1_af after insert on t1 for each row set @a=10;
+insert into t1 values (0);
+select * from t1;
+select @a;
+drop table t1;

--- 1.22/sql/sql_trigger.cc	2005-07-19 19:06:43 +03:00
+++ 1.23/sql/sql_trigger.cc	2005-07-22 15:34:49 +03:00
@@ -32,8 +32,12 @@
 */
 static File_option triggers_file_parameters[]=
 {
-  {{(char*)"triggers", 8}, offsetof(class Table_triggers_list, definitions_list),
-   FILE_OPTIONS_STRLIST},
+  {{(char*)"triggers", 8},
+    offsetof(class Table_triggers_list, definitions_list),
+    FILE_OPTIONS_STRLIST},
+  {{(char*)"parsing_modes", 13},
+    offsetof(class Table_triggers_list, definition_modes_list),
+    FILE_OPTIONS_ULLLIST},
   {{0, 0}, 0, FILE_OPTIONS_STRING}
 };
 
@@ -127,12 +131,12 @@
     DBUG_RETURN(TRUE);
 
   /*
-    We do not allow creation of triggers on views or temporary tables.
+    We do not allow creation of triggers on temporary tables.
     We have to do this check here and not in
     Table_triggers_list::create_trigger() because we want to avoid messing
-    with table cash for views and temporary tables.
+    with table cash for temporary tables.
   */
-  if (tables->view || table->s->tmp_table != NO_TMP_TABLE)
+  if (table->s->tmp_table != NO_TMP_TABLE)
   {
     my_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, MYF(0), tables->alias);
     DBUG_RETURN(TRUE);
@@ -221,6 +225,7 @@
        trigname_path[FN_REFLEN];
   LEX_STRING dir, file, trigname_file;
   LEX_STRING *trg_def, *name;
+  ulonglong *trg_parsing_mode;
   Item_trigger_field *trg_field;
   struct st_trigname trigname;
 
@@ -307,11 +312,15 @@
   */
   if (!(trg_def= (LEX_STRING *)alloc_root(&table->mem_root,
                                           sizeof(LEX_STRING))) ||
-      definitions_list.push_back(trg_def, &table->mem_root))
+      definitions_list.push_back(trg_def, &table->mem_root) ||
+      !(trg_parsing_mode= (ulonglong*)alloc_root(&table->mem_root,
+                                                 sizeof(ulonglong))) ||
+      definition_modes_list.push_back(trg_parsing_mode, &table->mem_root))
     goto err_with_cleanup;
 
   trg_def->str= thd->query;
   trg_def->length= thd->query_length;
+  *trg_parsing_mode= thd->variables.sql_mode;
 
   if (!sql_create_definition_file(&dir, &file, &triggers_file_type,
                                   (gptr)this, triggers_file_parameters, 3))
@@ -390,11 +399,13 @@
   LEX_STRING *name;
   List_iterator_fast<LEX_STRING> it_name(names_list);
   List_iterator<LEX_STRING>      it_def(definitions_list);
+  List_iterator<ulonglong>       it_mod(definition_modes_list);
   char path[FN_REFLEN];
 
   while ((name= it_name++))
   {
     it_def++;
+    it_mod++;
 
     if (my_strcasecmp(system_charset_info, lex->spname->m_name.str,
                       name->str) == 0)
@@ -404,6 +415,7 @@
         clean trigger removing since table will be reopened anyway.
       */
       it_def.remove();
+      it_mod.remove();
 
       if (definitions_list.is_empty())
       {
@@ -549,10 +561,48 @@
       if (!triggers)
         DBUG_RETURN(1);
 
+      /*
+        old versions of .TRG file we do not have nores, so we should
+        initialize list for safety
+      */
+      triggers->definition_modes_list.empty();
+
       if (parser->parse((gptr)triggers, &table->mem_root,
-                        triggers_file_parameters, 1))
+                        triggers_file_parameters, 2))
         DBUG_RETURN(1);
 
+      List_iterator_fast<LEX_STRING> it(triggers->definitions_list);
+      LEX_STRING *trg_create_str, *trg_name_str;
+      ulonglong *trg_parsing_mode;
+
+      if (triggers->definition_modes_list.is_empty() &&
+          !triggers->definitions_list.is_empty())
+      {
+        /*
+          It is old file format => we should fill list of sql_modes.
+
+          We use one mode (current) for all triggers, because we have not
+          information about mode in old format.
+        */
+        if (!(trg_parsing_mode= (ulonglong*)alloc_root(&table->mem_root,
+                                                       sizeof(ulonglong))))
+        {
+          DBUG_RETURN(1); // EOM
+        }
+        *trg_parsing_mode= thd->variables.sql_mode;
+        while ((trg_create_str= it++))
+        {
+          if (triggers->definition_modes_list.push_back(trg_parsing_mode,
+                                                        &table->mem_root))
+          {
+            DBUG_RETURN(1); // EOM
+          }
+        }
+        it.rewind();
+      }
+
+      DBUG_ASSERT(triggers->definition_modes_list.elements ==
+                  triggers->definitions_list.elements);
       table->triggers= triggers;
 
       /*
@@ -574,15 +624,17 @@
       if (!names_only && triggers->prepare_record1_accessors(table))
         DBUG_RETURN(1);
 
-      List_iterator_fast<LEX_STRING> it(triggers->definitions_list);
-      LEX_STRING *trg_create_str, *trg_name_str;
       char *trg_name_buff;
+      List_iterator_fast<ulonglong> itm(triggers->definition_modes_list);
       LEX *old_lex= thd->lex, lex;
+      ulong save_sql_mode= thd->variables.sql_mode;
 
       thd->lex= &lex;
 
       while ((trg_create_str= it++))
       {
+        trg_parsing_mode= itm++;
+        thd->variables.sql_mode= (ulong)*trg_parsing_mode;
         lex_start(thd, (uchar*)trg_create_str->str, trg_create_str->length);
 
         if (yyparse((void *)thd) || thd->is_fatal_error)
@@ -597,7 +649,8 @@
 
         triggers->bodies[lex.trg_chistics.event]
                              [lex.trg_chistics.action_time]= lex.sphead;
-        if (triggers->names_list.push_back(&lex.sphead->m_name,
&table->mem_root))
+        if (triggers->names_list.push_back(&lex.sphead->m_name,
+                                           &table->mem_root))
             goto err_with_lex_cleanup;
 
         if (names_only)
@@ -611,8 +664,9 @@
           in old/new versions of row in trigger to Field objects in table being
           opened.
 
-          We ignore errors here, because if even something is wrong we still will
-          be willing to open table to perform some operations (e.g. SELECT)...
+          We ignore errors here, because if even something is wrong we still
+          will be willing to open table to perform some operations (e.g.
+          SELECT)...
           Anyway some things can be checked only during trigger execution.
         */
         for (Item_trigger_field *trg_field=
@@ -624,6 +678,7 @@
         lex_end(&lex);
       }
       thd->lex= old_lex;
+      thd->variables.sql_mode= save_sql_mode;
 
       DBUG_RETURN(0);
 
@@ -631,6 +686,7 @@
       // QQ: anything else ?
       lex_end(&lex);
       thd->lex= old_lex;
+      thd->variables.sql_mode= save_sql_mode;
       DBUG_RETURN(1);
     }
 

--- 1.10/sql/sql_trigger.h	2005-07-19 19:06:43 +03:00
+++ 1.11/sql/sql_trigger.h	2005-07-22 15:34:49 +03:00
@@ -60,6 +60,7 @@
     It have to be public because we are using it directly from parser.
   */
   List<LEX_STRING>  definitions_list;
+  List<ulonglong> definition_modes_list;
 
   Table_triggers_list(TABLE *table_arg):
     record1_field(0), table(table_arg)
Thread
bk commit into 5.0 tree (bell:1.1883) BUG#5891sanja22 Jul