Commit 4d891eb9 authored by unknown's avatar unknown

WL1034 update for latest 5.1 sources


BUILD/SETUP.sh:
  for now no optimizations in debug build - get rid of "value optimized out"
parent dad8c665
......@@ -79,7 +79,7 @@ fast_cflags="-O3 -fno-omit-frame-pointer"
reckless_cflags="-O3 -fomit-frame-pointer "
debug_cflags="-DUNIV_MUST_NOT_INLINE -DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DPEDANTIC_SAFEMALLOC -DSAFE_MUTEX"
debug_extra_cflags="-O1 -Wuninitialized"
debug_extra_cflags="-O0"
base_cxxflags="-felide-constructors -fno-exceptions -fno-rtti"
amd64_cxxflags="" # If dropping '--with-big-tables', add here "-DBIG_TABLES"
......
......@@ -751,6 +751,7 @@ extern void get_dynamic(DYNAMIC_ARRAY *array,gptr element,uint array_index);
extern void delete_dynamic(DYNAMIC_ARRAY *array);
extern void delete_dynamic_element(DYNAMIC_ARRAY *array, uint array_index);
extern void freeze_size(DYNAMIC_ARRAY *array);
extern int get_index_dynamic(DYNAMIC_ARRAY *array, gptr element);
#define dynamic_array_ptr(array,array_index) ((array)->buffer+(array_index)*(array)->size_of_element)
#define dynamic_element(array,array_index,type) ((type)((array)->buffer) +(array_index))
#define push_dynamic(A,B) insert_dynamic(A,B)
......
......@@ -62,7 +62,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc \
spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.cc \
sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \
parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc event.cc \
rpl_filter.cc sql_partition.cc handlerton.cc sql_plugin.cc
libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources)
......
......@@ -278,3 +278,28 @@ void freeze_size(DYNAMIC_ARRAY *array)
array->max_element=elements;
}
}
/*
Get the index of a dynamic element
SYNOPSIS
get_index_dynamic()
array Array
element Whose element index
*/
int get_index_dynamic(DYNAMIC_ARRAY *array, gptr element)
{
uint ret;
if (array->buffer > element)
return -1;
ret= (element - array->buffer) / array->size_of_element;
if (ret > array->elements)
return -1;
return ret;
}
......@@ -61,7 +61,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
tztime.h my_decimal.h\
sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \
parse_file.h sql_view.h sql_trigger.h \
sql_array.h sql_cursor.h \
sql_array.h sql_cursor.h event.h \
sql_plugin.h authors.h
mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \
......@@ -94,7 +94,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
gstream.cc spatial.cc sql_help.cc sql_cursor.cc \
tztime.cc my_time.c my_decimal.cc\
sp_head.cc sp_pcontext.cc sp_rcontext.cc sp.cc \
sp_cache.cc parse_file.cc sql_trigger.cc \
sp_cache.cc parse_file.cc sql_trigger.cc event.cc \
sql_plugin.cc\
handlerton.cc
EXTRA_mysqld_SOURCES = ha_innodb.cc ha_berkeley.cc ha_archive.cc \
......
......@@ -74,6 +74,7 @@ static SYMBOL symbols[] = {
{ "ASC", SYM(ASC)},
{ "ASCII", SYM(ASCII_SYM)},
{ "ASENSITIVE", SYM(ASENSITIVE_SYM)},
{ "AT", SYM(AT_SYM)},
{ "AUTHORS", SYM(AUTHORS_SYM)},
{ "AUTO_INCREMENT", SYM(AUTO_INC)},
{ "AVG", SYM(AVG_SYM)},
......@@ -121,6 +122,7 @@ static SYMBOL symbols[] = {
{ "COMMIT", SYM(COMMIT_SYM)},
{ "COMMITTED", SYM(COMMITTED_SYM)},
{ "COMPACT", SYM(COMPACT_SYM)},
{ "COMPLETION", SYM(COMPLETION_SYM)},
{ "COMPRESSED", SYM(COMPRESSED_SYM)},
{ "CONCURRENT", SYM(CONCURRENT)},
{ "CONDITION", SYM(CONDITION_SYM)},
......@@ -180,13 +182,16 @@ static SYMBOL symbols[] = {
{ "ENABLE", SYM(ENABLE_SYM)},
{ "ENCLOSED", SYM(ENCLOSED)},
{ "END", SYM(END)},
{ "ENDS", SYM(ENDS_SYM)},
{ "ENGINE", SYM(ENGINE_SYM)},
{ "ENGINES", SYM(ENGINES_SYM)},
{ "ENUM", SYM(ENUM)},
{ "ERRORS", SYM(ERRORS)},
{ "ESCAPE", SYM(ESCAPE_SYM)},
{ "ESCAPED", SYM(ESCAPED)},
{ "EVENT", SYM(EVENT_SYM)},
{ "EVENTS", SYM(EVENTS_SYM)},
{ "EVERY", SYM(EVERY_SYM)},
{ "EXECUTE", SYM(EXECUTE_SYM)},
{ "EXISTS", SYM(EXISTS)},
{ "EXIT", SYM(EXIT_SYM)},
......@@ -384,6 +389,7 @@ static SYMBOL symbols[] = {
{ "POLYGON", SYM(POLYGON)},
{ "PRECISION", SYM(PRECISION)},
{ "PREPARE", SYM(PREPARE_SYM)},
{ "PRESERVE", SYM(PRESERVE_SYM)},
{ "PREV", SYM(PREV_SYM)},
{ "PRIMARY", SYM(PRIMARY_SYM)},
{ "PRIVILEGES", SYM(PRIVILEGES)},
......@@ -436,6 +442,7 @@ static SYMBOL symbols[] = {
{ "ROW_FORMAT", SYM(ROW_FORMAT_SYM)},
{ "RTREE", SYM(RTREE_SYM)},
{ "SAVEPOINT", SYM(SAVEPOINT_SYM)},
{ "SCHEDULE", SYM(SCHEDULE_SYM)},
{ "SCHEMA", SYM(DATABASE)},
{ "SCHEMAS", SYM(DATABASES)},
{ "SECOND", SYM(SECOND_SYM)},
......@@ -484,6 +491,7 @@ static SYMBOL symbols[] = {
{ "SSL", SYM(SSL_SYM)},
{ "START", SYM(START_SYM)},
{ "STARTING", SYM(STARTING)},
{ "STARTS", SYM(STARTS_SYM)},
{ "STATUS", SYM(STATUS_SYM)},
{ "STOP", SYM(STOP_SYM)},
{ "STORAGE", SYM(STORAGE_SYM)},
......
......@@ -24,6 +24,7 @@
#include "stacktrace.h"
#include "mysqld_suffix.h"
#include "mysys_err.h"
#include "event.h"
#include "ha_myisam.h"
......@@ -3502,6 +3503,8 @@ we force server id to 2, but this MySQL server will not act as a slave.");
}
}
init_events();
create_shutdown_thread();
create_maintenance_thread();
......@@ -4526,7 +4529,7 @@ enum options_mysqld
OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
OPT_SAFE_USER_CREATE, OPT_SQL_MODE,
OPT_HAVE_NAMED_PIPE,
OPT_DO_PSTACK, OPT_REPORT_HOST,
OPT_DO_PSTACK, OPT_EVENT_EXECUTOR, OPT_REPORT_HOST,
OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT,
OPT_SHOW_SLAVE_AUTH_INFO,
OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE,
......@@ -4804,6 +4807,9 @@ Disable with --skip-bdb (will save memory).",
(gptr*) &global_system_variables.engine_condition_pushdown,
(gptr*) &global_system_variables.engine_condition_pushdown,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"event-executor", OPT_EVENT_EXECUTOR, "Print a symbolic stack trace on failure.",
(gptr*) &opt_event_executor, (gptr*) &opt_event_executor, 0, GET_BOOL, NO_ARG,
1/*default*/, 0/*min-value*/, 1/*max-value*/, 0, 0, 0},
{"exit-info", 'T', "Used for debugging; Use at your own risk!", 0, 0, 0,
GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"external-locking", OPT_USE_LOCKING, "Use system (external) locking. With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running.",
......@@ -6028,6 +6034,7 @@ struct show_var_st status_vars[]= {
{"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONG_STATUS},
{"Com_admin_commands", (char*) offsetof(STATUS_VAR, com_other), SHOW_LONG_STATUS},
{"Com_alter_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS},
{"Com_alter_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_EVENT]), SHOW_LONG_STATUS},
{"Com_alter_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS},
{"Com_analyze", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ANALYZE]), SHOW_LONG_STATUS},
{"Com_backup_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BACKUP_TABLE]), SHOW_LONG_STATUS},
......@@ -6038,6 +6045,7 @@ struct show_var_st status_vars[]= {
{"Com_checksum", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECKSUM]), SHOW_LONG_STATUS},
{"Com_commit", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_COMMIT]), SHOW_LONG_STATUS},
{"Com_create_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_DB]), SHOW_LONG_STATUS},
{"Com_create_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_EVENT]), SHOW_LONG_STATUS},
{"Com_create_function", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_FUNCTION]), SHOW_LONG_STATUS},
{"Com_create_index", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS},
{"Com_create_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
......@@ -6046,6 +6054,7 @@ struct show_var_st status_vars[]= {
{"Com_delete_multi", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE_MULTI]), SHOW_LONG_STATUS},
{"Com_do", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DO]), SHOW_LONG_STATUS},
{"Com_drop_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_DB]), SHOW_LONG_STATUS},
{"Com_drop_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_EVENT]), SHOW_LONG_STATUS},
{"Com_drop_function", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_FUNCTION]), SHOW_LONG_STATUS},
{"Com_drop_index", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
{"Com_drop_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
......@@ -6087,6 +6096,7 @@ struct show_var_st status_vars[]= {
{"Com_show_collations", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLLATIONS]), SHOW_LONG_STATUS},
{"Com_show_column_types", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLUMN_TYPES]), SHOW_LONG_STATUS},
{"Com_show_create_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS},
{"Com_show_create_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_EVENT]), SHOW_LONG_STATUS},
{"Com_show_create_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE]), SHOW_LONG_STATUS},
{"Com_show_databases", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_DATABASES]), SHOW_LONG_STATUS},
{"Com_show_engine_logs", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_LOGS]), SHOW_LONG_STATUS},
......
......@@ -102,6 +102,7 @@ extern ulong ndb_cache_check_time;
extern my_bool event_executor_running_global_var;
static HASH system_variable_hash;
const char *bool_type_names[]= { "OFF", "ON", NullS };
......@@ -206,6 +207,8 @@ sys_var_long_ptr sys_delayed_insert_timeout("delayed_insert_timeout",
&delayed_insert_timeout);
sys_var_long_ptr sys_delayed_queue_size("delayed_queue_size",
&delayed_queue_size);
sys_var_bool_ptr sys_event_executor("event_executor",
&event_executor_running_global_var);
sys_var_long_ptr sys_expire_logs_days("expire_logs_days",
&expire_logs_days);
sys_var_bool_ptr sys_flush("flush", &myisam_flush);
......@@ -664,6 +667,7 @@ struct show_var_st init_vars[]= {
{sys_div_precincrement.name,(char*) &sys_div_precincrement,SHOW_SYS},
{sys_engine_condition_pushdown.name,
(char*) &sys_engine_condition_pushdown, SHOW_SYS},
{sys_event_executor.name, (char*) &sys_event_executor, SHOW_SYS},
{sys_expire_logs_days.name, (char*) &sys_expire_logs_days, SHOW_SYS},
{sys_flush.name, (char*) &sys_flush, SHOW_SYS},
{sys_flush_time.name, (char*) &sys_flush_time, SHOW_SYS},
......
......@@ -5721,3 +5721,19 @@ ER_DROP_PARTITION_WHEN_FK_DEFINED
swe "Kan inte ta bort en partition nr en frmmande nyckel r definierad p tabellen"
ER_PLUGIN_IS_NOT_LOADED
eng "Plugin '%-.64s' is not loaded"
ER_EVENT_ALREADY_EXISTS
eng "Event %s already exists"
ER_EVENT_STORE_FAILED
eng "Failed to create event %s"
ER_EVENT_DOES_NOT_EXIST
eng "Event %s does not exist"
ER_EVENT_CANT_ALTER
eng "Failed to alter event %s"
ER_EVENT_DROP_FAILED
eng "Failed to DROP %s %s"
ER_EVENT_INTERVAL_NOT_POSITIVE
eng "INTERVAL must be positive"
ER_EVENT_ENDS_BEFORE_STARTS
eng "ENDS must be after STARTS"
ER_EVENT_EXEC_TIME_IN_THE_PAST
eng "Activation (AT) time is in the past"
......@@ -20,6 +20,9 @@
#include "sp_cache.h"
#include "sql_trigger.h"
#define SP_OPEN_TABLE_FOR_UPDATE() \
open_proc_type_table_for_update(thd, "proc", &mysql_proc_table_exists)
static bool
create_string(THD *thd, String *buf,
int sp_type,
......@@ -68,7 +71,7 @@ bool mysql_proc_table_exists= 1;
/*
Close mysql.proc, opened with open_proc_table_for_read().
Close mysql.proc, opened with open_proc_type_table_for_read().
SYNOPSIS
close_proc_table()
......@@ -86,14 +89,16 @@ void close_proc_table(THD *thd, Open_tables_state *backup)
/*
Open the mysql.proc table for read.
Open table which has key structure like of mysql.proc for read.
SYNOPSIS
open_proc_table_for_read()
open_proc_type_table_for_read()
thd Thread context
backup Pointer to Open_tables_state instance where information about
currently open tables will be saved, and from which will be
restored when we will end work with mysql.proc.
tname Table name having primary key structure like mysql.proc
table_exists Ptr to boolean to set whether the system table exists or not
NOTES
Thanks to restrictions which we put on opening and locking of
......@@ -104,10 +109,11 @@ void close_proc_table(THD *thd, Open_tables_state *backup)
RETURN
0 Error
# Pointer to TABLE object of mysql.proc
# Pointer to TABLE object of tname
*/
TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup)
TABLE *open_proc_type_table_for_read(THD *thd, Open_tables_state *backup,
const char *tname, bool *table_exists)
{
TABLE_LIST tables;
TABLE *table;
......@@ -115,22 +121,22 @@ TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup)
DBUG_ENTER("open_proc_table");
/*
Speed up things if mysql.proc doesn't exists. mysql_proc_table_exists
Speed up things if the table doesn't exists. *table_exists
is set when we create or read stored procedure or on flush privileges.
*/
if (!mysql_proc_table_exists)
if (!*table_exists)
DBUG_RETURN(0);
thd->reset_n_backup_open_tables_state(backup);
bzero((char*) &tables, sizeof(tables));
tables.db= (char*) "mysql";
tables.table_name= tables.alias= (char*)"proc";
tables.table_name= tables.alias= (char*) tname;
if (!(table= open_table(thd, &tables, thd->mem_root, &not_used,
MYSQL_LOCK_IGNORE_FLUSH)))
{
thd->restore_backup_open_tables_state(backup);
mysql_proc_table_exists= 0;
*table_exists= 0;
DBUG_RETURN(0);
}
......@@ -152,11 +158,13 @@ TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup)
/*
Open the mysql.proc table for update.
Open table with primary key struct like mysql.proc for update.
SYNOPSIS
open_proc_table_for_update()
open_proc_type_table_for_update()
thd Thread context
tname Table name with primary key structure like mysql.proc
table_exists Ptr to boolean to set whether the system table exists or not
NOTES
Table opened with this call should closed using close_thread_tables().
......@@ -166,7 +174,8 @@ TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup)
# Pointer to TABLE object of mysql.proc
*/
static TABLE *open_proc_table_for_update(THD *thd)
TABLE *open_proc_type_table_for_update(THD *thd, const char *tname,
bool *table_exists)
{
TABLE_LIST tables;
TABLE *table;
......@@ -174,7 +183,7 @@ static TABLE *open_proc_table_for_update(THD *thd)
bzero((char*) &tables, sizeof(tables));
tables.db= (char*) "mysql";
tables.table_name= tables.alias= (char*)"proc";
tables.table_name= tables.alias= (char*) tname;
tables.lock_type= TL_WRITE;
table= open_ltable(thd, &tables, TL_WRITE);
......@@ -186,7 +195,7 @@ static TABLE *open_proc_table_for_update(THD *thd)
transient.
*/
if (!(thd->locked_tables || thd->prelocked_mode) || table)
mysql_proc_table_exists= test(table);
*table_exists= test(table);
DBUG_RETURN(table);
}
......@@ -196,10 +205,11 @@ static TABLE *open_proc_table_for_update(THD *thd)
Find row in open mysql.proc table representing stored routine.
SYNOPSIS
db_find_routine_aux()
sp_db_find_routine_aux()
thd Thread context
type Type of routine to find (function or procedure)
name Name of routine
dbname Name of routine's database
rname Name of the routine inside the db
table TABLE object for open mysql.proc table.
RETURN VALUE
......@@ -207,13 +217,14 @@ static TABLE *open_proc_table_for_update(THD *thd)
SP_KEY_NOT_FOUND- No routine with given name
*/
static int
db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table)
int
sp_db_find_routine_aux(THD *thd, int type, const LEX_STRING dbname,
const LEX_STRING rname, TABLE *table)
{
byte key[MAX_KEY_LENGTH]; // db, name, optional key length type
DBUG_ENTER("db_find_routine_aux");
DBUG_ENTER("sp_db_find_routine_aux");
DBUG_PRINT("enter", ("type: %d name: %.*s",
type, name->m_name.length, name->m_name.str));
type, rname.length, rname.str));
/*
Create key to find row. We have to use field->store() to be able to
......@@ -222,11 +233,10 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table)
'db', 'name' and 'type' and the first key is the primary key over the
same fields.
*/
if (name->m_name.length > table->field[1]->field_length)
if (rname.length > table->field[1]->field_length)
DBUG_RETURN(SP_KEY_NOT_FOUND);
table->field[0]->store(name->m_db.str, name->m_db.length, &my_charset_bin);
table->field[1]->store(name->m_name.str, name->m_name.length,
&my_charset_bin);
table->field[0]->store(dbname.str, dbname.length, &my_charset_bin);
table->field[1]->store(rname.str, rname.length, &my_charset_bin);
table->field[2]->store((longlong) type, TRUE);
key_copy(key, table->record[0], table->key_info,
table->key_info->key_length);
......@@ -283,10 +293,12 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
type, name->m_name.length, name->m_name.str));
*sphp= 0; // In case of errors
if (!(table= open_proc_table_for_read(thd, &open_tables_state_backup)))
if (!(table= open_proc_type_table_for_read(thd,&open_tables_state_backup,
"proc", &mysql_proc_table_exists)))
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
if ((ret= db_find_routine_aux(thd, type, name, table)) != SP_OK)
if ((ret= sp_db_find_routine_aux(thd, type, name->m_db, name->m_name,
table)) != SP_OK)
goto done;
if (table->s->fields != MYSQL_PROC_FIELD_COUNT)
......@@ -493,7 +505,7 @@ db_create_routine(THD *thd, int type, sp_head *sp)
goto done;
}
if (!(table= open_proc_table_for_update(thd)))
if (!(table= SP_OPEN_TABLE_FOR_UPDATE()))
ret= SP_OPEN_TABLE_FAILED;
else
{
......@@ -614,9 +626,10 @@ db_drop_routine(THD *thd, int type, sp_name *name)
DBUG_PRINT("enter", ("type: %d name: %.*s",
type, name->m_name.length, name->m_name.str));
if (!(table= open_proc_table_for_update(thd)))
if (!(table= SP_OPEN_TABLE_FOR_UPDATE()))
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
if ((ret= db_find_routine_aux(thd, type, name, table)) == SP_OK)
if ((ret= sp_db_find_routine_aux(thd, type, name->m_db, name->m_name,
table)) == SP_OK)
{
if (table->file->delete_row(table->record[0]))
ret= SP_DELETE_ROW_FAILED;
......@@ -636,9 +649,10 @@ db_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
DBUG_PRINT("enter", ("type: %d name: %.*s",
type, name->m_name.length, name->m_name.str));
if (!(table= open_proc_table_for_update(thd)))
if (!(table= SP_OPEN_TABLE_FOR_UPDATE()))
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
if ((ret= db_find_routine_aux(thd, type, name, table)) == SP_OK)
if ((ret= sp_db_find_routine_aux(thd, type, name->m_db, name->m_name,
table)) == SP_OK)
{
store_record(table,record[1]);
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
......@@ -860,7 +874,7 @@ sp_drop_db_routines(THD *thd, char *db)
keylen= sizeof(key);
ret= SP_OPEN_TABLE_FAILED;
if (!(table= open_proc_table_for_update(thd)))
if (!(table= SP_OPEN_TABLE_FOR_UPDATE()))
goto err;
ret= SP_OK;
......
......@@ -31,6 +31,8 @@
#define SP_BAD_IDENTIFIER -9
#define SP_BODY_TOO_LONG -10
extern bool mysql_proc_table_exists;
/* Drop all routines in database 'db' */
int
sp_drop_db_routines(THD *thd, char *db);
......@@ -97,9 +99,17 @@ extern "C" byte* sp_sroutine_key(const byte *ptr, uint *plen, my_bool first);
Routines which allow open/lock and close mysql.proc table even when
we already have some tables open and locked.
*/
TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup);
TABLE *open_proc_type_table_for_read(THD *thd, Open_tables_state *backup,
const char *tname, bool *table_exists);
TABLE *open_proc_type_table_for_update(THD *thd, const char *tname,
bool *table_exists);
void close_proc_table(THD *thd, Open_tables_state *backup);
int
sp_db_find_routine_aux(THD *thd, int type, const LEX_STRING dbname,
const LEX_STRING rname, TABLE *table);
//
// Utilities...
//
......
......@@ -3971,13 +3971,13 @@ static const char *command_array[]=
"ALTER", "SHOW DATABASES", "SUPER", "CREATE TEMPORARY TABLES",
"LOCK TABLES", "EXECUTE", "REPLICATION SLAVE", "REPLICATION CLIENT",
"CREATE VIEW", "SHOW VIEW", "CREATE ROUTINE", "ALTER ROUTINE",
"CREATE USER"
"CREATE USER", "EVENT"
};
static uint command_lengths[]=
{
6, 6, 6, 6, 6, 4, 6, 8, 7, 4, 5, 10, 5, 5, 14, 5, 23, 11, 7, 17, 18, 11, 9,
14, 13, 11
14, 13, 11, 5
};
......
......@@ -42,6 +42,7 @@
#define CREATE_PROC_ACL (1L << 23)
#define ALTER_PROC_ACL (1L << 24)
#define CREATE_USER_ACL (1L << 25)
#define EVENT_ACL (1L << 26)
/*
don't forget to update
1. static struct show_privileges_st sys_privileges[]
......@@ -78,7 +79,7 @@
REFERENCES_ACL | INDEX_ACL | ALTER_ACL | SHOW_DB_ACL | SUPER_ACL | \
CREATE_TMP_ACL | LOCK_TABLES_ACL | REPL_SLAVE_ACL | REPL_CLIENT_ACL | \
EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | CREATE_PROC_ACL | \
ALTER_PROC_ACL | CREATE_USER_ACL)
ALTER_PROC_ACL | CREATE_USER_ACL | EVENT_ACL)
#define DEFAULT_CREATE_PROC_ACLS \
(ALTER_PROC_ACL | EXECUTE_ACL)
......
......@@ -177,7 +177,9 @@ void lex_start(THD *thd, const uchar *buf, uint length)
lex->spcont= NULL;
lex->proc_list.first= 0;
lex->query_tables_own_last= 0;
lex->escape_used= FALSE;
lex->escape_used= lex->et_compile_phase= FALSE;
lex->et= NULL;
if (lex->sroutines.records)
my_hash_reset(&lex->sroutines);
......
......@@ -26,6 +26,7 @@ class sp_name;
class sp_instr;
class sp_pcontext;
class partition_info;
class event_timed;
/*
The following hack is needed because mysql_yacc.cc does not define
......@@ -94,6 +95,8 @@ enum enum_sql_command {
SQLCOM_SHOW_PROC_CODE, SQLCOM_SHOW_FUNC_CODE,
SQLCOM_INSTALL_PLUGIN, SQLCOM_UNINSTALL_PLUGIN,
SQLCOM_SHOW_AUTHORS,
SQLCOM_CREATE_EVENT, SQLCOM_ALTER_EVENT, SQLCOM_DROP_EVENT,
SQLCOM_SHOW_CREATE_EVENT,
/* This should be the last !!! */
SQLCOM_END
......@@ -890,6 +893,10 @@ typedef struct st_lex
uint sroutines_list_own_elements;
st_sp_chistics sp_chistics;
event_timed *et;
bool et_compile_phase;
bool only_view; /* used for SHOW CREATE TABLE/VIEW */
/*
field_list was created for view and should be removed before PS/SP
......
......@@ -25,6 +25,7 @@
#include "sp_head.h"
#include "sp.h"
#include "sp_cache.h"
#include "event.h"
#ifdef HAVE_OPENSSL
/*
......@@ -642,6 +643,9 @@ void init_update_queries(void)
uc_update_queries[SQLCOM_DROP_INDEX]=1;
uc_update_queries[SQLCOM_CREATE_VIEW]=1;
uc_update_queries[SQLCOM_DROP_VIEW]=1;
uc_update_queries[SQLCOM_CREATE_EVENT]=1;
uc_update_queries[SQLCOM_ALTER_EVENT]=1;
uc_update_queries[SQLCOM_DROP_EVENT]=1;
}
bool is_update_query(enum enum_sql_command command)
......@@ -3669,6 +3673,130 @@ end_with_restore_list:
res=mysqld_show_create_db(thd,lex->name,&lex->create_info);
break;
}
case SQLCOM_CREATE_EVENT:
{
if (check_global_access(thd, EVENT_ACL))
break;
DBUG_ASSERT(lex->et);
if (! lex->et->m_db.str)
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
delete lex->et;
lex->et= 0;
goto error;
}
int result;
uint create_options= lex->create_info.options;
res= (result= evex_create_event(thd, lex->et, create_options));
switch (result) {
case EVEX_OK:
send_ok(thd, 1);
break;
case EVEX_WRITE_ROW_FAILED:
my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), lex->et->m_name.str);
break;
case EVEX_NO_DB_ERROR:
my_error(ER_BAD_DB_ERROR, MYF(0), lex->et->m_db.str);
break;
default:
//includes EVEX_PARSE_ERROR
my_error(ER_EVENT_STORE_FAILED, MYF(0), lex->et->m_name.str);
break;
}
/* lex->unit.cleanup() is called outside, no need to call it here */
delete lex->et;
lex->et= 0;
delete lex->sphead;
lex->sphead= 0;
break;
}
case SQLCOM_ALTER_EVENT:
{
if (check_global_access(thd, EVENT_ACL))
break;
DBUG_ASSERT(lex->et);
if (! lex->et->m_db.str)
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
delete lex->et;
lex->et= 0;
goto error;
}
int result;
res= (result= evex_update_event(thd, lex->spname, lex->et));
switch (result) {
case EVEX_OK:
send_ok(thd, 1);
break;
case EVEX_KEY_NOT_FOUND:
my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), lex->et->m_qname.str);
break;
default:
my_error(ER_EVENT_CANT_ALTER, MYF(0), lex->et->m_qname.str);
break;
}
delete lex->et;
lex->et= 0;
if (lex->sphead)
{
delete lex->sphead;
lex->sphead= 0;
}
break;
}
case SQLCOM_DROP_EVENT:
{
if (check_global_access(thd, EVENT_ACL))
break;
DBUG_ASSERT(lex->et);
if (! lex->et->m_db.str)
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
delete lex->et;
lex->et= 0;
goto error;
}
int result;
res= (result= evex_drop_event(thd, lex->et, lex->drop_if_exists));
switch (result) {
case EVEX_OK:
send_ok(thd, 1);
break;
case EVEX_KEY_NOT_FOUND:
my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), lex->et->m_qname.str);
break;
default:
my_error(ER_EVENT_DROP_FAILED, MYF(0), lex->et->m_qname.str);
break;
}
delete lex->et;
lex->et= 0;
break;
}
case SQLCOM_SHOW_CREATE_EVENT:
{
if (check_global_access(thd, EVENT_ACL))
break;
if (lex->spname->m_name.length > NAME_LEN)
{
my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str);
goto error;
}
send_ok(thd, 1);
break;
}
case SQLCOM_CREATE_FUNCTION: // UDF function
{
if (check_access(thd,INSERT_ACL,"mysql",0,1,0,0))
......
......@@ -147,6 +147,7 @@ static struct show_privileges_st sys_privileges[]=
{"Create user", "Server Admin", "To create new users"},
{"Delete", "Tables", "To delete existing rows"},
{"Drop", "Databases,Tables", "To drop databases, tables, and views"},
{"Event","Server Admin","Creation, alteration, deletion and execution of events."},
{"Execute", "Functions,Procedures", "To execute stored routines"},
{"File", "File access on server", "To read and write files on the server"},
{"Grant option", "Databases,Tables,Functions,Procedures", "To give to other users those privileges you possess"},
......@@ -2930,7 +2931,9 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond)
proc_tables.table_name_length= 4;
proc_tables.lock_type= TL_READ;
full_access= !check_table_access(thd, SELECT_ACL, &proc_tables, 1);
if (!(proc_table= open_proc_table_for_read(thd, &open_tables_state_backup)))
if (!(proc_table= open_proc_type_table_for_read(thd, &open_tables_state_backup,
"proc",
&mysql_proc_table_exists)))
{
DBUG_RETURN(1);
}
......
......@@ -38,6 +38,7 @@
#include "sp_pcontext.h"
#include "sp_rcontext.h"
#include "sp.h"
#include "event.h"
#include <myisam.h>
#include <myisammrg.h>
......@@ -136,6 +137,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token ASC
%token ASCII_SYM
%token ASENSITIVE_SYM
%token AT_SYM
%token ATAN
%token AUTHORS_SYM
%token AUTO_INC
......@@ -186,6 +188,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token COMMITTED_SYM
%token COMMIT_SYM
%token COMPACT_SYM
%token COMPLETION_SYM
%token COMPRESSED_SYM
%token CONCAT
%token CONCAT_WS
......@@ -254,6 +257,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token ENCODE_SYM
%token ENCRYPT
%token END
%token ENDS_SYM
%token ENGINES_SYM
%token ENGINE_SYM
%token ENUM
......@@ -262,7 +266,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token ERRORS
%token ESCAPED
%token ESCAPE_SYM
%token EVENT_SYM
%token EVENTS_SYM
%token EVERY_SYM
%token EXECUTE_SYM
%token EXISTS
%token EXIT_SYM
......@@ -488,6 +494,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token POSITION_SYM
%token PRECISION
%token PREPARE_SYM
%token PRESERVE_SYM
%token PREV_SYM
%token PRIMARY_SYM
%token PRIVILEGES
......@@ -544,6 +551,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token ROW_SYM
%token RTREE_SYM
%token SAVEPOINT_SYM
%token SCHEDULE_SYM
%token SECOND_MICROSECOND_SYM
%token SECOND_SYM
%token SECURITY_SYM
......@@ -583,6 +591,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token SSL_SYM
%token STARTING
%token START_SYM
%token STARTS_SYM
%token STATUS_SYM
%token STD_SYM
%token STDDEV_SAMP_SYM
......@@ -676,6 +685,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token YEAR_SYM
%token ZEROFILL
%left JOIN_SYM INNER_SYM STRAIGHT_JOIN CROSS LEFT RIGHT
/* A dummy token to force the priority of table_ref production in a join. */
%left TABLE_REF_PRIORITY
......@@ -857,6 +867,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
END_OF_INPUT
%type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
%type <NONE> sp_proc_stmt_statement sp_proc_stmt_return
%type <NONE> sp_proc_stmt_if sp_proc_stmt_case_simple sp_proc_stmt_case
%type <NONE> sp_labeled_control sp_proc_stmt_unlabeled sp_proc_stmt_leave
%type <NONE> sp_proc_stmt_iterate sp_proc_stmt_label sp_proc_stmt_goto
%type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close
%type <num> sp_decl_idents sp_opt_inout sp_handler_type sp_hcond_list
%type <spcondtype> sp_cond sp_hcond
%type <spblock> sp_decls sp_decl
......@@ -1295,6 +1311,212 @@ create:
{
Lex->sql_command = SQLCOM_CREATE_USER;
}
| CREATE EVENT_SYM opt_if_not_exists sp_name
{
LEX *lex=Lex;
event_timed *et;
if (lex->et)
{
// ToDo Andrey : Change the error message
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "EVENT");
YYABORT;
}
lex->create_info.options=$3;
et= new event_timed();// implicitly calls event_timed::init()
lex->et = et;
if (!lex->et_compile_phase)
et->init_name(YYTHD, $4);
/*
We have to turn of CLIENT_MULTI_QUERIES while parsing a
stored procedure, otherwise yylex will chop it into pieces
at each ';'.
*/
et->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES;
lex->sphead= 0;
}
ON SCHEDULE_SYM ev_schedule_time
ev_on_completion
ev_status
ev_comment
DO_SYM ev_sql_stmt
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_CREATE_EVENT;
}
;
ev_schedule_time: EVERY_SYM expr interval
{
LEX *lex=Lex;
if (!lex->et_compile_phase)
{
switch (lex->et->init_interval(YYTHD , $2, $3)) {
case EVEX_PARSE_ERROR:
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
break;
case EVEX_BAD_PARAMS:
my_error(ER_EVENT_INTERVAL_NOT_POSITIVE, MYF(0));
YYABORT;
break;
}
}
}
ev_starts
ev_ends
| AT_SYM expr
{
LEX *lex=Lex;
if (!lex->et_compile_phase)
{
switch (lex->et->init_execute_at(YYTHD, $2)) {
case EVEX_PARSE_ERROR:
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
break;
case EVEX_BAD_PARAMS:
my_error(ER_EVENT_EXEC_TIME_IN_THE_PAST, MYF(0));
YYABORT;
break;
}
}
}
;
ev_status: /* empty */
| ENABLE_SYM
{
LEX *lex=Lex;
if (!lex->et_compile_phase)
lex->et->set_event_status(1);
}
| DISABLE_SYM
{
LEX *lex=Lex;
if (!lex->et_compile_phase)
lex->et->set_event_status(0);
}
;
ev_starts: /* empty */
| STARTS_SYM expr
{
LEX *lex= Lex;
if (!lex->et_compile_phase)
lex->et->init_starts(YYTHD, $2);
}
;
ev_ends: /* empty */
| ENDS_SYM expr
{
LEX *lex= Lex;
if (!lex->et_compile_phase)
{
switch (lex->et->init_ends(YYTHD, $2)) {
case EVEX_PARSE_ERROR:
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
break;
case EVEX_BAD_PARAMS:
my_error(ER_EVENT_ENDS_BEFORE_STARTS, MYF(0));
YYABORT;
break;
}
}
}
;
ev_on_completion: /* empty */
| ON COMPLETION_SYM PRESERVE_SYM
{
LEX *lex=Lex;
if (!lex->et_compile_phase)
lex->et->set_on_completion_drop(false);
}
| ON COMPLETION_SYM NOT_SYM PRESERVE_SYM
{
LEX *lex=Lex;
if (!lex->et_compile_phase)
lex->et->set_on_completion_drop(true);
}
;
ev_comment: /* empty */
| COMMENT_SYM TEXT_STRING_sys
{
LEX *lex= Lex;
if (!lex->et_compile_phase)
{
lex->comment= $2;
lex->et->init_comment(YYTHD, &$2);
}
}
;
ev_sql_stmt:
{
LEX *lex= Lex;
sp_head *sp;
if (!(sp= new sp_head()))
YYABORT;
sp->reset_thd_mem_root(YYTHD);
sp->init(lex);
sp->m_type= TYPE_ENUM_PROCEDURE;
lex->sphead= sp;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
lex->sphead->m_chistics= &lex->sp_chistics;
lex->sphead->m_body_begin= lex->ptr;
if (!lex->et_compile_phase)
lex->et->m_body_begin= lex->ptr;
}
ev_sql_stmt_inner
{
LEX *lex=Lex;
sp_head *sp= lex->sphead;
// return back to the original memory root ASAP
sp->init_strings(YYTHD, lex, NULL);
sp->restore_thd_mem_root(YYTHD);
lex->sp_chistics.suid= SP_IS_SUID;//always the definer!
// Restore flag if it was cleared above
if (lex->et->m_old_cmq)
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
if (!lex->et_compile_phase)
{
lex->et->init_body(YYTHD);
lex->et->init_definer(YYTHD);
}
}
;
ev_sql_stmt_inner:
sp_proc_stmt_statement
| sp_proc_stmt_return
| sp_proc_stmt_if
| sp_proc_stmt_case_simple
| sp_proc_stmt_case
| sp_labeled_control {}
| sp_proc_stmt_unlabeled
| sp_proc_stmt_leave
| sp_proc_stmt_iterate
| sp_proc_stmt_label
| sp_proc_stmt_goto
| sp_proc_stmt_open
| sp_proc_stmt_fetch
| sp_proc_stmt_close
;
clear_privileges:
......@@ -1905,6 +2127,28 @@ sp_opt_default:
;
sp_proc_stmt:
sp_proc_stmt_statement
| sp_proc_stmt_return
| sp_proc_stmt_if
| sp_proc_stmt_case_simple
| sp_proc_stmt_case
| sp_labeled_control
{}
| sp_proc_stmt_unlabeled
| sp_proc_stmt_leave
| sp_proc_stmt_iterate
| sp_proc_stmt_label
| sp_proc_stmt_goto
| sp_proc_stmt_open
| sp_proc_stmt_fetch
| sp_proc_stmt_close
;
sp_proc_stmt_if:
IF sp_if END IF {}
;
sp_proc_stmt_statement:
{
LEX *lex= Lex;
......@@ -1947,7 +2191,10 @@ sp_proc_stmt:
}
sp->restore_lex(YYTHD);
}
| RETURN_SYM
;
sp_proc_stmt_return:
RETURN_SYM
{ Lex->sphead->reset_lex(YYTHD); }
expr
{
......@@ -1970,13 +2217,18 @@ sp_proc_stmt:
}
sp->restore_lex(YYTHD);
}
| IF sp_if END IF {}
| CASE_SYM WHEN_SYM
;
sp_proc_stmt_case_simple:
CASE_SYM WHEN_SYM
{
Lex->sphead->m_flags&= ~sp_head::IN_SIMPLE_CASE;
}
sp_case END CASE_SYM {}
| CASE_SYM
;
sp_proc_stmt_case:
CASE_SYM
{ Lex->sphead->reset_lex(YYTHD); }
expr WHEN_SYM
{
......@@ -2000,9 +2252,10 @@ sp_proc_stmt:
{
Lex->spcont->pop_pvar();
}
| sp_labeled_control
{}
| { /* Unlabeled controls get a secret label. */
;
sp_proc_stmt_unlabeled:
{ /* Unlabeled controls get a secret label. */
LEX *lex= Lex;
lex->spcont->push_label((char *)"", lex->sphead->instructions());
......@@ -2013,7 +2266,10 @@ sp_proc_stmt:
lex->sphead->backpatch(lex->spcont->pop_label());
}
| LEAVE_SYM label_ident
;
sp_proc_stmt_leave:
LEAVE_SYM label_ident
{
LEX *lex= Lex;
sp_head *sp = lex->sphead;
......@@ -2043,7 +2299,10 @@ sp_proc_stmt:
sp->add_instr(i);
}
}
| ITERATE_SYM label_ident
;
sp_proc_stmt_iterate:
ITERATE_SYM label_ident
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
......@@ -2071,7 +2330,10 @@ sp_proc_stmt:
sp->add_instr(i);
}
}
| LABEL_SYM IDENT
;
sp_proc_stmt_label:
LABEL_SYM IDENT
{
#ifdef SP_GOTO
LEX *lex= Lex;
......@@ -2096,7 +2358,10 @@ sp_proc_stmt:
YYABORT;
#endif
}
| GOTO_SYM IDENT
;
sp_proc_stmt_goto:
GOTO_SYM IDENT
{
#ifdef SP_GOTO
LEX *lex= Lex;
......@@ -2156,7 +2421,10 @@ sp_proc_stmt:
YYABORT;
#endif
}
| OPEN_SYM ident
;
sp_proc_stmt_open:
OPEN_SYM ident
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
......@@ -2171,7 +2439,10 @@ sp_proc_stmt:
i= new sp_instr_copen(sp->instructions(), lex->spcont, offset);
sp->add_instr(i);
}
| FETCH_SYM sp_opt_fetch_noise ident INTO
;
sp_proc_stmt_fetch:
FETCH_SYM sp_opt_fetch_noise ident INTO
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
......@@ -2188,7 +2459,10 @@ sp_proc_stmt:
}
sp_fetch_list
{ }
| CLOSE_SYM ident
;
sp_proc_stmt_close:
CLOSE_SYM ident
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
......@@ -3913,6 +4187,62 @@ alter:
}
view_list_opt AS view_select view_check_option
{}
| ALTER EVENT_SYM sp_name
{
LEX *lex=Lex;
event_timed *et;
if (lex->et)
{
// ToDo Andrey : Change the error message
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "EVENT");
YYABORT;
}
lex->spname= 0;//defensive
et= new event_timed();// implicitly calls event_timed::init()
lex->et = et;
et->init_name(YYTHD, $3);
/*
We have to turn of CLIENT_MULTI_QUERIES while parsing a
stored procedure, otherwise yylex will chop it into pieces
at each ';'.
*/
et->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES;
/*
defensive. in sql_parse.cc it is checked whether is not null
and then deleted
*/
lex->sphead= 0;
}
ev_on_schedule
ev_rename_to
ev_on_completion
ev_status
ev_comment
ev_opt_sql_stmt
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_ALTER_EVENT;
}
;
ev_on_schedule: /* empty */
| ON SCHEDULE_SYM ev_schedule_time;
ev_opt_sql_stmt: /* empty*/
| DO_SYM ev_sql_stmt;
ev_rename_to: /* empty */
| RENAME TO_SYM sp_name
{
LEX *lex=Lex;
lex->spname= $3; //use lex's spname to hold the new name
//the original name is in the event_timed object
}
;
ident_or_empty:
......@@ -6620,6 +6950,25 @@ drop:
lex->sql_command= SQLCOM_DROP_TRIGGER;
lex->spname= $3;
}
| DROP EVENT_SYM if_exists sp_name
{
LEX *lex=Lex;
event_timed *et;
if (lex->et)
{
// ToDo Andrey : Change the error message
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "EVENT");
YYABORT;
}
et= new event_timed;
lex->et = et;
et->init_name(YYTHD, $4);
lex->sql_command = SQLCOM_DROP_EVENT;
lex->drop_if_exists= $3;
}
;
table_list:
......@@ -7272,6 +7621,13 @@ show_param:
Lex->spname= $3;
#endif
}
| CREATE EVENT_SYM sp_name
{
LEX *lex= Lex;
lex->sql_command = SQLCOM_SHOW_CREATE_EVENT;
lex->spname= $3;
};
;
show_engine_param:
......@@ -8159,6 +8515,7 @@ keyword_sp:
| AGGREGATE_SYM {}
| ALGORITHM_SYM {}
| ANY_SYM {}
| AT_SYM {}
| AUTO_INC {}
| AVG_ROW_LENGTH {}
| AVG_SYM {}
......@@ -8179,6 +8536,7 @@ keyword_sp:
| COLUMNS {}
| COMMITTED_SYM {}
| COMPACT_SYM {}
| COMPLETION_SYM {}
| COMPRESSED_SYM {}
| CONCURRENT {}
| CONSISTENT_SYM {}
......@@ -8195,12 +8553,15 @@ keyword_sp:
| DUMPFILE {}
| DUPLICATE_SYM {}
| DYNAMIC_SYM {}
| ENDS_SYM {}
| ENUM {}
| ENGINE_SYM {}
| ENGINES_SYM {}
| ERRORS {}
| ESCAPE_SYM {}
| EVENT_SYM {}
| EVENTS_SYM {}
| EVERY_SYM {}
| EXPANSION_SYM {}
| EXTENDED_SYM {}
| FAST_SYM {}
......@@ -8293,6 +8654,7 @@ keyword_sp:
| PHASE_SYM {}
| POINT_SYM {}
| POLYGON {}
| PRESERVE_SYM {}
| PREV_SYM {}
| PRIVILEGES {}
| PROCESS {}
......@@ -8322,6 +8684,7 @@ keyword_sp:
| ROW_FORMAT_SYM {}
| ROW_SYM {}
| RTREE_SYM {}
| SCHEDULE_SYM {}
| SECOND_SYM {}
| SERIAL_SYM {}
| SERIALIZABLE_SYM {}
......@@ -8335,6 +8698,7 @@ keyword_sp:
| SQL_BUFFER_RESULT {}
| SQL_NO_CACHE_SYM {}
| SQL_THREAD {}
| STARTS_SYM {}
| STATUS_SYM {}
| STORAGE_SYM {}
| STRING_SYM {}
......@@ -9061,6 +9425,7 @@ object_privilege:
| CREATE ROUTINE_SYM { Lex->grant |= CREATE_PROC_ACL; }
| ALTER ROUTINE_SYM { Lex->grant |= ALTER_PROC_ACL; }
| CREATE USER { Lex->grant |= CREATE_USER_ACL; }
| EVENT_SYM { Lex->grant |= EVENT_ACL;}
;
......
......@@ -282,7 +282,8 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags)
*/
if (share->db.length == 5 &&
!my_strcasecmp(system_charset_info, share->db.str, "mysql") &&
!my_strcasecmp(system_charset_info, share->table_name.str, "proc"))
(!my_strcasecmp(system_charset_info, share->table_name.str, "proc") ||
!my_strcasecmp(system_charset_info, share->table_name.str, "event")))
share->system_table= 1;
error_given= 1;
}
......
......@@ -807,6 +807,18 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec)
}
/*
Works like sec_since_epoch but expects TIME structure as parameter.
*/
my_time_t
sec_since_epoch_TIME(TIME *t)
{
return sec_since_epoch(t->year, t->month, t->day,
t->hour, t->minute, t->second);
}
/*
Converts local time in broken down TIME representation to my_time_t
representation.
......
......@@ -64,6 +64,7 @@ extern Time_zone * my_tz_find(const String *name, TABLE_LIST *tz_tables);
extern Time_zone * my_tz_find_with_opening_tz_tables(THD *thd, const String *name);
extern my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap);
extern void my_tz_free();
my_time_t sec_since_epoch_TIME(TIME *t);
extern TABLE_LIST fake_time_zone_tables_list;
......
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