MySQL Lists are EOL. Please join:

List:Internals« Previous MessageNext Message »
From:Marc Alff Date:July 2 2006 10:49pm
Subject:Contribution for Bug#11230 (comments in functions / SP / triggers)
View as plain text  
Hi All

Please find attached a contribution,
as a proposed implementation for the following bugs:
- Bug#11230 (Keeping comments when storing stored procedures)
- Bug#14369 (Views & Stored Procedures are stored without text formatting)
- Bug#14487 (Comments are being ripped out of SP's during restore)
- Bug#15344 (Comments on views and triggers)

Note that the fix for #14369 and #15244 is partial,
as treatment for views is unchanged.

Functionality changed by this patch :
- new options, "--enable-comments" / "--disable-comments" are
available in the mysql client.
- by default, comments are disabled: the mysql client behaves
as before: it filters comments out before sending queries to the server.

When "mysql --enable-comments" is used :
- "#" comments,
- "--<space>" comments,
- "/* ... */" multi-line comments,
- empty lines,
- comments after a delimiter and on the same line,
that are present in the SQL script processed by the mysql client
are sent with the query to the server.

As a result, comments and the original formatting present in the code of :
- functions
- stored procedures
- triggers
are preserved with the code, and can be displayed using :
- show create function
- show create procedure
- show create trigger (see below)

Dependencies :
- The patch itself is up to date with the latest code publicly available
(bk://mysql.bkbits.net/mysql-5.1 as of 2006-07-02).
- See the proposed trigger patch http://lists.mysql.com/internals/33687
- the production code (mysql.cc) is *NOT* dependent on the trigger change,
- the tests however, do depend on the trigger patch (for show create
trigger).

You are encouraged to apply the 'trigger' patch first, but it's not
strictly mandatory (the tests will have to be simplified to ignore
triggers).

Tests cases are provided, see :
- $/mysql-test/t/comments-51.sh (start here)
- $/mysql-test/t/comments-51.sql
- $/mysql-test/r/comments-51-enable.result
- $/mysql-test/r/comments-51-disable.result

It should be noted that :
- since, technically, the change is located in mysql, the tests are not
using the mysqltest framework, which would not test the modified code.
- since the mysqltest language processes comments differently from mysql,
using a mysqltest script to test the server behavior can not be done
without changes to the test framework itself, and was avoided.

As a result, the tests provided are manual.
They are provided to show what testing was done,
and to help evaluating the patch during the review,
but are not integrated into the makefiles or into mysqltest.

The code was built and tested on a Gentoo Linux AMD64 host.

As with any changes, this one needs review ...

Comments (pun intended) are welcome :)

Regards,
Marc Alff.



diff -Naur mysql-5.1-BK/client/mysql.cc mysql-5.1-comment/client/mysql.cc
--- mysql-5.1-BK/client/mysql.cc	2006-06-26 03:55:58.000000000 +0000
+++ mysql-5.1-comment/client/mysql.cc	2006-07-02 18:44:13.000000000 +0000
@@ -137,6 +137,7 @@
 	       default_charset_used= 0, opt_secure_auth= 0,
                default_pager_set= 0, opt_sigint_ignore= 0,
                show_warnings= 0, executing_query= 0, interrupted_query= 0;
+static my_bool preserve_comments= 0;
 static ulong opt_max_allowed_packet, opt_net_buffer_length;
 static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0;
 static my_string opt_mysql_unix_port=0;
@@ -746,6 +747,10 @@
   {"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.",
     (gptr*) &show_warnings, (gptr*) &show_warnings, 0, GET_BOOL, NO_ARG, 
     0, 0, 0, 0, 0, 0},
+  {"comments", 'c', "Preserve comments. Send comments to the server."
+    " Comments are discarded by default, enable with --enable-comments",
+    (gptr*) &preserve_comments, (gptr*) &preserve_comments,
+    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };
 
@@ -1083,17 +1088,12 @@
       status.exit_status=0;
       break;
     }
