Commit 9a1fed13 authored by unknown's avatar unknown
Browse files

Implementation of WL#2897: Complete definer support in the stored routines.

The idea is to add DEFINER-clause in CREATE PROCEDURE and CREATE FUNCTION
statements. Almost all support of definer in stored routines had been already
done before this patch.

NOTE: this patch changes behaviour of dumping stored routines in mysqldump.
Before this patch, mysqldump did not dump DEFINER-clause for stored routines
and this was documented behaviour. In order to get full information about stored
routines, one should have dumped mysql.proc table. This patch changes this
behaviour, so that DEFINER-clause is dumped.

Since DEFINER-clause is not supported in CREATE PROCEDURE | FUNCTION statements
before this patch, the clause is covered by additional version-specific comments.


client/mysqldump.c:
  Updated the code for dumping stored routines: cover DEFINER-clause
  into version-specific comment.
mysql-test/r/gis.result:
  Updated result file after adding DEFINER-clause.
mysql-test/r/information_schema.result:
  Updated result file after adding DEFINER-clause.
mysql-test/r/mysqldump.result:
  Updated result file after adding DEFINER-clause.
mysql-test/r/rpl_ddl.result:
  Updated result file after adding DEFINER-clause.
mysql-test/r/rpl_sp.result:
  Updated result file after adding DEFINER-clause.
mysql-test/r/rpl_trigger.result:
  Updated result file after adding DEFINER-clause.
mysql-test/r/sp-security.result:
  Updated result file after adding DEFINER-clause.
mysql-test/r/sp.result:
  Updated result file after adding DEFINER-clause.
mysql-test/r/sql_mode.result:
  Updated result file after adding DEFINER-clause.
mysql-test/t/sp-security.test:
  Updated result file after adding DEFINER-clause.
sql/sp.cc:
  Added DEFINER-clause.
sql/sp_head.cc:
  Added a new convenient variant of set_definer() operation.
sql/sp_head.h:
  Updated result file after adding DEFINER-clause.
sql/sql_lex.h:
  Renamed trigger_definition_begin into stmt_definition_begin to be used for
  triggers and stored routines.
sql/sql_parse.cc:
  Check DEFINER-clause.
sql/sql_trigger.cc:
  Renamed trigger_definition_begin into stmt_definition_begin to be used for
  triggers and stored routines.
sql/sql_yacc.yy:
  Added DEFINER-clause.
parent fad27ebf
Loading
Loading
Loading
Loading
+47 −1
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ static char *add_load_option(char *ptr, const char *object,
			     const char *statement);
static ulong find_set(TYPELIB *lib, const char *x, uint length,
		      char **err_pos, uint *err_len);
static char *alloc_query_str(ulong size);

static char *field_escape(char *to,const char *from,uint length);
static my_bool  verbose=0,tFlag=0,dFlag=0,quick= 1, extended_insert= 1,
@@ -1304,19 +1305,64 @@ static uint dump_routines_for_db(char *db)
                             routine_name, row[2], strlen(row[2])));
          if (strlen(row[2]))
          {
            char *query_str= NULL;
            char *definer_begin;

            if (opt_drop)
              fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */;;\n",
                      routine_type[i], routine_name);

            /*
              Cover DEFINER-clause in version-specific comments.

              TODO: this is definitely a BAD IDEA to parse SHOW CREATE output.
              We should user INFORMATION_SCHEMA instead. The only problem is
              that now INFORMATION_SCHEMA does not provide information about
              routine parameters.
            */

            definer_begin= strstr(row[2], " DEFINER");
            
            if (definer_begin)
            {
              char *definer_end= strstr(definer_begin, " PROCEDURE");

              if (!definer_end)
                definer_end= strstr(definer_begin, " FUNCTION");

              if (definer_end)
              {
                char *query_str_tail;

                /*
                  Allocate memory for new query string: original string
                  from SHOW statement and version-specific comments.
                */
                query_str= alloc_query_str(strlen(row[2]) + 23);

                query_str_tail= strnmov(query_str, row[2],
                                        definer_begin - row[2]);
                query_str_tail= strmov(query_str_tail, "*/ /*!50019");
                query_str_tail= strnmov(query_str_tail, definer_begin,
                                        definer_end - definer_begin);
                query_str_tail= strxmov(query_str_tail, "*/ /*!50003",
                                        definer_end, NullS);
              }
            }

            /*
              we need to change sql_mode only for the CREATE
              PROCEDURE/FUNCTION otherwise we may need to re-quote routine_name
            */;
            fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=\"%s\"*/;;\n",
                    row[1] /* sql_mode */);
            fprintf(sql_file, "/*!50003 %s */;;\n", row[2]);
            fprintf(sql_file, "/*!50003 %s */;;\n",
                    (query_str != NULL ? query_str : row[2]));
            fprintf(sql_file,
                    "/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/"
                    ";;\n");

            my_free(query_str, MYF(MY_ALLOW_ZERO_PTR));
          }
        } /* end of routine printing */
      } /* end of list of routines */
