Commit 3702a1db authored by unknown's avatar unknown

WL#1363: Update the mysql.proc table and add new fields.

Also made the parsing and handling of SP characteristics
more general and extendable, and added a few ch:istics.


Docs/sp-imp-spec.txt:
  Updated spec with new schema.
Docs/sp-implemented.txt:
  Added info about ALTER and SHOW.
mysql-test/r/sp.result:
  Minor change in SHOW FUNCTION|PROCEDURE STATUS output.
scripts/mysql_create_system_tables.sh:
  New mysql.proc schema.
scripts/mysql_fix_privilege_tables.sql:
  New mysql.proc schema.
sql/lex.h:
  New lex words for SP characteristics.
sql/sp.cc:
  New mysql.proc schema.
  Also made the characteristics handling slightly more extendable.
sql/sp.h:
  Made the characteristics handling slightly more extendable.
sql/sp_head.cc:
  Made the characteristics handling slightly more extendable.
sql/sp_head.h:
  Made the characteristics handling slightly more extendable.
sql/sql_lex.h:
  Made the characteristics handling slightly more extendable.
sql/sql_parse.cc:
  Made the characteristics handling slightly more extendable.
sql/sql_yacc.yy:
  Made the characteristics handling slightly more extendable
  and made the parsing of characteristics more general, and
  added a few new dito. (LANGUAGE SQL, and [NOT] DETERMINISTIC
  for starters).