-    if (!in_string && (line[0] == '#' ||
-		       (line[0] == '-' && line[1] == '-') ||
-		       line[0] == 0))
-      continue;					// Skip comment lines
-
     /*
       Check if line is a mysql command line
       (We want to allow help, print and clear anywhere at line start
     */
     if ((named_cmds || glob_buffer.is_empty())
-	&& !in_string && (com=find_command(line,0)))
+	&& !ml_comment && !in_string && (com=find_command(line,0)))
     {
       if ((*com->func)(&glob_buffer,line) > 0)
 	break;
@@ -1211,15 +1211,22 @@
 
   for (pos=out=line ; (inchar= (uchar) *pos) ; pos++)
   {
-    if (my_isspace(charset_info,inchar) && out == line && 
-        buffer.is_empty())
-      continue;
+    if (! preserve_comments)
+    {
+      // Skip spaces at the beggining of a statement
+      if (my_isspace(charset_info,inchar)
+          && (out == line)
+          && buffer.is_empty())
+        continue;
+    }
+
 #ifdef USE_MB
+    // Accept multi-byte characters as-is
     int length;
     if (use_mb(charset_info) &&
         (length= my_ismbchar(charset_info, pos, end_of_line)))
     {
-      if (!*ml_comment)
+      if (!*ml_comment || preserve_comments)
       {
         while (length--)
           *out++ = *pos++;
@@ -1230,9 +1237,10 @@
       continue;
     }
 #endif
+
     if (!*ml_comment && inchar == '\\')
     {
-      // Found possbile one character command like \c
+      // Found possible one character command like \c
 
       if (!(inchar = (uchar) *++pos))
 	break;				// readline adds one '\'
@@ -1244,8 +1252,13 @@
       }
       if ((com=find_command(NullS,(char) inchar)))
       {
-	const String tmp(line,(uint) (out-line), charset_info);
-	buffer.append(tmp);
+        // Flush previously accepted characters
+        if (out != line)
+        {
+          buffer.append(line, (uint) (out-line));
+          out = line;
+        }
+
 	if ((*com->func)(&buffer,pos-1) > 0)
 	  DBUG_RETURN(1);                       // Quit
 	if (com->takes_params)
@@ -1259,7 +1272,6 @@
 	  else 
 	    pos+= delimiter_length - 1; // Point at last delim char
 	}
-	out=line;
       }
       else
       {
@@ -1271,27 +1283,77 @@
 	continue;
       }
     }
-    else if (!*ml_comment && !*in_string &&
-             (*pos == *delimiter && is_prefix(pos + 1, delimiter + 1) ||
-              buffer.length() == 0 && (out - line) >= 9 &&
-              !my_strcasecmp(charset_info, line, "delimiter")))
-    {					
-      uint old_delimiter_length= delimiter_length;
+    else if (   !*ml_comment
+             && !*in_string
+             && is_prefix(pos, "delimiter")
+             && my_isspace(charset_info, pos[9]))
+    {
+      // Flush previously accepted characters
       if (out != line)
-	buffer.append(line, (uint) (out - line));	// Add this line
-      if ((com= find_command(buffer.c_ptr(), 0)))
       {
-        if (com->func == com_delimiter)
+        buffer.append(line, (uint) (out-line));
+        out = line;
+      }
+
+      // Flush possible comments in the buffer
+      if ( ! buffer.is_empty())
+      {
+        if (com_go(&buffer, 0) > 0)             // < 0 is not fatal
+          DBUG_RETURN(1);
+        buffer.length(0);
+      }
+
+      /*
+        Delimiter wants the get rest of the given line as argument to
+        allow one to change ';' to ';;' and back
+      */
+      buffer.append(pos);
+      if (com_delimiter(& buffer, pos) > 0)
+        DBUG_RETURN(1);                       // Quit
+
+      buffer.length(0);
+      break;
+    }
+    else if (   !*ml_comment
+             && !*in_string
+             && is_prefix(pos, delimiter))
+    {
+      // Found a statement. Continue parsing after the delimiter
+      pos+= delimiter_length ;
+
+      if (preserve_comments)
+      {
+        while (my_isspace(charset_info, *pos))
         {
-          /*
-            Delimiter wants the get rest of the given line as argument to
-            allow one to change ';' to ';;' and back
-          */
-          char *end= strend(pos);
-          buffer.append(pos, (uint) (end - pos));
-          /* Ensure pos will point at \0 after the pos+= below */
-          pos= end - old_delimiter_length + 1;
+          *out ++ = *pos ++;
         }
+      }
+
+      // Flush previously accepted characters
+      if (out != line)
+      {
+        buffer.append(line, (uint) (out-line));
+        out = line;
+      }
+
+      if (  preserve_comments
+          && (  (*pos == '#')
+             || (   (*pos == '-')
+                 && (pos[1] == '-')
+                 && my_isspace(charset_info, pos[2])
+                )
+             )
+         )
+      {
+        // Add trailing single line comments to this statement
+        buffer.append(pos);
+        pos+= strlen(pos);
+      }
+
+      pos--;
+
+      if ((com= find_command(buffer.c_ptr(), 0)))
+      {
 	if ((*com->func)(&buffer, buffer.c_ptr()) > 0)
 	  DBUG_RETURN(1);                       // Quit
       }
@@ -1301,17 +1363,42 @@
 	  DBUG_RETURN(1);
       }
       buffer.length(0);
-      out= line;
-      pos+= old_delimiter_length - 1;
     }
-    else if (!*ml_comment && (!*in_string && (inchar == '#' ||
-			      inchar == '-' && pos[1] == '-' &&
-			      my_isspace(charset_info,pos[2]))))
-      break;					// comment to end of line
+    else if (   !*ml_comment
+             && !*in_string
+             && (   (inchar == '#')
+                 || (   (inchar == '-')
+                     && (pos[1] == '-')
+                     && my_isspace(charset_info,pos[2]))
+                )
+            )
+    {
+      // Flush previously accepted characters
+      if (out != line)
+      {
+        buffer.append(line, (uint) (out-line));
+        out = line;
+      }
+
+      // comment to end of line
+      if (preserve_comments)
+      {
+        buffer.append(pos);
+      }
+      break;
+    }
     else if (!*in_string && inchar == '/' && *(pos+1) == '*' &&
 	     *(pos+2) != '!')
     {
-      pos++;
+      if (preserve_comments)
+      {
+        *out++ = *pos++ ;                       // copy '/'
+        *out++ = *pos ;                         // copy '*'
+      }
+      else
+      {
+        pos++;
+      }
       *ml_comment= 1;
       if (out != line)
       {
@@ -1321,10 +1408,25 @@
     }
     else if (*ml_comment && inchar == '*' && *(pos + 1) == '/')
     {
-      pos++;
+      if (preserve_comments)
+      {
+        *out++ = *pos++ ;                       // copy '*'
+        *out++ = *pos ;                         // copy '/'
+      }
+      else
+      {
+        pos++;
+      }
       *ml_comment= 0;
+      if (out != line)
+      {
+        buffer.append(line,(uint) (out-line));
+        out=line;
+      }
+      // Consumed a 2 chars or more, and will add 1 at most,
+      // so using the 'line' buffer to edit data in place is ok.
       need_space= 1;
-    }      
+    }
     else
     {						// Add found char to buffer
       if (inchar == *in_string)
@@ -1332,14 +1434,14 @@
       else if (!*ml_comment && !*in_string &&
 	       (inchar == '\'' || inchar == '"' || inchar == '`'))
 	*in_string= (char) inchar;
-      if (!*ml_comment)
+      if (!*ml_comment || preserve_comments)
       {
         if (need_space && !my_isspace(charset_info, (char)inchar))
         {
           *out++= ' ';
-          need_space= 0;
         }
-	*out++= (char) inchar;
+        need_space= 0;
+        *out++= (char) inchar;
       }
     }
   }
@@ -1349,7 +1451,7 @@
     uint length=(uint) (out-line);
     if (buffer.length() + length >= buffer.alloced_length())
       buffer.realloc(buffer.length()+length+IO_SIZE);
-    if (!(*ml_comment) && buffer.append(line,length))
+    if ((!*ml_comment || preserve_comments) && buffer.append(line,length))
       DBUG_RETURN(1);
   }
   DBUG_RETURN(0);
diff -Naur mysql-5.1-BK/mysql-test/r/comments-51-disable.result
mysql-5.1-comment/mysql-test/r/comments-51-disable.result
--- mysql-5.1-BK/mysql-test/r/comments-51-disable.result	1970-01-01 00:00:00.000000000
+0000
+++ mysql-5.1-comment/mysql-test/r/comments-51-disable.result	2006-07-02
18:44:11.000000000 +0000
@@ -0,0 +1,26 @@
+1
+1
+2
+2
+foofct("call 1")
+call 1
+Function	sql_mode	Create Function
+foofct		CREATE DEFINER=`tcov`@`localhost` FUNCTION `foofct`(x char(20)) RETURNS
char(20)\nreturn\n\n\n\nx
+foofct("call 2")
+call 2
+Function	sql_mode	Create Function
+foofct		CREATE DEFINER=`tcov`@`localhost` FUNCTION `foofct`(x char(20)) RETURNS
char(20)\nbegin\n  \n  \n  \n\n  \n\n  \n  return x;\nend
+Procedure	sql_mode	Create Procedure
+empty		CREATE DEFINER=`tcov`@`localhost` PROCEDURE `empty`()\nbegin\nend
+id	data
+foo	42
+Procedure	sql_mode	Create Procedure
+foosp		CREATE DEFINER=`tcov`@`localhost` PROCEDURE `foosp`()\ninsert into
test.t1\n\n\n\n\n  \n\n  \n  values ("foo", 42)
+Procedure	sql_mode	Create Procedure
+nicesp		CREATE DEFINER=`tcov`@`localhost` PROCEDURE `nicesp`(a int)\nbegin\n  \n  declare
b int;\n  declare c float;\n\n  \n  \n\n  \nend
+Db	Name	Create Trigger
+test	t1_empty	CREATE DEFINER = 'tcov'@'localhost' TRIGGER `test`.`t1_empty` AFTER DELETE
ON `test`.`t1` FOR EACH ROW begin\nend
+Db	Name	Create Trigger
+test	t1_bi	CREATE DEFINER = 'tcov'@'localhost' TRIGGER `test`.`t1_bi` BEFORE INSERT ON
`test`.`t1` FOR EACH ROW begin\n\n\n\n  \n  declare b int;\n  declare c float;\n\n  \n 
\n\n  \n  set NEW.data := 12;\nend
+id	data
+trig	12
diff -Naur mysql-5.1-BK/mysql-test/r/comments-51-enable.result
mysql-5.1-comment/mysql-test/r/comments-51-enable.result
--- mysql-5.1-BK/mysql-test/r/comments-51-enable.result	1970-01-01 00:00:00.000000000
+0000
+++ mysql-5.1-comment/mysql-test/r/comments-51-enable.result	2006-07-02 18:44:12.000000000
+0000
@@ -0,0 +1,26 @@
+1
+1
+2
+2
+foofct("call 1")
+call 1
+Function	sql_mode	Create Function
+foofct		CREATE DEFINER=`tcov`@`localhost` FUNCTION `foofct`(x char(20)) RETURNS
char(20)\nreturn\n-- comment 1a\n# comment 1b\n/* comment 1c */\nx # after body, on same
line
+foofct("call 2")
+call 2
+Function	sql_mode	Create Function
+foofct		CREATE DEFINER=`tcov`@`localhost` FUNCTION `foofct`(x char(20)) RETURNS
char(20)\nbegin\n  -- comment 1a\n  # comment 1b\n  /*\n     comment 1c\n  */\n\n  --
empty line below\n\n  -- empty line above\n  return x;\nend
+Procedure	sql_mode	Create Procedure
+empty		CREATE DEFINER=`tcov`@`localhost` PROCEDURE `empty`()\nbegin\nend
+id	data
+foo	42
+Procedure	sql_mode	Create Procedure
+foosp		CREATE DEFINER=`tcov`@`localhost` PROCEDURE `foosp`()\ninsert into test.t1\n##
These comments are part of the procedure body, and should be kept.\n# Comment 2a\n--
Comment 2b\n/* Comment 2c */\n  -- empty line below\n\n  -- empty line above\n  values
("foo", 42) # comment 3, still part of the body
+Procedure	sql_mode	Create Procedure
+nicesp		CREATE DEFINER=`tcov`@`localhost` PROCEDURE `nicesp`(a int)\nbegin\n  -- declare
some variables here\n  declare b int;\n  declare c float;\n\n  -- do more stuff here\n  --
commented nicely and so on\n\n  -- famous last words ...\nend
+Db	Name	Create Trigger
+test	t1_empty	CREATE DEFINER = 'tcov'@'localhost' TRIGGER `test`.`t1_empty` AFTER DELETE
ON `test`.`t1` FOR EACH ROW begin\nend
+Db	Name	Create Trigger
+test	t1_bi	CREATE DEFINER = 'tcov'@'localhost' TRIGGER `test`.`t1_bi` BEFORE INSERT ON
`test`.`t1` FOR EACH ROW begin\n# comment 1a\n-- comment 1b\n/*\n   comment 1c\n*/\n  --
declare some variables here\n  declare b int;\n  declare c float;\n\n  -- do more stuff
here\n  -- commented nicely and so on\n\n  -- famous last words ...\n  set NEW.data :=
12;\nend
+id	data
+trig	12
diff -Naur mysql-5.1-BK/mysql-test/t/comments-51.sh
mysql-5.1-comment/mysql-test/t/comments-51.sh
--- mysql-5.1-BK/mysql-test/t/comments-51.sh	1970-01-01 00:00:00.000000000 +0000
+++ mysql-5.1-comment/mysql-test/t/comments-51.sh	2006-07-02 18:44:11.000000000 +0000
@@ -0,0 +1,61 @@
+#!/bin/sh
+##============================================================================
+## This file is part of MySQL.
+## Copyright (c) 2006, MySQL AB.
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor,
+## Boston, MA 02110-1301, USA.
+##============================================================================
+
+## Written by Marc Alff.
+
+##============================================================================
+## Notes
+##============================================================================
+
+# This is a manual test for Bug#11230
+# Preconditions are :
+# - the MySQL server must be up and running.
+# - the environment variable CONNECT must contain a valid user/password
+# - the script is invoked from $/mysql-test/t
+# TODO: see how this test can be integrated to the automated test suite.
+
+export MYSQL;
+MYSQL=../../client/mysql
+
+echo "Running the test with --disable-comments"
+$MYSQL $CONNECT < ./comments-51.sql > ../r/comments-51-disable.log
+
+echo "Verifying results"
+diff ../r/comments-51-disable.log ../r/comments-51-disable.result
+
+if [ $? = "0" ]; then
+  echo "TEST <disable> PASSED" ;
+else
+  echo "TEST <disable> FAILED" ;
+fi ;
+
+echo "Running the test with --enable-comments"
+$MYSQL $CONNECT --enable-comments < ./comments-51.sql > ../r/comments-51-enable.log
+
+echo "Verifying results"
+diff ../r/comments-51-enable.log ../r/comments-51-enable.result
+
+if [ $? = "0" ]; then
+  echo "TEST <enable> PASSED" ;
+else
+  echo "TEST <enable> FAILED" ;
+fi ;
+
diff -Naur mysql-5.1-BK/mysql-test/t/comments-51.sql
mysql-5.1-comment/mysql-test/t/comments-51.sql
--- mysql-5.1-BK/mysql-test/t/comments-51.sql	1970-01-01 00:00:00.000000000 +0000
+++ mysql-5.1-comment/mysql-test/t/comments-51.sql	2006-07-02 18:44:11.000000000 +0000
@@ -0,0 +1,241 @@
+##============================================================================
+## This file is part of MySQL.
+## Copyright (c) 2006, MySQL AB.
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor,
+## Boston, MA 02110-1301, USA.
+##============================================================================
+
+## Written by Marc Alff.
+
+##============================================================================
+## Notes
+##============================================================================
+
+# Test case for Bug#11230
+
+# The point of this test is to make sure that '#', '-- ' and '/* ... */'
+# comments, as well as empty lines, are sent from the client to the server.
+# This is to ensure better error reporting, and to keep comments in the code
+# for stored procedures / functions / triggers (Bug#11230).
+# As a result, be careful when editing comments in this script, they do
+# matter.
+#
+# Also, note that this is a script for **mysql**, not mysqltest.
+# This is critical, as the mysqltest client interprets comments differently.
+
+##============================================================================
+## Setup
+##============================================================================
+
+use test;
+
+# Test tables
+#
+# t1 is reused throughout the file, and dropped at the end.
+#
+drop table if exists t1;
+create table t1 (
+  id   char(16) not null default '',
+  data int not null
+);
+
+##============================================================================
+## Comments outside statements
+##============================================================================
+
+# Ignored 1a
+-- Ignored 1b
+/*
+   Ignored 1c
+*/
+
+select 1;
+
+##============================================================================
+## Comments inside statements
+##============================================================================
+
+select # comment 1a
+# comment 2a
+-- comment 2b
+/*
+   comment 2c
+*/
+2
+; # not strictly inside, but on same line
+# ignored
+
+##============================================================================
+## Comments inside functions
+##============================================================================
+
+drop function if exists foofct ;
+
+create function foofct (x char(20))
+returns char(20)
+/* not inside the body yet */
+return
+-- comment 1a
+# comment 1b
+/* comment 1c */
+x; # after body, on same line
+
+select foofct("call 1");
+
+show create function foofct;
+drop function foofct;
+
+delimiter |
+
+create function foofct(x char(20))
+returns char(20)
+begin
+  -- comment 1a
+  # comment 1b
+  /*
+     comment 1c
+  */
+
+  -- empty line below
+
+  -- empty line above
+  return x;
+end|
+
+delimiter ;
+
+select foofct("call 2");
+
+show create function foofct;
+drop function foofct;
+
+##============================================================================
+## Comments inside stored procedures
+##============================================================================
+
+# Empty statement
+drop procedure if exists empty;
+create procedure empty()
+begin
+end;
+
+call empty();
+show create procedure empty;
+drop procedure empty;
+
+drop procedure if exists foosp;
+
+## These comments are before the create, and will be lost
+# Comment 1a
+-- Comment 1b
+/*
+   Comment 1c
+ */
+create procedure foosp()
+/* Comment not quiet in the body yet */
+  insert into test.t1
+## These comments are part of the procedure body, and should be kept.
+# Comment 2a
+-- Comment 2b
+/* Comment 2c */
+  -- empty line below
+
+  -- empty line above
+  values ("foo", 42); # comment 3, still part of the body
+## After the ';', therefore not part of the body
+# comment 4a
+-- Comment 4b
+/*
+   Comment 4c
+ */
+
+call foosp();
+select * from t1;
+delete from t1;
+show create procedure foosp;
+drop procedure foosp;
+
+drop procedure if exists nicesp;
+
+delimiter |
+
+create procedure nicesp(a int)
+begin
+  -- declare some variables here
+  declare b int;
+  declare c float;
+
+  -- do more stuff here
+  -- commented nicely and so on
+
+  -- famous last words ...
+end|
+
+delimiter ;
+
+show create procedure nicesp;
+drop procedure nicesp;
+
+##============================================================================
+## Comments inside triggers
+##============================================================================
+
+drop trigger if exists t1_empty;
+
+create trigger t1_empty after delete on t1
+for each row
+begin
+end;
+
+show create trigger t1_empty;
+
+drop trigger if exists t1_bi;
+
+delimiter |
+
+create trigger t1_bi before insert on t1
+for each row
+begin
+# comment 1a
+-- comment 1b
+/*
+   comment 1c
+*/
+  -- declare some variables here
+  declare b int;
+  declare c float;
+
+  -- do more stuff here
+  -- commented nicely and so on
+
+  -- famous last words ...
+  set NEW.data := 12;
+end|
+
+delimiter ;
+
+show create trigger t1_bi;
+
+# also make sure the trigger still works
+insert into t1(id) value ("trig");
+select * from t1;
+
+##============================================================================
+## Cleanup
+##============================================================================
+
+drop table t1;
+

Thread
Contribution for Bug#11230 (comments in functions / SP / triggers)Marc Alff2 Jul