+1 −1
Original line number Diff line number Diff line
@@ -680,7 +680,7 @@ drop procedure if exists fn3;
create function fn3 () returns point return GeomFromText("point(1 1)");
show create function fn3;
Function	sql_mode	Create Function
fn3		CREATE FUNCTION `fn3`() RETURNS point
fn3		CREATE DEFINER=`root`@`localhost` FUNCTION `fn3`() RETURNS point
return GeomFromText("point(1 1)")
select astext(fn3());
astext(fn3())
+2 −2
Original line number Diff line number Diff line
@@ -309,7 +309,7 @@ Function sql_mode Create Function
sub1		
show create function sub2;
Function	sql_mode	Create Function
sub2		CREATE FUNCTION `sub2`(i int) RETURNS int(11)
sub2		CREATE DEFINER=`mysqltest_1`@`localhost` FUNCTION `sub2`(i int) RETURNS int(11)
return i+1
show function status like "sub2";
Db	Name	Type	Definer	Modified	Created	Security_type	Comment
@@ -317,7 +317,7 @@ test sub2 FUNCTION mysqltest_1@localhost # # DEFINER
drop function sub2;
show create procedure sel2;
Procedure	sql_mode	Create Procedure
sel2		CREATE PROCEDURE `sel2`()
sel2		CREATE DEFINER=`root`@`localhost` PROCEDURE `sel2`()
begin
select * from t1;
select * from t2;
+7 −7
Original line number Diff line number Diff line
@@ -2210,12 +2210,12 @@ UNLOCK TABLES;
DELIMITER ;;
/*!50003 DROP FUNCTION IF EXISTS `bug9056_func1` */;;
/*!50003 SET SESSION SQL_MODE=""*/;;
/*!50003 CREATE FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11)
/*!50003 CREATE*/ /*!50019 DEFINER=`root`@`localhost`*/ /*!50003 FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11)
RETURN a+b */;;
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;;
/*!50003 DROP FUNCTION IF EXISTS `bug9056_func2` */;;
/*!50003 SET SESSION SQL_MODE=""*/;;
/*!50003 CREATE FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1)
/*!50003 CREATE*/ /*!50019 DEFINER=`root`@`localhost`*/ /*!50003 FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1)
begin
set f1= concat( 'hello', f1 );
return f1;
@@ -2223,17 +2223,17 @@ end */;;
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;;
/*!50003 DROP PROCEDURE IF EXISTS `a'b` */;;
/*!50003 SET SESSION SQL_MODE="REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI"*/;;
/*!50003 CREATE PROCEDURE "a'b"()
/*!50003 CREATE*/ /*!50019 DEFINER="root"@"localhost"*/ /*!50003 PROCEDURE "a'b"()
select 1 */;;
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;;
/*!50003 DROP PROCEDURE IF EXISTS `bug9056_proc1` */;;
/*!50003 SET SESSION SQL_MODE=""*/;;
/*!50003 CREATE PROCEDURE `bug9056_proc1`(IN a INT, IN b INT, OUT c INT)
/*!50003 CREATE*/ /*!50019 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `bug9056_proc1`(IN a INT, IN b INT, OUT c INT)
BEGIN SELECT a+b INTO c; end */;;
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;;
/*!50003 DROP PROCEDURE IF EXISTS `bug9056_proc2` */;;
/*!50003 SET SESSION SQL_MODE=""*/;;
/*!50003 CREATE PROCEDURE `bug9056_proc2`(OUT a INT)
/*!50003 CREATE*/ /*!50019 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `bug9056_proc2`(OUT a INT)
BEGIN 
select sum(id) from t1 into a; 
END */;;
@@ -2685,11 +2685,11 @@ return 42 */|
select 42 */|
show create function f;
Function	sql_mode	Create Function
f		CREATE FUNCTION `f`() RETURNS bigint(20)
f		CREATE DEFINER=`root`@`localhost` FUNCTION `f`() RETURNS bigint(20)
return 42
show create procedure p;
Procedure	sql_mode	Create Procedure
p		CREATE PROCEDURE `p`()
p		CREATE DEFINER=`root`@`localhost` PROCEDURE `p`()
select 42
drop function f;
drop procedure p;
+2 −2
Original line number Diff line number Diff line
@@ -1133,7 +1133,7 @@ SHOW PROCEDURE STATUS LIKE 'p1';
Db	mysqltest1
Name	p1
Type	PROCEDURE
Definer	@
Definer	root@localhost
Modified	#
Created	#
Security_type	DEFINER
@@ -1199,7 +1199,7 @@ SHOW PROCEDURE STATUS LIKE 'p1';
Db	mysqltest1
Name	p1
Type	PROCEDURE
Definer	@
Definer	root@localhost
Modified	#
Created	#
Security_type	DEFINER
Loading