summaryrefslogtreecommitdiff
path: root/sql/event.cc
diff options
context:
space:
mode:
authorandrey@lmy004. <>2006-01-30 13:15:23 +0100
committerandrey@lmy004. <>2006-01-30 13:15:23 +0100
commitd847ac54caf4853d757c1f96a60b15cd2a338073 (patch)
tree85e23e401f2246d158fe3e4d023c5a02d3e89a6c /sql/event.cc
parent9a6bad5951922d922eebdc0d088e070d8697736a (diff)
downloadmariadb-git-d847ac54caf4853d757c1f96a60b15cd2a338073.tar.gz
fix for bug#16642 (Events: No INFORMATION_SCHEMA.EVENTS table)
post-review change - use pointer instead of copy on the stack. WL#1034 (Internal CRON) This patch adds INFORMATION_SCHEMA.EVENTS table with the following format: EVENT_CATALOG - MYSQL_TYPE_STRING (Always NULL) EVENT_SCHEMA - MYSQL_TYPE_STRING (the database) EVENT_NAME - MYSQL_TYPE_STRING (the name) DEFINER - MYSQL_TYPE_STRING (user@host) EVENT_BODY - MYSQL_TYPE_STRING (the body from mysql.event) EVENT_TYPE - MYSQL_TYPE_STRING ("ONE TIME" | "RECURRING") EXECUTE_AT - MYSQL_TYPE_TIMESTAMP (set for "ONE TIME" otherwise NULL) INTERVAL_VALUE - MYSQL_TYPE_LONG (set for RECURRING otherwise NULL) INTERVAL_FIELD - MYSQL_TYPE_STRING (set for RECURRING otherwise NULL) SQL_MODE - MYSQL_TYPE_STRING (for now NULL) STARTS - MYSQL_TYPE_TIMESTAMP (starts from mysql.event) ENDS - MYSQL_TYPE_TIMESTAMP (ends from mysql.event) STATUS - MYSQL_TYPE_STRING (ENABLED | DISABLED) ON_COMPLETION - MYSQL_TYPE_STRING (NOT PRESERVE | PRESERVE) CREATED - MYSQL_TYPE_TIMESTAMP LAST_ALTERED - MYSQL_TYPE_TIMESTAMP LAST_EXECUTED - MYSQL_TYPE_TIMESTAMP EVENT_COMMENT - MYSQL_TYPE_STRING SQL_MODE is NULL for now, because the value is still not stored in mysql.event . Support will be added as a fix for another bug. This patch also adds SHOW [FULL] EVENTS [FROM db] [LIKE pattern] 1. SHOW EVENTS shows always only the events on the same user, because the PK of mysql.event is (definer, db, name) several users may have event with the same name -> no information disclosure. 2. SHOW FULL EVENTS - shows the events (in the current db as SHOW EVENTS) of all users. The user has to have PROCESS privilege, if not then SHOW FULL EVENTS behave like SHOW EVENTS. 3. If [FROM db] is specified then this db is considered. 4. Event names can be filtered with LIKE pattern. SHOW EVENTS returns table with the following columns, which are subset of the data which is returned by SELECT * FROM I_S.EVENTS Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
Diffstat (limited to 'sql/event.cc')
-rw-r--r--sql/event.cc63
1 files changed, 41 insertions, 22 deletions
diff --git a/sql/event.cc b/sql/event.cc
index 6d62be903bd..5decbefe287 100644
--- a/sql/event.cc
+++ b/sql/event.cc
@@ -77,7 +77,7 @@ evex_queue_init(EVEX_QUEUE_TYPE *queue)
}
-static
+
int sortcmp_lex_string(LEX_STRING s, LEX_STRING t, CHARSET_INFO *cs)
{
return cs->coll->strnncollsp(cs, (unsigned char *) s.str,s.length,
@@ -176,7 +176,9 @@ evex_open_event_table(THD *thd, enum thr_lock_type lock_type, TABLE **table)
int
evex_db_find_event_aux(THD *thd, const LEX_STRING dbname,
- const LEX_STRING ev_name, TABLE *table)
+ const LEX_STRING ev_name,
+ const LEX_STRING user_name,
+ TABLE *table)
{
byte key[MAX_KEY_LENGTH];
DBUG_ENTER("evex_db_find_event_aux");
@@ -190,11 +192,17 @@ evex_db_find_event_aux(THD *thd, const LEX_STRING dbname,
same fields.
*/
if (dbname.length > table->field[EVEX_FIELD_DB]->field_length ||
- ev_name.length > table->field[EVEX_FIELD_NAME]->field_length)
+ ev_name.length > table->field[EVEX_FIELD_NAME]->field_length ||
+ user_name.length > table->field[EVEX_FIELD_DEFINER]->field_length)
+
DBUG_RETURN(EVEX_KEY_NOT_FOUND);
- table->field[0]->store(dbname.str, dbname.length, &my_charset_bin);
- table->field[1]->store(ev_name.str, ev_name.length, &my_charset_bin);
+ table->field[EVEX_FIELD_DB]->store(dbname.str, dbname.length, &my_charset_bin);
+ table->field[EVEX_FIELD_NAME]->store(ev_name.str, ev_name.length,
+ &my_charset_bin);
+ table->field[EVEX_FIELD_DEFINER]->store(user_name.str, user_name.length,
+ &my_charset_bin);
+
key_copy(key, table->record[0], table->key_info, table->key_info->key_length);
if (table->file->index_read_idx(table->record[0], 0, key,
@@ -283,10 +291,15 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update)
from 1. Thus +1 offset is needed!
*/
table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->store((longlong)et->interval+1);
+
+ table->field[EVEX_FIELD_EXECUTE_AT]->set_null();
}
else if (et->execute_at.year)
{
// fix_fields already called in init_execute_at
+ table->field[EVEX_FIELD_INTERVAL_EXPR]->set_null();
+ table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->set_null();
+
table->field[EVEX_FIELD_EXECUTE_AT]->set_notnull();
table->field[EVEX_FIELD_EXECUTE_AT]->store_time(&et->execute_at,
MYSQL_TIMESTAMP_DATETIME);
@@ -351,9 +364,9 @@ db_create_event(THD *thd, event_timed *et, my_bool create_if_not,
my_error(ER_EVENT_OPEN_TABLE_FAILED, MYF(0));
goto err;
}
-
+
DBUG_PRINT("info", ("check existance of an event with the same name"));
- if (!evex_db_find_event_aux(thd, et->dbname, et->name, table))
+ if (!evex_db_find_event_aux(thd, et->dbname, et->name, et->definer, table))
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_EVENT_ALREADY_EXISTS, ER(ER_EVENT_ALREADY_EXISTS),
@@ -398,10 +411,9 @@ db_create_event(THD *thd, event_timed *et, my_bool create_if_not,
goto err;
}
- strxmov(definer, et->definer_user.str, "@", et->definer_host.str, NullS);
- if ((ret=table->field[EVEX_FIELD_DEFINER]->
- store(definer, et->definer_user.length + 1 + et->definer_host.length,
- system_charset_info)))
+ if ((ret=table->field[EVEX_FIELD_DEFINER]->store(et->definer.str,
+ et->definer.length,
+ system_charset_info)))
{
my_error(ER_EVENT_STORE_FAILED, MYF(0), et->name.str, ret);
goto err;
@@ -464,7 +476,9 @@ db_update_event(THD *thd, event_timed *et, sp_name *new_name)
TABLE *table;
int ret= EVEX_OPEN_TABLE_FAILED;
DBUG_ENTER("db_update_event");
+ DBUG_PRINT("enter", ("dbname: %.*s", et->dbname.length, et->dbname.str));
DBUG_PRINT("enter", ("name: %.*s", et->name.length, et->name.str));
+ DBUG_PRINT("enter", ("user: %.*s", et->name.length, et->name.str));
if (new_name)
DBUG_PRINT("enter", ("rename to: %.*s", new_name->m_name.length,
new_name->m_name.str));
@@ -485,7 +499,8 @@ db_update_event(THD *thd, event_timed *et, sp_name *new_name)
goto err;
}
- if (!evex_db_find_event_aux(thd, new_name->m_db, new_name->m_name, table))
+ if (!evex_db_find_event_aux(thd, new_name->m_db, new_name->m_name,
+ et->definer, table))
{
my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), new_name->m_name.str);
goto err;
@@ -498,7 +513,7 @@ db_update_event(THD *thd, event_timed *et, sp_name *new_name)
row (copied into record[1] later
*/
if (EVEX_KEY_NOT_FOUND == evex_db_find_event_aux(thd, et->dbname, et->name,
- table))
+ et->definer, table))
{
my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), et->name.str);
goto err;
@@ -547,6 +562,7 @@ err:
db_find_event()
thd THD
name the name of the event to find
+ definer who owns the event
ett event's data if event is found
tbl TABLE object to use when not NULL
@@ -556,11 +572,11 @@ err:
*/
static int
-db_find_event(THD *thd, sp_name *name, event_timed **ett, TABLE *tbl)
+db_find_event(THD *thd, sp_name *name, LEX_STRING definer, event_timed **ett,
+ TABLE *tbl)
{
TABLE *table;
int ret;
- const char *definer;
char *ptr;
event_timed *et;
DBUG_ENTER("db_find_event");
@@ -575,7 +591,8 @@ db_find_event(THD *thd, sp_name *name, event_timed **ett, TABLE *tbl)
goto done;
}
- if ((ret= evex_db_find_event_aux(thd, name->m_db, name->m_name, table)))
+ if ((ret= evex_db_find_event_aux(thd, name->m_db, name->m_name, definer,
+ table)))
{
my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), name->m_name.str);
goto done;
@@ -616,6 +633,7 @@ done:
evex_load_and_compile_event()
thd THD
spn the name of the event to alter
+ definer who is the owner
use_lock whether to obtain a lock on LOCK_event_arrays or not
RETURN VALUE
@@ -625,7 +643,8 @@ done:
*/
static int
-evex_load_and_compile_event(THD * thd, sp_name *spn, bool use_lock)
+evex_load_and_compile_event(THD * thd, sp_name *spn, LEX_STRING definer,
+ bool use_lock)
{
int ret= 0;
MEM_ROOT *tmp_mem_root;
@@ -640,7 +659,7 @@ evex_load_and_compile_event(THD * thd, sp_name *spn, bool use_lock)
thd->reset_n_backup_open_tables_state(&backup);
// no need to use my_error() here because db_find_event() has done it
- if ((ret= db_find_event(thd, spn, &ett, NULL)))
+ if ((ret= db_find_event(thd, spn, definer, &ett, NULL)))
goto done;
thd->restore_backup_open_tables_state(&backup);
@@ -756,7 +775,7 @@ evex_create_event(THD *thd, event_timed *et, uint create_options,
if (evex_is_running && et->status == MYSQL_EVENT_ENABLED)
{
sp_name spn(et->dbname, et->name);
- ret= evex_load_and_compile_event(thd, &spn, true);
+ ret= evex_load_and_compile_event(thd, &spn, et->definer, true);
}
VOID(pthread_mutex_unlock(&LOCK_evex_running));
@@ -809,11 +828,11 @@ evex_update_event(THD *thd, event_timed *et, sp_name *new_name,
if (et->status == MYSQL_EVENT_ENABLED)
{
if (new_name)
- ret= evex_load_and_compile_event(thd, new_name, false);
+ ret= evex_load_and_compile_event(thd, new_name, et->definer, false);
else
{
sp_name spn(et->dbname, et->name);
- ret= evex_load_and_compile_event(thd, &spn, false);
+ ret= evex_load_and_compile_event(thd, &spn, et->definer, false);
}
if (ret == EVEX_COMPILE_ERROR)
my_error(ER_EVENT_COMPILE_ERROR, MYF(0));
@@ -851,7 +870,7 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists,
goto done;
}
- if (!(ret= evex_db_find_event_aux(thd, et->dbname, et->name, table)))
+ if (!(ret= evex_db_find_event_aux(thd, et->dbname,et->name,et->definer,table)))
{
if ((ret= table->file->ha_delete_row(table->record[0])))
{