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
This commit is contained in:
parent
acefb78bc3
commit
8ca78787a5
@ -20,6 +20,7 @@
|
|||||||
#include "sp_head.h"
|
#include "sp_head.h"
|
||||||
#include "sp.h"
|
#include "sp.h"
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
|
#include "sql_show.h"
|
||||||
|
|
||||||
#define EVEX_DB_FIELD_LEN 64
|
#define EVEX_DB_FIELD_LEN 64
|
||||||
#define EVEX_NAME_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)
|
if (et->expression)
|
||||||
{
|
{
|
||||||
table->field[ET_FIELD_INTERVAL_EXPR]->set_notnull();
|
table->field[ET_FIELD_INTERVAL_EXPR]->set_notnull();
|
||||||
table->field[ET_FIELD_INTERVAL_EXPR]->
|
table->field[ET_FIELD_INTERVAL_EXPR]->store((longlong)et->expression, true);
|
||||||
store((longlong)et->expression, true);
|
|
||||||
|
|
||||||
table->field[ET_FIELD_TRANSIENT_INTERVAL]->set_notnull();
|
table->field[ET_FIELD_TRANSIENT_INTERVAL]->set_notnull();
|
||||||
/*
|
/*
|
||||||
@ -276,16 +276,181 @@ 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
|
Looks for a named event in mysql.event and in case of success returns
|
||||||
an object will data loaded from the table.
|
an object will data loaded from the table.
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
db_find_event()
|
Event_db_repository::find_event()
|
||||||
thd THD
|
thd THD
|
||||||
name the name of the event to find
|
name the name of the event to find
|
||||||
ett event's data if event is found
|
ett event's data if event is found
|
||||||
tbl TABLE object to use when not NULL
|
tbl TABLE object to use when not NULL
|
||||||
|
root On which root to load the event
|
||||||
|
|
||||||
NOTES
|
NOTES
|
||||||
1) Use sp_name for look up, return in **ett if found
|
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)
|
if (tbl)
|
||||||
table= 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));
|
my_error(ER_EVENT_OPEN_TABLE_FAILED, MYF(0));
|
||||||
ret= EVEX_GENERAL_ERROR;
|
ret= EVEX_GENERAL_ERROR;
|
||||||
|
@ -43,6 +43,17 @@ evex_db_find_event_by_name(THD *thd, const LEX_STRING dbname,
|
|||||||
const LEX_STRING ev_name,
|
const LEX_STRING ev_name,
|
||||||
TABLE *table);
|
TABLE *table);
|
||||||
|
|
||||||
|
int
|
||||||
|
events_table_index_read_for_db(THD *thd, TABLE *schema_table,
|
||||||
|
TABLE *event_table);
|
||||||
|
|
||||||
|
int
|
||||||
|
events_table_scan_all(THD *thd, TABLE *schema_table, TABLE *event_table);
|
||||||
|
|
||||||
|
int
|
||||||
|
fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */);
|
||||||
|
|
||||||
|
|
||||||
class Event_queue_element;
|
class Event_queue_element;
|
||||||
|
|
||||||
class Event_db_repository
|
class Event_db_repository
|
||||||
@ -57,9 +68,6 @@ public:
|
|||||||
void
|
void
|
||||||
deinit_repository();
|
deinit_repository();
|
||||||
|
|
||||||
int
|
|
||||||
open_event_table(THD *thd, enum thr_lock_type lock_type, TABLE **table);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
create_event(THD *thd, Event_timed *et, my_bool create_if_not,
|
create_event(THD *thd, Event_timed *et, my_bool create_if_not,
|
||||||
uint *rows_affected);
|
uint *rows_affected);
|
||||||
@ -86,11 +94,23 @@ public:
|
|||||||
|
|
||||||
int
|
int
|
||||||
find_event_by_name(THD *thd, LEX_STRING db, LEX_STRING name, TABLE *table);
|
find_event_by_name(THD *thd, LEX_STRING db, LEX_STRING name, TABLE *table);
|
||||||
private:
|
|
||||||
|
|
||||||
|
int
|
||||||
|
open_event_table(THD *thd, enum thr_lock_type lock_type, TABLE **table);
|
||||||
|
|
||||||
|
int
|
||||||
|
fill_schema_events(THD *thd, TABLE_LIST *tables, char *db);
|
||||||
|
|
||||||
|
private:
|
||||||
int
|
int
|
||||||
drop_events_by_field(THD *thd, enum enum_events_table_field field,
|
drop_events_by_field(THD *thd, enum enum_events_table_field field,
|
||||||
LEX_STRING field_value);
|
LEX_STRING field_value);
|
||||||
|
int
|
||||||
|
index_read_for_db_for_i_s(THD *thd, TABLE *schema_table, TABLE *event_table,
|
||||||
|
char *db);
|
||||||
|
|
||||||
|
int
|
||||||
|
table_scan_all_for_i_s(THD *thd, TABLE *schema_table, TABLE *event_table);
|
||||||
|
|
||||||
MEM_ROOT repo_root;
|
MEM_ROOT repo_root;
|
||||||
|
|
||||||
|
@ -2159,7 +2159,7 @@ Event_scheduler::load_events_from_db(THD *thd)
|
|||||||
DBUG_RETURN(EVEX_GENERAL_ERROR);
|
DBUG_RETURN(EVEX_GENERAL_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret= Events::get_instance()->open_event_table(thd, TL_READ, &table)))
|
if ((ret= db_repository->open_event_table(thd, TL_READ, &table)))
|
||||||
{
|
{
|
||||||
sql_print_error("SCHEDULER: Table mysql.event is damaged. Can not open.");
|
sql_print_error("SCHEDULER: Table mysql.event is damaged. Can not open.");
|
||||||
DBUG_RETURN(EVEX_OPEN_TABLE_FAILED);
|
DBUG_RETURN(EVEX_OPEN_TABLE_FAILED);
|
||||||
|
@ -88,6 +88,15 @@ int sortcmp_lex_string(LEX_STRING s, LEX_STRING t, CHARSET_INFO *cs)
|
|||||||
(unsigned char *) t.str,t.length, 0);
|
(unsigned char *) t.str,t.length, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Accessor for the singleton instance.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
Events::get_instance()
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
address
|
||||||
|
*/
|
||||||
|
|
||||||
Events *
|
Events *
|
||||||
Events::get_instance()
|
Events::get_instance()
|
||||||
@ -110,7 +119,7 @@ Events::get_instance()
|
|||||||
interval - the interval type (for instance YEAR_MONTH)
|
interval - the interval type (for instance YEAR_MONTH)
|
||||||
expression - the value in the lowest entity
|
expression - the value in the lowest entity
|
||||||
|
|
||||||
RETURNS
|
RETURN VALUE
|
||||||
0 - OK
|
0 - OK
|
||||||
1 - Error
|
1 - Error
|
||||||
*/
|
*/
|
||||||
@ -562,6 +571,42 @@ Events::dump_internal_status(THD *thd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Proxy for Event_db_repository::fill_schema_events.
|
||||||
|
Callback for I_S from sql_show.cc
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
Events::fill_schema_events()
|
||||||
|
thd Thread
|
||||||
|
tables The schema table
|
||||||
|
cond Unused
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
0 OK
|
||||||
|
!0 Error
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */)
|
||||||
|
{
|
||||||
|
char *db= NULL;
|
||||||
|
DBUG_ENTER("Events::fill_schema_events");
|
||||||
|
/*
|
||||||
|
If it's SHOW EVENTS then thd->lex->select_lex.db is guaranteed not to
|
||||||
|
be NULL. Let's do an assert anyway.
|
||||||
|
*/
|
||||||
|
if (thd->lex->orig_sql_command == SQLCOM_SHOW_EVENTS)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(thd->lex->select_lex.db);
|
||||||
|
if (check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0,
|
||||||
|
is_schema_db(thd->lex->select_lex.db)))
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
db= thd->lex->select_lex.db;
|
||||||
|
}
|
||||||
|
DBUG_RETURN(get_instance()->db_repository.fill_schema_events(thd, tables, db));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Inits Events mutexes
|
Inits Events mutexes
|
||||||
|
|
||||||
|
@ -90,6 +90,9 @@ public:
|
|||||||
|
|
||||||
int
|
int
|
||||||
drop_schema_events(THD *thd, char *db);
|
drop_schema_events(THD *thd, char *db);
|
||||||
|
|
||||||
|
static int
|
||||||
|
fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */);
|
||||||
|
|
||||||
int
|
int
|
||||||
dump_internal_status(THD *thd);
|
dump_internal_status(THD *thd);
|
||||||
|
181
sql/sql_show.cc
181
sql/sql_show.cc
@ -4160,7 +4160,7 @@ extern LEX_STRING interval_type_to_name[];
|
|||||||
1 Error
|
1 Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
int
|
||||||
copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
|
copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
|
||||||
{
|
{
|
||||||
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
|
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
|
||||||
@ -4295,183 +4295,6 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Performs an index scan of event_table (mysql.event) and fills schema_table.
|
|
||||||
|
|
||||||
Synopsis
|
|
||||||
events_table_index_read_for_db()
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
|
|
||||||
static
|
|
||||||
int events_table_index_read_for_db(THD *thd, TABLE *schema_table,
|
|
||||||
TABLE *event_table)
|
|
||||||
{
|
|
||||||
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("schema_events_do_index_scan");
|
|
||||||
|
|
||||||
DBUG_PRINT("info", ("Using prefix scanning on PK"));
|
|
||||||
event_table->file->ha_index_init(0, 1);
|
|
||||||
event_table->field[ET_FIELD_DB]->
|
|
||||||
store(thd->lex->select_lex.db, strlen(thd->lex->select_lex.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_table_scan_all()
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
|
|
||||||
static
|
|
||||||
int events_table_scan_all(THD *thd, TABLE *schema_table,
|
|
||||||
TABLE *event_table)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
READ_RECORD read_record_info;
|
|
||||||
|
|
||||||
DBUG_ENTER("schema_events_do_table_scan");
|
|
||||||
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
|
|
||||||
fill_schema_events()
|
|
||||||
thd Thread
|
|
||||||
tables The schema table
|
|
||||||
cond Unused
|
|
||||||
|
|
||||||
Returns
|
|
||||||
0 OK
|
|
||||||
1 Error
|
|
||||||
*/
|
|
||||||
|
|
||||||
int fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */)
|
|
||||||
{
|
|
||||||
TABLE *schema_table= tables->table;
|
|
||||||
TABLE *event_table= NULL;
|
|
||||||
Open_tables_state backup;
|
|
||||||
int ret= 0;
|
|
||||||
|
|
||||||
DBUG_ENTER("fill_schema_events");
|
|
||||||
/*
|
|
||||||
If it's SHOW EVENTS then thd->lex->select_lex.db is guaranteed not to
|
|
||||||
be NULL. Let's do an assert anyway.
|
|
||||||
*/
|
|
||||||
if (thd->lex->orig_sql_command == SQLCOM_SHOW_EVENTS)
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(thd->lex->select_lex.db);
|
|
||||||
if (check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0,
|
|
||||||
is_schema_db(thd->lex->select_lex.db)))
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
DBUG_PRINT("info",("db=%s", thd->lex->select_lex.db?
|
|
||||||
thd->lex->select_lex.db:"(null)"));
|
|
||||||
|
|
||||||
thd->reset_n_backup_open_tables_state(&backup);
|
|
||||||
if (Events::get_instance()->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 (thd->lex->orig_sql_command == SQLCOM_SHOW_EVENTS)
|
|
||||||
ret= events_table_index_read_for_db(thd, schema_table, event_table);
|
|
||||||
else
|
|
||||||
ret= events_table_scan_all(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("fill_open_tables");
|
DBUG_ENTER("fill_open_tables");
|
||||||
@ -5568,7 +5391,7 @@ ST_SCHEMA_TABLE schema_tables[]=
|
|||||||
{"ENGINES", engines_fields_info, create_schema_table,
|
{"ENGINES", engines_fields_info, create_schema_table,
|
||||||
fill_schema_engines, make_old_format, 0, -1, -1, 0},
|
fill_schema_engines, make_old_format, 0, -1, -1, 0},
|
||||||
{"EVENTS", events_fields_info, create_schema_table,
|
{"EVENTS", events_fields_info, create_schema_table,
|
||||||
fill_schema_events, make_old_format, 0, -1, -1, 0},
|
Events::fill_schema_events, make_old_format, 0, -1, -1, 0},
|
||||||
{"FILES", files_fields_info, create_schema_table,
|
{"FILES", files_fields_info, create_schema_table,
|
||||||
fill_schema_files, 0, 0, -1, -1, 0},
|
fill_schema_files, 0, 0, -1, -1, 0},
|
||||||
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
|
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
|
||||||
|
@ -14,4 +14,6 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
|
|||||||
HA_CREATE_INFO *create_info_arg);
|
HA_CREATE_INFO *create_info_arg);
|
||||||
int view_store_create_info(THD *thd, TABLE_LIST *table, String *buff);
|
int view_store_create_info(THD *thd, TABLE_LIST *table, String *buff);
|
||||||
|
|
||||||
|
int copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table);
|
||||||
|
|
||||||
#endif /* SQL_SHOW_H */
|
#endif /* SQL_SHOW_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user