summaryrefslogtreecommitdiff
path: root/sql/event_db_repository.cc
diff options
context:
space:
mode:
authorunknown <andrey@lmy004.>2006-06-28 14:22:14 +0200
committerunknown <andrey@lmy004.>2006-06-28 14:22:14 +0200
commit8ca78787a54f5d86f23147ca734e8e167a56b7b4 (patch)
tree5f8ea7fe8597821677207641a35819493c44dedd /sql/event_db_repository.cc
parentacefb78bc3fbf28376d8713e1dc9f056dc3cdbf6 (diff)
downloadmariadb-git-8ca78787a54f5d86f23147ca734e8e167a56b7b4.tar.gz
WL#3337 (Events new architecture)
Cut number 6. Move code from sql_show.cc to event_db_repository.cc that more belongs to the latter. sql/event_db_repository.cc: move code that works with mysql.event from sql_show.cc to event_db_repository.cc . Route through Event_db_repository's interface which is proxied by class Events. The code relies on a function from sql_show.cc which does the actual storage in the schema table. I think it's better to leave the function there because the structure of I_S.EVENTS is defined in sql_show.cc sql/event_db_repository.h: I_S / SHOW EVENTS handling hooks sql/event_scheduler.cc: use the pointer to db_repository which Event_scheduler already has sql/events.cc: Put a comment to get_instance sql/events.h: callback for I_S (sql_show.cc) sql/sql_show.cc: move code that belongs more to Event_db_repository than to here. Use a callback of class Events. Only 1 function is left here, because it copies data into the actual rows of I_S.EVENTS and belongs to this file. sql/sql_show.h: export this function will be called from event_db_repository.cc
Diffstat (limited to 'sql/event_db_repository.cc')
-rw-r--r--sql/event_db_repository.cc173
1 files changed, 169 insertions, 4 deletions
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index 249910c5f50..96d2b6c957f 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -20,6 +20,7 @@
#include "sp_head.h"
#include "sp.h"
#include "events.h"
+#include "sql_show.h"
#define EVEX_DB_FIELD_LEN 64
#define EVEX_NAME_FIELD_LEN 64
@@ -188,8 +189,7 @@ evex_fill_row(THD *thd, TABLE *table, Event_timed *et, my_bool is_update)
if (et->expression)
{
table->field[ET_FIELD_INTERVAL_EXPR]->set_notnull();
- table->field[ET_FIELD_INTERVAL_EXPR]->
- store((longlong)et->expression, true);
+ table->field[ET_FIELD_INTERVAL_EXPR]->store((longlong)et->expression, true);
table->field[ET_FIELD_TRANSIENT_INTERVAL]->set_notnull();
/*
@@ -277,15 +277,180 @@ evex_db_find_event_by_name(THD *thd, const LEX_STRING dbname,
/*
+ Performs an index scan of event_table (mysql.event) and fills schema_table.
+
+ Synopsis
+ Event_db_repository::index_read_for_db_for_i_s()
+ thd Thread
+ schema_table The I_S.EVENTS table
+ event_table The event table to use for loading (mysql.event)
+
+ Returns
+ 0 OK
+ 1 Error
+*/
+
+int
+Event_db_repository::index_read_for_db_for_i_s(THD *thd, TABLE *schema_table,
+ TABLE *event_table, char *db)
+{
+ int ret=0;
+ CHARSET_INFO *scs= system_charset_info;
+ KEY *key_info;
+ uint key_len;
+ byte *key_buf= NULL;
+ LINT_INIT(key_buf);
+
+ DBUG_ENTER("Event_db_repository::index_read_for_db_for_i_s");
+
+ DBUG_PRINT("info", ("Using prefix scanning on PK"));
+ event_table->file->ha_index_init(0, 1);
+ event_table->field[ET_FIELD_DB]->store(db, strlen(db), scs);
+ key_info= event_table->key_info;
+ key_len= key_info->key_part[0].store_length;
+
+ if (!(key_buf= (byte *)alloc_root(thd->mem_root, key_len)))
+ {
+ ret= 1;
+ /* don't send error, it would be done by sql_alloc_error_handler() */
+ }
+ else
+ {
+ key_copy(key_buf, event_table->record[0], key_info, key_len);
+ if (!(ret= event_table->file->index_read(event_table->record[0], key_buf,
+ key_len, HA_READ_PREFIX)))
+ {
+ DBUG_PRINT("info",("Found rows. Let's retrieve them. ret=%d", ret));
+ do
+ {
+ ret= copy_event_to_schema_table(thd, schema_table, event_table);
+ if (ret == 0)
+ ret= event_table->file->index_next_same(event_table->record[0],
+ key_buf, key_len);
+ } while (ret == 0);
+ }
+ DBUG_PRINT("info", ("Scan finished. ret=%d", ret));
+ }
+ event_table->file->ha_index_end();
+ /* ret is guaranteed to be != 0 */
+ if (ret == HA_ERR_END_OF_FILE || ret == HA_ERR_KEY_NOT_FOUND)
+ DBUG_RETURN(0);
+ DBUG_RETURN(1);
+}
+
+
+/*
+ Performs a table scan of event_table (mysql.event) and fills schema_table.
+
+ Synopsis
+ Events_db_repository::table_scan_all_for_i_s()
+ thd Thread
+ schema_table The I_S.EVENTS in memory table
+ event_table The event table to use for loading.
+
+ Returns
+ 0 OK
+ 1 Error
+*/
+
+int
+Event_db_repository::table_scan_all_for_i_s(THD *thd, TABLE *schema_table,
+ TABLE *event_table)
+{
+ int ret;
+ READ_RECORD read_record_info;
+
+ DBUG_ENTER("Event_db_repository::table_scan_all_for_i_s");
+ init_read_record(&read_record_info, thd, event_table, NULL, 1, 0);
+
+ /*
+ rr_sequential, in read_record(), returns 137==HA_ERR_END_OF_FILE,
+ but rr_handle_error returns -1 for that reason. Thus, read_record()
+ returns -1 eventually.
+ */
+ do
+ {
+ ret= read_record_info.read_record(&read_record_info);
+ if (ret == 0)
+ ret= copy_event_to_schema_table(thd, schema_table, event_table);
+ }
+ while (ret == 0);
+
+ DBUG_PRINT("info", ("Scan finished. ret=%d", ret));
+ end_read_record(&read_record_info);
+
+ /* ret is guaranteed to be != 0 */
+ DBUG_RETURN(ret == -1? 0:1);
+}
+
+
+/*
+ Fills I_S.EVENTS with data loaded from mysql.event. Also used by
+ SHOW EVENTS
+
+ Synopsis
+ Event_db_repository::fill_schema_events()
+ thd Thread
+ tables The schema table
+ db If not NULL then get events only from this schema
+
+ Returns
+ 0 OK
+ 1 Error
+*/
+
+int
+Event_db_repository::fill_schema_events(THD *thd, TABLE_LIST *tables, char *db)
+{
+ TABLE *schema_table= tables->table;
+ TABLE *event_table= NULL;
+ Open_tables_state backup;
+ int ret= 0;
+
+ DBUG_ENTER("Event_db_repository::fill_schema_events");
+ DBUG_PRINT("info",("db=%s", db? db:"(null)"));
+
+ thd->reset_n_backup_open_tables_state(&backup);
+ if (open_event_table(thd, TL_READ, &event_table))
+ {
+ sql_print_error("Table mysql.event is damaged.");
+ thd->restore_backup_open_tables_state(&backup);
+ DBUG_RETURN(1);
+ }
+
+ /*
+ 1. SELECT I_S => use table scan. I_S.EVENTS does not guarantee order
+ thus we won't order it. OTOH, SHOW EVENTS will be
+ ordered.
+ 2. SHOW EVENTS => PRIMARY KEY with prefix scanning on (db)
+ Reasoning: Events are per schema, therefore a scan over an index
+ will save use from doing a table scan and comparing
+ every single row's `db` with the schema which we show.
+ */
+ if (db)
+ ret= index_read_for_db_for_i_s(thd, schema_table, event_table, db);
+ else
+ ret= table_scan_all_for_i_s(thd, schema_table, event_table);
+
+ close_thread_tables(thd);
+ thd->restore_backup_open_tables_state(&backup);
+
+ DBUG_PRINT("info", ("Return code=%d", ret));
+ DBUG_RETURN(ret);
+}
+
+
+/*
Looks for a named event in mysql.event and in case of success returns
an object will data loaded from the table.
SYNOPSIS
- db_find_event()
+ Event_db_repository::find_event()
thd THD
name the name of the event to find
ett event's data if event is found
tbl TABLE object to use when not NULL
+ root On which root to load the event
NOTES
1) Use sp_name for look up, return in **ett if found
@@ -308,7 +473,7 @@ Event_db_repository::find_event(THD *thd, sp_name *name, Event_timed **ett,
if (tbl)
table= tbl;
- else if (Events::get_instance()->db_repository.open_event_table(thd, TL_READ, &table))
+ else if (open_event_table(thd, TL_READ, &table))
{
my_error(ER_EVENT_OPEN_TABLE_FAILED, MYF(0));
ret= EVEX_GENERAL_ERROR;