Commit b67555d5 authored by unknown's avatar unknown

Merge ahristov@bk-internal.mysql.com:/home/bk/mysql-5.1-wl1034

into lmy004.:/work/mysql-5.1-tt-copy-works


libmysqld/Makefile.am:
  Auto merged
sql/Makefile.am:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/set_var.cc:
  Auto merged
sql/sp_head.cc:
  Auto merged
sql/sql_acl.cc:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_show.cc:
  Auto merged
sql/table.cc:
  Auto merged
parents 44523ebc d22bb45c
...@@ -79,7 +79,7 @@ fast_cflags="-O3 -fno-omit-frame-pointer" ...@@ -79,7 +79,7 @@ fast_cflags="-O3 -fno-omit-frame-pointer"
reckless_cflags="-O3 -fomit-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_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" base_cxxflags="-felide-constructors -fno-exceptions -fno-rtti"
amd64_cxxflags="" # If dropping '--with-big-tables', add here "-DBIG_TABLES" 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); ...@@ -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(DYNAMIC_ARRAY *array);
extern void delete_dynamic_element(DYNAMIC_ARRAY *array, uint array_index); extern void delete_dynamic_element(DYNAMIC_ARRAY *array, uint array_index);
extern void freeze_size(DYNAMIC_ARRAY *array); 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_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 dynamic_element(array,array_index,type) ((type)((array)->buffer) +(array_index))
#define push_dynamic(A,B) insert_dynamic(A,B) #define push_dynamic(A,B) insert_dynamic(A,B)
......
...@@ -35,6 +35,7 @@ typedef struct st_queue { ...@@ -35,6 +35,7 @@ typedef struct st_queue {
uint offset_to_key; /* compare is done on element+offset */ uint offset_to_key; /* compare is done on element+offset */
int max_at_top; /* Set if queue_top gives max */ int max_at_top; /* Set if queue_top gives max */
int (*compare)(void *, byte *,byte *); int (*compare)(void *, byte *,byte *);
uint auto_extent;
} QUEUE; } QUEUE;
#define queue_top(queue) ((queue)->root[1]) #define queue_top(queue) ((queue)->root[1])
...@@ -49,14 +50,19 @@ typedef int (*queue_compare)(void *,byte *, byte *); ...@@ -49,14 +50,19 @@ typedef int (*queue_compare)(void *,byte *, byte *);
int init_queue(QUEUE *queue,uint max_elements,uint offset_to_key, int init_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
pbool max_at_top, queue_compare compare, pbool max_at_top, queue_compare compare,
void *first_cmp_arg); void *first_cmp_arg);
int init_queue_ex(QUEUE *queue,uint max_elements,uint offset_to_key,
pbool max_at_top, queue_compare compare,
void *first_cmp_arg, uint auto_extent);
int reinit_queue(QUEUE *queue,uint max_elements,uint offset_to_key, int reinit_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
pbool max_at_top, queue_compare compare, pbool max_at_top, queue_compare compare,
void *first_cmp_arg); void *first_cmp_arg);
int resize_queue(QUEUE *queue, uint max_elements); int resize_queue(QUEUE *queue, uint max_elements);
void delete_queue(QUEUE *queue); void delete_queue(QUEUE *queue);
void queue_insert(QUEUE *queue,byte *element); void queue_insert(QUEUE *queue,byte *element);
int queue_insert_safe(QUEUE *queue, byte *element);
byte *queue_remove(QUEUE *queue,uint idx); byte *queue_remove(QUEUE *queue,uint idx);
#define queue_remove_all(queue) { (queue)->elements= 0; } #define queue_remove_all(queue) { (queue)->elements= 0; }
#define queue_is_full(queue) (queue->elements == queue->max_elements)
void _downheap(QUEUE *queue,uint idx); void _downheap(QUEUE *queue,uint idx);
void queue_fix(QUEUE *queue); void queue_fix(QUEUE *queue);
#define is_queue_inited(queue) ((queue)->root != 0) #define is_queue_inited(queue) ((queue)->root != 0)
......
...@@ -62,7 +62,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \ ...@@ -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 \ unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc \
spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.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 \ 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 rpl_filter.cc sql_partition.cc handlerton.cc sql_plugin.cc
libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources)
......
/* -*- C++ -*- */
#ifndef _EVENT_H_
#define _EVENT_H_
#include "sp_head.h"
extern ulong opt_event_executor;
#define EVEX_OK 0
#define EVEX_KEY_NOT_FOUND -1
#define EVEX_OPEN_TABLE_FAILED -2
#define EVEX_WRITE_ROW_FAILED -3
#define EVEX_DELETE_ROW_FAILED -4
#define EVEX_GET_FIELD_FAILED -5
#define EVEX_PARSE_ERROR -6
#define EVEX_INTERNAL_ERROR -7
#define EVEX_NO_DB_ERROR -8
#define EVEX_GENERAL_ERROR -9
#define EVEX_BAD_PARAMS -10
#define EVEX_NOT_RUNNING -11
#define EVENT_EXEC_NO_MORE (1L << 0)
#define EVENT_NOT_USED (1L << 1)
enum enum_event_on_completion
{
MYSQL_EVENT_ON_COMPLETION_DROP = 1,
MYSQL_EVENT_ON_COMPLETION_PRESERVE
};
enum enum_event_status
{
MYSQL_EVENT_ENABLED = 1,
MYSQL_EVENT_DISABLED
};
class event_timed
{
event_timed(const event_timed &); /* Prevent use of these */
void operator=(event_timed &);
public:
LEX_STRING m_db;
LEX_STRING m_name;
LEX_STRING m_qname; // db.name
LEX_STRING m_body;
LEX_STRING m_definer_user;
LEX_STRING m_definer_host;
LEX_STRING m_definer;// combination of user and host
LEX_STRING m_comment;
TIME m_starts;
TIME m_ends;
TIME m_execute_at;
longlong m_expr;
interval_type m_interval;
longlong m_created;
longlong m_modified;
TIME m_last_executed;
enum enum_event_on_completion m_on_completion;
enum enum_event_status m_status;
sp_head *m_sphead;
uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value
const uchar *m_body_begin;
bool m_dropped;
bool m_free_sphead_on_delete;
uint m_flags;//all kind of purposes
bool m_last_executed_changed;
bool m_status_changed;
event_timed():m_expr(0), m_created(0), m_modified(0),
m_on_completion(MYSQL_EVENT_ON_COMPLETION_DROP),
m_status(MYSQL_EVENT_ENABLED), m_sphead(0), m_dropped(false),
m_free_sphead_on_delete(true), m_flags(0),
m_last_executed_changed(false), m_status_changed(false)
{ init(); }
~event_timed()
{
if (m_free_sphead_on_delete)
free_sp();
}
void
init();
int
init_definer(THD *thd);
int
init_execute_at(THD *thd, Item *expr);
int
init_interval(THD *thd, Item *expr, interval_type interval);
void
init_name(THD *thd, sp_name *name);
int
init_starts(THD *thd, Item *starts);
int
init_ends(THD *thd, Item *ends);
void
event_timed::init_body(THD *thd);
void
init_comment(THD *thd, LEX_STRING *comment);
void
set_on_completion_drop(bool drop);
void
set_event_status(bool enabled);
int
load_from_row(MEM_ROOT *mem_root, TABLE *table);
bool
compute_next_execution_time();
void
mark_last_executed();
bool
drop(THD *thd);
bool
update_fields(THD *thd);
char *
get_show_create_event(THD *thd, uint *length);
int
execute(THD *thd, MEM_ROOT *mem_root);
int
compile(THD *thd, MEM_ROOT *mem_root);
void free_sp()
{
if (m_sphead)
{
delete m_sphead;
m_sphead= 0;
}
}
};
int
evex_create_event(THD *thd, event_timed *et, uint create_options);
int
evex_update_event(THD *thd, sp_name *name, event_timed *et);
int
evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists);
int
init_events();
void
shutdown_events();
/*
typedef struct st_event_item {
my_time_t execute_at;
sp_head *proc;
char *definer_user;
char *definer_host;
} EVENT_ITEM;
*/
/*
CREATE TABLE `event` (
`db` varchar(64) character set latin1 collate latin1_bin NOT NULL default '',
`name` varchar(64) NOT NULL default '',
`body` blob NOT NULL,
`definer` varchar(77) character set latin1 collate latin1_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 latin1 collate latin1_bin NOT NULL default '',
PRIMARY KEY (`db`,`name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
*/
#endif /* _EVENT_H_ */
...@@ -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';
create database events_test;
use events_test;
drop event if exists event1;
create event event1 on schedule every 15 minute starts now() ends date_add(now(), interval 5 hour) DO begin end;
alter event event1 rename to event2;
alter event event2 disable;
drop event event2;
create event event2 on schedule every 2 second starts now() ends date_add(now(), interval 5 hour) comment "some" DO begin end;
drop event event2;
create table t_event3 (a int, b float);
drop event if exists event3;
create event event3 on schedule every 50 + 10 minute starts date_add("20010101", interval 5 minute) ends date_add("20151010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand());
set max_allowed_packet=128000000;
select sha1(space(9999999));
select count(*) from t_event3;
drop event event3;
drop database events_test;
...@@ -278,3 +278,28 @@ void freeze_size(DYNAMIC_ARRAY *array) ...@@ -278,3 +278,28 @@ void freeze_size(DYNAMIC_ARRAY *array)
array->max_element=elements; 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;
}
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
Implemention of queues from "Algoritms in C" by Robert Sedgewick. Implemention of queues from "Algoritms in C" by Robert Sedgewick.
An optimisation of _downheap suggested in Exercise 7.51 in "Data An optimisation of _downheap suggested in Exercise 7.51 in "Data
Structures & Algorithms in C++" by Mark Allen Weiss, Second Edition Structures & Algorithms in C++" by Mark Allen Weiss, Second Edition
was implemented by Mikael Ronstrm 2005. Also the O(N) algorithm was implemented by Mikael Ronstrom 2005. Also the O(N) algorithm
of queue_fix was implemented. of queue_fix was implemented.
*/ */
...@@ -67,6 +67,46 @@ int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key, ...@@ -67,6 +67,46 @@ int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
} }
/*
Init queue, uses init_queue internally for init work but also accepts
auto_extent as parameter
SYNOPSIS
init_queue_ex()
queue Queue to initialise
max_elements Max elements that will be put in queue
offset_to_key Offset to key in element stored in queue
Used when sending pointers to compare function
max_at_top Set to 1 if you want biggest element on top.
compare Compare function for elements, takes 3 arguments.
first_cmp_arg First argument to compare function
auto_extent When the queue is full and there is insert operation
extend the queue.
NOTES
Will allocate max_element pointers for queue array
RETURN
0 ok
1 Could not allocate memory
*/
int init_queue_ex(QUEUE *queue, uint max_elements, uint offset_to_key,
pbool max_at_top, int (*compare) (void *, byte *, byte *),
void *first_cmp_arg, uint auto_extent)
{
int ret;
DBUG_ENTER("init_queue_ex");
if ((ret= init_queue(queue, max_elements, offset_to_key, max_at_top, compare,
first_cmp_arg)))
DBUG_RETURN(ret);
queue->auto_extent= auto_extent;
DBUG_RETURN(0);
}
/* /*
Reinitialize queue for other usage Reinitialize queue for other usage
...@@ -192,6 +232,31 @@ void queue_insert(register QUEUE *queue, byte *element) ...@@ -192,6 +232,31 @@ void queue_insert(register QUEUE *queue, byte *element)
} }
} }
/*
Does safe insert. If no more space left on the queue resize it.
Return codes:
0 - OK
1 - Cannot allocate more memory
2 - auto_extend is 0, the operation would
*/
int queue_insert_safe(register QUEUE *queue, byte *element)
{
if (queue->elements == queue->max_elements)
{
if (!queue->auto_extent)
return 2;
else if (resize_queue(queue, queue->max_elements + queue->auto_extent))
return 1;
}
queue_insert(queue, element);
return 0;
}
/* Remove item from queue */ /* Remove item from queue */
/* Returns pointer to removed element */ /* Returns pointer to removed element */
......
...@@ -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 \ 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 \
...@@ -95,6 +95,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ ...@@ -95,6 +95,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.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 \ 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.
/* Copyright (C) 2004-2005 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_
#define _EVENT_H_
#include "sp.h"
#include "sp_head.h"
#define EVEX_OK SP_OK
#define EVEX_KEY_NOT_FOUND SP_KEY_NOT_FOUND
#define EVEX_OPEN_TABLE_FAILED SP_OPEN_TABLE_FAILED
#define EVEX_WRITE_ROW_FAILED SP_WRITE_ROW_FAILED
#define EVEX_DELETE_ROW_FAILED SP_DELETE_ROW_FAILED
#define EVEX_GET_FIELD_FAILED SP_GET_FIELD_FAILED
#define EVEX_PARSE_ERROR SP_PARSE_ERROR
#define EVEX_INTERNAL_ERROR SP_INTERNAL_ERROR
#define EVEX_NO_DB_ERROR SP_NO_DB_ERROR
#define EVEX_COMPILE_ERROR -19
#define EVEX_GENERAL_ERROR -20
#define EVEX_BAD_IDENTIFIER SP_BAD_IDENTIFIER
#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_NOT_USED (1L << 1)
extern ulong opt_event_executor;
enum enum_event_on_completion
{
MYSQL_EVENT_ON_COMPLETION_DROP = 1,
MYSQL_EVENT_ON_COMPLETION_PRESERVE
};
enum enum_event_status
{
MYSQL_EVENT_ENABLED = 1,
MYSQL_EVENT_DISABLED
};
class event_timed
{
event_timed(const event_timed &); /* Prevent use of these */
void operator=(event_timed &);
my_bool running;
pthread_mutex_t LOCK_running;
bool status_changed;
bool last_executed_changed;
TIME last_executed;
public:
LEX_STRING dbname;
LEX_STRING name;
LEX_STRING body;
LEX_STRING definer_user;
LEX_STRING definer_host;
LEX_STRING definer;// combination of user and host
LEX_STRING comment;
TIME starts;
TIME ends;
TIME execute_at;
longlong expression;
interval_type interval;
longlong created;
longlong modified;
enum enum_event_on_completion on_completion;
enum enum_event_status status;
sp_head *sphead;
const uchar *body_begin;
bool dropped;
bool free_sphead_on_delete;
uint flags;//all kind of purposes
event_timed():running(0), status_changed(false), last_executed_changed(false),
expression(0), created(0), modified(0),
on_completion(MYSQL_EVENT_ON_COMPLETION_DROP),
status(MYSQL_EVENT_ENABLED), sphead(0), dropped(false),
free_sphead_on_delete(true), flags(0)
{
pthread_mutex_init(&LOCK_running, MY_MUTEX_INIT_FAST);
init();
}
~event_timed()
{
pthread_mutex_destroy(&LOCK_running);
if (free_sphead_on_delete)
free_sp();
}
void
init();
int
init_definer(THD *thd);
int
init_execute_at(THD *thd, Item *expr);
int
init_interval(THD *thd, Item *expr, interval_type new_interval);
void
init_name(THD *thd, sp_name *spn);
int
init_starts(THD *thd, Item *starts);
int
init_ends(THD *thd, Item *ends);
void
event_timed::init_body(THD *thd);
void
init_comment(THD *thd, LEX_STRING *set_comment);
int
load_from_row(MEM_ROOT *mem_root, TABLE *table);
bool
compute_next_execution_time();
void
mark_last_executed();
bool
drop(THD *thd);
bool
update_fields(THD *thd);
char *
get_show_create_event(THD *thd, uint *length);
int
execute(THD *thd, MEM_ROOT *mem_root= NULL);
int
compile(THD *thd, MEM_ROOT *mem_root= NULL);
void free_sp()
{
delete sphead;
sphead= 0;
}
};
int
evex_create_event(THD *thd, event_timed *et, uint create_options);
int
evex_update_event(THD *thd, event_timed *et, sp_name *new_name);
int
evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists);
int
init_events();
void
shutdown_events();
// auxiliary
int
event_timed_compare(event_timed **a, event_timed **b);
/*
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,
`modified` timestamp NOT NULL,
`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
*/
#endif /* _EVENT_H_ */
This diff is collapsed.
/* Copyright (C) 2004-2005 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_
#include "mysql_priv.h"
#define EVEX_USE_QUEUE
#define UNLOCK_MUTEX_AND_BAIL_OUT(__mutex, __label) \
{ VOID(pthread_mutex_unlock(&__mutex)); goto __label; }
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 :) */
};
int
my_time_compare(TIME *a, TIME *b);
int
evex_db_find_event_aux(THD *thd, const LEX_STRING dbname,
const LEX_STRING rname, TABLE *table);
TABLE *
evex_open_event_table(THD *thd, enum thr_lock_type lock_type);
int
event_timed_compare_q(void *vptr, byte* a, byte *b);
int
evex_time_diff(TIME *a, TIME *b);
#define EXEC_QUEUE_QUEUE_NAME executing_queue
#define EXEC_QUEUE_DARR_NAME evex_executing_queue
#define EVEX_QUEUE_TYPE QUEUE
#define EVEX_PTOQEL byte *
#define EVEX_EQ_NAME executing_queue
#define evex_queue_first_element(queue, __cast) ((__cast)queue_top(queue))
#define evex_queue_element(queue, idx, __cast) ((__cast)queue_element(queue, idx))
#define evex_queue_delete_element(queue, idx) queue_remove(queue, idx)
#define evex_queue_destroy(queue) delete_queue(queue)
#define evex_queue_first_updated(queue) queue_replaced(queue)
#define evex_queue_insert(queue, element) queue_insert_safe(queue, element);
void
evex_queue_init(EVEX_QUEUE_TYPE *queue);
#define evex_queue_num_elements(queue) queue.elements
extern bool evex_is_running;
extern MEM_ROOT evex_mem_root;
extern pthread_mutex_t LOCK_event_arrays,
LOCK_workers_count,
LOCK_evex_running;
extern ulonglong evex_main_thread_id;
extern QUEUE EVEX_EQ_NAME;
#endif /* _EVENT_PRIV_H_ */
This diff is collapsed.
...@@ -74,6 +74,7 @@ static SYMBOL symbols[] = { ...@@ -74,6 +74,7 @@ static SYMBOL symbols[] = {
{ "ASC", SYM(ASC)}, { "ASC", SYM(ASC)},
{ "ASCII", SYM(ASCII_SYM)}, { "ASCII", SYM(ASCII_SYM)},
{ "ASENSITIVE", SYM(ASENSITIVE_SYM)}, { "ASENSITIVE", SYM(ASENSITIVE_SYM)},
{ "AT", SYM(AT_SYM)},
{ "AUTHORS", SYM(AUTHORS_SYM)}, { "AUTHORS", SYM(AUTHORS_SYM)},
{ "AUTO_INCREMENT", SYM(AUTO_INC)}, { "AUTO_INCREMENT", SYM(AUTO_INC)},
{ "AVG", SYM(AVG_SYM)}, { "AVG", SYM(AVG_SYM)},
...@@ -121,6 +122,7 @@ static SYMBOL symbols[] = { ...@@ -121,6 +122,7 @@ static SYMBOL symbols[] = {
{ "COMMIT", SYM(COMMIT_SYM)}, { "COMMIT", SYM(COMMIT_SYM)},
{ "COMMITTED", SYM(COMMITTED_SYM)}, { "COMMITTED", SYM(COMMITTED_SYM)},
{ "COMPACT", SYM(COMPACT_SYM)}, { "COMPACT", SYM(COMPACT_SYM)},
{ "COMPLETION", SYM(COMPLETION_SYM)},
{ "COMPRESSED", SYM(COMPRESSED_SYM)}, { "COMPRESSED", SYM(COMPRESSED_SYM)},
{ "CONCURRENT", SYM(CONCURRENT)}, { "CONCURRENT", SYM(CONCURRENT)},
{ "CONDITION", SYM(CONDITION_SYM)}, { "CONDITION", SYM(CONDITION_SYM)},
...@@ -180,13 +182,16 @@ static SYMBOL symbols[] = { ...@@ -180,13 +182,16 @@ static SYMBOL symbols[] = {
{ "ENABLE", SYM(ENABLE_SYM)}, { "ENABLE", SYM(ENABLE_SYM)},
{ "ENCLOSED", SYM(ENCLOSED)}, { "ENCLOSED", SYM(ENCLOSED)},
{ "END", SYM(END)}, { "END", SYM(END)},
{ "ENDS", SYM(ENDS_SYM)},
{ "ENGINE", SYM(ENGINE_SYM)}, { "ENGINE", SYM(ENGINE_SYM)},
{ "ENGINES", SYM(ENGINES_SYM)}, { "ENGINES", SYM(ENGINES_SYM)},
{ "ENUM", SYM(ENUM)}, { "ENUM", SYM(ENUM)},
{ "ERRORS", SYM(ERRORS)}, { "ERRORS", SYM(ERRORS)},
{ "ESCAPE", SYM(ESCAPE_SYM)}, { "ESCAPE", SYM(ESCAPE_SYM)},
{ "ESCAPED", SYM(ESCAPED)}, { "ESCAPED", SYM(ESCAPED)},
{ "EVENT", SYM(EVENT_SYM)},
{ "EVENTS", SYM(EVENTS_SYM)}, { "EVENTS", SYM(EVENTS_SYM)},
{ "EVERY", SYM(EVERY_SYM)},
{ "EXECUTE", SYM(EXECUTE_SYM)}, { "EXECUTE", SYM(EXECUTE_SYM)},
{ "EXISTS", SYM(EXISTS)}, { "EXISTS", SYM(EXISTS)},
{ "EXIT", SYM(EXIT_SYM)}, { "EXIT", SYM(EXIT_SYM)},
...@@ -384,6 +389,7 @@ static SYMBOL symbols[] = { ...@@ -384,6 +389,7 @@ static SYMBOL symbols[] = {
{ "POLYGON", SYM(POLYGON)}, { "POLYGON", SYM(POLYGON)},
{ "PRECISION", SYM(PRECISION)}, { "PRECISION", SYM(PRECISION)},
{ "PREPARE", SYM(PREPARE_SYM)}, { "PREPARE", SYM(PREPARE_SYM)},
{ "PRESERVE", SYM(PRESERVE_SYM)},
{ "PREV", SYM(PREV_SYM)}, { "PREV", SYM(PREV_SYM)},
{ "PRIMARY", SYM(PRIMARY_SYM)}, { "PRIMARY", SYM(PRIMARY_SYM)},
{ "PRIVILEGES", SYM(PRIVILEGES)}, { "PRIVILEGES", SYM(PRIVILEGES)},
...@@ -436,6 +442,7 @@ static SYMBOL symbols[] = { ...@@ -436,6 +442,7 @@ static SYMBOL symbols[] = {
{ "ROW_FORMAT", SYM(ROW_FORMAT_SYM)}, { "ROW_FORMAT", SYM(ROW_FORMAT_SYM)},
{ "RTREE", SYM(RTREE_SYM)}, { "RTREE", SYM(RTREE_SYM)},
{ "SAVEPOINT", SYM(SAVEPOINT_SYM)}, { "SAVEPOINT", SYM(SAVEPOINT_SYM)},
{ "SCHEDULE", SYM(SCHEDULE_SYM)},
{ "SCHEMA", SYM(DATABASE)}, { "SCHEMA", SYM(DATABASE)},
{ "SCHEMAS", SYM(DATABASES)}, { "SCHEMAS", SYM(DATABASES)},
{ "SECOND", SYM(SECOND_SYM)}, { "SECOND", SYM(SECOND_SYM)},
...@@ -484,6 +491,7 @@ static SYMBOL symbols[] = { ...@@ -484,6 +491,7 @@ static SYMBOL symbols[] = {
{ "SSL", SYM(SSL_SYM)}, { "SSL", SYM(SSL_SYM)},
{ "START", SYM(START_SYM)}, { "START", SYM(START_SYM)},
{ "STARTING", SYM(STARTING)}, { "STARTING", SYM(STARTING)},
{ "STARTS", SYM(STARTS_SYM)},
{ "STATUS", SYM(STATUS_SYM)}, { "STATUS", SYM(STATUS_SYM)},
{ "STOP", SYM(STOP_SYM)}, { "STOP", SYM(STOP_SYM)},
{ "STORAGE", SYM(STORAGE_SYM)}, { "STORAGE", SYM(STORAGE_SYM)},
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "stacktrace.h" #include "stacktrace.h"
#include "mysqld_suffix.h" #include "mysqld_suffix.h"
#include "mysys_err.h" #include "mysys_err.h"
#include "event.h"
#include "ha_myisam.h" #include "ha_myisam.h"
...@@ -3505,6 +3506,8 @@ we force server id to 2, but this MySQL server will not act as a slave."); ...@@ -3505,6 +3506,8 @@ we force server id to 2, but this MySQL server will not act as a slave.");
} }
} }
init_events();
create_shutdown_thread(); create_shutdown_thread();
create_maintenance_thread(); create_maintenance_thread();
...@@ -3568,6 +3571,7 @@ we force server id to 2, but this MySQL server will not act as a slave."); ...@@ -3568,6 +3571,7 @@ we force server id to 2, but this MySQL server will not act as a slave.");
clean_up(1); clean_up(1);
wait_for_signal_thread_to_end(); wait_for_signal_thread_to_end();
clean_up_mutexes(); clean_up_mutexes();
shutdown_events();
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
exit(0); exit(0);
...@@ -4529,7 +4533,7 @@ enum options_mysqld ...@@ -4529,7 +4533,7 @@ enum options_mysqld
OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL, OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
OPT_SAFE_USER_CREATE, OPT_SQL_MODE, OPT_SAFE_USER_CREATE, OPT_SQL_MODE,
OPT_HAVE_NAMED_PIPE, 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_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT,
OPT_SHOW_SLAVE_AUTH_INFO, OPT_SHOW_SLAVE_AUTH_INFO,
OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE, OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE,
...@@ -4807,6 +4811,9 @@ Disable with --skip-bdb (will save memory).", ...@@ -4807,6 +4811,9 @@ 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-scheduler", OPT_EVENT_EXECUTOR, "Enable/disable the event scheduler.",
(gptr*) &opt_event_executor, (gptr*) &opt_event_executor, 0, GET_BOOL, NO_ARG,
0/*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,
GET_LONG, OPT_ARG, 0, 0, 0, 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.", {"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.",
...@@ -6031,6 +6038,7 @@ struct show_var_st status_vars[]= { ...@@ -6031,6 +6038,7 @@ struct show_var_st status_vars[]= {
{"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONG_STATUS}, {"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONG_STATUS},
{"Com_admin_commands", (char*) offsetof(STATUS_VAR, com_other), 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_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_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_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}, {"Com_backup_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BACKUP_TABLE]), SHOW_LONG_STATUS},
...@@ -6041,6 +6049,7 @@ struct show_var_st status_vars[]= { ...@@ -6041,6 +6049,7 @@ struct show_var_st status_vars[]= {
{"Com_checksum", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECKSUM]), SHOW_LONG_STATUS}, {"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_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_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_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_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}, {"Com_create_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
...@@ -6049,6 +6058,7 @@ struct show_var_st status_vars[]= { ...@@ -6049,6 +6058,7 @@ struct show_var_st status_vars[]= {
{"Com_delete_multi", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE_MULTI]), SHOW_LONG_STATUS}, {"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_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_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_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_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}, {"Com_drop_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
...@@ -6090,6 +6100,7 @@ struct show_var_st status_vars[]= { ...@@ -6090,6 +6100,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_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_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_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_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_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}, {"Com_show_engine_logs", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_LOGS]), SHOW_LONG_STATUS},
......
...@@ -104,6 +104,7 @@ extern ulong ndb_cache_check_time; ...@@ -104,6 +104,7 @@ extern ulong ndb_cache_check_time;
extern my_bool event_executor_running_global_var;
static HASH system_variable_hash; static HASH system_variable_hash;
const char *bool_type_names[]= { "OFF", "ON", NullS }; const char *bool_type_names[]= { "OFF", "ON", NullS };
...@@ -208,6 +209,8 @@ sys_var_long_ptr sys_delayed_insert_timeout("delayed_insert_timeout", ...@@ -208,6 +209,8 @@ 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_event_executor sys_event_executor("event_scheduler",
&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);
sys_var_bool_ptr sys_flush("flush", &myisam_flush); sys_var_bool_ptr sys_flush("flush", &myisam_flush);
...@@ -666,6 +669,7 @@ struct show_var_st init_vars[]= { ...@@ -666,6 +669,7 @@ struct show_var_st init_vars[]= {
{sys_div_precincrement.name,(char*) &sys_div_precincrement,SHOW_SYS}, {sys_div_precincrement.name,(char*) &sys_div_precincrement,SHOW_SYS},
{sys_engine_condition_pushdown.name, {sys_engine_condition_pushdown.name,
(char*) &sys_engine_condition_pushdown, SHOW_SYS}, (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_expire_logs_days.name, (char*) &sys_expire_logs_days, SHOW_SYS},
{sys_flush.name, (char*) &sys_flush, SHOW_SYS}, {sys_flush.name, (char*) &sys_flush, SHOW_SYS},
{sys_flush_time.name, (char*) &sys_flush_time, SHOW_SYS}, {sys_flush_time.name, (char*) &sys_flush_time, SHOW_SYS},
...@@ -3362,6 +3366,7 @@ bool sys_var_trust_routine_creators::update(THD *thd, set_var *var) ...@@ -3362,6 +3366,7 @@ bool sys_var_trust_routine_creators::update(THD *thd, set_var *var)
return sys_var_bool_ptr::update(thd, var); return sys_var_bool_ptr::update(thd, var);
} }
/**************************************************************************** /****************************************************************************
Used templates Used templates
****************************************************************************/ ****************************************************************************/
......
...@@ -782,6 +782,17 @@ class sys_var_trust_routine_creators :public sys_var_bool_ptr ...@@ -782,6 +782,17 @@ class sys_var_trust_routine_creators :public sys_var_bool_ptr
bool update(THD *thd, set_var *var); bool update(THD *thd, set_var *var);
}; };
class sys_var_event_executor :public sys_var_bool_ptr
{
/* We need a derived class only to have a warn_deprecated() */
public:
sys_var_event_executor(const char *name_arg, my_bool *value_arg) :
sys_var_bool_ptr(name_arg, value_arg) {};
bool update(THD *thd, set_var *var);
};
/**************************************************************************** /****************************************************************************
Classes for parsing of the SET command Classes for parsing of the SET command
****************************************************************************/ ****************************************************************************/
......
...@@ -5721,3 +5721,33 @@ ER_DROP_PARTITION_WHEN_FK_DEFINED ...@@ -5721,3 +5721,33 @@ ER_DROP_PARTITION_WHEN_FK_DEFINED
swe "Kan inte ta bort en partition nr en frmmande nyckel r definierad p tabellen" swe "Kan inte ta bort en partition nr en frmmande nyckel r definierad p tabellen"
ER_PLUGIN_IS_NOT_LOADED ER_PLUGIN_IS_NOT_LOADED
eng "Plugin '%-.64s' 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 store event %s. Error code %d from storage engine."
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"
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"
ER_EVENT_OPEN_TABLE_FAILED
eng "Failed to open mysql.event"
ER_EVENT_NEITHER_M_EXPR_NOR_M_AT
eng "No datetime expression provided"
ER_EVENT_COL_COUNT_DOESNT_MATCH
eng "Column count of %s.%s is wrong. Table probably corrupted"
ER_EVENT_CANNOT_LOAD_FROM_TABLE
eng "Cannot load from mysql.event. Table probably corrupted"
ER_EVENT_CANNOT_DELETE
eng "Failed to delete the event from mysql.event"
ER_EVENT_COMPILE_ERROR
eng "Error during compilation of event's body"
ER_EVENT_SAME_NAME
eng "Same old and new event name"
...@@ -130,7 +130,6 @@ class sp_head :private Query_arena ...@@ -130,7 +130,6 @@ class sp_head :private Query_arena
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);
...@@ -3971,13 +3979,13 @@ static const char *command_array[]= ...@@ -3971,13 +3979,13 @@ static const char *command_array[]=
"ALTER", "SHOW DATABASES", "SUPER", "CREATE TEMPORARY TABLES", "ALTER", "SHOW DATABASES", "SUPER", "CREATE TEMPORARY TABLES",
"LOCK TABLES", "EXECUTE", "REPLICATION SLAVE", "REPLICATION CLIENT", "LOCK TABLES", "EXECUTE", "REPLICATION SLAVE", "REPLICATION CLIENT",
"CREATE VIEW", "SHOW VIEW", "CREATE ROUTINE", "ALTER ROUTINE", "CREATE VIEW", "SHOW VIEW", "CREATE ROUTINE", "ALTER ROUTINE",
"CREATE USER" "CREATE USER", "EVENT"
}; };
static uint command_lengths[]= 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, 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 @@ ...@@ -42,6 +42,7 @@
#define CREATE_PROC_ACL (1L << 23) #define CREATE_PROC_ACL (1L << 23)
#define ALTER_PROC_ACL (1L << 24) #define ALTER_PROC_ACL (1L << 24)
#define CREATE_USER_ACL (1L << 25) #define CREATE_USER_ACL (1L << 25)
#define EVENT_ACL (1L << 26)
/* /*
don't forget to update don't forget to update
1. static struct show_privileges_st sys_privileges[] 1. static struct show_privileges_st sys_privileges[]
...@@ -56,7 +57,7 @@ ...@@ -56,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 | \
...@@ -78,7 +79,7 @@ ...@@ -78,7 +79,7 @@
REFERENCES_ACL | INDEX_ACL | ALTER_ACL | SHOW_DB_ACL | SUPER_ACL | \ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | SHOW_DB_ACL | SUPER_ACL | \
CREATE_TMP_ACL | LOCK_TABLES_ACL | REPL_SLAVE_ACL | REPL_CLIENT_ACL | \ CREATE_TMP_ACL | LOCK_TABLES_ACL | REPL_SLAVE_ACL | REPL_CLIENT_ACL | \
EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | CREATE_PROC_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 \ #define DEFAULT_CREATE_PROC_ACLS \
(ALTER_PROC_ACL | EXECUTE_ACL) (ALTER_PROC_ACL | EXECUTE_ACL)
......
...@@ -177,7 +177,9 @@ void lex_start(THD *thd, const uchar *buf, uint length) ...@@ -177,7 +177,9 @@ void lex_start(THD *thd, const uchar *buf, uint length)
lex->spcont= NULL; lex->spcont= NULL;
lex->proc_list.first= 0; lex->proc_list.first= 0;
lex->query_tables_own_last= 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) if (lex->sroutines.records)
my_hash_reset(&lex->sroutines); my_hash_reset(&lex->sroutines);
......
...@@ -26,6 +26,7 @@ class sp_name; ...@@ -26,6 +26,7 @@ class sp_name;
class sp_instr; class sp_instr;
class sp_pcontext; class sp_pcontext;
class partition_info; class partition_info;
class event_timed;
/* /*
The following hack is needed because mysql_yacc.cc does not define The following hack is needed because mysql_yacc.cc does not define
...@@ -94,6 +95,8 @@ enum enum_sql_command { ...@@ -94,6 +95,8 @@ enum enum_sql_command {
SQLCOM_SHOW_PROC_CODE, SQLCOM_SHOW_FUNC_CODE, SQLCOM_SHOW_PROC_CODE, SQLCOM_SHOW_FUNC_CODE,
SQLCOM_INSTALL_PLUGIN, SQLCOM_UNINSTALL_PLUGIN, SQLCOM_INSTALL_PLUGIN, SQLCOM_UNINSTALL_PLUGIN,
SQLCOM_SHOW_AUTHORS, SQLCOM_SHOW_AUTHORS,
SQLCOM_CREATE_EVENT, SQLCOM_ALTER_EVENT, SQLCOM_DROP_EVENT,
SQLCOM_SHOW_CREATE_EVENT,
/* This should be the last !!! */ /* This should be the last !!! */
SQLCOM_END SQLCOM_END
...@@ -890,6 +893,10 @@ typedef struct st_lex ...@@ -890,6 +893,10 @@ typedef struct st_lex
uint sroutines_list_own_elements; uint sroutines_list_own_elements;
st_sp_chistics sp_chistics; st_sp_chistics sp_chistics;
event_timed *et;
bool et_compile_phase;
bool only_view; /* used for SHOW CREATE TABLE/VIEW */ bool only_view; /* used for SHOW CREATE TABLE/VIEW */
/* /*
field_list was created for view and should be removed before PS/SP field_list was created for view and should be removed before PS/SP
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "sp_head.h" #include "sp_head.h"
#include "sp.h" #include "sp.h"
#include "sp_cache.h" #include "sp_cache.h"
#include "event.h"
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
/* /*
...@@ -642,6 +643,9 @@ void init_update_queries(void) ...@@ -642,6 +643,9 @@ void init_update_queries(void)
uc_update_queries[SQLCOM_DROP_INDEX]=1; uc_update_queries[SQLCOM_DROP_INDEX]=1;
uc_update_queries[SQLCOM_CREATE_VIEW]=1; uc_update_queries[SQLCOM_CREATE_VIEW]=1;
uc_update_queries[SQLCOM_DROP_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) bool is_update_query(enum enum_sql_command command)
...@@ -3667,6 +3671,60 @@ mysql_execute_command(THD *thd) ...@@ -3667,6 +3671,60 @@ mysql_execute_command(THD *thd)
res=mysqld_show_create_db(thd,lex->name,&lex->create_info); res=mysqld_show_create_db(thd,lex->name,&lex->create_info);
break; break;
} }
case SQLCOM_CREATE_EVENT:
case SQLCOM_ALTER_EVENT:
case SQLCOM_DROP_EVENT:
{
DBUG_ASSERT(lex->et);
do {
if (! lex->et->dbname.str)
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
res= true;
break;
}
if (check_access(thd, EVENT_ACL, lex->et->dbname.str, 0, 0, 0,
is_schema_db(lex->et->dbname.str)))
break;
switch (lex->sql_command) {
case SQLCOM_CREATE_EVENT:
res= evex_create_event(thd, lex->et, (uint) lex->create_info.options);
break;
case SQLCOM_ALTER_EVENT:
res= evex_update_event(thd, lex->et, lex->spname);
break;
case SQLCOM_DROP_EVENT:
evex_drop_event(thd, lex->et, lex->drop_if_exists);
default:;
}
if (!res)
send_ok(thd, 1);
/* lex->unit.cleanup() is called outside, no need to call it here */
} while (0);
delete lex->et;
delete lex->sphead;
lex->et= 0;
lex->sphead= 0;
break;
}
case SQLCOM_SHOW_CREATE_EVENT:
{
if (check_access(thd, EVENT_ACL, lex->spname->m_db.str, 0, 0, 0,
is_schema_db(lex->spname->m_db.str)))
break;
if (lex->spname->m_name.length > NAME_LEN)
{
my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str);
goto error;
}
/* TODO : Implement it */
send_ok(thd, 1);
break;
}
case SQLCOM_CREATE_FUNCTION: // UDF function case SQLCOM_CREATE_FUNCTION: // UDF function
{ {
if (check_access(thd,INSERT_ACL,"mysql",0,1,0,0)) if (check_access(thd,INSERT_ACL,"mysql",0,1,0,0))
...@@ -5598,6 +5656,11 @@ void mysql_parse(THD *thd, char *inBuf, uint length) ...@@ -5598,6 +5656,11 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
delete thd->lex->sphead; delete thd->lex->sphead;
thd->lex->sphead= NULL; thd->lex->sphead= NULL;
} }
if (thd->lex->et)
{
delete thd->lex->et;
thd->lex->et= NULL;
}
} }
else else
{ {
...@@ -5633,6 +5696,11 @@ void mysql_parse(THD *thd, char *inBuf, uint length) ...@@ -5633,6 +5696,11 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
delete thd->lex->sphead; delete thd->lex->sphead;
thd->lex->sphead= NULL; thd->lex->sphead= NULL;
} }
if (thd->lex->et)
{
delete thd->lex->et;
thd->lex->et= NULL;
}
} }
thd->proc_info="freeing items"; thd->proc_info="freeing items";
thd->end_statement(); thd->end_statement();
......
...@@ -147,6 +147,7 @@ static struct show_privileges_st sys_privileges[]= ...@@ -147,6 +147,7 @@ static struct show_privileges_st sys_privileges[]=
{"Create user", "Server Admin", "To create new users"}, {"Create user", "Server Admin", "To create new users"},
{"Delete", "Tables", "To delete existing rows"}, {"Delete", "Tables", "To delete existing rows"},
{"Drop", "Databases,Tables", "To drop databases, tables, and views"}, {"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"}, {"Execute", "Functions,Procedures", "To execute stored routines"},
{"File", "File access on server", "To read and write files on the server"}, {"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"}, {"Grant option", "Databases,Tables,Functions,Procedures", "To give to other users those privileges you possess"},
......
This diff is collapsed.
...@@ -282,7 +282,8 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags) ...@@ -282,7 +282,8 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags)
*/ */
if (share->db.length == 5 && if (share->db.length == 5 &&
!my_strcasecmp(system_charset_info, share->db.str, "mysql") && !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; share->system_table= 1;
error_given= 1; error_given= 1;
} }
......
...@@ -807,6 +807,18 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec) ...@@ -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 Converts local time in broken down TIME representation to my_time_t
representation. representation.
......
...@@ -64,6 +64,7 @@ extern Time_zone * my_tz_find(const String *name, TABLE_LIST *tz_tables); ...@@ -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 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();
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