Commit 7120d43c authored by andrey@lmy004's avatar andrey@lmy004

WL#1034 updated

- split into several files
- forbid parallel execution (before analyse is done how to make it possible)
  because the same sp_head instance cannot be executed in parallel
- added GPL headers
- changed EVENT_ACL to be per DB variable
- fixed minor problems
parent 96f9681c
...@@ -89,6 +89,7 @@ CREATE TABLE user ( ...@@ -89,6 +89,7 @@ CREATE TABLE user (
Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL,
ssl_cipher BLOB NOT NULL, ssl_cipher BLOB NOT NULL,
x509_issuer BLOB NOT NULL, x509_issuer BLOB NOT NULL,
...@@ -103,9 +104,9 @@ CHARACTER SET utf8 COLLATE utf8_bin ...@@ -103,9 +104,9 @@ CHARACTER SET utf8 COLLATE utf8_bin
comment='Users and global privileges'; comment='Users and global privileges';
INSERT INTO user VALUES ('localhost' ,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0); INSERT INTO user VALUES ('localhost' ,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
INSERT INTO user VALUES ('@HOSTNAME@%' ,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0); INSERT INTO user VALUES ('@HOSTNAME@%' ,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
REPLACE INTO user VALUES ('127.0.0.1' ,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0); REPLACE INTO user VALUES ('127.0.0.1' ,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
INSERT INTO user (host,user) VALUES ('localhost',''); INSERT INTO user (host,user) VALUES ('localhost','');
INSERT INTO user (host,user) VALUES ('@HOSTNAME@%',''); INSERT INTO user (host,user) VALUES ('@HOSTNAME@%','');
...@@ -566,3 +567,29 @@ CREATE TABLE proc ( ...@@ -566,3 +567,29 @@ CREATE TABLE proc (
comment char(64) collate utf8_bin DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL,
PRIMARY KEY (db,name,type) PRIMARY KEY (db,name,type)
) character set utf8 comment='Stored Procedures'; ) character set utf8 comment='Stored Procedures';
CREATE TABLE event (
'db' VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '',
'name' VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '',
'body' longblob NOT NULL,
'definer' VARCHAR(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '',
'execute_at' DATETIME default NULL,
'transient_expression' int(11) default NULL,
'interval_type' ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK',
'SECOND','MICROSECOND', 'YEAR_MONTH','DAY_HOUR',
'DAY_MINUTE','DAY_SECOND',
'HOUR_MINUTE','HOUR_SECOND',
'MINUTE_SECOND','DAY_MICROSECOND',
'HOUR_MICROSECOND','MINUTE_MICROSECOND',
'SECOND_MICROSECOND') default NULL,
'created' TIMESTAMP NOT NULL default '0000-00-00 00:00:00',
'modified' TIMESTAMP NOT NULL default '0000-00-00 00:00:00',
'last_executed' DATETIME default NULL,
'starts' DATETIME default NULL,
'ends' DATETIME default NULL,
'status' ENUM('ENABLED','DISABLED') NOT NULL default 'ENABLED',
'on_completion' ENUM('DROP','PRESERVE') NOT NULL default 'DROP',
'comment' varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '',
PRIMARY KEY ('db','name')
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
...@@ -526,3 +526,41 @@ ALTER TABLE proc MODIFY db ...@@ -526,3 +526,41 @@ ALTER TABLE proc MODIFY db
char(77) collate utf8_bin DEFAULT '' NOT NULL, char(77) collate utf8_bin DEFAULT '' NOT NULL,
MODIFY comment MODIFY comment
char(64) collate utf8_bin DEFAULT '' NOT NULL; char(64) collate utf8_bin DEFAULT '' NOT NULL;
#
# EVENT table
#
CREATE TABLE event (
'db' VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '',
'name' VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '',
'body' longblob NOT NULL,
'definer' VARCHAR(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '',
'execute_at' DATETIME default NULL,
'transient_expression' int(11) default NULL,
'interval_type' ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK',
'SECOND','MICROSECOND', 'YEAR_MONTH','DAY_HOUR',
'DAY_MINUTE','DAY_SECOND',
'HOUR_MINUTE','HOUR_SECOND',
'MINUTE_SECOND','DAY_MICROSECOND',
'HOUR_MICROSECOND','MINUTE_MICROSECOND',
'SECOND_MICROSECOND') default NULL,
'created' TIMESTAMP NOT NULL default '0000-00-00 00:00:00',
'modified' TIMESTAMP NOT NULL default '0000-00-00 00:00:00',
'last_executed' DATETIME default NULL,
'starts' DATETIME default NULL,
'ends' DATETIME default NULL,
'status' ENUM('ENABLED','DISABLED') NOT NULL default 'ENABLED',
'on_completion' ENUM('DROP','PRESERVE') NOT NULL default 'DROP',
'comment' varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '',
PRIMARY KEY ('db','name')
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
#
# EVENT privilege
#
ALTER TABLE mysql.user add Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_user_priv;
ALTER TABLE mysql.db add Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL;
...@@ -61,7 +61,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ ...@@ -61,7 +61,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
tztime.h my_decimal.h\ tztime.h my_decimal.h\
sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \ sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \
parse_file.h sql_view.h sql_trigger.h \ parse_file.h sql_view.h sql_trigger.h \
sql_array.h sql_cursor.h event.h \ sql_array.h sql_cursor.h event.h event_priv.h \
sql_plugin.h authors.h sql_plugin.h authors.h
mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \ item.cc item_sum.cc item_buff.cc item_func.cc \
...@@ -94,7 +94,8 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ ...@@ -94,7 +94,8 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
gstream.cc spatial.cc sql_help.cc sql_cursor.cc \ gstream.cc spatial.cc sql_help.cc sql_cursor.cc \
tztime.cc my_time.c my_decimal.cc\ tztime.cc my_time.c my_decimal.cc\
sp_head.cc sp_pcontext.cc sp_rcontext.cc sp.cc \ sp_head.cc sp_pcontext.cc sp_rcontext.cc sp.cc \
sp_cache.cc parse_file.cc sql_trigger.cc event.cc \ sp_cache.cc parse_file.cc sql_trigger.cc \
event_executor.cc event.cc event_timed.cc \
sql_plugin.cc\ sql_plugin.cc\
handlerton.cc handlerton.cc
EXTRA_mysqld_SOURCES = ha_innodb.cc ha_berkeley.cc ha_archive.cc \ EXTRA_mysqld_SOURCES = ha_innodb.cc ha_berkeley.cc ha_archive.cc \
......
This diff is collapsed.
/* -*- C++ -*- */ /* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _EVENT_H_ #ifndef _EVENT_H_
#define _EVENT_H_ #define _EVENT_H_
#include "sp_head.h" #include "sp_head.h"
#include "sp.h"
extern ulong opt_event_executor; extern ulong opt_event_executor;
#define EVEX_OK 0 #define EVEX_OK SP_OK
#define EVEX_KEY_NOT_FOUND -1 #define EVEX_KEY_NOT_FOUND SP_KEY_NOT_FOUND
#define EVEX_OPEN_TABLE_FAILED -2 #define EVEX_OPEN_TABLE_FAILED SP_OPEN_TABLE_FAILED
#define EVEX_WRITE_ROW_FAILED -3 #define EVEX_WRITE_ROW_FAILED SP_WRITE_ROW_FAILED
#define EVEX_DELETE_ROW_FAILED -4 #define EVEX_DELETE_ROW_FAILED SP_DELETE_ROW_FAILED
#define EVEX_GET_FIELD_FAILED -5 #define EVEX_GET_FIELD_FAILED SP_GET_FIELD_FAILED
#define EVEX_PARSE_ERROR -6 #define EVEX_PARSE_ERROR SP_PARSE_ERROR
#define EVEX_INTERNAL_ERROR -7 #define EVEX_INTERNAL_ERROR SP_INTERNAL_ERROR
#define EVEX_NO_DB_ERROR -8 #define EVEX_NO_DB_ERROR SP_NO_DB_ERROR
#define EVEX_GENERAL_ERROR -9 #define EVEX_GENERAL_ERROR -20
#define EVEX_BAD_PARAMS -10 #define EVEX_BAD_IDENTIFIER SP_BAD_IDENTIFIER
#define EVEX_NOT_RUNNING -11 #define EVEX_BODY_TOO_LONG SP_BODY_TOO_LONG
#define EVEX_BAD_PARAMS -21
#define EVEX_NOT_RUNNING -22
#define EVENT_EXEC_NO_MORE (1L << 0) #define EVENT_EXEC_NO_MORE (1L << 0)
#define EVENT_NOT_USED (1L << 1) #define EVENT_NOT_USED (1L << 1)
#define SP_OK 0
#define SP_KEY_NOT_FOUND -1
#define SP_OPEN_TABLE_FAILED -2
#define SP_WRITE_ROW_FAILED -3
#define SP_DELETE_ROW_FAILED -4
#define SP_GET_FIELD_FAILED -5
#define SP_PARSE_ERROR -6
#define SP_INTERNAL_ERROR -7
#define SP_NO_DB_ERROR -8
#define SP_BAD_IDENTIFIER -9
#define SP_BODY_TOO_LONG -10
extern ulong opt_event_executor;
enum enum_event_on_completion enum enum_event_on_completion
{ {
...@@ -40,11 +71,12 @@ class event_timed ...@@ -40,11 +71,12 @@ class event_timed
{ {
event_timed(const event_timed &); /* Prevent use of these */ event_timed(const event_timed &); /* Prevent use of these */
void operator=(event_timed &); void operator=(event_timed &);
my_bool running;
pthread_mutex_t LOCK_running;
public: public:
LEX_STRING m_db; LEX_STRING m_db;
LEX_STRING m_name; LEX_STRING m_name;
LEX_STRING m_qname; // db.name
LEX_STRING m_body; LEX_STRING m_body;
LEX_STRING m_definer_user; LEX_STRING m_definer_user;
...@@ -64,9 +96,6 @@ public: ...@@ -64,9 +96,6 @@ public:
enum enum_event_status m_status; enum enum_event_status m_status;
sp_head *m_sphead; sp_head *m_sphead;
uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value
const uchar *m_body_begin; const uchar *m_body_begin;
bool m_dropped; bool m_dropped;
...@@ -75,15 +104,19 @@ public: ...@@ -75,15 +104,19 @@ public:
bool m_last_executed_changed; bool m_last_executed_changed;
bool m_status_changed; bool m_status_changed;
event_timed():m_expr(0), m_created(0), m_modified(0), event_timed():running(0), m_expr(0), m_created(0), m_modified(0),
m_on_completion(MYSQL_EVENT_ON_COMPLETION_DROP), m_on_completion(MYSQL_EVENT_ON_COMPLETION_DROP),
m_status(MYSQL_EVENT_ENABLED), m_sphead(0), m_dropped(false), m_status(MYSQL_EVENT_ENABLED), m_sphead(0), m_dropped(false),
m_free_sphead_on_delete(true), m_flags(0), m_free_sphead_on_delete(true), m_flags(0),
m_last_executed_changed(false), m_status_changed(false) m_last_executed_changed(false), m_status_changed(false)
{ init(); } {
pthread_mutex_init(&LOCK_running, MY_MUTEX_INIT_FAST);
init();
}
~event_timed() ~event_timed()
{ {
pthread_mutex_destroy(&LOCK_running);
if (m_free_sphead_on_delete) if (m_free_sphead_on_delete)
free_sp(); free_sp();
} }
...@@ -115,12 +148,6 @@ public: ...@@ -115,12 +148,6 @@ public:
void void
init_comment(THD *thd, LEX_STRING *comment); init_comment(THD *thd, LEX_STRING *comment);
void
set_on_completion_drop(bool drop);
void
set_event_status(bool enabled);
int int
load_from_row(MEM_ROOT *mem_root, TABLE *table); load_from_row(MEM_ROOT *mem_root, TABLE *table);
...@@ -140,10 +167,10 @@ public: ...@@ -140,10 +167,10 @@ public:
get_show_create_event(THD *thd, uint *length); get_show_create_event(THD *thd, uint *length);
int int
execute(THD *thd, MEM_ROOT *mem_root); execute(THD *thd, MEM_ROOT *mem_root= NULL);
int int
compile(THD *thd, MEM_ROOT *mem_root); compile(THD *thd, MEM_ROOT *mem_root= NULL);
void free_sp() void free_sp()
{ {
...@@ -172,29 +199,21 @@ init_events(); ...@@ -172,29 +199,21 @@ init_events();
void void
shutdown_events(); shutdown_events();
/*
typedef struct st_event_item { // auxiliary
my_time_t execute_at; int
sp_head *proc; event_timed_compare(event_timed **a, event_timed **b);
char *definer_user;
char *definer_host;
} EVENT_ITEM;
*/
/* /*
CREATE TABLE `event` ( CREATE TABLE `event` (
`db` varchar(64) character set latin1 collate latin1_bin NOT NULL default '', `db` varchar(64) character set utf8 collate utf8_bin NOT NULL default '',
`name` varchar(64) NOT NULL default '', `name` varchar(64) character set utf8 collate utf8_bin NOT NULL default '',
`body` blob NOT NULL, `body` longblob NOT NULL,
`definer` varchar(77) character set latin1 collate latin1_bin NOT NULL default '', `definer` varchar(77) character set utf8 collate utf8_bin NOT NULL default '',
`execute_at` datetime default NULL, `execute_at` datetime default NULL,
`transient_expression` int(11) default NULL, `transient_expression` int(11) default NULL,
`interval_type` enum('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK', `interval_type` enum('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL,
'SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE',
'DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND',
'DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND',
'SECOND_MICROSECOND') DEFAULT NULL,
`created` timestamp NOT NULL default '0000-00-00 00:00:00', `created` timestamp NOT NULL default '0000-00-00 00:00:00',
`modified` timestamp NOT NULL default '0000-00-00 00:00:00', `modified` timestamp NOT NULL default '0000-00-00 00:00:00',
`last_executed` datetime default NULL, `last_executed` datetime default NULL,
...@@ -202,9 +221,9 @@ CREATE TABLE `event` ( ...@@ -202,9 +221,9 @@ CREATE TABLE `event` (
`ends` datetime default NULL, `ends` datetime default NULL,
`status` enum('ENABLED','DISABLED') NOT NULL default 'ENABLED', `status` enum('ENABLED','DISABLED') NOT NULL default 'ENABLED',
`on_completion` enum('DROP','PRESERVE') NOT NULL default 'DROP', `on_completion` enum('DROP','PRESERVE') NOT NULL default 'DROP',
`comment` varchar(64) character set latin1 collate latin1_bin NOT NULL default '', `comment` varchar(64) character set utf8 collate utf8_bin NOT NULL default '',
PRIMARY KEY (`db`,`name`) PRIMARY KEY (`db`,`name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=utf8
*/ */
#endif /* _EVENT_H_ */ #endif /* _EVENT_H_ */
This diff is collapsed.
/* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _EVENT_PRIV_H_
#define _EVENT_PRIV_H_
#define EVEX_OPEN_TABLE_FOR_UPDATE() \
open_proc_type_table_for_update(thd, "event", &mysql_event_table_exists)
enum
{
EVEX_FIELD_DB = 0,
EVEX_FIELD_NAME,
EVEX_FIELD_BODY,
EVEX_FIELD_DEFINER,
EVEX_FIELD_EXECUTE_AT,
EVEX_FIELD_INTERVAL_EXPR,
EVEX_FIELD_TRANSIENT_INTERVAL,
EVEX_FIELD_CREATED,
EVEX_FIELD_MODIFIED,
EVEX_FIELD_LAST_EXECUTED,
EVEX_FIELD_STARTS,
EVEX_FIELD_ENDS,
EVEX_FIELD_STATUS,
EVEX_FIELD_ON_COMPLETION,
EVEX_FIELD_COMMENT,
EVEX_FIELD_COUNT /* a cool trick to count the number of fields :) */
};
extern bool evex_is_running;
extern bool mysql_event_table_exists;
extern DYNAMIC_ARRAY events_array;
extern DYNAMIC_ARRAY evex_executing_queue;
extern MEM_ROOT evex_mem_root;
extern pthread_mutex_t LOCK_event_arrays,
LOCK_workers_count,
LOCK_evex_running;
int
my_time_compare(TIME *a, TIME *b);
#endif /* _EVENT_PRIV_H_ */
This diff is collapsed.
...@@ -4807,7 +4807,7 @@ Disable with --skip-bdb (will save memory).", ...@@ -4807,7 +4807,7 @@ Disable with --skip-bdb (will save memory).",
(gptr*) &global_system_variables.engine_condition_pushdown, (gptr*) &global_system_variables.engine_condition_pushdown,
(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}, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"event-executor", OPT_EVENT_EXECUTOR, "Print a symbolic stack trace on failure.", {"event-scheduler", OPT_EVENT_EXECUTOR, "Enable/disable the event scheduler.",
(gptr*) &opt_event_executor, (gptr*) &opt_event_executor, 0, GET_BOOL, NO_ARG, (gptr*) &opt_event_executor, (gptr*) &opt_event_executor, 0, GET_BOOL, NO_ARG,
1/*default*/, 0/*min-value*/, 1/*max-value*/, 0, 0, 0}, 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, {"exit-info", 'T', "Used for debugging; Use at your own risk!", 0, 0, 0,
......
...@@ -207,7 +207,7 @@ sys_var_long_ptr sys_delayed_insert_timeout("delayed_insert_timeout", ...@@ -207,7 +207,7 @@ sys_var_long_ptr sys_delayed_insert_timeout("delayed_insert_timeout",
&delayed_insert_timeout); &delayed_insert_timeout);
sys_var_long_ptr sys_delayed_queue_size("delayed_queue_size", sys_var_long_ptr sys_delayed_queue_size("delayed_queue_size",
&delayed_queue_size); &delayed_queue_size);
sys_var_bool_ptr sys_event_executor("event_executor", sys_var_bool_ptr sys_event_executor("event_scheduler",
&event_executor_running_global_var); &event_executor_running_global_var);
sys_var_long_ptr sys_expire_logs_days("expire_logs_days", sys_var_long_ptr sys_expire_logs_days("expire_logs_days",
&expire_logs_days); &expire_logs_days);
......
...@@ -5730,7 +5730,7 @@ ER_EVENT_DOES_NOT_EXIST ...@@ -5730,7 +5730,7 @@ ER_EVENT_DOES_NOT_EXIST
ER_EVENT_CANT_ALTER ER_EVENT_CANT_ALTER
eng "Failed to alter event %s" eng "Failed to alter event %s"
ER_EVENT_DROP_FAILED ER_EVENT_DROP_FAILED
eng "Failed to DROP %s %s" eng "Failed to drop %s"
ER_EVENT_INTERVAL_NOT_POSITIVE ER_EVENT_INTERVAL_NOT_POSITIVE
eng "INTERVAL must be positive" eng "INTERVAL must be positive"
ER_EVENT_ENDS_BEFORE_STARTS ER_EVENT_ENDS_BEFORE_STARTS
......
...@@ -958,10 +958,10 @@ int sp_head::execute(THD *thd) ...@@ -958,10 +958,10 @@ int sp_head::execute(THD *thd)
DBUG_ASSERT(!(m_flags & IS_INVOKED)); DBUG_ASSERT(!(m_flags & IS_INVOKED));
m_flags|= IS_INVOKED; m_flags|= IS_INVOKED;
m_first_instance->m_first_free_instance= m_next_cached_sp; m_first_instance->m_first_free_instance= m_next_cached_sp;
DBUG_PRINT("info", ("first free for 0x%lx ++: 0x%lx->0x%lx, level: %lu, flags %x", // DBUG_PRINT("info", ("first free for 0x%lx ++: 0x%lx->0x%lx, level: %lu, flags %x",
(ulong)m_first_instance, this, m_next_cached_sp, // (ulong)m_first_instance, this, m_next_cached_sp,
m_next_cached_sp->m_recursion_level, // m_next_cached_sp->m_recursion_level,
m_next_cached_sp->m_flags)); // m_next_cached_sp->m_flags));
/* /*
Check that if there are not any instances after this one then Check that if there are not any instances after this one then
pointer to the last instance points on this instance or if there are pointer to the last instance points on this instance or if there are
......
...@@ -130,7 +130,6 @@ public: ...@@ -130,7 +130,6 @@ public:
uint m_returns_len; // For FUNCTIONs only uint m_returns_len; // For FUNCTIONs only
uint m_returns_pack; // For FUNCTIONs only uint m_returns_pack; // For FUNCTIONs only
const uchar *m_tmp_query; // Temporary pointer to sub query string const uchar *m_tmp_query; // Temporary pointer to sub query string
uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value
st_sp_chistics *m_chistics; st_sp_chistics *m_chistics;
ulong m_sql_mode; // For SHOW CREATE and execution ulong m_sql_mode; // For SHOW CREATE and execution
LEX_STRING m_qname; // db.name LEX_STRING m_qname; // db.name
......
...@@ -352,6 +352,14 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) ...@@ -352,6 +352,14 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
if (table->s->fields <= 36 && (user.access & GRANT_ACL)) if (table->s->fields <= 36 && (user.access & GRANT_ACL))
user.access|= CREATE_USER_ACL; user.access|= CREATE_USER_ACL;
/*
if it is pre 5.1.4 privilege table then map CREATE privilege on
CREATE|ALTER|DROP|EXECUTE EVENT
*/
if (table->s->fields <= 37 && (user.access & CREATE_ACL))
user.access|= EVENT_ACL;
user.sort= get_sort(2,user.host.hostname,user.user); user.sort= get_sort(2,user.host.hostname,user.user);
user.hostname_length= (user.host.hostname ? user.hostname_length= (user.host.hostname ?
(uint) strlen(user.host.hostname) : 0); (uint) strlen(user.host.hostname) : 0);
......
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
(UPDATE_ACL | SELECT_ACL | INSERT_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \ (UPDATE_ACL | SELECT_ACL | INSERT_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL | \ GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL | \
LOCK_TABLES_ACL | EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | \ LOCK_TABLES_ACL | EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | \
CREATE_PROC_ACL | ALTER_PROC_ACL) CREATE_PROC_ACL | ALTER_PROC_ACL | EVENT_ACL)
#define TABLE_ACLS \ #define TABLE_ACLS \
(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \ (SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
......
...@@ -3675,9 +3675,6 @@ end_with_restore_list: ...@@ -3675,9 +3675,6 @@ end_with_restore_list:
} }
case SQLCOM_CREATE_EVENT: case SQLCOM_CREATE_EVENT:
{ {
if (check_global_access(thd, EVENT_ACL))
break;
DBUG_ASSERT(lex->et); DBUG_ASSERT(lex->et);
if (! lex->et->m_db.str) if (! lex->et->m_db.str)
{ {
...@@ -3686,7 +3683,9 @@ end_with_restore_list: ...@@ -3686,7 +3683,9 @@ end_with_restore_list:
lex->et= 0; lex->et= 0;
goto error; goto error;
} }
if (check_access(thd, EVENT_ACL, lex->et->m_db.str, 0, 0, 0,
is_schema_db(lex->et->m_db.str)))
break;
int result; int result;
uint create_options= lex->create_info.options; uint create_options= lex->create_info.options;
res= (result= evex_create_event(thd, lex->et, create_options)); res= (result= evex_create_event(thd, lex->et, create_options));
...@@ -3716,9 +3715,6 @@ end_with_restore_list: ...@@ -3716,9 +3715,6 @@ end_with_restore_list:
} }
case SQLCOM_ALTER_EVENT: case SQLCOM_ALTER_EVENT:
{ {
if (check_global_access(thd, EVENT_ACL))
break;
DBUG_ASSERT(lex->et); DBUG_ASSERT(lex->et);
if (! lex->et->m_db.str) if (! lex->et->m_db.str)
{ {
...@@ -3727,6 +3723,9 @@ end_with_restore_list: ...@@ -3727,6 +3723,9 @@ end_with_restore_list:
lex->et= 0; lex->et= 0;
goto error; goto error;
} }
if (check_access(thd, EVENT_ACL, lex->et->m_db.str, 0, 0, 0,
is_schema_db(lex->et->m_db.str)))
break;
int result; int result;
res= (result= evex_update_event(thd, lex->spname, lex->et)); res= (result= evex_update_event(thd, lex->spname, lex->et));
...@@ -3735,10 +3734,10 @@ end_with_restore_list: ...@@ -3735,10 +3734,10 @@ end_with_restore_list:
send_ok(thd, 1); send_ok(thd, 1);
break; break;
case EVEX_KEY_NOT_FOUND: case EVEX_KEY_NOT_FOUND:
my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), lex->et->m_qname.str); my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), lex->et->m_name.str);
break; break;
default: default:
my_error(ER_EVENT_CANT_ALTER, MYF(0), lex->et->m_qname.str); my_error(ER_EVENT_CANT_ALTER, MYF(0), lex->et->m_name.str);
break; break;
} }
delete lex->et; delete lex->et;
...@@ -3754,9 +3753,6 @@ end_with_restore_list: ...@@ -3754,9 +3753,6 @@ end_with_restore_list:
} }
case SQLCOM_DROP_EVENT: case SQLCOM_DROP_EVENT:
{ {
if (check_global_access(thd, EVENT_ACL))
break;
DBUG_ASSERT(lex->et); DBUG_ASSERT(lex->et);
if (! lex->et->m_db.str) if (! lex->et->m_db.str)
{ {
...@@ -3765,6 +3761,9 @@ end_with_restore_list: ...@@ -3765,6 +3761,9 @@ end_with_restore_list:
lex->et= 0; lex->et= 0;
goto error; goto error;
} }
if (check_access(thd, EVENT_ACL, lex->et->m_db.str, 0, 0, 0,
is_schema_db(lex->et->m_db.str)))
break;
int result; int result;
res= (result= evex_drop_event(thd, lex->et, lex->drop_if_exists)); res= (result= evex_drop_event(thd, lex->et, lex->drop_if_exists));
...@@ -3773,10 +3772,10 @@ end_with_restore_list: ...@@ -3773,10 +3772,10 @@ end_with_restore_list:
send_ok(thd, 1); send_ok(thd, 1);
break; break;
case EVEX_KEY_NOT_FOUND: case EVEX_KEY_NOT_FOUND:
my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), lex->et->m_qname.str); my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), lex->et->m_name.str);
break; break;
default: default:
my_error(ER_EVENT_DROP_FAILED, MYF(0), lex->et->m_qname.str); my_error(ER_EVENT_DROP_FAILED, MYF(0), lex->et->m_name.str);
break; break;
} }
delete lex->et; delete lex->et;
...@@ -3786,7 +3785,8 @@ end_with_restore_list: ...@@ -3786,7 +3785,8 @@ end_with_restore_list:
} }
case SQLCOM_SHOW_CREATE_EVENT: case SQLCOM_SHOW_CREATE_EVENT:
{ {
if (check_global_access(thd, EVENT_ACL)) if (check_access(thd, EVENT_ACL, lex->spname->m_db.str, 0, 0, 0,
is_schema_db(lex->spname->m_db.str)))
break; break;
if (lex->spname->m_name.length > NAME_LEN) if (lex->spname->m_name.length > NAME_LEN)
...@@ -3794,6 +3794,7 @@ end_with_restore_list: ...@@ -3794,6 +3794,7 @@ end_with_restore_list:
my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str); my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str);
goto error; goto error;
} }
/* TODO : Implement it */
send_ok(thd, 1); send_ok(thd, 1);
break; break;
} }
......
...@@ -1261,7 +1261,7 @@ create: ...@@ -1261,7 +1261,7 @@ create:
* stored procedure, otherwise yylex will chop it into pieces * stored procedure, otherwise yylex will chop it into pieces
* at each ';'. * at each ';'.
*/ */
sp->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; $<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES); YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES);
} }
'(' '('
...@@ -1294,9 +1294,9 @@ create: ...@@ -1294,9 +1294,9 @@ create:
YYABORT; YYABORT;
sp->init_strings(YYTHD, lex, $3); sp->init_strings(YYTHD, lex, $3);
lex->sql_command= SQLCOM_CREATE_PROCEDURE; lex->sql_command= SQLCOM_CREATE_PROCEDURE;
/* Restore flag if it was cleared above */ /* Restore flag if it was cleared above */
if (sp->m_old_cmq) YYTHD->client_capabilities |= $<ulong_num>3;
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
sp->restore_thd_mem_root(YYTHD); sp->restore_thd_mem_root(YYTHD);
} }
| CREATE | CREATE
...@@ -1314,32 +1314,35 @@ create: ...@@ -1314,32 +1314,35 @@ create:
| CREATE EVENT_SYM opt_if_not_exists sp_name | CREATE EVENT_SYM opt_if_not_exists sp_name
{ {
LEX *lex=Lex; LEX *lex=Lex;
event_timed *et;
if (lex->et) if (lex->et)
{ {
/*
Recursive events are not possible because recursive SPs
are not also possible. lex->sp_head is not stacked.
*/
// ToDo Andrey : Change the error message // ToDo Andrey : Change the error message
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "EVENT"); my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "EVENT");
YYABORT; YYABORT;
} }
lex->create_info.options=$3; lex->create_info.options= $3;
et= new event_timed();// implicitly calls event_timed::init()
lex->et = et;
if (!lex->et_compile_phase) if (!(lex->et= new event_timed())) // implicitly calls event_timed::init()
et->init_name(YYTHD, $4); YYABORT;
/* /*
We have to turn of CLIENT_MULTI_QUERIES while parsing a We have to turn of CLIENT_MULTI_QUERIES while parsing a
stored procedure, otherwise yylex will chop it into pieces stored procedure, otherwise yylex will chop it into pieces
at each ';'. at each ';'.
*/ */
et->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; $<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES; YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES);
lex->sphead= 0; if (!lex->et_compile_phase)
lex->et->init_name(YYTHD, $4);
lex->sphead= 0;//defensive programming
} }
ON SCHEDULE_SYM ev_schedule_time ON SCHEDULE_SYM ev_schedule_time
ev_on_completion ev_on_completion
...@@ -1347,9 +1350,14 @@ create: ...@@ -1347,9 +1350,14 @@ create:
ev_comment ev_comment
DO_SYM ev_sql_stmt DO_SYM ev_sql_stmt
{ {
LEX *lex=Lex; /*
sql_command is set here because some rules in ev_sql_stmt
can overwrite it
*/
// Restore flag if it was cleared above
YYTHD->client_capabilities |= $<ulong_num>5;
lex->sql_command= SQLCOM_CREATE_EVENT; Lex->sql_command= SQLCOM_CREATE_EVENT;
} }
; ;
...@@ -1396,14 +1404,14 @@ ev_status: /* empty */ ...@@ -1396,14 +1404,14 @@ ev_status: /* empty */
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (!lex->et_compile_phase) if (!lex->et_compile_phase)
lex->et->set_event_status(1); lex->et->m_status= MYSQL_EVENT_ENABLED;
} }
| DISABLE_SYM | DISABLE_SYM
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (!lex->et_compile_phase) if (!lex->et_compile_phase)
lex->et->set_event_status(0); lex->et->m_status= MYSQL_EVENT_DISABLED;
} }
; ;
ev_starts: /* empty */ ev_starts: /* empty */
...@@ -1438,13 +1446,13 @@ ev_on_completion: /* empty */ ...@@ -1438,13 +1446,13 @@ ev_on_completion: /* empty */
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (!lex->et_compile_phase) if (!lex->et_compile_phase)
lex->et->set_on_completion_drop(false); lex->et->m_on_completion= MYSQL_EVENT_ON_COMPLETION_PRESERVE;
} }
| ON COMPLETION_SYM NOT_SYM PRESERVE_SYM | ON COMPLETION_SYM NOT_SYM PRESERVE_SYM
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (!lex->et_compile_phase) if (!lex->et_compile_phase)
lex->et->set_on_completion_drop(true); lex->et->m_on_completion= MYSQL_EVENT_ON_COMPLETION_DROP;
} }
; ;
ev_comment: /* empty */ ev_comment: /* empty */
...@@ -1490,10 +1498,6 @@ ev_sql_stmt: ...@@ -1490,10 +1498,6 @@ ev_sql_stmt:
lex->sp_chistics.suid= SP_IS_SUID;//always the definer! 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) if (!lex->et_compile_phase)
{ {
lex->et->init_body(YYTHD); lex->et->init_body(YYTHD);
...@@ -1577,7 +1581,7 @@ create_function_tail: ...@@ -1577,7 +1581,7 @@ create_function_tail:
* stored procedure, otherwise yylex will chop it into pieces * stored procedure, otherwise yylex will chop it into pieces
* at each ';'. * at each ';'.
*/ */
sp->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; $<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES; YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES;
lex->sphead->m_param_begin= lex->tok_start+1; lex->sphead->m_param_begin= lex->tok_start+1;
} }
...@@ -1656,9 +1660,9 @@ create_function_tail: ...@@ -1656,9 +1660,9 @@ create_function_tail:
YYABORT; YYABORT;
lex->sql_command= SQLCOM_CREATE_SPFUNCTION; lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
sp->init_strings(YYTHD, lex, lex->spname); sp->init_strings(YYTHD, lex, lex->spname);
/* Restore flag if it was cleared above */ /* Restore flag if it was cleared above */
if (sp->m_old_cmq) YYTHD->client_capabilities |= $<ulong_num>2;
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
sp->restore_thd_mem_root(YYTHD); sp->restore_thd_mem_root(YYTHD);
} }
; ;
...@@ -4194,11 +4198,15 @@ alter: ...@@ -4194,11 +4198,15 @@ alter:
if (lex->et) if (lex->et)
{ {
/*
Recursive events are not possible because recursive SPs
are not also possible. lex->sp_head is not stacked.
*/
// ToDo Andrey : Change the error message // ToDo Andrey : Change the error message
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "EVENT"); my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "EVENT");
YYABORT; YYABORT;
} }
lex->spname= 0;//defensive lex->spname= 0;//defensive programming
et= new event_timed();// implicitly calls event_timed::init() et= new event_timed();// implicitly calls event_timed::init()
lex->et = et; lex->et = et;
...@@ -4209,7 +4217,7 @@ alter: ...@@ -4209,7 +4217,7 @@ alter:
stored procedure, otherwise yylex will chop it into pieces stored procedure, otherwise yylex will chop it into pieces
at each ';'. at each ';'.
*/ */
et->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; $<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES; YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES;
/* /*
...@@ -4225,8 +4233,12 @@ alter: ...@@ -4225,8 +4233,12 @@ alter:
ev_comment ev_comment
ev_opt_sql_stmt ev_opt_sql_stmt
{ {
LEX *lex=Lex; /*
lex->sql_command= SQLCOM_ALTER_EVENT; sql_command is set here because some rules in ev_sql_stmt
can overwrite it
*/
YYTHD->client_capabilities |= $<ulong_num>3;
Lex->sql_command= SQLCOM_ALTER_EVENT;
} }
; ;
...@@ -6953,18 +6965,21 @@ drop: ...@@ -6953,18 +6965,21 @@ drop:
| DROP EVENT_SYM if_exists sp_name | DROP EVENT_SYM if_exists sp_name
{ {
LEX *lex=Lex; LEX *lex=Lex;
event_timed *et;
if (lex->et) if (lex->et)
{ {
// ToDo Andrey : Change the error message // ToDo Andrey : Change the error message
/*
Recursive events are not possible because recursive SPs
are not also possible. lex->sp_head is not stacked.
*/
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "EVENT"); my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "EVENT");
YYABORT; YYABORT;
} }
et= new event_timed; if (!(lex->et= new event_timed()))
lex->et = et; YYABORT;
et->init_name(YYTHD, $4); lex->et->init_name(YYTHD, $4);
lex->sql_command = SQLCOM_DROP_EVENT; lex->sql_command = SQLCOM_DROP_EVENT;
lex->drop_if_exists= $3; lex->drop_if_exists= $3;
...@@ -7623,10 +7638,8 @@ show_param: ...@@ -7623,10 +7638,8 @@ show_param:
} }
| CREATE EVENT_SYM sp_name | CREATE EVENT_SYM sp_name
{ {
LEX *lex= Lex; Lex->sql_command = SQLCOM_SHOW_CREATE_EVENT;
Lex->spname= $3;
lex->sql_command = SQLCOM_SHOW_CREATE_EVENT;
lex->spname= $3;
}; };
; ;
...@@ -10076,7 +10089,7 @@ trigger_tail: ...@@ -10076,7 +10089,7 @@ trigger_tail:
stored procedure, otherwise yylex will chop it into pieces stored procedure, otherwise yylex will chop it into pieces
at each ';'. at each ';'.
*/ */
sp->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; $<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES; YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
...@@ -10091,8 +10104,8 @@ trigger_tail: ...@@ -10091,8 +10104,8 @@ trigger_tail:
lex->sql_command= SQLCOM_CREATE_TRIGGER; lex->sql_command= SQLCOM_CREATE_TRIGGER;
sp->init_strings(YYTHD, lex, $3); sp->init_strings(YYTHD, lex, $3);
/* Restore flag if it was cleared above */ /* Restore flag if it was cleared above */
if (sp->m_old_cmq)
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES; YYTHD->client_capabilities |= $<ulong_num>11;
sp->restore_thd_mem_root(YYTHD); sp->restore_thd_mem_root(YYTHD);
if (sp->is_not_allowed_in_function("trigger")) if (sp->is_not_allowed_in_function("trigger"))
......
...@@ -64,7 +64,7 @@ extern Time_zone * my_tz_find(const String *name, TABLE_LIST *tz_tables); ...@@ -64,7 +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 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 my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap);
extern void my_tz_free(); extern void my_tz_free();
my_time_t sec_since_epoch_TIME(TIME *t); extern my_time_t sec_since_epoch_TIME(TIME *t);
extern TABLE_LIST fake_time_zone_tables_list; 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