parent 4c8f7bd8
...@@ -1052,4 +1052,46 @@ ...@@ -1052,4 +1052,46 @@
/* Remove an SP from cache */ /* Remove an SP from cache */
void sp_cache_remove(sp_cache **cp, sp_head *sp); void sp_cache_remove(sp_cache **cp, sp_head *sp);
- The mysql.proc schema:
CREATE TABLE proc (
schema char(64) binary DEFAULT '' NOT NULL,
name char(64) binary DEFAULT '' NOT NULL,
type enum('FUNCTION','PROCEDURE') NOT NULL,
specific_name char(64) binary DEFAULT '' NOT NULL,
language enum('SQL') DEFAULT 'SQL' NOT NULL,
sql_data_access enum('CONTAINS_SQL') DEFAULT 'CONTAINS_SQL' NOT NULL,
is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL,
definition blob DEFAULT '' NOT NULL,
security_type enum('INVOKER','DEFINER') DEFAULT 'INVOKER' NOT NULL,
definer char(77) binary DEFAULT '' NOT NULL,
created timestamp,
modified timestamp,
sql_mode set(
'REAL_AS_FLOAT',
'PIPES_AS_CONCAT',
'ANSI_QUOTES',
'IGNORE_SPACE',
'NOT_USED',
'ONLY_FULL_GROUP_BY',
'NO_UNSIGNED_SUBTRACTION',
'NO_DIR_IN_CREATE',
'POSTGRESQL',
'ORACLE',
'MSSQL',
'DB2',
'MAXDB',
'NO_KEY_OPTIONS',
'NO_TABLE_OPTIONS',
'NO_FIELD_OPTIONS',
'MYSQL323',
'MYSQL40',
'ANSI',
'NO_AUTO_VALUE_ON_ZERO'
) DEFAULT 0 NOT NULL,
comment char(64) binary DEFAULT '' NOT NULL,
PRIMARY KEY (schema,name,type)
) comment='Stored Procedures';
-- --
Stored Procedures implemented 2003-09-16: Stored Procedures implemented 2003-12-10:
Summary of Not Yet Implemented: Summary of Not Yet Implemented:
- SQL queries (like SELECT, INSERT, UPDATE etc) in FUNCTION bodies - SQL statements using table (like SELECT, INSERT, UPDATE etc)
in FUNCTIONs
- External languages - External languages
- Access control - Access control
- Routine characteristics (mostly used for external languages) - Routine characteristics (mostly used for external languages)
...@@ -25,18 +26,28 @@ Summary of what's implemented: ...@@ -25,18 +26,28 @@ Summary of what's implemented:
- Prepared SP caching - Prepared SP caching
- CONDITIONs and HANDLERs - CONDITIONs and HANDLERs
- Simple read-only CURSORs. - Simple read-only CURSORs.
- SHOW DECLARE PROCEDURE/FUNCTION and SHOW PROCEDURE/FUNCTION STATUS
List of what's implemented:
- CREATE PROCEDURE|FUNCTION name ( args ) body List of what's implemented:
No routine characteristics yet.
- ALTER PROCEDURE|FUNCTION name ... - CREATE PROCEDURE|FUNCTION name ( args ) characteristics body
Is parsed, but a no-op (as there are no characteristics implemented yet). where characteristics is:
CASCADE/RESTRICT is not implemented (and CASCADE probably will not be). LANGUAGE SQL |
[NOT] DETERMINISTIC |
SQL SECURITY [DEFINER|INVOKER] |
COMMENT string
However the DETERMINISTIC setting is not currently used.
- ALTER PROCEDURE|FUNCTION name characteristics
CASCADE/RESTRICT is not implemented.
characteristics is:
COMMENT string |
SQL SECURITY [DEFINER|INVOKER] |
NAME newname
- DROP PROCEDURE|FUNCTION [IF EXISTS] name - DROP PROCEDURE|FUNCTION [IF EXISTS] name
CASCADE/RESTRICT is not implemented (and CASCADE probably will not be). CASCADE/RESTRICT is not implemented.
- CALL name (args) - CALL name (args)
OUT and INOUT parameters are only supported for local variables, and OUT and INOUT parameters are only supported for local variables, and
...@@ -92,23 +103,9 @@ List of what's implemented: ...@@ -92,23 +103,9 @@ List of what's implemented:
(The additional syntax will be added for completeness, but for the (The additional syntax will be added for completeness, but for the
most part unsupported with the current underlying cursor mechanism.) most part unsupported with the current underlying cursor mechanism.)
Closed questions: - SHOW procedures and functions
SHOW DECLARE PROCEDURE|FUNCTION <name>
- What is the expected result when creating a procedure with a name that returns the definition of a routine.
already exists? An error or overwrite? SHOW PROCEDURE|FUNCTION STATUS [LIKE <pattern>]
Answer: Error returns characteristics of routines, like the name, type, creator,
creation and modification dates, etc.
- Do PROCEDUREs and FUNCTIONs share namespace or not? I think not, but the
we need to flag the type in the mysql.proc table and the name alone is
not a unique key any more, or, we have separate tables.
(Unfortunately, mysql.func is already taken. Use "sfunc" and maybe even
rename "proc" into "sproc" while we still can, for consistency?)
Answer: Same tables, with an additional key-field for the type.
Open questions/issues:
- SQL-99 variables and parameters are typed. For the present we don't do
any type checking, since this is the way MySQL works. I still don't know
if we should keep it this way, or implement type checking. Possibly we
should have optional, uset-settable, type checking.
...@@ -852,12 +852,12 @@ n f ...@@ -852,12 +852,12 @@ n f
20 2432902008176640000 20 2432902008176640000
drop table fac; drop table fac;
show function status like '%f%'; show function status like '%f%';
Name Type Creator Modified Created Suid Comment Name Type Definer Modified Created Security_type Comment
fac function root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 Y fac FUNCTION root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 INVOKER
drop procedure ifac; drop procedure ifac;
drop function fac; drop function fac;
show function status like '%f%'; show function status like '%f%';
Name Type Creator Modified Created Suid Comment Name Type Definer Modified Created Security_type Comment
drop table if exists primes; drop table if exists primes;
create table primes ( create table primes (
i int unsigned not null primary key, i int unsigned not null primary key,
...@@ -945,9 +945,9 @@ end if; ...@@ -945,9 +945,9 @@ end if;
end loop; end loop;
end end
show procedure status like '%p%'; show procedure status like '%p%';
Name Type Creator Modified Created Suid Comment Name Type Definer Modified Created Security_type Comment
ip procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 Y ip PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 INVOKER
opp procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 Y opp PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 INVOKER
call ip(200); call ip(200);
select * from primes where i=45 or i=100 or i=199; select * from primes where i=45 or i=100 or i=199;
i p i p
...@@ -958,7 +958,7 @@ drop table primes; ...@@ -958,7 +958,7 @@ drop table primes;
drop procedure opp; drop procedure opp;
drop procedure ip; drop procedure ip;
show procedure status like '%p%'; show procedure status like '%p%';
Name Type Creator Modified Created Suid Comment Name Type Definer Modified Created Security_type Comment
drop table if exists fib; drop table if exists fib;
create table fib ( f bigint unsigned not null ); create table fib ( f bigint unsigned not null );
insert into fib values (1), (1); insert into fib values (1), (1);
...@@ -1008,8 +1008,8 @@ create procedure bar(x char(16), y int) ...@@ -1008,8 +1008,8 @@ create procedure bar(x char(16), y int)
comment "111111111111" sql security invoker comment "111111111111" sql security invoker
insert into test.t1 values (x, y); insert into test.t1 values (x, y);
show procedure status like 'bar'; show procedure status like 'bar';
Name Type Creator Modified Created Suid Comment Name Type Definer Modified Created Security_type Comment
bar procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 N 111111111111 bar PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 INVOKER 111111111111
alter procedure bar name bar2 comment "2222222222" sql security definer; alter procedure bar name bar2 comment "2222222222" sql security definer;
alter procedure bar2 name bar comment "3333333333"; alter procedure bar2 name bar comment "3333333333";
alter procedure bar; alter procedure bar;
...@@ -1019,8 +1019,8 @@ bar create procedure bar(x char(16), y int) ...@@ -1019,8 +1019,8 @@ bar create procedure bar(x char(16), y int)
comment "111111111111" sql security invoker comment "111111111111" sql security invoker
insert into test.t1 values (x, y) insert into test.t1 values (x, y)
show procedure status like 'bar'; show procedure status like 'bar';
Name Type Creator Modified Created Suid Comment Name Type Definer Modified Created Security_type Comment
bar procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 Y 3333333333 bar PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER 3333333333
drop procedure bar; drop procedure bar;
drop table t1; drop table t1;
drop table t2; drop table t2;
...@@ -289,17 +289,43 @@ fi ...@@ -289,17 +289,43 @@ fi
if test ! -f $mdata/proc.frm if test ! -f $mdata/proc.frm
then then
c_p="$c_p CREATE TABLE proc (" c_p="$c_p CREATE TABLE proc ("
c_p="$c_p schema char(64) binary DEFAULT '' NOT NULL,"
c_p="$c_p name char(64) binary DEFAULT '' NOT NULL," c_p="$c_p name char(64) binary DEFAULT '' NOT NULL,"
c_p="$c_p type enum('function','procedure') NOT NULL," c_p="$c_p type enum('FUNCTION','PROCEDURE') NOT NULL,"
c_p="$c_p body blob DEFAULT '' NOT NULL," c_p="$c_p specific_name char(64) binary DEFAULT '' NOT NULL,"
c_p="$c_p creator char(77) binary DEFAULT '' NOT NULL," c_p="$c_p language enum('SQL') DEFAULT 'SQL' NOT NULL,"
c_p="$c_p modified timestamp," c_p="$c_p sql_data_access enum('CONTAINS_SQL') DEFAULT 'CONTAINS_SQL' NOT NULL,"
c_p="$c_p is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL,"
c_p="$c_p definition blob DEFAULT '' NOT NULL,"
c_p="$c_p security_type enum('INVOKER','DEFINER') DEFAULT 'INVOKER' NOT NULL,"
c_p="$c_p definer char(77) binary DEFAULT '' NOT NULL,"
c_p="$c_p created timestamp," c_p="$c_p created timestamp,"
c_p="$c_p suid enum ('N', 'Y') DEFAULT 'Y' NOT NULL," c_p="$c_p modified timestamp,"
c_p="$c_p sql_mode set("
c_p="$c_p 'REAL_AS_FLOAT',"
c_p="$c_p 'PIPES_AS_CONCAT',"
c_p="$c_p 'ANSI_QUOTES',"
c_p="$c_p 'IGNORE_SPACE',"
c_p="$c_p 'NOT_USED',"
c_p="$c_p 'ONLY_FULL_GROUP_BY',"
c_p="$c_p 'NO_UNSIGNED_SUBTRACTION',"
c_p="$c_p 'NO_DIR_IN_CREATE',"
c_p="$c_p 'POSTGRESQL',"
c_p="$c_p 'ORACLE',"
c_p="$c_p 'MSSQL',"
c_p="$c_p 'DB2',"
c_p="$c_p 'MAXDB',"
c_p="$c_p 'NO_KEY_OPTIONS',"
c_p="$c_p 'NO_TABLE_OPTIONS',"
c_p="$c_p 'NO_FIELD_OPTIONS',"
c_p="$c_p 'MYSQL323',"
c_p="$c_p 'MYSQL40',"
c_p="$c_p 'ANSI',"
c_p="$c_p 'NO_AUTO_VALUE_ON_ZERO'"
c_p="$c_p ) DEFAULT 0 NOT NULL,"
c_p="$c_p comment char(64) binary DEFAULT '' NOT NULL," c_p="$c_p comment char(64) binary DEFAULT '' NOT NULL,"
c_p="$c_p PRIMARY KEY (name,type)" c_p="$c_p PRIMARY KEY (schema,name,type)"
c_p="$c_p )" c_p="$c_p ) comment='Stored Procedures';"
c_p="$c_p comment='Stored Procedures';"
fi fi
cat << END_OF_DATA cat << END_OF_DATA
......
...@@ -140,14 +140,40 @@ unique index (name) ...@@ -140,14 +140,40 @@ unique index (name)
# #
CREATE TABLE IF NOT EXISTS proc ( CREATE TABLE IF NOT EXISTS proc (
schema char(64) binary DEFAULT '' NOT NULL,
name char(64) binary DEFAULT '' NOT NULL, name char(64) binary DEFAULT '' NOT NULL,
type enum('function','procedure') NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL,
body blob DEFAULT '' NOT NULL, specific_name char(64) binary DEFAULT '' NOT NULL,
creator char(77) binary DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL,
modified timestamp, sql_data_access enum('CONTAINS_SQL') DEFAULT 'CONTAINS_SQL' NOT NULL,
is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL,
definition blob DEFAULT '' NOT NULL,
security_type enum('INVOKER','DEFINER') DEFAULT 'INVOKER' NOT NULL,
definer char(77) binary DEFAULT '' NOT NULL,
created timestamp, created timestamp,
suid enum ('N', 'Y') DEFAULT 'Y' NOT NULL, modified timestamp,
sql_mode set(
'REAL_AS_FLOAT',
'PIPES_AS_CONCAT',
'ANSI_QUOTES',
'IGNORE_SPACE',
'NOT_USED',
'ONLY_FULL_GROUP_BY',
'NO_UNSIGNED_SUBTRACTION',
'NO_DIR_IN_CREATE',
'POSTGRESQL',
'ORACLE',
'MSSQL',
'DB2',
'MAXDB',
'NO_KEY_OPTIONS',
'NO_TABLE_OPTIONS',
'NO_FIELD_OPTIONS',
'MYSQL323',
'MYSQL40',
'ANSI',
'NO_AUTO_VALUE_ON_ZERO'
) DEFAULT 0 NOT NULL,
comment char(64) binary DEFAULT '' NOT NULL, comment char(64) binary DEFAULT '' NOT NULL,
PRIMARY KEY (name,type) PRIMARY KEY (schema,name,type)
) comment='Stored Procedures'; ) comment='Stored Procedures';
...@@ -136,6 +136,7 @@ static SYMBOL symbols[] = { ...@@ -136,6 +136,7 @@ static SYMBOL symbols[] = {
{ "DELETE", SYM(DELETE_SYM),0,0}, { "DELETE", SYM(DELETE_SYM),0,0},
{ "DESC", SYM(DESC),0,0}, { "DESC", SYM(DESC),0,0},
{ "DESCRIBE", SYM(DESCRIBE),0,0}, { "DESCRIBE", SYM(DESCRIBE),0,0},
{ "DETERMINISTIC", SYM(DETERMINISTIC_SYM),0,0},
{ "DIRECTORY", SYM(DIRECTORY_SYM),0,0}, { "DIRECTORY", SYM(DIRECTORY_SYM),0,0},
{ "DISABLE", SYM(DISABLE_SYM),0,0}, { "DISABLE", SYM(DISABLE_SYM),0,0},
{ "DISCARD", SYM(DISCARD),0,0}, { "DISCARD", SYM(DISCARD),0,0},
...@@ -240,6 +241,7 @@ static SYMBOL symbols[] = { ...@@ -240,6 +241,7 @@ static SYMBOL symbols[] = {
{ "KEY", SYM(KEY_SYM),0,0}, { "KEY", SYM(KEY_SYM),0,0},
{ "KEYS", SYM(KEYS),0,0}, { "KEYS", SYM(KEYS),0,0},
{ "KILL", SYM(KILL_SYM),0,0}, { "KILL", SYM(KILL_SYM),0,0},
{ "LANGUAGE", SYM(LANGUAGE_SYM),0,0},
{ "LAST", SYM(LAST_SYM),0,0}, { "LAST", SYM(LAST_SYM),0,0},
{ "LEADING", SYM(LEADING),0,0}, { "LEADING", SYM(LEADING),0,0},
{ "LEAVE", SYM(LEAVE_SYM),0,0}, { "LEAVE", SYM(LEAVE_SYM),0,0},
......
...@@ -26,15 +26,21 @@ ...@@ -26,15 +26,21 @@
* *
*/ */
#define MYSQL_PROC_FIELD_NAME 0 #define MYSQL_PROC_FIELD_SCHEMA 0
#define MYSQL_PROC_FIELD_TYPE 1 #define MYSQL_PROC_FIELD_NAME 1
#define MYSQL_PROC_FIELD_DEFINITION 2 #define MYSQL_PROC_FIELD_TYPE 2
#define MYSQL_PROC_FIELD_CREATOR 3 #define MYSQL_PROC_FIELD_SPECIFIC_NAME 3
#define MYSQL_PROC_FIELD_MODIFIED 4 #define MYSQL_PROC_FIELD_LANGUAGE 4
#define MYSQL_PROC_FIELD_CREATED 5 #define MYSQL_PROC_FIELD_ACCESS 5
#define MYSQL_PROC_FIELD_SUID 6 #define MYSQL_PROC_FIELD_DETERMINISTIC 6
#define MYSQL_PROC_FIELD_COMMENT 7 #define MYSQL_PROC_FIELD_DEFINITION 7
#define MYSQL_PROC_FIELD_COUNT 8 #define MYSQL_PROC_FIELD_SECURITY_TYPE 8
#define MYSQL_PROC_FIELD_DEFINER 9
#define MYSQL_PROC_FIELD_CREATED 10
#define MYSQL_PROC_FIELD_MODIFIED 11
#define MYSQL_PROC_FIELD_SQL_MODE 12
#define MYSQL_PROC_FIELD_COMMENT 13
#define MYSQL_PROC_FIELD_COUNT 14
/* *opened=true means we opened ourselves */ /* *opened=true means we opened ourselves */
static int static int
...@@ -44,17 +50,18 @@ db_find_routine_aux(THD *thd, int type, char *name, uint namelen, ...@@ -44,17 +50,18 @@ db_find_routine_aux(THD *thd, int type, char *name, uint namelen,
DBUG_ENTER("db_find_routine_aux"); DBUG_ENTER("db_find_routine_aux");
DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name)); DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name));
TABLE *table; TABLE *table;
byte key[65]; // We know name is 64 and the enum is 1 byte byte key[64+64+1]; // schema, name, type
uint keylen; uint keylen;
int ret; int ret;
// Put the key together // Put the key together
memset(key, (int)' ', 64); // QQ Empty schema for now
keylen= namelen; keylen= namelen;
if (keylen > sizeof(key)-1) if (keylen > 64)
keylen= sizeof(key)-1; keylen= 64;
memcpy(key, name, keylen); memcpy(key+64, name, keylen);
memset(key+keylen, (int)' ', sizeof(key)-1 - keylen); // Pad with space memset(key+64+keylen, (int)' ', 64-keylen); // Pad with space
key[sizeof(key)-1]= type; key[128]= type;
keylen= sizeof(key); keylen= sizeof(key);
for (table= thd->open_tables ; table ; table= table->next) for (table= thd->open_tables ; table ; table= table->next)
...@@ -128,7 +135,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) ...@@ -128,7 +135,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp)
// Get additional information // Get additional information
if ((creator= get_field(&thd->mem_root, if ((creator= get_field(&thd->mem_root,
table->field[MYSQL_PROC_FIELD_CREATOR])) == NULL) table->field[MYSQL_PROC_FIELD_DEFINER])) == NULL)
{ {
ret= SP_GET_FIELD_FAILED; ret= SP_GET_FIELD_FAILED;
goto done; goto done;
...@@ -138,7 +145,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) ...@@ -138,7 +145,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp)
created= table->field[MYSQL_PROC_FIELD_CREATED]->val_int(); created= table->field[MYSQL_PROC_FIELD_CREATED]->val_int();
if ((ptr= get_field(&thd->mem_root, if ((ptr= get_field(&thd->mem_root,
table->field[MYSQL_PROC_FIELD_SUID])) == NULL) table->field[MYSQL_PROC_FIELD_SECURITY_TYPE])) == NULL)
{ {
ret= SP_GET_FIELD_FAILED; ret= SP_GET_FIELD_FAILED;
goto done; goto done;
...@@ -180,7 +187,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) ...@@ -180,7 +187,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp)
else else
{ {
*sphp= thd->lex->sphead; *sphp= thd->lex->sphead;
(*sphp)->sp_set_info((char *) creator, (uint) strlen(creator), (*sphp)->set_info((char *) creator, (uint) strlen(creator),
created, modified, suid, created, modified, suid,
ptr, length); ptr, length);
} }
...@@ -196,7 +203,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) ...@@ -196,7 +203,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp)
static int static int
db_create_routine(THD *thd, int type, db_create_routine(THD *thd, int type,
char *name, uint namelen, char *def, uint deflen, char *name, uint namelen, char *def, uint deflen,
char *comment, uint commentlen, bool suid) st_sp_chistics *chistics)
{ {
DBUG_ENTER("db_create_routine"); DBUG_ENTER("db_create_routine");
DBUG_PRINT("enter", ("type: %d name: %*s def: %*s", type, namelen, name, deflen, def)); DBUG_PRINT("enter", ("type: %d name: %*s def: %*s", type, namelen, name, deflen, def));
...@@ -224,16 +231,23 @@ db_create_routine(THD *thd, int type, ...@@ -224,16 +231,23 @@ db_create_routine(THD *thd, int type,
table->field[MYSQL_PROC_FIELD_NAME]->store(name, namelen, table->field[MYSQL_PROC_FIELD_NAME]->store(name, namelen,
system_charset_info); system_charset_info);
table->field[MYSQL_PROC_FIELD_TYPE]->store((longlong)type); table->field[MYSQL_PROC_FIELD_TYPE]->store((longlong)type);
table->field[MYSQL_PROC_FIELD_SPECIFIC_NAME]->store(name, namelen,
system_charset_info);
table->field[MYSQL_PROC_FIELD_DEFINITION]->store(def, deflen, table->field[MYSQL_PROC_FIELD_DEFINITION]->store(def, deflen,
system_charset_info); system_charset_info);
table->field[MYSQL_PROC_FIELD_CREATOR]->store(creator, table->field[MYSQL_PROC_FIELD_DEFINER]->store(creator,
(uint)strlen(creator), (uint)strlen(creator),
system_charset_info); system_charset_info);
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_CREATED])->set_time(); ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_CREATED])->set_time();
if (!suid) if (chistics->suid != IS_DEFAULT_SUID)
table->field[MYSQL_PROC_FIELD_SUID]->store((longlong) 1); table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->store(
if (comment) (longlong)chistics->suid);
table->field[MYSQL_PROC_FIELD_COMMENT]->store(comment, commentlen, table->field[MYSQL_PROC_FIELD_SQL_MODE]->store(
(longlong)thd->variables.sql_mode);
if (chistics->comment.str)
table->field[MYSQL_PROC_FIELD_COMMENT]->store(
chistics->comment.str,
chistics->comment.length,
system_charset_info); system_charset_info);
if (table->file->write_row(table->record[0])) if (table->file->write_row(table->record[0]))
...@@ -271,7 +285,7 @@ db_drop_routine(THD *thd, int type, char *name, uint namelen) ...@@ -271,7 +285,7 @@ db_drop_routine(THD *thd, int type, char *name, uint namelen)
static int static int
db_update_routine(THD *thd, int type, char *name, uint namelen, db_update_routine(THD *thd, int type, char *name, uint namelen,
char *newname, uint newnamelen, char *newname, uint newnamelen,
char *comment, uint commentlen, enum suid_behaviour suid) st_sp_chistics *chistics)
{ {
DBUG_ENTER("db_update_routine"); DBUG_ENTER("db_update_routine");
DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name)); DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name));
...@@ -284,15 +298,15 @@ db_update_routine(THD *thd, int type, char *name, uint namelen, ...@@ -284,15 +298,15 @@ db_update_routine(THD *thd, int type, char *name, uint namelen,
{ {
store_record(table,record[1]); store_record(table,record[1]);
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time(); ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time();
if (suid) if (chistics->suid)
table->field[MYSQL_PROC_FIELD_SUID]->store((longlong) suid); table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->store((longlong)chistics->suid);
if (newname) if (newname)
table->field[MYSQL_PROC_FIELD_NAME]->store(newname, table->field[MYSQL_PROC_FIELD_NAME]->store(newname,
newnamelen, newnamelen,
system_charset_info); system_charset_info);
if (comment) if (chistics->comment.str)
table->field[MYSQL_PROC_FIELD_COMMENT]->store(comment, table->field[MYSQL_PROC_FIELD_COMMENT]->store(chistics->comment.str,
commentlen, chistics->comment.length,
system_charset_info); system_charset_info);
if ((table->file->update_row(table->record[1],table->record[0]))) if ((table->file->update_row(table->record[1],table->record[0])))
ret= SP_WRITE_ROW_FAILED; ret= SP_WRITE_ROW_FAILED;
...@@ -314,10 +328,10 @@ static struct st_used_field init_fields[]= ...@@ -314,10 +328,10 @@ static struct st_used_field init_fields[]=
{ {
{ "Name", NAME_LEN, MYSQL_TYPE_STRING, 0}, { "Name", NAME_LEN, MYSQL_TYPE_STRING, 0},
{ "Type", 9, MYSQL_TYPE_STRING, 0}, { "Type", 9, MYSQL_TYPE_STRING, 0},
{ "Creator", 77, MYSQL_TYPE_STRING, 0}, { "Definer", 77, MYSQL_TYPE_STRING, 0},
{ "Modified", 0, MYSQL_TYPE_TIMESTAMP, 0}, { "Modified", 0, MYSQL_TYPE_TIMESTAMP, 0},
{ "Created", 0, MYSQL_TYPE_TIMESTAMP, 0}, { "Created", 0, MYSQL_TYPE_TIMESTAMP, 0},
{ "Suid", 1, MYSQL_TYPE_STRING, 0}, { "Security_type", 1, MYSQL_TYPE_STRING, 0},
{ "Comment", NAME_LEN, MYSQL_TYPE_STRING, 0}, { "Comment", NAME_LEN, MYSQL_TYPE_STRING, 0},
{ 0, 0, MYSQL_TYPE_STRING, 0} { 0, 0, MYSQL_TYPE_STRING, 0}
}; };
...@@ -347,6 +361,8 @@ print_field_values(THD *thd, TABLE *table, ...@@ -347,6 +361,8 @@ print_field_values(THD *thd, TABLE *table,
case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_TIMESTAMP:
{ {
TIME tmp_time; TIME tmp_time;
bzero((char *)&tmp_time, sizeof(tmp_time));
((Field_timestamp *) used_field->field)->get_time(&tmp_time); ((Field_timestamp *) used_field->field)->get_time(&tmp_time);
protocol->store(&tmp_time); protocol->store(&tmp_time);
} }
...@@ -354,6 +370,7 @@ print_field_values(THD *thd, TABLE *table, ...@@ -354,6 +370,7 @@ print_field_values(THD *thd, TABLE *table,
default: default:
{ {
String *tmp_string1= new String(); String *tmp_string1= new String();
get_field(&thd->mem_root, used_field->field, tmp_string1); get_field(&thd->mem_root, used_field->field, tmp_string1);
protocol->store(tmp_string1); protocol->store(tmp_string1);
} }
...@@ -490,14 +507,14 @@ sp_find_procedure(THD *thd, LEX_STRING *name) ...@@ -490,14 +507,14 @@ sp_find_procedure(THD *thd, LEX_STRING *name)
int int
sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen, sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen,
char *comment, uint commentlen, bool suid) st_sp_chistics *chistics)
{ {
DBUG_ENTER("sp_create_procedure"); DBUG_ENTER("sp_create_procedure");
DBUG_PRINT("enter", ("name: %*s def: %*s", namelen, name, deflen, def)); DBUG_PRINT("enter", ("name: %*s def: %*s", namelen, name, deflen, def));
int ret; int ret;
ret= db_create_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen, def, deflen, ret= db_create_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen, def, deflen,
comment, commentlen, suid); chistics);
DBUG_RETURN(ret); DBUG_RETURN(ret);
} }
...@@ -521,7 +538,7 @@ sp_drop_procedure(THD *thd, char *name, uint namelen) ...@@ -521,7 +538,7 @@ sp_drop_procedure(THD *thd, char *name, uint namelen)
int int
sp_update_procedure(THD *thd, char *name, uint namelen, sp_update_procedure(THD *thd, char *name, uint namelen,
char *newname, uint newnamelen, char *newname, uint newnamelen,
char *comment, uint commentlen, enum suid_behaviour suid) st_sp_chistics *chistics)
{ {
DBUG_ENTER("sp_update_procedure"); DBUG_ENTER("sp_update_procedure");
DBUG_PRINT("enter", ("name: %*s", namelen, name)); DBUG_PRINT("enter", ("name: %*s", namelen, name));
...@@ -533,7 +550,7 @@ sp_update_procedure(THD *thd, char *name, uint namelen, ...@@ -533,7 +550,7 @@ sp_update_procedure(THD *thd, char *name, uint namelen,
delete sp; delete sp;
ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen, ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen,
newname, newnamelen, newname, newnamelen,
comment, commentlen, suid); chistics);
DBUG_RETURN(ret); DBUG_RETURN(ret);
} }
...@@ -585,14 +602,14 @@ sp_find_function(THD *thd, LEX_STRING *name) ...@@ -585,14 +602,14 @@ sp_find_function(THD *thd, LEX_STRING *name)
int int
sp_create_function(THD *thd, char *name, uint namelen, char *def, uint deflen, sp_create_function(THD *thd, char *name, uint namelen, char *def, uint deflen,
char *comment, uint commentlen, bool suid) st_sp_chistics *chistics)
{ {
DBUG_ENTER("sp_create_function"); DBUG_ENTER("sp_create_function");
DBUG_PRINT("enter", ("name: %*s def: %*s", namelen, name, deflen, def)); DBUG_PRINT("enter", ("name: %*s def: %*s", namelen, name, deflen, def));
int ret; int ret;
ret= db_create_routine(thd, TYPE_ENUM_FUNCTION, name, namelen, def, deflen, ret= db_create_routine(thd, TYPE_ENUM_FUNCTION, name, namelen, def, deflen,
comment, commentlen, suid); chistics);
DBUG_RETURN(ret); DBUG_RETURN(ret);
} }
...@@ -616,7 +633,7 @@ sp_drop_function(THD *thd, char *name, uint namelen) ...@@ -616,7 +633,7 @@ sp_drop_function(THD *thd, char *name, uint namelen)
int int
sp_update_function(THD *thd, char *name, uint namelen, sp_update_function(THD *thd, char *name, uint namelen,
char *newname, uint newnamelen, char *newname, uint newnamelen,
char *comment, uint commentlen, enum suid_behaviour suid) st_sp_chistics *chistics)
{ {
DBUG_ENTER("sp_update_procedure"); DBUG_ENTER("sp_update_procedure");
DBUG_PRINT("enter", ("name: %*s", namelen, name)); DBUG_PRINT("enter", ("name: %*s", namelen, name));
...@@ -628,7 +645,7 @@ sp_update_function(THD *thd, char *name, uint namelen, ...@@ -628,7 +645,7 @@ sp_update_function(THD *thd, char *name, uint namelen,
delete sp; delete sp;
ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name, namelen, ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name, namelen,
newname, newnamelen, newname, newnamelen,
comment, commentlen, suid); chistics);
DBUG_RETURN(ret); DBUG_RETURN(ret);
} }
......
...@@ -33,7 +33,7 @@ sp_find_procedure(THD *thd, LEX_STRING *name); ...@@ -33,7 +33,7 @@ sp_find_procedure(THD *thd, LEX_STRING *name);
int int
sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen, sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen,
char *comment, uint commentlen, bool suid); st_sp_chistics *chistics);
int int
sp_drop_procedure(THD *thd, char *name, uint namelen); sp_drop_procedure(THD *thd, char *name, uint namelen);
...@@ -42,7 +42,7 @@ sp_drop_procedure(THD *thd, char *name, uint namelen); ...@@ -42,7 +42,7 @@ sp_drop_procedure(THD *thd, char *name, uint namelen);
int int
sp_update_procedure(THD *thd, char *name, uint namelen, sp_update_procedure(THD *thd, char *name, uint namelen,
char *newname, uint newnamelen, char *newname, uint newnamelen,
char *comment, uint commentlen, enum suid_behaviour suid); st_sp_chistics *chistics);
int int
sp_show_create_procedure(THD *thd, LEX_STRING *name); sp_show_create_procedure(THD *thd, LEX_STRING *name);
...@@ -55,7 +55,7 @@ sp_find_function(THD *thd, LEX_STRING *name); ...@@ -55,7 +55,7 @@ sp_find_function(THD *thd, LEX_STRING *name);
int int
sp_create_function(THD *thd, char *name, uint namelen, char *def, uint deflen, sp_create_function(THD *thd, char *name, uint namelen, char *def, uint deflen,
char *comment, uint commentlen, bool suid); st_sp_chistics *chistics);
int int
sp_drop_function(THD *thd, char *name, uint namelen); sp_drop_function(THD *thd, char *name, uint namelen);
...@@ -63,7 +63,7 @@ sp_drop_function(THD *thd, char *name, uint namelen); ...@@ -63,7 +63,7 @@ sp_drop_function(THD *thd, char *name, uint namelen);
int int
sp_update_function(THD *thd, char *name, uint namelen, sp_update_function(THD *thd, char *name, uint namelen,
char *newname, uint newnamelen, char *newname, uint newnamelen,
char *comment, uint commentlen, enum suid_behaviour suid); st_sp_chistics *chistics);
int int
sp_show_create_function(THD *thd, LEX_STRING *name); sp_show_create_function(THD *thd, LEX_STRING *name);
......
...@@ -190,14 +190,12 @@ sp_head::create(THD *thd) ...@@ -190,14 +190,12 @@ sp_head::create(THD *thd)
ret= sp_create_function(thd, ret= sp_create_function(thd,
m_name.str, m_name.length, m_name.str, m_name.length,
m_defstr.str, m_defstr.length, m_defstr.str, m_defstr.length,
m_comment.str, m_comment.length, m_chistics);
m_suid);
else else
ret= sp_create_procedure(thd, ret= sp_create_procedure(thd,
m_name.str, m_name.length, m_name.str, m_name.length,
m_defstr.str, m_defstr.length, m_defstr.str, m_defstr.length,
m_comment.str, m_comment.length, m_chistics);
m_suid);
DBUG_RETURN(ret); DBUG_RETURN(ret);
} }
......
...@@ -50,6 +50,7 @@ public: ...@@ -50,6 +50,7 @@ public:
my_bool m_simple_case; // TRUE if parsing simple case, FALSE otherwise my_bool m_simple_case; // TRUE if parsing simple case, FALSE otherwise
my_bool m_multi_results; // TRUE if a procedure with SELECT(s) my_bool m_multi_results; // TRUE if a procedure with SELECT(s)
uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value
st_sp_chistics *m_chistics;
#if NOT_USED_NOW #if NOT_USED_NOW
// QQ We're not using this at the moment. // QQ We're not using this at the moment.
List<char *> m_calls; // Called procedures. List<char *> m_calls; // Called procedures.
...@@ -68,20 +69,6 @@ public: ...@@ -68,20 +69,6 @@ public:
void void
init(LEX_STRING *name, LEX *lex); init(LEX_STRING *name, LEX *lex);
void
init_options(LEX_STRING *comment, enum suid_behaviour suid)
{
m_comment.length= 0;
m_comment.str= 0;
if (comment)
{
m_comment.length= comment->length;
m_comment.str= comment->str;
}
m_suid= suid ? suid - 1 : 1;
}
int int
create(THD *thd); create(THD *thd);
...@@ -154,7 +141,7 @@ public: ...@@ -154,7 +141,7 @@ public:
return sp_map_result_type(m_returns); return sp_map_result_type(m_returns);
} }
void sp_set_info(char *creator, uint creatorlen, void set_info(char *creator, uint creatorlen,
longlong created, longlong modified, longlong created, longlong modified,
bool suid, char *comment, uint commentlen) bool suid, char *comment, uint commentlen)
{ {
...@@ -162,9 +149,9 @@ public: ...@@ -162,9 +149,9 @@ public:
m_creatorlen= creatorlen; m_creatorlen= creatorlen;
m_created= created; m_created= created;
m_modified= modified; m_modified= modified;
m_comment.length= commentlen; m_chistics->comment.length= commentlen;
m_comment.str= comment; m_chistics->comment.str= comment;
m_suid= suid; m_chistics->suid= (suid ? IS_SUID : IS_NOT_SUID);
} }
inline void reset_thd_mem_root(THD *thd) inline void reset_thd_mem_root(THD *thd)
...@@ -195,12 +182,10 @@ private: ...@@ -195,12 +182,10 @@ private:
LEX_STRING m_name; LEX_STRING m_name;
LEX_STRING m_defstr; LEX_STRING m_defstr;
LEX_STRING m_comment;
char *m_creator; char *m_creator;
uint m_creatorlen; uint m_creatorlen;
longlong m_created; longlong m_created;
longlong m_modified; longlong m_modified;
bool m_suid;
sp_pcontext *m_pcont; // Parse context sp_pcontext *m_pcont; // Parse context
List<LEX> m_lex; // Temp. store for the other lex List<LEX> m_lex; // Temp. store for the other lex
......
...@@ -517,6 +517,13 @@ public: ...@@ -517,6 +517,13 @@ public:
typedef class st_select_lex SELECT_LEX; typedef class st_select_lex SELECT_LEX;
struct st_sp_chistics
{
LEX_STRING comment;
enum suid_behaviour suid;
bool detistic;
};
/* The state of the lex parsing. This is saved in the THD struct */ /* The state of the lex parsing. This is saved in the THD struct */
typedef struct st_lex typedef struct st_lex
...@@ -583,7 +590,6 @@ typedef struct st_lex ...@@ -583,7 +590,6 @@ typedef struct st_lex
enum enum_enable_or_disable alter_keys_onoff; enum enum_enable_or_disable alter_keys_onoff;
enum enum_var_type option_type; enum enum_var_type option_type;
enum tablespace_op_type tablespace_op; enum tablespace_op_type tablespace_op;
enum suid_behaviour suid;
uint uint_geom_type; uint uint_geom_type;
uint grant, grant_tot_col, which_columns; uint grant, grant_tot_col, which_columns;
uint fk_delete_opt, fk_update_opt, fk_match_option; uint fk_delete_opt, fk_update_opt, fk_match_option;
...@@ -598,6 +604,7 @@ typedef struct st_lex ...@@ -598,6 +604,7 @@ typedef struct st_lex
bool sp_lex_in_use; /* Keep track on lex usage in SPs for error handling */ bool sp_lex_in_use; /* Keep track on lex usage in SPs for error handling */
sp_pcontext *spcont; sp_pcontext *spcont;
HASH spfuns; /* Called functions */ HASH spfuns; /* Called functions */
st_sp_chistics sp_chistics;
st_lex() st_lex()
{ {
......
...@@ -3558,12 +3558,10 @@ mysql_execute_command(THD *thd) ...@@ -3558,12 +3558,10 @@ mysql_execute_command(THD *thd)
} }
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE) if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
res= sp_update_procedure(thd, lex->udf.name.str, lex->udf.name.length, res= sp_update_procedure(thd, lex->udf.name.str, lex->udf.name.length,
lex->name, newname_len, lex->comment->str, lex->name, newname_len, &lex->sp_chistics);
lex->comment->length, lex->suid);
else else
res= sp_update_function(thd, lex->udf.name.str, lex->udf.name.length, res= sp_update_function(thd, lex->udf.name.str, lex->udf.name.length,
lex->name, newname_len, lex->comment->str, lex->name, newname_len, &lex->sp_chistics);
lex->comment->length, lex->suid);
switch (res) switch (res)
{ {
case SP_OK: case SP_OK:
......
...@@ -139,6 +139,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -139,6 +139,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token CUBE_SYM %token CUBE_SYM
%token DEFINER_SYM %token DEFINER_SYM
%token DELETE_SYM %token DELETE_SYM
%token DETERMINISTIC_SYM
%token DUAL_SYM %token DUAL_SYM
%token DO_SYM %token DO_SYM
%token DROP %token DROP
...@@ -283,6 +284,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -283,6 +284,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token LEAVES %token LEAVES
%token LEVEL_SYM %token LEVEL_SYM
%token LEX_HOSTNAME %token LEX_HOSTNAME
%token LANGUAGE_SYM
%token LIKE %token LIKE
%token LINES %token LINES
%token LOCAL_SYM %token LOCAL_SYM
...@@ -630,7 +632,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -630,7 +632,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text
UNDERSCORE_CHARSET IDENT_sys TEXT_STRING_sys TEXT_STRING_literal UNDERSCORE_CHARSET IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
NCHAR_STRING opt_component key_cache_name NCHAR_STRING opt_component key_cache_name
SP_FUNC ident_or_spfunc sp_opt_label sp_comment sp_newname SP_FUNC ident_or_spfunc sp_opt_label
%type <lex_str_ptr> %type <lex_str_ptr>
opt_table_alias opt_table_alias
...@@ -761,6 +763,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -761,6 +763,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
subselect_end select_var_list select_var_list_init help opt_len subselect_end select_var_list select_var_list_init help opt_len
opt_extended_describe opt_extended_describe
statement sp_suid statement sp_suid
sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic sp_a_chistic
END_OF_INPUT END_OF_INPUT
%type <NONE> call sp_proc_stmts sp_proc_stmt %type <NONE> call sp_proc_stmts sp_proc_stmt
...@@ -1051,11 +1054,16 @@ create: ...@@ -1051,11 +1054,16 @@ create:
} }
'(' sp_pdparam_list ')' '(' sp_pdparam_list ')'
{ {
Lex->spcont->set_params(); LEX *lex= Lex;
lex->spcont->set_params();
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
} }
sp_comment sp_suid sp_c_chistics
{ {
Lex->sphead->init_options(&$9, Lex->suid); LEX *lex= Lex;
lex->sphead->m_chistics= &lex->sp_chistics;
} }
sp_proc_stmt sp_proc_stmt
{ {
...@@ -1113,17 +1121,22 @@ create_function_tail: ...@@ -1113,17 +1121,22 @@ create_function_tail:
} }
RETURNS_SYM type RETURNS_SYM type
{ {
Lex->sphead->m_returns= (enum enum_field_types)$7; LEX *lex= Lex;
lex->sphead->m_returns= (enum enum_field_types)$7;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
} }
sp_comment sp_suid sp_c_chistics
{ {
Lex->sphead->init_options(&$9, Lex->suid); LEX *lex= Lex;
lex->sphead->m_chistics= &lex->sp_chistics;
} }
sp_proc_stmt sp_proc_stmt
{ {
LEX *lex= Lex; LEX *lex= Lex;
lex->sql_command = SQLCOM_CREATE_SPFUNCTION; lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
/* Restore flag if it was cleared above */ /* Restore flag if it was cleared above */
if (lex->sphead->m_old_cmq) if (lex->sphead->m_old_cmq)
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES; YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
...@@ -1131,21 +1144,45 @@ create_function_tail: ...@@ -1131,21 +1144,45 @@ create_function_tail:
} }
; ;
sp_comment: sp_a_chistics:
/* Empty */ { $$.str= 0; $$.length= 0; } /* Empty */ {}
| COMMENT_SYM TEXT_STRING_sys { $$= $2; } | sp_a_chistics sp_a_chistic {}
;
sp_c_chistics:
/* Empty */ {}
| sp_c_chistics sp_c_chistic {}
;
/* Characteristics for both create and alter */
sp_chistic:
COMMENT_SYM TEXT_STRING_sys { Lex->sp_chistics.comment= $2; }
| sp_suid { }
; ;
sp_newname: /* Alter characteristics */
/* Empty */ { $$.str= 0; $$.length= 0; } sp_a_chistic:
| NAME_SYM ident { $$= $2; } sp_chistic { }
| NAME_SYM ident { Lex->name= $2.str; }
; ;
/* Create characteristics */
sp_c_chistic:
sp_chistic { }
| LANGUAGE_SYM SQL_SYM { }
| DETERMINISTIC_SYM { Lex->sp_chistics.detistic= TRUE; }
| NOT DETERMINISTIC_SYM { Lex->sp_chistics.detistic= FALSE; }
;
sp_suid: sp_suid:
/* Empty */ { Lex->suid= IS_DEFAULT_SUID; } SQL_SYM SECURITY_SYM DEFINER_SYM
| SQL_SYM SECURITY_SYM DEFINER_SYM { Lex->suid= IS_SUID; } {
| SQL_SYM SECURITY_SYM INVOKER_SYM { Lex->suid= IS_NOT_SUID; } Lex->sp_chistics.suid= IS_SUID;
}
| SQL_SYM SECURITY_SYM INVOKER_SYM
{
Lex->sp_chistics.suid= IS_NOT_SUID;
}
; ;
call: call:
...@@ -2648,36 +2685,35 @@ alter: ...@@ -2648,36 +2685,35 @@ alter:
lex->sql_command=SQLCOM_ALTER_DB; lex->sql_command=SQLCOM_ALTER_DB;
lex->name=$3.str; lex->name=$3.str;
} }
| ALTER PROCEDURE ident sp_newname sp_comment sp_suid | ALTER PROCEDURE ident
opt_restrict {
LEX *lex= Lex;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
Lex->name= 0;
}
sp_a_chistics
{ {
THD *thd= YYTHD; THD *thd= YYTHD;
LEX *lex=Lex; LEX *lex=Lex;
lex->sql_command= SQLCOM_ALTER_PROCEDURE; lex->sql_command= SQLCOM_ALTER_PROCEDURE;
lex->udf.name= $3; lex->udf.name= $3;
lex->name= $4.str;
/* $5 is a yacc/bison internal struct, so we can't keep
the pointer to it for use outside the parser. */
lex->comment= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING));
lex->comment->str= $5.str;
lex->comment->length= $5.length;
} }
| ALTER FUNCTION_SYM ident sp_newname sp_comment sp_suid | ALTER FUNCTION_SYM ident
opt_restrict {
LEX *lex= Lex;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
lex->name= 0;
}
sp_a_chistics
{ {
THD *thd= YYTHD; THD *thd= YYTHD;
LEX *lex=Lex; LEX *lex=Lex;
lex->sql_command= SQLCOM_ALTER_FUNCTION; lex->sql_command= SQLCOM_ALTER_FUNCTION;
lex->udf.name= $3; lex->udf.name= $3;
lex->name= $4.str;
/* $5 is a yacc/bison internal struct, so we can't keep
the pointer to it for use outside the parser. */
lex->comment= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING));
lex->comment= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING));
lex->comment->str= $5.str;
lex->comment->length= $5.length;
} }
; ;
...@@ -5775,6 +5811,7 @@ keyword: ...@@ -5775,6 +5811,7 @@ keyword:
| INNOBASE_SYM {} | INNOBASE_SYM {}
| INSERT_METHOD {} | INSERT_METHOD {}
| RELAY_THREAD {} | RELAY_THREAD {}
| LANGUAGE_SYM {}
| LAST_SYM {} | LAST_SYM {}
| LEAVES {} | LEAVES {}
| LEVEL_SYM {} | LEVEL_SYM {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment